From 7a7b6be32add44c14a750db6d0a84d51b5df20bd Mon Sep 17 00:00:00 2001 From: Shyamal Khachane Date: Tue, 7 May 2024 15:49:46 +0530 Subject: [PATCH] fix(esp_wifi): Populate appropriate reason codes when softAP sends deauthentication Populate appropriate reason for sending deauthentication when softAP receives invalid RSN IE from association request --- .../esp_supplicant/src/esp_hostap.c | 121 +++++++++++++++++- .../esp_supplicant/src/esp_wpa_main.c | 13 +- components/wpa_supplicant/src/ap/ap_config.h | 2 +- components/wpa_supplicant/src/ap/wpa_auth.c | 49 ------- components/wpa_supplicant/src/ap/wpa_auth.h | 5 +- .../src/common/ieee802_11_defs.h | 2 + 6 files changed, 136 insertions(+), 56 deletions(-) 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 ecedd7e67b..db49db00e6 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -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/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