 83ebf55865
			
		
	
	
		83ebf55865
		
	
	
	
	
		
			
			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>
		
			
				
	
	
		
			156 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * WPA Supplicant / dbus-based control interface (WPS)
 | |
|  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
 | |
|  *
 | |
|  * This software may be distributed under the terms of the BSD license.
 | |
|  * See README for more details.
 | |
|  */
 | |
| 
 | |
| #include "includes.h"
 | |
| #include <dbus/dbus.h>
 | |
| 
 | |
| #include "common.h"
 | |
| #include "../config.h"
 | |
| #include "../wpa_supplicant_i.h"
 | |
| #include "../wps_supplicant.h"
 | |
| #include "dbus_old.h"
 | |
| #include "dbus_old_handlers.h"
 | |
| 
 | |
| /**
 | |
|  * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
 | |
|  * @message: Pointer to incoming dbus message
 | |
|  * @wpa_s: %wpa_supplicant data structure
 | |
|  * Returns: A dbus message containing a UINT32 indicating success (1) or
 | |
|  *          failure (0)
 | |
|  *
 | |
|  * Handler function for "wpsPbc" method call
 | |
|  */
 | |
| DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
 | |
| 				      struct wpa_supplicant *wpa_s)
 | |
| {
 | |
| 	char *arg_bssid = NULL;
 | |
| 	u8 bssid[ETH_ALEN];
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
 | |
| 				   DBUS_TYPE_INVALID))
 | |
| 		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, 0);
 | |
| 	else if (!hwaddr_aton(arg_bssid, bssid))
 | |
| 		ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
 | |
| 	else {
 | |
| 		return wpas_dbus_new_invalid_opts_error(message,
 | |
| 							"Invalid BSSID");
 | |
| 	}
 | |
| 
 | |
| 	if (ret < 0) {
 | |
| 		return dbus_message_new_error(
 | |
| 			message, WPAS_ERROR_WPS_PBC_ERROR,
 | |
| 			"Could not start PBC negotiation");
 | |
| 	}
 | |
| 
 | |
| 	return wpas_dbus_new_success_reply(message);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
 | |
|  * @message: Pointer to incoming dbus message
 | |
|  * @wpa_s: %wpa_supplicant data structure
 | |
|  * Returns: A dbus message containing a UINT32 indicating success (1) or
 | |
|  *          failure (0)
 | |
|  *
 | |
|  * Handler function for "wpsPin" method call
 | |
|  */
 | |
| DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
 | |
| 				      struct wpa_supplicant *wpa_s)
 | |
| {
 | |
| 	DBusMessage *reply = NULL;
 | |
| 	char *arg_bssid;
 | |
| 	char *pin = NULL;
 | |
| 	u8 bssid[ETH_ALEN], *_bssid = NULL;
 | |
| 	int ret;
 | |
| 	char npin[9];
 | |
| 
 | |
| 	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
 | |
| 				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
 | |
| 		return wpas_dbus_new_invalid_opts_error(message, NULL);
 | |
| 
 | |
| 	if (os_strcmp(arg_bssid, "any") == 0)
 | |
| 		_bssid = NULL;
 | |
| 	else if (!hwaddr_aton(arg_bssid, bssid))
 | |
| 		_bssid = bssid;
 | |
| 	else {
 | |
| 		return wpas_dbus_new_invalid_opts_error(message,
 | |
| 							"Invalid BSSID");
 | |
| 	}
 | |
| 
 | |
| 	if (os_strlen(pin) > 0)
 | |
| 		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
 | |
| 					 DEV_PW_DEFAULT);
 | |
| 	else
 | |
| 		ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
 | |
| 					 DEV_PW_DEFAULT);
 | |
| 
 | |
| 	if (ret < 0) {
 | |
| 		return dbus_message_new_error(message,
 | |
| 					      WPAS_ERROR_WPS_PIN_ERROR,
 | |
| 					      "Could not init PIN");
 | |
| 	}
 | |
| 
 | |
| 	reply = dbus_message_new_method_return(message);
 | |
| 	if (reply == NULL)
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (ret > 0) {
 | |
| 		ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
 | |
| 		if (os_snprintf_error(sizeof(npin), ret))
 | |
| 			return wpas_dbus_new_invalid_opts_error(message,
 | |
| 								"invalid PIN");
 | |
| 
 | |
| 		pin = npin;
 | |
| 	}
 | |
| 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
 | |
| 				 DBUS_TYPE_INVALID);
 | |
| 	return reply;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
 | |
|  * @message: Pointer to incoming dbus message
 | |
|  * @wpa_s: %wpa_supplicant data structure
 | |
|  * Returns: A dbus message containing a UINT32 indicating success (1) or
 | |
|  *          failure (0)
 | |
|  *
 | |
|  * Handler function for "wpsReg" method call
 | |
|  */
 | |
| DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
 | |
| 				      struct wpa_supplicant *wpa_s)
 | |
| {
 | |
| 	char *arg_bssid;
 | |
| 	char *pin = NULL;
 | |
| 	u8 bssid[ETH_ALEN];
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
 | |
| 				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
 | |
| 		return wpas_dbus_new_invalid_opts_error(message, NULL);
 | |
| 
 | |
| 	if (!hwaddr_aton(arg_bssid, bssid))
 | |
| 		ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
 | |
| 	else {
 | |
| 		return wpas_dbus_new_invalid_opts_error(message,
 | |
| 							"Invalid BSSID");
 | |
| 	}
 | |
| 
 | |
| 	if (ret < 0) {
 | |
| 		return dbus_message_new_error(message,
 | |
| 					      WPAS_ERROR_WPS_REG_ERROR,
 | |
| 					      "Could not request credentials");
 | |
| 	}
 | |
| 
 | |
| 	return wpas_dbus_new_success_reply(message);
 | |
| }
 |