WPS: Added callback for failure-after-M2/M2D

This callback is now used to stop wpa_supplicant from trying to continue
using parameters (most likely, device password) that do not work in a
loop. In addition, wpa_gui can now notify user of failed registration.
This commit is contained in:
Jouni Malinen 2008-12-19 22:19:41 +02:00
parent 4b68290e77
commit 469fc3a41f
8 changed files with 91 additions and 2 deletions

View file

@ -62,6 +62,8 @@ extern "C" {
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED " #define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
/** M2D received */ /** M2D received */
#define WPS_EVENT_M2D "WPS-M2D " #define WPS_EVENT_M2D "WPS-M2D "
/** WPS registration failed after M2/M2D */
#define WPS_EVENT_FAIL "WPS-FAIL "
/* hostapd control interface - fixed message prefixes */ /* hostapd control interface - fixed message prefixes */
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED " #define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "

View file

@ -96,7 +96,8 @@ struct wps_registrar_config {
enum wps_event { enum wps_event {
WPS_EV_M2D WPS_EV_M2D,
WPS_EV_FAIL
}; };
union wps_event_data { union wps_event_data {
@ -116,6 +117,9 @@ union wps_event_data {
u16 config_error; u16 config_error;
u16 dev_password_id; u16 dev_password_id;
} m2d; } m2d;
struct wps_event_fail {
int msg; /* enum wps_msg_type */
} fail;
}; };
/** /**

View file

@ -298,3 +298,16 @@ unsigned int wps_generate_pin(void)
/* Append checksum digit */ /* Append checksum digit */
return val * 10 + wps_pin_checksum(val); return val * 10 + wps_pin_checksum(val);
} }
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg)
{
union wps_event_data data;
if (wps->event_cb == NULL)
return;
os_memset(&data, 0, sizeof(data));
data.fail.msg = msg;
wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
}

View file

@ -947,12 +947,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
break; break;
case WPS_M4: case WPS_M4:
ret = wps_process_m4(wps, msg, &attr); ret = wps_process_m4(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M4);
break; break;
case WPS_M6: case WPS_M6:
ret = wps_process_m6(wps, msg, &attr); ret = wps_process_m6(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M6);
break; break;
case WPS_M8: case WPS_M8:
ret = wps_process_m8(wps, msg, &attr); ret = wps_process_m8(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M8);
break; break;
default: default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@ -1079,6 +1085,24 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with " wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
"Configuration Error %d", WPA_GET_BE16(attr.config_error)); "Configuration Error %d", WPA_GET_BE16(attr.config_error));
switch (wps->state) {
case RECV_M4:
wps_fail_event(wps->wps, WPS_M3);
break;
case RECV_M6:
wps_fail_event(wps->wps, WPS_M5);
break;
case RECV_M8:
wps_fail_event(wps->wps, WPS_M7);
break;
default:
break;
}
/* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
* Enrollee is Authenticator */
wps->state = SEND_WSC_NACK;
return WPS_FAILURE; return WPS_FAILURE;
} }

View file

@ -165,6 +165,7 @@ void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
size_t dev_passwd_len); size_t dev_passwd_len);
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr, struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
size_t encr_len); size_t encr_len);
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg);
/* wps_attr_parse.c */ /* wps_attr_parse.c */
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr); int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);

View file

@ -1824,12 +1824,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
break; break;
case WPS_M3: case WPS_M3:
ret = wps_process_m3(wps, msg, &attr); ret = wps_process_m3(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M3);
break; break;
case WPS_M5: case WPS_M5:
ret = wps_process_m5(wps, msg, &attr); ret = wps_process_m5(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M5);
break; break;
case WPS_M7: case WPS_M7:
ret = wps_process_m7(wps, msg, &attr); ret = wps_process_m7(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M7);
break; break;
default: default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@ -1904,9 +1910,11 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
const struct wpabuf *msg) const struct wpabuf *msg)
{ {
struct wps_parse_attr attr; struct wps_parse_attr attr;
int old_state;
wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK"); wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
old_state = wps->state;
wps->state = SEND_WSC_NACK; wps->state = SEND_WSC_NACK;
if (wps_parse_msg(msg, &attr) < 0) if (wps_parse_msg(msg, &attr) < 0)
@ -1951,6 +1959,23 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with " wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
"Configuration Error %d", WPA_GET_BE16(attr.config_error)); "Configuration Error %d", WPA_GET_BE16(attr.config_error));
switch (old_state) {
case RECV_M3:
wps_fail_event(wps->wps, WPS_M2);
break;
case RECV_M5:
wps_fail_event(wps->wps, WPS_M4);
break;
case RECV_M7:
wps_fail_event(wps->wps, WPS_M6);
break;
case RECV_DONE:
wps_fail_event(wps->wps, WPS_M8);
break;
default:
break;
}
return WPS_FAILURE; return WPS_FAILURE;
} }
@ -2060,6 +2085,7 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
u8 op_code, u8 op_code,
const struct wpabuf *msg) const struct wpabuf *msg)
{ {
enum wps_process_res ret;
wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu " wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
"op_code=%d)", "op_code=%d)",
@ -2073,7 +2099,12 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
case WSC_NACK: case WSC_NACK:
return wps_process_wsc_nack(wps, msg); return wps_process_wsc_nack(wps, msg);
case WSC_Done: case WSC_Done:
return wps_process_wsc_done(wps, msg); ret = wps_process_wsc_done(wps, msg);
if (ret == WPS_FAILURE) {
wps->state = SEND_WSC_NACK;
wps_fail_event(wps->wps, WPS_WSC_DONE);
}
return ret;
default: default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code); wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
return WPS_FAILURE; return WPS_FAILURE;

View file

@ -804,6 +804,8 @@ void WpaGui::processMsg(char *msg)
wpsStatusText->setText("Registration started"); wpsStatusText->setText("Registration started");
} else if (str_match(pos, WPS_EVENT_M2D)) { } else if (str_match(pos, WPS_EVENT_M2D)) {
wpsStatusText->setText("Registrar does not yet know PIN"); wpsStatusText->setText("Registrar does not yet know PIN");
} else if (str_match(pos, WPS_EVENT_FAIL)) {
wpsStatusText->setText("Registration failed");
} }
} }

View file

@ -29,6 +29,7 @@
static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx); static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
@ -189,6 +190,14 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
} }
static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail)
{
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d", fail->msg);
wpas_clear_wps(wpa_s);
}
static void wpa_supplicant_wps_event(void *ctx, enum wps_event event, static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
union wps_event_data *data) union wps_event_data *data)
{ {
@ -197,6 +206,9 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
case WPS_EV_M2D: case WPS_EV_M2D:
wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d); wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
break; break;
case WPS_EV_FAIL:
wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
break;
} }
} }