Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * wpa_supplicant / WPS integration
      3  * Copyright (c) 2008-2010, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #include "includes.h"
     16 
     17 #include "common.h"
     18 #include "eloop.h"
     19 #include "uuid.h"
     20 #include "crypto/dh_group5.h"
     21 #include "common/ieee802_11_defs.h"
     22 #include "common/ieee802_11_common.h"
     23 #include "common/wpa_common.h"
     24 #include "common/wpa_ctrl.h"
     25 #include "eap_common/eap_wsc_common.h"
     26 #include "eap_peer/eap.h"
     27 #include "eapol_supp/eapol_supp_sm.h"
     28 #include "rsn_supp/wpa.h"
     29 #include "config.h"
     30 #include "wpa_supplicant_i.h"
     31 #include "driver_i.h"
     32 #include "notify.h"
     33 #include "blacklist.h"
     34 #include "bss.h"
     35 #include "scan.h"
     36 #include "ap.h"
     37 #include "p2p/p2p.h"
     38 #include "p2p_supplicant.h"
     39 #include "wps_supplicant.h"
     40 
     41 
     42 #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
     43 #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
     44 #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
     45 
     46 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
     47 static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
     48 
     49 
     50 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
     51 {
     52 	if (!wpa_s->wps_success &&
     53 	    wpa_s->current_ssid &&
     54 	    eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
     55 		const u8 *bssid = wpa_s->bssid;
     56 		if (is_zero_ether_addr(bssid))
     57 			bssid = wpa_s->pending_bssid;
     58 
     59 		wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
     60 			   " did not succeed - continue trying to find "
     61 			   "suitable AP", MAC2STR(bssid));
     62 		wpa_blacklist_add(wpa_s, bssid);
     63 
     64 		wpa_supplicant_deauthenticate(wpa_s,
     65 					      WLAN_REASON_DEAUTH_LEAVING);
     66 		wpa_s->reassociate = 1;
     67 		wpa_supplicant_req_scan(wpa_s,
     68 					wpa_s->blacklist_cleared ? 5 : 0, 0);
     69 		wpa_s->blacklist_cleared = 0;
     70 		return 1;
     71 	}
     72 
     73 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
     74 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success)
     75 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL);
     76 
     77 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
     78 	    !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
     79 		int disabled = wpa_s->current_ssid->disabled;
     80 		wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
     81 			   "try to associate with the received credential");
     82 		wpa_supplicant_deauthenticate(wpa_s,
     83 					      WLAN_REASON_DEAUTH_LEAVING);
     84 		if (disabled) {
     85 			wpa_printf(MSG_DEBUG, "WPS: Current network is "
     86 				   "disabled - wait for user to enable");
     87 			return 1;
     88 		}
     89 		wpa_s->after_wps = 5;
     90 		wpa_s->wps_freq = wpa_s->assoc_freq;
     91 		wpa_s->reassociate = 1;
     92 		wpa_supplicant_req_scan(wpa_s, 0, 0);
     93 		return 1;
     94 	}
     95 
     96 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
     97 		wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
     98 			   "for external credential processing");
     99 		wpas_clear_wps(wpa_s);
    100 		wpa_supplicant_deauthenticate(wpa_s,
    101 					      WLAN_REASON_DEAUTH_LEAVING);
    102 		return 1;
    103 	}
    104 
    105 	return 0;
    106 }
    107 
    108 
    109 static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
    110 					 struct wpa_ssid *ssid,
    111 					 const struct wps_credential *cred)
    112 {
    113 	struct wpa_driver_capa capa;
    114 	struct wpa_bss *bss;
    115 	const u8 *ie;
    116 	struct wpa_ie_data adv;
    117 	int wpa2 = 0, ccmp = 0;
    118 
    119 	/*
    120 	 * Many existing WPS APs do not know how to negotiate WPA2 or CCMP in
    121 	 * case they are configured for mixed mode operation (WPA+WPA2 and
    122 	 * TKIP+CCMP). Try to use scan results to figure out whether the AP
    123 	 * actually supports stronger security and select that if the client
    124 	 * has support for it, too.
    125 	 */
    126 
    127 	if (wpa_drv_get_capa(wpa_s, &capa))
    128 		return; /* Unknown what driver supports */
    129 
    130 	bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
    131 	if (bss == NULL) {
    132 		wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
    133 			   "table - use credential as-is");
    134 		return;
    135 	}
    136 
    137 	wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
    138 
    139 	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    140 	if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
    141 		wpa2 = 1;
    142 		if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
    143 			ccmp = 1;
    144 	} else {
    145 		ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    146 		if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 &&
    147 		    adv.pairwise_cipher & WPA_CIPHER_CCMP)
    148 			ccmp = 1;
    149 	}
    150 
    151 	if (ie == NULL && (ssid->proto & WPA_PROTO_WPA) &&
    152 	    (ssid->pairwise_cipher & WPA_CIPHER_TKIP)) {
    153 		/*
    154 		 * TODO: This could be the initial AP configuration and the
    155 		 * Beacon contents could change shortly. Should request a new
    156 		 * scan and delay addition of the network until the updated
    157 		 * scan results are available.
    158 		 */
    159 		wpa_printf(MSG_DEBUG, "WPS: The AP did not yet advertise WPA "
    160 			   "support - use credential as-is");
    161 		return;
    162 	}
    163 
    164 	if (ccmp && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
    165 	    (ssid->pairwise_cipher & WPA_CIPHER_TKIP) &&
    166 	    (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
    167 		wpa_printf(MSG_DEBUG, "WPS: Add CCMP into the credential "
    168 			   "based on scan results");
    169 		if (wpa_s->conf->ap_scan == 1)
    170 			ssid->pairwise_cipher |= WPA_CIPHER_CCMP;
    171 		else
    172 			ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    173 	}
    174 
    175 	if (wpa2 && !(ssid->proto & WPA_PROTO_RSN) &&
    176 	    (ssid->proto & WPA_PROTO_WPA) &&
    177 	    (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
    178 		wpa_printf(MSG_DEBUG, "WPS: Add WPA2 into the credential "
    179 			   "based on scan results");
    180 		if (wpa_s->conf->ap_scan == 1)
    181 			ssid->proto |= WPA_PROTO_RSN;
    182 		else
    183 			ssid->proto = WPA_PROTO_RSN;
    184 	}
    185 }
    186 
    187 
    188 static int wpa_supplicant_wps_cred(void *ctx,
    189 				   const struct wps_credential *cred)
    190 {
    191 	struct wpa_supplicant *wpa_s = ctx;
    192 	struct wpa_ssid *ssid = wpa_s->current_ssid;
    193 	u8 key_idx = 0;
    194 	u16 auth_type;
    195 	int registrar = 0;
    196 
    197 	if ((wpa_s->conf->wps_cred_processing == 1 ||
    198 	     wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
    199 		size_t blen = cred->cred_attr_len * 2 + 1;
    200 		char *buf = os_malloc(blen);
    201 		if (buf) {
    202 			wpa_snprintf_hex(buf, blen,
    203 					 cred->cred_attr, cred->cred_attr_len);
    204 			wpa_msg(wpa_s, MSG_INFO, "%s%s",
    205 				WPS_EVENT_CRED_RECEIVED, buf);
    206 			os_free(buf);
    207 		}
    208 
    209 		wpas_notify_wps_credential(wpa_s, cred);
    210 	} else
    211 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
    212 
    213 	wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
    214 			cred->cred_attr, cred->cred_attr_len);
    215 
    216 	if (wpa_s->conf->wps_cred_processing == 1)
    217 		return 0;
    218 
    219 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
    220 	wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
    221 		   cred->auth_type);
    222 	wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
    223 	wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
    224 	wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
    225 			cred->key, cred->key_len);
    226 	wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
    227 		   MAC2STR(cred->mac_addr));
    228 
    229 	auth_type = cred->auth_type;
    230 	if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
    231 		wpa_printf(MSG_DEBUG, "WPS: Workaround - convert mixed-mode "
    232 			   "auth_type into WPA2PSK");
    233 		auth_type = WPS_AUTH_WPA2PSK;
    234 	}
    235 
    236 	if (auth_type != WPS_AUTH_OPEN &&
    237 	    auth_type != WPS_AUTH_SHARED &&
    238 	    auth_type != WPS_AUTH_WPAPSK &&
    239 	    auth_type != WPS_AUTH_WPA2PSK) {
    240 		wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for "
    241 			   "unsupported authentication type 0x%x",
    242 			   auth_type);
    243 		return 0;
    244 	}
    245 
    246 	if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
    247 		wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
    248 			   "on the received credential");
    249 		if (ssid->eap.identity &&
    250 		    ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
    251 		    os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
    252 			      WSC_ID_REGISTRAR_LEN) == 0)
    253 			registrar = 1;
    254 		os_free(ssid->eap.identity);
    255 		ssid->eap.identity = NULL;
    256 		ssid->eap.identity_len = 0;
    257 		os_free(ssid->eap.phase1);
    258 		ssid->eap.phase1 = NULL;
    259 		os_free(ssid->eap.eap_methods);
    260 		ssid->eap.eap_methods = NULL;
    261 		if (!ssid->p2p_group)
    262 			ssid->temporary = 0;
    263 	} else {
    264 		wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
    265 			   "received credential");
    266 		ssid = wpa_config_add_network(wpa_s->conf);
    267 		if (ssid == NULL)
    268 			return -1;
    269 		wpas_notify_network_added(wpa_s, ssid);
    270 	}
    271 
    272 	wpa_config_set_network_defaults(ssid);
    273 
    274 	os_free(ssid->ssid);
    275 	ssid->ssid = os_malloc(cred->ssid_len);
    276 	if (ssid->ssid) {
    277 		os_memcpy(ssid->ssid, cred->ssid, cred->ssid_len);
    278 		ssid->ssid_len = cred->ssid_len;
    279 	}
    280 
    281 	switch (cred->encr_type) {
    282 	case WPS_ENCR_NONE:
    283 		break;
    284 	case WPS_ENCR_WEP:
    285 		if (cred->key_len <= 0)
    286 			break;
    287 		if (cred->key_len != 5 && cred->key_len != 13 &&
    288 		    cred->key_len != 10 && cred->key_len != 26) {
    289 			wpa_printf(MSG_ERROR, "WPS: Invalid WEP Key length "
    290 				   "%lu", (unsigned long) cred->key_len);
    291 			return -1;
    292 		}
    293 		if (cred->key_idx > NUM_WEP_KEYS) {
    294 			wpa_printf(MSG_ERROR, "WPS: Invalid WEP Key index %d",
    295 				   cred->key_idx);
    296 			return -1;
    297 		}
    298 		if (cred->key_idx)
    299 			key_idx = cred->key_idx - 1;
    300 		if (cred->key_len == 10 || cred->key_len == 26) {
    301 			if (hexstr2bin((char *) cred->key,
    302 				       ssid->wep_key[key_idx],
    303 				       cred->key_len / 2) < 0) {
    304 				wpa_printf(MSG_ERROR, "WPS: Invalid WEP Key "
    305 					   "%d", key_idx);
    306 				return -1;
    307 			}
    308 			ssid->wep_key_len[key_idx] = cred->key_len / 2;
    309 		} else {
    310 			os_memcpy(ssid->wep_key[key_idx], cred->key,
    311 				  cred->key_len);
    312 			ssid->wep_key_len[key_idx] = cred->key_len;
    313 		}
    314 		ssid->wep_tx_keyidx = key_idx;
    315 		break;
    316 	case WPS_ENCR_TKIP:
    317 		ssid->pairwise_cipher = WPA_CIPHER_TKIP;
    318 		break;
    319 	case WPS_ENCR_AES:
    320 		ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    321 		break;
    322 	}
    323 
    324 	switch (auth_type) {
    325 	case WPS_AUTH_OPEN:
    326 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    327 		ssid->key_mgmt = WPA_KEY_MGMT_NONE;
    328 		ssid->proto = 0;
    329 #ifdef CONFIG_WPS_REG_DISABLE_OPEN
    330 		if (registrar) {
    331 			wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OPEN_NETWORK
    332 				"id=%d - Credentials for an open "
    333 				"network disabled by default - use "
    334 				"'select_network %d' to enable",
    335 				ssid->id, ssid->id);
    336 			ssid->disabled = 1;
    337 		}
    338 #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
    339 		break;
    340 	case WPS_AUTH_SHARED:
    341 		ssid->auth_alg = WPA_AUTH_ALG_SHARED;
    342 		ssid->key_mgmt = WPA_KEY_MGMT_NONE;
    343 		ssid->proto = 0;
    344 		break;
    345 	case WPS_AUTH_WPAPSK:
    346 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    347 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    348 		ssid->proto = WPA_PROTO_WPA;
    349 		break;
    350 	case WPS_AUTH_WPA:
    351 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    352 		ssid->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
    353 		ssid->proto = WPA_PROTO_WPA;
    354 		break;
    355 	case WPS_AUTH_WPA2:
    356 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    357 		ssid->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
    358 		ssid->proto = WPA_PROTO_RSN;
    359 		break;
    360 	case WPS_AUTH_WPA2PSK:
    361 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    362 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    363 		ssid->proto = WPA_PROTO_RSN;
    364 		break;
    365 	}
    366 
    367 	if (ssid->key_mgmt == WPA_KEY_MGMT_PSK) {
    368 		if (cred->key_len == 2 * PMK_LEN) {
    369 			if (hexstr2bin((const char *) cred->key, ssid->psk,
    370 				       PMK_LEN)) {
    371 				wpa_printf(MSG_ERROR, "WPS: Invalid Network "
    372 					   "Key");
    373 				return -1;
    374 			}
    375 			ssid->psk_set = 1;
    376 			ssid->export_keys = 1;
    377 		} else if (cred->key_len >= 8 && cred->key_len < 2 * PMK_LEN) {
    378 			os_free(ssid->passphrase);
    379 			ssid->passphrase = os_malloc(cred->key_len + 1);
    380 			if (ssid->passphrase == NULL)
    381 				return -1;
    382 			os_memcpy(ssid->passphrase, cred->key, cred->key_len);
    383 			ssid->passphrase[cred->key_len] = '\0';
    384 			wpa_config_update_psk(ssid);
    385 			ssid->export_keys = 1;
    386 		} else {
    387 			wpa_printf(MSG_ERROR, "WPS: Invalid Network Key "
    388 				   "length %lu",
    389 				   (unsigned long) cred->key_len);
    390 			return -1;
    391 		}
    392 	}
    393 
    394 	wpas_wps_security_workaround(wpa_s, ssid, cred);
    395 
    396 #ifndef CONFIG_NO_CONFIG_WRITE
    397 	if (wpa_s->conf->update_config &&
    398 	    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
    399 		wpa_printf(MSG_DEBUG, "WPS: Failed to update configuration");
    400 		return -1;
    401 	}
    402 #endif /* CONFIG_NO_CONFIG_WRITE */
    403 
    404 	return 0;
    405 }
    406 
    407 
    408 #ifdef CONFIG_P2P
    409 static void wpas_wps_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
    410 {
    411 	struct wpa_supplicant *wpa_s = eloop_ctx;
    412 	wpas_p2p_notif_pbc_overlap(wpa_s);
    413 }
    414 #endif /* CONFIG_P2P */
    415 
    416 
    417 static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
    418 					 struct wps_event_m2d *m2d)
    419 {
    420 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
    421 		"dev_password_id=%d config_error=%d",
    422 		m2d->dev_password_id, m2d->config_error);
    423 	wpas_notify_wps_event_m2d(wpa_s, m2d);
    424 #ifdef CONFIG_P2P
    425 	if (wpa_s->parent && wpa_s->parent != wpa_s) {
    426 		wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_M2D
    427 			"dev_password_id=%d config_error=%d",
    428 			m2d->dev_password_id, m2d->config_error);
    429 	}
    430 	if (m2d->config_error == WPS_CFG_MULTIPLE_PBC_DETECTED) {
    431 		/*
    432 		 * Notify P2P from eloop timeout to avoid issues with the
    433 		 * interface getting removed while processing a message.
    434 		 */
    435 		eloop_register_timeout(0, 0, wpas_wps_pbc_overlap_cb, wpa_s,
    436 				       NULL);
    437 	}
    438 #endif /* CONFIG_P2P */
    439 }
    440 
    441 
    442 static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
    443 	"No Error", /* WPS_EI_NO_ERROR */
    444 	"TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
    445 	"WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
    446 };
    447 
    448 static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
    449 					  struct wps_event_fail *fail)
    450 {
    451 	if (fail->error_indication > 0 &&
    452 	    fail->error_indication < NUM_WPS_EI_VALUES) {
    453 		wpa_msg(wpa_s, MSG_INFO,
    454 			WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
    455 			fail->msg, fail->config_error, fail->error_indication,
    456 			wps_event_fail_reason[fail->error_indication]);
    457 		if (wpa_s->parent && wpa_s->parent != wpa_s)
    458 			wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
    459 				"msg=%d config_error=%d reason=%d (%s)",
    460 				fail->msg, fail->config_error,
    461 				fail->error_indication,
    462 				wps_event_fail_reason[fail->error_indication]);
    463 	} else {
    464 		wpa_msg(wpa_s, MSG_INFO,
    465 			WPS_EVENT_FAIL "msg=%d config_error=%d",
    466 			fail->msg, fail->config_error);
    467 		if (wpa_s->parent && wpa_s->parent != wpa_s)
    468 			wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
    469 				"msg=%d config_error=%d",
    470 				fail->msg, fail->config_error);
    471 	}
    472 	wpas_clear_wps(wpa_s);
    473 	wpas_notify_wps_event_fail(wpa_s, fail);
    474 #ifdef CONFIG_P2P
    475 	wpas_p2p_wps_failed(wpa_s, fail);
    476 #endif /* CONFIG_P2P */
    477 }
    478 
    479 
    480 static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
    481 {
    482 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
    483 	wpa_s->wps_success = 1;
    484 	wpas_notify_wps_event_success(wpa_s);
    485 #ifdef CONFIG_P2P
    486 	wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
    487 #endif /* CONFIG_P2P */
    488 }
    489 
    490 
    491 static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
    492 					       struct wps_event_er_ap *ap)
    493 {
    494 	char uuid_str[100];
    495 	char dev_type[WPS_DEV_TYPE_BUFSIZE];
    496 
    497 	uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
    498 	if (ap->pri_dev_type)
    499 		wps_dev_type_bin2str(ap->pri_dev_type, dev_type,
    500 				     sizeof(dev_type));
    501 	else
    502 		dev_type[0] = '\0';
    503 
    504 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR
    505 		" pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|",
    506 		uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state,
    507 		ap->friendly_name ? ap->friendly_name : "",
    508 		ap->manufacturer ? ap->manufacturer : "",
    509 		ap->model_description ? ap->model_description : "",
    510 		ap->model_name ? ap->model_name : "",
    511 		ap->manufacturer_url ? ap->manufacturer_url : "",
    512 		ap->model_url ? ap->model_url : "");
    513 }
    514 
    515 
    516 static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
    517 						  struct wps_event_er_ap *ap)
    518 {
    519 	char uuid_str[100];
    520 	uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
    521 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
    522 }
    523 
    524 
    525 static void wpa_supplicant_wps_event_er_enrollee_add(
    526 	struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
    527 {
    528 	char uuid_str[100];
    529 	char dev_type[WPS_DEV_TYPE_BUFSIZE];
    530 
    531 	uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
    532 	if (enrollee->pri_dev_type)
    533 		wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type,
    534 				     sizeof(dev_type));
    535 	else
    536 		dev_type[0] = '\0';
    537 
    538 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
    539 		" M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
    540 		"|%s|%s|%s|%s|%s|",
    541 		uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
    542 		enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
    543 		enrollee->dev_name ? enrollee->dev_name : "",
    544 		enrollee->manufacturer ? enrollee->manufacturer : "",
    545 		enrollee->model_name ? enrollee->model_name : "",
    546 		enrollee->model_number ? enrollee->model_number : "",
    547 		enrollee->serial_number ? enrollee->serial_number : "");
    548 }
    549 
    550 
    551 static void wpa_supplicant_wps_event_er_enrollee_remove(
    552 	struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
    553 {
    554 	char uuid_str[100];
    555 	uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
    556 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
    557 		uuid_str, MAC2STR(enrollee->mac_addr));
    558 }
    559 
    560 
    561 static void wpa_supplicant_wps_event_er_ap_settings(
    562 	struct wpa_supplicant *wpa_s,
    563 	struct wps_event_er_ap_settings *ap_settings)
    564 {
    565 	char uuid_str[100];
    566 	char key_str[65];
    567 	const struct wps_credential *cred = ap_settings->cred;
    568 
    569 	key_str[0] = '\0';
    570 	if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
    571 		if (cred->key_len >= 8 && cred->key_len <= 64) {
    572 			os_memcpy(key_str, cred->key, cred->key_len);
    573 			key_str[cred->key_len] = '\0';
    574 		}
    575 	}
    576 
    577 	uuid_bin2str(ap_settings->uuid, uuid_str, sizeof(uuid_str));
    578 	/* Use wpa_msg_ctrl to avoid showing the key in debug log */
    579 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_SETTINGS
    580 		     "uuid=%s ssid=%s auth_type=0x%04x encr_type=0x%04x "
    581 		     "key=%s",
    582 		     uuid_str, wpa_ssid_txt(cred->ssid, cred->ssid_len),
    583 		     cred->auth_type, cred->encr_type, key_str);
    584 }
    585 
    586 
    587 static void wpa_supplicant_wps_event_er_set_sel_reg(
    588 	struct wpa_supplicant *wpa_s,
    589 	struct wps_event_er_set_selected_registrar *ev)
    590 {
    591 	char uuid_str[100];
    592 
    593 	uuid_bin2str(ev->uuid, uuid_str, sizeof(uuid_str));
    594 	switch (ev->state) {
    595 	case WPS_ER_SET_SEL_REG_START:
    596 		wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
    597 			"uuid=%s state=START sel_reg=%d dev_passwd_id=%u "
    598 			"sel_reg_config_methods=0x%x",
    599 			uuid_str, ev->sel_reg, ev->dev_passwd_id,
    600 			ev->sel_reg_config_methods);
    601 		break;
    602 	case WPS_ER_SET_SEL_REG_DONE:
    603 		wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
    604 			"uuid=%s state=DONE", uuid_str);
    605 		break;
    606 	case WPS_ER_SET_SEL_REG_FAILED:
    607 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_SET_SEL_REG
    608 			"uuid=%s state=FAILED", uuid_str);
    609 		break;
    610 	}
    611 }
    612 
    613 
    614 static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
    615 				     union wps_event_data *data)
    616 {
    617 	struct wpa_supplicant *wpa_s = ctx;
    618 	switch (event) {
    619 	case WPS_EV_M2D:
    620 		wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
    621 		break;
    622 	case WPS_EV_FAIL:
    623 		wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
    624 		break;
    625 	case WPS_EV_SUCCESS:
    626 		wpa_supplicant_wps_event_success(wpa_s);
    627 		break;
    628 	case WPS_EV_PWD_AUTH_FAIL:
    629 #ifdef CONFIG_AP
    630 		if (wpa_s->ap_iface && data->pwd_auth_fail.enrollee)
    631 			wpa_supplicant_ap_pwd_auth_fail(wpa_s);
    632 #endif /* CONFIG_AP */
    633 		break;
    634 	case WPS_EV_PBC_OVERLAP:
    635 		break;
    636 	case WPS_EV_PBC_TIMEOUT:
    637 		break;
    638 	case WPS_EV_ER_AP_ADD:
    639 		wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
    640 		break;
    641 	case WPS_EV_ER_AP_REMOVE:
    642 		wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
    643 		break;
    644 	case WPS_EV_ER_ENROLLEE_ADD:
    645 		wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
    646 							 &data->enrollee);
    647 		break;
    648 	case WPS_EV_ER_ENROLLEE_REMOVE:
    649 		wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
    650 							    &data->enrollee);
    651 		break;
    652 	case WPS_EV_ER_AP_SETTINGS:
    653 		wpa_supplicant_wps_event_er_ap_settings(wpa_s,
    654 							&data->ap_settings);
    655 		break;
    656 	case WPS_EV_ER_SET_SELECTED_REGISTRAR:
    657 		wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
    658 							&data->set_sel_reg);
    659 		break;
    660 	}
    661 }
    662 
    663 
    664 enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
    665 {
    666 	if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
    667 	    eap_is_wps_pin_enrollee(&ssid->eap))
    668 		return WPS_REQ_ENROLLEE;
    669 	else
    670 		return WPS_REQ_REGISTRAR;
    671 }
    672 
    673 
    674 static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
    675 {
    676 	int id;
    677 	struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
    678 
    679 	prev_current = wpa_s->current_ssid;
    680 
    681 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
    682 
    683 	/* Remove any existing WPS network from configuration */
    684 	ssid = wpa_s->conf->ssid;
    685 	while (ssid) {
    686 		if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
    687 			if (ssid == wpa_s->current_ssid) {
    688 				wpa_s->current_ssid = NULL;
    689 				if (ssid != NULL)
    690 					wpas_notify_network_changed(wpa_s);
    691 			}
    692 			id = ssid->id;
    693 			remove_ssid = ssid;
    694 		} else
    695 			id = -1;
    696 		ssid = ssid->next;
    697 		if (id >= 0) {
    698 			if (prev_current == remove_ssid) {
    699 				wpa_sm_set_config(wpa_s->wpa, NULL);
    700 				eapol_sm_notify_config(wpa_s->eapol, NULL,
    701 						       NULL);
    702 			}
    703 			wpas_notify_network_removed(wpa_s, remove_ssid);
    704 			wpa_config_remove_network(wpa_s->conf, id);
    705 		}
    706 	}
    707 }
    708 
    709 
    710 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
    711 {
    712 	struct wpa_supplicant *wpa_s = eloop_ctx;
    713 	wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
    714 		"out");
    715 	wpas_clear_wps(wpa_s);
    716 }
    717 
    718 
    719 static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
    720 					      int registrar, const u8 *bssid)
    721 {
    722 	struct wpa_ssid *ssid;
    723 
    724 	ssid = wpa_config_add_network(wpa_s->conf);
    725 	if (ssid == NULL)
    726 		return NULL;
    727 	wpas_notify_network_added(wpa_s, ssid);
    728 	wpa_config_set_network_defaults(ssid);
    729 	ssid->temporary = 1;
    730 	if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
    731 	    wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
    732 	    wpa_config_set(ssid, "identity", registrar ?
    733 			   "\"" WSC_ID_REGISTRAR "\"" :
    734 			   "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
    735 		wpas_notify_network_removed(wpa_s, ssid);
    736 		wpa_config_remove_network(wpa_s->conf, ssid->id);
    737 		return NULL;
    738 	}
    739 
    740 	if (bssid) {
    741 #ifndef CONFIG_P2P
    742 		struct wpa_bss *bss;
    743 		int count = 0;
    744 #endif /* CONFIG_P2P */
    745 
    746 		os_memcpy(ssid->bssid, bssid, ETH_ALEN);
    747 		ssid->bssid_set = 1;
    748 
    749 		/*
    750 		 * Note: With P2P, the SSID may change at the time the WPS
    751 		 * provisioning is started, so better not filter the AP based
    752 		 * on the current SSID in the scan results.
    753 		 */
    754 #ifndef CONFIG_P2P
    755 		dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
    756 			if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
    757 				continue;
    758 
    759 			os_free(ssid->ssid);
    760 			ssid->ssid = os_malloc(bss->ssid_len);
    761 			if (ssid->ssid == NULL)
    762 				break;
    763 			os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
    764 			ssid->ssid_len = bss->ssid_len;
    765 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
    766 					  "scan results",
    767 					  ssid->ssid, ssid->ssid_len);
    768 			count++;
    769 		}
    770 
    771 		if (count > 1) {
    772 			wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
    773 				   "for the AP; use wildcard");
    774 			os_free(ssid->ssid);
    775 			ssid->ssid = NULL;
    776 			ssid->ssid_len = 0;
    777 		}
    778 #endif /* CONFIG_P2P */
    779 	}
    780 
    781 	return ssid;
    782 }
    783 
    784 
    785 static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
    786 			     struct wpa_ssid *selected)
    787 {
    788 	struct wpa_ssid *ssid;
    789 
    790 	/* Mark all other networks disabled and trigger reassociation */
    791 	ssid = wpa_s->conf->ssid;
    792 	while (ssid) {
    793 		int was_disabled = ssid->disabled;
    794 		/*
    795 		 * In case the network object corresponds to a persistent group
    796 		 * then do not send out network disabled signal. In addition,
    797 		 * do not change disabled status of persistent network objects
    798 		 * from 2 to 1 should we connect to another network.
    799 		 */
    800 		if (was_disabled != 2) {
    801 			ssid->disabled = ssid != selected;
    802 			if (was_disabled != ssid->disabled)
    803 				wpas_notify_network_enabled_changed(wpa_s,
    804 								    ssid);
    805 		}
    806 		ssid = ssid->next;
    807 	}
    808 	wpa_s->disconnected = 0;
    809 	wpa_s->reassociate = 1;
    810 	wpa_s->scan_runs = 0;
    811 	wpa_s->wps_success = 0;
    812 	wpa_s->blacklist_cleared = 0;
    813 	wpa_supplicant_req_scan(wpa_s, 0, 0);
    814 }
    815 
    816 
    817 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
    818 		       int p2p_group)
    819 {
    820 	struct wpa_ssid *ssid;
    821 	wpas_clear_wps(wpa_s);
    822 	ssid = wpas_wps_add_network(wpa_s, 0, bssid);
    823 	if (ssid == NULL)
    824 		return -1;
    825 	ssid->temporary = 1;
    826 	ssid->p2p_group = p2p_group;
    827 #ifdef CONFIG_P2P
    828 	if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
    829 		ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
    830 		if (ssid->ssid) {
    831 			ssid->ssid_len = wpa_s->go_params->ssid_len;
    832 			os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
    833 				  ssid->ssid_len);
    834 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
    835 					  "SSID", ssid->ssid, ssid->ssid_len);
    836 		}
    837 	}
    838 #endif /* CONFIG_P2P */
    839 	wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0);
    840 	if (wpa_s->wps_fragment_size)
    841 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
    842 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
    843 			       wpa_s, NULL);
    844 	wpas_wps_reassoc(wpa_s, ssid);
    845 	return 0;
    846 }
    847 
    848 
    849 int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
    850 		       const char *pin, int p2p_group, u16 dev_pw_id)
    851 {
    852 	struct wpa_ssid *ssid;
    853 	char val[128];
    854 	unsigned int rpin = 0;
    855 
    856 	wpas_clear_wps(wpa_s);
    857 	ssid = wpas_wps_add_network(wpa_s, 0, bssid);
    858 	if (ssid == NULL)
    859 		return -1;
    860 	ssid->temporary = 1;
    861 	ssid->p2p_group = p2p_group;
    862 #ifdef CONFIG_P2P
    863 	if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
    864 		ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
    865 		if (ssid->ssid) {
    866 			ssid->ssid_len = wpa_s->go_params->ssid_len;
    867 			os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
    868 				  ssid->ssid_len);
    869 			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
    870 					  "SSID", ssid->ssid, ssid->ssid_len);
    871 		}
    872 	}
    873 #endif /* CONFIG_P2P */
    874 	if (pin)
    875 		os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u\"",
    876 			    pin, dev_pw_id);
    877 	else {
    878 		rpin = wps_generate_pin();
    879 		os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u\"",
    880 			    rpin, dev_pw_id);
    881 	}
    882 	wpa_config_set(ssid, "phase1", val, 0);
    883 	if (wpa_s->wps_fragment_size)
    884 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
    885 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
    886 			       wpa_s, NULL);
    887 	wpas_wps_reassoc(wpa_s, ssid);
    888 	return rpin;
    889 }
    890 
    891 
    892 /* Cancel the wps pbc/pin requests */
    893 int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
    894 {
    895 #ifdef CONFIG_AP
    896 	if (wpa_s->ap_iface) {
    897 		wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
    898 		return wpa_supplicant_ap_wps_cancel(wpa_s);
    899 	}
    900 #endif /* CONFIG_AP */
    901 
    902 	if (wpa_s->wpa_state == WPA_SCANNING) {
    903 		wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
    904 		wpa_supplicant_cancel_scan(wpa_s);
    905 		wpas_clear_wps(wpa_s);
    906 	} else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
    907 		wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
    908 			   "deauthenticate");
    909 		wpa_supplicant_deauthenticate(wpa_s,
    910 					      WLAN_REASON_DEAUTH_LEAVING);
    911 		wpas_clear_wps(wpa_s);
    912 	}
    913 
    914 	return 0;
    915 }
    916 
    917 
    918 #ifdef CONFIG_WPS_OOB
    919 int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
    920 		       char *path, char *method, char *name)
    921 {
    922 	struct wps_context *wps = wpa_s->wps;
    923 	struct oob_device_data *oob_dev;
    924 
    925 	oob_dev = wps_get_oob_device(device_type);
    926 	if (oob_dev == NULL)
    927 		return -1;
    928 	oob_dev->device_path = path;
    929 	oob_dev->device_name = name;
    930 	wps->oob_conf.oob_method = wps_get_oob_method(method);
    931 
    932 	if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) {
    933 		/*
    934 		 * Use pre-configured DH keys in order to be able to write the
    935 		 * key hash into the OOB file.
    936 		 */
    937 		wpabuf_free(wps->dh_pubkey);
    938 		wpabuf_free(wps->dh_privkey);
    939 		wps->dh_privkey = NULL;
    940 		wps->dh_pubkey = NULL;
    941 		dh5_free(wps->dh_ctx);
    942 		wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey);
    943 		wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
    944 		if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) {
    945 			wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
    946 				   "Diffie-Hellman handshake");
    947 			return -1;
    948 		}
    949 	}
    950 
    951 	if (wps->oob_conf.oob_method == OOB_METHOD_CRED)
    952 		wpas_clear_wps(wpa_s);
    953 
    954 	if (wps_process_oob(wps, oob_dev, 0) < 0)
    955 		return -1;
    956 
    957 	if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ||
    958 	     wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) &&
    959 	    wpas_wps_start_pin(wpa_s, NULL,
    960 			       wpabuf_head(wps->oob_conf.dev_password), 0,
    961 			       DEV_PW_DEFAULT) < 0)
    962 			return -1;
    963 
    964 	return 0;
    965 }
    966 #endif /* CONFIG_WPS_OOB */
    967 
    968 
    969 int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
    970 		       const char *pin, struct wps_new_ap_settings *settings)
    971 {
    972 	struct wpa_ssid *ssid;
    973 	char val[200];
    974 	char *pos, *end;
    975 	int res;
    976 
    977 	if (!pin)
    978 		return -1;
    979 	wpas_clear_wps(wpa_s);
    980 	ssid = wpas_wps_add_network(wpa_s, 1, bssid);
    981 	if (ssid == NULL)
    982 		return -1;
    983 	ssid->temporary = 1;
    984 	pos = val;
    985 	end = pos + sizeof(val);
    986 	res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
    987 	if (res < 0 || res >= end - pos)
    988 		return -1;
    989 	pos += res;
    990 	if (settings) {
    991 		res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s "
    992 				  "new_encr=%s new_key=%s",
    993 				  settings->ssid_hex, settings->auth,
    994 				  settings->encr, settings->key_hex);
    995 		if (res < 0 || res >= end - pos)
    996 			return -1;
    997 		pos += res;
    998 	}
    999 	res = os_snprintf(pos, end - pos, "\"");
   1000 	if (res < 0 || res >= end - pos)
   1001 		return -1;
   1002 	wpa_config_set(ssid, "phase1", val, 0);
   1003 	if (wpa_s->wps_fragment_size)
   1004 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
   1005 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
   1006 			       wpa_s, NULL);
   1007 	wpas_wps_reassoc(wpa_s, ssid);
   1008 	return 0;
   1009 }
   1010 
   1011 
   1012 static int wpas_wps_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *psk,
   1013 			       size_t psk_len)
   1014 {
   1015 	wpa_printf(MSG_DEBUG, "WPS: Received new WPA/WPA2-PSK from WPS for "
   1016 		   "STA " MACSTR, MAC2STR(mac_addr));
   1017 	wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
   1018 
   1019 	/* TODO */
   1020 
   1021 	return 0;
   1022 }
   1023 
   1024 
   1025 static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
   1026 				   const struct wps_device_data *dev)
   1027 {
   1028 	char uuid[40], txt[400];
   1029 	int len;
   1030 	char devtype[WPS_DEV_TYPE_BUFSIZE];
   1031 	if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
   1032 		return;
   1033 	wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
   1034 	len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
   1035 			  " [%s|%s|%s|%s|%s|%s]",
   1036 			  uuid, MAC2STR(dev->mac_addr), dev->device_name,
   1037 			  dev->manufacturer, dev->model_name,
   1038 			  dev->model_number, dev->serial_number,
   1039 			  wps_dev_type_bin2str(dev->pri_dev_type, devtype,
   1040 					       sizeof(devtype)));
   1041 	if (len > 0 && len < (int) sizeof(txt))
   1042 		wpa_printf(MSG_INFO, "%s", txt);
   1043 }
   1044 
   1045 
   1046 static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
   1047 				    u16 sel_reg_config_methods)
   1048 {
   1049 #ifdef CONFIG_WPS_ER
   1050 	struct wpa_supplicant *wpa_s = ctx;
   1051 
   1052 	if (wpa_s->wps_er == NULL)
   1053 		return;
   1054 	wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
   1055 		   "dev_password_id=%u sel_reg_config_methods=0x%x",
   1056 		   sel_reg, dev_passwd_id, sel_reg_config_methods);
   1057 	wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
   1058 			   sel_reg_config_methods);
   1059 #endif /* CONFIG_WPS_ER */
   1060 }
   1061 
   1062 
   1063 static u16 wps_fix_config_methods(u16 config_methods)
   1064 {
   1065 #ifdef CONFIG_WPS2
   1066 	if ((config_methods &
   1067 	     (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
   1068 	      WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
   1069 		wpa_printf(MSG_INFO, "WPS: Converting display to "
   1070 			   "virtual_display for WPS 2.0 compliance");
   1071 		config_methods |= WPS_CONFIG_VIRT_DISPLAY;
   1072 	}
   1073 	if ((config_methods &
   1074 	     (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
   1075 	      WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
   1076 		wpa_printf(MSG_INFO, "WPS: Converting push_button to "
   1077 			   "virtual_push_button for WPS 2.0 compliance");
   1078 		config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
   1079 	}
   1080 #endif /* CONFIG_WPS2 */
   1081 
   1082 	return config_methods;
   1083 }
   1084 
   1085 
   1086 static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
   1087 			      struct wps_context *wps)
   1088 {
   1089 	wpa_printf(MSG_DEBUG, "WPS: Set UUID for interface %s", wpa_s->ifname);
   1090 	if (is_nil_uuid(wpa_s->conf->uuid)) {
   1091 		struct wpa_supplicant *first;
   1092 		first = wpa_s->global->ifaces;
   1093 		while (first && first->next)
   1094 			first = first->next;
   1095 		if (first && first != wpa_s) {
   1096 			os_memcpy(wps->uuid, wpa_s->global->ifaces->wps->uuid,
   1097 				  WPS_UUID_LEN);
   1098 			wpa_hexdump(MSG_DEBUG, "WPS: UUID from the first "
   1099 				    "interface", wps->uuid, WPS_UUID_LEN);
   1100 		} else {
   1101 			uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
   1102 			wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC "
   1103 				    "address", wps->uuid, WPS_UUID_LEN);
   1104 		}
   1105 	} else {
   1106 		os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
   1107 		wpa_hexdump(MSG_DEBUG, "WPS: UUID based on configuration",
   1108 			    wps->uuid, WPS_UUID_LEN);
   1109 	}
   1110 }
   1111 
   1112 
   1113 int wpas_wps_init(struct wpa_supplicant *wpa_s)
   1114 {
   1115 	struct wps_context *wps;
   1116 	struct wps_registrar_config rcfg;
   1117 
   1118 	wps = os_zalloc(sizeof(*wps));
   1119 	if (wps == NULL)
   1120 		return -1;
   1121 
   1122 	wps->cred_cb = wpa_supplicant_wps_cred;
   1123 	wps->event_cb = wpa_supplicant_wps_event;
   1124 	wps->cb_ctx = wpa_s;
   1125 
   1126 	wps->dev.device_name = wpa_s->conf->device_name;
   1127 	wps->dev.manufacturer = wpa_s->conf->manufacturer;
   1128 	wps->dev.model_name = wpa_s->conf->model_name;
   1129 	wps->dev.model_number = wpa_s->conf->model_number;
   1130 	wps->dev.serial_number = wpa_s->conf->serial_number;
   1131 	wps->config_methods =
   1132 		wps_config_methods_str2bin(wpa_s->conf->config_methods);
   1133 	if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
   1134 	    (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
   1135 		wpa_printf(MSG_ERROR, "WPS: Both Label and Display config "
   1136 			   "methods are not allowed at the same time");
   1137 		os_free(wps);
   1138 		return -1;
   1139 	}
   1140 	wps->config_methods = wps_fix_config_methods(wps->config_methods);
   1141 	os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
   1142 		  WPS_DEV_TYPE_LEN);
   1143 
   1144 	wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
   1145 	os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
   1146 		  WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
   1147 
   1148 	wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
   1149 	wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */
   1150 	os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
   1151 	wpas_wps_set_uuid(wpa_s, wps);
   1152 
   1153 	wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
   1154 	wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
   1155 
   1156 	os_memset(&rcfg, 0, sizeof(rcfg));
   1157 	rcfg.new_psk_cb = wpas_wps_new_psk_cb;
   1158 	rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
   1159 	rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
   1160 	rcfg.cb_ctx = wpa_s;
   1161 
   1162 	wps->registrar = wps_registrar_init(wps, &rcfg);
   1163 	if (wps->registrar == NULL) {
   1164 		wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
   1165 		os_free(wps);
   1166 		return -1;
   1167 	}
   1168 
   1169 	wpa_s->wps = wps;
   1170 
   1171 	return 0;
   1172 }
   1173 
   1174 
   1175 void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
   1176 {
   1177 	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
   1178 
   1179 	if (wpa_s->wps == NULL)
   1180 		return;
   1181 
   1182 #ifdef CONFIG_WPS_ER
   1183 	wps_er_deinit(wpa_s->wps_er, NULL, NULL);
   1184 	wpa_s->wps_er = NULL;
   1185 #endif /* CONFIG_WPS_ER */
   1186 
   1187 	wps_registrar_deinit(wpa_s->wps->registrar);
   1188 	wpabuf_free(wpa_s->wps->dh_pubkey);
   1189 	wpabuf_free(wpa_s->wps->dh_privkey);
   1190 	wpabuf_free(wpa_s->wps->oob_conf.pubkey_hash);
   1191 	wpabuf_free(wpa_s->wps->oob_conf.dev_password);
   1192 	os_free(wpa_s->wps->network_key);
   1193 	os_free(wpa_s->wps);
   1194 	wpa_s->wps = NULL;
   1195 }
   1196 
   1197 
   1198 int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
   1199 			    struct wpa_ssid *ssid, struct wpa_scan_res *bss)
   1200 {
   1201 	struct wpabuf *wps_ie;
   1202 
   1203 	if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
   1204 		return -1;
   1205 
   1206 	wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1207 	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
   1208 		if (!wps_ie) {
   1209 			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
   1210 			return 0;
   1211 		}
   1212 
   1213 		if (!wps_is_selected_pbc_registrar(wps_ie)) {
   1214 			wpa_printf(MSG_DEBUG, "   skip - WPS AP "
   1215 				   "without active PBC Registrar");
   1216 			wpabuf_free(wps_ie);
   1217 			return 0;
   1218 		}
   1219 
   1220 		/* TODO: overlap detection */
   1221 		wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
   1222 			   "(Active PBC)");
   1223 		wpabuf_free(wps_ie);
   1224 		return 1;
   1225 	}
   1226 
   1227 	if (eap_is_wps_pin_enrollee(&ssid->eap)) {
   1228 		if (!wps_ie) {
   1229 			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
   1230 			return 0;
   1231 		}
   1232 
   1233 		/*
   1234 		 * Start with WPS APs that advertise our address as an
   1235 		 * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
   1236 		 * allow any WPS AP after couple of scans since some APs do not
   1237 		 * set Selected Registrar attribute properly when using
   1238 		 * external Registrar.
   1239 		 */
   1240 		if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
   1241 			if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) {
   1242 				wpa_printf(MSG_DEBUG, "   skip - WPS AP "
   1243 					   "without active PIN Registrar");
   1244 				wpabuf_free(wps_ie);
   1245 				return 0;
   1246 			}
   1247 			wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
   1248 		} else {
   1249 			wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
   1250 				   "(Authorized MAC or Active PIN)");
   1251 		}
   1252 		wpabuf_free(wps_ie);
   1253 		return 1;
   1254 	}
   1255 
   1256 	if (wps_ie) {
   1257 		wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
   1258 		wpabuf_free(wps_ie);
   1259 		return 1;
   1260 	}
   1261 
   1262 	return -1;
   1263 }
   1264 
   1265 
   1266 int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
   1267 			      struct wpa_ssid *ssid,
   1268 			      struct wpa_scan_res *bss)
   1269 {
   1270 	struct wpabuf *wps_ie = NULL;
   1271 	int ret = 0;
   1272 
   1273 	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
   1274 		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1275 		if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
   1276 			/* allow wildcard SSID for WPS PBC */
   1277 			ret = 1;
   1278 		}
   1279 	} else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
   1280 		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1281 		if (wps_ie &&
   1282 		    (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
   1283 		     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
   1284 			/* allow wildcard SSID for WPS PIN */
   1285 			ret = 1;
   1286 		}
   1287 	}
   1288 
   1289 	if (!ret && ssid->bssid_set &&
   1290 	    os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
   1291 		/* allow wildcard SSID due to hardcoded BSSID match */
   1292 		ret = 1;
   1293 	}
   1294 
   1295 #ifdef CONFIG_WPS_STRICT
   1296 	if (wps_ie) {
   1297 		if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
   1298 						   0, bss->bssid) < 0)
   1299 			ret = 0;
   1300 		if (bss->beacon_ie_len) {
   1301 			struct wpabuf *bcn_wps;
   1302 			bcn_wps = wpa_scan_get_vendor_ie_multi_beacon(
   1303 				bss, WPS_IE_VENDOR_TYPE);
   1304 			if (bcn_wps == NULL) {
   1305 				wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
   1306 					   "missing from AP Beacon");
   1307 				ret = 0;
   1308 			} else {
   1309 				if (wps_validate_beacon(wps_ie) < 0)
   1310 					ret = 0;
   1311 				wpabuf_free(bcn_wps);
   1312 			}
   1313 		}
   1314 	}
   1315 #endif /* CONFIG_WPS_STRICT */
   1316 
   1317 	wpabuf_free(wps_ie);
   1318 
   1319 	return ret;
   1320 }
   1321 
   1322 
   1323 int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
   1324 			      struct wpa_bss *selected, struct wpa_ssid *ssid)
   1325 {
   1326 	const u8 *sel_uuid, *uuid;
   1327 	struct wpabuf *wps_ie;
   1328 	int ret = 0;
   1329 	struct wpa_bss *bss;
   1330 
   1331 	if (!eap_is_wps_pbc_enrollee(&ssid->eap))
   1332 		return 0;
   1333 
   1334 	wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
   1335 		   "present in scan results; selected BSSID " MACSTR,
   1336 		   MAC2STR(selected->bssid));
   1337 
   1338 	/* Make sure that only one AP is in active PBC mode */
   1339 	wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
   1340 	if (wps_ie) {
   1341 		sel_uuid = wps_get_uuid_e(wps_ie);
   1342 		wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
   1343 			    sel_uuid, UUID_LEN);
   1344 	} else {
   1345 		wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
   1346 			   "WPS IE?!");
   1347 		sel_uuid = NULL;
   1348 	}
   1349 
   1350 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
   1351 		struct wpabuf *ie;
   1352 		if (bss == selected)
   1353 			continue;
   1354 		ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1355 		if (!ie)
   1356 			continue;
   1357 		if (!wps_is_selected_pbc_registrar(ie)) {
   1358 			wpabuf_free(ie);
   1359 			continue;
   1360 		}
   1361 		wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
   1362 			   MACSTR, MAC2STR(bss->bssid));
   1363 		uuid = wps_get_uuid_e(ie);
   1364 		wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
   1365 			    uuid, UUID_LEN);
   1366 		if (sel_uuid == NULL || uuid == NULL ||
   1367 		    os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) {
   1368 			ret = 1; /* PBC overlap */
   1369 			wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
   1370 				MACSTR " and " MACSTR,
   1371 				MAC2STR(selected->bssid),
   1372 				MAC2STR(bss->bssid));
   1373 			wpabuf_free(ie);
   1374 			break;
   1375 		}
   1376 
   1377 		/* TODO: verify that this is reasonable dual-band situation */
   1378 
   1379 		wpabuf_free(ie);
   1380 	}
   1381 
   1382 	wpabuf_free(wps_ie);
   1383 
   1384 	return ret;
   1385 }
   1386 
   1387 
   1388 void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
   1389 {
   1390 	struct wpa_bss *bss;
   1391 	unsigned int pbc = 0, auth = 0, pin = 0, wps = 0;
   1392 
   1393 	if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
   1394 		return;
   1395 
   1396 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
   1397 		struct wpabuf *ie;
   1398 		ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
   1399 		if (!ie)
   1400 			continue;
   1401 		if (wps_is_selected_pbc_registrar(ie))
   1402 			pbc++;
   1403 		else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
   1404 			auth++;
   1405 		else if (wps_is_selected_pin_registrar(ie))
   1406 			pin++;
   1407 		else
   1408 			wps++;
   1409 		wpabuf_free(ie);
   1410 	}
   1411 
   1412 	if (pbc)
   1413 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
   1414 	else if (auth)
   1415 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH);
   1416 	else if (pin)
   1417 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
   1418 	else if (wps)
   1419 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
   1420 }
   1421 
   1422 
   1423 int wpas_wps_searching(struct wpa_supplicant *wpa_s)
   1424 {
   1425 	struct wpa_ssid *ssid;
   1426 
   1427 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
   1428 		if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
   1429 			return 1;
   1430 	}
   1431 
   1432 	return 0;
   1433 }
   1434 
   1435 
   1436 int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
   1437 			      char *end)
   1438 {
   1439 	struct wpabuf *wps_ie;
   1440 	int ret;
   1441 
   1442 	wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA);
   1443 	if (wps_ie == NULL)
   1444 		return 0;
   1445 
   1446 	ret = wps_attr_text(wps_ie, buf, end);
   1447 	wpabuf_free(wps_ie);
   1448 	return ret;
   1449 }
   1450 
   1451 
   1452 int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
   1453 {
   1454 #ifdef CONFIG_WPS_ER
   1455 	if (wpa_s->wps_er) {
   1456 		wps_er_refresh(wpa_s->wps_er);
   1457 		return 0;
   1458 	}
   1459 	wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
   1460 	if (wpa_s->wps_er == NULL)
   1461 		return -1;
   1462 	return 0;
   1463 #else /* CONFIG_WPS_ER */
   1464 	return 0;
   1465 #endif /* CONFIG_WPS_ER */
   1466 }
   1467 
   1468 
   1469 int wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
   1470 {
   1471 #ifdef CONFIG_WPS_ER
   1472 	wps_er_deinit(wpa_s->wps_er, NULL, NULL);
   1473 	wpa_s->wps_er = NULL;
   1474 #endif /* CONFIG_WPS_ER */
   1475 	return 0;
   1476 }
   1477 
   1478 
   1479 #ifdef CONFIG_WPS_ER
   1480 int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
   1481 			const char *uuid, const char *pin)
   1482 {
   1483 	u8 u[UUID_LEN];
   1484 	int any = 0;
   1485 
   1486 	if (os_strcmp(uuid, "any") == 0)
   1487 		any = 1;
   1488 	else if (uuid_str2bin(uuid, u))
   1489 		return -1;
   1490 	return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
   1491 				     any ? NULL : u,
   1492 				     (const u8 *) pin, os_strlen(pin), 300);
   1493 }
   1494 
   1495 
   1496 int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
   1497 {
   1498 	u8 u[UUID_LEN];
   1499 
   1500 	if (uuid_str2bin(uuid, u))
   1501 		return -1;
   1502 	return wps_er_pbc(wpa_s->wps_er, u);
   1503 }
   1504 
   1505 
   1506 int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
   1507 		      const char *pin)
   1508 {
   1509 	u8 u[UUID_LEN];
   1510 
   1511 	if (uuid_str2bin(uuid, u))
   1512 		return -1;
   1513 	return wps_er_learn(wpa_s->wps_er, u, (const u8 *) pin,
   1514 			    os_strlen(pin));
   1515 }
   1516 
   1517 
   1518 int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
   1519 			   int id)
   1520 {
   1521 	u8 u[UUID_LEN];
   1522 	struct wpa_ssid *ssid;
   1523 	struct wps_credential cred;
   1524 
   1525 	if (uuid_str2bin(uuid, u))
   1526 		return -1;
   1527 	ssid = wpa_config_get_network(wpa_s->conf, id);
   1528 	if (ssid == NULL || ssid->ssid == NULL)
   1529 		return -1;
   1530 
   1531 	os_memset(&cred, 0, sizeof(cred));
   1532 	if (ssid->ssid_len > 32)
   1533 		return -1;
   1534 	os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
   1535 	cred.ssid_len = ssid->ssid_len;
   1536 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
   1537 		cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
   1538 			WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
   1539 		if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
   1540 			cred.encr_type = WPS_ENCR_AES;
   1541 		else
   1542 			cred.encr_type = WPS_ENCR_TKIP;
   1543 		if (ssid->passphrase) {
   1544 			cred.key_len = os_strlen(ssid->passphrase);
   1545 			if (cred.key_len >= 64)
   1546 				return -1;
   1547 			os_memcpy(cred.key, ssid->passphrase, cred.key_len);
   1548 		} else if (ssid->psk_set) {
   1549 			cred.key_len = 32;
   1550 			os_memcpy(cred.key, ssid->psk, 32);
   1551 		} else
   1552 			return -1;
   1553 	} else {
   1554 		cred.auth_type = WPS_AUTH_OPEN;
   1555 		cred.encr_type = WPS_ENCR_NONE;
   1556 	}
   1557 	return wps_er_set_config(wpa_s->wps_er, u, &cred);
   1558 }
   1559 
   1560 
   1561 int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
   1562 		       const char *pin, struct wps_new_ap_settings *settings)
   1563 {
   1564 	u8 u[UUID_LEN];
   1565 	struct wps_credential cred;
   1566 	size_t len;
   1567 
   1568 	if (uuid_str2bin(uuid, u))
   1569 		return -1;
   1570 	if (settings->ssid_hex == NULL || settings->auth == NULL ||
   1571 	    settings->encr == NULL || settings->key_hex == NULL)
   1572 		return -1;
   1573 
   1574 	os_memset(&cred, 0, sizeof(cred));
   1575 	len = os_strlen(settings->ssid_hex);
   1576 	if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
   1577 	    hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
   1578 		return -1;
   1579 	cred.ssid_len = len / 2;
   1580 
   1581 	len = os_strlen(settings->key_hex);
   1582 	if ((len & 1) || len > 2 * sizeof(cred.key) ||
   1583 	    hexstr2bin(settings->key_hex, cred.key, len / 2))
   1584 		return -1;
   1585 	cred.key_len = len / 2;
   1586 
   1587 	if (os_strcmp(settings->auth, "OPEN") == 0)
   1588 		cred.auth_type = WPS_AUTH_OPEN;
   1589 	else if (os_strcmp(settings->auth, "WPAPSK") == 0)
   1590 		cred.auth_type = WPS_AUTH_WPAPSK;
   1591 	else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
   1592 		cred.auth_type = WPS_AUTH_WPA2PSK;
   1593 	else
   1594 		return -1;
   1595 
   1596 	if (os_strcmp(settings->encr, "NONE") == 0)
   1597 		cred.encr_type = WPS_ENCR_NONE;
   1598 	else if (os_strcmp(settings->encr, "WEP") == 0)
   1599 		cred.encr_type = WPS_ENCR_WEP;
   1600 	else if (os_strcmp(settings->encr, "TKIP") == 0)
   1601 		cred.encr_type = WPS_ENCR_TKIP;
   1602 	else if (os_strcmp(settings->encr, "CCMP") == 0)
   1603 		cred.encr_type = WPS_ENCR_AES;
   1604 	else
   1605 		return -1;
   1606 
   1607 	return wps_er_config(wpa_s->wps_er, u, (const u8 *) pin,
   1608 			     os_strlen(pin), &cred);
   1609 }
   1610 
   1611 
   1612 static int callbacks_pending = 0;
   1613 
   1614 static void wpas_wps_terminate_cb(void *ctx)
   1615 {
   1616 	wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
   1617 	if (--callbacks_pending <= 0)
   1618 		eloop_terminate();
   1619 }
   1620 #endif /* CONFIG_WPS_ER */
   1621 
   1622 
   1623 int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
   1624 {
   1625 #ifdef CONFIG_WPS_ER
   1626 	if (wpa_s->wps_er) {
   1627 		callbacks_pending++;
   1628 		wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
   1629 		wpa_s->wps_er = NULL;
   1630 		return 1;
   1631 	}
   1632 #endif /* CONFIG_WPS_ER */
   1633 	return 0;
   1634 }
   1635 
   1636 
   1637 int wpas_wps_in_progress(struct wpa_supplicant *wpa_s)
   1638 {
   1639 	struct wpa_ssid *ssid;
   1640 
   1641 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
   1642 		if (!ssid->disabled && ssid->key_mgmt == WPA_KEY_MGMT_WPS)
   1643 			return 1;
   1644 	}
   1645 
   1646 	return 0;
   1647 }
   1648 
   1649 
   1650 void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
   1651 {
   1652 	struct wps_context *wps = wpa_s->wps;
   1653 
   1654 	if (wps == NULL)
   1655 		return;
   1656 
   1657 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
   1658 		wps->config_methods = wps_config_methods_str2bin(
   1659 			wpa_s->conf->config_methods);
   1660 		if ((wps->config_methods &
   1661 		     (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
   1662 		    (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
   1663 			wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
   1664 				   "config methods are not allowed at the "
   1665 				   "same time");
   1666 			wps->config_methods &= ~WPS_CONFIG_LABEL;
   1667 		}
   1668 	}
   1669 	wps->config_methods = wps_fix_config_methods(wps->config_methods);
   1670 
   1671 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
   1672 		os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
   1673 			  WPS_DEV_TYPE_LEN);
   1674 
   1675 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
   1676 		wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
   1677 		os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
   1678 			  wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
   1679 	}
   1680 
   1681 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
   1682 		wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
   1683 
   1684 	if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
   1685 		wpas_wps_set_uuid(wpa_s, wps);
   1686 
   1687 	if (wpa_s->conf->changed_parameters &
   1688 	    (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
   1689 		/* Update pointers to make sure they refer current values */
   1690 		wps->dev.device_name = wpa_s->conf->device_name;
   1691 		wps->dev.manufacturer = wpa_s->conf->manufacturer;
   1692 		wps->dev.model_name = wpa_s->conf->model_name;
   1693 		wps->dev.model_number = wpa_s->conf->model_number;
   1694 		wps->dev.serial_number = wpa_s->conf->serial_number;
   1695 	}
   1696 }
   1697