1/* 2 * hostapd / WPS integration 3 * Copyright (c) 2008-2012, Jouni Malinen <j@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 "utils/includes.h" 10 11#include "utils/common.h" 12#include "utils/eloop.h" 13#include "utils/uuid.h" 14#include "common/wpa_ctrl.h" 15#include "common/ieee802_11_defs.h" 16#include "common/ieee802_11_common.h" 17#include "eapol_auth/eapol_auth_sm.h" 18#include "eapol_auth/eapol_auth_sm_i.h" 19#include "wps/wps.h" 20#include "wps/wps_defs.h" 21#include "wps/wps_dev_attr.h" 22#include "wps/wps_attr_parse.h" 23#include "hostapd.h" 24#include "ap_config.h" 25#include "ap_drv_ops.h" 26#include "beacon.h" 27#include "sta_info.h" 28#include "wps_hostapd.h" 29 30 31#ifdef CONFIG_WPS_UPNP 32#include "wps/wps_upnp.h" 33static int hostapd_wps_upnp_init(struct hostapd_data *hapd, 34 struct wps_context *wps); 35static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd); 36#endif /* CONFIG_WPS_UPNP */ 37 38static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da, 39 const u8 *bssid, 40 const u8 *ie, size_t ie_len, 41 int ssi_signal); 42static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx); 43 44 45struct wps_for_each_data { 46 int (*func)(struct hostapd_data *h, void *ctx); 47 void *ctx; 48 struct hostapd_data *calling_hapd; 49}; 50 51 52static int wps_for_each(struct hostapd_iface *iface, void *ctx) 53{ 54 struct wps_for_each_data *data = ctx; 55 size_t j; 56 57 if (iface == NULL) 58 return 0; 59 for (j = 0; j < iface->num_bss; j++) { 60 struct hostapd_data *hapd = iface->bss[j]; 61 int ret; 62 63 if (hapd != data->calling_hapd && 64 (hapd->conf->wps_independent || 65 data->calling_hapd->conf->wps_independent)) 66 continue; 67 68 ret = data->func(hapd, data->ctx); 69 if (ret) 70 return ret; 71 } 72 73 return 0; 74} 75 76 77static int hostapd_wps_for_each(struct hostapd_data *hapd, 78 int (*func)(struct hostapd_data *h, void *ctx), 79 void *ctx) 80{ 81 struct hostapd_iface *iface = hapd->iface; 82 struct wps_for_each_data data; 83 data.func = func; 84 data.ctx = ctx; 85 data.calling_hapd = hapd; 86 if (iface->interfaces == NULL || 87 iface->interfaces->for_each_interface == NULL) 88 return wps_for_each(iface, &data); 89 return iface->interfaces->for_each_interface(iface->interfaces, 90 wps_for_each, &data); 91} 92 93 94static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr, 95 const u8 *p2p_dev_addr, const u8 *psk, 96 size_t psk_len) 97{ 98 struct hostapd_data *hapd = ctx; 99 struct hostapd_wpa_psk *p; 100 struct hostapd_ssid *ssid = &hapd->conf->ssid; 101 102 if (is_zero_ether_addr(p2p_dev_addr)) { 103 wpa_printf(MSG_DEBUG, 104 "Received new WPA/WPA2-PSK from WPS for STA " MACSTR, 105 MAC2STR(mac_addr)); 106 } else { 107 wpa_printf(MSG_DEBUG, 108 "Received new WPA/WPA2-PSK from WPS for STA " MACSTR 109 " P2P Device Addr " MACSTR, 110 MAC2STR(mac_addr), MAC2STR(p2p_dev_addr)); 111 } 112 wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len); 113 114 if (psk_len != PMK_LEN) { 115 wpa_printf(MSG_DEBUG, "Unexpected PSK length %lu", 116 (unsigned long) psk_len); 117 return -1; 118 } 119 120 /* Add the new PSK to runtime PSK list */ 121 p = os_zalloc(sizeof(*p)); 122 if (p == NULL) 123 return -1; 124 os_memcpy(p->addr, mac_addr, ETH_ALEN); 125 os_memcpy(p->p2p_dev_addr, p2p_dev_addr, ETH_ALEN); 126 os_memcpy(p->psk, psk, PMK_LEN); 127 128 if (hapd->new_psk_cb) { 129 hapd->new_psk_cb(hapd->new_psk_cb_ctx, mac_addr, p2p_dev_addr, 130 psk, psk_len); 131 } 132 133 p->next = ssid->wpa_psk; 134 ssid->wpa_psk = p; 135 136 if (ssid->wpa_psk_file) { 137 FILE *f; 138 char hex[PMK_LEN * 2 + 1]; 139 /* Add the new PSK to PSK list file */ 140 f = fopen(ssid->wpa_psk_file, "a"); 141 if (f == NULL) { 142 wpa_printf(MSG_DEBUG, "Failed to add the PSK to " 143 "'%s'", ssid->wpa_psk_file); 144 return -1; 145 } 146 147 wpa_snprintf_hex(hex, sizeof(hex), psk, psk_len); 148 fprintf(f, MACSTR " %s\n", MAC2STR(mac_addr), hex); 149 fclose(f); 150 } 151 152 return 0; 153} 154 155 156static int hostapd_wps_set_ie_cb(void *ctx, struct wpabuf *beacon_ie, 157 struct wpabuf *probe_resp_ie) 158{ 159 struct hostapd_data *hapd = ctx; 160 wpabuf_free(hapd->wps_beacon_ie); 161 hapd->wps_beacon_ie = beacon_ie; 162 wpabuf_free(hapd->wps_probe_resp_ie); 163 hapd->wps_probe_resp_ie = probe_resp_ie; 164 if (hapd->beacon_set_done) 165 ieee802_11_set_beacon(hapd); 166 return hostapd_set_ap_wps_ie(hapd); 167} 168 169 170static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e, 171 const struct wps_device_data *dev) 172{ 173 struct hostapd_data *hapd = ctx; 174 char uuid[40], txt[400]; 175 int len; 176 char devtype[WPS_DEV_TYPE_BUFSIZE]; 177 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) 178 return; 179 wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid); 180 len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED 181 "%s " MACSTR " [%s|%s|%s|%s|%s|%s]", 182 uuid, MAC2STR(dev->mac_addr), dev->device_name, 183 dev->manufacturer, dev->model_name, 184 dev->model_number, dev->serial_number, 185 wps_dev_type_bin2str(dev->pri_dev_type, devtype, 186 sizeof(devtype))); 187 if (len > 0 && len < (int) sizeof(txt)) 188 wpa_msg(hapd->msg_ctx, MSG_INFO, "%s", txt); 189 190 if (hapd->conf->wps_pin_requests) { 191 FILE *f; 192 struct os_time t; 193 f = fopen(hapd->conf->wps_pin_requests, "a"); 194 if (f == NULL) 195 return; 196 os_get_time(&t); 197 fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s" 198 "\t%s\n", 199 t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name, 200 dev->manufacturer, dev->model_name, dev->model_number, 201 dev->serial_number, 202 wps_dev_type_bin2str(dev->pri_dev_type, devtype, 203 sizeof(devtype))); 204 fclose(f); 205 } 206} 207 208 209struct wps_stop_reg_data { 210 struct hostapd_data *current_hapd; 211 const u8 *uuid_e; 212 const u8 *dev_pw; 213 size_t dev_pw_len; 214}; 215 216static int wps_stop_registrar(struct hostapd_data *hapd, void *ctx) 217{ 218 struct wps_stop_reg_data *data = ctx; 219 if (hapd != data->current_hapd && hapd->wps != NULL) 220 wps_registrar_complete(hapd->wps->registrar, data->uuid_e, 221 data->dev_pw, data->dev_pw_len); 222 return 0; 223} 224 225 226static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr, 227 const u8 *uuid_e, const u8 *dev_pw, 228 size_t dev_pw_len) 229{ 230 struct hostapd_data *hapd = ctx; 231 char uuid[40]; 232 struct wps_stop_reg_data data; 233 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) 234 return; 235 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s", 236 MAC2STR(mac_addr), uuid); 237 if (hapd->wps_reg_success_cb) 238 hapd->wps_reg_success_cb(hapd->wps_reg_success_cb_ctx, 239 mac_addr, uuid_e); 240 data.current_hapd = hapd; 241 data.uuid_e = uuid_e; 242 data.dev_pw = dev_pw; 243 data.dev_pw_len = dev_pw_len; 244 hostapd_wps_for_each(hapd, wps_stop_registrar, &data); 245} 246 247 248static void hostapd_wps_enrollee_seen_cb(void *ctx, const u8 *addr, 249 const u8 *uuid_e, 250 const u8 *pri_dev_type, 251 u16 config_methods, 252 u16 dev_password_id, u8 request_type, 253 const char *dev_name) 254{ 255 struct hostapd_data *hapd = ctx; 256 char uuid[40]; 257 char devtype[WPS_DEV_TYPE_BUFSIZE]; 258 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid))) 259 return; 260 if (dev_name == NULL) 261 dev_name = ""; 262 wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ENROLLEE_SEEN MACSTR 263 " %s %s 0x%x %u %u [%s]", 264 MAC2STR(addr), uuid, 265 wps_dev_type_bin2str(pri_dev_type, devtype, 266 sizeof(devtype)), 267 config_methods, dev_password_id, request_type, dev_name); 268} 269 270 271static int str_starts(const char *str, const char *start) 272{ 273 return os_strncmp(str, start, os_strlen(start)) == 0; 274} 275 276 277static void wps_reload_config(void *eloop_data, void *user_ctx) 278{ 279 struct hostapd_iface *iface = eloop_data; 280 281 wpa_printf(MSG_DEBUG, "WPS: Reload configuration data"); 282 if (iface->interfaces == NULL || 283 iface->interfaces->reload_config(iface) < 0) { 284 wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated " 285 "configuration"); 286 } 287} 288 289 290static void hapd_new_ap_event(struct hostapd_data *hapd, const u8 *attr, 291 size_t attr_len) 292{ 293 size_t blen = attr_len * 2 + 1; 294 char *buf = os_malloc(blen); 295 if (buf) { 296 wpa_snprintf_hex(buf, blen, attr, attr_len); 297 wpa_msg(hapd->msg_ctx, MSG_INFO, 298 WPS_EVENT_NEW_AP_SETTINGS "%s", buf); 299 os_free(buf); 300 } 301} 302 303 304static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd, 305 const struct wps_credential *cred) 306{ 307 struct hostapd_bss_config *bss = hapd->conf; 308 309 wpa_printf(MSG_DEBUG, "WPS: Updating in-memory configuration"); 310 311 bss->wps_state = 2; 312 if (cred->ssid_len <= HOSTAPD_MAX_SSID_LEN) { 313 os_memcpy(bss->ssid.ssid, cred->ssid, cred->ssid_len); 314 bss->ssid.ssid_len = cred->ssid_len; 315 bss->ssid.ssid_set = 1; 316 } 317 318 if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) && 319 (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))) 320 bss->wpa = 3; 321 else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) 322 bss->wpa = 2; 323 else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)) 324 bss->wpa = 1; 325 else 326 bss->wpa = 0; 327 328 if (bss->wpa) { 329 if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) 330 bss->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X; 331 if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) 332 bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK; 333 334 bss->wpa_pairwise = 0; 335 if (cred->encr_type & WPS_ENCR_AES) 336 bss->wpa_pairwise |= WPA_CIPHER_CCMP; 337 if (cred->encr_type & WPS_ENCR_TKIP) 338 bss->wpa_pairwise |= WPA_CIPHER_TKIP; 339 bss->rsn_pairwise = bss->wpa_pairwise; 340 bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, 341 bss->wpa_pairwise, 342 bss->rsn_pairwise); 343 344 if (cred->key_len >= 8 && cred->key_len < 64) { 345 os_free(bss->ssid.wpa_passphrase); 346 bss->ssid.wpa_passphrase = os_zalloc(cred->key_len + 1); 347 if (bss->ssid.wpa_passphrase) 348 os_memcpy(bss->ssid.wpa_passphrase, cred->key, 349 cred->key_len); 350 os_free(bss->ssid.wpa_psk); 351 bss->ssid.wpa_psk = NULL; 352 } else if (cred->key_len == 64) { 353 os_free(bss->ssid.wpa_psk); 354 bss->ssid.wpa_psk = 355 os_zalloc(sizeof(struct hostapd_wpa_psk)); 356 if (bss->ssid.wpa_psk && 357 hexstr2bin((const char *) cred->key, 358 bss->ssid.wpa_psk->psk, PMK_LEN) == 0) { 359 bss->ssid.wpa_psk->group = 1; 360 os_free(bss->ssid.wpa_passphrase); 361 bss->ssid.wpa_passphrase = NULL; 362 } 363 } 364 bss->auth_algs = 1; 365 } else { 366 if ((cred->auth_type & WPS_AUTH_OPEN) && 367 (cred->auth_type & WPS_AUTH_SHARED)) 368 bss->auth_algs = 3; 369 else if (cred->auth_type & WPS_AUTH_SHARED) 370 bss->auth_algs = 2; 371 else 372 bss->auth_algs = 1; 373 if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx > 0 && 374 cred->key_idx <= 4) { 375 struct hostapd_wep_keys *wep = &bss->ssid.wep; 376 int idx = cred->key_idx; 377 if (idx) 378 idx--; 379 wep->idx = idx; 380 if (cred->key_len == 10 || cred->key_len == 26) { 381 os_free(wep->key[idx]); 382 wep->key[idx] = os_malloc(cred->key_len / 2); 383 if (wep->key[idx] == NULL || 384 hexstr2bin((const char *) cred->key, 385 wep->key[idx], 386 cred->key_len / 2)) 387 return -1; 388 wep->len[idx] = cred->key_len / 2; 389 } else { 390 os_free(wep->key[idx]); 391 wep->key[idx] = os_malloc(cred->key_len); 392 if (wep->key[idx] == NULL) 393 return -1; 394 os_memcpy(wep->key[idx], cred->key, 395 cred->key_len); 396 wep->len[idx] = cred->key_len; 397 } 398 wep->keys_set = 1; 399 } 400 } 401 402 /* Schedule configuration reload after short period of time to allow 403 * EAP-WSC to be finished. 404 */ 405 eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface, 406 NULL); 407 408 return 0; 409} 410 411 412static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx) 413{ 414 const struct wps_credential *cred = ctx; 415 FILE *oconf, *nconf; 416 size_t len, i; 417 char *tmp_fname; 418 char buf[1024]; 419 int multi_bss; 420 int wpa; 421 422 if (hapd->wps == NULL) 423 return 0; 424 425 wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", 426 cred->cred_attr, cred->cred_attr_len); 427 428 wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings"); 429 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len); 430 wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x", 431 cred->auth_type); 432 wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type); 433 wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx); 434 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", 435 cred->key, cred->key_len); 436 wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, 437 MAC2STR(cred->mac_addr)); 438 439 if ((hapd->conf->wps_cred_processing == 1 || 440 hapd->conf->wps_cred_processing == 2) && cred->cred_attr) { 441 hapd_new_ap_event(hapd, cred->cred_attr, cred->cred_attr_len); 442 } else if (hapd->conf->wps_cred_processing == 1 || 443 hapd->conf->wps_cred_processing == 2) { 444 struct wpabuf *attr; 445 attr = wpabuf_alloc(200); 446 if (attr && wps_build_credential_wrap(attr, cred) == 0) 447 hapd_new_ap_event(hapd, wpabuf_head_u8(attr), 448 wpabuf_len(attr)); 449 wpabuf_free(attr); 450 } else 451 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS); 452 453 if (hapd->conf->wps_cred_processing == 1) 454 return 0; 455 456 os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len); 457 hapd->wps->ssid_len = cred->ssid_len; 458 hapd->wps->encr_types = cred->encr_type; 459 hapd->wps->auth_types = cred->auth_type; 460 if (cred->key_len == 0) { 461 os_free(hapd->wps->network_key); 462 hapd->wps->network_key = NULL; 463 hapd->wps->network_key_len = 0; 464 } else { 465 if (hapd->wps->network_key == NULL || 466 hapd->wps->network_key_len < cred->key_len) { 467 hapd->wps->network_key_len = 0; 468 os_free(hapd->wps->network_key); 469 hapd->wps->network_key = os_malloc(cred->key_len); 470 if (hapd->wps->network_key == NULL) 471 return -1; 472 } 473 hapd->wps->network_key_len = cred->key_len; 474 os_memcpy(hapd->wps->network_key, cred->key, cred->key_len); 475 } 476 hapd->wps->wps_state = WPS_STATE_CONFIGURED; 477 478 if (hapd->iface->config_fname == NULL) 479 return hapd_wps_reconfig_in_memory(hapd, cred); 480 len = os_strlen(hapd->iface->config_fname) + 5; 481 tmp_fname = os_malloc(len); 482 if (tmp_fname == NULL) 483 return -1; 484 os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname); 485 486 oconf = fopen(hapd->iface->config_fname, "r"); 487 if (oconf == NULL) { 488 wpa_printf(MSG_WARNING, "WPS: Could not open current " 489 "configuration file"); 490 os_free(tmp_fname); 491 return -1; 492 } 493 494 nconf = fopen(tmp_fname, "w"); 495 if (nconf == NULL) { 496 wpa_printf(MSG_WARNING, "WPS: Could not write updated " 497 "configuration file"); 498 os_free(tmp_fname); 499 fclose(oconf); 500 return -1; 501 } 502 503 fprintf(nconf, "# WPS configuration - START\n"); 504 505 fprintf(nconf, "wps_state=2\n"); 506 507 if (is_hex(cred->ssid, cred->ssid_len)) { 508 fprintf(nconf, "ssid2="); 509 for (i = 0; i < cred->ssid_len; i++) 510 fprintf(nconf, "%02x", cred->ssid[i]); 511 fprintf(nconf, "\n"); 512 } else { 513 fprintf(nconf, "ssid="); 514 for (i = 0; i < cred->ssid_len; i++) 515 fputc(cred->ssid[i], nconf); 516 fprintf(nconf, "\n"); 517 } 518 519 if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) && 520 (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))) 521 wpa = 3; 522 else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) 523 wpa = 2; 524 else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)) 525 wpa = 1; 526 else 527 wpa = 0; 528 529 if (wpa) { 530 char *prefix; 531 fprintf(nconf, "wpa=%d\n", wpa); 532 533 fprintf(nconf, "wpa_key_mgmt="); 534 prefix = ""; 535 if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) { 536 fprintf(nconf, "WPA-EAP"); 537 prefix = " "; 538 } 539 if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) 540 fprintf(nconf, "%sWPA-PSK", prefix); 541 fprintf(nconf, "\n"); 542 543 fprintf(nconf, "wpa_pairwise="); 544 prefix = ""; 545 if (cred->encr_type & WPS_ENCR_AES) { 546 fprintf(nconf, "CCMP"); 547 prefix = " "; 548 } 549 if (cred->encr_type & WPS_ENCR_TKIP) { 550 fprintf(nconf, "%sTKIP", prefix); 551 } 552 fprintf(nconf, "\n"); 553 554 if (cred->key_len >= 8 && cred->key_len < 64) { 555 fprintf(nconf, "wpa_passphrase="); 556 for (i = 0; i < cred->key_len; i++) 557 fputc(cred->key[i], nconf); 558 fprintf(nconf, "\n"); 559 } else if (cred->key_len == 64) { 560 fprintf(nconf, "wpa_psk="); 561 for (i = 0; i < cred->key_len; i++) 562 fputc(cred->key[i], nconf); 563 fprintf(nconf, "\n"); 564 } else { 565 wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu " 566 "for WPA/WPA2", 567 (unsigned long) cred->key_len); 568 } 569 570 fprintf(nconf, "auth_algs=1\n"); 571 } else { 572 if ((cred->auth_type & WPS_AUTH_OPEN) && 573 (cred->auth_type & WPS_AUTH_SHARED)) 574 fprintf(nconf, "auth_algs=3\n"); 575 else if (cred->auth_type & WPS_AUTH_SHARED) 576 fprintf(nconf, "auth_algs=2\n"); 577 else 578 fprintf(nconf, "auth_algs=1\n"); 579 580 if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) { 581 int key_idx = cred->key_idx; 582 if (key_idx) 583 key_idx--; 584 fprintf(nconf, "wep_default_key=%d\n", key_idx); 585 fprintf(nconf, "wep_key%d=", key_idx); 586 if (cred->key_len == 10 || cred->key_len == 26) { 587 /* WEP key as a hex string */ 588 for (i = 0; i < cred->key_len; i++) 589 fputc(cred->key[i], nconf); 590 } else { 591 /* Raw WEP key; convert to hex */ 592 for (i = 0; i < cred->key_len; i++) 593 fprintf(nconf, "%02x", cred->key[i]); 594 } 595 fprintf(nconf, "\n"); 596 } 597 } 598 599 fprintf(nconf, "# WPS configuration - END\n"); 600 601 multi_bss = 0; 602 while (fgets(buf, sizeof(buf), oconf)) { 603 if (os_strncmp(buf, "bss=", 4) == 0) 604 multi_bss = 1; 605 if (!multi_bss && 606 (str_starts(buf, "ssid=") || 607 str_starts(buf, "ssid2=") || 608 str_starts(buf, "auth_algs=") || 609 str_starts(buf, "wep_default_key=") || 610 str_starts(buf, "wep_key") || 611 str_starts(buf, "wps_state=") || 612 str_starts(buf, "wpa=") || 613 str_starts(buf, "wpa_psk=") || 614 str_starts(buf, "wpa_pairwise=") || 615 str_starts(buf, "rsn_pairwise=") || 616 str_starts(buf, "wpa_key_mgmt=") || 617 str_starts(buf, "wpa_passphrase="))) { 618 fprintf(nconf, "#WPS# %s", buf); 619 } else 620 fprintf(nconf, "%s", buf); 621 } 622 623 fclose(nconf); 624 fclose(oconf); 625 626 if (rename(tmp_fname, hapd->iface->config_fname) < 0) { 627 wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated " 628 "configuration file: %s", strerror(errno)); 629 os_free(tmp_fname); 630 return -1; 631 } 632 633 os_free(tmp_fname); 634 635 /* Schedule configuration reload after short period of time to allow 636 * EAP-WSC to be finished. 637 */ 638 eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface, 639 NULL); 640 641 wpa_printf(MSG_DEBUG, "WPS: AP configuration updated"); 642 643 return 0; 644} 645 646 647static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred) 648{ 649 struct hostapd_data *hapd = ctx; 650 return hostapd_wps_for_each(hapd, hapd_wps_cred_cb, (void *) cred); 651} 652 653 654static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx) 655{ 656 struct hostapd_data *hapd = eloop_data; 657 658 if (hapd->conf->ap_setup_locked) 659 return; 660 if (hapd->ap_pin_failures_consecutive >= 10) 661 return; 662 663 wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN"); 664 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED); 665 hapd->wps->ap_setup_locked = 0; 666 wps_registrar_update_ie(hapd->wps->registrar); 667} 668 669 670static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx) 671{ 672 struct wps_event_pwd_auth_fail *data = ctx; 673 674 if (!data->enrollee || hapd->conf->ap_pin == NULL || hapd->wps == NULL) 675 return 0; 676 677 /* 678 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup 679 * for some time if this happens multiple times to slow down brute 680 * force attacks. 681 */ 682 hapd->ap_pin_failures++; 683 hapd->ap_pin_failures_consecutive++; 684 wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u " 685 "(%u consecutive)", 686 hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive); 687 if (hapd->ap_pin_failures < 3) 688 return 0; 689 690 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED); 691 hapd->wps->ap_setup_locked = 1; 692 693 wps_registrar_update_ie(hapd->wps->registrar); 694 695 if (!hapd->conf->ap_setup_locked && 696 hapd->ap_pin_failures_consecutive >= 10) { 697 /* 698 * In indefinite lockdown - disable automatic AP PIN 699 * reenablement. 700 */ 701 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL); 702 wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely"); 703 } else if (!hapd->conf->ap_setup_locked) { 704 if (hapd->ap_pin_lockout_time == 0) 705 hapd->ap_pin_lockout_time = 60; 706 else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 && 707 (hapd->ap_pin_failures % 3) == 0) 708 hapd->ap_pin_lockout_time *= 2; 709 710 wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN for %u seconds", 711 hapd->ap_pin_lockout_time); 712 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL); 713 eloop_register_timeout(hapd->ap_pin_lockout_time, 0, 714 hostapd_wps_reenable_ap_pin, hapd, 715 NULL); 716 } 717 718 return 0; 719} 720 721 722static void hostapd_pwd_auth_fail(struct hostapd_data *hapd, 723 struct wps_event_pwd_auth_fail *data) 724{ 725 /* Update WPS Status - Authentication Failure */ 726 wpa_printf(MSG_DEBUG, "WPS: Authentication failure update"); 727 hapd->wps_stats.status = WPS_STATUS_FAILURE; 728 hapd->wps_stats.failure_reason = WPS_EI_AUTH_FAILURE; 729 os_memcpy(hapd->wps_stats.peer_addr, data->peer_macaddr, ETH_ALEN); 730 731 hostapd_wps_for_each(hapd, wps_pwd_auth_fail, data); 732} 733 734 735static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx) 736{ 737 if (hapd->conf->ap_pin == NULL || hapd->wps == NULL) 738 return 0; 739 740 if (hapd->ap_pin_failures_consecutive == 0) 741 return 0; 742 743 wpa_printf(MSG_DEBUG, "WPS: Clear consecutive AP PIN failure counter " 744 "- total validation failures %u (%u consecutive)", 745 hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive); 746 hapd->ap_pin_failures_consecutive = 0; 747 748 return 0; 749} 750 751 752static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd) 753{ 754 hostapd_wps_for_each(hapd, wps_ap_pin_success, NULL); 755} 756 757 758static void hostapd_wps_event_pbc_overlap(struct hostapd_data *hapd) 759{ 760 /* Update WPS Status - PBC Overlap */ 761 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_OVERLAP; 762} 763 764 765static void hostapd_wps_event_pbc_timeout(struct hostapd_data *hapd) 766{ 767 /* Update WPS PBC Status:PBC Timeout */ 768 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_TIMEOUT; 769} 770 771 772static void hostapd_wps_event_pbc_active(struct hostapd_data *hapd) 773{ 774 /* Update WPS PBC status - Active */ 775 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_ACTIVE; 776} 777 778 779static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd) 780{ 781 /* Update WPS PBC status - Active */ 782 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE; 783} 784 785 786static void hostapd_wps_event_success(struct hostapd_data *hapd, 787 struct wps_event_success *success) 788{ 789 /* Update WPS status - Success */ 790 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE; 791 hapd->wps_stats.status = WPS_STATUS_SUCCESS; 792 os_memcpy(hapd->wps_stats.peer_addr, success->peer_macaddr, ETH_ALEN); 793} 794 795 796static void hostapd_wps_event_fail(struct hostapd_data *hapd, 797 struct wps_event_fail *fail) 798{ 799 /* Update WPS status - Failure */ 800 hapd->wps_stats.status = WPS_STATUS_FAILURE; 801 os_memcpy(hapd->wps_stats.peer_addr, fail->peer_macaddr, ETH_ALEN); 802 803 hapd->wps_stats.failure_reason = fail->error_indication; 804 805 if (fail->error_indication > 0 && 806 fail->error_indication < NUM_WPS_EI_VALUES) { 807 wpa_msg(hapd->msg_ctx, MSG_INFO, 808 WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)", 809 fail->msg, fail->config_error, fail->error_indication, 810 wps_ei_str(fail->error_indication)); 811 } else { 812 wpa_msg(hapd->msg_ctx, MSG_INFO, 813 WPS_EVENT_FAIL "msg=%d config_error=%d", 814 fail->msg, fail->config_error); 815 } 816} 817 818 819static void hostapd_wps_event_cb(void *ctx, enum wps_event event, 820 union wps_event_data *data) 821{ 822 struct hostapd_data *hapd = ctx; 823 824 switch (event) { 825 case WPS_EV_M2D: 826 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_M2D); 827 break; 828 case WPS_EV_FAIL: 829 hostapd_wps_event_fail(hapd, &data->fail); 830 break; 831 case WPS_EV_SUCCESS: 832 hostapd_wps_event_success(hapd, &data->success); 833 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_SUCCESS); 834 break; 835 case WPS_EV_PWD_AUTH_FAIL: 836 hostapd_pwd_auth_fail(hapd, &data->pwd_auth_fail); 837 break; 838 case WPS_EV_PBC_OVERLAP: 839 hostapd_wps_event_pbc_overlap(hapd); 840 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP); 841 break; 842 case WPS_EV_PBC_TIMEOUT: 843 hostapd_wps_event_pbc_timeout(hapd); 844 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_TIMEOUT); 845 break; 846 case WPS_EV_PBC_ACTIVE: 847 hostapd_wps_event_pbc_active(hapd); 848 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ACTIVE); 849 break; 850 case WPS_EV_PBC_DISABLE: 851 hostapd_wps_event_pbc_disable(hapd); 852 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_DISABLE); 853 break; 854 case WPS_EV_ER_AP_ADD: 855 break; 856 case WPS_EV_ER_AP_REMOVE: 857 break; 858 case WPS_EV_ER_ENROLLEE_ADD: 859 break; 860 case WPS_EV_ER_ENROLLEE_REMOVE: 861 break; 862 case WPS_EV_ER_AP_SETTINGS: 863 break; 864 case WPS_EV_ER_SET_SELECTED_REGISTRAR: 865 break; 866 case WPS_EV_AP_PIN_SUCCESS: 867 hostapd_wps_ap_pin_success(hapd); 868 break; 869 } 870 if (hapd->wps_event_cb) 871 hapd->wps_event_cb(hapd->wps_event_cb_ctx, event, data); 872} 873 874 875static int hostapd_wps_rf_band_cb(void *ctx) 876{ 877 struct hostapd_data *hapd = ctx; 878 879 return hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? 880 WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ 881} 882 883 884static void hostapd_wps_clear_ies(struct hostapd_data *hapd) 885{ 886 wpabuf_free(hapd->wps_beacon_ie); 887 hapd->wps_beacon_ie = NULL; 888 889 wpabuf_free(hapd->wps_probe_resp_ie); 890 hapd->wps_probe_resp_ie = NULL; 891 892 hostapd_set_ap_wps_ie(hapd); 893} 894 895 896static int get_uuid_cb(struct hostapd_iface *iface, void *ctx) 897{ 898 const u8 **uuid = ctx; 899 size_t j; 900 901 if (iface == NULL) 902 return 0; 903 for (j = 0; j < iface->num_bss; j++) { 904 struct hostapd_data *hapd = iface->bss[j]; 905 if (hapd->wps && !hapd->conf->wps_independent && 906 !is_nil_uuid(hapd->wps->uuid)) { 907 *uuid = hapd->wps->uuid; 908 return 1; 909 } 910 } 911 912 return 0; 913} 914 915 916static const u8 * get_own_uuid(struct hostapd_iface *iface) 917{ 918 const u8 *uuid; 919 if (iface->interfaces == NULL || 920 iface->interfaces->for_each_interface == NULL) 921 return NULL; 922 uuid = NULL; 923 iface->interfaces->for_each_interface(iface->interfaces, get_uuid_cb, 924 &uuid); 925 return uuid; 926} 927 928 929static int count_interface_cb(struct hostapd_iface *iface, void *ctx) 930{ 931 int *count= ctx; 932 (*count)++; 933 return 0; 934} 935 936 937static int interface_count(struct hostapd_iface *iface) 938{ 939 int count = 0; 940 if (iface->interfaces == NULL || 941 iface->interfaces->for_each_interface == NULL) 942 return 0; 943 iface->interfaces->for_each_interface(iface->interfaces, 944 count_interface_cb, &count); 945 return count; 946} 947 948 949static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd, 950 struct wps_context *wps) 951{ 952 int i; 953 954 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { 955 wpabuf_free(wps->dev.vendor_ext[i]); 956 wps->dev.vendor_ext[i] = NULL; 957 958 if (hapd->conf->wps_vendor_ext[i] == NULL) 959 continue; 960 961 wps->dev.vendor_ext[i] = 962 wpabuf_dup(hapd->conf->wps_vendor_ext[i]); 963 if (wps->dev.vendor_ext[i] == NULL) { 964 while (--i >= 0) 965 wpabuf_free(wps->dev.vendor_ext[i]); 966 return -1; 967 } 968 } 969 970 return 0; 971} 972 973 974int hostapd_init_wps(struct hostapd_data *hapd, 975 struct hostapd_bss_config *conf) 976{ 977 struct wps_context *wps; 978 struct wps_registrar_config cfg; 979 980 if (conf->wps_state == 0) { 981 hostapd_wps_clear_ies(hapd); 982 return 0; 983 } 984 985 wps = os_zalloc(sizeof(*wps)); 986 if (wps == NULL) 987 return -1; 988 989 wps->cred_cb = hostapd_wps_cred_cb; 990 wps->event_cb = hostapd_wps_event_cb; 991 wps->rf_band_cb = hostapd_wps_rf_band_cb; 992 wps->cb_ctx = hapd; 993 994 os_memset(&cfg, 0, sizeof(cfg)); 995 wps->wps_state = hapd->conf->wps_state; 996 wps->ap_setup_locked = hapd->conf->ap_setup_locked; 997 if (is_nil_uuid(hapd->conf->uuid)) { 998 const u8 *uuid; 999 uuid = get_own_uuid(hapd->iface); 1000 if (uuid && !conf->wps_independent) { 1001 os_memcpy(wps->uuid, uuid, UUID_LEN); 1002 wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another " 1003 "interface", wps->uuid, UUID_LEN); 1004 } else { 1005 uuid_gen_mac_addr(hapd->own_addr, wps->uuid); 1006 wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC " 1007 "address", wps->uuid, UUID_LEN); 1008 } 1009 } else { 1010 os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); 1011 wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID", 1012 wps->uuid, UUID_LEN); 1013 } 1014 wps->ssid_len = hapd->conf->ssid.ssid_len; 1015 os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len); 1016 wps->ap = 1; 1017 os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN); 1018 wps->dev.device_name = hapd->conf->device_name ? 1019 os_strdup(hapd->conf->device_name) : NULL; 1020 wps->dev.manufacturer = hapd->conf->manufacturer ? 1021 os_strdup(hapd->conf->manufacturer) : NULL; 1022 wps->dev.model_name = hapd->conf->model_name ? 1023 os_strdup(hapd->conf->model_name) : NULL; 1024 wps->dev.model_number = hapd->conf->model_number ? 1025 os_strdup(hapd->conf->model_number) : NULL; 1026 wps->dev.serial_number = hapd->conf->serial_number ? 1027 os_strdup(hapd->conf->serial_number) : NULL; 1028 wps->config_methods = 1029 wps_config_methods_str2bin(hapd->conf->config_methods); 1030#ifdef CONFIG_WPS2 1031 if ((wps->config_methods & 1032 (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY | 1033 WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) { 1034 wpa_printf(MSG_INFO, "WPS: Converting display to " 1035 "virtual_display for WPS 2.0 compliance"); 1036 wps->config_methods |= WPS_CONFIG_VIRT_DISPLAY; 1037 } 1038 if ((wps->config_methods & 1039 (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON | 1040 WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) { 1041 wpa_printf(MSG_INFO, "WPS: Converting push_button to " 1042 "virtual_push_button for WPS 2.0 compliance"); 1043 wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON; 1044 } 1045#endif /* CONFIG_WPS2 */ 1046 os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type, 1047 WPS_DEV_TYPE_LEN); 1048 1049 if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) { 1050 os_free(wps); 1051 return -1; 1052 } 1053 1054 wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); 1055 1056 if (conf->wps_rf_bands) { 1057 wps->dev.rf_bands = conf->wps_rf_bands; 1058 } else { 1059 wps->dev.rf_bands = 1060 hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? 1061 WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ 1062 } 1063 1064 if (conf->wpa & WPA_PROTO_RSN) { 1065 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) 1066 wps->auth_types |= WPS_AUTH_WPA2PSK; 1067 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) 1068 wps->auth_types |= WPS_AUTH_WPA2; 1069 1070 if (conf->rsn_pairwise & WPA_CIPHER_CCMP) 1071 wps->encr_types |= WPS_ENCR_AES; 1072 if (conf->rsn_pairwise & WPA_CIPHER_TKIP) 1073 wps->encr_types |= WPS_ENCR_TKIP; 1074 } 1075 1076 if (conf->wpa & WPA_PROTO_WPA) { 1077 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) 1078 wps->auth_types |= WPS_AUTH_WPAPSK; 1079 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) 1080 wps->auth_types |= WPS_AUTH_WPA; 1081 1082 if (conf->wpa_pairwise & WPA_CIPHER_CCMP) 1083 wps->encr_types |= WPS_ENCR_AES; 1084 if (conf->wpa_pairwise & WPA_CIPHER_TKIP) 1085 wps->encr_types |= WPS_ENCR_TKIP; 1086 } 1087 1088 if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { 1089 wps->encr_types |= WPS_ENCR_NONE; 1090 wps->auth_types |= WPS_AUTH_OPEN; 1091 } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) { 1092 wps->encr_types |= WPS_ENCR_WEP; 1093 if (conf->auth_algs & WPA_AUTH_ALG_OPEN) 1094 wps->auth_types |= WPS_AUTH_OPEN; 1095 if (conf->auth_algs & WPA_AUTH_ALG_SHARED) 1096 wps->auth_types |= WPS_AUTH_SHARED; 1097 } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) { 1098 wps->auth_types |= WPS_AUTH_OPEN; 1099 if (conf->default_wep_key_len) 1100 wps->encr_types |= WPS_ENCR_WEP; 1101 else 1102 wps->encr_types |= WPS_ENCR_NONE; 1103 } 1104 1105 if (conf->ssid.wpa_psk_file) { 1106 /* Use per-device PSKs */ 1107 } else if (conf->ssid.wpa_passphrase) { 1108 wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); 1109 wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); 1110 } else if (conf->ssid.wpa_psk) { 1111 wps->network_key = os_malloc(2 * PMK_LEN + 1); 1112 if (wps->network_key == NULL) { 1113 os_free(wps); 1114 return -1; 1115 } 1116 wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, 1117 conf->ssid.wpa_psk->psk, PMK_LEN); 1118 wps->network_key_len = 2 * PMK_LEN; 1119 } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { 1120 wps->network_key = os_malloc(conf->ssid.wep.len[0]); 1121 if (wps->network_key == NULL) { 1122 os_free(wps); 1123 return -1; 1124 } 1125 os_memcpy(wps->network_key, conf->ssid.wep.key[0], 1126 conf->ssid.wep.len[0]); 1127 wps->network_key_len = conf->ssid.wep.len[0]; 1128 } 1129 1130 if (conf->ssid.wpa_psk) { 1131 os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN); 1132 wps->psk_set = 1; 1133 } 1134 1135 if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { 1136 /* Override parameters to enable security by default */ 1137 wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; 1138 wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; 1139 } 1140 1141 wps->ap_settings = conf->ap_settings; 1142 wps->ap_settings_len = conf->ap_settings_len; 1143 1144 cfg.new_psk_cb = hostapd_wps_new_psk_cb; 1145 cfg.set_ie_cb = hostapd_wps_set_ie_cb; 1146 cfg.pin_needed_cb = hostapd_wps_pin_needed_cb; 1147 cfg.reg_success_cb = hostapd_wps_reg_success_cb; 1148 cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb; 1149 cfg.cb_ctx = hapd; 1150 cfg.skip_cred_build = conf->skip_cred_build; 1151 cfg.extra_cred = conf->extra_cred; 1152 cfg.extra_cred_len = conf->extra_cred_len; 1153 cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) && 1154 conf->skip_cred_build; 1155 if (conf->ssid.security_policy == SECURITY_STATIC_WEP) 1156 cfg.static_wep_only = 1; 1157 cfg.dualband = interface_count(hapd->iface) > 1; 1158 if ((wps->dev.rf_bands & (WPS_RF_50GHZ | WPS_RF_24GHZ)) == 1159 (WPS_RF_50GHZ | WPS_RF_24GHZ)) 1160 cfg.dualband = 1; 1161 if (cfg.dualband) 1162 wpa_printf(MSG_DEBUG, "WPS: Dualband AP"); 1163 cfg.force_per_enrollee_psk = conf->force_per_enrollee_psk; 1164 1165 wps->registrar = wps_registrar_init(wps, &cfg); 1166 if (wps->registrar == NULL) { 1167 wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar"); 1168 os_free(wps->network_key); 1169 os_free(wps); 1170 return -1; 1171 } 1172 1173#ifdef CONFIG_WPS_UPNP 1174 wps->friendly_name = hapd->conf->friendly_name; 1175 wps->manufacturer_url = hapd->conf->manufacturer_url; 1176 wps->model_description = hapd->conf->model_description; 1177 wps->model_url = hapd->conf->model_url; 1178 wps->upc = hapd->conf->upc; 1179#endif /* CONFIG_WPS_UPNP */ 1180 1181 hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd); 1182 1183 hapd->wps = wps; 1184 1185 return 0; 1186} 1187 1188 1189int hostapd_init_wps_complete(struct hostapd_data *hapd) 1190{ 1191 struct wps_context *wps = hapd->wps; 1192 1193 if (wps == NULL) 1194 return 0; 1195 1196#ifdef CONFIG_WPS_UPNP 1197 if (hostapd_wps_upnp_init(hapd, wps) < 0) { 1198 wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP"); 1199 wps_registrar_deinit(wps->registrar); 1200 os_free(wps->network_key); 1201 os_free(wps); 1202 hapd->wps = NULL; 1203 return -1; 1204 } 1205#endif /* CONFIG_WPS_UPNP */ 1206 1207 return 0; 1208} 1209 1210 1211static void hostapd_wps_nfc_clear(struct wps_context *wps) 1212{ 1213#ifdef CONFIG_WPS_NFC 1214 wps->ap_nfc_dev_pw_id = 0; 1215 wpabuf_free(wps->ap_nfc_dh_pubkey); 1216 wps->ap_nfc_dh_pubkey = NULL; 1217 wpabuf_free(wps->ap_nfc_dh_privkey); 1218 wps->ap_nfc_dh_privkey = NULL; 1219 wpabuf_free(wps->ap_nfc_dev_pw); 1220 wps->ap_nfc_dev_pw = NULL; 1221#endif /* CONFIG_WPS_NFC */ 1222} 1223 1224 1225void hostapd_deinit_wps(struct hostapd_data *hapd) 1226{ 1227 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL); 1228 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL); 1229 if (hapd->wps == NULL) 1230 return; 1231#ifdef CONFIG_WPS_UPNP 1232 hostapd_wps_upnp_deinit(hapd); 1233#endif /* CONFIG_WPS_UPNP */ 1234 wps_registrar_deinit(hapd->wps->registrar); 1235 os_free(hapd->wps->network_key); 1236 wps_device_data_free(&hapd->wps->dev); 1237 wpabuf_free(hapd->wps->dh_pubkey); 1238 wpabuf_free(hapd->wps->dh_privkey); 1239 wps_free_pending_msgs(hapd->wps->upnp_msgs); 1240 hostapd_wps_nfc_clear(hapd->wps); 1241 os_free(hapd->wps); 1242 hapd->wps = NULL; 1243 hostapd_wps_clear_ies(hapd); 1244} 1245 1246 1247void hostapd_update_wps(struct hostapd_data *hapd) 1248{ 1249 if (hapd->wps == NULL) 1250 return; 1251 1252#ifdef CONFIG_WPS_UPNP 1253 hapd->wps->friendly_name = hapd->conf->friendly_name; 1254 hapd->wps->manufacturer_url = hapd->conf->manufacturer_url; 1255 hapd->wps->model_description = hapd->conf->model_description; 1256 hapd->wps->model_url = hapd->conf->model_url; 1257 hapd->wps->upc = hapd->conf->upc; 1258#endif /* CONFIG_WPS_UPNP */ 1259 1260 hostapd_wps_set_vendor_ext(hapd, hapd->wps); 1261 1262 if (hapd->conf->wps_state) 1263 wps_registrar_update_ie(hapd->wps->registrar); 1264 else 1265 hostapd_deinit_wps(hapd); 1266} 1267 1268 1269struct wps_add_pin_data { 1270 const u8 *addr; 1271 const u8 *uuid; 1272 const u8 *pin; 1273 size_t pin_len; 1274 int timeout; 1275 int added; 1276}; 1277 1278 1279static int wps_add_pin(struct hostapd_data *hapd, void *ctx) 1280{ 1281 struct wps_add_pin_data *data = ctx; 1282 int ret; 1283 1284 if (hapd->wps == NULL) 1285 return 0; 1286 ret = wps_registrar_add_pin(hapd->wps->registrar, data->addr, 1287 data->uuid, data->pin, data->pin_len, 1288 data->timeout); 1289 if (ret == 0) 1290 data->added++; 1291 return ret; 1292} 1293 1294 1295int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *addr, 1296 const char *uuid, const char *pin, int timeout) 1297{ 1298 u8 u[UUID_LEN]; 1299 struct wps_add_pin_data data; 1300 1301 data.addr = addr; 1302 data.uuid = u; 1303 data.pin = (const u8 *) pin; 1304 data.pin_len = os_strlen(pin); 1305 data.timeout = timeout; 1306 data.added = 0; 1307 1308 if (os_strcmp(uuid, "any") == 0) 1309 data.uuid = NULL; 1310 else { 1311 if (uuid_str2bin(uuid, u)) 1312 return -1; 1313 data.uuid = u; 1314 } 1315 if (hostapd_wps_for_each(hapd, wps_add_pin, &data) < 0) 1316 return -1; 1317 return data.added ? 0 : -1; 1318} 1319 1320 1321static int wps_button_pushed(struct hostapd_data *hapd, void *ctx) 1322{ 1323 const u8 *p2p_dev_addr = ctx; 1324 if (hapd->wps == NULL) 1325 return 0; 1326 return wps_registrar_button_pushed(hapd->wps->registrar, p2p_dev_addr); 1327} 1328 1329 1330int hostapd_wps_button_pushed(struct hostapd_data *hapd, 1331 const u8 *p2p_dev_addr) 1332{ 1333 return hostapd_wps_for_each(hapd, wps_button_pushed, 1334 (void *) p2p_dev_addr); 1335} 1336 1337 1338static int wps_cancel(struct hostapd_data *hapd, void *ctx) 1339{ 1340 if (hapd->wps == NULL) 1341 return 0; 1342 1343 wps_registrar_wps_cancel(hapd->wps->registrar); 1344 ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL); 1345 1346 return 0; 1347} 1348 1349 1350int hostapd_wps_cancel(struct hostapd_data *hapd) 1351{ 1352 return hostapd_wps_for_each(hapd, wps_cancel, NULL); 1353} 1354 1355 1356static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da, 1357 const u8 *bssid, 1358 const u8 *ie, size_t ie_len, 1359 int ssi_signal) 1360{ 1361 struct hostapd_data *hapd = ctx; 1362 struct wpabuf *wps_ie; 1363 struct ieee802_11_elems elems; 1364 1365 if (hapd->wps == NULL) 1366 return 0; 1367 1368 if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) { 1369 wpa_printf(MSG_DEBUG, "WPS: Could not parse ProbeReq from " 1370 MACSTR, MAC2STR(addr)); 1371 return 0; 1372 } 1373 1374 if (elems.ssid && elems.ssid_len > 0 && 1375 (elems.ssid_len != hapd->conf->ssid.ssid_len || 1376 os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 1377 0)) 1378 return 0; /* Not for us */ 1379 1380 wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA); 1381 if (wps_ie == NULL) 1382 return 0; 1383 if (wps_validate_probe_req(wps_ie, addr) < 0) { 1384 wpabuf_free(wps_ie); 1385 return 0; 1386 } 1387 1388 if (wpabuf_len(wps_ie) > 0) { 1389 int p2p_wildcard = 0; 1390#ifdef CONFIG_P2P 1391 if (elems.ssid && elems.ssid_len == P2P_WILDCARD_SSID_LEN && 1392 os_memcmp(elems.ssid, P2P_WILDCARD_SSID, 1393 P2P_WILDCARD_SSID_LEN) == 0) 1394 p2p_wildcard = 1; 1395#endif /* CONFIG_P2P */ 1396 wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie, 1397 p2p_wildcard); 1398#ifdef CONFIG_WPS_UPNP 1399 /* FIX: what exactly should be included in the WLANEvent? 1400 * WPS attributes? Full ProbeReq frame? */ 1401 if (!p2p_wildcard) 1402 upnp_wps_device_send_wlan_event( 1403 hapd->wps_upnp, addr, 1404 UPNP_WPS_WLANEVENT_TYPE_PROBE, wps_ie); 1405#endif /* CONFIG_WPS_UPNP */ 1406 } 1407 1408 wpabuf_free(wps_ie); 1409 1410 return 0; 1411} 1412 1413 1414#ifdef CONFIG_WPS_UPNP 1415 1416static int hostapd_rx_req_put_wlan_response( 1417 void *priv, enum upnp_wps_wlanevent_type ev_type, 1418 const u8 *mac_addr, const struct wpabuf *msg, 1419 enum wps_msg_type msg_type) 1420{ 1421 struct hostapd_data *hapd = priv; 1422 struct sta_info *sta; 1423 struct upnp_pending_message *p; 1424 1425 wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr=" 1426 MACSTR, ev_type, MAC2STR(mac_addr)); 1427 wpa_hexdump(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage", 1428 wpabuf_head(msg), wpabuf_len(msg)); 1429 if (ev_type != UPNP_WPS_WLANEVENT_TYPE_EAP) { 1430 wpa_printf(MSG_DEBUG, "WPS UPnP: Ignored unexpected " 1431 "PutWLANResponse WLANEventType %d", ev_type); 1432 return -1; 1433 } 1434 1435 /* 1436 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC 1437 * server implementation for delivery to the peer. 1438 */ 1439 1440 sta = ap_get_sta(hapd, mac_addr); 1441#ifndef CONFIG_WPS_STRICT 1442 if (!sta) { 1443 /* 1444 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC: 1445 * Pick STA that is in an ongoing WPS registration without 1446 * checking the MAC address. 1447 */ 1448 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found based " 1449 "on NewWLANEventMAC; try wildcard match"); 1450 for (sta = hapd->sta_list; sta; sta = sta->next) { 1451 if (sta->eapol_sm && (sta->flags & WLAN_STA_WPS)) 1452 break; 1453 } 1454 } 1455#endif /* CONFIG_WPS_STRICT */ 1456 1457 if (!sta || !(sta->flags & WLAN_STA_WPS)) { 1458 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found"); 1459 return 0; 1460 } 1461 1462 p = os_zalloc(sizeof(*p)); 1463 if (p == NULL) 1464 return -1; 1465 os_memcpy(p->addr, sta->addr, ETH_ALEN); 1466 p->msg = wpabuf_dup(msg); 1467 p->type = msg_type; 1468 p->next = hapd->wps->upnp_msgs; 1469 hapd->wps->upnp_msgs = p; 1470 1471 return eapol_auth_eap_pending_cb(sta->eapol_sm, sta->eapol_sm->eap); 1472} 1473 1474 1475static int hostapd_wps_upnp_init(struct hostapd_data *hapd, 1476 struct wps_context *wps) 1477{ 1478 struct upnp_wps_device_ctx *ctx; 1479 1480 if (!hapd->conf->upnp_iface) 1481 return 0; 1482 ctx = os_zalloc(sizeof(*ctx)); 1483 if (ctx == NULL) 1484 return -1; 1485 1486 ctx->rx_req_put_wlan_response = hostapd_rx_req_put_wlan_response; 1487 if (hapd->conf->ap_pin) 1488 ctx->ap_pin = os_strdup(hapd->conf->ap_pin); 1489 1490 hapd->wps_upnp = upnp_wps_device_init(ctx, wps, hapd, 1491 hapd->conf->upnp_iface); 1492 if (hapd->wps_upnp == NULL) 1493 return -1; 1494 wps->wps_upnp = hapd->wps_upnp; 1495 1496 return 0; 1497} 1498 1499 1500static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd) 1501{ 1502 upnp_wps_device_deinit(hapd->wps_upnp, hapd); 1503} 1504 1505#endif /* CONFIG_WPS_UPNP */ 1506 1507 1508int hostapd_wps_get_mib_sta(struct hostapd_data *hapd, const u8 *addr, 1509 char *buf, size_t buflen) 1510{ 1511 if (hapd->wps == NULL) 1512 return 0; 1513 return wps_registrar_get_info(hapd->wps->registrar, addr, buf, buflen); 1514} 1515 1516 1517static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx) 1518{ 1519 struct hostapd_data *hapd = eloop_data; 1520 wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out"); 1521 hostapd_wps_ap_pin_disable(hapd); 1522 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_PIN_DISABLED); 1523} 1524 1525 1526static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout) 1527{ 1528 wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout); 1529 hapd->ap_pin_failures = 0; 1530 hapd->ap_pin_failures_consecutive = 0; 1531 hapd->conf->ap_setup_locked = 0; 1532 if (hapd->wps->ap_setup_locked) { 1533 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED); 1534 hapd->wps->ap_setup_locked = 0; 1535 wps_registrar_update_ie(hapd->wps->registrar); 1536 } 1537 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL); 1538 if (timeout > 0) 1539 eloop_register_timeout(timeout, 0, 1540 hostapd_wps_ap_pin_timeout, hapd, NULL); 1541} 1542 1543 1544static int wps_ap_pin_disable(struct hostapd_data *hapd, void *ctx) 1545{ 1546 os_free(hapd->conf->ap_pin); 1547 hapd->conf->ap_pin = NULL; 1548#ifdef CONFIG_WPS_UPNP 1549 upnp_wps_set_ap_pin(hapd->wps_upnp, NULL); 1550#endif /* CONFIG_WPS_UPNP */ 1551 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL); 1552 return 0; 1553} 1554 1555 1556void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd) 1557{ 1558 wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN"); 1559 hostapd_wps_for_each(hapd, wps_ap_pin_disable, NULL); 1560} 1561 1562 1563struct wps_ap_pin_data { 1564 char pin_txt[9]; 1565 int timeout; 1566}; 1567 1568 1569static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx) 1570{ 1571 struct wps_ap_pin_data *data = ctx; 1572 os_free(hapd->conf->ap_pin); 1573 hapd->conf->ap_pin = os_strdup(data->pin_txt); 1574#ifdef CONFIG_WPS_UPNP 1575 upnp_wps_set_ap_pin(hapd->wps_upnp, data->pin_txt); 1576#endif /* CONFIG_WPS_UPNP */ 1577 hostapd_wps_ap_pin_enable(hapd, data->timeout); 1578 return 0; 1579} 1580 1581 1582const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout) 1583{ 1584 unsigned int pin; 1585 struct wps_ap_pin_data data; 1586 1587 pin = wps_generate_pin(); 1588 os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%08u", pin); 1589 data.timeout = timeout; 1590 hostapd_wps_for_each(hapd, wps_ap_pin_set, &data); 1591 return hapd->conf->ap_pin; 1592} 1593 1594 1595const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd) 1596{ 1597 return hapd->conf->ap_pin; 1598} 1599 1600 1601int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin, 1602 int timeout) 1603{ 1604 struct wps_ap_pin_data data; 1605 int ret; 1606 1607 ret = os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%s", pin); 1608 if (ret < 0 || ret >= (int) sizeof(data.pin_txt)) 1609 return -1; 1610 data.timeout = timeout; 1611 return hostapd_wps_for_each(hapd, wps_ap_pin_set, &data); 1612} 1613 1614 1615static int wps_update_ie(struct hostapd_data *hapd, void *ctx) 1616{ 1617 if (hapd->wps) 1618 wps_registrar_update_ie(hapd->wps->registrar); 1619 return 0; 1620} 1621 1622 1623void hostapd_wps_update_ie(struct hostapd_data *hapd) 1624{ 1625 hostapd_wps_for_each(hapd, wps_update_ie, NULL); 1626} 1627 1628 1629int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid, 1630 const char *auth, const char *encr, const char *key) 1631{ 1632 struct wps_credential cred; 1633 size_t len; 1634 1635 os_memset(&cred, 0, sizeof(cred)); 1636 1637 len = os_strlen(ssid); 1638 if ((len & 1) || len > 2 * sizeof(cred.ssid) || 1639 hexstr2bin(ssid, cred.ssid, len / 2)) 1640 return -1; 1641 cred.ssid_len = len / 2; 1642 1643 if (os_strncmp(auth, "OPEN", 4) == 0) 1644 cred.auth_type = WPS_AUTH_OPEN; 1645 else if (os_strncmp(auth, "WPAPSK", 6) == 0) 1646 cred.auth_type = WPS_AUTH_WPAPSK; 1647 else if (os_strncmp(auth, "WPA2PSK", 7) == 0) 1648 cred.auth_type = WPS_AUTH_WPA2PSK; 1649 else 1650 return -1; 1651 1652 if (encr) { 1653 if (os_strncmp(encr, "NONE", 4) == 0) 1654 cred.encr_type = WPS_ENCR_NONE; 1655 else if (os_strncmp(encr, "WEP", 3) == 0) 1656 cred.encr_type = WPS_ENCR_WEP; 1657 else if (os_strncmp(encr, "TKIP", 4) == 0) 1658 cred.encr_type = WPS_ENCR_TKIP; 1659 else if (os_strncmp(encr, "CCMP", 4) == 0) 1660 cred.encr_type = WPS_ENCR_AES; 1661 else 1662 return -1; 1663 } else 1664 cred.encr_type = WPS_ENCR_NONE; 1665 1666 if (key) { 1667 len = os_strlen(key); 1668 if ((len & 1) || len > 2 * sizeof(cred.key) || 1669 hexstr2bin(key, cred.key, len / 2)) 1670 return -1; 1671 cred.key_len = len / 2; 1672 } 1673 1674 return wps_registrar_config_ap(hapd->wps->registrar, &cred); 1675} 1676 1677 1678#ifdef CONFIG_WPS_NFC 1679 1680struct wps_nfc_password_token_data { 1681 const u8 *oob_dev_pw; 1682 size_t oob_dev_pw_len; 1683 int added; 1684}; 1685 1686 1687static int wps_add_nfc_password_token(struct hostapd_data *hapd, void *ctx) 1688{ 1689 struct wps_nfc_password_token_data *data = ctx; 1690 int ret; 1691 1692 if (hapd->wps == NULL) 1693 return 0; 1694 ret = wps_registrar_add_nfc_password_token(hapd->wps->registrar, 1695 data->oob_dev_pw, 1696 data->oob_dev_pw_len); 1697 if (ret == 0) 1698 data->added++; 1699 return ret; 1700} 1701 1702 1703static int hostapd_wps_add_nfc_password_token(struct hostapd_data *hapd, 1704 struct wps_parse_attr *attr) 1705{ 1706 struct wps_nfc_password_token_data data; 1707 1708 data.oob_dev_pw = attr->oob_dev_password; 1709 data.oob_dev_pw_len = attr->oob_dev_password_len; 1710 data.added = 0; 1711 if (hostapd_wps_for_each(hapd, wps_add_nfc_password_token, &data) < 0) 1712 return -1; 1713 return data.added ? 0 : -1; 1714} 1715 1716 1717static int hostapd_wps_nfc_tag_process(struct hostapd_data *hapd, 1718 const struct wpabuf *wps) 1719{ 1720 struct wps_parse_attr attr; 1721 1722 wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps); 1723 1724 if (wps_parse_msg(wps, &attr)) { 1725 wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag"); 1726 return -1; 1727 } 1728 1729 if (attr.oob_dev_password) 1730 return hostapd_wps_add_nfc_password_token(hapd, &attr); 1731 1732 wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag"); 1733 return -1; 1734} 1735 1736 1737int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd, 1738 const struct wpabuf *data) 1739{ 1740 const struct wpabuf *wps = data; 1741 struct wpabuf *tmp = NULL; 1742 int ret; 1743 1744 if (wpabuf_len(data) < 4) 1745 return -1; 1746 1747 if (*wpabuf_head_u8(data) != 0x10) { 1748 /* Assume this contains full NDEF record */ 1749 tmp = ndef_parse_wifi(data); 1750 if (tmp == NULL) { 1751 wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF"); 1752 return -1; 1753 } 1754 wps = tmp; 1755 } 1756 1757 ret = hostapd_wps_nfc_tag_process(hapd, wps); 1758 wpabuf_free(tmp); 1759 return ret; 1760} 1761 1762 1763struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd, 1764 int ndef) 1765{ 1766 struct wpabuf *ret; 1767 1768 if (hapd->wps == NULL) 1769 return NULL; 1770 1771 ret = wps_get_oob_cred(hapd->wps); 1772 if (ndef && ret) { 1773 struct wpabuf *tmp; 1774 tmp = ndef_build_wifi(ret); 1775 wpabuf_free(ret); 1776 if (tmp == NULL) 1777 return NULL; 1778 ret = tmp; 1779 } 1780 1781 return ret; 1782} 1783 1784 1785struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef) 1786{ 1787 /* 1788 * Handover Select carrier record for WPS uses the same format as 1789 * configuration token. 1790 */ 1791 return hostapd_wps_nfc_config_token(hapd, ndef); 1792} 1793 1794 1795struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef) 1796{ 1797 if (hapd->conf->wps_nfc_pw_from_config) { 1798 return wps_nfc_token_build(ndef, 1799 hapd->conf->wps_nfc_dev_pw_id, 1800 hapd->conf->wps_nfc_dh_pubkey, 1801 hapd->conf->wps_nfc_dev_pw); 1802 } 1803 1804 return wps_nfc_token_gen(ndef, &hapd->conf->wps_nfc_dev_pw_id, 1805 &hapd->conf->wps_nfc_dh_pubkey, 1806 &hapd->conf->wps_nfc_dh_privkey, 1807 &hapd->conf->wps_nfc_dev_pw); 1808} 1809 1810 1811int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd) 1812{ 1813 struct wps_context *wps = hapd->wps; 1814 struct wpabuf *pw; 1815 1816 if (wps == NULL) 1817 return -1; 1818 1819 if (!hapd->conf->wps_nfc_dh_pubkey || 1820 !hapd->conf->wps_nfc_dh_privkey || 1821 !hapd->conf->wps_nfc_dev_pw || 1822 !hapd->conf->wps_nfc_dev_pw_id) 1823 return -1; 1824 1825 hostapd_wps_nfc_clear(wps); 1826 wps->ap_nfc_dev_pw_id = hapd->conf->wps_nfc_dev_pw_id; 1827 wps->ap_nfc_dh_pubkey = wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey); 1828 wps->ap_nfc_dh_privkey = wpabuf_dup(hapd->conf->wps_nfc_dh_privkey); 1829 pw = hapd->conf->wps_nfc_dev_pw; 1830 wps->ap_nfc_dev_pw = wpabuf_alloc( 1831 wpabuf_len(pw) * 2 + 1); 1832 if (wps->ap_nfc_dev_pw) { 1833 wpa_snprintf_hex_uppercase( 1834 (char *) wpabuf_put(wps->ap_nfc_dev_pw, 1835 wpabuf_len(pw) * 2), 1836 wpabuf_len(pw) * 2 + 1, 1837 wpabuf_head(pw), wpabuf_len(pw)); 1838 } 1839 1840 if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey || 1841 !wps->ap_nfc_dev_pw) { 1842 hostapd_wps_nfc_clear(wps); 1843 return -1; 1844 } 1845 1846 return 0; 1847} 1848 1849 1850void hostapd_wps_nfc_token_disable(struct hostapd_data *hapd) 1851{ 1852 hostapd_wps_nfc_clear(hapd->wps); 1853} 1854 1855#endif /* CONFIG_WPS_NFC */ 1856