FT: Discard ReassocReq with mismatching RSNXE Used value

Discard the FT Reassociation Request frame instead of rejecting it
(i.e., do not send Reassociation Response frame) if RSNXE Used is
indicated in FTE, but no RSNXE is included even though the AP is
advertising RSNXE.

While there is not really much of a difference between discarding and
rejecting the frame, this discarding behavior is what the standard says
for this type of an error case.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-04-14 13:46:00 +03:00 committed by Jouni Malinen
parent 2012a26d0f
commit 5344af7d22
4 changed files with 17 additions and 12 deletions

View file

@ -117,7 +117,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
u8 *p = buf; u8 *p = buf;
u16 reason = WLAN_REASON_UNSPECIFIED; u16 reason = WLAN_REASON_UNSPECIFIED;
u16 status = WLAN_STATUS_SUCCESS; int status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL; const u8 *p2p_dev_addr = NULL;
if (addr == NULL) { if (addr == NULL) {
@ -606,17 +606,19 @@ skip_wpa_check:
wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
elems.owe_dh) { elems.owe_dh) {
u8 *npos; u8 *npos;
u16 ret_status;
npos = owe_assoc_req_process(hapd, sta, npos = owe_assoc_req_process(hapd, sta,
elems.owe_dh, elems.owe_dh_len, elems.owe_dh, elems.owe_dh_len,
p, sizeof(buf) - (p - buf), p, sizeof(buf) - (p - buf),
&status); &ret_status);
status = ret_status;
if (npos) if (npos)
p = npos; p = npos;
if (!npos && if (!npos &&
status == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) { status == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
hostapd_sta_assoc(hapd, addr, reassoc, status, buf, hostapd_sta_assoc(hapd, addr, reassoc, ret_status, buf,
p - buf); p - buf);
return 0; return 0;
} }
@ -709,7 +711,8 @@ skip_wpa_check:
fail: fail:
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); if (status >= 0)
hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
hostapd_drv_sta_disassoc(hapd, sta->addr, reason); hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
ap_free_sta(hapd, sta); ap_free_sta(hapd, sta);

View file

@ -3104,11 +3104,11 @@ end:
#endif /* CONFIG_OWE */ #endif /* CONFIG_OWE */
static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *ies, size_t ies_len, int reassoc) const u8 *ies, size_t ies_len, int reassoc)
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
u16 resp; int resp;
const u8 *wpa_ie; const u8 *wpa_ie;
size_t wpa_ie_len; size_t wpa_ie_len;
const u8 *p2p_dev_addr = NULL; const u8 *p2p_dev_addr = NULL;
@ -4075,7 +4075,8 @@ static void handle_assoc(struct hostapd_data *hapd,
int reassoc, int rssi) int reassoc, int rssi)
{ {
u16 capab_info, listen_interval, seq_ctrl, fc; u16 capab_info, listen_interval, seq_ctrl, fc;
u16 resp = WLAN_STATUS_SUCCESS, reply_res; int resp = WLAN_STATUS_SUCCESS;
u16 reply_res;
const u8 *pos; const u8 *pos;
int left, i; int left, i;
struct sta_info *sta; struct sta_info *sta;
@ -4449,8 +4450,9 @@ static void handle_assoc(struct hostapd_data *hapd,
} }
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos, if (resp >= 0)
left, rssi, omit_rsnxe); reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc,
pos, left, rssi, omit_rsnxe);
os_free(tmp); os_free(tmp);
/* /*

View file

@ -441,7 +441,7 @@ void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
u16 auth_transaction, u16 resp, u16 auth_transaction, u16 resp,
const u8 *ies, size_t ies_len), const u8 *ies, size_t ies_len),
void *ctx); void *ctx);
u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
size_t ies_len); size_t ies_len);
int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len); int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len);
int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr, int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,

View file

@ -3247,7 +3247,7 @@ void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
} }
u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
size_t ies_len) size_t ies_len)
{ {
struct wpa_ft_ies parse; struct wpa_ft_ies parse;
@ -3445,7 +3445,7 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
!parse.rsnxe) { !parse.rsnxe) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"FT: FTE indicated that STA uses RSNXE, but RSNXE was not included"); "FT: FTE indicated that STA uses RSNXE, but RSNXE was not included");
return WLAN_STATUS_UNSPECIFIED_FAILURE; return -1; /* discard request */
} }
#ifdef CONFIG_OCV #ifdef CONFIG_OCV