diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/wpa_ctrl.h | 2 | ||||
-rw-r--r-- | src/wps/wps.h | 6 | ||||
-rw-r--r-- | src/wps/wps_common.c | 13 | ||||
-rw-r--r-- | src/wps/wps_enrollee.c | 24 | ||||
-rw-r--r-- | src/wps/wps_i.h | 1 | ||||
-rw-r--r-- | src/wps/wps_registrar.c | 33 |
6 files changed, 77 insertions, 2 deletions
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 4032db8..b093f28 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -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 " diff --git a/src/wps/wps.h b/src/wps/wps.h index e1026b6..d61db68 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -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; }; /** diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index 7ac3c03..99f6eb9 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -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); +} diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 7fd1b35..18967cd 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -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; } diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h index b661b5d..3ae53b8 100644 --- a/src/wps/wps_i.h +++ b/src/wps/wps_i.h @@ -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); diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index b7a38c2..cd53c74 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -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; |