[PATCH v2] Add dbus signal for information about server certification
Dan Williams
dcbw
Wed Jun 29 14:13:00 PDT 2011
On Wed, 2011-06-29 at 14:54 +0800, Michael Chang wrote:
> 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 authenication.
Looking better; two more comments that I apparently missed the first
time.
1) isn't the cert hash a hex string? should that also be a byte array?
what is the "normal form" of the cert hash when it's used in other
programs? Would most clients of wpa_supplicant have to convert the hash
from a hex string to a binary one to use it internally, like eg pass the
hash to OpenSSL if they were to use OpenSSL to parse the certificate
data for some reason?
2) you've already done the work, but I don't know if we care a lot about
the old D-Bus interface; I'd just drop that part were I submitting the
patch, but maybe people can use that functionality.
Dan
> Signed-off-by: Michael Chang <mchang at novell.com>
> ---
> src/eap_peer/eap.c | 8 ++++++
> src/eap_peer/eap.h | 3 ++
> src/eapol_supp/eapol_supp_sm.c | 12 ++++++++-
> src/eapol_supp/eapol_supp_sm.h | 4 +++
> wpa_supplicant/dbus/dbus_new.c | 51 ++++++++++++++++++++++++++++++++++++++++
> wpa_supplicant/dbus/dbus_new.h | 15 +++++++++++
> wpa_supplicant/dbus/dbus_old.c | 48 +++++++++++++++++++++++++++++++++++++
> wpa_supplicant/dbus/dbus_old.h | 16 ++++++++++++
> wpa_supplicant/notify.c | 14 +++++++++++
> wpa_supplicant/notify.h | 6 ++++
> wpa_supplicant/wpas_glue.c | 12 +++++++++
> 11 files changed, 188 insertions(+), 1 deletions(-)
>
> diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
> index 8a9826f..add1e95 100644
> --- a/src/eap_peer/eap.c
> +++ b/src/eap_peer/eap.c
> @@ -1208,6 +1208,14 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
> data->peer_cert.depth,
> 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 ? hash_hex : "",
> + cert_hex ? wpabuf_head(data->peer_cert.cert) : NULL,
> + cert_hex ? wpabuf_len(data->peer_cert.cert) : 0);
> }
> break;
> }
> diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
> index 3550909..d0d7224 100644
> --- a/src/eap_peer/eap.h
> +++ b/src/eap_peer/eap.h
> @@ -221,6 +221,9 @@ struct eapol_callbacks {
> */
> void (*eap_param_needed)(void *ctx, const char *field,
> const char *txt);
> +
> + void (*notify_cert)(void *ctx, int depth, const char *subject,
> + const char *cert_hash, const char *cert_hex, int cert_hex_len);
> };
>
> /**
> diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
> index 18abb4e..89a9a91 100644
> --- a/src/eapol_supp/eapol_supp_sm.c
> +++ b/src/eapol_supp/eapol_supp_sm.c
> @@ -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 char *cert_hex, int cert_hex_len)
> +{
> + struct eapol_sm *sm = ctx;
> + if (sm->ctx->cert_cb)
> + sm->ctx->cert_cb(sm->ctx->ctx, depth, subject,
> + cert_hash, cert_hex, cert_hex_len);
> +}
>
> 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
> };
>
>
> diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
> index 1bdf8cd..a3ce604 100644
> --- a/src/eapol_supp/eapol_supp_sm.h
> +++ b/src/eapol_supp/eapol_supp_sm.h
> @@ -220,6 +220,10 @@ struct eapol_ctx {
> * @authorized: Whether the supplicant port is now in authorized state
> */
> void (*port_cb)(void *ctx, int authorized);
> +
> + void (*cert_cb)(void *ctx, int depth, const char *subject,
> + const char *cert_hash,
> + const char *cert_hex, int cert_hex_len);
> };
>
>
> diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
> index 389afc9..1ee4812 100644
> --- a/wpa_supplicant/dbus/dbus_new.c
> +++ b/wpa_supplicant/dbus/dbus_new.c
> @@ -653,6 +653,51 @@ nomem:
>
> #endif /* CONFIG_WPS */
>
> +void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
> + int depth,
> + const char *subject,
> + const char *cert_hash,
> + const char *cert_hex,
> + int cert_hex_len)
> +{
> + 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) ||
> + !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash))
> + goto nomem;
> +
> + if (cert_hex && cert_hex_len)
> + if (!wpa_dbus_dict_append_byte_array(&dict_iter, "cert_hex", cert_hex, cert_hex_len))
> + 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
>
> /**
> @@ -2641,6 +2686,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 } }
> };
>
> diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
> index 3b0d50c..06acef5 100644
> --- a/wpa_supplicant/dbus/dbus_new.h
> +++ b/wpa_supplicant/dbus/dbus_new.h
> @@ -201,6 +201,12 @@ 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 char *cert_hex,
> + int cert_hex_len);
>
> #else /* CONFIG_CTRL_IFACE_DBUS_NEW */
>
> @@ -443,6 +449,15 @@ 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 char *cert_hex,
> + int cert_hex_len)
> +{
> +}
> +
> #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
>
> #endif /* CTRL_IFACE_DBUS_H_NEW */
> diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
> index 6a00f3e..9a3e488 100644
> --- a/wpa_supplicant/dbus/dbus_old.c
> +++ b/wpa_supplicant/dbus/dbus_old.c
> @@ -549,6 +549,54 @@ 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 char *cert_hex,
> + int cert_hex_len)
> +{
> + struct wpas_dbus_priv *iface;
> + DBusMessage *_signal = NULL;
> +
> + /* 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;
> + }
> +
> + if (!dbus_message_append_args(_signal,
> + DBUS_TYPE_INT32,&depth,
> + DBUS_TYPE_STRING, &subject,
> + DBUS_TYPE_STRING, &cert_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
> diff --git a/wpa_supplicant/dbus/dbus_old.h b/wpa_supplicant/dbus/dbus_old.h
> index a9840c2..dc35253 100644
> --- a/wpa_supplicant/dbus/dbus_old.h
> +++ b/wpa_supplicant/dbus/dbus_old.h
> @@ -82,6 +82,12 @@ 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 char *cert_hex,
> + int cert_hex_len);
>
> char * wpas_dbus_decompose_object_path(const char *path, char **network,
> char **bssid);
> @@ -114,6 +120,16 @@ 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 char *cert_hex,
> + int cert_hex_len)
> +{
> +}
> +
> static inline int
> wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
> {
> diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
> index b03c589..5692d0d 100644
> --- a/wpa_supplicant/notify.c
> +++ b/wpa_supplicant/notify.c
> @@ -202,6 +202,20 @@ void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s)
> #endif /* CONFIG_WPS */
> }
>
> +void wpas_notify_certification(struct wpa_supplicant *wpa_s,
> + int depth,
> + const char *subject,
> + const char *cert_hash,
> + const char *cert_hex,
> + int cert_hex_len)
> +{
> + /* notify the old DBus API */
> + wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
> + cert_hash, cert_hex, cert_hex_len);
> + /* notify the new DBus API */
> + wpas_dbus_signal_certification(wpa_s, depth, subject,
> + cert_hash, cert_hex, cert_hex_len);
> +}
>
> void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
> struct wpa_ssid *ssid)
> diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
> index 766668f..1732841 100644
> --- a/wpa_supplicant/notify.h
> +++ b/wpa_supplicant/notify.h
> @@ -119,4 +119,10 @@ 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 char *cert_hex,
> + int cert_hex_len);
> #endif /* NOTIFY_H */
> diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
> index 2662eec..f8b098d 100644
> --- a/wpa_supplicant/wpas_glue.c
> +++ b/wpa_supplicant/wpas_glue.c
> @@ -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 char *cert_hex, int cert_hex_len)
> +{
> + struct wpa_supplicant *wpa_s = ctx;
> +
> + wpas_notify_certification(wpa_s, depth, subject,
> + cert_hash, cert_hex, cert_hex_len);
> +}
> #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) {
More information about the Hostap
mailing list