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:
parent
4b68290e77
commit
469fc3a41f
8 changed files with 91 additions and 2 deletions
|
@ -62,6 +62,8 @@ extern "C" {
|
|||
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
|
||||
/** M2D received */
|
||||
#define WPS_EVENT_M2D "WPS-M2D "
|
||||
/** WPS registration failed after M2/M2D */
|
||||
#define WPS_EVENT_FAIL "WPS-FAIL "
|
||||
|
||||
/* hostapd control interface - fixed message prefixes */
|
||||
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
|
||||
|
|
|
@ -96,7 +96,8 @@ struct wps_registrar_config {
|
|||
|
||||
|
||||
enum wps_event {
|
||||
WPS_EV_M2D
|
||||
WPS_EV_M2D,
|
||||
WPS_EV_FAIL
|
||||
};
|
||||
|
||||
union wps_event_data {
|
||||
|
@ -116,6 +117,9 @@ union wps_event_data {
|
|||
u16 config_error;
|
||||
u16 dev_password_id;
|
||||
} m2d;
|
||||
struct wps_event_fail {
|
||||
int msg; /* enum wps_msg_type */
|
||||
} fail;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -298,3 +298,16 @@ unsigned int wps_generate_pin(void)
|
|||
/* Append checksum digit */
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -947,12 +947,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
|
|||
break;
|
||||
case WPS_M4:
|
||||
ret = wps_process_m4(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M4);
|
||||
break;
|
||||
case WPS_M6:
|
||||
ret = wps_process_m6(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M6);
|
||||
break;
|
||||
case WPS_M8:
|
||||
ret = wps_process_m8(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M8);
|
||||
break;
|
||||
default:
|
||||
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 "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
|
|||
size_t dev_passwd_len);
|
||||
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
||||
size_t encr_len);
|
||||
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg);
|
||||
|
||||
/* wps_attr_parse.c */
|
||||
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
||||
|
|
|
@ -1824,12 +1824,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
|
|||
break;
|
||||
case WPS_M3:
|
||||
ret = wps_process_m3(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M3);
|
||||
break;
|
||||
case WPS_M5:
|
||||
ret = wps_process_m5(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M5);
|
||||
break;
|
||||
case WPS_M7:
|
||||
ret = wps_process_m7(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M7);
|
||||
break;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
struct wps_parse_attr attr;
|
||||
int old_state;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
|
||||
|
||||
old_state = wps->state;
|
||||
wps->state = SEND_WSC_NACK;
|
||||
|
||||
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 "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -2060,6 +2085,7 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
|
|||
u8 op_code,
|
||||
const struct wpabuf *msg)
|
||||
{
|
||||
enum wps_process_res ret;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
|
||||
"op_code=%d)",
|
||||
|
@ -2073,7 +2099,12 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
|
|||
case WSC_NACK:
|
||||
return wps_process_wsc_nack(wps, msg);
|
||||
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:
|
||||
wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
|
||||
return WPS_FAILURE;
|
||||
|
|
|
@ -804,6 +804,8 @@ void WpaGui::processMsg(char *msg)
|
|||
wpsStatusText->setText("Registration started");
|
||||
} else if (str_match(pos, WPS_EVENT_M2D)) {
|
||||
wpsStatusText->setText("Registrar does not yet know PIN");
|
||||
} else if (str_match(pos, WPS_EVENT_FAIL)) {
|
||||
wpsStatusText->setText("Registration failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
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)
|
||||
|
@ -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,
|
||||
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:
|
||||
wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
|
||||
break;
|
||||
case WPS_EV_FAIL:
|
||||
wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue