These patches should of course have been signed off properly. Re-attaching patches with signed-off tag. /Mikael
From 313944114e56d2445cacb1635de71d361d19ad1a Mon Sep 17 00:00:00 2001 From: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> Date: Thu, 30 Jun 2016 12:32:55 +0200 Subject: [PATCH 1/5] nl80211: Add driver parameter force_bss_selection Add driver parameter command to force capability flag WPA_DRIVER_FLAGS_BSS_SELECTION even if driver states otherwise. Signed-off-by: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> --- src/drivers/driver_nl80211.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index c89665b..e6d67bc 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -6930,6 +6930,12 @@ static int nl80211_set_param(void *priv, const char *param) drv->force_connect_cmd = 1; } + if (os_strstr(param, "force_bss_selection=1")) { + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + drv->capa.flags |= WPA_DRIVER_FLAGS_BSS_SELECTION; + } + if (os_strstr(param, "no_offchannel_tx=1")) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; -- 2.8.3
From f9bc204ff6772af245a5dc599284a4af651033da Mon Sep 17 00:00:00 2001 From: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> Date: Thu, 30 Jun 2016 12:37:33 +0200 Subject: [PATCH 2/5] wpa_supplicant: Support multiple driver parameters Support multiple driver parameters for driver_param config option. The option can now be a comma separated list of parameters. Signed-off-by: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> --- wpa_supplicant/main.c | 2 +- wpa_supplicant/wpa_supplicant.c | 38 +++++++++++++++++++++++++++++++++++++- wpa_supplicant/wpa_supplicant.conf | 2 +- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index e08c2fd..3524990 100644 --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -87,7 +87,7 @@ static void usage(void) " -N = start describing new interface\n" " -o = override driver parameter for new interfaces\n" " -O = override ctrl_interface parameter for new interfaces\n" - " -p = driver parameters\n" + " -p = driver parameters (comma separated if multiple)\n" " -P = PID file\n" " -q = decrease debugging verbosity (-qq even less)\n" #ifdef CONFIG_DEBUG_SYSLOG diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 6999bbb..70dc07b 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4505,6 +4505,42 @@ radio_work_pending(struct wpa_supplicant *wpa_s, const char *type) } +static int wpas_driver_set_params(struct wpa_supplicant *wpa_s) +{ + int ret = 0; + size_t len; + const char *pos; + const char* driver_param = wpa_s->conf->driver_param; + char* param; + + if (!driver_param) + return 0; + param = os_malloc(os_strlen(driver_param)); + if (!param) + return -1; + + do { + pos = os_strchr(driver_param, ','); + if (pos) + len = pos - driver_param; + else + len = os_strlen(driver_param); + + os_memcpy(param, driver_param, len); + param[len] = '\0'; + + if (wpa_drv_set_param(wpa_s, param) < 0) { + ret = -1; + break; + } + driver_param = pos + 1; + } while (pos); + + os_free(param); + return ret; +} + + static int wpas_init_driver(struct wpa_supplicant *wpa_s, struct wpa_interface *iface) { @@ -4529,7 +4565,7 @@ next_driver: "interface"); return -1; } - if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) { + if (wpas_driver_set_params(wpa_s) < 0) { wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected " "driver_param '%s'", wpa_s->conf->driver_param); return -1; diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 1d86a71..c7f20d7 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -203,7 +203,7 @@ fast_reauth=1 # This field can be used to configure arbitrary driver interace parameters. The # format is specific to the selected driver interface. This field is not used # in most cases. -#driver_param="field=value" +#driver_param="field=value,field2=value2" # Country code # The ISO/IEC alpha2 country code for the country in which this device is -- 2.8.3
From dc49e078b74d2baaebf4ae4fee885d9e5adf74cf Mon Sep 17 00:00:00 2001 From: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> Date: Wed, 29 Jun 2016 15:36:36 +0200 Subject: [PATCH 3/5] Implement IGNORE_AUTH_RESP control interface debug command Implement IGNORE_AUTH_RESP command to simulate auth/assoc response loss and eapol rx packet loss by ignoring corresponding incoming events. Signed-off-by: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> --- wpa_supplicant/ctrl_iface.c | 15 +++++++++++++++ wpa_supplicant/events.c | 10 ++++++++++ wpa_supplicant/wpa_cli.c | 7 +++++++ wpa_supplicant/wpa_supplicant.c | 5 +++++ wpa_supplicant/wpa_supplicant_i.h | 2 ++ 5 files changed, 39 insertions(+) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index e75323d..f8c76c7 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2102,6 +2102,18 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, } +static int wpa_supplicant_ctrl_iface_ignore_auth_resp(struct wpa_supplicant *wpa_s, + const char *params, + char *buf, size_t buflen) +{ + int enable = atoi(params); + wpa_printf(MSG_DEBUG, "CTRL_IFACE: ignore_auth_resp enable=%d", enable); + wpa_s->ignore_auth_resp = enable; + os_memcpy(buf, "OK\n", 3); + return 3; +} + + static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, char *cmd) { @@ -8689,6 +8701,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); + } else if (os_strncmp(buf, "IGNORE_AUTH_RESP", 16) == 0) { + reply_len = wpa_supplicant_ctrl_iface_ignore_auth_resp( + wpa_s, buf + 16, reply, reply_size); } else if (os_strcmp(buf, "PMKSA") == 0) { reply_len = wpas_ctrl_iface_pmksa(wpa_s, reply, reply_size); } else if (os_strcmp(buf, "PMKSA_FLUSH") == 0) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index b7a3bc0..d5dc1a7 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3431,6 +3431,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, sme_event_auth(wpa_s, data); break; case EVENT_ASSOC: + if (wpa_s->ignore_auth_resp) { + wpa_printf(MSG_INFO, + "EVENT_ASSOC - ignore_auth_resp active!"); + break; + } wpa_supplicant_event_assoc(wpa_s, data); if (data && data->assoc_info.authorized) wpa_supplicant_event_assoc_auth(wpa_s, data); @@ -3445,6 +3450,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data ? &data->disassoc_info : NULL); break; case EVENT_DEAUTH: + if (wpa_s->ignore_auth_resp) { + wpa_printf(MSG_INFO, + "EVENT_DEAUTH - ignore_auth_resp active!"); + break; + } wpas_event_deauth(wpa_s, data ? &data->deauth_info : NULL); break; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 53036ae..82c8e44 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -525,6 +525,10 @@ static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) return wpa_ctrl_command(ctrl, "STATUS"); } +static int wpa_cli_cmd_ignore_auth_resp(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_cli_cmd(ctrl, "IGNORE_AUTH_RESP", 1, argc, argv); +} static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3477,6 +3481,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, cli_cmd_flag_none, "<interface type> = retrieve preferred freq list for the specified interface type" }, + { "ignore_auth_resp", wpa_cli_cmd_ignore_auth_resp, NULL, + cli_cmd_flag_none, + "<0|1> ignore received auth/assoc response and rx eapol packets" }, { NULL, NULL, NULL, cli_cmd_flag_none, NULL } }; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 70dc07b..57881e8 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3266,6 +3266,11 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr)); wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len); + if (wpa_s->ignore_auth_resp) { + wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!"); + return; + } + #ifdef CONFIG_PEERKEY if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid && wpa_s->current_ssid->peerkey && diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index e45f662..0a4c6e9 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1065,6 +1065,8 @@ struct wpa_supplicant { */ struct wpabuf *lci; struct os_reltime lci_time; + + int ignore_auth_resp; }; -- 2.8.3
From fd0432cd2b434fbea6af09f3e24bf59e8101818a Mon Sep 17 00:00:00 2001 From: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> Date: Thu, 30 Jun 2016 10:37:43 +0200 Subject: [PATCH 4/5] tests: Add testcase for roaming failure with reassoc and bssid_set Add testcase that verifies that a failed roaming attempt performed with reassociate command and bssid_set=1 blacklists the correct AP. Signed-off-by: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> --- tests/hwsim/test_ap_roam.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/hwsim/test_ap_roam.py b/tests/hwsim/test_ap_roam.py index 11d9755..6389ead 100644 --- a/tests/hwsim/test_ap_roam.py +++ b/tests/hwsim/test_ap_roam.py @@ -11,6 +11,7 @@ logger = logging.getLogger() import hwsim_utils import hostapd +from wpasupplicant import WpaSupplicant @remote_compatible def test_ap_roam_open(dev, apdev): @@ -61,6 +62,45 @@ def test_ap_roam_wpa2_psk(dev, apdev): dev[0].roam(apdev[0]['bssid']) hwsim_utils.test_connectivity(dev[0], hapd0) +def get_blacklist(dev): + return dev.request("BLACKLIST").splitlines() + +def test_ap_roam_with_reassoc_wpa2_psk_failed(dev, apdev, params): + """Roam using reassoc between two WPA2-PSK APs""" + params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678") + hapd0 = hostapd.add_ap(apdev[0], params) + bssid0 = hapd0.own_addr() + + wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') + wpas.interface_add("wlan5", drv_params="force_connect_cmd=1,force_bss_selection=1") + + id = wpas.connect("test-wpa2-psk", psk="12345678", scan_freq="2412") + hwsim_utils.test_connectivity(wpas, hapd0) + + hapd1 = hostapd.add_ap(apdev[1], params) + bssid1 = hapd1.own_addr() + wpas.scan_for_bss(bssid1, freq=2412) + + if "OK" not in wpas.request("SET_NETWORK " + str(id) + " bssid " + bssid1): + raise Exception("SET_NETWORK failed") + if "OK" not in wpas.request("IGNORE_AUTH_RESP 1"): + raise Exception("IGNORE_AUTH_RESP failed") + if "OK" not in wpas.request("REASSOCIATE"): + raise Exception("REASSOCIATE failed") + + logger.info("Wait ~10s for auth timeout...") + ev = wpas.wait_event(["CTRL-EVENT-SCAN-STARTED"], 12) + if not ev: + raise Exception("CTRL-EVENT-SCAN-STARTED not seen"); + + b = get_blacklist(wpas) + if bssid0 in b: + raise Exception("Unexpected blacklist contents: " + str(b)) + + if "OK" not in wpas.request("IGNORE_AUTH_RESP 0"): + raise Exception("IGNORE_AUTH_RESP failed") + wpas.wait_connected(timeout=5) + def test_ap_roam_wpa2_psk_failed(dev, apdev, params): """Roam failure with WPA2-PSK AP due to wrong passphrase""" params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678") -- 2.8.3
From c466160b62e0400cae531537f5aeb83c287421a1 Mon Sep 17 00:00:00 2001 From: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> Date: Wed, 29 Jun 2016 15:44:19 +0200 Subject: [PATCH 5/5] Blacklist correct bssid on auth timeout if bssid_set If authentication times out while performing reassociate with bssid_set=1 incorrect bssid end up being blacklisted. Use pending_bss field on auth timeout and deauth to ensure correct AP get blacklisted. Signed-off-by: Mikael Kanstrup <mikael.kanstrup@xxxxxxxxxxxxxx> --- wpa_supplicant/wpa_supplicant.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 57881e8..73316db 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -192,7 +192,7 @@ static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; const u8 *bssid = wpa_s->bssid; - if (is_zero_ether_addr(bssid)) + if (!is_zero_ether_addr(wpa_s->pending_bssid)) bssid = wpa_s->pending_bssid; wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.", MAC2STR(bssid)); @@ -2156,7 +2156,10 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) } else { wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'", wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); - os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + if (bss && ssid->bssid_set) + os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); + else + os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); } if (!wpa_s->pno) wpa_supplicant_cancel_sched_scan(wpa_s); @@ -2685,12 +2688,12 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid), reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state)); - if (!is_zero_ether_addr(wpa_s->bssid)) - addr = wpa_s->bssid; - else if (!is_zero_ether_addr(wpa_s->pending_bssid) && + if (!is_zero_ether_addr(wpa_s->pending_bssid) && (wpa_s->wpa_state == WPA_AUTHENTICATING || wpa_s->wpa_state == WPA_ASSOCIATING)) addr = wpa_s->pending_bssid; + else if (!is_zero_ether_addr(wpa_s->bssid)) + addr = wpa_s->bssid; else if (wpa_s->wpa_state == WPA_ASSOCIATING) { /* * When using driver-based BSS selection, we may not know the -- 2.8.3
_______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap