WPS: Disable AP PIN after 10 consecutive failures
While the exponential increase in the lockout period provides an efficient mitigation mechanism against brute force attacks, this additional trigger to enter indefinite lockout period (cleared by restarting hostapd) will limit attacks even further by giving maximum of 10 attempts (without authorized user action) even in a very long term attack. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
80e8a5eef1
commit
32cdcf15b2
5 changed files with 55 additions and 4 deletions
|
@ -125,6 +125,7 @@ struct hostapd_data {
|
||||||
struct wpabuf *wps_probe_resp_ie;
|
struct wpabuf *wps_probe_resp_ie;
|
||||||
#ifdef CONFIG_WPS
|
#ifdef CONFIG_WPS
|
||||||
unsigned int ap_pin_failures;
|
unsigned int ap_pin_failures;
|
||||||
|
unsigned int ap_pin_failures_consecutive;
|
||||||
struct upnp_wps_device_sm *wps_upnp;
|
struct upnp_wps_device_sm *wps_upnp;
|
||||||
unsigned int ap_pin_lockout_time;
|
unsigned int ap_pin_lockout_time;
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
|
@ -512,6 +512,8 @@ static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
|
||||||
|
|
||||||
if (hapd->conf->ap_setup_locked)
|
if (hapd->conf->ap_setup_locked)
|
||||||
return;
|
return;
|
||||||
|
if (hapd->ap_pin_failures_consecutive >= 10)
|
||||||
|
return;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
|
wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
|
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
|
||||||
|
@ -533,8 +535,10 @@ static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
|
||||||
* force attacks.
|
* force attacks.
|
||||||
*/
|
*/
|
||||||
hapd->ap_pin_failures++;
|
hapd->ap_pin_failures++;
|
||||||
wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
|
hapd->ap_pin_failures_consecutive++;
|
||||||
hapd->ap_pin_failures);
|
wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u "
|
||||||
|
"(%u consecutive)",
|
||||||
|
hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
|
||||||
if (hapd->ap_pin_failures < 3)
|
if (hapd->ap_pin_failures < 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -543,7 +547,15 @@ static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
|
||||||
|
|
||||||
wps_registrar_update_ie(hapd->wps->registrar);
|
wps_registrar_update_ie(hapd->wps->registrar);
|
||||||
|
|
||||||
if (!hapd->conf->ap_setup_locked) {
|
if (!hapd->conf->ap_setup_locked &&
|
||||||
|
hapd->ap_pin_failures_consecutive >= 10) {
|
||||||
|
/*
|
||||||
|
* In indefinite lockdown - disable automatic AP PIN
|
||||||
|
* reenablement.
|
||||||
|
*/
|
||||||
|
eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
|
||||||
|
} else if (!hapd->conf->ap_setup_locked) {
|
||||||
if (hapd->ap_pin_lockout_time == 0)
|
if (hapd->ap_pin_lockout_time == 0)
|
||||||
hapd->ap_pin_lockout_time = 60;
|
hapd->ap_pin_lockout_time = 60;
|
||||||
else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
|
else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
|
||||||
|
@ -569,6 +581,29 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
|
||||||
|
{
|
||||||
|
if (hapd->conf->ap_pin == NULL || hapd->wps == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (hapd->ap_pin_failures_consecutive == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: Clear consecutive AP PIN failure counter "
|
||||||
|
"- total validation failures %u (%u consecutive)",
|
||||||
|
hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
|
||||||
|
hapd->ap_pin_failures_consecutive = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
hostapd_wps_for_each(hapd, wps_ap_pin_success, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
|
static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
|
||||||
"No Error", /* WPS_EI_NO_ERROR */
|
"No Error", /* WPS_EI_NO_ERROR */
|
||||||
"TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
|
"TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
|
||||||
|
@ -628,6 +663,9 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||||
break;
|
break;
|
||||||
case WPS_EV_ER_SET_SELECTED_REGISTRAR:
|
case WPS_EV_ER_SET_SELECTED_REGISTRAR:
|
||||||
break;
|
break;
|
||||||
|
case WPS_EV_AP_PIN_SUCCESS:
|
||||||
|
hostapd_wps_ap_pin_success(hapd);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (hapd->wps_event_cb)
|
if (hapd->wps_event_cb)
|
||||||
hapd->wps_event_cb(hapd->wps_event_cb_ctx, event, data);
|
hapd->wps_event_cb(hapd->wps_event_cb_ctx, event, data);
|
||||||
|
@ -1293,6 +1331,7 @@ static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
|
wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
|
||||||
hapd->ap_pin_failures = 0;
|
hapd->ap_pin_failures = 0;
|
||||||
|
hapd->ap_pin_failures_consecutive = 0;
|
||||||
hapd->conf->ap_setup_locked = 0;
|
hapd->conf->ap_setup_locked = 0;
|
||||||
if (hapd->wps->ap_setup_locked) {
|
if (hapd->wps->ap_setup_locked) {
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
|
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
|
||||||
|
|
|
@ -457,7 +457,12 @@ enum wps_event {
|
||||||
/**
|
/**
|
||||||
* WPS_EV_ER_SET_SELECTED_REGISTRAR - ER: SetSelectedRegistrar event
|
* WPS_EV_ER_SET_SELECTED_REGISTRAR - ER: SetSelectedRegistrar event
|
||||||
*/
|
*/
|
||||||
WPS_EV_ER_SET_SELECTED_REGISTRAR
|
WPS_EV_ER_SET_SELECTED_REGISTRAR,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPS_EV_AP_PIN_SUCCESS - External Registrar used correct AP PIN
|
||||||
|
*/
|
||||||
|
WPS_EV_AP_PIN_SUCCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1064,6 +1064,10 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps,
|
||||||
}
|
}
|
||||||
wpabuf_free(decrypted);
|
wpabuf_free(decrypted);
|
||||||
|
|
||||||
|
if (wps->wps->ap)
|
||||||
|
wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
|
||||||
|
NULL);
|
||||||
|
|
||||||
wps->state = SEND_M7;
|
wps->state = SEND_M7;
|
||||||
return WPS_CONTINUE;
|
return WPS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,6 +664,8 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
|
||||||
wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
|
wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
|
||||||
&data->set_sel_reg);
|
&data->set_sel_reg);
|
||||||
break;
|
break;
|
||||||
|
case WPS_EV_AP_PIN_SUCCESS:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue