Re: Roaming on android blacklists incorrect bss

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux