diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index faf643b75c..82ff55ee40 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -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" @@ -21,6 +22,9 @@ #include "esp_wps.h" #include "esp_wps_i.h" +#include "ap/sta_info.h" +#include "common/sae.h" +#include "ap/ieee802_11.h" #define WIFI_PASSWORD_LEN_MAX 65 struct hostapd_data *global_hapd; @@ -322,3 +326,143 @@ done: os_free(reply); return res; } + +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, uint8_t *rsnxe, uint8_t rsnxe_len, + bool *pmf_enable, int subtype, 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; + bool omit_rsnxe = false; + + 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, rsnxe, rsnxe_len); + +#ifdef CONFIG_SAE + if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && + sta->sae->state == SAE_ACCEPTED) { + wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); + } +#endif /* CONFIG_SAE */ + + status = wpa_res_to_status_code(res); + +send_resp: + if (!rsnxe) { + omit_rsnxe = true; + } + + if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + } + + 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; +} + +#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(u8* bssid) +{ + struct hostapd_data *hapd = hostapd_get_hapd_data(); + + if (!hapd) { + return false; + } + struct sta_info *sta = ap_get_sta(hapd, bssid); + if (!sta) { + return false; + } + +#ifdef CONFIG_SAE + if (sta->lock) { + if (os_semphr_take(sta->lock, 0)) { + ap_free_sta(hapd, sta); + } else { + sta->remove_pending = true; + } + return true; + } +#endif /* CONFIG_SAE */ + +#ifdef CONFIG_WPS_REGISTRAR + wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status()); + if (wps_get_status() == WPS_STATUS_PENDING) { + 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); + + 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 fd493d99b1..be88ac5b16 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -321,6 +321,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 { struct sta_info *sta_info = NULL; struct hostapd_data *hapd = hostapd_get_hapd_data(); + uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID; if (!hapd) { goto fail; @@ -379,7 +380,7 @@ process_old_sta: goto fail; } #endif - if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher)) { + if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher, &reason)) { goto done; } else { goto fail; @@ -400,7 +401,7 @@ fail: os_semphr_give(sta_info->lock); } #endif /* CONFIG_SAE */ - esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID); + 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 486d802a11..1d11dd4816 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -382,9 +382,9 @@ 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, +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len,uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason); bool wpa_ap_remove(u8* bssid); #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 513ec9fa82..58748a85ff 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -13,7 +13,6 @@ #include "common/ieee802_11_defs.h" #include "common/sae.h" #include "ap/sta_info.h" -#include "ap/ieee802_11.h" #include "ap/wpa_auth.h" #include "ap/wpa_auth_i.h" #include "ap/wpa_auth_ie.h" @@ -36,7 +35,6 @@ #include "esp_wifi.h" #include "esp_private/wifi.h" #include "esp_wpas_glue.h" -#include "esp_wps_i.h" #include "esp_hostap.h" #define STATE_MACHINE_DATA struct wpa_state_machine @@ -2557,97 +2555,6 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth) } -#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, - uint8_t wpa_ie_len, uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) -{ - struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); - enum wpa_validate_result status_code = WPA_IE_OK; - int resp = WLAN_STATUS_SUCCESS; - bool omit_rsnxe = false; - - 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) { - resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - goto send_resp; - } - - status_code = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len); - -#ifdef CONFIG_SAE - if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && - sta->sae->state == SAE_ACCEPTED) { - wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); - } -#endif /* CONFIG_SAE */ - - resp = wpa_res_to_status_code(status_code); - -send_resp: - if (!rsnxe) { - omit_rsnxe = true; - } - - if (esp_send_assoc_resp(hapd, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { - resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - } - - if (resp != WLAN_STATUS_SUCCESS) { - 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(u8* bssid) -{ - struct hostapd_data *hapd = hostapd_get_hapd_data(); - - if (!hapd) { - return false; - } - struct sta_info *sta = ap_get_sta(hapd, bssid); - if (!sta) { - return false; - } - -#ifdef CONFIG_SAE - if (sta->lock) { - if (os_semphr_take(sta->lock, 0)) { - ap_free_sta(hapd, sta); - } else { - sta->remove_pending = true; - } - return true; - } -#endif /* CONFIG_SAE */ - ap_free_sta(hapd, sta); - - return true; -} -#endif /* CONFIG_ESP_WIFI_SOFTAP_SUPPORT */ - void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr) { diff --git a/components/wpa_supplicant/src/common/ieee802_11_defs.h b/components/wpa_supplicant/src/common/ieee802_11_defs.h index b496690ab7..958bf5feeb 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_defs.h +++ b/components/wpa_supplicant/src/common/ieee802_11_defs.h @@ -186,6 +186,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