aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorDavina Lu <ylu@quantenna.com>2019-02-12 14:35:25 (GMT)
committerJouni Malinen <j@w1.fi>2019-02-18 20:35:41 (GMT)
commit83ebf558654615e02beb3be7011e63307bf328b7 (patch)
tree7886461aa64d5f4026cd6ff00202c530bfb7617f /wpa_supplicant
parent56a2d788f9dea36c32eebb3c54081ecea29766d4 (diff)
downloadhostap-83ebf558654615e02beb3be7011e63307bf328b7.zip
hostap-83ebf558654615e02beb3be7011e63307bf328b7.tar.gz
hostap-83ebf558654615e02beb3be7011e63307bf328b7.tar.bz2
wpa_supplicant: Support Multi-AP backhaul STA onboarding with WPS
The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a backhaul STA through WPS. To enable this, the backhaul STA needs to add a Multi-AP IE to the WFA vendor extension element in the WSC M1 message that indicates it supports the Multi-AP backhaul STA role. The Registrar (if it support Multi-AP onboarding) will respond to that with a WSC M8 message that also contains the Multi-AP IE, and that contains the credentials for the backhaul SSID (which may be different from the SSID on which WPS is performed). Introduce a new parameter to wpas_wps_start_pbc() and allow it to be set via control interface's new multi_ap=1 parameter of WPS_PBC call. multi_ap_backhaul_sta is set to 1 in the automatically created SSID. Thus, if the AP does not support Multi-AP, association will fail and WPS will be terminated. Only wps_pbc is supported. This commit adds the multi_ap argument only to the control socket interface, not to the D-Bus interface. Since WPS associates with the fronthaul BSS instead of the backhaul BSS, we should not drop association if the AP announces fronthaul-only BSS. Still, we should only do that in the specific case of WPS. Therefore, add a check to multi_ap_process_assoc_resp() to allow association with a fronthaul-only BSS if and only if key_mgmt contains WPS. Signed-off-by: Davina Lu <ylu@quantenna.com> Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be> Signed-off-by: Daniel Golle <daniel@makrotopia.org> Cc: Marianna Carrera <marianna.carrera.so@quantenna.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c18
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_wps.c2
-rw-r--r--wpa_supplicant/dbus/dbus_old_handlers_wps.c4
-rw-r--r--wpa_supplicant/events.c9
-rw-r--r--wpa_supplicant/p2p_supplicant.c2
-rw-r--r--wpa_supplicant/wps_supplicant.c9
-rw-r--r--wpa_supplicant/wps_supplicant.h2
7 files changed, 36 insertions, 10 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 89c5d45..80f2d08 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1168,8 +1168,11 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_AP
u8 *_p2p_dev_addr = NULL;
#endif /* CONFIG_AP */
+ char *pos;
+ int multi_ap = 0;
- if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
+ if (!cmd || os_strcmp(cmd, "any") == 0 ||
+ os_strncmp(cmd, "any ", 4) == 0) {
_bssid = NULL;
#ifdef CONFIG_P2P
} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
@@ -1181,18 +1184,29 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
}
_p2p_dev_addr = p2p_dev_addr;
#endif /* CONFIG_P2P */
+ } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
+ _bssid = NULL;
+ multi_ap = atoi(cmd + 9);
} else if (hwaddr_aton(cmd, bssid)) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
cmd);
return -1;
}
+ if (cmd) {
+ pos = os_strstr(cmd, " multi_ap=");
+ if (pos) {
+ pos += 10;
+ multi_ap = atoi(pos);
+ }
+ }
+
#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
#endif /* CONFIG_AP */
- return wpas_wps_start_pbc(wpa_s, _bssid, 0);
+ return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index 19c1a61..1594daf 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -293,7 +293,7 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
message, "invalid PIN");
}
} else {
- ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
+ ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
}
if (ret < 0) {
diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
index 987e12d..6c8405b 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
@@ -37,9 +37,9 @@ DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
return wpas_dbus_new_invalid_opts_error(message, NULL);
if (os_strcmp(arg_bssid, "any") == 0)
- ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
+ ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
else if (!hwaddr_aton(arg_bssid, bssid))
- ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
+ ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
else {
return wpas_dbus_new_invalid_opts_error(message,
"Invalid BSSID");
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 0e483ec..b254d4e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2305,6 +2305,13 @@ static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
}
if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
+ if ((map_sub_elem[2] & MULTI_AP_FRONTHAUL_BSS) &&
+ wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+ wpa_printf(MSG_INFO,
+ "WPS active, accepting fronthaul-only BSS");
+ /* Don't set 4addr mode in this case, so just return */
+ return;
+ }
wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
goto fail;
}
@@ -4829,7 +4836,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
case EVENT_WPS_BUTTON_PUSHED:
#ifdef CONFIG_WPS
- wpas_wps_start_pbc(wpa_s, NULL, 0);
+ wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
#endif /* CONFIG_WPS */
break;
case EVENT_AVOID_FREQUENCIES:
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 18fd02c..937b70f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1656,7 +1656,7 @@ static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
wpa_supplicant_ap_deinit(wpa_s);
wpas_copy_go_neg_results(wpa_s, res);
if (res->wps_method == WPS_PBC) {
- wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
+ wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
#ifdef CONFIG_WPS_NFC
} else if (res->wps_method == WPS_NFC) {
wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 1a2677b..c11d4fb 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1137,9 +1137,10 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group)
+ int p2p_group, int multi_ap_backhaul_sta)
{
struct wpa_ssid *ssid;
+ char phase1[32];
#ifdef CONFIG_AP
if (wpa_s->ap_iface) {
@@ -1177,10 +1178,14 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
}
}
#endif /* CONFIG_P2P */
- if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
+ os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
+ multi_ap_backhaul_sta ? " multi_ap=1" : "");
+ if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
return -1;
if (wpa_s->wps_fragment_size)
ssid->eap.fragment_size = wpa_s->wps_fragment_size;
+ if (multi_ap_backhaul_sta)
+ ssid->multi_ap_backhaul_sta = 1;
wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
wpa_s, NULL);
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index c8fe47e..0fbc851 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s);
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group);
+ int p2p_group, int multi_ap_backhaul_sta);
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
const char *pin, int p2p_group, u16 dev_pw_id);
void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);