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