WPS: Add mechanism for indicating non-standard WPS errors
Previously, only the Configuration Error values were indicated in WPS-FAIL events. Since those values are defined in the specification it is not feasible to extend them for indicating other errors. Add a new error indication value that is internal to wpa_supplicant and hostapd to allow other errors to be indicated. Use the new mechanism to indicate if negotiation fails because of WEP or TKIP-only configurations being disallows by WPS 2.0.
This commit is contained in:
parent
e24cf97c0d
commit
c5cf0a18f1
8 changed files with 88 additions and 24 deletions
|
@ -535,13 +535,27 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
|
||||
"No Error", /* WPS_EI_NO_ERROR */
|
||||
"TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
|
||||
"WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
|
||||
};
|
||||
|
||||
static void hostapd_wps_event_fail(struct hostapd_data *hapd,
|
||||
struct wps_event_fail *fail)
|
||||
{
|
||||
if (fail->error_indication > 0 &&
|
||||
fail->error_indication < NUM_WPS_EI_VALUES) {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
|
||||
fail->msg, fail->config_error, fail->error_indication,
|
||||
wps_event_fail_reason[fail->error_indication]);
|
||||
} else {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d",
|
||||
fail->msg, fail->config_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
|
|
|
@ -456,6 +456,7 @@ union wps_event_data {
|
|||
struct wps_event_fail {
|
||||
int msg;
|
||||
u16 config_error;
|
||||
u16 error_indication;
|
||||
} fail;
|
||||
|
||||
struct wps_event_pwd_auth_fail {
|
||||
|
|
|
@ -257,7 +257,7 @@ unsigned int wps_generate_pin(void)
|
|||
|
||||
|
||||
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
|
||||
u16 config_error)
|
||||
u16 config_error, u16 error_indication)
|
||||
{
|
||||
union wps_event_data data;
|
||||
|
||||
|
@ -267,6 +267,7 @@ void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
|
|||
os_memset(&data, 0, sizeof(data));
|
||||
data.fail.msg = msg;
|
||||
data.fail.config_error = config_error;
|
||||
data.fail.error_indication = error_indication;
|
||||
wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
|
||||
}
|
||||
|
||||
|
|
|
@ -224,6 +224,14 @@ enum wps_config_error {
|
|||
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
|
||||
};
|
||||
|
||||
/* Vendor specific Error Indication for WPS event messages */
|
||||
enum wps_error_indication {
|
||||
WPS_EI_NO_ERROR,
|
||||
WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
|
||||
WPS_EI_SECURITY_WEP_PROHIBITED,
|
||||
NUM_WPS_EI_VALUES
|
||||
};
|
||||
|
||||
/* RF Bands */
|
||||
#define WPS_RF_24GHZ 0x01
|
||||
#define WPS_RF_50GHZ 0x02
|
||||
|
|
|
@ -672,6 +672,7 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
|
|||
if (wps->cred.encr_type & WPS_ENCR_WEP) {
|
||||
wpa_printf(MSG_INFO, "WPS: Reject Credential "
|
||||
"due to WEP configuration");
|
||||
wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -772,6 +773,7 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
|
|||
if (cred.encr_type & WPS_ENCR_WEP) {
|
||||
wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
|
||||
"due to WEP configuration");
|
||||
wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -789,6 +791,8 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
|
|||
WPS_AUTH_WPAPSK) {
|
||||
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
|
||||
"AP Settings: WPA-Personal/TKIP only");
|
||||
wps->error_indication =
|
||||
WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1140,21 +1144,24 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
|
|||
return WPS_FAILURE;
|
||||
ret = wps_process_m4(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M4, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M4, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case WPS_M6:
|
||||
if (wps_validate_m6(msg) < 0)
|
||||
return WPS_FAILURE;
|
||||
ret = wps_process_m6(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M6, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M6, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case WPS_M8:
|
||||
if (wps_validate_m8(msg) < 0)
|
||||
return WPS_FAILURE;
|
||||
ret = wps_process_m8(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M8, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M8, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
|
||||
|
@ -1281,13 +1288,16 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
|
|||
|
||||
switch (wps->state) {
|
||||
case RECV_M4:
|
||||
wps_fail_event(wps->wps, WPS_M3, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M3, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case RECV_M6:
|
||||
wps_fail_event(wps->wps, WPS_M5, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M5, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case RECV_M8:
|
||||
wps_fail_event(wps->wps, WPS_M7, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M7, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -102,6 +102,7 @@ struct wps_data {
|
|||
* config_error - Configuration Error value to be used in NACK
|
||||
*/
|
||||
u16 config_error;
|
||||
u16 error_indication;
|
||||
|
||||
int ext_reg;
|
||||
int int_reg;
|
||||
|
@ -213,7 +214,7 @@ void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
|
|||
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,
|
||||
u16 config_error);
|
||||
u16 config_error, u16 error_indication);
|
||||
void wps_success_event(struct wps_context *wps);
|
||||
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
|
||||
void wps_pbc_overlap_event(struct wps_context *wps);
|
||||
|
|
|
@ -2597,21 +2597,24 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
|
|||
return WPS_FAILURE;
|
||||
ret = wps_process_m3(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M3, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M3, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case WPS_M5:
|
||||
if (wps_validate_m5(msg) < 0)
|
||||
return WPS_FAILURE;
|
||||
ret = wps_process_m5(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M5, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M5, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case WPS_M7:
|
||||
if (wps_validate_m7(msg) < 0)
|
||||
return WPS_FAILURE;
|
||||
ret = wps_process_m7(wps, msg, &attr);
|
||||
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
|
||||
wps_fail_event(wps->wps, WPS_M7, wps->config_error);
|
||||
wps_fail_event(wps->wps, WPS_M7, wps->config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
|
||||
|
@ -2756,16 +2759,20 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
|
|||
|
||||
switch (old_state) {
|
||||
case RECV_M3:
|
||||
wps_fail_event(wps->wps, WPS_M2, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M2, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case RECV_M5:
|
||||
wps_fail_event(wps->wps, WPS_M4, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M4, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case RECV_M7:
|
||||
wps_fail_event(wps->wps, WPS_M6, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M6, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
case RECV_DONE:
|
||||
wps_fail_event(wps->wps, WPS_M8, config_error);
|
||||
wps_fail_event(wps->wps, WPS_M8, config_error,
|
||||
wps->error_indication);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2949,7 +2956,8 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
|
|||
if (ret == WPS_FAILURE) {
|
||||
wps->state = SEND_WSC_NACK;
|
||||
wps_fail_event(wps->wps, WPS_WSC_DONE,
|
||||
wps->config_error);
|
||||
wps->config_error,
|
||||
wps->error_indication);
|
||||
}
|
||||
return ret;
|
||||
default:
|
||||
|
|
|
@ -410,15 +410,36 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
|
||||
"No Error", /* WPS_EI_NO_ERROR */
|
||||
"TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
|
||||
"WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
|
||||
};
|
||||
|
||||
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 config_error=%d",
|
||||
if (fail->error_indication > 0 &&
|
||||
fail->error_indication < NUM_WPS_EI_VALUES) {
|
||||
wpa_msg(wpa_s, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
|
||||
fail->msg, fail->config_error, fail->error_indication,
|
||||
wps_event_fail_reason[fail->error_indication]);
|
||||
if (wpa_s->parent && wpa_s->parent != wpa_s)
|
||||
wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
|
||||
"msg=%d config_error=%d reason=%d (%s)",
|
||||
fail->msg, fail->config_error,
|
||||
fail->error_indication,
|
||||
wps_event_fail_reason[fail->error_indication]);
|
||||
} else {
|
||||
wpa_msg(wpa_s, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d",
|
||||
fail->msg, fail->config_error);
|
||||
if (wpa_s->parent && wpa_s->parent != wpa_s)
|
||||
wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
|
||||
"msg=%d config_error=%d",
|
||||
fail->msg, fail->config_error);
|
||||
}
|
||||
wpas_clear_wps(wpa_s);
|
||||
wpas_notify_wps_event_fail(wpa_s, fail);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue