aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2017-10-08 09:32:02 (GMT)
committerJouni Malinen <j@w1.fi>2017-10-08 14:12:35 (GMT)
commite8b96490122cc53d54a06433e0284061b63700ac (patch)
tree4095aba5d01c8e78df04b8b8b5044c6b5b4c978d /wpa_supplicant
parent675112df1b539d9d4ba80249a13946a869445fba (diff)
downloadhostap-e8b96490122cc53d54a06433e0284061b63700ac.zip
hostap-e8b96490122cc53d54a06433e0284061b63700ac.tar.gz
hostap-e8b96490122cc53d54a06433e0284061b63700ac.tar.bz2
OWE: Transition mode support on station side
Add support for using the OWE Transition Mode element to determine the hidden SSID for an OWE BSS that is used in transition mode. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c21
-rw-r--r--wpa_supplicant/events.c88
-rw-r--r--wpa_supplicant/wpa_supplicant.c44
3 files changed, 147 insertions, 6 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 40c0c45..0fc5642 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2745,7 +2745,7 @@ static int wpa_supplicant_ctrl_iface_scan_result(
{
char *pos, *end;
int ret;
- const u8 *ie, *ie2, *osen_ie, *p2p, *mesh;
+ const u8 *ie, *ie2, *osen_ie, *p2p, *mesh, *owe;
mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
@@ -2776,6 +2776,14 @@ static int wpa_supplicant_ctrl_iface_scan_result(
if (osen_ie)
pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
osen_ie, 2 + osen_ie[1]);
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (owe) {
+ ret = os_snprintf(pos, end - pos,
+ ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) {
ret = os_snprintf(pos, end - pos, "[WEP]");
@@ -4452,7 +4460,7 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
size_t i;
int ret;
char *pos, *end;
- const u8 *ie, *ie2, *osen_ie, *mesh;
+ const u8 *ie, *ie2, *osen_ie, *mesh, *owe;
pos = buf;
end = buf + buflen;
@@ -4576,6 +4584,15 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
if (osen_ie)
pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
osen_ie, 2 + osen_ie[1]);
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (owe) {
+ ret = os_snprintf(
+ pos, end - pos,
+ ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && !osen_ie &&
(bss->caps & IEEE80211_CAP_PRIVACY)) {
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 500e66c..65d453c 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -879,6 +879,80 @@ static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
}
+static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ const u8 **ret_ssid, size_t *ret_ssid_len)
+{
+#ifdef CONFIG_OWE
+ const u8 *owe, *pos, *end, *bssid;
+ u8 ssid_len;
+ struct wpa_bss *open_bss;
+
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (!owe || !wpa_bss_get_ie(bss, WLAN_EID_RSN))
+ return;
+
+ pos = owe + 6;
+ end = owe + 2 + owe[1];
+
+ if (end - pos < ETH_ALEN + 1)
+ return;
+ bssid = pos;
+ pos += ETH_ALEN;
+ ssid_len = *pos++;
+ if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
+ return;
+
+ /* Match the profile SSID against the OWE transition mode SSID on the
+ * open network. */
+ wpa_dbg(wpa_s, MSG_DEBUG, "OWE: transition mode BSSID: " MACSTR
+ " SSID: %s", MAC2STR(bssid), wpa_ssid_txt(pos, ssid_len));
+ *ret_ssid = pos;
+ *ret_ssid_len = ssid_len;
+
+ if (bss->ssid_len > 0)
+ return;
+
+ open_bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
+ if (!open_bss)
+ return;
+ if (ssid_len != open_bss->ssid_len ||
+ os_memcmp(pos, open_bss->ssid, ssid_len) != 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "OWE: transition mode SSID mismatch: %s",
+ wpa_ssid_txt(open_bss->ssid, open_bss->ssid_len));
+ return;
+ }
+
+ owe = wpa_bss_get_vendor_ie(open_bss, OWE_IE_VENDOR_TYPE);
+ if (!owe || wpa_bss_get_ie(open_bss, WLAN_EID_RSN)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "OWE: transition mode open BSS unexpected info");
+ return;
+ }
+
+ pos = owe + 6;
+ end = owe + 2 + owe[1];
+
+ if (end - pos < ETH_ALEN + 1)
+ return;
+ if (os_memcmp(pos, bss->bssid, ETH_ALEN) != 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "OWE: transition mode BSSID mismatch: " MACSTR,
+ MAC2STR(pos));
+ return;
+ }
+ pos += ETH_ALEN;
+ ssid_len = *pos++;
+ if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
+ return;
+ wpa_dbg(wpa_s, MSG_DEBUG, "OWE: learned transition mode OWE SSID: %s",
+ wpa_ssid_txt(pos, ssid_len));
+ os_memcpy(bss->ssid, pos, ssid_len);
+ bss->ssid_len = ssid_len;
+#endif /* CONFIG_OWE */
+}
+
+
struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
int i, struct wpa_bss *bss,
struct wpa_ssid *group,
@@ -893,6 +967,8 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_MBO
const u8 *assoc_disallow;
#endif /* CONFIG_MBO */
+ const u8 *match_ssid;
+ size_t match_ssid_len;
ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
wpa_ie_len = ie ? ie[1] : 0;
@@ -942,7 +1018,11 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
}
}
- if (bss->ssid_len == 0) {
+ match_ssid = bss->ssid;
+ match_ssid_len = bss->ssid_len;
+ owe_trans_ssid(wpa_s, bss, &match_ssid, &match_ssid_len);
+
+ if (match_ssid_len == 0) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID not known");
return NULL;
@@ -954,7 +1034,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
return NULL;
}
- if (disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
+ if (disallowed_ssid(wpa_s, match_ssid, match_ssid_len)) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID disallowed");
return NULL;
@@ -1009,8 +1089,8 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
check_ssid = 0;
if (check_ssid &&
- (bss->ssid_len != ssid->ssid_len ||
- os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
+ (match_ssid_len != ssid->ssid_len ||
+ os_memcmp(match_ssid, ssid->ssid, match_ssid_len) != 0)) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
" skip - SSID mismatch");
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index ddfdaf7..e463709 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3533,6 +3533,41 @@ int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
}
+#ifdef CONFIG_OWE
+static int owe_trans_ssid_match(struct wpa_supplicant *wpa_s, const u8 *bssid,
+ const u8 *entry_ssid, size_t entry_ssid_len)
+{
+ const u8 *owe, *pos, *end;
+ u8 ssid_len;
+ struct wpa_bss *bss;
+
+ /* Check network profile SSID aganst the SSID in the
+ * OWE Transition Mode element. */
+
+ bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
+ if (!bss)
+ return 0;
+
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (!owe)
+ return 0;
+
+ pos = owe + 6;
+ end = owe + 2 + owe[1];
+
+ if (end - pos < ETH_ALEN + 1)
+ return 0;
+ pos += ETH_ALEN;
+ ssid_len = *pos++;
+ if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
+ return 0;
+
+ return entry_ssid_len == ssid_len &&
+ os_memcmp(pos, entry_ssid, ssid_len) == 0;
+}
+#endif /* CONFIG_OWE */
+
+
/**
* wpa_supplicant_get_ssid - Get a pointer to the current network structure
* @wpa_s: Pointer to wpa_supplicant data
@@ -3581,6 +3616,15 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
return entry;
#endif /* CONFIG_WPS */
+#ifdef CONFIG_OWE
+ if (!wpas_network_disabled(wpa_s, entry) &&
+ owe_trans_ssid_match(wpa_s, bssid, entry->ssid,
+ entry->ssid_len) &&
+ (!entry->bssid_set ||
+ os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
+ return entry;
+#endif /* CONFIG_OWE */
+
if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
entry->ssid_len == 0 &&
os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)