mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-20 08:39:05 +00:00
WiFi: Add WPS softAP registrar example and events
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "wpa_auth.h"
|
||||
#include "ap_config.h"
|
||||
#include "sta_info.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx);
|
||||
void hostapd_wps_eap_completed(struct hostapd_data *hapd);
|
||||
@@ -167,7 +168,6 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
|
||||
|
||||
static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = eloop_ctx;
|
||||
struct sta_info *sta = timeout_ctx;
|
||||
u16 reason;
|
||||
|
||||
@@ -177,14 +177,21 @@ static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx)
|
||||
|
||||
reason = WLAN_REASON_IEEE_802_1X_AUTH_FAILED;
|
||||
esp_wifi_ap_deauth_internal(sta->addr, reason);
|
||||
if (sta->flags & WLAN_STA_WPS)
|
||||
hostapd_wps_eap_completed(hapd);
|
||||
}
|
||||
|
||||
|
||||
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
#ifdef ESP_SUPPLICANT
|
||||
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
|
||||
"IEEE 802.1X: Scheduled disconnection of " MACSTR
|
||||
" after EAP-Failure", MAC2STR(sta->addr));
|
||||
|
||||
esp_wifi_ap_deauth_internal(sta->addr, WLAN_REASON_IEEE_802_1X_AUTH_FAILED);
|
||||
if (wps_get_status() == WPS_STATUS_PENDING)
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
#else
|
||||
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
|
||||
"IEEE 802.1X: Force disconnection of " MACSTR
|
||||
" after EAP-Failure in 10 ms", MAC2STR(sta->addr));
|
||||
@@ -197,6 +204,7 @@ void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
|
||||
eloop_cancel_timeout(ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
|
||||
eloop_register_timeout(0, 10000, ap_sta_delayed_1x_auth_fail_cb,
|
||||
hapd, sta);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpas_glue.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
#define STATE_MACHINE_DATA struct wpa_state_machine
|
||||
#define STATE_MACHINE_DEBUG_PREFIX "WPA"
|
||||
@@ -2375,13 +2376,42 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS_REGISTRAR
|
||||
static void ap_free_sta_timeout(void *ctx, void *data)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *) ctx;
|
||||
u8 *addr = (u8 *) data;
|
||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||
|
||||
if (sta) {
|
||||
ap_free_sta(hapd, sta);
|
||||
}
|
||||
|
||||
os_free(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wpa_ap_remove(void* sta_info)
|
||||
{
|
||||
struct hostapd_data *hapd = hostapd_get_hapd_data();
|
||||
|
||||
if (!sta_info || !hapd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS_REGISTRAR
|
||||
wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status());
|
||||
if (wps_get_status() == WPS_STATUS_PENDING) {
|
||||
struct sta_info *sta = (struct sta_info *)sta_info;
|
||||
u8 *addr = os_malloc(ETH_ALEN);
|
||||
|
||||
if (!addr) {
|
||||
return false;
|
||||
}
|
||||
os_memcpy(addr, sta->addr, ETH_ALEN);
|
||||
eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr);
|
||||
} else
|
||||
#endif
|
||||
ap_free_sta(hapd, sta_info);
|
||||
|
||||
return true;
|
||||
|
@@ -90,7 +90,6 @@ static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
|
||||
data.dev_pw = dev_pw;
|
||||
data.dev_pw_len = dev_pw_len;
|
||||
wps_stop_registrar(hapd, &data);
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
|
||||
/* TODO add callback event for freeRTOS */
|
||||
}
|
||||
@@ -111,68 +110,20 @@ static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
|
||||
wps_registrar_update_ie(hapd->wps->registrar);
|
||||
}
|
||||
|
||||
|
||||
static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
|
||||
{
|
||||
struct wps_event_pwd_auth_fail *data = ctx;
|
||||
|
||||
if (!data->enrollee || hapd->conf->ap_pin == NULL || hapd->wps == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
|
||||
* for some time if this happens multiple times to slow down brute
|
||||
* force attacks.
|
||||
*/
|
||||
hapd->ap_pin_failures++;
|
||||
hapd->ap_pin_failures_consecutive++;
|
||||
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)
|
||||
return 0;
|
||||
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
|
||||
hapd->wps->ap_setup_locked = 1;
|
||||
|
||||
wps_registrar_update_ie(hapd->wps->registrar);
|
||||
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
|
||||
struct wps_event_pwd_auth_fail *data)
|
||||
{
|
||||
/* Update WPS Status - Authentication Failure */
|
||||
wifi_event_ap_wps_rg_fail_reason_t evt = {0};
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: Authentication failure update");
|
||||
hapd->wps_stats.status = WPS_FAILURE_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, data->peer_macaddr, ETH_ALEN);
|
||||
|
||||
wps_pwd_auth_fail(hapd, data);
|
||||
os_memcpy(evt.peer_macaddr, data->peer_macaddr, ETH_ALEN);
|
||||
evt.reason = WPS_AP_FAIL_REASON_AUTH;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@@ -193,16 +144,12 @@ static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd)
|
||||
{
|
||||
wps_ap_pin_success(hapd, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_overlap(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS Status - PBC Overlap */
|
||||
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_OVERLAP;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@@ -210,16 +157,14 @@ static void hostapd_wps_event_pbc_timeout(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC Status:PBC Timeout */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_TIMEOUT;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_active(struct hostapd_data *hapd)
|
||||
static void hostapd_wps_event_pin_timeout(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC status - Active */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_ACTIVE;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC status - Active */
|
||||
@@ -230,31 +175,25 @@ static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
|
||||
static void hostapd_wps_event_success(struct hostapd_data *hapd,
|
||||
struct wps_event_success *success)
|
||||
{
|
||||
/* Update WPS status - Success */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE;
|
||||
hapd->wps_stats.status = WPS_SUCCESS_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, success->peer_macaddr, ETH_ALEN);
|
||||
wifi_event_ap_wps_rg_success_t evt;
|
||||
|
||||
os_memcpy(evt.peer_macaddr, success->peer_macaddr, ETH_ALEN);
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_SUCCESS, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_fail(struct hostapd_data *hapd,
|
||||
struct wps_event_fail *fail)
|
||||
{
|
||||
/* Update WPS status - Failure */
|
||||
hapd->wps_stats.status = WPS_FAILURE_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, fail->peer_macaddr, ETH_ALEN);
|
||||
|
||||
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_ei_str(fail->error_indication));
|
||||
} else {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d",
|
||||
fail->msg, fail->config_error);
|
||||
}
|
||||
wifi_event_ap_wps_rg_fail_reason_t evt;
|
||||
if (fail->config_error > WPS_CFG_NO_ERROR)
|
||||
evt.reason = WPS_AP_FAIL_REASON_CONFIG;
|
||||
else
|
||||
evt.reason = WPS_AP_FAIL_REASON_NORMAL;
|
||||
os_memcpy(evt.peer_macaddr, fail->peer_macaddr, ETH_ALEN);
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@@ -264,9 +203,6 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
struct hostapd_data *hapd = ctx;
|
||||
|
||||
switch (event) {
|
||||
case WPS_EV_M2D:
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_M2D);
|
||||
break;
|
||||
case WPS_EV_FAIL:
|
||||
hostapd_wps_event_fail(hapd, &data->fail);
|
||||
break;
|
||||
@@ -285,8 +221,9 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
hostapd_wps_event_pbc_timeout(hapd);
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_TIMEOUT);
|
||||
break;
|
||||
case WPS_EV_SELECTED_REGISTRAR_TIMEOUT:
|
||||
hostapd_wps_event_pin_timeout(hapd);
|
||||
case WPS_EV_PBC_ACTIVE:
|
||||
hostapd_wps_event_pbc_active(hapd);
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ACTIVE);
|
||||
break;
|
||||
case WPS_EV_PBC_DISABLE:
|
||||
@@ -306,7 +243,9 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
case WPS_EV_ER_SET_SELECTED_REGISTRAR:
|
||||
break;
|
||||
case WPS_EV_AP_PIN_SUCCESS:
|
||||
hostapd_wps_ap_pin_success(hapd);
|
||||
wps_ap_pin_success(hapd, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (hapd->wps_event_cb)
|
||||
@@ -392,7 +331,8 @@ void hostapd_deinit_wps(struct hostapd_data *hapd)
|
||||
return;
|
||||
}
|
||||
wps_registrar_deinit(hapd->wps->registrar);
|
||||
hostapd_free_wps(hapd->wps);
|
||||
hapd->wps->registrar = NULL;
|
||||
eap_server_unregister_methods();
|
||||
hapd->wps = NULL;
|
||||
hostapd_wps_clear_ies(hapd, 1);
|
||||
}
|
||||
|
Reference in New Issue
Block a user