aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-08-24 12:24:05 (GMT)
committerJouni Malinen <j@w1.fi>2010-09-05 14:31:01 (GMT)
commitcf375f646e364d2da0c66bb42898ed98e65060d1 (patch)
treed5dc04af9e6ad3104167e3c68f3000453809458b
parentd52f4054d05973cb2131e9222f20f8b08dcdb8b4 (diff)
downloadhostap-07-cf375f646e364d2da0c66bb42898ed98e65060d1.zip
hostap-07-cf375f646e364d2da0c66bb42898ed98e65060d1.tar.gz
hostap-07-cf375f646e364d2da0c66bb42898ed98e65060d1.tar.bz2
WPS: Do not disable AP PIN permanently, only slow down attacks
As a compromise between usability and security, do not disable AP PIN permanently based on failed PIN validations. Instead, go to AP Setup Locked state for increasing amount of time between each failure to slow down brute force attacks against the AP PIN. This avoids problems with some external Registrars that may try to use the same PIN multiple times without user input. Now, the user will still be able to fix the PIN and try again later while a real attack is delayed enough to make it impractical. (cherry picked from commit 944814106ec9c9f502ce4329783dd47c6f3d5fbd)
-rw-r--r--src/ap/hostapd.h1
-rw-r--r--src/ap/wps_hostapd.c54
-rw-r--r--src/common/wpa_ctrl.h1
3 files changed, 37 insertions, 19 deletions
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 5bf4040..d0d67c8 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -167,6 +167,7 @@ struct hostapd_data {
#ifdef CONFIG_WPS
unsigned int ap_pin_failures;
struct upnp_wps_device_sm *wps_upnp;
+ unsigned int ap_pin_lockout_time;
#endif /* CONFIG_WPS */
struct hostapd_probereq_cb *probereq_cb;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index c63b7fc..d0e7e0a 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -421,20 +421,36 @@ static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred)
}
+static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
+{
+ struct hostapd_data *hapd = eloop_data;
+
+ if (hapd->conf->ap_setup_locked)
+ return;
+
+ wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
+ wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
+ hapd->wps->ap_setup_locked = 0;
+ wps_registrar_update_ie(hapd->wps->registrar);
+
+}
+
+
static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
struct wps_event_pwd_auth_fail *data)
{
- FILE *f;
-
if (!data->enrollee || hapd->conf->ap_pin == NULL)
return;
/*
* Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
- * if this happens multiple times.
+ * for some time if this happens multiple times to slow down brute
+ * force attacks.
*/
hapd->ap_pin_failures++;
- if (hapd->ap_pin_failures < 4)
+ wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
+ hapd->ap_pin_failures);
+ if (hapd->ap_pin_failures < 3)
return;
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
@@ -442,23 +458,22 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
wps_registrar_update_ie(hapd->wps->registrar);
- if (hapd->conf->wps_cred_processing == 1)
- return;
-
- f = fopen(hapd->iface->config_fname, "a");
- if (f == NULL) {
- wpa_printf(MSG_WARNING, "WPS: Could not append to the current "
- "configuration file");
- return;
+ if (!hapd->conf->ap_setup_locked) {
+ if (hapd->ap_pin_lockout_time == 0)
+ hapd->ap_pin_lockout_time = 60;
+ else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
+ (hapd->ap_pin_failures % 3) == 0)
+ hapd->ap_pin_lockout_time *= 2;
+
+ wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN for %u seconds",
+ hapd->ap_pin_lockout_time);
+ eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+ eloop_register_timeout(hapd->ap_pin_lockout_time, 0,
+ hostapd_wps_reenable_ap_pin, hapd,
+ NULL);
}
- fprintf(f, "# WPS AP Setup Locked based on possible attack\n");
- fprintf(f, "ap_setup_locked=1\n");
- fclose(f);
-
- /* TODO: dualband AP may need to update multiple configuration files */
-
- wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");
+ /* TODO: dualband AP may need to update other interfaces */
}
@@ -667,6 +682,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
void hostapd_deinit_wps(struct hostapd_data *hapd)
{
+ eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
if (hapd->wps == NULL)
return;
#ifdef CONFIG_WPS_UPNP
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 95f7db7..19457b8 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -92,6 +92,7 @@ extern "C" {
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
#define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED "
+#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
#define AP_STA_CONNECTED "AP-STA-CONNECTED "
#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "