]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add dbus signal for information about server certification
authorMichael Chang <mchang@novell.com>
Tue, 5 Jul 2011 09:22:32 +0000 (12:22 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 5 Jul 2011 09:22:32 +0000 (12:22 +0300)
In general, this patch attemps to extend commit
00468b4650998144f794762206c695c962c54734 with dbus support.

This can be used by dbus client to implement subject match text
entry with preset value probed from server. This preset value, if
user accepts it, is remembered and passed to subject_match config
for any future authentication.

Signed-off-by: Michael Chang <mchang@novell.com>
src/eap_peer/eap.c
src/eap_peer/eap.h
src/eapol_supp/eapol_supp_sm.c
src/eapol_supp/eapol_supp_sm.h
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new.h
wpa_supplicant/dbus/dbus_old.c
wpa_supplicant/dbus/dbus_old.h
wpa_supplicant/notify.c
wpa_supplicant/notify.h
wpa_supplicant/wpas_glue.c

index 8a9826f1bd200e0636fb7ebcbb613184ea369641..0e83268343925216f22799e6ec2a5bc846f409d6 100644 (file)
@@ -1209,6 +1209,13 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
                                     data->peer_cert.subject,
                                     cert_hex);
                }
+               if (sm->eapol_cb->notify_cert) {
+                       sm->eapol_cb->notify_cert(sm->eapol_ctx,
+                                                 data->peer_cert.depth,
+                                                 data->peer_cert.subject,
+                                                 hash_hex,
+                                                 data->peer_cert.cert);
+               }
                break;
        }
 
index 35509090c36567af1b27bd7026052570f5465084..2a80d4e74707816b5281309a3b961ceb0d9b1a93 100644 (file)
@@ -221,6 +221,17 @@ struct eapol_callbacks {
         */
        void (*eap_param_needed)(void *ctx, const char *field,
                                 const char *txt);
+
+       /**
+        * notify_cert - Notification of a peer certificate
+        * @ctx: eapol_ctx from eap_peer_sm_init() call
+        * @depth: Depth in certificate chain (0 = server)
+        * @subject: Subject of the peer certificate
+        * @cert_hash: SHA-256 hash of the certificate
+        * @cert: Peer certificate
+        */
+       void (*notify_cert)(void *ctx, int depth, const char *subject,
+                           const char *cert_hash, const struct wpabuf *cert);
 };
 
 /**
index 18abb4e3c4173af4eaeb612adf95fd617a0d9f1f..bb6cff604106f5bcfd908dc4597b6f2de6c7b1bb 100644 (file)
@@ -1825,6 +1825,15 @@ static void eapol_sm_eap_param_needed(void *ctx, const char *field,
 #define eapol_sm_eap_param_needed NULL
 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
 
+static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject,
+                                const char *cert_hash,
+                                const struct wpabuf *cert)
+{
+       struct eapol_sm *sm = ctx;
+       if (sm->ctx->cert_cb)
+               sm->ctx->cert_cb(sm->ctx->ctx, depth, subject,
+                                cert_hash, cert);
+}
 
 static struct eapol_callbacks eapol_cb =
 {
@@ -1837,7 +1846,8 @@ static struct eapol_callbacks eapol_cb =
        eapol_sm_set_config_blob,
        eapol_sm_get_config_blob,
        eapol_sm_notify_pending,
-       eapol_sm_eap_param_needed
+       eapol_sm_eap_param_needed,
+       eapol_sm_notify_cert
 };
 
 
index 1bdf8cdd4f1199ee670730b6029e551365008024..3ea7e79935037b40131da874acddc82fa09282f5 100644 (file)
@@ -220,6 +220,17 @@ struct eapol_ctx {
         * @authorized: Whether the supplicant port is now in authorized state
         */
        void (*port_cb)(void *ctx, int authorized);
+
+       /**
+        * cert_cb - Notification of a peer certificate
+        * @ctx: Callback context (ctx)
+        * @depth: Depth in certificate chain (0 = server)
+        * @subject: Subject of the peer certificate
+        * @cert_hash: SHA-256 hash of the certificate
+        * @cert: Peer certificate
+        */
+       void (*cert_cb)(void *ctx, int depth, const char *subject,
+                       const char *cert_hash, const struct wpabuf *cert);
 };
 
 
index d48c3d6be33d0d087f387183ca2622828b3da173..533cb3210d72442b69841316d9a4857c411a0034 100644 (file)
@@ -653,6 +653,54 @@ nomem:
 
 #endif /* CONFIG_WPS */
 
+void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
+                                   int depth, const char *subject,
+                                   const char *cert_hash,
+                                   const struct wpabuf *cert)
+{
+       struct wpas_dbus_priv *iface;
+       DBusMessage *msg;
+       DBusMessageIter iter, dict_iter;
+
+       iface = wpa_s->global->dbus;
+
+       /* Do nothing if the control interface is not turned on */
+       if (iface == NULL)
+               return;
+
+       msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+                                     WPAS_DBUS_NEW_IFACE_INTERFACE,
+                                     "Certification");
+       if (msg == NULL)
+               return;
+
+       dbus_message_iter_init_append(msg, &iter);
+       if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
+               goto nomem;
+
+       if (!wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
+           !wpa_dbus_dict_append_string(&dict_iter, "subject", subject))
+               goto nomem;
+
+       if (cert_hash &&
+           !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash))
+               goto nomem;
+
+       if (cert &&
+           !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
+                                            wpabuf_head(cert),
+                                            wpabuf_len(cert)))
+               goto nomem;
+
+       if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
+               goto nomem;
+
+       dbus_connection_send(iface->con, msg, NULL);
+
+nomem:
+       dbus_message_unref(msg);
+}
+
 #ifdef CONFIG_P2P
 
 /**
@@ -2647,6 +2695,12 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
          }
        },
 #endif /* CONFIG_P2P */
+       { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
+         {
+                 { "certification", "a{sv}", ARG_OUT },
+                 END_ARGS
+         }
+       },
        { NULL, NULL, { END_ARGS } }
 };
 
index 3b0d50c4b91c1264de7be03aded9b6b0caf39205..080000c070ca64ce052ee9e9856caf4390ff519e 100644 (file)
@@ -201,6 +201,10 @@ void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
                                const u8 *member);
 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
                                     struct wps_event_fail *fail);
+void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
+                                   int depth, const char *subject,
+                                   const char *cert_hash,
+                                   const struct wpabuf *cert);
 
 #else /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
@@ -443,6 +447,14 @@ wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
 {
 }
 
+static inline void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
+                                                 int depth,
+                                                 const char *subject,
+                                                 const char *cert_hash,
+                                                 const struct wpabuf *cert)
+{
+}
+
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
 #endif /* CTRL_IFACE_DBUS_H_NEW */
index 6a00f3e57be1a77e37c940a3d1b7b9ee34a8b107..d255e142b3fa60701c163b23b37847f67454123f 100644 (file)
@@ -549,6 +549,59 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
 }
 #endif /* CONFIG_WPS */
 
+void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
+                                             int depth, const char *subject,
+                                             const char *cert_hash,
+                                             const struct wpabuf *cert)
+{
+       struct wpas_dbus_priv *iface;
+       DBusMessage *_signal = NULL;
+       const char *hash;
+       const char *cert_hex;
+       int cert_hex_len;
+
+       /* Do nothing if the control interface is not turned on */
+       if (wpa_s->global == NULL)
+               return;
+       iface = wpa_s->global->dbus;
+       if (iface == NULL)
+               return;
+
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
+                                         "Certification");
+       if (_signal == NULL) {
+               wpa_printf(MSG_ERROR,
+                          "dbus: wpa_supplicant_dbus_notify_certification: "
+                          "Could not create dbus signal; likely out of "
+                          "memory");
+               return;
+       }
+
+       hash = cert_hash ? cert_hash : "";
+       cert_hex = cert ? wpabuf_head(cert) : "";
+       cert_hex_len = cert ? wpabuf_len(cert) : 0;
+
+       if (!dbus_message_append_args(_signal,
+                                     DBUS_TYPE_INT32,&depth,
+                                     DBUS_TYPE_STRING, &subject,
+                                     DBUS_TYPE_STRING, &hash,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+                                     &cert_hex, cert_hex_len,
+                                     DBUS_TYPE_INVALID)) {
+               wpa_printf(MSG_ERROR,
+                          "dbus: wpa_supplicant_dbus_notify_certification: "
+                          "Not enough memory to construct signal");
+               goto out;
+       }
+
+       dbus_connection_send(iface->con, _signal, NULL);
+
+out:
+       dbus_message_unref(_signal);
+
+}
+
 
 /**
  * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
index a9840c2591293aecdb7ee87677520d319c631632..d4af8620673d2742637be336b3d59433738c49b4 100644 (file)
@@ -82,6 +82,10 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
                                             enum wpa_states old_state);
 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
                                         const struct wps_credential *cred);
+void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
+                                             int depth, const char *subject,
+                                             const char *cert_hash,
+                                             const struct wpabuf *cert);
 
 char * wpas_dbus_decompose_object_path(const char *path, char **network,
                                        char **bssid);
@@ -114,6 +118,14 @@ wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
 {
 }
 
+static inline void
+void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
+                                             int depth, const char *subject,
+                                             const char *cert_hash,
+                                             const struct wpabuf *cert)
+{
+}
+
 static inline int
 wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
 {
index b03c589ebc771be9d84ac24e9be7c7163b43ef60..138c229807e938ffeefc85e1ddb5c4cce8a9ff50 100644 (file)
@@ -555,3 +555,15 @@ void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
        else
                wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr);
 }
+
+
+void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth,
+                              const char *subject, const char *cert_hash,
+                              const struct wpabuf *cert)
+{
+       /* notify the old DBus API */
+       wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
+                                                cert_hash, cert);
+       /* notify the new DBus API */
+       wpas_dbus_signal_certification(wpa_s, depth, subject, cert_hash, cert);
+}
index 766668fc686b1509f75fa6c2e480e369e5205745..98cbcb1b3dca09797c0f333e0c9fc47781f1a7f6 100644 (file)
@@ -119,4 +119,8 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
 void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
                                struct wps_event_fail *fail);
 
+void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth,
+                              const char *subject, const char *cert_hash,
+                              const struct wpabuf *cert);
+
 #endif /* NOTIFY_H */
index 2662eec4654c644a041db211f4985cd1349c87d4..edb947529a91fbf3d16743cf339a0d61f42bf5b0 100644 (file)
@@ -32,6 +32,7 @@
 #include "wps_supplicant.h"
 #include "bss.h"
 #include "scan.h"
+#include "notify.h"
 
 
 #ifndef CONFIG_NO_CONFIG_BLOBS
@@ -611,6 +612,16 @@ static void wpa_supplicant_port_cb(void *ctx, int authorized)
                   authorized ? "Authorized" : "Unauthorized");
        wpa_drv_set_supp_port(wpa_s, authorized);
 }
+
+
+static void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject,
+                                  const char *cert_hash,
+                                  const struct wpabuf *cert)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       wpas_notify_certification(wpa_s, depth, subject, cert_hash, cert);
+}
 #endif /* IEEE8021X_EAPOL */
 
 
@@ -641,6 +652,7 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
        ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
        ctx->port_cb = wpa_supplicant_port_cb;
        ctx->cb = wpa_supplicant_eapol_cb;
+       ctx->cert_cb = wpa_supplicant_cert_cb;
        ctx->cb_ctx = wpa_s;
        wpa_s->eapol = eapol_sm_init(ctx);
        if (wpa_s->eapol == NULL) {