]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OWE: Improve discovery of OWE transition mode AP
authorIlan Peer <ilan.peer@intel.com>
Wed, 22 Aug 2018 16:49:04 +0000 (19:49 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 12 Oct 2018 16:59:26 +0000 (19:59 +0300)
An OWE AP device that supports transition mode does not transmit the
SSID of the OWE AP in its Beacon frames and in addition the OWE AP does
not reply to broadcast Probe Request frames. Thus, the scan results
matching relies only on Beacon frames from the OWE open AP which can be
missed in case the AP's frequency is actively scanned.

To improve the discovery of transition mode APs, include their SSID in
the scan command to perform an active scan for the SSIDs learned from
the open mode BSSs.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
wpa_supplicant/scan.c

index 56d53fbba01944761710a46b3083317088899b57..ee39e0c9228d16e99897f14a23430c56205568cc 100644 (file)
@@ -677,6 +677,87 @@ 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, const 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)
+                       return; /* already in the list */
+       }
+
+       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;
+               const u8 *owe_ssid;
+               size_t owe_ssid_len;
+
+               if (bss->ssid_len != ssid->ssid_len ||
+                   os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) != 0)
+                       continue;
+
+               owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+               if (!owe || owe[1] < 4)
+                       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 = 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)
@@ -691,33 +772,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 more quickly.
+                */
+               wpa_add_owe_scan_ssid(wpa_s, params, ssid, max_ssids);
        }
 
        wpa_s->scan_id_count = 0;
@@ -984,6 +1049,17 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                                if (params.num_ssids + 1 >= max_ssids)
                                        break;
                        }
+
+                       if (!wpas_network_disabled(wpa_s, ssid)) {
+                               /*
+                                * Also add the SSID of the OWE BSS, to allow
+                                * discovery of transition mode APs more
+                                * quickly.
+                                */
+                               wpa_add_owe_scan_ssid(wpa_s, &params, ssid,
+                                                     max_ssids);
+                       }
+
                        ssid = ssid->next;
                        if (ssid == start)
                                break;