OWE: Improve discovery of OWE transition mode AP

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>
This commit is contained in:
Ilan Peer 2018-08-22 19:49:04 +03:00 committed by Jouni Malinen
parent a5e6270f25
commit c04562e67e

View 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;