diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 81d184e8df..92a221f0c8 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -69,10 +69,13 @@ typedef enum { WIFI_REASON_UNSPECIFIED = 1, WIFI_REASON_AUTH_EXPIRE = 2, WIFI_REASON_AUTH_LEAVE = 3, - WIFI_REASON_ASSOC_EXPIRE = 4, + WIFI_REASON_ASSOC_EXPIRE = 4, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, WIFI_REASON_ASSOC_TOOMANY = 5, - WIFI_REASON_NOT_AUTHED = 6, - WIFI_REASON_NOT_ASSOCED = 7, + WIFI_REASON_NOT_AUTHED = 6, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WIFI_REASON_NOT_ASSOCED = 7, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, WIFI_REASON_ASSOC_LEAVE = 8, WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 34e4b12665..8b765ecaf0 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 34e4b12665c5806f9213472ea820bfde48e7f673 +Subproject commit 8b765ecaf0183137061d5726507e93d69b1ba4c1 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index 2b78fbf24d..38b2fca94f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include "utils/includes.h" #include "utils/common.h" +//#include "utils/eloop.h" #include "crypto/sha1.h" #include "common/ieee802_11_defs.h" #include "common/eapol_common.h" @@ -20,6 +21,10 @@ #include "esp_wps.h" #include "esp_wps_i.h" +#include "ap/sta_info.h" +#include "common/sae.h" +//#include "ap/ieee802_11.h" + struct hostapd_data *global_hapd; struct hostapd_data *hostapd_get_hapd_data(void) @@ -183,3 +188,117 @@ bool hostap_deinit(void *data) return true; } + +u16 wpa_res_to_status_code(enum wpa_validate_result res) +{ + switch (res) { + case WPA_IE_OK: + return WLAN_STATUS_SUCCESS; + case WPA_INVALID_IE: + return WLAN_STATUS_INVALID_IE; + case WPA_INVALID_GROUP: + return WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + case WPA_INVALID_PAIRWISE: + return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; + case WPA_INVALID_AKMP: + return WLAN_STATUS_AKMP_NOT_VALID; + case WPA_NOT_ENABLED: + return WLAN_STATUS_INVALID_IE; + case WPA_ALLOC_FAIL: + return WLAN_STATUS_UNSPECIFIED_FAILURE; + case WPA_MGMT_FRAME_PROTECTION_VIOLATION: + return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + case WPA_INVALID_MGMT_GROUP_CIPHER: + return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; + case WPA_INVALID_MDIE: + return WLAN_STATUS_INVALID_MDIE; + case WPA_INVALID_PROTO: + return WLAN_STATUS_INVALID_IE; + case WPA_INVALID_PMKID: + return WLAN_STATUS_INVALID_PMKID; + case WPA_DENIED_OTHER_REASON: + return WLAN_STATUS_ASSOC_DENIED_UNSPEC; + } + return WLAN_STATUS_INVALID_IE; +} + +uint8_t wpa_status_to_reason_code(int status) +{ + switch (status) { + case WLAN_STATUS_INVALID_IE: + return WLAN_REASON_INVALID_IE; + case WLAN_STATUS_GROUP_CIPHER_NOT_VALID: + return WLAN_REASON_GROUP_CIPHER_NOT_VALID; + case WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID: + return WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; + case WLAN_STATUS_AKMP_NOT_VALID: + return WLAN_REASON_AKMP_NOT_VALID; + case WLAN_STATUS_CIPHER_REJECTED_PER_POLICY: + return WLAN_REASON_CIPHER_SUITE_REJECTED; + case WLAN_STATUS_INVALID_PMKID: + return WLAN_REASON_INVALID_PMKID; + case WLAN_STATUS_INVALID_MDIE: + return WLAN_REASON_INVALID_MDE; + default: + return WLAN_REASON_UNSPECIFIED; + } +} + +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, + uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher, uint8_t *reason) +{ + struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); + enum wpa_validate_result res = WPA_IE_OK; + int status = WLAN_STATUS_SUCCESS; + + if (!sta || !bssid || !wpa_ie) { + return false; + } + + if (hapd) { + if (hapd->wpa_auth->conf.wpa) { + if (sta->wpa_sm) { + wpa_auth_sta_deinit(sta->wpa_sm); + } + + sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid); + wpa_printf(MSG_DEBUG, "init wpa sm=%p", sta->wpa_sm); + + if (sta->wpa_sm == NULL) { + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + goto send_resp; + } + + res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len); + + status = wpa_res_to_status_code(res); + +send_resp: + if (status != WLAN_STATUS_SUCCESS) { + *reason = wpa_status_to_reason_code(status); + return false; + } + + //Check whether AP uses Management Frame Protection for this connection + *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); + *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); + } + + wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); + } + + return true; +} + +bool wpa_ap_remove(void* sta_info) +{ + struct hostapd_data *hapd = hostapd_get_hapd_data(); + + if (!sta_info || !hapd) { + return false; + } + + ap_free_sta(hapd, sta_info); + + return true; +} diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index fef09195f9..db49db00e6 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -250,8 +250,8 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) { switch (reason_code) { case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_NOT_AUTHED: - case WIFI_REASON_NOT_ASSOCED: + case WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + case WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: case WIFI_REASON_INVALID_PMKID: case WIFI_REASON_AUTH_FAIL: @@ -314,6 +314,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo { struct sta_info *sta_info; struct hostapd_data *hapd = hostapd_get_hapd_data(); + uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID; if (!hapd) { return 0; @@ -334,11 +335,17 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, bo return true; } #endif - if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable, pairwise_cipher)) { - *sta = sta_info; - return true; + if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, pmf_enable, pairwise_cipher, &reason)) { + goto done; + } else { + goto fail; } +done: + *sta = sta_info; + return true; +fail: + esp_wifi_ap_deauth_internal(bssid, reason); return false; } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 84e230f16d..fd019627ff 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -917,7 +917,7 @@ int wps_start_msg_timer(void) ret = 0; } else if (sm->wps->state == RECV_M2) { msg_timeout = 5; - wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " ms", msg_timeout); + wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " s", msg_timeout); eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL); eloop_register_timeout(msg_timeout, 0, wifi_station_wps_msg_timeout, NULL, NULL); ret = 0; diff --git a/components/wpa_supplicant/src/ap/ap_config.h b/components/wpa_supplicant/src/ap/ap_config.h index 118da6e578..534ed17ad3 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -373,7 +373,7 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, const u8 *addr, const u8 *prev_psk); int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); struct sta_info; -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher); +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher, uint8_t *reason); bool wpa_ap_remove(void* sta_info); #endif /* HOSTAPD_CONFIG_H */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 205d878856..06cbb414a5 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -2374,52 +2374,3 @@ static int wpa_sm_step(struct wpa_state_machine *sm) } return 0; } - -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, bool *pmf_enable, uint8_t *pairwise_cipher) -{ - struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); - - if (!sta || !bssid || !wpa_ie){ - return false; - } - - if (hapd) { - if (hapd->wpa_auth->conf.wpa) { - if (sta->wpa_sm){ - wpa_auth_sta_deinit(sta->wpa_sm); - } - - sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid); - wpa_printf( MSG_DEBUG, "init wpa sm=%p\n", sta->wpa_sm); - - if (sta->wpa_sm == NULL) { - return false; - } - - if (wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len)) { - return false; - } - - //Check whether AP uses Management Frame Protection for this connection - *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); - *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); - } - - wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); - } - - return true; -} - -bool wpa_ap_remove(void* sta_info) -{ - struct hostapd_data *hapd = hostapd_get_hapd_data(); - - if (!sta_info || !hapd) { - return false; - } - - ap_free_sta(hapd, sta_info); - - return true; -} diff --git a/components/wpa_supplicant/src/ap/wpa_auth.h b/components/wpa_supplicant/src/ap/wpa_auth.h index a4a040fd27..0f9d57fad7 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.h +++ b/components/wpa_supplicant/src/ap/wpa_auth.h @@ -213,11 +213,12 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth); int wpa_reconfig(struct wpa_authenticator *wpa_auth, struct wpa_auth_config *conf); -enum { +enum wpa_validate_result { WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE, WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL, WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER, - WPA_INVALID_MDIE, WPA_INVALID_PROTO + WPA_INVALID_MDIE, WPA_INVALID_PROTO, WPA_INVALID_PMKID, + WPA_DENIED_OTHER_REASON }; int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, diff --git a/components/wpa_supplicant/src/common/ieee802_11_defs.h b/components/wpa_supplicant/src/common/ieee802_11_defs.h index 1742eed0c5..7ed718b318 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_defs.h +++ b/components/wpa_supplicant/src/common/ieee802_11_defs.h @@ -184,6 +184,8 @@ #define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 #define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 #define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#define WLAN_REASON_INVALID_PMKID 49 +#define WLAN_REASON_INVALID_MDE 50 /* Information Element IDs (IEEE Std 802.11-2016, 9.4.2.1, Table 9-77) */ #define WLAN_EID_SSID 0 diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 2d26991735..741f835eec 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -756,7 +756,7 @@ Association Phase +++++++++++++++++++++ - s3.1: The association request is sent and the association timer is enabled. - - s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be WIFI_REASON_ASSOC_EXPIRE. Refer to `Wi-Fi Reason Code`_. + - s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY. Refer to `Wi-Fi Reason Code`_. - s3.3: The association response is received and the association timer is stopped. - s3.4: The AP rejects the association in the response and `WIFI_EVENT_STA_DISCONNECTED`_ arises, while the reason code is the one specified in the association response. Refer to `Wi-Fi Reason Code`_. @@ -813,20 +813,16 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co For the ESP station, this reason is reported when: - it is received from the AP. - * - ASSOC_EXPIRE + * - DISASSOC_DUE_TO_INACTIVITY - 4 - 4 - Disassociated due to inactivity. For the ESP station, this reason is reported when: + - assoc is timed out. - it is received from the AP. - For the ESP AP, this reason is reported when: - - - the AP has not received any packets from the station in the past five minutes. - - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. - - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. * - ASSOC_TOOMANY - 5 - 5 @@ -839,7 +835,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co For the ESP AP, this reason is reported when: - the stations associated with the AP reach the maximum number that the AP can support. - * - NOT_AUTHED + * - CLASS2_FRAME_FROM_NONAUTH_STA - 6 - 6 - Class-2 frame received from a non-authenticated STA. @@ -851,7 +847,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co For the ESP AP, this reason is reported when: - the AP receives a packet with data from a non-authenticated station. - * - NOT_ASSOCED + * - CLASS3_FRAME_FROM_NONASSOC_STA - 7 - 7 - Class-3 frame received from a non-associated STA. @@ -1116,7 +1112,7 @@ The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first co * - ASSOC_FAIL - 203 - reserved - - Espressif-specific Wi-Fi reason code: the association fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. + - Espressif-specific Wi-Fi reason code: the association fails, but not because of DISASSOC_DUE_TO_INACTIVITY or ASSOC_TOOMANY. * - HANDSHAKE_TIMEOUT - 204 - reserved diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index 2b8ae46a35..0068d45092 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -756,7 +756,7 @@ Wi-Fi 驱动程序内部扫描阶段 +++++++++++++++++++++ - s3.1:发送关联请求并使能关联计时器。 - - s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 WIFI_REASON_ASSOC_EXPIRE。请参阅 `Wi-Fi 原因代码`_。 + - s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY。请参阅 `Wi-Fi 原因代码`_。 - s3.3:接收到关联响应,且关联计时器终止。 - s3.4:AP 在响应中拒绝关联且产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,原因代码将在关联响应中指定。请参阅 `Wi-Fi 原因代码`_。 @@ -813,7 +813,7 @@ Wi-Fi 原因代码 对于 ESP station,出现以下情况时报告该代码: - 从 AP 接收到该代码。 - * - ASSOC_EXPIRE + * - DISASSOC_DUE_TO_INACTIVITY - 4 - 4 - 因为 AP 不活跃,association 取消。 @@ -839,7 +839,7 @@ Wi-Fi 原因代码 对于 ESP AP,出现以下情况时将报告该代码: - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 - * - NOT_AUTHED + * - CLASS2_FRAME_FROM_NONAUTH_STA - 6 - 6 - 从一个未认证 station 接收到 class-2 frame。 @@ -851,7 +851,7 @@ Wi-Fi 原因代码 对于 ESP AP,出现以下情况时将报告该代码: - AP 从一个未认证 station 接收到数据包。 - * - NOT_ASSOCED + * - CLASS3_FRAME_FROM_NONASSOC_STA - 7 - 7 - 从一个未关联 station 接收到的 class-3 frame。 @@ -1116,7 +1116,7 @@ Wi-Fi 原因代码 * - ASSOC_FAIL - 203 - 保留 - - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 + - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 DISASSOC_DUE_TO_INACTIVITY 或 ASSOC_TOOMANY 引发。 * - HANDSHAKE_TIMEOUT - 204 - 保留