wpa_supplicant: Report EAP connection progress to DBus

Send an "EAP" signal via the new DBus interface under various
conditions during EAP authentication:

  - During method selection (ACK and NAK)
  - During certificate verification
  - While sending and receiving TLS alert messages
  - EAP success and failure messages

This provides DBus callers a number of new tools:

  - The ability to probe an AP for available EAP methods
    (given an identity).
  - The ability to identify why the remote certificate was
    not verified.
  - The ability to identify why the remote peer refused
    a TLS connection.

Signed-hostap: Paul Stewart <pstew@chromium.org>
This commit is contained in:
Paul Stewart 2012-06-04 21:10:01 +03:00 committed by Jouni Malinen
parent 24b5bd8b42
commit dd7fec1f29
11 changed files with 156 additions and 3 deletions

View file

@ -21,8 +21,10 @@ struct tls_keys {
};
enum tls_event {
TLS_CERT_CHAIN_SUCCESS,
TLS_CERT_CHAIN_FAILURE,
TLS_PEER_CERTIFICATE
TLS_PEER_CERTIFICATE,
TLS_ALERT
};
/*
@ -57,6 +59,12 @@ union tls_event_data {
const u8 *hash;
size_t hash_len;
} peer_cert;
struct {
int is_local;
const char *type;
const char *description;
} alert;
};
struct tls_config {

View file

@ -525,6 +525,15 @@ static void ssl_info_cb(const SSL *ssl, int where, int ret)
else
conn->write_alerts++;
}
if (tls_global->event_cb != NULL) {
union tls_event_data ev;
os_memset(&ev, 0, sizeof(ev));
ev.alert.is_local = !(where & SSL_CB_READ);
ev.alert.type = SSL_alert_type_string_long(ret);
ev.alert.description = SSL_alert_desc_string_long(ret);
tls_global->event_cb(tls_global->cb_ctx, TLS_ALERT,
&ev);
}
} else if (where & SSL_CB_EXIT && ret <= 0) {
wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
str, ret == 0 ? "failed" : "error",
@ -1265,6 +1274,10 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
TLS_FAIL_SERVER_CHAIN_PROBE);
}
if (preverify_ok && tls_global->event_cb != NULL)
tls_global->event_cb(tls_global->cb_ctx,
TLS_CERT_CHAIN_SUCCESS, NULL);
return preverify_ok;
}

View file

@ -81,6 +81,16 @@ static struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm)
}
static void eap_notify_status(struct eap_sm *sm, const char *status,
const char *parameter)
{
wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)",
status, parameter);
if (sm->eapol_cb->notify_status)
sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
}
static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
{
if (sm->m == NULL || sm->eap_method_priv == NULL)
@ -213,6 +223,7 @@ SM_STATE(EAP, GET_METHOD)
{
int reinit;
EapType method;
const struct eap_method *eap_method;
SM_ENTRY(EAP, GET_METHOD);
@ -221,18 +232,24 @@ SM_STATE(EAP, GET_METHOD)
else
method = sm->reqMethod;
eap_method = eap_peer_get_eap_method(sm->reqVendor, method);
if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed",
sm->reqVendor, method);
wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
"vendor=%u method=%u -> NAK",
sm->reqVendor, method);
eap_notify_status(sm, "refuse proposed method",
eap_method ? eap_method->name : "unknown");
goto nak;
}
wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
"vendor=%u method=%u", sm->reqVendor, method);
eap_notify_status(sm, "accept proposed method",
eap_method ? eap_method->name : "unknown");
/*
* RFC 4137 does not define specific operation for fast
* re-authentication (session resumption). The design here is to allow
@ -256,7 +273,7 @@ SM_STATE(EAP, GET_METHOD)
sm->selectedMethod = sm->reqMethod;
if (sm->m == NULL)
sm->m = eap_peer_get_eap_method(sm->reqVendor, method);
sm->m = eap_method;
if (!sm->m) {
wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: "
"vendor %d method %d",
@ -1235,10 +1252,12 @@ static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
break;
case EAP_CODE_SUCCESS:
wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
eap_notify_status(sm, "completion", "success");
sm->rxSuccess = TRUE;
break;
case EAP_CODE_FAILURE:
wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
eap_notify_status(sm, "completion", "failure");
sm->rxFailure = TRUE;
break;
default:
@ -1256,6 +1275,10 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
char *hash_hex = NULL;
switch (ev) {
case TLS_CERT_CHAIN_SUCCESS:
eap_notify_status(sm, "remote certificate verification",
"success");
break;
case TLS_CERT_CHAIN_FAILURE:
wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR
"reason=%d depth=%d subject='%s' err='%s'",
@ -1263,6 +1286,8 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
data->cert_fail.depth,
data->cert_fail.subject,
data->cert_fail.reason_txt);
eap_notify_status(sm, "remote certificate verification",
data->cert_fail.reason_txt);
break;
case TLS_PEER_CERTIFICATE:
if (!sm->eapol_cb->notify_cert)
@ -1283,6 +1308,14 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
data->peer_cert.subject,
hash_hex, data->peer_cert.cert);
break;
case TLS_ALERT:
if (data->alert.is_local)
eap_notify_status(sm, "local TLS alert",
data->alert.description);
else
eap_notify_status(sm, "remote TLS alert",
data->alert.description);
break;
}
os_free(hash_hex);

View file

@ -226,6 +226,15 @@ struct eapol_callbacks {
*/
void (*notify_cert)(void *ctx, int depth, const char *subject,
const char *cert_hash, const struct wpabuf *cert);
/**
* notify_status - Notification of the current EAP state
* @ctx: eapol_ctx from eap_peer_sm_init() call
* @status: Step in the process of EAP authentication
* @parameter: Step-specific parameter, e.g., EAP method name
*/
void (*notify_status)(void *ctx, const char *status,
const char *parameter);
};
/**

View file

@ -1847,6 +1847,17 @@ static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject,
cert_hash, cert);
}
static void eapol_sm_notify_status(void *ctx, const char *status,
const char *parameter)
{
struct eapol_sm *sm = ctx;
if (sm->ctx->status_cb)
sm->ctx->status_cb(sm->ctx->ctx, status, parameter);
}
static struct eapol_callbacks eapol_cb =
{
eapol_sm_get_config,
@ -1859,7 +1870,8 @@ static struct eapol_callbacks eapol_cb =
eapol_sm_get_config_blob,
eapol_sm_notify_pending,
eapol_sm_eap_param_needed,
eapol_sm_notify_cert
eapol_sm_notify_cert,
eapol_sm_notify_status
};

View file

@ -230,6 +230,15 @@ struct eapol_ctx {
* cert_in_cb - Include server certificates in callback
*/
int cert_in_cb;
/**
* status_cb - Notification of a change in EAP status
* @ctx: Callback context (ctx)
* @status: Step in the process of EAP authentication
* @parameter: Step-specific parameter, e.g., EAP method name
*/
void (*status_cb)(void *ctx, const char *status,
const char *parameter);
};