tests: Association comeback mechanism in wpa_supplicant
Allow the Timeout Interval Type field in the Timeout Interval element to be overridden with a different value for testing purposes to be able to bypass the association comeback processing in mac80211. This allows the wpa_supplicant internal functionality to be tested. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
33179cd291
commit
ee9375fb3b
9 changed files with 98 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / Configuration file parser
|
* hostapd / Configuration file parser
|
||||||
* Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -4450,6 +4450,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
return 1;
|
return 1;
|
||||||
} else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
|
} else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
|
||||||
bss->eapol_m3_no_encrypt = atoi(pos);
|
bss->eapol_m3_no_encrypt = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) {
|
||||||
|
bss->test_assoc_comeback_type = atoi(pos);
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
} else if (os_strcmp(buf, "sae_password") == 0) {
|
} else if (os_strcmp(buf, "sae_password") == 0) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / Configuration helper functions
|
* hostapd / Configuration helper functions
|
||||||
* Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -165,6 +165,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
bss->sae_commit_status = -1;
|
bss->sae_commit_status = -1;
|
||||||
|
bss->test_assoc_comeback_type = -1;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
#ifdef CONFIG_PASN
|
#ifdef CONFIG_PASN
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / Configuration definitions and helpers functions
|
* hostapd / Configuration definitions and helpers functions
|
||||||
* Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -708,6 +708,7 @@ struct hostapd_bss_config {
|
||||||
struct wpabuf *eapol_m1_elements;
|
struct wpabuf *eapol_m1_elements;
|
||||||
struct wpabuf *eapol_m3_elements;
|
struct wpabuf *eapol_m3_elements;
|
||||||
bool eapol_m3_no_encrypt;
|
bool eapol_m3_no_encrypt;
|
||||||
|
int test_assoc_comeback_type;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211BE
|
#ifdef CONFIG_IEEE80211BE
|
||||||
u16 eht_oper_puncturing_override;
|
u16 eht_oper_puncturing_override;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / IEEE 802.11 Management
|
* hostapd / IEEE 802.11 Management
|
||||||
* Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -21,16 +21,25 @@
|
||||||
#include "ieee802_11.h"
|
#include "ieee802_11.h"
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_eid_timeout_interval(u8 *pos, u8 type, u32 value)
|
||||||
|
{
|
||||||
|
*pos++ = WLAN_EID_TIMEOUT_INTERVAL;
|
||||||
|
*pos++ = 5;
|
||||||
|
*pos++ = type;
|
||||||
|
WPA_PUT_LE32(pos, value);
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
|
u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
|
||||||
struct sta_info *sta, u8 *eid)
|
struct sta_info *sta, u8 *eid)
|
||||||
{
|
{
|
||||||
u8 *pos = eid;
|
|
||||||
u32 timeout, tu;
|
u32 timeout, tu;
|
||||||
struct os_reltime now, passed;
|
struct os_reltime now, passed;
|
||||||
|
u8 type = WLAN_TIMEOUT_ASSOC_COMEBACK;
|
||||||
|
|
||||||
*pos++ = WLAN_EID_TIMEOUT_INTERVAL;
|
|
||||||
*pos++ = 5;
|
|
||||||
*pos++ = WLAN_TIMEOUT_ASSOC_COMEBACK;
|
|
||||||
os_get_reltime(&now);
|
os_get_reltime(&now);
|
||||||
os_reltime_sub(&now, &sta->sa_query_start, &passed);
|
os_reltime_sub(&now, &sta->sa_query_start, &passed);
|
||||||
tu = (passed.sec * 1000000 + passed.usec) / 1024;
|
tu = (passed.sec * 1000000 + passed.usec) / 1024;
|
||||||
|
@ -40,10 +49,12 @@ u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
if (timeout < hapd->conf->assoc_sa_query_max_timeout)
|
if (timeout < hapd->conf->assoc_sa_query_max_timeout)
|
||||||
timeout++; /* add some extra time for local timers */
|
timeout++; /* add some extra time for local timers */
|
||||||
WPA_PUT_LE32(pos, timeout);
|
|
||||||
pos += 4;
|
|
||||||
|
|
||||||
return pos;
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (hapd->conf->test_assoc_comeback_type != -1)
|
||||||
|
type = hapd->conf->test_assoc_comeback_type;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
return hostapd_eid_timeout_interval(eid, type, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Protected management frames tests
|
# Protected management frames tests
|
||||||
# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
|
# Copyright (c) 2013-2024, Jouni Malinen <j@w1.fi>
|
||||||
#
|
#
|
||||||
# This software may be distributed under the terms of the BSD license.
|
# This software may be distributed under the terms of the BSD license.
|
||||||
# See README for more details.
|
# See README for more details.
|
||||||
|
@ -272,6 +272,61 @@ def run_ap_pmf_assoc_comeback(dev, apdev, comeback=None):
|
||||||
dev[0].p2p_interface_addr()) < 1:
|
dev[0].p2p_interface_addr()) < 1:
|
||||||
raise Exception("AP did not use association comeback request")
|
raise Exception("AP did not use association comeback request")
|
||||||
|
|
||||||
|
def test_ap_pmf_assoc_comeback_in_wpas(dev, apdev):
|
||||||
|
"""WPA2-PSK AP with PMF association comeback in wpa_supplicant"""
|
||||||
|
ssid = "assoc-comeback"
|
||||||
|
params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
|
||||||
|
params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
|
||||||
|
params["ieee80211w"] = "2"
|
||||||
|
params["test_assoc_comeback_type"] = "255"
|
||||||
|
hapd = hostapd.add_ap(apdev[0], params)
|
||||||
|
|
||||||
|
dev[0].set("test_assoc_comeback_type", "255")
|
||||||
|
dev[0].connect(ssid, psk="12345678", ieee80211w="1",
|
||||||
|
key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
|
||||||
|
scan_freq="2412")
|
||||||
|
hapd.wait_sta(wait_4way_hs=True)
|
||||||
|
hapd.set("ext_mgmt_frame_handling", "1")
|
||||||
|
dev[0].request("DISCONNECT")
|
||||||
|
dev[0].wait_disconnected(timeout=10)
|
||||||
|
ev = hapd.wait_event(["MGMT-RX"], timeout=1)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Deauthentication frame RX not reported")
|
||||||
|
hapd.set("ext_mgmt_frame_handling", "0")
|
||||||
|
dev[0].request("REASSOCIATE")
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
|
||||||
|
if ev is None or "status_code=30" not in ev:
|
||||||
|
raise Exception("Association comeback not requested")
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
|
||||||
|
"CTRL-EVENT-ASSOC-REJECT"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Association not reported")
|
||||||
|
if "CTRL-EVENT-ASSOC-REJECT" in ev:
|
||||||
|
raise Exception("Unexpected association rejection: " + ev)
|
||||||
|
hapd.wait_4way_hs()
|
||||||
|
|
||||||
|
hapd.set("ext_mgmt_frame_handling", "1")
|
||||||
|
dev[0].request("DISCONNECT")
|
||||||
|
dev[0].wait_disconnected(timeout=10)
|
||||||
|
ev = hapd.wait_event(["MGMT-RX"], timeout=1)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Deauthentication frame RX not reported")
|
||||||
|
hapd.set("ext_mgmt_frame_handling", "0")
|
||||||
|
dev[0].set("test_assoc_comeback_type", "254")
|
||||||
|
dev[0].request("REASSOCIATE")
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
|
||||||
|
if ev is None or "status_code=30" not in ev:
|
||||||
|
raise Exception("Association comeback not requested")
|
||||||
|
ev = dev[0].wait_event(["SME: Temporary assoc reject: missing association comeback time",
|
||||||
|
"CTRL-EVENT-CONNECTED",
|
||||||
|
"CTRL-EVENT-ASSOC-REJECT"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Association not reported")
|
||||||
|
if "SME: Temporary assoc reject: missing association comeback time" not in ev:
|
||||||
|
raise Exception("Unexpected result: " + ev)
|
||||||
|
dev[0].wait_connected(timeout=20, error="Timeout on re-connection with misbehaving AP")
|
||||||
|
hapd.wait_4way_hs()
|
||||||
|
|
||||||
@remote_compatible
|
@remote_compatible
|
||||||
def test_ap_pmf_assoc_comeback2(dev, apdev):
|
def test_ap_pmf_assoc_comeback2(dev, apdev):
|
||||||
"""WPA2-PSK AP with PMF association comeback (using DROP_SA)"""
|
"""WPA2-PSK AP with PMF association comeback (using DROP_SA)"""
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant / Control interface (shared code for all backends)
|
* WPA Supplicant / Control interface (shared code for all backends)
|
||||||
* Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -850,6 +850,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||||
/* Populate value to wpa_sm if already associated. */
|
/* Populate value to wpa_sm if already associated. */
|
||||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DISABLE_EAPOL_G2_TX,
|
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DISABLE_EAPOL_G2_TX,
|
||||||
wpa_s->disable_eapol_g2_tx);
|
wpa_s->disable_eapol_g2_tx);
|
||||||
|
} else if (os_strcasecmp(cmd, "test_assoc_comeback_type") == 0) {
|
||||||
|
wpa_s->test_assoc_comeback_type = atoi(value);
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
|
} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
|
||||||
os_free(wpa_s->dpp_config_obj_override);
|
os_free(wpa_s->dpp_config_obj_override);
|
||||||
|
@ -8888,6 +8890,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->oci_freq_override_fils_assoc = 0;
|
wpa_s->oci_freq_override_fils_assoc = 0;
|
||||||
wpa_s->oci_freq_override_wnm_sleep = 0;
|
wpa_s->oci_freq_override_wnm_sleep = 0;
|
||||||
wpa_s->disable_eapol_g2_tx = 0;
|
wpa_s->disable_eapol_g2_tx = 0;
|
||||||
|
wpa_s->test_assoc_comeback_type = -1;
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
os_free(wpa_s->dpp_config_obj_override);
|
os_free(wpa_s->dpp_config_obj_override);
|
||||||
wpa_s->dpp_config_obj_override = NULL;
|
wpa_s->dpp_config_obj_override = NULL;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant - SME
|
* wpa_supplicant - SME
|
||||||
* Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2009-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -2745,6 +2745,12 @@ static bool sme_try_assoc_comeback(struct wpa_supplicant *wpa_s,
|
||||||
struct ieee802_11_elems elems;
|
struct ieee802_11_elems elems;
|
||||||
u32 timeout_interval;
|
u32 timeout_interval;
|
||||||
unsigned long comeback_usec;
|
unsigned long comeback_usec;
|
||||||
|
u8 type = WLAN_TIMEOUT_ASSOC_COMEBACK;
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (wpa_s->test_assoc_comeback_type != -1)
|
||||||
|
type = wpa_s->test_assoc_comeback_type;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
if (ieee802_11_parse_elems(data->assoc_reject.resp_ies,
|
if (ieee802_11_parse_elems(data->assoc_reject.resp_ies,
|
||||||
data->assoc_reject.resp_ies_len,
|
data->assoc_reject.resp_ies_len,
|
||||||
|
@ -2760,7 +2766,7 @@ static bool sme_try_assoc_comeback(struct wpa_supplicant *wpa_s,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elems.timeout_int[0] != WLAN_TIMEOUT_ASSOC_COMEBACK) {
|
if (elems.timeout_int[0] != type) {
|
||||||
wpa_msg(wpa_s, MSG_INFO,
|
wpa_msg(wpa_s, MSG_INFO,
|
||||||
"SME: Temporary assoc reject: missing association comeback time");
|
"SME: Temporary assoc reject: missing association comeback time");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant
|
* WPA Supplicant
|
||||||
* Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -5857,6 +5857,7 @@ wpa_supplicant_alloc(struct wpa_supplicant *parent)
|
||||||
dl_list_init(&wpa_s->fils_hlp_req);
|
dl_list_init(&wpa_s->fils_hlp_req);
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
dl_list_init(&wpa_s->drv_signal_override);
|
dl_list_init(&wpa_s->drv_signal_override);
|
||||||
|
wpa_s->test_assoc_comeback_type = -1;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#ifndef CONFIG_NO_ROBUST_AV
|
#ifndef CONFIG_NO_ROBUST_AV
|
||||||
dl_list_init(&wpa_s->active_scs_ids);
|
dl_list_init(&wpa_s->active_scs_ids);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant - Internal definitions
|
* wpa_supplicant - Internal definitions
|
||||||
* Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -1366,6 +1366,7 @@ struct wpa_supplicant {
|
||||||
unsigned int oci_freq_override_fils_assoc;
|
unsigned int oci_freq_override_fils_assoc;
|
||||||
unsigned int oci_freq_override_wnm_sleep;
|
unsigned int oci_freq_override_wnm_sleep;
|
||||||
unsigned int disable_eapol_g2_tx;
|
unsigned int disable_eapol_g2_tx;
|
||||||
|
int test_assoc_comeback_type;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
struct wmm_ac_assoc_data *wmm_ac_assoc_info;
|
struct wmm_ac_assoc_data *wmm_ac_assoc_info;
|
||||||
|
|
Loading…
Reference in a new issue