Add dbus signal for information about server certification

In general, this patch attemps to extend commit
00468b4650 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>
This commit is contained in:
Michael Chang 2011-07-05 12:22:32 +03:00 committed by Jouni Malinen
parent a3e685a04b
commit ade74830b4
11 changed files with 199 additions and 1 deletions

View file

@ -1209,6 +1209,13 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
data->peer_cert.subject, data->peer_cert.subject,
cert_hex); 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; break;
} }

View file

@ -221,6 +221,17 @@ struct eapol_callbacks {
*/ */
void (*eap_param_needed)(void *ctx, const char *field, void (*eap_param_needed)(void *ctx, const char *field,
const char *txt); 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);
}; };
/** /**

View file

@ -1825,6 +1825,15 @@ static void eapol_sm_eap_param_needed(void *ctx, const char *field,
#define eapol_sm_eap_param_needed NULL #define eapol_sm_eap_param_needed NULL
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ #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 = static struct eapol_callbacks eapol_cb =
{ {
@ -1837,7 +1846,8 @@ static struct eapol_callbacks eapol_cb =
eapol_sm_set_config_blob, eapol_sm_set_config_blob,
eapol_sm_get_config_blob, eapol_sm_get_config_blob,
eapol_sm_notify_pending, eapol_sm_notify_pending,
eapol_sm_eap_param_needed eapol_sm_eap_param_needed,
eapol_sm_notify_cert
}; };

View file

@ -220,6 +220,17 @@ struct eapol_ctx {
* @authorized: Whether the supplicant port is now in authorized state * @authorized: Whether the supplicant port is now in authorized state
*/ */
void (*port_cb)(void *ctx, int authorized); 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);
}; };

View file

@ -653,6 +653,54 @@ nomem:
#endif /* CONFIG_WPS */ #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 #ifdef CONFIG_P2P
/** /**
@ -2647,6 +2695,12 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
} }
}, },
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
{
{ "certification", "a{sv}", ARG_OUT },
END_ARGS
}
},
{ NULL, NULL, { END_ARGS } } { NULL, NULL, { END_ARGS } }
}; };

View file

@ -201,6 +201,10 @@ void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
const u8 *member); const u8 *member);
void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s, void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail); 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 */ #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 /* CONFIG_CTRL_IFACE_DBUS_NEW */
#endif /* CTRL_IFACE_DBUS_H_NEW */ #endif /* CTRL_IFACE_DBUS_H_NEW */

View file

@ -549,6 +549,59 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
} }
#endif /* CONFIG_WPS */ #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 * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface

View file

@ -82,6 +82,10 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
enum wpa_states old_state); enum wpa_states old_state);
void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
const struct wps_credential *cred); 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 * wpas_dbus_decompose_object_path(const char *path, char **network,
char **bssid); 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 static inline int
wpas_dbus_register_iface(struct wpa_supplicant *wpa_s) wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
{ {

View file

@ -555,3 +555,15 @@ void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
else else
wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr); 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);
}

View 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, void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail); 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 */ #endif /* NOTIFY_H */

View file

@ -32,6 +32,7 @@
#include "wps_supplicant.h" #include "wps_supplicant.h"
#include "bss.h" #include "bss.h"
#include "scan.h" #include "scan.h"
#include "notify.h"
#ifndef CONFIG_NO_CONFIG_BLOBS #ifndef CONFIG_NO_CONFIG_BLOBS
@ -611,6 +612,16 @@ static void wpa_supplicant_port_cb(void *ctx, int authorized)
authorized ? "Authorized" : "Unauthorized"); authorized ? "Authorized" : "Unauthorized");
wpa_drv_set_supp_port(wpa_s, authorized); 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 */ #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->eap_param_needed = wpa_supplicant_eap_param_needed;
ctx->port_cb = wpa_supplicant_port_cb; ctx->port_cb = wpa_supplicant_port_cb;
ctx->cb = wpa_supplicant_eapol_cb; ctx->cb = wpa_supplicant_eapol_cb;
ctx->cert_cb = wpa_supplicant_cert_cb;
ctx->cb_ctx = wpa_s; ctx->cb_ctx = wpa_s;
wpa_s->eapol = eapol_sm_init(ctx); wpa_s->eapol = eapol_sm_init(ctx);
if (wpa_s->eapol == NULL) { if (wpa_s->eapol == NULL) {