OWE: Improve discovery of OWE transition mode AP

Message ID 1534956548-8088-3-git-send-email-andrei.otcheretianski@intel.com
State Accepted
Headers show
Series
  • OWE: Improve discovery of OWE transition mode AP
Related show

Commit Message

Andrei Otcheretianski Aug. 22, 2018, 4:49 p.m.
From: Ilan Peer <ilan.peer@intel.com>

An OWE AP device that supports transition mode does not transmit
the SSID of the OWE AP in its beacons and in addition the OWE AP
does not reply to broadcast probe requests. Thus, the scan results
matching relies only on beacons from the OWE open AP which can be
missed in case the AP's frequency is actively scanned.

To improve the discovery of transition modes AP, include their
SSID in the scan command.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 wpa_supplicant/scan.c | 154 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 118 insertions(+), 36 deletions(-)

Comments

Jouni Malinen Oct. 12, 2018, 7:03 p.m. | #1
On Wed, Aug 22, 2018 at 07:49:04PM +0300, Andrei Otcheretianski wrote:
> An OWE AP device that supports transition mode does not transmit
> the SSID of the OWE AP in its beacons and in addition the OWE AP
> does not reply to broadcast probe requests. Thus, the scan results
> matching relies only on beacons from the OWE open AP which can be
> missed in case the AP's frequency is actively scanned.
> 
> To improve the discovery of transition modes AP, include their
> SSID in the scan command.

Thanks, applied.

Patch

diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 104b258..05f2d7c 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -643,6 +643,93 @@  static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
 }
 
 
+static void wpa_add_scan_ssid(struct wpa_supplicant *wpa_s,
+			      struct wpa_driver_scan_params *params,
+			      size_t max_ssids, u8 *ssid, size_t ssid_len)
+{
+	unsigned int j;
+
+	for (j = 0; j < params->num_ssids; j++) {
+		if (params->ssids[j].ssid_len == ssid_len &&
+		    params->ssids[j].ssid &&
+		    os_memcmp(params->ssids[j].ssid, ssid,
+			      ssid_len) == 0)
+			break;
+	}
+
+	if (j < params->num_ssids)
+		return;
+
+	if (params->num_ssids + 1 > max_ssids) {
+		wpa_printf(MSG_DEBUG,
+			   "Over max scan SSIDs for manual request");
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
+		   wpa_ssid_txt(ssid, ssid_len));
+
+	params->ssids[params->num_ssids].ssid = ssid;
+	params->ssids[params->num_ssids].ssid_len = ssid_len;
+	params->num_ssids++;
+}
+
+
+static void wpa_add_owe_scan_ssid(struct wpa_supplicant *wpa_s,
+				  struct wpa_driver_scan_params *params,
+				  struct wpa_ssid *ssid, size_t max_ssids)
+{
+#ifdef CONFIG_OWE
+	struct wpa_bss *bss;
+
+	if (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE))
+		return;
+
+	wpa_printf(MSG_DEBUG,
+		   "OWE: look for transition mode AP. ssid=%s",
+		   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+
+	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+		const u8 *owe, *pos, *end;
+		u8 *owe_ssid;
+		size_t owe_ssid_len;
+
+		if (bss->ssid_len != ssid->ssid_len ||
+		    os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len))
+			continue;
+
+		owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+		if (!owe)
+			continue;
+
+		pos = owe + 6;
+		end = owe + 2 + owe[1];
+
+		/* must include BSSID and ssid_len */
+		if (end - pos < ETH_ALEN + 1)
+			return;
+
+		/* skip BSSID */
+		pos += ETH_ALEN;
+		owe_ssid_len = *pos++;
+		owe_ssid = (u8 *)pos;
+
+		if ((size_t)(end - pos) < owe_ssid_len ||
+		    owe_ssid_len > SSID_MAX_LEN)
+			return;
+
+		wpa_printf(MSG_DEBUG,
+			   "OWE: scan_ssids: transition mode OWE ssid=%s",
+			   wpa_ssid_txt(owe_ssid, owe_ssid_len));
+
+		wpa_add_scan_ssid(wpa_s, params, max_ssids,
+				  owe_ssid, owe_ssid_len);
+		return;
+	}
+#endif /* CONFIG_OWE */
+}
+
+
 static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
 			       struct wpa_driver_scan_params *params,
 			       size_t max_ssids)
@@ -657,33 +744,17 @@  static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
 	max_ssids = max_ssids > 1 ? max_ssids - 1 : max_ssids;
 
 	for (i = 0; i < wpa_s->scan_id_count; i++) {
-		unsigned int j;
-
 		ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
-		if (!ssid || !ssid->scan_ssid)
+		if (!ssid)
 			continue;
-
-		for (j = 0; j < params->num_ssids; j++) {
-			if (params->ssids[j].ssid_len == ssid->ssid_len &&
-			    params->ssids[j].ssid &&
-			    os_memcmp(params->ssids[j].ssid, ssid->ssid,
-				      ssid->ssid_len) == 0)
-				break;
-		}
-		if (j < params->num_ssids)
-			continue; /* already in the list */
-
-		if (params->num_ssids + 1 > max_ssids) {
-			wpa_printf(MSG_DEBUG,
-				   "Over max scan SSIDs for manual request");
-			break;
-		}
-
-		wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
-			   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
-		params->ssids[params->num_ssids].ssid = ssid->ssid;
-		params->ssids[params->num_ssids].ssid_len = ssid->ssid_len;
-		params->num_ssids++;
+		if (ssid->scan_ssid)
+			wpa_add_scan_ssid(wpa_s, params, max_ssids,
+					  ssid->ssid, ssid->ssid_len);
+		/*
+		 * Also add the SSID of the OWE BSS, to allow discovery of
+		 * transition mode APs
+		 */
+		wpa_add_owe_scan_ssid(wpa_s, params, ssid, max_ssids);
 	}
 
 	wpa_s->scan_id_count = 0;
@@ -938,17 +1009,28 @@  static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 		if (ssid == NULL && max_ssids > 1)
 			ssid = wpa_s->conf->ssid;
 		while (ssid) {
-			if (!wpas_network_disabled(wpa_s, ssid) &&
-			    ssid->scan_ssid) {
-				wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
-						  ssid->ssid, ssid->ssid_len);
-				params.ssids[params.num_ssids].ssid =
-					ssid->ssid;
-				params.ssids[params.num_ssids].ssid_len =
-					ssid->ssid_len;
-				params.num_ssids++;
-				if (params.num_ssids + 1 >= max_ssids)
-					break;
+			if (!wpas_network_disabled(wpa_s, ssid)) {
+				if (ssid->scan_ssid) {
+					wpa_hexdump_ascii(MSG_DEBUG,
+							  "Scan SSID",
+							  ssid->ssid,
+							  ssid->ssid_len);
+					params.ssids[params.num_ssids].ssid =
+						ssid->ssid;
+					params.ssids[params.num_ssids].ssid_len =
+						ssid->ssid_len;
+					params.num_ssids++;
+
+					if (params.num_ssids + 1 >= max_ssids)
+						break;
+				}
+
+				/*
+				 * Also add the SSID of the OWE BSS, to allow
+				 * discovery of transition mode APs
+				 */
+				wpa_add_owe_scan_ssid(wpa_s, &params, ssid,
+						      max_ssids);
 			}
 			ssid = ssid->next;
 			if (ssid == start)