Home | History | Annotate | Line # | Download | only in wpa_supplicant
      1       1.1  christos /*
      2       1.1  christos  * wpa_supplicant / WPS integration
      3   1.1.1.5  christos  * Copyright (c) 2008-2014, Jouni Malinen <j (at) w1.fi>
      4       1.1  christos  *
      5   1.1.1.4  christos  * This software may be distributed under the terms of the BSD license.
      6   1.1.1.4  christos  * See README for more details.
      7       1.1  christos  */
      8       1.1  christos 
      9       1.1  christos #include "includes.h"
     10       1.1  christos 
     11       1.1  christos #include "common.h"
     12       1.1  christos #include "eloop.h"
     13       1.1  christos #include "uuid.h"
     14   1.1.1.4  christos #include "crypto/random.h"
     15       1.1  christos #include "crypto/dh_group5.h"
     16       1.1  christos #include "common/ieee802_11_defs.h"
     17       1.1  christos #include "common/ieee802_11_common.h"
     18       1.1  christos #include "common/wpa_common.h"
     19       1.1  christos #include "common/wpa_ctrl.h"
     20       1.1  christos #include "eap_common/eap_wsc_common.h"
     21       1.1  christos #include "eap_peer/eap.h"
     22   1.1.1.2  christos #include "eapol_supp/eapol_supp_sm.h"
     23       1.1  christos #include "rsn_supp/wpa.h"
     24   1.1.1.4  christos #include "wps/wps_attr_parse.h"
     25       1.1  christos #include "config.h"
     26       1.1  christos #include "wpa_supplicant_i.h"
     27       1.1  christos #include "driver_i.h"
     28       1.1  christos #include "notify.h"
     29  1.1.1.10  christos #include "bssid_ignore.h"
     30       1.1  christos #include "bss.h"
     31       1.1  christos #include "scan.h"
     32   1.1.1.2  christos #include "ap.h"
     33   1.1.1.2  christos #include "p2p/p2p.h"
     34   1.1.1.2  christos #include "p2p_supplicant.h"
     35       1.1  christos #include "wps_supplicant.h"
     36       1.1  christos 
     37       1.1  christos 
     38   1.1.1.2  christos #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
     39       1.1  christos #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
     40   1.1.1.2  christos #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
     41       1.1  christos 
     42   1.1.1.7  christos /*
     43   1.1.1.7  christos  * The minimum time in seconds before trying to associate to a WPS PIN AP that
     44   1.1.1.7  christos  * does not have Selected Registrar TRUE.
     45   1.1.1.7  christos  */
     46   1.1.1.7  christos #ifndef WPS_PIN_TIME_IGNORE_SEL_REG
     47   1.1.1.7  christos #define WPS_PIN_TIME_IGNORE_SEL_REG 5
     48   1.1.1.7  christos #endif /* WPS_PIN_TIME_IGNORE_SEL_REG */
     49   1.1.1.7  christos 
     50       1.1  christos static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
     51       1.1  christos static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
     52       1.1  christos 
     53       1.1  christos 
     54   1.1.1.4  christos static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
     55   1.1.1.4  christos {
     56   1.1.1.4  christos 	os_free(wpa_s->wps_ap);
     57   1.1.1.4  christos 	wpa_s->wps_ap = NULL;
     58   1.1.1.4  christos 	wpa_s->num_wps_ap = 0;
     59   1.1.1.4  christos 	wpa_s->wps_ap_iter = 0;
     60   1.1.1.4  christos }
     61   1.1.1.4  christos 
     62   1.1.1.4  christos 
     63   1.1.1.5  christos static void wpas_wps_assoc_with_cred(void *eloop_ctx, void *timeout_ctx)
     64   1.1.1.5  christos {
     65   1.1.1.5  christos 	struct wpa_supplicant *wpa_s = eloop_ctx;
     66   1.1.1.5  christos 	int use_fast_assoc = timeout_ctx != NULL;
     67   1.1.1.5  christos 
     68   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "WPS: Continuing association after eapol_cb");
     69   1.1.1.5  christos 	if (!use_fast_assoc ||
     70   1.1.1.5  christos 	    wpa_supplicant_fast_associate(wpa_s) != 1)
     71   1.1.1.5  christos 		wpa_supplicant_req_scan(wpa_s, 0, 0);
     72   1.1.1.5  christos }
     73   1.1.1.5  christos 
     74   1.1.1.5  christos 
     75   1.1.1.5  christos static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
     76   1.1.1.5  christos {
     77   1.1.1.5  christos 	eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 0);
     78   1.1.1.5  christos 	eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 1);
     79   1.1.1.5  christos }
     80   1.1.1.5  christos 
     81   1.1.1.5  christos 
     82  1.1.1.10  christos static struct wpabuf * wpas_wps_get_wps_ie(struct wpa_bss *bss)
     83  1.1.1.10  christos {
     84  1.1.1.10  christos 	/* Return the latest receive WPS IE from the AP regardless of whether
     85  1.1.1.10  christos 	 * it was from a Beacon frame or Probe Response frame to avoid using
     86  1.1.1.10  christos 	 * stale information. */
     87  1.1.1.10  christos 	if (bss->beacon_newer)
     88  1.1.1.10  christos 		return wpa_bss_get_vendor_ie_multi_beacon(bss,
     89  1.1.1.10  christos 							  WPS_IE_VENDOR_TYPE);
     90  1.1.1.10  christos 	return wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
     91  1.1.1.10  christos }
     92  1.1.1.10  christos 
     93  1.1.1.10  christos 
     94       1.1  christos int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
     95       1.1  christos {
     96   1.1.1.5  christos 	if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
     97   1.1.1.5  christos 		return 1;
     98   1.1.1.5  christos 
     99       1.1  christos 	if (!wpa_s->wps_success &&
    100       1.1  christos 	    wpa_s->current_ssid &&
    101       1.1  christos 	    eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
    102       1.1  christos 		const u8 *bssid = wpa_s->bssid;
    103       1.1  christos 		if (is_zero_ether_addr(bssid))
    104       1.1  christos 			bssid = wpa_s->pending_bssid;
    105       1.1  christos 
    106       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
    107       1.1  christos 			   " did not succeed - continue trying to find "
    108       1.1  christos 			   "suitable AP", MAC2STR(bssid));
    109  1.1.1.10  christos 		wpa_bssid_ignore_add(wpa_s, bssid);
    110       1.1  christos 
    111       1.1  christos 		wpa_supplicant_deauthenticate(wpa_s,
    112       1.1  christos 					      WLAN_REASON_DEAUTH_LEAVING);
    113       1.1  christos 		wpa_s->reassociate = 1;
    114       1.1  christos 		wpa_supplicant_req_scan(wpa_s,
    115  1.1.1.10  christos 					wpa_s->bssid_ignore_cleared ? 5 : 0, 0);
    116  1.1.1.10  christos 		wpa_s->bssid_ignore_cleared = false;
    117       1.1  christos 		return 1;
    118       1.1  christos 	}
    119       1.1  christos 
    120   1.1.1.4  christos 	wpas_wps_clear_ap_info(wpa_s);
    121       1.1  christos 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
    122   1.1.1.2  christos 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success)
    123   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL);
    124       1.1  christos 
    125       1.1  christos 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
    126       1.1  christos 	    !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
    127   1.1.1.2  christos 		int disabled = wpa_s->current_ssid->disabled;
    128   1.1.1.2  christos 		unsigned int freq = wpa_s->assoc_freq;
    129   1.1.1.5  christos 		struct wpa_bss *bss;
    130   1.1.1.5  christos 		struct wpa_ssid *ssid = NULL;
    131   1.1.1.5  christos 		int use_fast_assoc = 0;
    132   1.1.1.5  christos 
    133       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
    134   1.1.1.2  christos 			   "try to associate with the received credential "
    135   1.1.1.2  christos 			   "(freq=%u)", freq);
    136   1.1.1.6  christos 		wpa_s->own_disconnect_req = 1;
    137       1.1  christos 		wpa_supplicant_deauthenticate(wpa_s,
    138       1.1  christos 					      WLAN_REASON_DEAUTH_LEAVING);
    139   1.1.1.2  christos 		if (disabled) {
    140   1.1.1.2  christos 			wpa_printf(MSG_DEBUG, "WPS: Current network is "
    141   1.1.1.2  christos 				   "disabled - wait for user to enable");
    142   1.1.1.2  christos 			return 1;
    143   1.1.1.2  christos 		}
    144       1.1  christos 		wpa_s->after_wps = 5;
    145   1.1.1.2  christos 		wpa_s->wps_freq = freq;
    146   1.1.1.4  christos 		wpa_s->normal_scans = 0;
    147       1.1  christos 		wpa_s->reassociate = 1;
    148   1.1.1.5  christos 
    149   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
    150   1.1.1.5  christos 			   "without a new scan can be used");
    151   1.1.1.5  christos 		bss = wpa_supplicant_pick_network(wpa_s, &ssid);
    152   1.1.1.5  christos 		if (bss) {
    153   1.1.1.5  christos 			struct wpabuf *wps;
    154   1.1.1.5  christos 			struct wps_parse_attr attr;
    155   1.1.1.5  christos 
    156  1.1.1.10  christos 			wps = wpas_wps_get_wps_ie(bss);
    157   1.1.1.5  christos 			if (wps && wps_parse_msg(wps, &attr) == 0 &&
    158   1.1.1.5  christos 			    attr.wps_state &&
    159   1.1.1.5  christos 			    *attr.wps_state == WPS_STATE_CONFIGURED)
    160   1.1.1.5  christos 				use_fast_assoc = 1;
    161   1.1.1.5  christos 			wpabuf_free(wps);
    162   1.1.1.5  christos 		}
    163   1.1.1.5  christos 
    164   1.1.1.5  christos 		/*
    165   1.1.1.5  christos 		 * Complete the next step from an eloop timeout to allow pending
    166   1.1.1.5  christos 		 * driver events related to the disconnection to be processed
    167   1.1.1.5  christos 		 * first. This makes it less likely for disconnection event to
    168   1.1.1.5  christos 		 * cause problems with the following connection.
    169   1.1.1.5  christos 		 */
    170   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Continue association from timeout");
    171   1.1.1.5  christos 		wpas_wps_assoc_with_cred_cancel(wpa_s);
    172   1.1.1.5  christos 		eloop_register_timeout(0, 10000,
    173   1.1.1.5  christos 				       wpas_wps_assoc_with_cred, wpa_s,
    174   1.1.1.5  christos 				       use_fast_assoc ? (void *) 1 :
    175   1.1.1.5  christos 				       (void *) 0);
    176       1.1  christos 		return 1;
    177       1.1  christos 	}
    178       1.1  christos 
    179       1.1  christos 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
    180       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
    181       1.1  christos 			   "for external credential processing");
    182       1.1  christos 		wpas_clear_wps(wpa_s);
    183   1.1.1.6  christos 		wpa_s->own_disconnect_req = 1;
    184       1.1  christos 		wpa_supplicant_deauthenticate(wpa_s,
    185       1.1  christos 					      WLAN_REASON_DEAUTH_LEAVING);
    186       1.1  christos 		return 1;
    187       1.1  christos 	}
    188       1.1  christos 
    189       1.1  christos 	return 0;
    190       1.1  christos }
    191       1.1  christos 
    192       1.1  christos 
    193       1.1  christos static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
    194       1.1  christos 					 struct wpa_ssid *ssid,
    195       1.1  christos 					 const struct wps_credential *cred)
    196       1.1  christos {
    197       1.1  christos 	struct wpa_driver_capa capa;
    198       1.1  christos 	struct wpa_bss *bss;
    199       1.1  christos 	const u8 *ie;
    200       1.1  christos 	struct wpa_ie_data adv;
    201       1.1  christos 	int wpa2 = 0, ccmp = 0;
    202  1.1.1.10  christos 	enum wpa_driver_if_type iftype;
    203       1.1  christos 
    204       1.1  christos 	/*
    205       1.1  christos 	 * Many existing WPS APs do not know how to negotiate WPA2 or CCMP in
    206       1.1  christos 	 * case they are configured for mixed mode operation (WPA+WPA2 and
    207       1.1  christos 	 * TKIP+CCMP). Try to use scan results to figure out whether the AP
    208       1.1  christos 	 * actually supports stronger security and select that if the client
    209       1.1  christos 	 * has support for it, too.
    210       1.1  christos 	 */
    211       1.1  christos 
    212       1.1  christos 	if (wpa_drv_get_capa(wpa_s, &capa))
    213       1.1  christos 		return; /* Unknown what driver supports */
    214       1.1  christos 
    215   1.1.1.2  christos 	if (ssid->ssid == NULL)
    216   1.1.1.2  christos 		return;
    217       1.1  christos 	bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
    218   1.1.1.8  christos 	if (!bss)
    219   1.1.1.8  christos 		bss = wpa_bss_get(wpa_s, wpa_s->bssid,
    220   1.1.1.8  christos 				  ssid->ssid, ssid->ssid_len);
    221       1.1  christos 	if (bss == NULL) {
    222       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
    223       1.1  christos 			   "table - use credential as-is");
    224       1.1  christos 		return;
    225       1.1  christos 	}
    226       1.1  christos 
    227       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
    228       1.1  christos 
    229       1.1  christos 	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    230       1.1  christos 	if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
    231       1.1  christos 		wpa2 = 1;
    232       1.1  christos 		if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
    233       1.1  christos 			ccmp = 1;
    234       1.1  christos 	} else {
    235       1.1  christos 		ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    236       1.1  christos 		if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 &&
    237       1.1  christos 		    adv.pairwise_cipher & WPA_CIPHER_CCMP)
    238       1.1  christos 			ccmp = 1;
    239       1.1  christos 	}
    240       1.1  christos 
    241       1.1  christos 	if (ie == NULL && (ssid->proto & WPA_PROTO_WPA) &&
    242       1.1  christos 	    (ssid->pairwise_cipher & WPA_CIPHER_TKIP)) {
    243       1.1  christos 		/*
    244       1.1  christos 		 * TODO: This could be the initial AP configuration and the
    245       1.1  christos 		 * Beacon contents could change shortly. Should request a new
    246       1.1  christos 		 * scan and delay addition of the network until the updated
    247       1.1  christos 		 * scan results are available.
    248       1.1  christos 		 */
    249       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: The AP did not yet advertise WPA "
    250       1.1  christos 			   "support - use credential as-is");
    251       1.1  christos 		return;
    252       1.1  christos 	}
    253       1.1  christos 
    254  1.1.1.10  christos 	iftype = ssid->p2p_group ? WPA_IF_P2P_CLIENT : WPA_IF_STATION;
    255  1.1.1.10  christos 
    256       1.1  christos 	if (ccmp && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
    257       1.1  christos 	    (ssid->pairwise_cipher & WPA_CIPHER_TKIP) &&
    258  1.1.1.10  christos 	    (capa.key_mgmt_iftype[iftype] &
    259  1.1.1.10  christos 	     WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
    260       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Add CCMP into the credential "
    261       1.1  christos 			   "based on scan results");
    262       1.1  christos 		if (wpa_s->conf->ap_scan == 1)
    263       1.1  christos 			ssid->pairwise_cipher |= WPA_CIPHER_CCMP;
    264       1.1  christos 		else
    265       1.1  christos 			ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    266       1.1  christos 	}
    267       1.1  christos 
    268       1.1  christos 	if (wpa2 && !(ssid->proto & WPA_PROTO_RSN) &&
    269       1.1  christos 	    (ssid->proto & WPA_PROTO_WPA) &&
    270       1.1  christos 	    (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
    271       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Add WPA2 into the credential "
    272       1.1  christos 			   "based on scan results");
    273       1.1  christos 		if (wpa_s->conf->ap_scan == 1)
    274       1.1  christos 			ssid->proto |= WPA_PROTO_RSN;
    275       1.1  christos 		else
    276       1.1  christos 			ssid->proto = WPA_PROTO_RSN;
    277       1.1  christos 	}
    278       1.1  christos }
    279       1.1  christos 
    280       1.1  christos 
    281   1.1.1.5  christos static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s,
    282   1.1.1.5  christos 					struct wpa_ssid *new_ssid)
    283   1.1.1.5  christos {
    284   1.1.1.5  christos 	struct wpa_ssid *ssid, *next;
    285   1.1.1.5  christos 
    286   1.1.1.5  christos 	for (ssid = wpa_s->conf->ssid, next = ssid ? ssid->next : NULL; ssid;
    287   1.1.1.5  christos 	     ssid = next, next = ssid ? ssid->next : NULL) {
    288   1.1.1.5  christos 		/*
    289   1.1.1.5  christos 		 * new_ssid has already been added to the list in
    290   1.1.1.5  christos 		 * wpas_wps_add_network(), so skip it.
    291   1.1.1.5  christos 		 */
    292   1.1.1.5  christos 		if (ssid == new_ssid)
    293   1.1.1.5  christos 			continue;
    294   1.1.1.5  christos 
    295   1.1.1.5  christos 		if (ssid->bssid_set || new_ssid->bssid_set) {
    296   1.1.1.5  christos 			if (ssid->bssid_set != new_ssid->bssid_set)
    297   1.1.1.5  christos 				continue;
    298  1.1.1.10  christos 			if (!ether_addr_equal(ssid->bssid, new_ssid->bssid))
    299   1.1.1.5  christos 				continue;
    300   1.1.1.5  christos 		}
    301   1.1.1.5  christos 
    302   1.1.1.5  christos 		/* compare SSID */
    303   1.1.1.5  christos 		if (ssid->ssid_len == 0 || ssid->ssid_len != new_ssid->ssid_len)
    304   1.1.1.5  christos 			continue;
    305   1.1.1.5  christos 
    306   1.1.1.5  christos 		if (ssid->ssid && new_ssid->ssid) {
    307   1.1.1.5  christos 			if (os_memcmp(ssid->ssid, new_ssid->ssid,
    308   1.1.1.5  christos 				      ssid->ssid_len) != 0)
    309   1.1.1.5  christos 				continue;
    310   1.1.1.5  christos 		} else if (ssid->ssid || new_ssid->ssid)
    311   1.1.1.5  christos 			continue;
    312   1.1.1.5  christos 
    313   1.1.1.5  christos 		/* compare security parameters */
    314   1.1.1.5  christos 		if (ssid->auth_alg != new_ssid->auth_alg ||
    315   1.1.1.5  christos 		    ssid->key_mgmt != new_ssid->key_mgmt ||
    316   1.1.1.6  christos 		    (ssid->group_cipher != new_ssid->group_cipher &&
    317   1.1.1.6  christos 		     !(ssid->group_cipher & new_ssid->group_cipher &
    318   1.1.1.6  christos 		       WPA_CIPHER_CCMP)))
    319   1.1.1.5  christos 			continue;
    320   1.1.1.5  christos 
    321   1.1.1.5  christos 		/*
    322   1.1.1.5  christos 		 * Some existing WPS APs will send two creds in case they are
    323   1.1.1.5  christos 		 * configured for mixed mode operation (WPA+WPA2 and TKIP+CCMP).
    324   1.1.1.5  christos 		 * Try to merge these two creds if they are received in the same
    325   1.1.1.5  christos 		 * M8 message.
    326   1.1.1.5  christos 		 */
    327   1.1.1.5  christos 		if (ssid->wps_run && ssid->wps_run == new_ssid->wps_run &&
    328   1.1.1.5  christos 		    wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
    329   1.1.1.5  christos 			if (new_ssid->passphrase && ssid->passphrase &&
    330   1.1.1.5  christos 			    os_strcmp(new_ssid->passphrase, ssid->passphrase) !=
    331   1.1.1.5  christos 			    0) {
    332   1.1.1.5  christos 				wpa_printf(MSG_DEBUG,
    333   1.1.1.5  christos 					   "WPS: M8 Creds with different passphrase - do not merge");
    334   1.1.1.5  christos 				continue;
    335   1.1.1.5  christos 			}
    336   1.1.1.5  christos 
    337   1.1.1.5  christos 			if (new_ssid->psk_set &&
    338   1.1.1.5  christos 			    (!ssid->psk_set ||
    339   1.1.1.5  christos 			     os_memcmp(new_ssid->psk, ssid->psk, 32) != 0)) {
    340   1.1.1.5  christos 				wpa_printf(MSG_DEBUG,
    341   1.1.1.5  christos 					   "WPS: M8 Creds with different PSK - do not merge");
    342   1.1.1.5  christos 				continue;
    343   1.1.1.5  christos 			}
    344   1.1.1.5  christos 
    345   1.1.1.5  christos 			if ((new_ssid->passphrase && !ssid->passphrase) ||
    346   1.1.1.5  christos 			    (!new_ssid->passphrase && ssid->passphrase)) {
    347   1.1.1.5  christos 				wpa_printf(MSG_DEBUG,
    348   1.1.1.5  christos 					   "WPS: M8 Creds with different passphrase/PSK type - do not merge");
    349   1.1.1.5  christos 				continue;
    350   1.1.1.5  christos 			}
    351   1.1.1.5  christos 
    352   1.1.1.5  christos 			wpa_printf(MSG_DEBUG,
    353   1.1.1.5  christos 				   "WPS: Workaround - merge likely WPA/WPA2-mixed mode creds in same M8 message");
    354   1.1.1.5  christos 			new_ssid->proto |= ssid->proto;
    355   1.1.1.5  christos 			new_ssid->pairwise_cipher |= ssid->pairwise_cipher;
    356   1.1.1.5  christos 		} else {
    357   1.1.1.5  christos 			/*
    358   1.1.1.5  christos 			 * proto and pairwise_cipher difference matter for
    359   1.1.1.5  christos 			 * non-mixed-mode creds.
    360   1.1.1.5  christos 			 */
    361   1.1.1.5  christos 			if (ssid->proto != new_ssid->proto ||
    362   1.1.1.5  christos 			    ssid->pairwise_cipher != new_ssid->pairwise_cipher)
    363   1.1.1.5  christos 				continue;
    364   1.1.1.5  christos 		}
    365   1.1.1.5  christos 
    366   1.1.1.5  christos 		/* Remove the duplicated older network entry. */
    367   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id);
    368   1.1.1.5  christos 		wpas_notify_network_removed(wpa_s, ssid);
    369   1.1.1.5  christos 		wpa_config_remove_network(wpa_s->conf, ssid->id);
    370   1.1.1.5  christos 	}
    371   1.1.1.5  christos }
    372   1.1.1.5  christos 
    373   1.1.1.5  christos 
    374       1.1  christos static int wpa_supplicant_wps_cred(void *ctx,
    375       1.1  christos 				   const struct wps_credential *cred)
    376       1.1  christos {
    377       1.1  christos 	struct wpa_supplicant *wpa_s = ctx;
    378       1.1  christos 	struct wpa_ssid *ssid = wpa_s->current_ssid;
    379       1.1  christos 	u16 auth_type;
    380   1.1.1.2  christos #ifdef CONFIG_WPS_REG_DISABLE_OPEN
    381   1.1.1.2  christos 	int registrar = 0;
    382   1.1.1.2  christos #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
    383  1.1.1.10  christos 	bool add_sae;
    384       1.1  christos 
    385       1.1  christos 	if ((wpa_s->conf->wps_cred_processing == 1 ||
    386       1.1  christos 	     wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
    387       1.1  christos 		size_t blen = cred->cred_attr_len * 2 + 1;
    388       1.1  christos 		char *buf = os_malloc(blen);
    389       1.1  christos 		if (buf) {
    390       1.1  christos 			wpa_snprintf_hex(buf, blen,
    391       1.1  christos 					 cred->cred_attr, cred->cred_attr_len);
    392       1.1  christos 			wpa_msg(wpa_s, MSG_INFO, "%s%s",
    393       1.1  christos 				WPS_EVENT_CRED_RECEIVED, buf);
    394       1.1  christos 			os_free(buf);
    395       1.1  christos 		}
    396       1.1  christos 
    397       1.1  christos 		wpas_notify_wps_credential(wpa_s, cred);
    398       1.1  christos 	} else
    399       1.1  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
    400       1.1  christos 
    401       1.1  christos 	wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
    402       1.1  christos 			cred->cred_attr, cred->cred_attr_len);
    403       1.1  christos 
    404       1.1  christos 	if (wpa_s->conf->wps_cred_processing == 1)
    405       1.1  christos 		return 0;
    406       1.1  christos 
    407       1.1  christos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
    408       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
    409       1.1  christos 		   cred->auth_type);
    410       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
    411       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
    412       1.1  christos 	wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
    413       1.1  christos 			cred->key, cred->key_len);
    414       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
    415       1.1  christos 		   MAC2STR(cred->mac_addr));
    416       1.1  christos 
    417       1.1  christos 	auth_type = cred->auth_type;
    418       1.1  christos 	if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
    419       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Workaround - convert mixed-mode "
    420       1.1  christos 			   "auth_type into WPA2PSK");
    421       1.1  christos 		auth_type = WPS_AUTH_WPA2PSK;
    422       1.1  christos 	}
    423       1.1  christos 
    424       1.1  christos 	if (auth_type != WPS_AUTH_OPEN &&
    425       1.1  christos 	    auth_type != WPS_AUTH_WPAPSK &&
    426       1.1  christos 	    auth_type != WPS_AUTH_WPA2PSK) {
    427       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for "
    428       1.1  christos 			   "unsupported authentication type 0x%x",
    429       1.1  christos 			   auth_type);
    430       1.1  christos 		return 0;
    431       1.1  christos 	}
    432       1.1  christos 
    433   1.1.1.4  christos 	if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) {
    434   1.1.1.4  christos 		if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) {
    435   1.1.1.4  christos 			wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with "
    436   1.1.1.4  christos 				   "invalid Network Key length %lu",
    437   1.1.1.4  christos 				   (unsigned long) cred->key_len);
    438   1.1.1.4  christos 			return -1;
    439   1.1.1.4  christos 		}
    440   1.1.1.4  christos 	}
    441   1.1.1.4  christos 
    442       1.1  christos 	if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
    443       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
    444       1.1  christos 			   "on the received credential");
    445   1.1.1.2  christos #ifdef CONFIG_WPS_REG_DISABLE_OPEN
    446   1.1.1.2  christos 		if (ssid->eap.identity &&
    447   1.1.1.2  christos 		    ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
    448   1.1.1.2  christos 		    os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
    449   1.1.1.2  christos 			      WSC_ID_REGISTRAR_LEN) == 0)
    450   1.1.1.2  christos 			registrar = 1;
    451   1.1.1.2  christos #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
    452       1.1  christos 		os_free(ssid->eap.identity);
    453       1.1  christos 		ssid->eap.identity = NULL;
    454       1.1  christos 		ssid->eap.identity_len = 0;
    455       1.1  christos 		os_free(ssid->eap.phase1);
    456       1.1  christos 		ssid->eap.phase1 = NULL;
    457       1.1  christos 		os_free(ssid->eap.eap_methods);
    458       1.1  christos 		ssid->eap.eap_methods = NULL;
    459   1.1.1.4  christos 		if (!ssid->p2p_group) {
    460   1.1.1.2  christos 			ssid->temporary = 0;
    461   1.1.1.4  christos 			ssid->bssid_set = 0;
    462   1.1.1.4  christos 		}
    463   1.1.1.4  christos 		ssid->disabled_until.sec = 0;
    464   1.1.1.4  christos 		ssid->disabled_until.usec = 0;
    465   1.1.1.4  christos 		ssid->auth_failures = 0;
    466       1.1  christos 	} else {
    467       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
    468       1.1  christos 			   "received credential");
    469       1.1  christos 		ssid = wpa_config_add_network(wpa_s->conf);
    470       1.1  christos 		if (ssid == NULL)
    471       1.1  christos 			return -1;
    472   1.1.1.5  christos 		if (wpa_s->current_ssid) {
    473   1.1.1.5  christos 			/*
    474   1.1.1.5  christos 			 * Should the GO issue multiple credentials for some
    475   1.1.1.5  christos 			 * reason, each credential should be marked as a
    476   1.1.1.5  christos 			 * temporary P2P group similarly to the one that gets
    477   1.1.1.5  christos 			 * marked as such based on the pre-configured values
    478   1.1.1.5  christos 			 * used for the WPS network block.
    479   1.1.1.5  christos 			 */
    480   1.1.1.5  christos 			ssid->p2p_group = wpa_s->current_ssid->p2p_group;
    481   1.1.1.5  christos 			ssid->temporary = wpa_s->current_ssid->temporary;
    482   1.1.1.5  christos 		}
    483       1.1  christos 		wpas_notify_network_added(wpa_s, ssid);
    484       1.1  christos 	}
    485       1.1  christos 
    486       1.1  christos 	wpa_config_set_network_defaults(ssid);
    487   1.1.1.5  christos 	ssid->wps_run = wpa_s->wps_run;
    488       1.1  christos 
    489       1.1  christos 	os_free(ssid->ssid);
    490       1.1  christos 	ssid->ssid = os_malloc(cred->ssid_len);
    491       1.1  christos 	if (ssid->ssid) {
    492       1.1  christos 		os_memcpy(ssid->ssid, cred->ssid, cred->ssid_len);
    493       1.1  christos 		ssid->ssid_len = cred->ssid_len;
    494       1.1  christos 	}
    495       1.1  christos 
    496       1.1  christos 	switch (cred->encr_type) {
    497       1.1  christos 	case WPS_ENCR_NONE:
    498       1.1  christos 		break;
    499       1.1  christos 	case WPS_ENCR_TKIP:
    500  1.1.1.10  christos 		ssid->pairwise_cipher = WPA_CIPHER_TKIP | WPA_CIPHER_CCMP;
    501       1.1  christos 		break;
    502       1.1  christos 	case WPS_ENCR_AES:
    503       1.1  christos 		ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    504   1.1.1.6  christos 		if (wpa_s->drv_capa_known &&
    505   1.1.1.6  christos 		    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP)) {
    506   1.1.1.6  christos 			ssid->pairwise_cipher |= WPA_CIPHER_GCMP;
    507   1.1.1.6  christos 			ssid->group_cipher |= WPA_CIPHER_GCMP;
    508   1.1.1.6  christos 		}
    509   1.1.1.8  christos 		if (wpa_s->drv_capa_known &&
    510   1.1.1.8  christos 		    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)) {
    511   1.1.1.8  christos 			ssid->pairwise_cipher |= WPA_CIPHER_GCMP_256;
    512   1.1.1.8  christos 			ssid->group_cipher |= WPA_CIPHER_GCMP_256;
    513   1.1.1.8  christos 		}
    514   1.1.1.8  christos 		if (wpa_s->drv_capa_known &&
    515   1.1.1.8  christos 		    (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256)) {
    516   1.1.1.8  christos 			ssid->pairwise_cipher |= WPA_CIPHER_CCMP_256;
    517   1.1.1.8  christos 			ssid->group_cipher |= WPA_CIPHER_CCMP_256;
    518   1.1.1.8  christos 		}
    519       1.1  christos 		break;
    520       1.1  christos 	}
    521       1.1  christos 
    522       1.1  christos 	switch (auth_type) {
    523       1.1  christos 	case WPS_AUTH_OPEN:
    524       1.1  christos 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    525       1.1  christos 		ssid->key_mgmt = WPA_KEY_MGMT_NONE;
    526       1.1  christos 		ssid->proto = 0;
    527   1.1.1.2  christos #ifdef CONFIG_WPS_REG_DISABLE_OPEN
    528   1.1.1.2  christos 		if (registrar) {
    529   1.1.1.2  christos 			wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OPEN_NETWORK
    530   1.1.1.2  christos 				"id=%d - Credentials for an open "
    531   1.1.1.2  christos 				"network disabled by default - use "
    532   1.1.1.2  christos 				"'select_network %d' to enable",
    533   1.1.1.2  christos 				ssid->id, ssid->id);
    534   1.1.1.2  christos 			ssid->disabled = 1;
    535   1.1.1.2  christos 		}
    536   1.1.1.2  christos #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
    537       1.1  christos 		break;
    538       1.1  christos 	case WPS_AUTH_WPAPSK:
    539       1.1  christos 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    540       1.1  christos 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    541  1.1.1.10  christos 		ssid->proto = WPA_PROTO_WPA | WPA_PROTO_RSN;
    542       1.1  christos 		break;
    543       1.1  christos 	case WPS_AUTH_WPA2PSK:
    544       1.1  christos 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    545       1.1  christos 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    546  1.1.1.10  christos 		add_sae = wpa_s->conf->wps_cred_add_sae;
    547  1.1.1.10  christos #ifdef CONFIG_P2P
    548  1.1.1.10  christos 		if (ssid->p2p_group && is_p2p_6ghz_capable(wpa_s->global->p2p))
    549  1.1.1.10  christos 			add_sae = true;
    550  1.1.1.10  christos #endif /* CONFIG_P2P */
    551  1.1.1.10  christos 		if (add_sae && cred->key_len != 2 * PMK_LEN) {
    552  1.1.1.10  christos 			ssid->auth_alg = 0;
    553   1.1.1.9  christos 			ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
    554   1.1.1.9  christos 			ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
    555   1.1.1.9  christos 		}
    556       1.1  christos 		ssid->proto = WPA_PROTO_RSN;
    557       1.1  christos 		break;
    558       1.1  christos 	}
    559       1.1  christos 
    560   1.1.1.9  christos 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
    561       1.1  christos 		if (cred->key_len == 2 * PMK_LEN) {
    562       1.1  christos 			if (hexstr2bin((const char *) cred->key, ssid->psk,
    563       1.1  christos 				       PMK_LEN)) {
    564       1.1  christos 				wpa_printf(MSG_ERROR, "WPS: Invalid Network "
    565       1.1  christos 					   "Key");
    566       1.1  christos 				return -1;
    567       1.1  christos 			}
    568       1.1  christos 			ssid->psk_set = 1;
    569   1.1.1.2  christos 			ssid->export_keys = 1;
    570       1.1  christos 		} else if (cred->key_len >= 8 && cred->key_len < 2 * PMK_LEN) {
    571       1.1  christos 			os_free(ssid->passphrase);
    572       1.1  christos 			ssid->passphrase = os_malloc(cred->key_len + 1);
    573       1.1  christos 			if (ssid->passphrase == NULL)
    574       1.1  christos 				return -1;
    575       1.1  christos 			os_memcpy(ssid->passphrase, cred->key, cred->key_len);
    576       1.1  christos 			ssid->passphrase[cred->key_len] = '\0';
    577       1.1  christos 			wpa_config_update_psk(ssid);
    578   1.1.1.2  christos 			ssid->export_keys = 1;
    579       1.1  christos 		} else {
    580       1.1  christos 			wpa_printf(MSG_ERROR, "WPS: Invalid Network Key "
    581       1.1  christos 				   "length %lu",
    582       1.1  christos 				   (unsigned long) cred->key_len);
    583       1.1  christos 			return -1;
    584       1.1  christos 		}
    585       1.1  christos 	}
    586   1.1.1.7  christos 	ssid->priority = wpa_s->conf->wps_priority;
    587       1.1  christos 
    588       1.1  christos 	wpas_wps_security_workaround(wpa_s, ssid, cred);
    589       1.1  christos 
    590   1.1.1.5  christos 	wpas_wps_remove_dup_network(wpa_s, ssid);
    591   1.1.1.4  christos 
    592       1.1  christos #ifndef CONFIG_NO_CONFIG_WRITE
    593       1.1  christos 	if (wpa_s->conf->update_config &&
    594       1.1  christos 	    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
    595       1.1  christos 		wpa_printf(MSG_DEBUG, "WPS: Failed to update configuration");
    596       1.1  christos 		return -1;
    597       1.1  christos 	}
    598       1.1  christos #endif /* CONFIG_NO_CONFIG_WRITE */
    599       1.1  christos 
    600   1.1.1.7  christos 	if (ssid->priority)
    601   1.1.1.7  christos 		wpa_config_update_prio_list(wpa_s->conf);
    602   1.1.1.7  christos 
    603   1.1.1.4  christos 	/*
    604   1.1.1.4  christos 	 * Optimize the post-WPS scan based on the channel used during
    605   1.1.1.4  christos 	 * the provisioning in case EAP-Failure is not received.
    606   1.1.1.4  christos 	 */
    607   1.1.1.4  christos 	wpa_s->after_wps = 5;
    608   1.1.1.4  christos 	wpa_s->wps_freq = wpa_s->assoc_freq;
    609   1.1.1.4  christos 
    610       1.1  christos 	return 0;
    611       1.1  christos }
    612       1.1  christos 
    613       1.1  christos 
    614       1.1  christos static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
    615       1.1  christos 					 struct wps_event_m2d *m2d)
    616       1.1  christos {
    617       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
    618       1.1  christos 		"dev_password_id=%d config_error=%d",
    619       1.1  christos 		m2d->dev_password_id, m2d->config_error);
    620       1.1  christos 	wpas_notify_wps_event_m2d(wpa_s, m2d);
    621   1.1.1.2  christos #ifdef CONFIG_P2P
    622   1.1.1.7  christos 	if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s) {
    623   1.1.1.7  christos 		wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_M2D
    624   1.1.1.2  christos 			"dev_password_id=%d config_error=%d",
    625   1.1.1.2  christos 			m2d->dev_password_id, m2d->config_error);
    626   1.1.1.2  christos 	}
    627   1.1.1.2  christos 	if (m2d->config_error == WPS_CFG_MULTIPLE_PBC_DETECTED) {
    628   1.1.1.2  christos 		/*
    629   1.1.1.2  christos 		 * Notify P2P from eloop timeout to avoid issues with the
    630   1.1.1.2  christos 		 * interface getting removed while processing a message.
    631   1.1.1.2  christos 		 */
    632   1.1.1.5  christos 		eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, wpa_s,
    633   1.1.1.2  christos 				       NULL);
    634   1.1.1.2  christos 	}
    635   1.1.1.2  christos #endif /* CONFIG_P2P */
    636       1.1  christos }
    637       1.1  christos 
    638       1.1  christos 
    639   1.1.1.5  christos static void wpas_wps_clear_timeout(void *eloop_ctx, void *timeout_ctx)
    640   1.1.1.5  christos {
    641   1.1.1.5  christos 	struct wpa_supplicant *wpa_s = eloop_ctx;
    642   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "WPS: Clear WPS network from timeout");
    643   1.1.1.5  christos 	wpas_clear_wps(wpa_s);
    644   1.1.1.5  christos }
    645   1.1.1.5  christos 
    646   1.1.1.2  christos 
    647       1.1  christos static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
    648       1.1  christos 					  struct wps_event_fail *fail)
    649       1.1  christos {
    650   1.1.1.2  christos 	if (fail->error_indication > 0 &&
    651   1.1.1.2  christos 	    fail->error_indication < NUM_WPS_EI_VALUES) {
    652   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_INFO,
    653   1.1.1.2  christos 			WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
    654   1.1.1.2  christos 			fail->msg, fail->config_error, fail->error_indication,
    655   1.1.1.5  christos 			wps_ei_str(fail->error_indication));
    656   1.1.1.7  christos 		if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
    657   1.1.1.7  christos 			wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
    658   1.1.1.2  christos 				"msg=%d config_error=%d reason=%d (%s)",
    659   1.1.1.2  christos 				fail->msg, fail->config_error,
    660   1.1.1.2  christos 				fail->error_indication,
    661   1.1.1.5  christos 				wps_ei_str(fail->error_indication));
    662   1.1.1.2  christos 	} else {
    663   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_INFO,
    664   1.1.1.2  christos 			WPS_EVENT_FAIL "msg=%d config_error=%d",
    665   1.1.1.2  christos 			fail->msg, fail->config_error);
    666   1.1.1.7  christos 		if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
    667   1.1.1.7  christos 			wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
    668   1.1.1.2  christos 				"msg=%d config_error=%d",
    669   1.1.1.2  christos 				fail->msg, fail->config_error);
    670   1.1.1.2  christos 	}
    671   1.1.1.5  christos 
    672   1.1.1.5  christos 	/*
    673   1.1.1.5  christos 	 * Need to allow WPS processing to complete, e.g., by sending WSC_NACK.
    674   1.1.1.5  christos 	 */
    675   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "WPS: Register timeout to clear WPS network");
    676   1.1.1.5  christos 	eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
    677   1.1.1.5  christos 	eloop_register_timeout(0, 100000, wpas_wps_clear_timeout, wpa_s, NULL);
    678   1.1.1.5  christos 
    679       1.1  christos 	wpas_notify_wps_event_fail(wpa_s, fail);
    680   1.1.1.2  christos 	wpas_p2p_wps_failed(wpa_s, fail);
    681       1.1  christos }
    682       1.1  christos 
    683       1.1  christos 
    684   1.1.1.4  christos static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx);
    685   1.1.1.4  christos 
    686   1.1.1.4  christos static void wpas_wps_reenable_networks(struct wpa_supplicant *wpa_s)
    687   1.1.1.4  christos {
    688   1.1.1.4  christos 	struct wpa_ssid *ssid;
    689   1.1.1.4  christos 	int changed = 0;
    690   1.1.1.4  christos 
    691   1.1.1.4  christos 	eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
    692   1.1.1.4  christos 
    693   1.1.1.4  christos 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
    694   1.1.1.4  christos 		if (ssid->disabled_for_connect && ssid->disabled) {
    695   1.1.1.4  christos 			ssid->disabled_for_connect = 0;
    696   1.1.1.4  christos 			ssid->disabled = 0;
    697   1.1.1.4  christos 			wpas_notify_network_enabled_changed(wpa_s, ssid);
    698   1.1.1.4  christos 			changed++;
    699   1.1.1.4  christos 		}
    700   1.1.1.4  christos 	}
    701   1.1.1.4  christos 
    702   1.1.1.4  christos 	if (changed) {
    703   1.1.1.4  christos #ifndef CONFIG_NO_CONFIG_WRITE
    704   1.1.1.4  christos 		if (wpa_s->conf->update_config &&
    705   1.1.1.4  christos 		    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
    706   1.1.1.4  christos 			wpa_printf(MSG_DEBUG, "WPS: Failed to update "
    707   1.1.1.4  christos 				   "configuration");
    708   1.1.1.4  christos 		}
    709   1.1.1.4  christos #endif /* CONFIG_NO_CONFIG_WRITE */
    710   1.1.1.4  christos 	}
    711   1.1.1.4  christos }
    712   1.1.1.4  christos 
    713   1.1.1.4  christos 
    714   1.1.1.4  christos static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx)
    715   1.1.1.4  christos {
    716   1.1.1.4  christos 	struct wpa_supplicant *wpa_s = eloop_ctx;
    717   1.1.1.4  christos 	/* Enable the networks disabled during wpas_wps_reassoc */
    718   1.1.1.4  christos 	wpas_wps_reenable_networks(wpa_s);
    719   1.1.1.4  christos }
    720   1.1.1.4  christos 
    721   1.1.1.4  christos 
    722   1.1.1.7  christos int wpas_wps_reenable_networks_pending(struct wpa_supplicant *wpa_s)
    723   1.1.1.7  christos {
    724   1.1.1.7  christos 	return eloop_is_timeout_registered(wpas_wps_reenable_networks_cb,
    725   1.1.1.7  christos 					   wpa_s, NULL);
    726   1.1.1.7  christos }
    727   1.1.1.7  christos 
    728   1.1.1.7  christos 
    729       1.1  christos static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
    730       1.1  christos {
    731       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
    732       1.1  christos 	wpa_s->wps_success = 1;
    733       1.1  christos 	wpas_notify_wps_event_success(wpa_s);
    734   1.1.1.5  christos 	if (wpa_s->current_ssid)
    735   1.1.1.5  christos 		wpas_clear_temp_disabled(wpa_s, wpa_s->current_ssid, 1);
    736  1.1.1.10  christos 	wpa_s->consecutive_conn_failures = 0;
    737   1.1.1.4  christos 
    738   1.1.1.4  christos 	/*
    739   1.1.1.4  christos 	 * Enable the networks disabled during wpas_wps_reassoc after 10
    740   1.1.1.4  christos 	 * seconds. The 10 seconds timer is to allow the data connection to be
    741   1.1.1.4  christos 	 * formed before allowing other networks to be selected.
    742   1.1.1.4  christos 	 */
    743   1.1.1.4  christos 	eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
    744   1.1.1.4  christos 			       NULL);
    745   1.1.1.4  christos 
    746   1.1.1.2  christos 	wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
    747       1.1  christos }
    748       1.1  christos 
    749       1.1  christos 
    750       1.1  christos static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
    751       1.1  christos 					       struct wps_event_er_ap *ap)
    752       1.1  christos {
    753       1.1  christos 	char uuid_str[100];
    754       1.1  christos 	char dev_type[WPS_DEV_TYPE_BUFSIZE];
    755       1.1  christos 
    756       1.1  christos 	uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
    757       1.1  christos 	if (ap->pri_dev_type)
    758       1.1  christos 		wps_dev_type_bin2str(ap->pri_dev_type, dev_type,
    759       1.1  christos 				     sizeof(dev_type));
    760       1.1  christos 	else
    761       1.1  christos 		dev_type[0] = '\0';
    762       1.1  christos 
    763       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR
    764       1.1  christos 		" pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|",
    765       1.1  christos 		uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state,
    766       1.1  christos 		ap->friendly_name ? ap->friendly_name : "",
    767       1.1  christos 		ap->manufacturer ? ap->manufacturer : "",
    768       1.1  christos 		ap->model_description ? ap->model_description : "",
    769       1.1  christos 		ap->model_name ? ap->model_name : "",
    770       1.1  christos 		ap->manufacturer_url ? ap->manufacturer_url : "",
    771       1.1  christos 		ap->model_url ? ap->model_url : "");
    772       1.1  christos }
    773       1.1  christos 
    774       1.1  christos 
    775       1.1  christos static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
    776       1.1  christos 						  struct wps_event_er_ap *ap)
    777       1.1  christos {
    778       1.1  christos 	char uuid_str[100];
    779       1.1  christos 	uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
    780       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
    781       1.1  christos }
    782       1.1  christos 
    783       1.1  christos 
    784       1.1  christos static void wpa_supplicant_wps_event_er_enrollee_add(
    785       1.1  christos 	struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
    786       1.1  christos {
    787       1.1  christos 	char uuid_str[100];
    788       1.1  christos 	char dev_type[WPS_DEV_TYPE_BUFSIZE];
    789       1.1  christos 
    790       1.1  christos 	uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
    791       1.1  christos 	if (enrollee->pri_dev_type)
    792       1.1  christos 		wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type,
    793       1.1  christos 				     sizeof(dev_type));
    794       1.1  christos 	else
    795       1.1  christos 		dev_type[0] = '\0';
    796       1.1  christos 
    797       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
    798       1.1  christos 		" M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
    799       1.1  christos 		"|%s|%s|%s|%s|%s|",
    800       1.1  christos 		uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
    801       1.1  christos 		enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
    802       1.1  christos 		enrollee->dev_name ? enrollee->dev_name : "",
    803       1.1  christos 		enrollee->manufacturer ? enrollee->manufacturer : "",
    804       1.1  christos 		enrollee->model_name ? enrollee->model_name : "",
    805       1.1  christos 		enrollee->model_number ? enrollee->model_number : "",
    806       1.1  christos 		enrollee->serial_number ? enrollee->serial_number : "");
    807       1.1  christos }
    808       1.1  christos 
    809       1.1  christos 
    810       1.1  christos static void wpa_supplicant_wps_event_er_enrollee_remove(
    811       1.1  christos 	struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
    812       1.1  christos {
    813       1.1  christos 	char uuid_str[100];
    814       1.1  christos 	uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
    815       1.1  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
    816       1.1  christos 		uuid_str, MAC2STR(enrollee->mac_addr));
    817       1.1  christos }
    818       1.1  christos 
    819       1.1  christos 
    820   1.1.1.2  christos static void wpa_supplicant_wps_event_er_ap_settings(
    821   1.1.1.2  christos 	struct wpa_supplicant *wpa_s,
    822   1.1.1.2  christos 	struct wps_event_er_ap_settings *ap_settings)
    823   1.1.1.2  christos {
    824   1.1.1.2  christos 	char uuid_str[100];
    825   1.1.1.2  christos 	char key_str[65];
    826   1.1.1.2  christos 	const struct wps_credential *cred = ap_settings->cred;
    827   1.1.1.2  christos 
    828   1.1.1.2  christos 	key_str[0] = '\0';
    829   1.1.1.2  christos 	if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
    830   1.1.1.2  christos 		if (cred->key_len >= 8 && cred->key_len <= 64) {
    831   1.1.1.2  christos 			os_memcpy(key_str, cred->key, cred->key_len);
    832   1.1.1.2  christos 			key_str[cred->key_len] = '\0';
    833   1.1.1.2  christos 		}
    834   1.1.1.2  christos 	}
    835   1.1.1.2  christos 
    836   1.1.1.2  christos 	uuid_bin2str(ap_settings->uuid, uuid_str, sizeof(uuid_str));
    837   1.1.1.2  christos 	/* Use wpa_msg_ctrl to avoid showing the key in debug log */
    838   1.1.1.2  christos 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_SETTINGS
    839   1.1.1.2  christos 		     "uuid=%s ssid=%s auth_type=0x%04x encr_type=0x%04x "
    840   1.1.1.2  christos 		     "key=%s",
    841   1.1.1.2  christos 		     uuid_str, wpa_ssid_txt(cred->ssid, cred->ssid_len),
    842   1.1.1.2  christos 		     cred->auth_type, cred->encr_type, key_str);
    843   1.1.1.2  christos }
    844   1.1.1.2  christos 
    845   1.1.1.2  christos 
    846   1.1.1.2  christos static void wpa_supplicant_wps_event_er_set_sel_reg(
    847   1.1.1.2  christos 	struct wpa_supplicant *wpa_s,
    848   1.1.1.2  christos 	struct wps_event_er_set_selected_registrar *ev)
    849   1.1.1.2  christos {
    850   1.1.1.2  christos 	char uuid_str[100];
    851   1.1.1.2  christos 
    852   1.1.1.2  christos 	uuid_bin2str(ev->uuid, uuid_str, sizeof(uuid_str));
    853   1.1.1.2  christos 	switch (ev->state) {
    854   1.1.1.2  christos 	case WPS_ER_SET_SEL_REG_START:
    855   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
    856   1.1.1.2  christos 			"uuid=%s state=START sel_reg=%d dev_passwd_id=%u "
    857   1.1.1.2  christos 			"sel_reg_config_methods=0x%x",
    858   1.1.1.2  christos 			uuid_str, ev->sel_reg, ev->dev_passwd_id,
    859   1.1.1.2  christos 			ev->sel_reg_config_methods);
    860   1.1.1.2  christos 		break;
    861   1.1.1.2  christos 	case WPS_ER_SET_SEL_REG_DONE:
    862   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
    863   1.1.1.2  christos 			"uuid=%s state=DONE", uuid_str);
    864   1.1.1.2  christos 		break;
    865   1.1.1.2  christos 	case WPS_ER_SET_SEL_REG_FAILED:
    866   1.1.1.2  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_SET_SEL_REG
    867   1.1.1.2  christos 			"uuid=%s state=FAILED", uuid_str);
    868   1.1.1.2  christos 		break;
    869   1.1.1.2  christos 	}
    870   1.1.1.2  christos }
    871   1.1.1.2  christos 
    872   1.1.1.2  christos 
    873       1.1  christos static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
    874       1.1  christos 				     union wps_event_data *data)
    875       1.1  christos {
    876       1.1  christos 	struct wpa_supplicant *wpa_s = ctx;
    877       1.1  christos 	switch (event) {
    878       1.1  christos 	case WPS_EV_M2D:
    879       1.1  christos 		wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
    880       1.1  christos 		break;
    881       1.1  christos 	case WPS_EV_FAIL:
    882       1.1  christos 		wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
    883       1.1  christos 		break;
    884       1.1  christos 	case WPS_EV_SUCCESS:
    885       1.1  christos 		wpa_supplicant_wps_event_success(wpa_s);
    886       1.1  christos 		break;
    887       1.1  christos 	case WPS_EV_PWD_AUTH_FAIL:
    888   1.1.1.2  christos #ifdef CONFIG_AP
    889   1.1.1.2  christos 		if (wpa_s->ap_iface && data->pwd_auth_fail.enrollee)
    890   1.1.1.2  christos 			wpa_supplicant_ap_pwd_auth_fail(wpa_s);
    891   1.1.1.2  christos #endif /* CONFIG_AP */
    892       1.1  christos 		break;
    893       1.1  christos 	case WPS_EV_PBC_OVERLAP:
    894       1.1  christos 		break;
    895       1.1  christos 	case WPS_EV_PBC_TIMEOUT:
    896       1.1  christos 		break;
    897   1.1.1.5  christos 	case WPS_EV_PBC_ACTIVE:
    898   1.1.1.5  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ACTIVE);
    899   1.1.1.5  christos 		break;
    900   1.1.1.5  christos 	case WPS_EV_PBC_DISABLE:
    901   1.1.1.5  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_DISABLE);
    902   1.1.1.5  christos 		break;
    903       1.1  christos 	case WPS_EV_ER_AP_ADD:
    904       1.1  christos 		wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
    905       1.1  christos 		break;
    906       1.1  christos 	case WPS_EV_ER_AP_REMOVE:
    907       1.1  christos 		wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
    908       1.1  christos 		break;
    909       1.1  christos 	case WPS_EV_ER_ENROLLEE_ADD:
    910       1.1  christos 		wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
    911       1.1  christos 							 &data->enrollee);
    912       1.1  christos 		break;
    913       1.1  christos 	case WPS_EV_ER_ENROLLEE_REMOVE:
    914       1.1  christos 		wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
    915       1.1  christos 							    &data->enrollee);
    916       1.1  christos 		break;
    917   1.1.1.2  christos 	case WPS_EV_ER_AP_SETTINGS:
    918   1.1.1.2  christos 		wpa_supplicant_wps_event_er_ap_settings(wpa_s,
    919   1.1.1.2  christos 							&data->ap_settings);
    920   1.1.1.2  christos 		break;
    921   1.1.1.2  christos 	case WPS_EV_ER_SET_SELECTED_REGISTRAR:
    922   1.1.1.2  christos 		wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
    923   1.1.1.2  christos 							&data->set_sel_reg);
    924   1.1.1.2  christos 		break;
    925   1.1.1.2  christos 	case WPS_EV_AP_PIN_SUCCESS:
    926   1.1.1.2  christos 		break;
    927       1.1  christos 	}
    928       1.1  christos }
    929       1.1  christos 
    930       1.1  christos 
    931   1.1.1.5  christos static int wpa_supplicant_wps_rf_band(void *ctx)
    932   1.1.1.5  christos {
    933   1.1.1.5  christos 	struct wpa_supplicant *wpa_s = ctx;
    934   1.1.1.5  christos 
    935   1.1.1.5  christos 	if (!wpa_s->current_ssid || !wpa_s->assoc_freq)
    936   1.1.1.5  christos 		return 0;
    937   1.1.1.5  christos 
    938   1.1.1.7  christos 	return (wpa_s->assoc_freq > 50000) ? WPS_RF_60GHZ :
    939   1.1.1.7  christos 		(wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ;
    940   1.1.1.5  christos }
    941   1.1.1.5  christos 
    942   1.1.1.5  christos 
    943       1.1  christos enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
    944       1.1  christos {
    945       1.1  christos 	if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
    946       1.1  christos 	    eap_is_wps_pin_enrollee(&ssid->eap))
    947       1.1  christos 		return WPS_REQ_ENROLLEE;
    948       1.1  christos 	else
    949       1.1  christos 		return WPS_REQ_REGISTRAR;
    950       1.1  christos }
    951       1.1  christos 
    952       1.1  christos 
    953       1.1  christos static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
    954       1.1  christos {
    955       1.1  christos 	int id;
    956   1.1.1.2  christos 	struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
    957   1.1.1.2  christos 
    958   1.1.1.5  christos 	wpa_s->after_wps = 0;
    959   1.1.1.5  christos 	wpa_s->known_wps_freq = 0;
    960   1.1.1.5  christos 
    961   1.1.1.2  christos 	prev_current = wpa_s->current_ssid;
    962       1.1  christos 
    963   1.1.1.4  christos 	/* Enable the networks disabled during wpas_wps_reassoc */
    964   1.1.1.4  christos 	wpas_wps_reenable_networks(wpa_s);
    965   1.1.1.4  christos 
    966       1.1  christos 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
    967   1.1.1.5  christos 	eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
    968       1.1  christos 
    969       1.1  christos 	/* Remove any existing WPS network from configuration */
    970       1.1  christos 	ssid = wpa_s->conf->ssid;
    971       1.1  christos 	while (ssid) {
    972       1.1  christos 		if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
    973       1.1  christos 			if (ssid == wpa_s->current_ssid) {
    974   1.1.1.6  christos 				wpa_s->own_disconnect_req = 1;
    975   1.1.1.5  christos 				wpa_supplicant_deauthenticate(
    976   1.1.1.5  christos 					wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    977       1.1  christos 			}
    978       1.1  christos 			id = ssid->id;
    979       1.1  christos 			remove_ssid = ssid;
    980       1.1  christos 		} else
    981       1.1  christos 			id = -1;
    982       1.1  christos 		ssid = ssid->next;
    983       1.1  christos 		if (id >= 0) {
    984   1.1.1.2  christos 			if (prev_current == remove_ssid) {
    985   1.1.1.2  christos 				wpa_sm_set_config(wpa_s->wpa, NULL);
    986   1.1.1.2  christos 				eapol_sm_notify_config(wpa_s->eapol, NULL,
    987   1.1.1.2  christos 						       NULL);
    988   1.1.1.2  christos 			}
    989       1.1  christos 			wpas_notify_network_removed(wpa_s, remove_ssid);
    990       1.1  christos 			wpa_config_remove_network(wpa_s->conf, id);
    991       1.1  christos 		}
    992       1.1  christos 	}
    993   1.1.1.4  christos 
    994   1.1.1.4  christos 	wpas_wps_clear_ap_info(wpa_s);
    995       1.1  christos }
    996       1.1  christos 
    997       1.1  christos 
    998       1.1  christos static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
    999       1.1  christos {
   1000       1.1  christos 	struct wpa_supplicant *wpa_s = eloop_ctx;
   1001   1.1.1.7  christos 	union wps_event_data data;
   1002   1.1.1.7  christos 
   1003   1.1.1.2  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
   1004   1.1.1.2  christos 		"out");
   1005   1.1.1.7  christos 	os_memset(&data, 0, sizeof(data));
   1006   1.1.1.7  christos 	data.fail.config_error = WPS_CFG_MSG_TIMEOUT;
   1007   1.1.1.7  christos 	data.fail.error_indication = WPS_EI_NO_ERROR;
   1008   1.1.1.7  christos 	/*
   1009   1.1.1.7  christos 	 * Call wpas_notify_wps_event_fail() directly instead of through
   1010   1.1.1.7  christos 	 * wpa_supplicant_wps_event() which would end up registering unnecessary
   1011   1.1.1.7  christos 	 * timeouts (those are only for the case where the failure happens
   1012   1.1.1.7  christos 	 * during an EAP-WSC exchange).
   1013   1.1.1.7  christos 	 */
   1014   1.1.1.7  christos 	wpas_notify_wps_event_fail(wpa_s, &data.fail);
   1015  1.1.1.10  christos 	wpa_s->supp_pbc_active = false;
   1016  1.1.1.10  christos 	wpa_s->wps_overlap = false;
   1017       1.1  christos 	wpas_clear_wps(wpa_s);
   1018       1.1  christos }
   1019       1.1  christos 
   1020       1.1  christos 
   1021       1.1  christos static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
   1022   1.1.1.5  christos 					      int registrar, const u8 *dev_addr,
   1023   1.1.1.5  christos 					      const u8 *bssid)
   1024       1.1  christos {
   1025       1.1  christos 	struct wpa_ssid *ssid;
   1026       1.1  christos 
   1027       1.1  christos 	ssid = wpa_config_add_network(wpa_s->conf);
   1028       1.1  christos 	if (ssid == NULL)
   1029       1.1  christos 		return NULL;
   1030       1.1  christos 	wpas_notify_network_added(wpa_s, ssid);
   1031       1.1  christos 	wpa_config_set_network_defaults(ssid);
   1032   1.1.1.2  christos 	ssid->temporary = 1;
   1033       1.1  christos 	if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
   1034       1.1  christos 	    wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
   1035       1.1  christos 	    wpa_config_set(ssid, "identity", registrar ?
   1036       1.1  christos 			   "\"" WSC_ID_REGISTRAR "\"" :
   1037       1.1  christos 			   "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
   1038       1.1  christos 		wpas_notify_network_removed(wpa_s, ssid);
   1039       1.1  christos 		wpa_config_remove_network(wpa_s->conf, ssid->id);
   1040       1.1  christos 		return NULL;
   1041       1.1  christos 	}
   1042       1.1  christos 
   1043   1.1.1.5  christos #ifdef CONFIG_P2P
   1044   1.1.1.5  christos 	if (dev_addr)
   1045   1.1.1.5  christos 		os_memcpy(ssid->go_p2p_dev_addr, dev_addr, ETH_ALEN);
   1046   1.1.1.5  christos #endif /* CONFIG_P2P */
   1047   1.1.1.5  christos 
   1048       1.1  christos 	if (bssid) {
   1049   1.1.1.2  christos #ifndef CONFIG_P2P
   1050       1.1  christos 		struct wpa_bss *bss;
   1051       1.1  christos 		int count = 0;
   1052   1.1.1.2  christos #endif /* CONFIG_P2P */
   1053       1.1  christos 
   1054       1.1  christos 		os_memcpy(ssid->bssid, bssid, ETH_ALEN);
   1055       1.1  christos 		ssid->bssid_set = 1;
   1056       1.1  christos 
   1057   1.1.1.2  christos 		/*
   1058   1.1.1.2  christos 		 * Note: With P2P, the SSID may change at the time the WPS
   1059   1.1.1.2  christos 		 * provisioning is started, so better not filter the AP based
   1060   1.1.1.2  christos 		 * on the current SSID in the scan results.
   1061   1.1.1.2  christos 		 */
   1062   1.1.1.2  christos #ifndef CONFIG_P2P
   1063       1.1  christos 		dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
   1064  1.1.1.10  christos 			if (!ether_addr_equal(bssid, bss->bssid))
   1065       1.1  christos 				continue;
   1066       1.1  christos 
   1067       1.1  christos 			os_free(ssid->ssid);
   1068   1.1.1.8  christos 			ssid->ssid = os_memdup(bss->ssid, bss->ssid_len);
   1069       1.1  christos 			if (ssid->ssid == NULL)
   1070       1.1  christos 				break;
   1071       1.1  christos 			ssid->ssid_len = bss->ssid_len;
   1072       1.1  christos 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
   1073       1.1  christos 					  "scan results",
   1074       1.1  christos 					  ssid->ssid, ssid->ssid_len);
   1075       1.1  christos 			count++;
   1076       1.1  christos 		}
   1077       1.1  christos 
   1078       1.1  christos 		if (count > 1) {
   1079       1.1  christos 			wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
   1080       1.1  christos 				   "for the AP; use wildcard");
   1081       1.1  christos 			os_free(ssid->ssid);
   1082       1.1  christos 			ssid->ssid = NULL;
   1083       1.1  christos 			ssid->ssid_len = 0;
   1084       1.1  christos 		}
   1085   1.1.1.2  christos #endif /* CONFIG_P2P */
   1086       1.1  christos 	}
   1087       1.1  christos 
   1088       1.1  christos 	return ssid;
   1089       1.1  christos }
   1090       1.1  christos 
   1091       1.1  christos 
   1092   1.1.1.5  christos static void wpas_wps_temp_disable(struct wpa_supplicant *wpa_s,
   1093   1.1.1.5  christos 				  struct wpa_ssid *selected)
   1094       1.1  christos {
   1095       1.1  christos 	struct wpa_ssid *ssid;
   1096       1.1  christos 
   1097   1.1.1.6  christos 	if (wpa_s->current_ssid) {
   1098   1.1.1.6  christos 		wpa_s->own_disconnect_req = 1;
   1099   1.1.1.2  christos 		wpa_supplicant_deauthenticate(
   1100   1.1.1.2  christos 			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
   1101   1.1.1.6  christos 	}
   1102   1.1.1.2  christos 
   1103       1.1  christos 	/* Mark all other networks disabled and trigger reassociation */
   1104       1.1  christos 	ssid = wpa_s->conf->ssid;
   1105       1.1  christos 	while (ssid) {
   1106       1.1  christos 		int was_disabled = ssid->disabled;
   1107   1.1.1.4  christos 		ssid->disabled_for_connect = 0;
   1108   1.1.1.2  christos 		/*
   1109   1.1.1.2  christos 		 * In case the network object corresponds to a persistent group
   1110   1.1.1.2  christos 		 * then do not send out network disabled signal. In addition,
   1111   1.1.1.2  christos 		 * do not change disabled status of persistent network objects
   1112   1.1.1.2  christos 		 * from 2 to 1 should we connect to another network.
   1113   1.1.1.2  christos 		 */
   1114   1.1.1.2  christos 		if (was_disabled != 2) {
   1115   1.1.1.2  christos 			ssid->disabled = ssid != selected;
   1116   1.1.1.4  christos 			if (was_disabled != ssid->disabled) {
   1117   1.1.1.4  christos 				if (ssid->disabled)
   1118   1.1.1.4  christos 					ssid->disabled_for_connect = 1;
   1119   1.1.1.2  christos 				wpas_notify_network_enabled_changed(wpa_s,
   1120   1.1.1.2  christos 								    ssid);
   1121   1.1.1.4  christos 			}
   1122   1.1.1.2  christos 		}
   1123       1.1  christos 		ssid = ssid->next;
   1124       1.1  christos 	}
   1125   1.1.1.5  christos }
   1126   1.1.1.5  christos 
   1127   1.1.1.5  christos 
   1128   1.1.1.5  christos static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
   1129   1.1.1.5  christos 			     struct wpa_ssid *selected, const u8 *bssid,
   1130   1.1.1.5  christos 			     int freq)
   1131   1.1.1.5  christos {
   1132   1.1.1.5  christos 	struct wpa_bss *bss;
   1133   1.1.1.5  christos 
   1134   1.1.1.5  christos 	wpa_s->wps_run++;
   1135   1.1.1.5  christos 	if (wpa_s->wps_run == 0)
   1136   1.1.1.5  christos 		wpa_s->wps_run++;
   1137   1.1.1.5  christos 	wpa_s->after_wps = 0;
   1138   1.1.1.5  christos 	wpa_s->known_wps_freq = 0;
   1139   1.1.1.5  christos 	if (freq) {
   1140   1.1.1.5  christos 		wpa_s->after_wps = 5;
   1141   1.1.1.5  christos 		wpa_s->wps_freq = freq;
   1142   1.1.1.5  christos 	} else if (bssid) {
   1143   1.1.1.5  christos 		bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
   1144   1.1.1.5  christos 		if (bss && bss->freq > 0) {
   1145   1.1.1.5  christos 			wpa_s->known_wps_freq = 1;
   1146   1.1.1.5  christos 			wpa_s->wps_freq = bss->freq;
   1147   1.1.1.5  christos 		}
   1148   1.1.1.5  christos 	}
   1149   1.1.1.5  christos 
   1150   1.1.1.5  christos 	wpas_wps_temp_disable(wpa_s, selected);
   1151   1.1.1.5  christos 
   1152       1.1  christos 	wpa_s->disconnected = 0;
   1153       1.1  christos 	wpa_s->reassociate = 1;
   1154       1.1  christos 	wpa_s->scan_runs = 0;
   1155   1.1.1.4  christos 	wpa_s->normal_scans = 0;
   1156       1.1  christos 	wpa_s->wps_success = 0;
   1157  1.1.1.10  christos 	wpa_s->bssid_ignore_cleared = false;
   1158   1.1.1.5  christos 
   1159   1.1.1.5  christos 	wpa_supplicant_cancel_sched_scan(wpa_s);
   1160       1.1  christos 	wpa_supplicant_req_scan(wpa_s, 0, 0);
   1161       1.1  christos }
   1162       1.1  christos 
   1163       1.1  christos 
   1164   1.1.1.2  christos int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
   1165   1.1.1.9  christos 		       int p2p_group, int multi_ap_backhaul_sta)
   1166       1.1  christos {
   1167       1.1  christos 	struct wpa_ssid *ssid;
   1168   1.1.1.9  christos 	char phase1[32];
   1169   1.1.1.6  christos 
   1170   1.1.1.6  christos #ifdef CONFIG_AP
   1171   1.1.1.6  christos 	if (wpa_s->ap_iface) {
   1172   1.1.1.6  christos 		wpa_printf(MSG_DEBUG,
   1173   1.1.1.6  christos 			   "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
   1174   1.1.1.6  christos 		return -1;
   1175   1.1.1.6  christos 	}
   1176   1.1.1.6  christos #endif /* CONFIG_AP */
   1177       1.1  christos 	wpas_clear_wps(wpa_s);
   1178   1.1.1.5  christos 	ssid = wpas_wps_add_network(wpa_s, 0, NULL, bssid);
   1179       1.1  christos 	if (ssid == NULL)
   1180       1.1  christos 		return -1;
   1181   1.1.1.2  christos 	ssid->temporary = 1;
   1182   1.1.1.2  christos 	ssid->p2p_group = p2p_group;
   1183   1.1.1.7  christos 	/*
   1184   1.1.1.7  christos 	 * When starting a regular WPS process (not P2P group formation)
   1185   1.1.1.7  christos 	 * the registrar/final station can be either AP or PCP
   1186   1.1.1.7  christos 	 * so use a "don't care" value for the pbss flag.
   1187   1.1.1.7  christos 	 */
   1188   1.1.1.7  christos 	if (!p2p_group)
   1189   1.1.1.7  christos 		ssid->pbss = 2;
   1190   1.1.1.2  christos #ifdef CONFIG_P2P
   1191   1.1.1.2  christos 	if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
   1192   1.1.1.2  christos 		ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
   1193   1.1.1.2  christos 		if (ssid->ssid) {
   1194   1.1.1.2  christos 			ssid->ssid_len = wpa_s->go_params->ssid_len;
   1195   1.1.1.2  christos 			os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
   1196   1.1.1.2  christos 				  ssid->ssid_len);
   1197   1.1.1.7  christos 			if (wpa_s->go_params->freq > 56160) {
   1198   1.1.1.7  christos 				/* P2P in 60 GHz uses PBSS */
   1199   1.1.1.7  christos 				ssid->pbss = 1;
   1200   1.1.1.7  christos 			}
   1201  1.1.1.10  christos 			if (wpa_s->go_params->edmg &&
   1202  1.1.1.10  christos 			    wpas_p2p_try_edmg_channel(wpa_s,
   1203  1.1.1.10  christos 						      wpa_s->go_params) == 0)
   1204  1.1.1.10  christos 				ssid->enable_edmg = 1;
   1205  1.1.1.10  christos 
   1206   1.1.1.2  christos 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
   1207   1.1.1.2  christos 					  "SSID", ssid->ssid, ssid->ssid_len);
   1208   1.1.1.2  christos 		}
   1209   1.1.1.2  christos 	}
   1210   1.1.1.2  christos #endif /* CONFIG_P2P */
   1211  1.1.1.10  christos 	if (multi_ap_backhaul_sta)
   1212  1.1.1.10  christos 		os_snprintf(phase1, sizeof(phase1), "pbc=1 multi_ap=%d",
   1213  1.1.1.10  christos 			    multi_ap_backhaul_sta);
   1214  1.1.1.10  christos 	else
   1215  1.1.1.10  christos 		os_snprintf(phase1, sizeof(phase1), "pbc=1");
   1216   1.1.1.9  christos 	if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
   1217   1.1.1.5  christos 		return -1;
   1218   1.1.1.2  christos 	if (wpa_s->wps_fragment_size)
   1219   1.1.1.2  christos 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
   1220  1.1.1.10  christos 	if (multi_ap_backhaul_sta) {
   1221   1.1.1.9  christos 		ssid->multi_ap_backhaul_sta = 1;
   1222  1.1.1.10  christos 		ssid->multi_ap_profile = multi_ap_backhaul_sta;
   1223  1.1.1.10  christos 	}
   1224  1.1.1.10  christos 	wpa_s->supp_pbc_active = true;
   1225  1.1.1.10  christos 	wpa_s->wps_overlap = false;
   1226   1.1.1.8  christos 	wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
   1227       1.1  christos 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
   1228       1.1  christos 			       wpa_s, NULL);
   1229   1.1.1.5  christos 	wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
   1230       1.1  christos 	return 0;
   1231       1.1  christos }
   1232       1.1  christos 
   1233       1.1  christos 
   1234   1.1.1.5  christos static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
   1235   1.1.1.5  christos 				 const u8 *dev_addr, const u8 *bssid,
   1236   1.1.1.5  christos 				 const char *pin, int p2p_group, u16 dev_pw_id,
   1237   1.1.1.5  christos 				 const u8 *peer_pubkey_hash,
   1238   1.1.1.5  christos 				 const u8 *ssid_val, size_t ssid_len, int freq)
   1239       1.1  christos {
   1240       1.1  christos 	struct wpa_ssid *ssid;
   1241   1.1.1.5  christos 	char val[128 + 2 * WPS_OOB_PUBKEY_HASH_LEN];
   1242       1.1  christos 	unsigned int rpin = 0;
   1243   1.1.1.5  christos 	char hash[2 * WPS_OOB_PUBKEY_HASH_LEN + 10];
   1244       1.1  christos 
   1245   1.1.1.6  christos #ifdef CONFIG_AP
   1246   1.1.1.6  christos 	if (wpa_s->ap_iface) {
   1247   1.1.1.6  christos 		wpa_printf(MSG_DEBUG,
   1248   1.1.1.6  christos 			   "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
   1249   1.1.1.6  christos 		return -1;
   1250   1.1.1.6  christos 	}
   1251   1.1.1.6  christos #endif /* CONFIG_AP */
   1252       1.1  christos 	wpas_clear_wps(wpa_s);
   1253   1.1.1.5  christos 	if (bssid && is_zero_ether_addr(bssid))
   1254   1.1.1.5  christos 		bssid = NULL;
   1255   1.1.1.5  christos 	ssid = wpas_wps_add_network(wpa_s, 0, dev_addr, bssid);
   1256   1.1.1.5  christos 	if (ssid == NULL) {
   1257   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Could not add network");
   1258       1.1  christos 		return -1;
   1259   1.1.1.5  christos 	}
   1260   1.1.1.2  christos 	ssid->temporary = 1;
   1261   1.1.1.2  christos 	ssid->p2p_group = p2p_group;
   1262   1.1.1.7  christos 	/*
   1263   1.1.1.7  christos 	 * When starting a regular WPS process (not P2P group formation)
   1264   1.1.1.7  christos 	 * the registrar/final station can be either AP or PCP
   1265   1.1.1.7  christos 	 * so use a "don't care" value for the pbss flag.
   1266   1.1.1.7  christos 	 */
   1267   1.1.1.7  christos 	if (!p2p_group)
   1268   1.1.1.7  christos 		ssid->pbss = 2;
   1269   1.1.1.5  christos 	if (ssid_val) {
   1270   1.1.1.5  christos 		ssid->ssid = os_malloc(ssid_len);
   1271   1.1.1.5  christos 		if (ssid->ssid) {
   1272   1.1.1.5  christos 			os_memcpy(ssid->ssid, ssid_val, ssid_len);
   1273   1.1.1.5  christos 			ssid->ssid_len = ssid_len;
   1274   1.1.1.5  christos 		}
   1275   1.1.1.5  christos 	}
   1276   1.1.1.5  christos 	if (peer_pubkey_hash) {
   1277   1.1.1.5  christos 		os_memcpy(hash, " pkhash=", 8);
   1278   1.1.1.5  christos 		wpa_snprintf_hex_uppercase(hash + 8, sizeof(hash) - 8,
   1279   1.1.1.5  christos 					   peer_pubkey_hash,
   1280   1.1.1.5  christos 					   WPS_OOB_PUBKEY_HASH_LEN);
   1281   1.1.1.5  christos 	} else {
   1282   1.1.1.5  christos 		hash[0] = '\0';
   1283   1.1.1.5  christos 	}
   1284   1.1.1.2  christos #ifdef CONFIG_P2P
   1285   1.1.1.2  christos 	if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
   1286   1.1.1.7  christos 		os_free(ssid->ssid);
   1287   1.1.1.2  christos 		ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
   1288   1.1.1.2  christos 		if (ssid->ssid) {
   1289   1.1.1.2  christos 			ssid->ssid_len = wpa_s->go_params->ssid_len;
   1290   1.1.1.2  christos 			os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
   1291   1.1.1.2  christos 				  ssid->ssid_len);
   1292   1.1.1.7  christos 			if (wpa_s->go_params->freq > 56160) {
   1293   1.1.1.7  christos 				/* P2P in 60 GHz uses PBSS */
   1294   1.1.1.7  christos 				ssid->pbss = 1;
   1295   1.1.1.7  christos 			}
   1296  1.1.1.10  christos 			if (wpa_s->go_params->edmg &&
   1297  1.1.1.10  christos 			    wpas_p2p_try_edmg_channel(wpa_s,
   1298  1.1.1.10  christos 						      wpa_s->go_params) == 0)
   1299  1.1.1.10  christos 				ssid->enable_edmg = 1;
   1300  1.1.1.10  christos 
   1301   1.1.1.2  christos 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
   1302   1.1.1.2  christos 					  "SSID", ssid->ssid, ssid->ssid_len);
   1303   1.1.1.2  christos 		}
   1304   1.1.1.2  christos 	}
   1305   1.1.1.2  christos #endif /* CONFIG_P2P */
   1306       1.1  christos 	if (pin)
   1307   1.1.1.5  christos 		os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u%s\"",
   1308   1.1.1.5  christos 			    pin, dev_pw_id, hash);
   1309   1.1.1.5  christos 	else if (pin == NULL && dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
   1310   1.1.1.5  christos 		os_snprintf(val, sizeof(val), "\"dev_pw_id=%u%s\"",
   1311   1.1.1.5  christos 			    dev_pw_id, hash);
   1312   1.1.1.5  christos 	} else {
   1313   1.1.1.7  christos 		if (wps_generate_pin(&rpin) < 0) {
   1314   1.1.1.7  christos 			wpa_printf(MSG_DEBUG, "WPS: Could not generate PIN");
   1315   1.1.1.7  christos 			return -1;
   1316   1.1.1.7  christos 		}
   1317   1.1.1.5  christos 		os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u%s\"",
   1318   1.1.1.5  christos 			    rpin, dev_pw_id, hash);
   1319   1.1.1.5  christos 	}
   1320   1.1.1.5  christos 	if (wpa_config_set(ssid, "phase1", val, 0) < 0) {
   1321   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Failed to set phase1 '%s'", val);
   1322   1.1.1.5  christos 		return -1;
   1323       1.1  christos 	}
   1324  1.1.1.10  christos 
   1325  1.1.1.10  christos 	if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER)
   1326  1.1.1.10  christos 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_PIN_ACTIVE);
   1327  1.1.1.10  christos 
   1328   1.1.1.2  christos 	if (wpa_s->wps_fragment_size)
   1329   1.1.1.2  christos 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
   1330       1.1  christos 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
   1331       1.1  christos 			       wpa_s, NULL);
   1332   1.1.1.4  christos 	wpa_s->wps_ap_iter = 1;
   1333   1.1.1.5  christos 	wpas_wps_reassoc(wpa_s, ssid, bssid, freq);
   1334       1.1  christos 	return rpin;
   1335       1.1  christos }
   1336       1.1  christos 
   1337       1.1  christos 
   1338   1.1.1.5  christos int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
   1339   1.1.1.5  christos 		       const char *pin, int p2p_group, u16 dev_pw_id)
   1340   1.1.1.5  christos {
   1341   1.1.1.7  christos 	os_get_reltime(&wpa_s->wps_pin_start_time);
   1342   1.1.1.5  christos 	return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
   1343   1.1.1.5  christos 				     dev_pw_id, NULL, NULL, 0, 0);
   1344   1.1.1.5  christos }
   1345   1.1.1.5  christos 
   1346   1.1.1.5  christos 
   1347   1.1.1.7  christos void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s)
   1348   1.1.1.7  christos {
   1349   1.1.1.7  christos 	union wps_event_data data;
   1350   1.1.1.7  christos 
   1351   1.1.1.7  christos 	os_memset(&data, 0, sizeof(data));
   1352   1.1.1.7  christos 	data.fail.config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
   1353   1.1.1.7  christos 	data.fail.error_indication = WPS_EI_NO_ERROR;
   1354   1.1.1.7  christos 	/*
   1355   1.1.1.7  christos 	 * Call wpas_notify_wps_event_fail() directly instead of through
   1356   1.1.1.7  christos 	 * wpa_supplicant_wps_event() which would end up registering unnecessary
   1357   1.1.1.7  christos 	 * timeouts (those are only for the case where the failure happens
   1358   1.1.1.7  christos 	 * during an EAP-WSC exchange).
   1359   1.1.1.7  christos 	 */
   1360   1.1.1.7  christos 	wpas_notify_wps_event_fail(wpa_s, &data.fail);
   1361   1.1.1.7  christos }
   1362   1.1.1.7  christos 
   1363   1.1.1.2  christos /* Cancel the wps pbc/pin requests */
   1364   1.1.1.2  christos int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
   1365   1.1.1.2  christos {
   1366   1.1.1.2  christos #ifdef CONFIG_AP
   1367   1.1.1.2  christos 	if (wpa_s->ap_iface) {
   1368   1.1.1.2  christos 		wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
   1369   1.1.1.2  christos 		return wpa_supplicant_ap_wps_cancel(wpa_s);
   1370   1.1.1.2  christos 	}
   1371   1.1.1.2  christos #endif /* CONFIG_AP */
   1372   1.1.1.2  christos 
   1373   1.1.1.3      adam 	if (wpa_s->wpa_state == WPA_SCANNING ||
   1374   1.1.1.3      adam 	    wpa_s->wpa_state == WPA_DISCONNECTED) {
   1375   1.1.1.2  christos 		wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
   1376   1.1.1.2  christos 		wpa_supplicant_cancel_scan(wpa_s);
   1377   1.1.1.2  christos 		wpas_clear_wps(wpa_s);
   1378   1.1.1.2  christos 	} else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
   1379   1.1.1.2  christos 		wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
   1380   1.1.1.2  christos 			   "deauthenticate");
   1381   1.1.1.6  christos 		wpa_s->own_disconnect_req = 1;
   1382   1.1.1.2  christos 		wpa_supplicant_deauthenticate(wpa_s,
   1383   1.1.1.2  christos 					      WLAN_REASON_DEAUTH_LEAVING);
   1384   1.1.1.2  christos 		wpas_clear_wps(wpa_s);
   1385   1.1.1.4  christos 	} else {
   1386   1.1.1.4  christos 		wpas_wps_reenable_networks(wpa_s);
   1387   1.1.1.4  christos 		wpas_wps_clear_ap_info(wpa_s);
   1388   1.1.1.5  christos 		if (eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL) >
   1389   1.1.1.5  christos 		    0)
   1390   1.1.1.5  christos 			wpas_clear_wps(wpa_s);
   1391   1.1.1.2  christos 	}
   1392   1.1.1.2  christos 
   1393  1.1.1.10  christos 	wpa_s->supp_pbc_active = false;
   1394  1.1.1.10  christos 	wpa_s->wps_overlap = false;
   1395  1.1.1.10  christos 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CANCEL);
   1396   1.1.1.5  christos 	wpa_s->after_wps = 0;
   1397   1.1.1.5  christos 
   1398   1.1.1.2  christos 	return 0;
   1399   1.1.1.2  christos }
   1400   1.1.1.2  christos 
   1401   1.1.1.2  christos 
   1402       1.1  christos int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
   1403       1.1  christos 		       const char *pin, struct wps_new_ap_settings *settings)
   1404       1.1  christos {
   1405       1.1  christos 	struct wpa_ssid *ssid;
   1406       1.1  christos 	char val[200];
   1407       1.1  christos 	char *pos, *end;
   1408       1.1  christos 	int res;
   1409       1.1  christos 
   1410   1.1.1.6  christos #ifdef CONFIG_AP
   1411   1.1.1.6  christos 	if (wpa_s->ap_iface) {
   1412   1.1.1.6  christos 		wpa_printf(MSG_DEBUG,
   1413   1.1.1.6  christos 			   "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
   1414   1.1.1.6  christos 		return -1;
   1415   1.1.1.6  christos 	}
   1416   1.1.1.6  christos #endif /* CONFIG_AP */
   1417       1.1  christos 	if (!pin)
   1418       1.1  christos 		return -1;
   1419       1.1  christos 	wpas_clear_wps(wpa_s);
   1420   1.1.1.5  christos 	ssid = wpas_wps_add_network(wpa_s, 1, NULL, bssid);
   1421       1.1  christos 	if (ssid == NULL)
   1422       1.1  christos 		return -1;
   1423   1.1.1.2  christos 	ssid->temporary = 1;
   1424       1.1  christos 	pos = val;
   1425       1.1  christos 	end = pos + sizeof(val);
   1426       1.1  christos 	res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
   1427   1.1.1.6  christos 	if (os_snprintf_error(end - pos, res))
   1428       1.1  christos 		return -1;
   1429       1.1  christos 	pos += res;
   1430       1.1  christos 	if (settings) {
   1431       1.1  christos 		res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s "
   1432       1.1  christos 				  "new_encr=%s new_key=%s",
   1433       1.1  christos 				  settings->ssid_hex, settings->auth,
   1434       1.1  christos 				  settings->encr, settings->key_hex);
   1435   1.1.1.6  christos 		if (os_snprintf_error(end - pos, res))
   1436       1.1  christos 			return -1;
   1437       1.1  christos 		pos += res;
   1438       1.1  christos 	}
   1439       1.1  christos 	res = os_snprintf(pos, end - pos, "\"");
   1440   1.1.1.6  christos 	if (os_snprintf_error(end - pos, res))
   1441       1.1  christos 		return -1;
   1442   1.1.1.5  christos 	if (wpa_config_set(ssid, "phase1", val, 0) < 0)
   1443   1.1.1.5  christos 		return -1;
   1444   1.1.1.2  christos 	if (wpa_s->wps_fragment_size)
   1445   1.1.1.2  christos 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
   1446       1.1  christos 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
   1447       1.1  christos 			       wpa_s, NULL);
   1448   1.1.1.5  christos 	wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
   1449       1.1  christos 	return 0;
   1450       1.1  christos }
   1451       1.1  christos 
   1452       1.1  christos 
   1453   1.1.1.5  christos static int wpas_wps_new_psk_cb(void *ctx, const u8 *mac_addr,
   1454   1.1.1.5  christos 			       const u8 *p2p_dev_addr, const u8 *psk,
   1455       1.1  christos 			       size_t psk_len)
   1456       1.1  christos {
   1457   1.1.1.5  christos 	if (is_zero_ether_addr(p2p_dev_addr)) {
   1458   1.1.1.5  christos 		wpa_printf(MSG_DEBUG,
   1459   1.1.1.5  christos 			   "Received new WPA/WPA2-PSK from WPS for STA " MACSTR,
   1460   1.1.1.5  christos 			   MAC2STR(mac_addr));
   1461   1.1.1.5  christos 	} else {
   1462   1.1.1.5  christos 		wpa_printf(MSG_DEBUG,
   1463   1.1.1.5  christos 			   "Received new WPA/WPA2-PSK from WPS for STA " MACSTR
   1464   1.1.1.5  christos 			   " P2P Device Addr " MACSTR,
   1465   1.1.1.5  christos 			   MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
   1466   1.1.1.5  christos 	}
   1467       1.1  christos 	wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
   1468       1.1  christos 
   1469       1.1  christos 	/* TODO */
   1470       1.1  christos 
   1471       1.1  christos 	return 0;
   1472       1.1  christos }
   1473       1.1  christos 
   1474       1.1  christos 
   1475       1.1  christos static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
   1476       1.1  christos 				   const struct wps_device_data *dev)
   1477       1.1  christos {
   1478       1.1  christos 	char uuid[40], txt[400];
   1479       1.1  christos 	int len;
   1480       1.1  christos 	char devtype[WPS_DEV_TYPE_BUFSIZE];
   1481       1.1  christos 	if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
   1482       1.1  christos 		return;
   1483       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
   1484       1.1  christos 	len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
   1485       1.1  christos 			  " [%s|%s|%s|%s|%s|%s]",
   1486       1.1  christos 			  uuid, MAC2STR(dev->mac_addr), dev->device_name,
   1487       1.1  christos 			  dev->manufacturer, dev->model_name,
   1488       1.1  christos 			  dev->model_number, dev->serial_number,
   1489       1.1  christos 			  wps_dev_type_bin2str(dev->pri_dev_type, devtype,
   1490       1.1  christos 					       sizeof(devtype)));
   1491   1.1.1.6  christos 	if (!os_snprintf_error(sizeof(txt), len))
   1492       1.1  christos 		wpa_printf(MSG_INFO, "%s", txt);
   1493       1.1  christos }
   1494       1.1  christos 
   1495       1.1  christos 
   1496       1.1  christos static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
   1497       1.1  christos 				    u16 sel_reg_config_methods)
   1498       1.1  christos {
   1499       1.1  christos #ifdef CONFIG_WPS_ER
   1500       1.1  christos 	struct wpa_supplicant *wpa_s = ctx;
   1501       1.1  christos 
   1502       1.1  christos 	if (wpa_s->wps_er == NULL)
   1503       1.1  christos 		return;
   1504   1.1.1.2  christos 	wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
   1505   1.1.1.2  christos 		   "dev_password_id=%u sel_reg_config_methods=0x%x",
   1506   1.1.1.2  christos 		   sel_reg, dev_passwd_id, sel_reg_config_methods);
   1507       1.1  christos 	wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
   1508       1.1  christos 			   sel_reg_config_methods);
   1509       1.1  christos #endif /* CONFIG_WPS_ER */
   1510       1.1  christos }
   1511       1.1  christos 
   1512       1.1  christos 
   1513   1.1.1.2  christos static u16 wps_fix_config_methods(u16 config_methods)
   1514   1.1.1.2  christos {
   1515   1.1.1.2  christos 	if ((config_methods &
   1516   1.1.1.2  christos 	     (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
   1517   1.1.1.2  christos 	      WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
   1518   1.1.1.2  christos 		wpa_printf(MSG_INFO, "WPS: Converting display to "
   1519   1.1.1.2  christos 			   "virtual_display for WPS 2.0 compliance");
   1520   1.1.1.2  christos 		config_methods |= WPS_CONFIG_VIRT_DISPLAY;
   1521   1.1.1.2  christos 	}
   1522   1.1.1.2  christos 	if ((config_methods &
   1523   1.1.1.2  christos 	     (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
   1524   1.1.1.2  christos 	      WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
   1525   1.1.1.2  christos 		wpa_printf(MSG_INFO, "WPS: Converting push_button to "
   1526   1.1.1.2  christos 			   "virtual_push_button for WPS 2.0 compliance");
   1527   1.1.1.2  christos 		config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
   1528   1.1.1.2  christos 	}
   1529   1.1.1.2  christos 
   1530   1.1.1.2  christos 	return config_methods;
   1531   1.1.1.2  christos }
   1532   1.1.1.2  christos 
   1533   1.1.1.2  christos 
   1534   1.1.1.2  christos static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
   1535   1.1.1.2  christos 			      struct wps_context *wps)
   1536   1.1.1.2  christos {
   1537   1.1.1.5  christos 	char buf[50];
   1538   1.1.1.5  christos 	const char *src;
   1539   1.1.1.5  christos 
   1540   1.1.1.2  christos 	if (is_nil_uuid(wpa_s->conf->uuid)) {
   1541   1.1.1.2  christos 		struct wpa_supplicant *first;
   1542   1.1.1.2  christos 		first = wpa_s->global->ifaces;
   1543   1.1.1.2  christos 		while (first && first->next)
   1544   1.1.1.2  christos 			first = first->next;
   1545   1.1.1.2  christos 		if (first && first != wpa_s) {
   1546   1.1.1.3      adam 			if (wps != wpa_s->global->ifaces->wps)
   1547   1.1.1.3      adam 				os_memcpy(wps->uuid,
   1548   1.1.1.3      adam 					  wpa_s->global->ifaces->wps->uuid,
   1549   1.1.1.3      adam 					  WPS_UUID_LEN);
   1550   1.1.1.5  christos 			src = "from the first interface";
   1551   1.1.1.8  christos 		} else if (wpa_s->conf->auto_uuid == 1) {
   1552   1.1.1.8  christos 			uuid_random(wps->uuid);
   1553   1.1.1.8  christos 			src = "based on random data";
   1554   1.1.1.2  christos 		} else {
   1555   1.1.1.2  christos 			uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
   1556   1.1.1.5  christos 			src = "based on MAC address";
   1557   1.1.1.2  christos 		}
   1558   1.1.1.2  christos 	} else {
   1559   1.1.1.2  christos 		os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
   1560   1.1.1.5  christos 		src = "based on configuration";
   1561   1.1.1.2  christos 	}
   1562   1.1.1.5  christos 
   1563   1.1.1.5  christos 	uuid_bin2str(wps->uuid, buf, sizeof(buf));
   1564   1.1.1.5  christos 	wpa_dbg(wpa_s, MSG_DEBUG, "WPS: UUID %s: %s", src, buf);
   1565   1.1.1.2  christos }
   1566   1.1.1.2  christos 
   1567   1.1.1.2  christos 
   1568   1.1.1.4  christos static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
   1569   1.1.1.4  christos 				       struct wps_context *wps)
   1570   1.1.1.4  christos {
   1571   1.1.1.4  christos 	wpabuf_free(wps->dev.vendor_ext_m1);
   1572   1.1.1.4  christos 	wps->dev.vendor_ext_m1 = NULL;
   1573   1.1.1.4  christos 
   1574   1.1.1.4  christos 	if (wpa_s->conf->wps_vendor_ext_m1) {
   1575   1.1.1.4  christos 		wps->dev.vendor_ext_m1 =
   1576   1.1.1.4  christos 			wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
   1577   1.1.1.4  christos 		if (!wps->dev.vendor_ext_m1) {
   1578   1.1.1.4  christos 			wpa_printf(MSG_ERROR, "WPS: Cannot "
   1579   1.1.1.4  christos 				   "allocate memory for vendor_ext_m1");
   1580   1.1.1.4  christos 		}
   1581   1.1.1.4  christos 	}
   1582   1.1.1.4  christos }
   1583   1.1.1.4  christos 
   1584   1.1.1.4  christos 
   1585       1.1  christos int wpas_wps_init(struct wpa_supplicant *wpa_s)
   1586       1.1  christos {
   1587       1.1  christos 	struct wps_context *wps;
   1588       1.1  christos 	struct wps_registrar_config rcfg;
   1589   1.1.1.2  christos 	struct hostapd_hw_modes *modes;
   1590   1.1.1.2  christos 	u16 m;
   1591       1.1  christos 
   1592       1.1  christos 	wps = os_zalloc(sizeof(*wps));
   1593       1.1  christos 	if (wps == NULL)
   1594       1.1  christos 		return -1;
   1595       1.1  christos 
   1596       1.1  christos 	wps->cred_cb = wpa_supplicant_wps_cred;
   1597       1.1  christos 	wps->event_cb = wpa_supplicant_wps_event;
   1598   1.1.1.5  christos 	wps->rf_band_cb = wpa_supplicant_wps_rf_band;
   1599       1.1  christos 	wps->cb_ctx = wpa_s;
   1600       1.1  christos 
   1601       1.1  christos 	wps->dev.device_name = wpa_s->conf->device_name;
   1602       1.1  christos 	wps->dev.manufacturer = wpa_s->conf->manufacturer;
   1603       1.1  christos 	wps->dev.model_name = wpa_s->conf->model_name;
   1604       1.1  christos 	wps->dev.model_number = wpa_s->conf->model_number;
   1605       1.1  christos 	wps->dev.serial_number = wpa_s->conf->serial_number;
   1606       1.1  christos 	wps->config_methods =
   1607       1.1  christos 		wps_config_methods_str2bin(wpa_s->conf->config_methods);
   1608   1.1.1.2  christos 	if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
   1609   1.1.1.2  christos 	    (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
   1610   1.1.1.2  christos 		wpa_printf(MSG_ERROR, "WPS: Both Label and Display config "
   1611   1.1.1.2  christos 			   "methods are not allowed at the same time");
   1612       1.1  christos 		os_free(wps);
   1613       1.1  christos 		return -1;
   1614       1.1  christos 	}
   1615   1.1.1.2  christos 	wps->config_methods = wps_fix_config_methods(wps->config_methods);
   1616   1.1.1.2  christos 	wps->dev.config_methods = wps->config_methods;
   1617   1.1.1.2  christos 	os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
   1618   1.1.1.2  christos 		  WPS_DEV_TYPE_LEN);
   1619   1.1.1.2  christos 
   1620   1.1.1.2  christos 	wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
   1621   1.1.1.2  christos 	os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
   1622   1.1.1.2  christos 		  WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
   1623   1.1.1.2  christos 
   1624   1.1.1.4  christos 	wpas_wps_set_vendor_ext_m1(wpa_s, wps);
   1625   1.1.1.4  christos 
   1626       1.1  christos 	wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
   1627   1.1.1.2  christos 	modes = wpa_s->hw.modes;
   1628   1.1.1.2  christos 	if (modes) {
   1629   1.1.1.2  christos 		for (m = 0; m < wpa_s->hw.num_modes; m++) {
   1630   1.1.1.2  christos 			if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
   1631   1.1.1.2  christos 			    modes[m].mode == HOSTAPD_MODE_IEEE80211G)
   1632   1.1.1.2  christos 				wps->dev.rf_bands |= WPS_RF_24GHZ;
   1633   1.1.1.2  christos 			else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
   1634   1.1.1.2  christos 				wps->dev.rf_bands |= WPS_RF_50GHZ;
   1635   1.1.1.7  christos 			else if (modes[m].mode == HOSTAPD_MODE_IEEE80211AD)
   1636   1.1.1.7  christos 				wps->dev.rf_bands |= WPS_RF_60GHZ;
   1637   1.1.1.2  christos 		}
   1638   1.1.1.2  christos 	}
   1639   1.1.1.2  christos 	if (wps->dev.rf_bands == 0) {
   1640   1.1.1.2  christos 		/*
   1641   1.1.1.2  christos 		 * Default to claiming support for both bands if the driver
   1642   1.1.1.2  christos 		 * does not provide support for fetching supported bands.
   1643   1.1.1.2  christos 		 */
   1644   1.1.1.2  christos 		wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
   1645   1.1.1.2  christos 	}
   1646       1.1  christos 	os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
   1647   1.1.1.2  christos 	wpas_wps_set_uuid(wpa_s, wps);
   1648       1.1  christos 
   1649  1.1.1.10  christos #ifdef CONFIG_NO_TKIP
   1650  1.1.1.10  christos 	wps->auth_types = WPS_AUTH_WPA2PSK;
   1651  1.1.1.10  christos 	wps->encr_types = WPS_ENCR_AES;
   1652  1.1.1.10  christos #else /* CONFIG_NO_TKIP */
   1653       1.1  christos 	wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
   1654       1.1  christos 	wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
   1655  1.1.1.10  christos #endif /* CONFIG_NO_TKIP */
   1656       1.1  christos 
   1657       1.1  christos 	os_memset(&rcfg, 0, sizeof(rcfg));
   1658       1.1  christos 	rcfg.new_psk_cb = wpas_wps_new_psk_cb;
   1659       1.1  christos 	rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
   1660       1.1  christos 	rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
   1661       1.1  christos 	rcfg.cb_ctx = wpa_s;
   1662       1.1  christos 
   1663       1.1  christos 	wps->registrar = wps_registrar_init(wps, &rcfg);
   1664       1.1  christos 	if (wps->registrar == NULL) {
   1665       1.1  christos 		wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
   1666       1.1  christos 		os_free(wps);
   1667       1.1  christos 		return -1;
   1668       1.1  christos 	}
   1669       1.1  christos 
   1670       1.1  christos 	wpa_s->wps = wps;
   1671       1.1  christos 
   1672       1.1  christos 	return 0;
   1673       1.1  christos }
   1674       1.1  christos 
   1675       1.1  christos 
   1676   1.1.1.5  christos #ifdef CONFIG_WPS_ER
   1677   1.1.1.5  christos static void wpas_wps_nfc_clear(struct wps_context *wps)
   1678   1.1.1.5  christos {
   1679   1.1.1.5  christos 	wps->ap_nfc_dev_pw_id = 0;
   1680   1.1.1.5  christos 	wpabuf_free(wps->ap_nfc_dh_pubkey);
   1681   1.1.1.5  christos 	wps->ap_nfc_dh_pubkey = NULL;
   1682   1.1.1.5  christos 	wpabuf_free(wps->ap_nfc_dh_privkey);
   1683   1.1.1.5  christos 	wps->ap_nfc_dh_privkey = NULL;
   1684   1.1.1.5  christos 	wpabuf_free(wps->ap_nfc_dev_pw);
   1685   1.1.1.5  christos 	wps->ap_nfc_dev_pw = NULL;
   1686   1.1.1.5  christos }
   1687   1.1.1.5  christos #endif /* CONFIG_WPS_ER */
   1688   1.1.1.5  christos 
   1689   1.1.1.5  christos 
   1690       1.1  christos void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
   1691       1.1  christos {
   1692   1.1.1.5  christos 	wpas_wps_assoc_with_cred_cancel(wpa_s);
   1693       1.1  christos 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
   1694   1.1.1.5  christos 	eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
   1695   1.1.1.4  christos 	eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
   1696   1.1.1.4  christos 	wpas_wps_clear_ap_info(wpa_s);
   1697       1.1  christos 
   1698   1.1.1.5  christos #ifdef CONFIG_P2P
   1699   1.1.1.5  christos 	eloop_cancel_timeout(wpas_p2p_pbc_overlap_cb, wpa_s, NULL);
   1700   1.1.1.5  christos #endif /* CONFIG_P2P */
   1701   1.1.1.5  christos 
   1702       1.1  christos 	if (wpa_s->wps == NULL)
   1703       1.1  christos 		return;
   1704       1.1  christos 
   1705       1.1  christos #ifdef CONFIG_WPS_ER
   1706       1.1  christos 	wps_er_deinit(wpa_s->wps_er, NULL, NULL);
   1707       1.1  christos 	wpa_s->wps_er = NULL;
   1708   1.1.1.5  christos 	wpas_wps_nfc_clear(wpa_s->wps);
   1709       1.1  christos #endif /* CONFIG_WPS_ER */
   1710       1.1  christos 
   1711       1.1  christos 	wps_registrar_deinit(wpa_s->wps->registrar);
   1712       1.1  christos 	wpabuf_free(wpa_s->wps->dh_pubkey);
   1713       1.1  christos 	wpabuf_free(wpa_s->wps->dh_privkey);
   1714   1.1.1.4  christos 	wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
   1715       1.1  christos 	os_free(wpa_s->wps->network_key);
   1716       1.1  christos 	os_free(wpa_s->wps);
   1717       1.1  christos 	wpa_s->wps = NULL;
   1718       1.1  christos }
   1719       1.1  christos 
   1720       1.1  christos 
   1721       1.1  christos int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
   1722   1.1.1.4  christos 			    struct wpa_ssid *ssid, struct wpa_bss *bss)
   1723       1.1  christos {
   1724       1.1  christos 	struct wpabuf *wps_ie;
   1725       1.1  christos 
   1726       1.1  christos 	if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
   1727       1.1  christos 		return -1;
   1728       1.1  christos 
   1729  1.1.1.10  christos 	wps_ie = wpas_wps_get_wps_ie(bss);
   1730       1.1  christos 	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
   1731       1.1  christos 		if (!wps_ie) {
   1732       1.1  christos 			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
   1733       1.1  christos 			return 0;
   1734       1.1  christos 		}
   1735       1.1  christos 
   1736       1.1  christos 		if (!wps_is_selected_pbc_registrar(wps_ie)) {
   1737       1.1  christos 			wpa_printf(MSG_DEBUG, "   skip - WPS AP "
   1738       1.1  christos 				   "without active PBC Registrar");
   1739       1.1  christos 			wpabuf_free(wps_ie);
   1740       1.1  christos 			return 0;
   1741       1.1  christos 		}
   1742       1.1  christos 
   1743       1.1  christos 		/* TODO: overlap detection */
   1744       1.1  christos 		wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
   1745       1.1  christos 			   "(Active PBC)");
   1746       1.1  christos 		wpabuf_free(wps_ie);
   1747       1.1  christos 		return 1;
   1748       1.1  christos 	}
   1749       1.1  christos 
   1750       1.1  christos 	if (eap_is_wps_pin_enrollee(&ssid->eap)) {
   1751       1.1  christos 		if (!wps_ie) {
   1752       1.1  christos 			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
   1753       1.1  christos 			return 0;
   1754       1.1  christos 		}
   1755       1.1  christos 
   1756       1.1  christos 		/*
   1757   1.1.1.2  christos 		 * Start with WPS APs that advertise our address as an
   1758   1.1.1.2  christos 		 * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
   1759   1.1.1.2  christos 		 * allow any WPS AP after couple of scans since some APs do not
   1760   1.1.1.2  christos 		 * set Selected Registrar attribute properly when using
   1761   1.1.1.2  christos 		 * external Registrar.
   1762       1.1  christos 		 */
   1763   1.1.1.2  christos 		if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
   1764   1.1.1.7  christos 			struct os_reltime age;
   1765   1.1.1.7  christos 
   1766   1.1.1.7  christos 			os_reltime_age(&wpa_s->wps_pin_start_time, &age);
   1767   1.1.1.7  christos 
   1768   1.1.1.7  christos 			if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG ||
   1769   1.1.1.7  christos 			    age.sec < WPS_PIN_TIME_IGNORE_SEL_REG) {
   1770   1.1.1.7  christos 				wpa_printf(MSG_DEBUG,
   1771   1.1.1.7  christos 					   "   skip - WPS AP without active PIN Registrar (scan_runs=%d age=%d)",
   1772   1.1.1.7  christos 					   wpa_s->scan_runs, (int) age.sec);
   1773       1.1  christos 				wpabuf_free(wps_ie);
   1774       1.1  christos 				return 0;
   1775       1.1  christos 			}
   1776       1.1  christos 			wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
   1777       1.1  christos 		} else {
   1778       1.1  christos 			wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
   1779   1.1.1.2  christos 				   "(Authorized MAC or Active PIN)");
   1780       1.1  christos 		}
   1781       1.1  christos 		wpabuf_free(wps_ie);
   1782       1.1  christos 		return 1;
   1783       1.1  christos 	}
   1784       1.1  christos 
   1785       1.1  christos 	if (wps_ie) {
   1786       1.1  christos 		wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
   1787       1.1  christos 		wpabuf_free(wps_ie);
   1788       1.1  christos 		return 1;
   1789       1.1  christos 	}
   1790       1.1  christos 
   1791       1.1  christos 	return -1;
   1792       1.1  christos }
   1793       1.1  christos 
   1794       1.1  christos 
   1795       1.1  christos int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
   1796       1.1  christos 			      struct wpa_ssid *ssid,
   1797   1.1.1.4  christos 			      struct wpa_bss *bss)
   1798       1.1  christos {
   1799       1.1  christos 	struct wpabuf *wps_ie = NULL;
   1800       1.1  christos 	int ret = 0;
   1801       1.1  christos 
   1802       1.1  christos 	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
   1803  1.1.1.10  christos 		wps_ie = wpas_wps_get_wps_ie(bss);
   1804       1.1  christos 		if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
   1805       1.1  christos 			/* allow wildcard SSID for WPS PBC */
   1806       1.1  christos 			ret = 1;
   1807       1.1  christos 		}
   1808       1.1  christos 	} else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
   1809  1.1.1.10  christos 		wps_ie = wpas_wps_get_wps_ie(bss);
   1810       1.1  christos 		if (wps_ie &&
   1811   1.1.1.2  christos 		    (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
   1812       1.1  christos 		     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
   1813       1.1  christos 			/* allow wildcard SSID for WPS PIN */
   1814       1.1  christos 			ret = 1;
   1815       1.1  christos 		}
   1816       1.1  christos 	}
   1817       1.1  christos 
   1818       1.1  christos 	if (!ret && ssid->bssid_set &&
   1819  1.1.1.10  christos 	    ether_addr_equal(ssid->bssid, bss->bssid)) {
   1820       1.1  christos 		/* allow wildcard SSID due to hardcoded BSSID match */
   1821       1.1  christos 		ret = 1;
   1822       1.1  christos 	}
   1823       1.1  christos 
   1824   1.1.1.2  christos #ifdef CONFIG_WPS_STRICT
   1825   1.1.1.2  christos 	if (wps_ie) {
   1826   1.1.1.2  christos 		if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
   1827   1.1.1.2  christos 						   0, bss->bssid) < 0)
   1828   1.1.1.2  christos 			ret = 0;
   1829   1.1.1.2  christos 		if (bss->beacon_ie_len) {
   1830   1.1.1.2  christos 			struct wpabuf *bcn_wps;
   1831   1.1.1.4  christos 			bcn_wps = wpa_bss_get_vendor_ie_multi_beacon(
   1832   1.1.1.2  christos 				bss, WPS_IE_VENDOR_TYPE);
   1833   1.1.1.2  christos 			if (bcn_wps == NULL) {
   1834   1.1.1.2  christos 				wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
   1835   1.1.1.2  christos 					   "missing from AP Beacon");
   1836   1.1.1.2  christos 				ret = 0;
   1837   1.1.1.2  christos 			} else {
   1838   1.1.1.2  christos 				if (wps_validate_beacon(wps_ie) < 0)
   1839   1.1.1.2  christos 					ret = 0;
   1840   1.1.1.2  christos 				wpabuf_free(bcn_wps);
   1841   1.1.1.2  christos 			}
   1842   1.1.1.2  christos 		}
   1843   1.1.1.2  christos 	}
   1844   1.1.1.2  christos #endif /* CONFIG_WPS_STRICT */
   1845   1.1.1.2  christos 
   1846       1.1  christos 	wpabuf_free(wps_ie);
   1847       1.1  christos 
   1848       1.1  christos 	return ret;
   1849       1.1  christos }
   1850       1.1  christos 
   1851       1.1  christos 
   1852  1.1.1.10  christos static bool wpas_wps_is_pbc_overlap(struct wps_ap_info *ap,
   1853  1.1.1.10  christos 				    struct wpa_bss *selected,
   1854  1.1.1.10  christos 				    struct wpa_ssid *ssid,
   1855  1.1.1.10  christos 				    const u8 *sel_uuid)
   1856  1.1.1.10  christos {
   1857  1.1.1.10  christos 	if (!ap->pbc_active ||
   1858  1.1.1.10  christos 	    ether_addr_equal(selected->bssid, ap->bssid))
   1859  1.1.1.10  christos 		return false;
   1860  1.1.1.10  christos 
   1861  1.1.1.10  christos 	if (!is_zero_ether_addr(ssid->bssid) &&
   1862  1.1.1.10  christos 	    !ether_addr_equal(ap->bssid, ssid->bssid)) {
   1863  1.1.1.10  christos 		wpa_printf(MSG_DEBUG, "WPS: Ignore another BSS " MACSTR
   1864  1.1.1.10  christos 			   " in active PBC mode due to local BSSID limitation",
   1865  1.1.1.10  christos 			   MAC2STR(ap->bssid));
   1866  1.1.1.10  christos 		return 0;
   1867  1.1.1.10  christos 	}
   1868  1.1.1.10  christos 
   1869  1.1.1.10  christos 	wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: " MACSTR,
   1870  1.1.1.10  christos 		   MAC2STR(ap->bssid));
   1871  1.1.1.10  christos 	wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
   1872  1.1.1.10  christos 		    ap->uuid, UUID_LEN);
   1873  1.1.1.10  christos 	if (!sel_uuid || os_memcmp(sel_uuid, ap->uuid, UUID_LEN) != 0)
   1874  1.1.1.10  christos 		return true;
   1875  1.1.1.10  christos 
   1876  1.1.1.10  christos 	/* TODO: verify that this is reasonable dual-band situation */
   1877  1.1.1.10  christos 
   1878  1.1.1.10  christos 	return false;
   1879  1.1.1.10  christos }
   1880  1.1.1.10  christos 
   1881  1.1.1.10  christos 
   1882       1.1  christos int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
   1883       1.1  christos 			      struct wpa_bss *selected, struct wpa_ssid *ssid)
   1884       1.1  christos {
   1885  1.1.1.10  christos 	struct wpa_supplicant *iface;
   1886   1.1.1.7  christos 	const u8 *sel_uuid;
   1887       1.1  christos 	struct wpabuf *wps_ie;
   1888       1.1  christos 	int ret = 0;
   1889   1.1.1.7  christos 	size_t i;
   1890       1.1  christos 
   1891       1.1  christos 	if (!eap_is_wps_pbc_enrollee(&ssid->eap))
   1892       1.1  christos 		return 0;
   1893       1.1  christos 
   1894   1.1.1.2  christos 	wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
   1895   1.1.1.2  christos 		   "present in scan results; selected BSSID " MACSTR,
   1896   1.1.1.2  christos 		   MAC2STR(selected->bssid));
   1897  1.1.1.10  christos 	if (!is_zero_ether_addr(ssid->bssid))
   1898  1.1.1.10  christos 		wpa_printf(MSG_DEBUG,
   1899  1.1.1.10  christos 			   "WPS: Network profile limited to accept only a single BSSID " MACSTR,
   1900  1.1.1.10  christos 			   MAC2STR(ssid->bssid));
   1901   1.1.1.2  christos 
   1902       1.1  christos 	/* Make sure that only one AP is in active PBC mode */
   1903       1.1  christos 	wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
   1904   1.1.1.2  christos 	if (wps_ie) {
   1905       1.1  christos 		sel_uuid = wps_get_uuid_e(wps_ie);
   1906   1.1.1.2  christos 		wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
   1907   1.1.1.2  christos 			    sel_uuid, UUID_LEN);
   1908   1.1.1.2  christos 	} else {
   1909   1.1.1.2  christos 		wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
   1910   1.1.1.2  christos 			   "WPS IE?!");
   1911       1.1  christos 		sel_uuid = NULL;
   1912   1.1.1.2  christos 	}
   1913       1.1  christos 
   1914  1.1.1.10  christos 	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
   1915  1.1.1.10  christos 		for (i = 0; i < iface->num_wps_ap; i++) {
   1916  1.1.1.10  christos 			struct wps_ap_info *ap = &iface->wps_ap[i];
   1917  1.1.1.10  christos 
   1918  1.1.1.10  christos 			if (wpas_wps_is_pbc_overlap(ap, selected, ssid,
   1919  1.1.1.10  christos 						    sel_uuid)) {
   1920  1.1.1.10  christos 				ret = 1; /* PBC overlap */
   1921  1.1.1.10  christos 				wpa_msg(iface, MSG_INFO,
   1922  1.1.1.10  christos 					"WPS: PBC overlap detected: "
   1923  1.1.1.10  christos 					MACSTR " and " MACSTR,
   1924  1.1.1.10  christos 					MAC2STR(selected->bssid),
   1925  1.1.1.10  christos 					MAC2STR(ap->bssid));
   1926  1.1.1.10  christos 				break;
   1927  1.1.1.10  christos 			}
   1928       1.1  christos 		}
   1929       1.1  christos 	}
   1930       1.1  christos 
   1931       1.1  christos 	wpabuf_free(wps_ie);
   1932       1.1  christos 
   1933       1.1  christos 	return ret;
   1934       1.1  christos }
   1935       1.1  christos 
   1936       1.1  christos 
   1937       1.1  christos void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
   1938       1.1  christos {
   1939       1.1  christos 	struct wpa_bss *bss;
   1940   1.1.1.2  christos 	unsigned int pbc = 0, auth = 0, pin = 0, wps = 0;
   1941       1.1  christos 
   1942       1.1  christos 	if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
   1943       1.1  christos 		return;
   1944       1.1  christos 
   1945       1.1  christos 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
   1946       1.1  christos 		struct wpabuf *ie;
   1947  1.1.1.10  christos 
   1948  1.1.1.10  christos 		ie = wpas_wps_get_wps_ie(bss);
   1949       1.1  christos 		if (!ie)
   1950       1.1  christos 			continue;
   1951       1.1  christos 		if (wps_is_selected_pbc_registrar(ie))
   1952   1.1.1.2  christos 			pbc++;
   1953   1.1.1.2  christos 		else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
   1954   1.1.1.2  christos 			auth++;
   1955       1.1  christos 		else if (wps_is_selected_pin_registrar(ie))
   1956   1.1.1.2  christos 			pin++;
   1957       1.1  christos 		else
   1958   1.1.1.2  christos 			wps++;
   1959       1.1  christos 		wpabuf_free(ie);
   1960       1.1  christos 	}
   1961   1.1.1.2  christos 
   1962   1.1.1.2  christos 	if (pbc)
   1963   1.1.1.2  christos 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
   1964   1.1.1.2  christos 	else if (auth)
   1965   1.1.1.2  christos 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH);
   1966   1.1.1.2  christos 	else if (pin)
   1967   1.1.1.2  christos 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
   1968   1.1.1.2  christos 	else if (wps)
   1969   1.1.1.2  christos 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
   1970       1.1  christos }
   1971       1.1  christos 
   1972       1.1  christos 
   1973       1.1  christos int wpas_wps_searching(struct wpa_supplicant *wpa_s)
   1974       1.1  christos {
   1975       1.1  christos 	struct wpa_ssid *ssid;
   1976       1.1  christos 
   1977       1.1  christos 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
   1978       1.1  christos 		if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
   1979       1.1  christos 			return 1;
   1980       1.1  christos 	}
   1981       1.1  christos 
   1982       1.1  christos 	return 0;
   1983       1.1  christos }
   1984       1.1  christos 
   1985       1.1  christos 
   1986       1.1  christos int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
   1987       1.1  christos 			      char *end)
   1988       1.1  christos {
   1989       1.1  christos 	struct wpabuf *wps_ie;
   1990       1.1  christos 	int ret;
   1991       1.1  christos 
   1992       1.1  christos 	wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA);
   1993       1.1  christos 	if (wps_ie == NULL)
   1994       1.1  christos 		return 0;
   1995       1.1  christos 
   1996       1.1  christos 	ret = wps_attr_text(wps_ie, buf, end);
   1997       1.1  christos 	wpabuf_free(wps_ie);
   1998       1.1  christos 	return ret;
   1999       1.1  christos }
   2000       1.1  christos 
   2001       1.1  christos 
   2002   1.1.1.2  christos int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
   2003       1.1  christos {
   2004       1.1  christos #ifdef CONFIG_WPS_ER
   2005       1.1  christos 	if (wpa_s->wps_er) {
   2006       1.1  christos 		wps_er_refresh(wpa_s->wps_er);
   2007       1.1  christos 		return 0;
   2008       1.1  christos 	}
   2009   1.1.1.2  christos 	wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
   2010       1.1  christos 	if (wpa_s->wps_er == NULL)
   2011       1.1  christos 		return -1;
   2012       1.1  christos 	return 0;
   2013       1.1  christos #else /* CONFIG_WPS_ER */
   2014       1.1  christos 	return 0;
   2015       1.1  christos #endif /* CONFIG_WPS_ER */
   2016       1.1  christos }
   2017       1.1  christos 
   2018       1.1  christos 
   2019   1.1.1.6  christos void wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
   2020       1.1  christos {
   2021       1.1  christos #ifdef CONFIG_WPS_ER
   2022       1.1  christos 	wps_er_deinit(wpa_s->wps_er, NULL, NULL);
   2023       1.1  christos 	wpa_s->wps_er = NULL;
   2024       1.1  christos #endif /* CONFIG_WPS_ER */
   2025       1.1  christos }
   2026       1.1  christos 
   2027       1.1  christos 
   2028       1.1  christos #ifdef CONFIG_WPS_ER
   2029   1.1.1.2  christos int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
   2030   1.1.1.2  christos 			const char *uuid, const char *pin)
   2031       1.1  christos {
   2032       1.1  christos 	u8 u[UUID_LEN];
   2033   1.1.1.5  christos 	const u8 *use_uuid = NULL;
   2034   1.1.1.5  christos 	u8 addr_buf[ETH_ALEN];
   2035       1.1  christos 
   2036   1.1.1.5  christos 	if (os_strcmp(uuid, "any") == 0) {
   2037   1.1.1.5  christos 	} else if (uuid_str2bin(uuid, u) == 0) {
   2038   1.1.1.5  christos 		use_uuid = u;
   2039   1.1.1.5  christos 	} else if (hwaddr_aton(uuid, addr_buf) == 0) {
   2040   1.1.1.5  christos 		use_uuid = wps_er_get_sta_uuid(wpa_s->wps_er, addr_buf);
   2041   1.1.1.5  christos 		if (use_uuid == NULL)
   2042   1.1.1.5  christos 			return -1;
   2043   1.1.1.5  christos 	} else
   2044       1.1  christos 		return -1;
   2045   1.1.1.2  christos 	return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
   2046   1.1.1.5  christos 				     use_uuid,
   2047       1.1  christos 				     (const u8 *) pin, os_strlen(pin), 300);
   2048       1.1  christos }
   2049       1.1  christos 
   2050       1.1  christos 
   2051       1.1  christos int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
   2052       1.1  christos {
   2053   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2054   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2055       1.1  christos 
   2056   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2057   1.1.1.5  christos 		use_uuid = u;
   2058   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2059   1.1.1.5  christos 		use_addr = addr;
   2060   1.1.1.5  christos 	else
   2061       1.1  christos 		return -1;
   2062   1.1.1.5  christos 	return wps_er_pbc(wpa_s->wps_er, use_uuid, use_addr);
   2063       1.1  christos }
   2064       1.1  christos 
   2065       1.1  christos 
   2066       1.1  christos int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
   2067       1.1  christos 		      const char *pin)
   2068       1.1  christos {
   2069   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2070   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2071       1.1  christos 
   2072   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2073   1.1.1.5  christos 		use_uuid = u;
   2074   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2075   1.1.1.5  christos 		use_addr = addr;
   2076   1.1.1.5  christos 	else
   2077       1.1  christos 		return -1;
   2078   1.1.1.5  christos 
   2079   1.1.1.5  christos 	return wps_er_learn(wpa_s->wps_er, use_uuid, use_addr, (const u8 *) pin,
   2080       1.1  christos 			    os_strlen(pin));
   2081       1.1  christos }
   2082       1.1  christos 
   2083       1.1  christos 
   2084   1.1.1.5  christos static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
   2085   1.1.1.5  christos 				    struct wps_credential *cred)
   2086   1.1.1.2  christos {
   2087   1.1.1.5  christos 	os_memset(cred, 0, sizeof(*cred));
   2088   1.1.1.7  christos 	if (ssid->ssid_len > SSID_MAX_LEN)
   2089   1.1.1.2  christos 		return -1;
   2090   1.1.1.5  christos 	os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
   2091   1.1.1.5  christos 	cred->ssid_len = ssid->ssid_len;
   2092   1.1.1.2  christos 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
   2093   1.1.1.5  christos 		cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
   2094   1.1.1.2  christos 			WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
   2095   1.1.1.2  christos 		if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
   2096   1.1.1.5  christos 			cred->encr_type = WPS_ENCR_AES;
   2097   1.1.1.2  christos 		else
   2098   1.1.1.5  christos 			cred->encr_type = WPS_ENCR_TKIP;
   2099   1.1.1.2  christos 		if (ssid->passphrase) {
   2100   1.1.1.5  christos 			cred->key_len = os_strlen(ssid->passphrase);
   2101   1.1.1.5  christos 			if (cred->key_len >= 64)
   2102   1.1.1.2  christos 				return -1;
   2103   1.1.1.5  christos 			os_memcpy(cred->key, ssid->passphrase, cred->key_len);
   2104   1.1.1.2  christos 		} else if (ssid->psk_set) {
   2105   1.1.1.5  christos 			cred->key_len = 32;
   2106   1.1.1.5  christos 			os_memcpy(cred->key, ssid->psk, 32);
   2107   1.1.1.2  christos 		} else
   2108   1.1.1.2  christos 			return -1;
   2109   1.1.1.2  christos 	} else {
   2110   1.1.1.5  christos 		cred->auth_type = WPS_AUTH_OPEN;
   2111   1.1.1.5  christos 		cred->encr_type = WPS_ENCR_NONE;
   2112   1.1.1.2  christos 	}
   2113   1.1.1.5  christos 
   2114   1.1.1.5  christos 	return 0;
   2115   1.1.1.5  christos }
   2116   1.1.1.5  christos 
   2117   1.1.1.5  christos 
   2118   1.1.1.5  christos int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
   2119   1.1.1.5  christos 			   int id)
   2120   1.1.1.5  christos {
   2121   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2122   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2123   1.1.1.5  christos 	struct wpa_ssid *ssid;
   2124   1.1.1.5  christos 	struct wps_credential cred;
   2125   1.1.1.6  christos 	int ret;
   2126   1.1.1.5  christos 
   2127   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2128   1.1.1.5  christos 		use_uuid = u;
   2129   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2130   1.1.1.5  christos 		use_addr = addr;
   2131   1.1.1.5  christos 	else
   2132   1.1.1.5  christos 		return -1;
   2133   1.1.1.5  christos 	ssid = wpa_config_get_network(wpa_s->conf, id);
   2134   1.1.1.5  christos 	if (ssid == NULL || ssid->ssid == NULL)
   2135   1.1.1.5  christos 		return -1;
   2136   1.1.1.5  christos 
   2137   1.1.1.5  christos 	if (wpas_wps_network_to_cred(ssid, &cred) < 0)
   2138   1.1.1.5  christos 		return -1;
   2139   1.1.1.6  christos 	ret = wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
   2140   1.1.1.6  christos 	os_memset(&cred, 0, sizeof(cred));
   2141   1.1.1.6  christos 	return ret;
   2142   1.1.1.2  christos }
   2143   1.1.1.2  christos 
   2144   1.1.1.2  christos 
   2145   1.1.1.2  christos int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
   2146   1.1.1.2  christos 		       const char *pin, struct wps_new_ap_settings *settings)
   2147   1.1.1.2  christos {
   2148   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2149   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2150   1.1.1.2  christos 	struct wps_credential cred;
   2151   1.1.1.2  christos 	size_t len;
   2152   1.1.1.2  christos 
   2153   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2154   1.1.1.5  christos 		use_uuid = u;
   2155   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2156   1.1.1.5  christos 		use_addr = addr;
   2157   1.1.1.5  christos 	else
   2158   1.1.1.2  christos 		return -1;
   2159   1.1.1.2  christos 	if (settings->ssid_hex == NULL || settings->auth == NULL ||
   2160   1.1.1.2  christos 	    settings->encr == NULL || settings->key_hex == NULL)
   2161   1.1.1.2  christos 		return -1;
   2162   1.1.1.2  christos 
   2163   1.1.1.2  christos 	os_memset(&cred, 0, sizeof(cred));
   2164   1.1.1.2  christos 	len = os_strlen(settings->ssid_hex);
   2165   1.1.1.2  christos 	if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
   2166   1.1.1.2  christos 	    hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
   2167   1.1.1.2  christos 		return -1;
   2168   1.1.1.2  christos 	cred.ssid_len = len / 2;
   2169   1.1.1.2  christos 
   2170   1.1.1.2  christos 	len = os_strlen(settings->key_hex);
   2171   1.1.1.2  christos 	if ((len & 1) || len > 2 * sizeof(cred.key) ||
   2172   1.1.1.2  christos 	    hexstr2bin(settings->key_hex, cred.key, len / 2))
   2173   1.1.1.2  christos 		return -1;
   2174   1.1.1.2  christos 	cred.key_len = len / 2;
   2175   1.1.1.2  christos 
   2176   1.1.1.2  christos 	if (os_strcmp(settings->auth, "OPEN") == 0)
   2177   1.1.1.2  christos 		cred.auth_type = WPS_AUTH_OPEN;
   2178   1.1.1.2  christos 	else if (os_strcmp(settings->auth, "WPAPSK") == 0)
   2179   1.1.1.2  christos 		cred.auth_type = WPS_AUTH_WPAPSK;
   2180   1.1.1.2  christos 	else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
   2181   1.1.1.2  christos 		cred.auth_type = WPS_AUTH_WPA2PSK;
   2182   1.1.1.2  christos 	else
   2183   1.1.1.2  christos 		return -1;
   2184   1.1.1.2  christos 
   2185   1.1.1.2  christos 	if (os_strcmp(settings->encr, "NONE") == 0)
   2186   1.1.1.2  christos 		cred.encr_type = WPS_ENCR_NONE;
   2187   1.1.1.5  christos #ifdef CONFIG_TESTING_OPTIONS
   2188   1.1.1.2  christos 	else if (os_strcmp(settings->encr, "WEP") == 0)
   2189   1.1.1.2  christos 		cred.encr_type = WPS_ENCR_WEP;
   2190   1.1.1.5  christos #endif /* CONFIG_TESTING_OPTIONS */
   2191   1.1.1.2  christos 	else if (os_strcmp(settings->encr, "TKIP") == 0)
   2192   1.1.1.2  christos 		cred.encr_type = WPS_ENCR_TKIP;
   2193   1.1.1.2  christos 	else if (os_strcmp(settings->encr, "CCMP") == 0)
   2194   1.1.1.2  christos 		cred.encr_type = WPS_ENCR_AES;
   2195   1.1.1.2  christos 	else
   2196   1.1.1.2  christos 		return -1;
   2197   1.1.1.2  christos 
   2198   1.1.1.5  christos 	return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
   2199   1.1.1.5  christos 			     (const u8 *) pin, os_strlen(pin), &cred);
   2200   1.1.1.2  christos }
   2201   1.1.1.2  christos 
   2202   1.1.1.2  christos 
   2203   1.1.1.4  christos #ifdef CONFIG_WPS_NFC
   2204   1.1.1.4  christos struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
   2205   1.1.1.4  christos 					     int ndef, const char *uuid)
   2206   1.1.1.4  christos {
   2207   1.1.1.4  christos 	struct wpabuf *ret;
   2208   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2209   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2210   1.1.1.4  christos 
   2211   1.1.1.4  christos 	if (!wpa_s->wps_er)
   2212   1.1.1.4  christos 		return NULL;
   2213   1.1.1.4  christos 
   2214   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2215   1.1.1.5  christos 		use_uuid = u;
   2216   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2217   1.1.1.5  christos 		use_addr = addr;
   2218   1.1.1.5  christos 	else
   2219   1.1.1.4  christos 		return NULL;
   2220   1.1.1.4  christos 
   2221   1.1.1.5  christos 	ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
   2222   1.1.1.4  christos 	if (ndef && ret) {
   2223   1.1.1.4  christos 		struct wpabuf *tmp;
   2224   1.1.1.4  christos 		tmp = ndef_build_wifi(ret);
   2225   1.1.1.4  christos 		wpabuf_free(ret);
   2226   1.1.1.4  christos 		if (tmp == NULL)
   2227   1.1.1.4  christos 			return NULL;
   2228   1.1.1.4  christos 		ret = tmp;
   2229   1.1.1.4  christos 	}
   2230   1.1.1.4  christos 
   2231   1.1.1.4  christos 	return ret;
   2232   1.1.1.4  christos }
   2233   1.1.1.4  christos #endif /* CONFIG_WPS_NFC */
   2234   1.1.1.4  christos 
   2235   1.1.1.4  christos 
   2236   1.1.1.2  christos static int callbacks_pending = 0;
   2237   1.1.1.2  christos 
   2238       1.1  christos static void wpas_wps_terminate_cb(void *ctx)
   2239       1.1  christos {
   2240       1.1  christos 	wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
   2241   1.1.1.2  christos 	if (--callbacks_pending <= 0)
   2242   1.1.1.2  christos 		eloop_terminate();
   2243       1.1  christos }
   2244       1.1  christos #endif /* CONFIG_WPS_ER */
   2245       1.1  christos 
   2246       1.1  christos 
   2247       1.1  christos int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
   2248       1.1  christos {
   2249       1.1  christos #ifdef CONFIG_WPS_ER
   2250       1.1  christos 	if (wpa_s->wps_er) {
   2251   1.1.1.2  christos 		callbacks_pending++;
   2252       1.1  christos 		wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
   2253       1.1  christos 		wpa_s->wps_er = NULL;
   2254       1.1  christos 		return 1;
   2255       1.1  christos 	}
   2256       1.1  christos #endif /* CONFIG_WPS_ER */
   2257       1.1  christos 	return 0;
   2258       1.1  christos }
   2259   1.1.1.2  christos 
   2260   1.1.1.2  christos 
   2261   1.1.1.2  christos void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
   2262   1.1.1.2  christos {
   2263   1.1.1.2  christos 	struct wps_context *wps = wpa_s->wps;
   2264   1.1.1.2  christos 
   2265   1.1.1.2  christos 	if (wps == NULL)
   2266   1.1.1.2  christos 		return;
   2267   1.1.1.2  christos 
   2268   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
   2269   1.1.1.2  christos 		wps->config_methods = wps_config_methods_str2bin(
   2270   1.1.1.2  christos 			wpa_s->conf->config_methods);
   2271   1.1.1.2  christos 		if ((wps->config_methods &
   2272   1.1.1.2  christos 		     (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
   2273   1.1.1.2  christos 		    (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
   2274   1.1.1.2  christos 			wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
   2275   1.1.1.2  christos 				   "config methods are not allowed at the "
   2276   1.1.1.2  christos 				   "same time");
   2277   1.1.1.2  christos 			wps->config_methods &= ~WPS_CONFIG_LABEL;
   2278   1.1.1.2  christos 		}
   2279   1.1.1.2  christos 	}
   2280   1.1.1.2  christos 	wps->config_methods = wps_fix_config_methods(wps->config_methods);
   2281   1.1.1.4  christos 	wps->dev.config_methods = wps->config_methods;
   2282   1.1.1.2  christos 
   2283   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
   2284   1.1.1.2  christos 		os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
   2285   1.1.1.2  christos 			  WPS_DEV_TYPE_LEN);
   2286   1.1.1.2  christos 
   2287   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
   2288   1.1.1.2  christos 		wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
   2289   1.1.1.2  christos 		os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
   2290   1.1.1.2  christos 			  wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
   2291   1.1.1.2  christos 	}
   2292   1.1.1.2  christos 
   2293   1.1.1.4  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
   2294   1.1.1.4  christos 		wpas_wps_set_vendor_ext_m1(wpa_s, wps);
   2295   1.1.1.4  christos 
   2296   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
   2297   1.1.1.2  christos 		wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
   2298   1.1.1.2  christos 
   2299   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
   2300   1.1.1.2  christos 		wpas_wps_set_uuid(wpa_s, wps);
   2301   1.1.1.2  christos 
   2302   1.1.1.2  christos 	if (wpa_s->conf->changed_parameters &
   2303   1.1.1.2  christos 	    (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
   2304   1.1.1.2  christos 		/* Update pointers to make sure they refer current values */
   2305   1.1.1.2  christos 		wps->dev.device_name = wpa_s->conf->device_name;
   2306   1.1.1.2  christos 		wps->dev.manufacturer = wpa_s->conf->manufacturer;
   2307   1.1.1.2  christos 		wps->dev.model_name = wpa_s->conf->model_name;
   2308   1.1.1.2  christos 		wps->dev.model_number = wpa_s->conf->model_number;
   2309   1.1.1.2  christos 		wps->dev.serial_number = wpa_s->conf->serial_number;
   2310   1.1.1.2  christos 	}
   2311   1.1.1.2  christos }
   2312   1.1.1.4  christos 
   2313   1.1.1.4  christos 
   2314  1.1.1.10  christos void wpas_wps_update_mac_addr(struct wpa_supplicant *wpa_s)
   2315  1.1.1.10  christos {
   2316  1.1.1.10  christos 	struct wps_context *wps;
   2317  1.1.1.10  christos 
   2318  1.1.1.10  christos 	wps = wpa_s->wps;
   2319  1.1.1.10  christos 	if (wps)
   2320  1.1.1.10  christos 		os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
   2321  1.1.1.10  christos }
   2322  1.1.1.10  christos 
   2323  1.1.1.10  christos 
   2324   1.1.1.4  christos #ifdef CONFIG_WPS_NFC
   2325   1.1.1.4  christos 
   2326   1.1.1.5  christos #ifdef CONFIG_WPS_ER
   2327   1.1.1.5  christos static struct wpabuf *
   2328   1.1.1.5  christos wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
   2329   1.1.1.5  christos 			      struct wpa_ssid *ssid)
   2330   1.1.1.5  christos {
   2331   1.1.1.5  christos 	struct wpabuf *ret;
   2332   1.1.1.5  christos 	struct wps_credential cred;
   2333   1.1.1.5  christos 
   2334   1.1.1.5  christos 	if (wpas_wps_network_to_cred(ssid, &cred) < 0)
   2335   1.1.1.5  christos 		return NULL;
   2336   1.1.1.5  christos 
   2337   1.1.1.5  christos 	ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
   2338   1.1.1.5  christos 
   2339   1.1.1.5  christos 	if (ndef && ret) {
   2340   1.1.1.5  christos 		struct wpabuf *tmp;
   2341   1.1.1.5  christos 		tmp = ndef_build_wifi(ret);
   2342   1.1.1.5  christos 		wpabuf_free(ret);
   2343   1.1.1.5  christos 		if (tmp == NULL)
   2344   1.1.1.5  christos 			return NULL;
   2345   1.1.1.5  christos 		ret = tmp;
   2346   1.1.1.5  christos 	}
   2347   1.1.1.5  christos 
   2348   1.1.1.5  christos 	return ret;
   2349   1.1.1.5  christos }
   2350   1.1.1.5  christos #endif /* CONFIG_WPS_ER */
   2351   1.1.1.5  christos 
   2352   1.1.1.5  christos 
   2353   1.1.1.5  christos struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
   2354   1.1.1.5  christos 					  int ndef, const char *id_str)
   2355   1.1.1.5  christos {
   2356   1.1.1.5  christos #ifdef CONFIG_WPS_ER
   2357   1.1.1.5  christos 	if (id_str) {
   2358   1.1.1.5  christos 		int id;
   2359   1.1.1.5  christos 		char *end = NULL;
   2360   1.1.1.5  christos 		struct wpa_ssid *ssid;
   2361   1.1.1.5  christos 
   2362   1.1.1.5  christos 		id = strtol(id_str, &end, 10);
   2363   1.1.1.5  christos 		if (end && *end)
   2364   1.1.1.5  christos 			return NULL;
   2365   1.1.1.5  christos 
   2366   1.1.1.5  christos 		ssid = wpa_config_get_network(wpa_s->conf, id);
   2367   1.1.1.5  christos 		if (ssid == NULL)
   2368   1.1.1.5  christos 			return NULL;
   2369   1.1.1.5  christos 		return wpas_wps_network_config_token(wpa_s, ndef, ssid);
   2370   1.1.1.5  christos 	}
   2371   1.1.1.5  christos #endif /* CONFIG_WPS_ER */
   2372   1.1.1.5  christos #ifdef CONFIG_AP
   2373   1.1.1.5  christos 	if (wpa_s->ap_iface)
   2374   1.1.1.5  christos 		return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
   2375   1.1.1.5  christos #endif /* CONFIG_AP */
   2376   1.1.1.5  christos 	return NULL;
   2377   1.1.1.5  christos }
   2378   1.1.1.5  christos 
   2379   1.1.1.5  christos 
   2380   1.1.1.4  christos struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
   2381   1.1.1.4  christos {
   2382   1.1.1.5  christos 	if (wpa_s->conf->wps_nfc_pw_from_config) {
   2383   1.1.1.5  christos 		return wps_nfc_token_build(ndef,
   2384   1.1.1.5  christos 					   wpa_s->conf->wps_nfc_dev_pw_id,
   2385   1.1.1.5  christos 					   wpa_s->conf->wps_nfc_dh_pubkey,
   2386   1.1.1.5  christos 					   wpa_s->conf->wps_nfc_dev_pw);
   2387   1.1.1.5  christos 	}
   2388   1.1.1.5  christos 
   2389   1.1.1.4  christos 	return wps_nfc_token_gen(ndef, &wpa_s->conf->wps_nfc_dev_pw_id,
   2390   1.1.1.4  christos 				 &wpa_s->conf->wps_nfc_dh_pubkey,
   2391   1.1.1.4  christos 				 &wpa_s->conf->wps_nfc_dh_privkey,
   2392   1.1.1.4  christos 				 &wpa_s->conf->wps_nfc_dev_pw);
   2393   1.1.1.4  christos }
   2394   1.1.1.4  christos 
   2395   1.1.1.4  christos 
   2396   1.1.1.5  christos int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *go_dev_addr,
   2397   1.1.1.5  christos 		       const u8 *bssid,
   2398   1.1.1.5  christos 		       const struct wpabuf *dev_pw, u16 dev_pw_id,
   2399   1.1.1.5  christos 		       int p2p_group, const u8 *peer_pubkey_hash,
   2400   1.1.1.5  christos 		       const u8 *ssid, size_t ssid_len, int freq)
   2401   1.1.1.4  christos {
   2402   1.1.1.4  christos 	struct wps_context *wps = wpa_s->wps;
   2403   1.1.1.4  christos 	char pw[32 * 2 + 1];
   2404   1.1.1.4  christos 
   2405   1.1.1.5  christos 	if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
   2406   1.1.1.5  christos 		dev_pw = wpa_s->conf->wps_nfc_dev_pw;
   2407   1.1.1.5  christos 		dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
   2408   1.1.1.5  christos 	}
   2409   1.1.1.5  christos 
   2410   1.1.1.4  christos 	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
   2411   1.1.1.5  christos 	    wpa_s->conf->wps_nfc_dh_privkey == NULL) {
   2412   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Missing DH params - "
   2413   1.1.1.5  christos 			   "cannot start NFC-triggered connection");
   2414   1.1.1.4  christos 		return -1;
   2415   1.1.1.5  christos 	}
   2416   1.1.1.5  christos 
   2417   1.1.1.5  christos 	if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
   2418   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Missing Device Password (id=%u) - "
   2419   1.1.1.5  christos 			   "cannot start NFC-triggered connection", dev_pw_id);
   2420   1.1.1.5  christos 		return -1;
   2421   1.1.1.5  christos 	}
   2422   1.1.1.4  christos 
   2423   1.1.1.4  christos 	dh5_free(wps->dh_ctx);
   2424   1.1.1.4  christos 	wpabuf_free(wps->dh_pubkey);
   2425   1.1.1.4  christos 	wpabuf_free(wps->dh_privkey);
   2426   1.1.1.4  christos 	wps->dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
   2427   1.1.1.4  christos 	wps->dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
   2428   1.1.1.4  christos 	if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
   2429   1.1.1.4  christos 		wps->dh_ctx = NULL;
   2430   1.1.1.4  christos 		wpabuf_free(wps->dh_pubkey);
   2431   1.1.1.4  christos 		wps->dh_pubkey = NULL;
   2432   1.1.1.4  christos 		wpabuf_free(wps->dh_privkey);
   2433   1.1.1.4  christos 		wps->dh_privkey = NULL;
   2434   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Failed to get DH priv/pub key");
   2435   1.1.1.4  christos 		return -1;
   2436   1.1.1.4  christos 	}
   2437   1.1.1.4  christos 	wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
   2438   1.1.1.5  christos 	if (wps->dh_ctx == NULL) {
   2439   1.1.1.5  christos 		wpabuf_free(wps->dh_pubkey);
   2440   1.1.1.5  christos 		wps->dh_pubkey = NULL;
   2441   1.1.1.5  christos 		wpabuf_free(wps->dh_privkey);
   2442   1.1.1.5  christos 		wps->dh_privkey = NULL;
   2443   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Failed to initialize DH context");
   2444   1.1.1.4  christos 		return -1;
   2445   1.1.1.5  christos 	}
   2446   1.1.1.4  christos 
   2447   1.1.1.5  christos 	if (dev_pw) {
   2448   1.1.1.5  christos 		wpa_snprintf_hex_uppercase(pw, sizeof(pw),
   2449   1.1.1.5  christos 					   wpabuf_head(dev_pw),
   2450   1.1.1.5  christos 					   wpabuf_len(dev_pw));
   2451   1.1.1.5  christos 	}
   2452   1.1.1.5  christos 	return wpas_wps_start_dev_pw(wpa_s, go_dev_addr, bssid,
   2453   1.1.1.5  christos 				     dev_pw ? pw : NULL,
   2454   1.1.1.5  christos 				     p2p_group, dev_pw_id, peer_pubkey_hash,
   2455   1.1.1.5  christos 				     ssid, ssid_len, freq);
   2456   1.1.1.4  christos }
   2457   1.1.1.4  christos 
   2458   1.1.1.4  christos 
   2459   1.1.1.4  christos static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
   2460   1.1.1.4  christos 			     struct wps_parse_attr *attr)
   2461   1.1.1.4  christos {
   2462   1.1.1.5  christos 	/*
   2463   1.1.1.5  christos 	 * Disable existing networks temporarily to allow the newly learned
   2464   1.1.1.5  christos 	 * credential to be preferred. Enable the temporarily disabled networks
   2465   1.1.1.5  christos 	 * after 10 seconds.
   2466   1.1.1.5  christos 	 */
   2467   1.1.1.5  christos 	wpas_wps_temp_disable(wpa_s, NULL);
   2468   1.1.1.5  christos 	eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
   2469   1.1.1.5  christos 			       NULL);
   2470   1.1.1.4  christos 
   2471   1.1.1.4  christos 	if (wps_oob_use_cred(wpa_s->wps, attr) < 0)
   2472   1.1.1.4  christos 		return -1;
   2473   1.1.1.4  christos 
   2474   1.1.1.4  christos 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
   2475   1.1.1.4  christos 		return 0;
   2476   1.1.1.4  christos 
   2477   1.1.1.5  christos 	if (attr->ap_channel) {
   2478   1.1.1.5  christos 		u16 chan = WPA_GET_BE16(attr->ap_channel);
   2479   1.1.1.4  christos 		int freq = 0;
   2480   1.1.1.4  christos 
   2481   1.1.1.4  christos 		if (chan >= 1 && chan <= 13)
   2482   1.1.1.4  christos 			freq = 2407 + 5 * chan;
   2483   1.1.1.4  christos 		else if (chan == 14)
   2484   1.1.1.4  christos 			freq = 2484;
   2485   1.1.1.4  christos 		else if (chan >= 30)
   2486   1.1.1.4  christos 			freq = 5000 + 5 * chan;
   2487   1.1.1.4  christos 
   2488   1.1.1.4  christos 		if (freq) {
   2489   1.1.1.5  christos 			wpa_printf(MSG_DEBUG, "WPS: Credential container indicated AP channel %u -> %u MHz",
   2490   1.1.1.5  christos 				   chan, freq);
   2491   1.1.1.4  christos 			wpa_s->after_wps = 5;
   2492   1.1.1.4  christos 			wpa_s->wps_freq = freq;
   2493   1.1.1.4  christos 		}
   2494   1.1.1.4  christos 	}
   2495   1.1.1.5  christos 
   2496   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "WPS: Request reconnection with new network "
   2497   1.1.1.5  christos 		   "based on the received credential added");
   2498   1.1.1.5  christos 	wpa_s->normal_scans = 0;
   2499   1.1.1.5  christos 	wpa_supplicant_reinit_autoscan(wpa_s);
   2500   1.1.1.4  christos 	wpa_s->disconnected = 0;
   2501   1.1.1.4  christos 	wpa_s->reassociate = 1;
   2502   1.1.1.5  christos 
   2503   1.1.1.5  christos 	wpa_supplicant_cancel_sched_scan(wpa_s);
   2504   1.1.1.4  christos 	wpa_supplicant_req_scan(wpa_s, 0, 0);
   2505   1.1.1.4  christos 
   2506   1.1.1.4  christos 	return 0;
   2507   1.1.1.4  christos }
   2508   1.1.1.4  christos 
   2509   1.1.1.4  christos 
   2510   1.1.1.4  christos #ifdef CONFIG_WPS_ER
   2511   1.1.1.4  christos static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s,
   2512   1.1.1.4  christos 					   struct wps_parse_attr *attr)
   2513   1.1.1.4  christos {
   2514   1.1.1.4  christos 	return wps_registrar_add_nfc_password_token(
   2515   1.1.1.4  christos 		wpa_s->wps->registrar, attr->oob_dev_password,
   2516   1.1.1.4  christos 		attr->oob_dev_password_len);
   2517   1.1.1.4  christos }
   2518   1.1.1.4  christos #endif /* CONFIG_WPS_ER */
   2519   1.1.1.4  christos 
   2520   1.1.1.4  christos 
   2521   1.1.1.4  christos static int wpas_wps_nfc_tag_process(struct wpa_supplicant *wpa_s,
   2522   1.1.1.4  christos 				    const struct wpabuf *wps)
   2523   1.1.1.4  christos {
   2524   1.1.1.4  christos 	struct wps_parse_attr attr;
   2525   1.1.1.4  christos 
   2526   1.1.1.4  christos 	wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
   2527   1.1.1.4  christos 
   2528   1.1.1.4  christos 	if (wps_parse_msg(wps, &attr)) {
   2529   1.1.1.4  christos 		wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
   2530   1.1.1.4  christos 		return -1;
   2531   1.1.1.4  christos 	}
   2532   1.1.1.4  christos 
   2533   1.1.1.4  christos 	if (attr.num_cred)
   2534   1.1.1.4  christos 		return wpas_wps_use_cred(wpa_s, &attr);
   2535   1.1.1.4  christos 
   2536   1.1.1.4  christos #ifdef CONFIG_WPS_ER
   2537   1.1.1.4  christos 	if (attr.oob_dev_password)
   2538   1.1.1.4  christos 		return wpas_wps_add_nfc_password_token(wpa_s, &attr);
   2539   1.1.1.4  christos #endif /* CONFIG_WPS_ER */
   2540   1.1.1.4  christos 
   2541   1.1.1.4  christos 	wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
   2542   1.1.1.4  christos 	return -1;
   2543   1.1.1.4  christos }
   2544   1.1.1.4  christos 
   2545   1.1.1.4  christos 
   2546   1.1.1.4  christos int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
   2547   1.1.1.5  christos 			  const struct wpabuf *data, int forced_freq)
   2548   1.1.1.4  christos {
   2549   1.1.1.4  christos 	const struct wpabuf *wps = data;
   2550   1.1.1.4  christos 	struct wpabuf *tmp = NULL;
   2551   1.1.1.4  christos 	int ret;
   2552   1.1.1.4  christos 
   2553   1.1.1.4  christos 	if (wpabuf_len(data) < 4)
   2554   1.1.1.4  christos 		return -1;
   2555   1.1.1.4  christos 
   2556   1.1.1.4  christos 	if (*wpabuf_head_u8(data) != 0x10) {
   2557   1.1.1.4  christos 		/* Assume this contains full NDEF record */
   2558   1.1.1.4  christos 		tmp = ndef_parse_wifi(data);
   2559   1.1.1.4  christos 		if (tmp == NULL) {
   2560   1.1.1.5  christos #ifdef CONFIG_P2P
   2561   1.1.1.5  christos 			tmp = ndef_parse_p2p(data);
   2562   1.1.1.5  christos 			if (tmp) {
   2563   1.1.1.5  christos 				ret = wpas_p2p_nfc_tag_process(wpa_s, tmp,
   2564   1.1.1.5  christos 							       forced_freq);
   2565   1.1.1.5  christos 				wpabuf_free(tmp);
   2566   1.1.1.5  christos 				return ret;
   2567   1.1.1.5  christos 			}
   2568   1.1.1.5  christos #endif /* CONFIG_P2P */
   2569   1.1.1.4  christos 			wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
   2570   1.1.1.4  christos 			return -1;
   2571   1.1.1.4  christos 		}
   2572   1.1.1.4  christos 		wps = tmp;
   2573   1.1.1.4  christos 	}
   2574   1.1.1.4  christos 
   2575   1.1.1.4  christos 	ret = wpas_wps_nfc_tag_process(wpa_s, wps);
   2576   1.1.1.4  christos 	wpabuf_free(tmp);
   2577   1.1.1.4  christos 	return ret;
   2578   1.1.1.4  christos }
   2579   1.1.1.4  christos 
   2580   1.1.1.4  christos 
   2581   1.1.1.5  christos struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
   2582   1.1.1.5  christos 					  int ndef)
   2583   1.1.1.4  christos {
   2584   1.1.1.5  christos 	struct wpabuf *ret;
   2585   1.1.1.5  christos 
   2586   1.1.1.5  christos 	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
   2587   1.1.1.5  christos 	    wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
   2588   1.1.1.5  christos 			   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
   2589   1.1.1.5  christos 		return NULL;
   2590   1.1.1.5  christos 
   2591   1.1.1.5  christos 	ret = wps_build_nfc_handover_req(wpa_s->wps,
   2592   1.1.1.5  christos 					 wpa_s->conf->wps_nfc_dh_pubkey);
   2593   1.1.1.5  christos 
   2594   1.1.1.5  christos 	if (ndef && ret) {
   2595   1.1.1.5  christos 		struct wpabuf *tmp;
   2596   1.1.1.5  christos 		tmp = ndef_build_wifi(ret);
   2597   1.1.1.5  christos 		wpabuf_free(ret);
   2598   1.1.1.5  christos 		if (tmp == NULL)
   2599   1.1.1.5  christos 			return NULL;
   2600   1.1.1.5  christos 		ret = tmp;
   2601   1.1.1.5  christos 	}
   2602   1.1.1.5  christos 
   2603   1.1.1.5  christos 	return ret;
   2604   1.1.1.4  christos }
   2605   1.1.1.4  christos 
   2606   1.1.1.4  christos 
   2607   1.1.1.5  christos #ifdef CONFIG_WPS_NFC
   2608   1.1.1.5  christos 
   2609   1.1.1.5  christos static struct wpabuf *
   2610   1.1.1.5  christos wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s, int ndef,
   2611   1.1.1.5  christos 			     const char *uuid)
   2612   1.1.1.4  christos {
   2613   1.1.1.5  christos #ifdef CONFIG_WPS_ER
   2614   1.1.1.5  christos 	struct wpabuf *ret;
   2615   1.1.1.5  christos 	u8 u[UUID_LEN], *use_uuid = NULL;
   2616   1.1.1.5  christos 	u8 addr[ETH_ALEN], *use_addr = NULL;
   2617   1.1.1.5  christos 	struct wps_context *wps = wpa_s->wps;
   2618   1.1.1.5  christos 
   2619   1.1.1.5  christos 	if (wps == NULL)
   2620   1.1.1.5  christos 		return NULL;
   2621   1.1.1.5  christos 
   2622   1.1.1.5  christos 	if (uuid == NULL)
   2623   1.1.1.5  christos 		return NULL;
   2624   1.1.1.5  christos 	if (uuid_str2bin(uuid, u) == 0)
   2625   1.1.1.5  christos 		use_uuid = u;
   2626   1.1.1.5  christos 	else if (hwaddr_aton(uuid, addr) == 0)
   2627   1.1.1.5  christos 		use_addr = addr;
   2628   1.1.1.5  christos 	else
   2629   1.1.1.5  christos 		return NULL;
   2630   1.1.1.5  christos 
   2631   1.1.1.5  christos 	if (wpa_s->conf->wps_nfc_dh_pubkey == NULL) {
   2632   1.1.1.5  christos 		if (wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
   2633   1.1.1.5  christos 				   &wpa_s->conf->wps_nfc_dh_privkey) < 0)
   2634   1.1.1.5  christos 			return NULL;
   2635   1.1.1.5  christos 	}
   2636   1.1.1.5  christos 
   2637   1.1.1.5  christos 	wpas_wps_nfc_clear(wps);
   2638   1.1.1.5  christos 	wps->ap_nfc_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
   2639   1.1.1.5  christos 	wps->ap_nfc_dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
   2640   1.1.1.5  christos 	wps->ap_nfc_dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
   2641   1.1.1.5  christos 	if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey) {
   2642   1.1.1.5  christos 		wpas_wps_nfc_clear(wps);
   2643   1.1.1.5  christos 		return NULL;
   2644   1.1.1.5  christos 	}
   2645   1.1.1.5  christos 
   2646   1.1.1.5  christos 	ret = wps_er_nfc_handover_sel(wpa_s->wps_er, wpa_s->wps, use_uuid,
   2647   1.1.1.5  christos 				      use_addr, wpa_s->conf->wps_nfc_dh_pubkey);
   2648   1.1.1.5  christos 	if (ndef && ret) {
   2649   1.1.1.5  christos 		struct wpabuf *tmp;
   2650   1.1.1.5  christos 		tmp = ndef_build_wifi(ret);
   2651   1.1.1.5  christos 		wpabuf_free(ret);
   2652   1.1.1.5  christos 		if (tmp == NULL)
   2653   1.1.1.5  christos 			return NULL;
   2654   1.1.1.5  christos 		ret = tmp;
   2655   1.1.1.5  christos 	}
   2656   1.1.1.5  christos 
   2657   1.1.1.5  christos 	return ret;
   2658   1.1.1.5  christos #else /* CONFIG_WPS_ER */
   2659   1.1.1.4  christos 	return NULL;
   2660   1.1.1.5  christos #endif /* CONFIG_WPS_ER */
   2661   1.1.1.4  christos }
   2662   1.1.1.5  christos #endif /* CONFIG_WPS_NFC */
   2663   1.1.1.4  christos 
   2664   1.1.1.4  christos 
   2665   1.1.1.5  christos struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
   2666   1.1.1.5  christos 					  int ndef, int cr, const char *uuid)
   2667   1.1.1.4  christos {
   2668   1.1.1.5  christos 	struct wpabuf *ret;
   2669   1.1.1.5  christos 	if (!cr)
   2670   1.1.1.5  christos 		return NULL;
   2671   1.1.1.5  christos 	ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
   2672   1.1.1.5  christos 	if (ret)
   2673   1.1.1.5  christos 		return ret;
   2674   1.1.1.5  christos 	return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
   2675   1.1.1.4  christos }
   2676   1.1.1.4  christos 
   2677   1.1.1.4  christos 
   2678   1.1.1.5  christos static int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
   2679   1.1.1.5  christos 					const struct wpabuf *data)
   2680   1.1.1.4  christos {
   2681   1.1.1.4  christos 	struct wpabuf *wps;
   2682   1.1.1.5  christos 	int ret = -1;
   2683   1.1.1.5  christos 	u16 wsc_len;
   2684   1.1.1.5  christos 	const u8 *pos;
   2685   1.1.1.5  christos 	struct wpabuf msg;
   2686   1.1.1.5  christos 	struct wps_parse_attr attr;
   2687   1.1.1.5  christos 	u16 dev_pw_id;
   2688   1.1.1.5  christos 	const u8 *bssid = NULL;
   2689   1.1.1.5  christos 	int freq = 0;
   2690   1.1.1.4  christos 
   2691   1.1.1.4  christos 	wps = ndef_parse_wifi(data);
   2692   1.1.1.4  christos 	if (wps == NULL)
   2693   1.1.1.4  christos 		return -1;
   2694   1.1.1.4  christos 	wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
   2695   1.1.1.4  christos 		   "payload from NFC connection handover");
   2696   1.1.1.5  christos 	wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
   2697   1.1.1.5  christos 	if (wpabuf_len(wps) < 2) {
   2698   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Select "
   2699   1.1.1.5  christos 			   "Message");
   2700   1.1.1.5  christos 		goto out;
   2701   1.1.1.5  christos 	}
   2702   1.1.1.5  christos 	pos = wpabuf_head(wps);
   2703   1.1.1.5  christos 	wsc_len = WPA_GET_BE16(pos);
   2704   1.1.1.5  christos 	if (wsc_len > wpabuf_len(wps) - 2) {
   2705   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
   2706   1.1.1.5  christos 			   "in Wi-Fi Handover Select Message", wsc_len);
   2707   1.1.1.5  christos 		goto out;
   2708   1.1.1.5  christos 	}
   2709   1.1.1.5  christos 	pos += 2;
   2710   1.1.1.5  christos 
   2711   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG,
   2712   1.1.1.5  christos 		    "WPS: WSC attributes in Wi-Fi Handover Select Message",
   2713   1.1.1.5  christos 		    pos, wsc_len);
   2714   1.1.1.5  christos 	if (wsc_len < wpabuf_len(wps) - 2) {
   2715   1.1.1.5  christos 		wpa_hexdump(MSG_DEBUG,
   2716   1.1.1.5  christos 			    "WPS: Ignore extra data after WSC attributes",
   2717   1.1.1.5  christos 			    pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
   2718   1.1.1.5  christos 	}
   2719   1.1.1.5  christos 
   2720   1.1.1.5  christos 	wpabuf_set(&msg, pos, wsc_len);
   2721   1.1.1.5  christos 	ret = wps_parse_msg(&msg, &attr);
   2722   1.1.1.5  christos 	if (ret < 0) {
   2723   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
   2724   1.1.1.5  christos 			   "Wi-Fi Handover Select Message");
   2725   1.1.1.5  christos 		goto out;
   2726   1.1.1.5  christos 	}
   2727   1.1.1.5  christos 
   2728   1.1.1.5  christos 	if (attr.oob_dev_password == NULL ||
   2729   1.1.1.5  christos 	    attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
   2730   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
   2731   1.1.1.5  christos 			   "included in Wi-Fi Handover Select Message");
   2732   1.1.1.5  christos 		ret = -1;
   2733   1.1.1.5  christos 		goto out;
   2734   1.1.1.5  christos 	}
   2735   1.1.1.5  christos 
   2736   1.1.1.5  christos 	if (attr.ssid == NULL) {
   2737   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: No SSID included in Wi-Fi Handover "
   2738   1.1.1.5  christos 			   "Select Message");
   2739   1.1.1.5  christos 		ret = -1;
   2740   1.1.1.5  christos 		goto out;
   2741   1.1.1.5  christos 	}
   2742   1.1.1.5  christos 
   2743   1.1.1.5  christos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", attr.ssid, attr.ssid_len);
   2744   1.1.1.5  christos 
   2745   1.1.1.5  christos 	if (attr.mac_addr) {
   2746   1.1.1.5  christos 		bssid = attr.mac_addr;
   2747   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: MAC Address (BSSID): " MACSTR,
   2748   1.1.1.5  christos 			   MAC2STR(bssid));
   2749   1.1.1.5  christos 	}
   2750   1.1.1.5  christos 
   2751   1.1.1.5  christos 	if (attr.rf_bands)
   2752   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: RF Bands: %d", *attr.rf_bands);
   2753   1.1.1.5  christos 
   2754   1.1.1.5  christos 	if (attr.ap_channel) {
   2755   1.1.1.5  christos 		u16 chan = WPA_GET_BE16(attr.ap_channel);
   2756   1.1.1.5  christos 
   2757   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: AP Channel: %d", chan);
   2758   1.1.1.5  christos 
   2759   1.1.1.5  christos 		if (chan >= 1 && chan <= 13 &&
   2760   1.1.1.5  christos 		    (attr.rf_bands == NULL || *attr.rf_bands & WPS_RF_24GHZ))
   2761   1.1.1.5  christos 			freq = 2407 + 5 * chan;
   2762   1.1.1.5  christos 		else if (chan == 14 &&
   2763   1.1.1.5  christos 			 (attr.rf_bands == NULL ||
   2764   1.1.1.5  christos 			  *attr.rf_bands & WPS_RF_24GHZ))
   2765   1.1.1.5  christos 			freq = 2484;
   2766   1.1.1.5  christos 		else if (chan >= 30 &&
   2767   1.1.1.5  christos 			 (attr.rf_bands == NULL ||
   2768   1.1.1.5  christos 			  *attr.rf_bands & WPS_RF_50GHZ))
   2769   1.1.1.5  christos 			freq = 5000 + 5 * chan;
   2770  1.1.1.10  christos 		else if (chan >= 1 && chan <= 6 &&
   2771   1.1.1.7  christos 			 (attr.rf_bands == NULL ||
   2772   1.1.1.7  christos 			  *attr.rf_bands & WPS_RF_60GHZ))
   2773   1.1.1.7  christos 			freq = 56160 + 2160 * chan;
   2774   1.1.1.5  christos 
   2775   1.1.1.5  christos 		if (freq) {
   2776   1.1.1.5  christos 			wpa_printf(MSG_DEBUG,
   2777   1.1.1.5  christos 				   "WPS: AP indicated channel %u -> %u MHz",
   2778   1.1.1.5  christos 				   chan, freq);
   2779   1.1.1.5  christos 		}
   2780   1.1.1.5  christos 	}
   2781   1.1.1.5  christos 
   2782   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
   2783   1.1.1.5  christos 		    attr.oob_dev_password, attr.oob_dev_password_len);
   2784   1.1.1.5  christos 	dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
   2785   1.1.1.5  christos 				 WPS_OOB_PUBKEY_HASH_LEN);
   2786   1.1.1.5  christos 	if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
   2787   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
   2788   1.1.1.5  christos 			   "%u in Wi-Fi Handover Select Message", dev_pw_id);
   2789   1.1.1.5  christos 		ret = -1;
   2790   1.1.1.5  christos 		goto out;
   2791   1.1.1.5  christos 	}
   2792   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG, "WPS: AP Public Key hash",
   2793   1.1.1.5  christos 		    attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
   2794   1.1.1.5  christos 
   2795   1.1.1.5  christos 	ret = wpas_wps_start_nfc(wpa_s, NULL, bssid, NULL, dev_pw_id, 0,
   2796   1.1.1.5  christos 				 attr.oob_dev_password,
   2797   1.1.1.5  christos 				 attr.ssid, attr.ssid_len, freq);
   2798   1.1.1.5  christos 
   2799   1.1.1.5  christos out:
   2800   1.1.1.4  christos 	wpabuf_free(wps);
   2801   1.1.1.5  christos 	return ret;
   2802   1.1.1.5  christos }
   2803   1.1.1.5  christos 
   2804   1.1.1.5  christos 
   2805   1.1.1.5  christos int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
   2806   1.1.1.5  christos 				 const struct wpabuf *req,
   2807   1.1.1.5  christos 				 const struct wpabuf *sel)
   2808   1.1.1.5  christos {
   2809   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "NFC: WPS connection handover reported");
   2810   1.1.1.5  christos 	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in request", req);
   2811   1.1.1.5  christos 	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in select", sel);
   2812   1.1.1.5  christos 	return wpas_wps_nfc_rx_handover_sel(wpa_s, sel);
   2813   1.1.1.5  christos }
   2814   1.1.1.5  christos 
   2815   1.1.1.5  christos 
   2816   1.1.1.5  christos int wpas_er_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
   2817   1.1.1.5  christos 				    const struct wpabuf *req,
   2818   1.1.1.5  christos 				    const struct wpabuf *sel)
   2819   1.1.1.5  christos {
   2820   1.1.1.5  christos 	struct wpabuf *wps;
   2821   1.1.1.5  christos 	int ret = -1;
   2822   1.1.1.5  christos 	u16 wsc_len;
   2823   1.1.1.5  christos 	const u8 *pos;
   2824   1.1.1.5  christos 	struct wpabuf msg;
   2825   1.1.1.5  christos 	struct wps_parse_attr attr;
   2826   1.1.1.5  christos 	u16 dev_pw_id;
   2827   1.1.1.5  christos 
   2828   1.1.1.5  christos 	/*
   2829   1.1.1.5  christos 	 * Enrollee/station is always initiator of the NFC connection handover,
   2830   1.1.1.5  christos 	 * so use the request message here to find Enrollee public key hash.
   2831   1.1.1.5  christos 	 */
   2832   1.1.1.5  christos 	wps = ndef_parse_wifi(req);
   2833   1.1.1.5  christos 	if (wps == NULL)
   2834   1.1.1.5  christos 		return -1;
   2835   1.1.1.5  christos 	wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
   2836   1.1.1.5  christos 		   "payload from NFC connection handover");
   2837   1.1.1.5  christos 	wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
   2838   1.1.1.5  christos 	if (wpabuf_len(wps) < 2) {
   2839   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Request "
   2840   1.1.1.5  christos 			   "Message");
   2841   1.1.1.5  christos 		goto out;
   2842   1.1.1.5  christos 	}
   2843   1.1.1.5  christos 	pos = wpabuf_head(wps);
   2844   1.1.1.5  christos 	wsc_len = WPA_GET_BE16(pos);
   2845   1.1.1.5  christos 	if (wsc_len > wpabuf_len(wps) - 2) {
   2846   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
   2847   1.1.1.5  christos 			   "in rt Wi-Fi Handover Request Message", wsc_len);
   2848   1.1.1.5  christos 		goto out;
   2849   1.1.1.5  christos 	}
   2850   1.1.1.5  christos 	pos += 2;
   2851   1.1.1.5  christos 
   2852   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG,
   2853   1.1.1.5  christos 		    "WPS: WSC attributes in Wi-Fi Handover Request Message",
   2854   1.1.1.5  christos 		    pos, wsc_len);
   2855   1.1.1.5  christos 	if (wsc_len < wpabuf_len(wps) - 2) {
   2856   1.1.1.5  christos 		wpa_hexdump(MSG_DEBUG,
   2857   1.1.1.5  christos 			    "WPS: Ignore extra data after WSC attributes",
   2858   1.1.1.5  christos 			    pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
   2859   1.1.1.5  christos 	}
   2860   1.1.1.5  christos 
   2861   1.1.1.5  christos 	wpabuf_set(&msg, pos, wsc_len);
   2862   1.1.1.5  christos 	ret = wps_parse_msg(&msg, &attr);
   2863   1.1.1.5  christos 	if (ret < 0) {
   2864   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
   2865   1.1.1.5  christos 			   "Wi-Fi Handover Request Message");
   2866   1.1.1.5  christos 		goto out;
   2867   1.1.1.5  christos 	}
   2868   1.1.1.5  christos 
   2869   1.1.1.5  christos 	if (attr.oob_dev_password == NULL ||
   2870   1.1.1.5  christos 	    attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
   2871   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
   2872   1.1.1.5  christos 			   "included in Wi-Fi Handover Request Message");
   2873   1.1.1.5  christos 		ret = -1;
   2874   1.1.1.5  christos 		goto out;
   2875   1.1.1.5  christos 	}
   2876   1.1.1.5  christos 
   2877   1.1.1.5  christos 	if (attr.uuid_e == NULL) {
   2878   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: No UUID-E included in Wi-Fi "
   2879   1.1.1.5  christos 			   "Handover Request Message");
   2880   1.1.1.5  christos 		ret = -1;
   2881   1.1.1.5  christos 		goto out;
   2882   1.1.1.5  christos 	}
   2883   1.1.1.5  christos 
   2884   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", attr.uuid_e, WPS_UUID_LEN);
   2885   1.1.1.5  christos 
   2886   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
   2887   1.1.1.5  christos 		    attr.oob_dev_password, attr.oob_dev_password_len);
   2888   1.1.1.5  christos 	dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
   2889   1.1.1.5  christos 				 WPS_OOB_PUBKEY_HASH_LEN);
   2890   1.1.1.5  christos 	if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
   2891   1.1.1.5  christos 		wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
   2892   1.1.1.5  christos 			   "%u in Wi-Fi Handover Request Message", dev_pw_id);
   2893   1.1.1.5  christos 		ret = -1;
   2894   1.1.1.5  christos 		goto out;
   2895   1.1.1.5  christos 	}
   2896   1.1.1.5  christos 	wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Public Key hash",
   2897   1.1.1.5  christos 		    attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
   2898   1.1.1.5  christos 
   2899   1.1.1.5  christos 	ret = wps_registrar_add_nfc_pw_token(wpa_s->wps->registrar,
   2900   1.1.1.5  christos 					     attr.oob_dev_password,
   2901   1.1.1.5  christos 					     DEV_PW_NFC_CONNECTION_HANDOVER,
   2902   1.1.1.5  christos 					     NULL, 0, 1);
   2903   1.1.1.4  christos 
   2904   1.1.1.5  christos out:
   2905   1.1.1.5  christos 	wpabuf_free(wps);
   2906   1.1.1.4  christos 	return ret;
   2907   1.1.1.4  christos }
   2908   1.1.1.4  christos 
   2909   1.1.1.4  christos #endif /* CONFIG_WPS_NFC */
   2910   1.1.1.4  christos 
   2911   1.1.1.4  christos 
   2912   1.1.1.4  christos static void wpas_wps_dump_ap_info(struct wpa_supplicant *wpa_s)
   2913   1.1.1.4  christos {
   2914   1.1.1.4  christos 	size_t i;
   2915   1.1.1.5  christos 	struct os_reltime now;
   2916   1.1.1.4  christos 
   2917   1.1.1.4  christos 	if (wpa_debug_level > MSG_DEBUG)
   2918   1.1.1.4  christos 		return;
   2919   1.1.1.4  christos 
   2920   1.1.1.4  christos 	if (wpa_s->wps_ap == NULL)
   2921   1.1.1.4  christos 		return;
   2922   1.1.1.4  christos 
   2923   1.1.1.5  christos 	os_get_reltime(&now);
   2924   1.1.1.4  christos 
   2925   1.1.1.4  christos 	for (i = 0; i < wpa_s->num_wps_ap; i++) {
   2926   1.1.1.4  christos 		struct wps_ap_info *ap = &wpa_s->wps_ap[i];
   2927  1.1.1.10  christos 		struct wpa_bssid_ignore *e = wpa_bssid_ignore_get(wpa_s,
   2928  1.1.1.10  christos 								  ap->bssid);
   2929   1.1.1.4  christos 
   2930   1.1.1.4  christos 		wpa_printf(MSG_DEBUG, "WPS: AP[%d] " MACSTR " type=%d "
   2931  1.1.1.10  christos 			   "tries=%d last_attempt=%d sec ago bssid_ignore=%d",
   2932   1.1.1.4  christos 			   (int) i, MAC2STR(ap->bssid), ap->type, ap->tries,
   2933   1.1.1.4  christos 			   ap->last_attempt.sec > 0 ?
   2934   1.1.1.4  christos 			   (int) now.sec - (int) ap->last_attempt.sec : -1,
   2935   1.1.1.4  christos 			   e ? e->count : 0);
   2936   1.1.1.4  christos 	}
   2937   1.1.1.4  christos }
   2938   1.1.1.4  christos 
   2939   1.1.1.4  christos 
   2940   1.1.1.4  christos static struct wps_ap_info * wpas_wps_get_ap_info(struct wpa_supplicant *wpa_s,
   2941   1.1.1.4  christos 						 const u8 *bssid)
   2942   1.1.1.4  christos {
   2943   1.1.1.4  christos 	size_t i;
   2944   1.1.1.4  christos 
   2945   1.1.1.4  christos 	if (wpa_s->wps_ap == NULL)
   2946   1.1.1.4  christos 		return NULL;
   2947   1.1.1.4  christos 
   2948   1.1.1.4  christos 	for (i = 0; i < wpa_s->num_wps_ap; i++) {
   2949   1.1.1.4  christos 		struct wps_ap_info *ap = &wpa_s->wps_ap[i];
   2950  1.1.1.10  christos 		if (ether_addr_equal(ap->bssid, bssid))
   2951   1.1.1.4  christos 			return ap;
   2952   1.1.1.4  christos 	}
   2953   1.1.1.4  christos 
   2954   1.1.1.4  christos 	return NULL;
   2955   1.1.1.4  christos }
   2956   1.1.1.4  christos 
   2957   1.1.1.4  christos 
   2958   1.1.1.4  christos static void wpas_wps_update_ap_info_bss(struct wpa_supplicant *wpa_s,
   2959   1.1.1.4  christos 					struct wpa_scan_res *res)
   2960   1.1.1.4  christos {
   2961   1.1.1.4  christos 	struct wpabuf *wps;
   2962   1.1.1.4  christos 	enum wps_ap_info_type type;
   2963   1.1.1.4  christos 	struct wps_ap_info *ap;
   2964   1.1.1.7  christos 	int r, pbc_active;
   2965   1.1.1.7  christos 	const u8 *uuid;
   2966   1.1.1.4  christos 
   2967   1.1.1.4  christos 	if (wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE) == NULL)
   2968   1.1.1.4  christos 		return;
   2969   1.1.1.4  christos 
   2970   1.1.1.4  christos 	wps = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
   2971   1.1.1.4  christos 	if (wps == NULL)
   2972   1.1.1.4  christos 		return;
   2973   1.1.1.4  christos 
   2974   1.1.1.4  christos 	r = wps_is_addr_authorized(wps, wpa_s->own_addr, 1);
   2975   1.1.1.4  christos 	if (r == 2)
   2976   1.1.1.4  christos 		type = WPS_AP_SEL_REG_OUR;
   2977   1.1.1.4  christos 	else if (r == 1)
   2978   1.1.1.4  christos 		type = WPS_AP_SEL_REG;
   2979   1.1.1.4  christos 	else
   2980   1.1.1.4  christos 		type = WPS_AP_NOT_SEL_REG;
   2981   1.1.1.4  christos 
   2982   1.1.1.7  christos 	uuid = wps_get_uuid_e(wps);
   2983   1.1.1.7  christos 	pbc_active = wps_is_selected_pbc_registrar(wps);
   2984   1.1.1.4  christos 
   2985   1.1.1.4  christos 	ap = wpas_wps_get_ap_info(wpa_s, res->bssid);
   2986   1.1.1.4  christos 	if (ap) {
   2987   1.1.1.4  christos 		if (ap->type != type) {
   2988   1.1.1.4  christos 			wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR
   2989   1.1.1.4  christos 				   " changed type %d -> %d",
   2990   1.1.1.4  christos 				   MAC2STR(res->bssid), ap->type, type);
   2991   1.1.1.4  christos 			ap->type = type;
   2992   1.1.1.4  christos 			if (type != WPS_AP_NOT_SEL_REG)
   2993  1.1.1.10  christos 				wpa_bssid_ignore_del(wpa_s, ap->bssid);
   2994   1.1.1.4  christos 		}
   2995   1.1.1.7  christos 		ap->pbc_active = pbc_active;
   2996   1.1.1.7  christos 		if (uuid)
   2997   1.1.1.7  christos 			os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
   2998   1.1.1.7  christos 		goto out;
   2999   1.1.1.4  christos 	}
   3000   1.1.1.4  christos 
   3001   1.1.1.4  christos 	ap = os_realloc_array(wpa_s->wps_ap, wpa_s->num_wps_ap + 1,
   3002   1.1.1.4  christos 			      sizeof(struct wps_ap_info));
   3003   1.1.1.4  christos 	if (ap == NULL)
   3004   1.1.1.7  christos 		goto out;
   3005   1.1.1.4  christos 
   3006   1.1.1.4  christos 	wpa_s->wps_ap = ap;
   3007   1.1.1.4  christos 	ap = &wpa_s->wps_ap[wpa_s->num_wps_ap];
   3008   1.1.1.4  christos 	wpa_s->num_wps_ap++;
   3009   1.1.1.4  christos 
   3010   1.1.1.4  christos 	os_memset(ap, 0, sizeof(*ap));
   3011   1.1.1.4  christos 	os_memcpy(ap->bssid, res->bssid, ETH_ALEN);
   3012   1.1.1.4  christos 	ap->type = type;
   3013   1.1.1.7  christos 	ap->pbc_active = pbc_active;
   3014   1.1.1.7  christos 	if (uuid)
   3015   1.1.1.7  christos 		os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
   3016   1.1.1.4  christos 	wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR " type %d added",
   3017   1.1.1.4  christos 		   MAC2STR(ap->bssid), ap->type);
   3018   1.1.1.7  christos 
   3019   1.1.1.7  christos out:
   3020   1.1.1.7  christos 	wpabuf_free(wps);
   3021   1.1.1.4  christos }
   3022   1.1.1.4  christos 
   3023   1.1.1.4  christos 
   3024   1.1.1.4  christos void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
   3025   1.1.1.4  christos 			     struct wpa_scan_results *scan_res)
   3026   1.1.1.4  christos {
   3027   1.1.1.4  christos 	size_t i;
   3028   1.1.1.4  christos 
   3029   1.1.1.4  christos 	for (i = 0; i < scan_res->num; i++)
   3030   1.1.1.4  christos 		wpas_wps_update_ap_info_bss(wpa_s, scan_res->res[i]);
   3031   1.1.1.4  christos 
   3032   1.1.1.4  christos 	wpas_wps_dump_ap_info(wpa_s);
   3033   1.1.1.4  christos }
   3034   1.1.1.4  christos 
   3035   1.1.1.4  christos 
   3036  1.1.1.10  christos bool wpas_wps_partner_link_scan_done(struct wpa_supplicant *wpa_s)
   3037  1.1.1.10  christos {
   3038  1.1.1.10  christos 	struct wpa_global *global = wpa_s->global;
   3039  1.1.1.10  christos 	struct wpa_supplicant *iface;
   3040  1.1.1.10  christos 
   3041  1.1.1.10  christos 	for (iface = global->ifaces; iface; iface = iface->next) {
   3042  1.1.1.10  christos 		if (iface == wpa_s)
   3043  1.1.1.10  christos 			continue;
   3044  1.1.1.10  christos 
   3045  1.1.1.10  christos 		if (!iface->supp_pbc_active)
   3046  1.1.1.10  christos 			continue;
   3047  1.1.1.10  christos 
   3048  1.1.1.10  christos 		/* Scan results are available for both links. While the current
   3049  1.1.1.10  christos 		 * link will proceed for network selection, ensure the partner
   3050  1.1.1.10  christos 		 * link also gets an attempt at network selection and connect
   3051  1.1.1.10  christos 		 * with the selected BSS. */
   3052  1.1.1.10  christos 		if (iface->wps_scan_done)
   3053  1.1.1.10  christos 			wpa_wps_supplicant_fast_associate(iface);
   3054  1.1.1.10  christos 		else
   3055  1.1.1.10  christos 			return false;
   3056  1.1.1.10  christos 	}
   3057  1.1.1.10  christos 
   3058  1.1.1.10  christos 	return true;
   3059  1.1.1.10  christos }
   3060  1.1.1.10  christos 
   3061  1.1.1.10  christos 
   3062  1.1.1.10  christos bool wpas_wps_partner_link_overlap_detect(struct wpa_supplicant *wpa_s)
   3063  1.1.1.10  christos {
   3064  1.1.1.10  christos 	struct wpa_global *global = wpa_s->global;
   3065  1.1.1.10  christos 	struct wpa_supplicant *iface;
   3066  1.1.1.10  christos 
   3067  1.1.1.10  christos 	for (iface = global->ifaces; iface; iface = iface->next) {
   3068  1.1.1.10  christos 		if (iface == wpa_s)
   3069  1.1.1.10  christos 			continue;
   3070  1.1.1.10  christos 		if (iface->wps_overlap)
   3071  1.1.1.10  christos 			return true;
   3072  1.1.1.10  christos 	}
   3073  1.1.1.10  christos 
   3074  1.1.1.10  christos 	return false;
   3075  1.1.1.10  christos }
   3076  1.1.1.10  christos 
   3077  1.1.1.10  christos 
   3078   1.1.1.4  christos void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid)
   3079   1.1.1.4  christos {
   3080   1.1.1.4  christos 	struct wps_ap_info *ap;
   3081   1.1.1.5  christos 
   3082   1.1.1.5  christos 	wpa_s->after_wps = 0;
   3083   1.1.1.5  christos 
   3084   1.1.1.4  christos 	if (!wpa_s->wps_ap_iter)
   3085   1.1.1.4  christos 		return;
   3086   1.1.1.4  christos 	ap = wpas_wps_get_ap_info(wpa_s, bssid);
   3087   1.1.1.4  christos 	if (ap == NULL)
   3088   1.1.1.4  christos 		return;
   3089   1.1.1.4  christos 	ap->tries++;
   3090   1.1.1.5  christos 	os_get_reltime(&ap->last_attempt);
   3091   1.1.1.4  christos }
   3092