1 /* 2 * Wi-Fi Protected Setup - External Registrar 3 * Copyright (c) 2009-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 "includes.h" 10 11 #include "common.h" 12 #include "base64.h" 13 #include "uuid.h" 14 #include "eloop.h" 15 #include "httpread.h" 16 #include "http_client.h" 17 #include "http_server.h" 18 #include "upnp_xml.h" 19 #include "wps_i.h" 20 #include "wps_upnp.h" 21 #include "wps_upnp_i.h" 22 #include "wps_er.h" 23 24 25 static void wps_er_deinit_finish(void *eloop_data, void *user_ctx); 26 static void wps_er_ap_timeout(void *eloop_data, void *user_ctx); 27 static void wps_er_sta_timeout(void *eloop_data, void *user_ctx); 28 static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg); 29 static int wps_er_send_get_device_info(struct wps_er_ap *ap, 30 void (*m1_handler)(struct wps_er_ap *ap, 31 struct wpabuf *m1)); 32 33 34 static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta, 35 enum wps_event event) 36 { 37 union wps_event_data data; 38 struct wps_event_er_enrollee *ev = &data.enrollee; 39 40 if (wps->event_cb == NULL) 41 return; 42 43 os_memset(&data, 0, sizeof(data)); 44 ev->uuid = sta->uuid; 45 ev->mac_addr = sta->addr; 46 ev->m1_received = sta->m1_received; 47 ev->config_methods = sta->config_methods; 48 ev->dev_passwd_id = sta->dev_passwd_id; 49 ev->pri_dev_type = sta->pri_dev_type; 50 ev->dev_name = sta->dev_name; 51 ev->manufacturer = sta->manufacturer; 52 ev->model_name = sta->model_name; 53 ev->model_number = sta->model_number; 54 ev->serial_number = sta->serial_number; 55 wps->event_cb(wps->cb_ctx, event, &data); 56 } 57 58 59 static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr, 60 const u8 *uuid) 61 { 62 struct wps_er_sta *sta; 63 dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list) { 64 if ((addr == NULL || 65 os_memcmp(sta->addr, addr, ETH_ALEN) == 0) && 66 (uuid == NULL || 67 os_memcmp(uuid, sta->uuid, WPS_UUID_LEN) == 0)) 68 return sta; 69 } 70 return NULL; 71 } 72 73 74 static void wps_er_sta_free(struct wps_er_sta *sta) 75 { 76 wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE); 77 if (sta->wps) 78 wps_deinit(sta->wps); 79 os_free(sta->manufacturer); 80 os_free(sta->model_name); 81 os_free(sta->model_number); 82 os_free(sta->serial_number); 83 os_free(sta->dev_name); 84 http_client_free(sta->http); 85 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL); 86 os_free(sta->cred); 87 os_free(sta); 88 } 89 90 91 static void wps_er_sta_remove_all(struct wps_er_ap *ap) 92 { 93 struct wps_er_sta *prev, *sta; 94 dl_list_for_each_safe(sta, prev, &ap->sta, struct wps_er_sta, list) 95 wps_er_sta_free(sta); 96 } 97 98 99 static struct wps_er_ap * wps_er_ap_get(struct wps_er *er, 100 struct in_addr *addr, const u8 *uuid) 101 { 102 struct wps_er_ap *ap; 103 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 104 if ((addr == NULL || ap->addr.s_addr == addr->s_addr) && 105 (uuid == NULL || 106 os_memcmp(uuid, ap->uuid, WPS_UUID_LEN) == 0)) 107 return ap; 108 } 109 return NULL; 110 } 111 112 113 static struct wps_er_ap * wps_er_ap_get_id(struct wps_er *er, unsigned int id) 114 { 115 struct wps_er_ap *ap; 116 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 117 if (ap->id == id) 118 return ap; 119 } 120 return NULL; 121 } 122 123 124 static void wps_er_ap_event(struct wps_context *wps, struct wps_er_ap *ap, 125 enum wps_event event) 126 { 127 union wps_event_data data; 128 struct wps_event_er_ap *evap = &data.ap; 129 130 if (wps->event_cb == NULL) 131 return; 132 133 os_memset(&data, 0, sizeof(data)); 134 evap->uuid = ap->uuid; 135 evap->friendly_name = ap->friendly_name; 136 evap->manufacturer = ap->manufacturer; 137 evap->manufacturer_url = ap->manufacturer_url; 138 evap->model_description = ap->model_description; 139 evap->model_name = ap->model_name; 140 evap->model_number = ap->model_number; 141 evap->model_url = ap->model_url; 142 evap->serial_number = ap->serial_number; 143 evap->upc = ap->upc; 144 evap->pri_dev_type = ap->pri_dev_type; 145 evap->wps_state = ap->wps_state; 146 evap->mac_addr = ap->mac_addr; 147 wps->event_cb(wps->cb_ctx, event, &data); 148 } 149 150 151 static void wps_er_ap_free(struct wps_er_ap *ap) 152 { 153 http_client_free(ap->http); 154 ap->http = NULL; 155 156 os_free(ap->location); 157 os_free(ap->friendly_name); 158 os_free(ap->manufacturer); 159 os_free(ap->manufacturer_url); 160 os_free(ap->model_description); 161 os_free(ap->model_name); 162 os_free(ap->model_number); 163 os_free(ap->model_url); 164 os_free(ap->serial_number); 165 os_free(ap->udn); 166 os_free(ap->upc); 167 168 os_free(ap->scpd_url); 169 os_free(ap->control_url); 170 os_free(ap->event_sub_url); 171 172 os_free(ap->ap_settings); 173 174 os_free(ap); 175 } 176 177 178 static void wps_er_ap_unsubscribed(struct wps_er *er, struct wps_er_ap *ap) 179 { 180 wpa_printf(MSG_DEBUG, "WPS ER: Unsubscribed from AP %s (%s)", 181 inet_ntoa(ap->addr), ap->location); 182 dl_list_del(&ap->list); 183 wps_er_ap_free(ap); 184 185 if (er->deinitializing && dl_list_empty(&er->ap_unsubscribing)) { 186 eloop_cancel_timeout(wps_er_deinit_finish, er, NULL); 187 wps_er_deinit_finish(er, NULL); 188 } 189 } 190 191 192 static void wps_er_http_unsubscribe_cb(void *ctx, struct http_client *c, 193 enum http_client_event event) 194 { 195 struct wps_er_ap *ap = ctx; 196 197 switch (event) { 198 case HTTP_CLIENT_OK: 199 wpa_printf(MSG_DEBUG, "WPS ER: Unsubscribed from events"); 200 ap->subscribed = 0; 201 break; 202 case HTTP_CLIENT_FAILED: 203 case HTTP_CLIENT_INVALID_REPLY: 204 case HTTP_CLIENT_TIMEOUT: 205 wpa_printf(MSG_DEBUG, "WPS ER: Failed to unsubscribe from " 206 "events"); 207 break; 208 } 209 http_client_free(ap->http); 210 ap->http = NULL; 211 212 /* 213 * Need to get rid of the AP entry regardless of whether we managed to 214 * unsubscribe cleanly or not. 215 */ 216 wps_er_ap_unsubscribed(ap->er, ap); 217 } 218 219 220 static void wps_er_ap_unsubscribe(struct wps_er *er, struct wps_er_ap *ap) 221 { 222 struct wpabuf *req; 223 struct sockaddr_in dst; 224 char *url, *path; 225 char sid[100]; 226 227 if (ap->event_sub_url == NULL) { 228 wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot " 229 "subscribe"); 230 goto fail; 231 } 232 if (ap->http) { 233 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot " 234 "send subscribe request"); 235 goto fail; 236 } 237 238 url = http_client_url_parse(ap->event_sub_url, &dst, &path); 239 if (url == NULL) { 240 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL"); 241 goto fail; 242 } 243 244 req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000); 245 if (req == NULL) { 246 os_free(url); 247 goto fail; 248 } 249 uuid_bin2str(ap->sid, sid, sizeof(sid)); 250 wpabuf_printf(req, 251 "UNSUBSCRIBE %s HTTP/1.1\r\n" 252 "HOST: %s:%d\r\n" 253 "SID: uuid:%s\r\n" 254 "\r\n", 255 path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port), sid); 256 os_free(url); 257 wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Unsubscription request", 258 wpabuf_head(req), wpabuf_len(req)); 259 260 ap->http = http_client_addr(&dst, req, 1000, 261 wps_er_http_unsubscribe_cb, ap); 262 if (ap->http == NULL) { 263 wpabuf_free(req); 264 goto fail; 265 } 266 return; 267 268 fail: 269 /* 270 * Need to get rid of the AP entry even when we fail to unsubscribe 271 * cleanly. 272 */ 273 wps_er_ap_unsubscribed(ap->er, ap); 274 } 275 276 277 static struct wps_er_ap_settings * wps_er_ap_get_settings(struct wps_er *er, 278 const u8 *uuid) 279 { 280 struct wps_er_ap_settings *s; 281 dl_list_for_each(s, &er->ap_settings, struct wps_er_ap_settings, list) 282 if (os_memcmp(uuid, s->uuid, WPS_UUID_LEN) == 0) 283 return s; 284 return NULL; 285 } 286 287 288 int wps_er_ap_cache_settings(struct wps_er *er, struct in_addr *addr) 289 { 290 struct wps_er_ap *ap; 291 struct wps_er_ap_settings *settings; 292 293 ap = wps_er_ap_get(er, addr, NULL); 294 if (ap == NULL || ap->ap_settings == NULL) 295 return -1; 296 297 settings = wps_er_ap_get_settings(er, ap->uuid); 298 if (!settings) { 299 settings = os_zalloc(sizeof(*settings)); 300 if (settings == NULL) 301 return -1; 302 os_memcpy(settings->uuid, ap->uuid, WPS_UUID_LEN); 303 dl_list_add(&er->ap_settings, &settings->list); 304 } 305 os_memcpy(&settings->ap_settings, ap->ap_settings, 306 sizeof(struct wps_credential)); 307 308 return 0; 309 } 310 311 312 static int wps_er_ap_use_cached_settings(struct wps_er *er, 313 struct wps_er_ap *ap) 314 { 315 struct wps_er_ap_settings *s; 316 317 if (ap->ap_settings) 318 return 0; 319 320 s = wps_er_ap_get_settings(ap->er, ap->uuid); 321 if (!s) 322 return -1; 323 324 ap->ap_settings = os_malloc(sizeof(*ap->ap_settings)); 325 if (ap->ap_settings == NULL) 326 return -1; 327 328 os_memcpy(ap->ap_settings, &s->ap_settings, sizeof(*ap->ap_settings)); 329 wpa_printf(MSG_DEBUG, "WPS ER: Use cached AP settings"); 330 return 0; 331 } 332 333 334 static void wps_er_ap_remove_entry(struct wps_er *er, struct wps_er_ap *ap) 335 { 336 wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)", 337 inet_ntoa(ap->addr), ap->location); 338 eloop_cancel_timeout(wps_er_ap_timeout, er, ap); 339 wps_er_sta_remove_all(ap); 340 wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE); 341 http_client_free(ap->http); 342 ap->http = NULL; 343 if (ap->wps) { 344 wps_deinit(ap->wps); 345 ap->wps = NULL; 346 } 347 348 dl_list_del(&ap->list); 349 if (ap->subscribed) { 350 dl_list_add(&er->ap_unsubscribing, &ap->list); 351 wps_er_ap_unsubscribe(er, ap); 352 } else 353 wps_er_ap_free(ap); 354 } 355 356 357 static void wps_er_ap_timeout(void *eloop_data, void *user_ctx) 358 { 359 struct wps_er *er = eloop_data; 360 struct wps_er_ap *ap = user_ctx; 361 wpa_printf(MSG_DEBUG, "WPS ER: AP advertisement timed out"); 362 wps_er_ap_remove_entry(er, ap); 363 } 364 365 366 static int wps_er_get_sid(struct wps_er_ap *ap, char *sid) 367 { 368 char *pos; 369 char txt[100]; 370 371 if (!sid) { 372 wpa_printf(MSG_DEBUG, "WPS ER: No SID received from %s (%s)", 373 inet_ntoa(ap->addr), ap->location); 374 return -1; 375 } 376 377 pos = os_strstr(sid, "uuid:"); 378 if (!pos) { 379 wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from " 380 "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location, 381 sid); 382 return -1; 383 } 384 385 pos += 5; 386 if (uuid_str2bin(pos, ap->sid) < 0) { 387 wpa_printf(MSG_DEBUG, "WPS ER: Invalid SID received from " 388 "%s (%s): '%s'", inet_ntoa(ap->addr), ap->location, 389 sid); 390 return -1; 391 } 392 393 uuid_bin2str(ap->sid, txt, sizeof(txt)); 394 wpa_printf(MSG_DEBUG, "WPS ER: SID for subscription with %s (%s): %s", 395 inet_ntoa(ap->addr), ap->location, txt); 396 397 return 0; 398 } 399 400 401 static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c, 402 enum http_client_event event) 403 { 404 struct wps_er_ap *ap = ctx; 405 406 switch (event) { 407 case HTTP_CLIENT_OK: 408 wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events"); 409 ap->subscribed = 1; 410 wps_er_get_sid(ap, http_client_get_hdr_line(c, "SID")); 411 wps_er_ap_use_cached_settings(ap->er, ap); 412 wps_er_ap_event(ap->er->wps, ap, WPS_EV_ER_AP_ADD); 413 break; 414 case HTTP_CLIENT_FAILED: 415 case HTTP_CLIENT_INVALID_REPLY: 416 case HTTP_CLIENT_TIMEOUT: 417 wpa_printf(MSG_DEBUG, "WPS ER: Failed to subscribe to events"); 418 break; 419 } 420 http_client_free(ap->http); 421 ap->http = NULL; 422 } 423 424 425 static void wps_er_subscribe(struct wps_er_ap *ap) 426 { 427 struct wpabuf *req; 428 struct sockaddr_in dst; 429 char *url, *path; 430 431 if (ap->event_sub_url == NULL) { 432 wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot " 433 "subscribe"); 434 return; 435 } 436 if (ap->http) { 437 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot " 438 "send subscribe request"); 439 return; 440 } 441 442 url = http_client_url_parse(ap->event_sub_url, &dst, &path); 443 if (url == NULL) { 444 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL"); 445 return; 446 } 447 448 req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000); 449 if (req == NULL) { 450 os_free(url); 451 return; 452 } 453 wpabuf_printf(req, 454 "SUBSCRIBE %s HTTP/1.1\r\n" 455 "HOST: %s:%d\r\n" 456 "CALLBACK: <http://%s:%d/event/%u/%u>\r\n" 457 "NT: upnp:event\r\n" 458 "TIMEOUT: Second-%d\r\n" 459 "\r\n", 460 path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port), 461 ap->er->ip_addr_text, ap->er->http_port, 462 ap->er->event_id, ap->id, 1800); 463 os_free(url); 464 wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request", 465 wpabuf_head(req), wpabuf_len(req)); 466 467 ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb, 468 ap); 469 if (ap->http == NULL) 470 wpabuf_free(req); 471 } 472 473 474 static void wps_er_ap_get_m1(struct wps_er_ap *ap, struct wpabuf *m1) 475 { 476 struct wps_parse_attr attr; 477 478 if (wps_parse_msg(m1, &attr) < 0) { 479 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse M1"); 480 return; 481 } 482 if (attr.primary_dev_type) 483 os_memcpy(ap->pri_dev_type, attr.primary_dev_type, 8); 484 if (attr.wps_state) 485 ap->wps_state = *attr.wps_state; 486 if (attr.mac_addr) 487 os_memcpy(ap->mac_addr, attr.mac_addr, ETH_ALEN); 488 489 wps_er_subscribe(ap); 490 } 491 492 493 static void wps_er_get_device_info(struct wps_er_ap *ap) 494 { 495 wps_er_send_get_device_info(ap, wps_er_ap_get_m1); 496 } 497 498 499 static const char * wps_er_find_wfadevice(const char *data) 500 { 501 const char *tag, *tagname, *end; 502 char *val; 503 int found = 0; 504 505 while (!found) { 506 /* Find next <device> */ 507 for (;;) { 508 if (xml_next_tag(data, &tag, &tagname, &end)) 509 return NULL; 510 data = end; 511 if (!os_strncasecmp(tagname, "device", 6) && 512 *tag != '/' && 513 (tagname[6] == '>' || !isgraph(tagname[6]))) { 514 break; 515 } 516 } 517 518 /* Check whether deviceType is WFADevice */ 519 val = xml_get_first_item(data, "deviceType"); 520 if (val == NULL) 521 return NULL; 522 wpa_printf(MSG_DEBUG, "WPS ER: Found deviceType '%s'", val); 523 found = os_strcasecmp(val, "urn:schemas-wifialliance-org:" 524 "device:WFADevice:1") == 0; 525 os_free(val); 526 } 527 528 return data; 529 } 530 531 532 static void wps_er_parse_device_description(struct wps_er_ap *ap, 533 struct wpabuf *reply) 534 { 535 /* Note: reply includes null termination after the buffer data */ 536 const char *tmp, *data = wpabuf_head(reply); 537 char *pos; 538 539 wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info", 540 wpabuf_head(reply), wpabuf_len(reply)); 541 542 /* 543 * The root device description may include multiple devices, so first 544 * find the beginning of the WFADevice description to allow the 545 * simplistic parser to pick the correct entries. 546 */ 547 tmp = wps_er_find_wfadevice(data); 548 if (tmp == NULL) { 549 wpa_printf(MSG_DEBUG, "WPS ER: WFADevice:1 device not found - " 550 "trying to parse invalid data"); 551 } else 552 data = tmp; 553 554 ap->friendly_name = xml_get_first_item(data, "friendlyName"); 555 wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name); 556 557 ap->manufacturer = xml_get_first_item(data, "manufacturer"); 558 wpa_printf(MSG_DEBUG, "WPS ER: manufacturer='%s'", ap->manufacturer); 559 560 ap->manufacturer_url = xml_get_first_item(data, "manufacturerURL"); 561 wpa_printf(MSG_DEBUG, "WPS ER: manufacturerURL='%s'", 562 ap->manufacturer_url); 563 564 ap->model_description = xml_get_first_item(data, "modelDescription"); 565 wpa_printf(MSG_DEBUG, "WPS ER: modelDescription='%s'", 566 ap->model_description); 567 568 ap->model_name = xml_get_first_item(data, "modelName"); 569 wpa_printf(MSG_DEBUG, "WPS ER: modelName='%s'", ap->model_name); 570 571 ap->model_number = xml_get_first_item(data, "modelNumber"); 572 wpa_printf(MSG_DEBUG, "WPS ER: modelNumber='%s'", ap->model_number); 573 574 ap->model_url = xml_get_first_item(data, "modelURL"); 575 wpa_printf(MSG_DEBUG, "WPS ER: modelURL='%s'", ap->model_url); 576 577 ap->serial_number = xml_get_first_item(data, "serialNumber"); 578 wpa_printf(MSG_DEBUG, "WPS ER: serialNumber='%s'", ap->serial_number); 579 580 ap->udn = xml_get_first_item(data, "UDN"); 581 wpa_printf(MSG_DEBUG, "WPS ER: UDN='%s'", ap->udn); 582 pos = os_strstr(ap->udn, "uuid:"); 583 if (pos) { 584 pos += 5; 585 if (uuid_str2bin(pos, ap->uuid) < 0) 586 wpa_printf(MSG_DEBUG, "WPS ER: Invalid UUID in UDN"); 587 } 588 589 ap->upc = xml_get_first_item(data, "UPC"); 590 wpa_printf(MSG_DEBUG, "WPS ER: UPC='%s'", ap->upc); 591 592 ap->scpd_url = http_link_update( 593 xml_get_first_item(data, "SCPDURL"), ap->location); 594 wpa_printf(MSG_DEBUG, "WPS ER: SCPDURL='%s'", ap->scpd_url); 595 596 ap->control_url = http_link_update( 597 xml_get_first_item(data, "controlURL"), ap->location); 598 wpa_printf(MSG_DEBUG, "WPS ER: controlURL='%s'", ap->control_url); 599 600 ap->event_sub_url = http_link_update( 601 xml_get_first_item(data, "eventSubURL"), ap->location); 602 wpa_printf(MSG_DEBUG, "WPS ER: eventSubURL='%s'", ap->event_sub_url); 603 } 604 605 606 static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c, 607 enum http_client_event event) 608 { 609 struct wps_er_ap *ap = ctx; 610 struct wpabuf *reply; 611 int ok = 0; 612 613 switch (event) { 614 case HTTP_CLIENT_OK: 615 reply = http_client_get_body(c); 616 if (reply == NULL) 617 break; 618 wps_er_parse_device_description(ap, reply); 619 ok = 1; 620 break; 621 case HTTP_CLIENT_FAILED: 622 case HTTP_CLIENT_INVALID_REPLY: 623 case HTTP_CLIENT_TIMEOUT: 624 wpa_printf(MSG_DEBUG, "WPS ER: Failed to fetch device info"); 625 break; 626 } 627 http_client_free(ap->http); 628 ap->http = NULL; 629 if (ok) 630 wps_er_get_device_info(ap); 631 } 632 633 634 void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr, 635 const char *location, int max_age) 636 { 637 struct wps_er_ap *ap; 638 639 ap = wps_er_ap_get(er, addr, uuid); 640 if (ap) { 641 /* Update advertisement timeout */ 642 eloop_cancel_timeout(wps_er_ap_timeout, er, ap); 643 eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap); 644 return; 645 } 646 647 ap = os_zalloc(sizeof(*ap)); 648 if (ap == NULL) 649 return; 650 dl_list_init(&ap->sta); 651 ap->er = er; 652 ap->id = ++er->next_ap_id; 653 ap->location = os_strdup(location); 654 if (ap->location == NULL) { 655 os_free(ap); 656 return; 657 } 658 dl_list_add(&er->ap, &ap->list); 659 660 ap->addr.s_addr = addr->s_addr; 661 os_memcpy(ap->uuid, uuid, WPS_UUID_LEN); 662 eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap); 663 664 wpa_printf(MSG_DEBUG, "WPS ER: Added AP entry for %s (%s)", 665 inet_ntoa(ap->addr), ap->location); 666 667 /* Fetch device description */ 668 ap->http = http_client_url(ap->location, NULL, 10000, 669 wps_er_http_dev_desc_cb, ap); 670 } 671 672 673 void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr) 674 { 675 struct wps_er_ap *ap; 676 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 677 if (ap->addr.s_addr == addr->s_addr) { 678 wps_er_ap_remove_entry(er, ap); 679 return; 680 } 681 } 682 } 683 684 685 static void wps_er_ap_remove_all(struct wps_er *er) 686 { 687 struct wps_er_ap *prev, *ap; 688 struct wps_er_ap_settings *prev_s, *s; 689 dl_list_for_each_safe(ap, prev, &er->ap, struct wps_er_ap, list) 690 wps_er_ap_remove_entry(er, ap); 691 dl_list_for_each_safe(s, prev_s, &er->ap_settings, 692 struct wps_er_ap_settings, list) 693 os_free(s); 694 } 695 696 697 static void http_put_date(struct wpabuf *buf) 698 { 699 wpabuf_put_str(buf, "Date: "); 700 format_date(buf); 701 wpabuf_put_str(buf, "\r\n"); 702 } 703 704 705 static void wps_er_http_resp_not_found(struct http_request *req) 706 { 707 struct wpabuf *buf; 708 buf = wpabuf_alloc(200); 709 if (buf == NULL) { 710 http_request_deinit(req); 711 return; 712 } 713 714 wpabuf_put_str(buf, 715 "HTTP/1.1 404 Not Found\r\n" 716 "Server: unspecified, UPnP/1.0, unspecified\r\n" 717 "Connection: close\r\n"); 718 http_put_date(buf); 719 wpabuf_put_str(buf, "\r\n"); 720 http_request_send_and_deinit(req, buf); 721 } 722 723 724 static void wps_er_http_resp_ok(struct http_request *req) 725 { 726 struct wpabuf *buf; 727 buf = wpabuf_alloc(200); 728 if (buf == NULL) { 729 http_request_deinit(req); 730 return; 731 } 732 733 wpabuf_put_str(buf, 734 "HTTP/1.1 200 OK\r\n" 735 "Server: unspecified, UPnP/1.0, unspecified\r\n" 736 "Connection: close\r\n" 737 "Content-Length: 0\r\n"); 738 http_put_date(buf); 739 wpabuf_put_str(buf, "\r\n"); 740 http_request_send_and_deinit(req, buf); 741 } 742 743 744 static void wps_er_sta_timeout(void *eloop_data, void *user_ctx) 745 { 746 struct wps_er_sta *sta = eloop_data; 747 wpa_printf(MSG_DEBUG, "WPS ER: STA entry timed out"); 748 dl_list_del(&sta->list); 749 wps_er_sta_free(sta); 750 } 751 752 753 static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap, 754 const u8 *addr, 755 struct wps_parse_attr *attr, 756 int probe_req) 757 { 758 struct wps_er_sta *sta = wps_er_sta_get(ap, addr, NULL); 759 int new_sta = 0; 760 int m1; 761 762 m1 = !probe_req && attr->msg_type && *attr->msg_type == WPS_M1; 763 764 if (sta == NULL) { 765 /* 766 * Only allow new STA entry to be added based on Probe Request 767 * or M1. This will filter out bogus events and anything that 768 * may have been ongoing at the time ER subscribed for events. 769 */ 770 if (!probe_req && !m1) 771 return NULL; 772 773 sta = os_zalloc(sizeof(*sta)); 774 if (sta == NULL) 775 return NULL; 776 os_memcpy(sta->addr, addr, ETH_ALEN); 777 sta->ap = ap; 778 dl_list_add(&ap->sta, &sta->list); 779 new_sta = 1; 780 } 781 782 if (m1) 783 sta->m1_received = 1; 784 785 if (attr->config_methods && (!probe_req || !sta->m1_received)) 786 sta->config_methods = WPA_GET_BE16(attr->config_methods); 787 if (attr->uuid_e && (!probe_req || !sta->m1_received)) 788 os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN); 789 if (attr->primary_dev_type && (!probe_req || !sta->m1_received)) 790 os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8); 791 if (attr->dev_password_id && (!probe_req || !sta->m1_received)) 792 sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id); 793 794 if (attr->manufacturer) { 795 os_free(sta->manufacturer); 796 sta->manufacturer = os_malloc(attr->manufacturer_len + 1); 797 if (sta->manufacturer) { 798 os_memcpy(sta->manufacturer, attr->manufacturer, 799 attr->manufacturer_len); 800 sta->manufacturer[attr->manufacturer_len] = '\0'; 801 } 802 } 803 804 if (attr->model_name) { 805 os_free(sta->model_name); 806 sta->model_name = os_malloc(attr->model_name_len + 1); 807 if (sta->model_name) { 808 os_memcpy(sta->model_name, attr->model_name, 809 attr->model_name_len); 810 sta->model_name[attr->model_name_len] = '\0'; 811 } 812 } 813 814 if (attr->model_number) { 815 os_free(sta->model_number); 816 sta->model_number = os_malloc(attr->model_number_len + 1); 817 if (sta->model_number) { 818 os_memcpy(sta->model_number, attr->model_number, 819 attr->model_number_len); 820 sta->model_number[attr->model_number_len] = '\0'; 821 } 822 } 823 824 if (attr->serial_number) { 825 os_free(sta->serial_number); 826 sta->serial_number = os_malloc(attr->serial_number_len + 1); 827 if (sta->serial_number) { 828 os_memcpy(sta->serial_number, attr->serial_number, 829 attr->serial_number_len); 830 sta->serial_number[attr->serial_number_len] = '\0'; 831 } 832 } 833 834 if (attr->dev_name) { 835 os_free(sta->dev_name); 836 sta->dev_name = os_malloc(attr->dev_name_len + 1); 837 if (sta->dev_name) { 838 os_memcpy(sta->dev_name, attr->dev_name, 839 attr->dev_name_len); 840 sta->dev_name[attr->dev_name_len] = '\0'; 841 } 842 } 843 844 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL); 845 eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL); 846 847 if (m1 || new_sta) 848 wps_er_sta_event(ap->er->wps, sta, WPS_EV_ER_ENROLLEE_ADD); 849 850 return sta; 851 } 852 853 854 static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap, 855 const u8 *addr, 856 struct wpabuf *msg) 857 { 858 struct wps_parse_attr attr; 859 860 wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - Probe Request - from " 861 MACSTR, MAC2STR(addr)); 862 wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message " 863 "(TLVs from Probe Request)", msg); 864 865 if (wps_validate_probe_req(msg, addr) < 0) { 866 wpa_printf(MSG_INFO, "WPS-STRICT: ER: Ignore invalid proxied " 867 "Probe Request frame from " MACSTR, MAC2STR(addr)); 868 return; 869 } 870 871 if (wps_parse_msg(msg, &attr) < 0) { 872 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in " 873 "WLANEvent message"); 874 return; 875 } 876 877 wps_er_add_sta_data(ap, addr, &attr, 1); 878 wps_registrar_probe_req_rx(ap->er->wps->registrar, addr, msg, 0); 879 } 880 881 882 static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c, 883 enum http_client_event event) 884 { 885 struct wps_er_sta *sta = ctx; 886 887 switch (event) { 888 case HTTP_CLIENT_OK: 889 wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK"); 890 break; 891 case HTTP_CLIENT_FAILED: 892 case HTTP_CLIENT_INVALID_REPLY: 893 case HTTP_CLIENT_TIMEOUT: 894 wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed"); 895 break; 896 } 897 http_client_free(sta->http); 898 sta->http = NULL; 899 } 900 901 902 static const char *soap_prefix = 903 "<?xml version=\"1.0\"?>\n" 904 "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " 905 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" 906 "<s:Body>\n"; 907 static const char *soap_postfix = 908 "</s:Body>\n</s:Envelope>\n"; 909 static const char *urn_wfawlanconfig = 910 "urn:schemas-wifialliance-org:service:WFAWLANConfig:1"; 911 912 static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg, 913 const char *name, const char *arg_name, 914 const char *path, 915 const struct sockaddr_in *dst, 916 char **len_ptr, char **body_ptr) 917 { 918 unsigned char *encoded; 919 size_t encoded_len; 920 struct wpabuf *buf; 921 922 if (msg) { 923 encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg), 924 &encoded_len); 925 if (encoded == NULL) 926 return NULL; 927 } else { 928 encoded = NULL; 929 encoded_len = 0; 930 } 931 932 buf = wpabuf_alloc(1000 + encoded_len); 933 if (buf == NULL) { 934 os_free(encoded); 935 return NULL; 936 } 937 938 wpabuf_printf(buf, 939 "POST %s HTTP/1.1\r\n" 940 "Host: %s:%d\r\n" 941 "Content-Type: text/xml; charset=\"utf-8\"\r\n" 942 "Content-Length: ", 943 path, inet_ntoa(dst->sin_addr), ntohs(dst->sin_port)); 944 945 *len_ptr = wpabuf_put(buf, 0); 946 wpabuf_printf(buf, 947 " \r\n" 948 "SOAPACTION: \"%s#%s\"\r\n" 949 "\r\n", 950 urn_wfawlanconfig, name); 951 952 *body_ptr = wpabuf_put(buf, 0); 953 954 wpabuf_put_str(buf, soap_prefix); 955 wpabuf_printf(buf, "<u:%s xmlns:u=\"", name); 956 wpabuf_put_str(buf, urn_wfawlanconfig); 957 wpabuf_put_str(buf, "\">\n"); 958 if (encoded) { 959 wpabuf_printf(buf, "<%s>%s</%s>\n", 960 arg_name, (char *) encoded, arg_name); 961 os_free(encoded); 962 } 963 964 return buf; 965 } 966 967 968 static void wps_er_soap_end(struct wpabuf *buf, const char *name, 969 char *len_ptr, char *body_ptr) 970 { 971 char len_buf[10]; 972 wpabuf_printf(buf, "</u:%s>\n", name); 973 wpabuf_put_str(buf, soap_postfix); 974 os_snprintf(len_buf, sizeof(len_buf), "%d", 975 (int) ((char *) wpabuf_put(buf, 0) - body_ptr)); 976 os_memcpy(len_ptr, len_buf, os_strlen(len_buf)); 977 } 978 979 980 static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg) 981 { 982 struct wpabuf *buf; 983 char *len_ptr, *body_ptr; 984 struct sockaddr_in dst; 985 char *url, *path; 986 987 if (sta->http) { 988 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - " 989 "ignore new request"); 990 wpabuf_free(msg); 991 return; 992 } 993 994 if (sta->ap->control_url == NULL) { 995 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP"); 996 wpabuf_free(msg); 997 return; 998 } 999 1000 url = http_client_url_parse(sta->ap->control_url, &dst, &path); 1001 if (url == NULL) { 1002 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL"); 1003 wpabuf_free(msg); 1004 return; 1005 } 1006 1007 buf = wps_er_soap_hdr(msg, "PutWLANResponse", "NewMessage", path, &dst, 1008 &len_ptr, &body_ptr); 1009 wpabuf_free(msg); 1010 os_free(url); 1011 if (buf == NULL) 1012 return; 1013 wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n", 1014 UPNP_WPS_WLANEVENT_TYPE_EAP); 1015 wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n", 1016 MAC2STR(sta->addr)); 1017 1018 wps_er_soap_end(buf, "PutWLANResponse", len_ptr, body_ptr); 1019 1020 sta->http = http_client_addr(&dst, buf, 1000, 1021 wps_er_http_put_wlan_response_cb, sta); 1022 if (sta->http == NULL) 1023 wpabuf_free(buf); 1024 } 1025 1026 1027 static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg, 1028 enum wsc_op_code op_code) 1029 { 1030 enum wps_process_res res; 1031 1032 res = wps_process_msg(sta->wps, op_code, msg); 1033 if (res == WPS_CONTINUE) { 1034 struct wpabuf *next = wps_get_msg(sta->wps, &op_code); 1035 if (next) 1036 wps_er_sta_send_msg(sta, next); 1037 } else { 1038 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run %s with the " 1039 "enrollee (res=%d)", 1040 res == WPS_DONE ? "succeeded" : "failed", res); 1041 wps_deinit(sta->wps); 1042 sta->wps = NULL; 1043 if (res == WPS_DONE) { 1044 /* Remove the STA entry after short timeout */ 1045 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL); 1046 eloop_register_timeout(10, 0, wps_er_sta_timeout, sta, 1047 NULL); 1048 } 1049 } 1050 } 1051 1052 1053 static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg) 1054 { 1055 struct wps_config cfg; 1056 1057 if (sta->wps) 1058 wps_deinit(sta->wps); 1059 1060 os_memset(&cfg, 0, sizeof(cfg)); 1061 cfg.wps = sta->ap->er->wps; 1062 cfg.registrar = 1; 1063 cfg.peer_addr = sta->addr; 1064 1065 sta->wps = wps_init(&cfg); 1066 if (sta->wps == NULL) 1067 return; 1068 sta->wps->er = 1; 1069 sta->wps->use_cred = sta->ap->ap_settings; 1070 if (sta->ap->ap_settings) { 1071 os_free(sta->cred); 1072 sta->cred = os_malloc(sizeof(*sta->cred)); 1073 if (sta->cred) { 1074 os_memcpy(sta->cred, sta->ap->ap_settings, 1075 sizeof(*sta->cred)); 1076 sta->cred->cred_attr = NULL; 1077 os_memcpy(sta->cred->mac_addr, sta->addr, ETH_ALEN); 1078 sta->wps->use_cred = sta->cred; 1079 } 1080 } 1081 1082 wps_er_sta_process(sta, msg, WSC_MSG); 1083 } 1084 1085 1086 static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr, 1087 struct wpabuf *msg) 1088 { 1089 struct wps_parse_attr attr; 1090 struct wps_er_sta *sta; 1091 1092 wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR, 1093 MAC2STR(addr)); 1094 wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message " 1095 "(TLVs from EAP-WSC)", msg); 1096 1097 if (wps_parse_msg(msg, &attr) < 0) { 1098 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in " 1099 "WLANEvent message"); 1100 return; 1101 } 1102 1103 sta = wps_er_add_sta_data(ap, addr, &attr, 0); 1104 if (sta == NULL) 1105 return; 1106 1107 if (attr.msg_type && *attr.msg_type == WPS_M1) 1108 wps_er_sta_start(sta, msg); 1109 else if (sta->wps) { 1110 enum wsc_op_code op_code = WSC_MSG; 1111 if (attr.msg_type) { 1112 switch (*attr.msg_type) { 1113 case WPS_WSC_ACK: 1114 op_code = WSC_ACK; 1115 break; 1116 case WPS_WSC_NACK: 1117 op_code = WSC_NACK; 1118 break; 1119 case WPS_WSC_DONE: 1120 op_code = WSC_Done; 1121 break; 1122 } 1123 } 1124 wps_er_sta_process(sta, msg, op_code); 1125 } 1126 } 1127 1128 1129 static void wps_er_process_wlanevent(struct wps_er_ap *ap, 1130 struct wpabuf *event) 1131 { 1132 u8 *data; 1133 u8 wlan_event_type; 1134 u8 wlan_event_mac[ETH_ALEN]; 1135 struct wpabuf msg; 1136 1137 wpa_hexdump(MSG_MSGDUMP, "WPS ER: Received WLANEvent", 1138 wpabuf_head(event), wpabuf_len(event)); 1139 if (wpabuf_len(event) < 1 + 17) { 1140 wpa_printf(MSG_DEBUG, "WPS ER: Too short WLANEvent"); 1141 return; 1142 } 1143 1144 data = wpabuf_mhead(event); 1145 wlan_event_type = data[0]; 1146 if (hwaddr_aton((char *) data + 1, wlan_event_mac) < 0) { 1147 wpa_printf(MSG_DEBUG, "WPS ER: Invalid WLANEventMAC in " 1148 "WLANEvent"); 1149 return; 1150 } 1151 1152 wpabuf_set(&msg, data + 1 + 17, wpabuf_len(event) - (1 + 17)); 1153 1154 switch (wlan_event_type) { 1155 case 1: 1156 wps_er_process_wlanevent_probe_req(ap, wlan_event_mac, &msg); 1157 break; 1158 case 2: 1159 wps_er_process_wlanevent_eap(ap, wlan_event_mac, &msg); 1160 break; 1161 default: 1162 wpa_printf(MSG_DEBUG, "WPS ER: Unknown WLANEventType %d", 1163 wlan_event_type); 1164 break; 1165 } 1166 } 1167 1168 1169 static void wps_er_http_event(struct wps_er *er, struct http_request *req, 1170 unsigned int ap_id) 1171 { 1172 struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id); 1173 struct wpabuf *event; 1174 enum http_reply_code ret; 1175 1176 if (ap == NULL) { 1177 wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id " 1178 "%u", ap_id); 1179 wps_er_http_resp_not_found(req); 1180 return; 1181 } 1182 wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s", 1183 ap_id, http_request_get_data(req)); 1184 1185 event = xml_get_base64_item(http_request_get_data(req), "WLANEvent", 1186 &ret); 1187 if (event == NULL) { 1188 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent " 1189 "from the event notification"); 1190 /* 1191 * Reply with OK anyway to avoid getting unregistered from 1192 * events. 1193 */ 1194 wps_er_http_resp_ok(req); 1195 return; 1196 } 1197 1198 wps_er_process_wlanevent(ap, event); 1199 1200 wpabuf_free(event); 1201 wps_er_http_resp_ok(req); 1202 } 1203 1204 1205 static void wps_er_http_notify(struct wps_er *er, struct http_request *req) 1206 { 1207 char *uri = http_request_get_uri(req); 1208 1209 if (os_strncmp(uri, "/event/", 7) == 0) { 1210 unsigned int event_id; 1211 char *pos; 1212 event_id = atoi(uri + 7); 1213 if (event_id != er->event_id) { 1214 wpa_printf(MSG_DEBUG, "WPS ER: HTTP event for an " 1215 "unknown event id %u", event_id); 1216 return; 1217 } 1218 pos = os_strchr(uri + 7, '/'); 1219 if (pos == NULL) 1220 return; 1221 pos++; 1222 wps_er_http_event(er, req, atoi(pos)); 1223 } else { 1224 wpa_printf(MSG_DEBUG, "WPS ER: Unknown HTTP NOTIFY for '%s'", 1225 uri); 1226 wps_er_http_resp_not_found(req); 1227 } 1228 } 1229 1230 1231 static void wps_er_http_req(void *ctx, struct http_request *req) 1232 { 1233 struct wps_er *er = ctx; 1234 struct sockaddr_in *cli = http_request_get_cli_addr(req); 1235 enum httpread_hdr_type type = http_request_get_type(req); 1236 struct wpabuf *buf; 1237 1238 wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from " 1239 "%s:%d", 1240 http_request_get_uri(req), type, 1241 inet_ntoa(cli->sin_addr), ntohs(cli->sin_port)); 1242 1243 switch (type) { 1244 case HTTPREAD_HDR_TYPE_NOTIFY: 1245 wps_er_http_notify(er, req); 1246 break; 1247 default: 1248 wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type " 1249 "%d", type); 1250 buf = wpabuf_alloc(200); 1251 if (buf == NULL) { 1252 http_request_deinit(req); 1253 return; 1254 } 1255 wpabuf_put_str(buf, 1256 "HTTP/1.1 501 Unimplemented\r\n" 1257 "Connection: close\r\n"); 1258 http_put_date(buf); 1259 wpabuf_put_str(buf, "\r\n"); 1260 http_request_send_and_deinit(req, buf); 1261 break; 1262 } 1263 } 1264 1265 1266 struct wps_er * 1267 wps_er_init(struct wps_context *wps, const char *ifname, const char *filter) 1268 { 1269 struct wps_er *er; 1270 struct in_addr addr; 1271 1272 er = os_zalloc(sizeof(*er)); 1273 if (er == NULL) 1274 return NULL; 1275 dl_list_init(&er->ap); 1276 dl_list_init(&er->ap_unsubscribing); 1277 dl_list_init(&er->ap_settings); 1278 1279 er->multicast_sd = -1; 1280 er->ssdp_sd = -1; 1281 1282 os_strlcpy(er->ifname, ifname, sizeof(er->ifname)); 1283 er->wps = wps; 1284 if (os_get_random((unsigned char *) &er->event_id, 1285 sizeof(er->event_id)) < 0) { 1286 wps_er_deinit(er, NULL, NULL); 1287 return NULL; 1288 } 1289 /* Limit event_id to < 32 bits to avoid issues with atoi() */ 1290 er->event_id &= 0x0fffffff; 1291 1292 if (filter) { 1293 if (inet_aton(filter, &er->filter_addr) == 0) { 1294 wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter " 1295 "address %s", filter); 1296 wps_er_deinit(er, NULL, NULL); 1297 return NULL; 1298 } 1299 wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections " 1300 "with %s", filter); 1301 } 1302 if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text, 1303 er->mac_addr)) { 1304 wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " 1305 "for %s. Does it have IP address?", ifname); 1306 wps_er_deinit(er, NULL, NULL); 1307 return NULL; 1308 } 1309 1310 if (wps_er_ssdp_init(er) < 0) { 1311 wpa_printf(MSG_INFO, "WPS UPnP: SSDP initialization failed"); 1312 wps_er_deinit(er, NULL, NULL); 1313 return NULL; 1314 } 1315 1316 addr.s_addr = er->ip_addr; 1317 er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er); 1318 if (er->http_srv == NULL) { 1319 wpa_printf(MSG_INFO, "WPS UPnP: HTTP initialization failed"); 1320 wps_er_deinit(er, NULL, NULL); 1321 return NULL; 1322 } 1323 er->http_port = http_server_get_port(er->http_srv); 1324 1325 wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s)", 1326 er->ifname, er->ip_addr_text); 1327 1328 return er; 1329 } 1330 1331 1332 void wps_er_refresh(struct wps_er *er) 1333 { 1334 struct wps_er_ap *ap; 1335 struct wps_er_sta *sta; 1336 1337 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 1338 wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_ADD); 1339 dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list) 1340 wps_er_sta_event(er->wps, sta, WPS_EV_ER_ENROLLEE_ADD); 1341 } 1342 1343 wps_er_send_ssdp_msearch(er); 1344 } 1345 1346 1347 static void wps_er_deinit_finish(void *eloop_data, void *user_ctx) 1348 { 1349 struct wps_er *er = eloop_data; 1350 void (*deinit_done_cb)(void *ctx); 1351 void *deinit_done_ctx; 1352 1353 wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit"); 1354 1355 deinit_done_cb = er->deinit_done_cb; 1356 deinit_done_ctx = er->deinit_done_ctx; 1357 os_free(er->ip_addr_text); 1358 os_free(er); 1359 1360 if (deinit_done_cb) 1361 deinit_done_cb(deinit_done_ctx); 1362 } 1363 1364 1365 void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx) 1366 { 1367 if (er == NULL) 1368 return; 1369 http_server_deinit(er->http_srv); 1370 wps_er_ap_remove_all(er); 1371 wps_er_ssdp_deinit(er); 1372 eloop_register_timeout(dl_list_empty(&er->ap_unsubscribing) ? 0 : 5, 0, 1373 wps_er_deinit_finish, er, NULL); 1374 wpa_printf(MSG_DEBUG, "WPS ER: Finish deinit from timeout"); 1375 er->deinitializing = 1; 1376 er->deinit_done_cb = cb; 1377 er->deinit_done_ctx = ctx; 1378 } 1379 1380 1381 static void wps_er_http_set_sel_reg_cb(void *ctx, struct http_client *c, 1382 enum http_client_event event) 1383 { 1384 struct wps_er_ap *ap = ctx; 1385 union wps_event_data data; 1386 1387 os_memset(&data, 0, sizeof(data)); 1388 1389 switch (event) { 1390 case HTTP_CLIENT_OK: 1391 wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar OK"); 1392 data.set_sel_reg.state = WPS_ER_SET_SEL_REG_DONE; 1393 data.set_sel_reg.uuid = ap->uuid; 1394 break; 1395 case HTTP_CLIENT_FAILED: 1396 case HTTP_CLIENT_INVALID_REPLY: 1397 case HTTP_CLIENT_TIMEOUT: 1398 wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar failed"); 1399 data.set_sel_reg.state = WPS_ER_SET_SEL_REG_FAILED; 1400 data.set_sel_reg.uuid = ap->uuid; 1401 break; 1402 } 1403 http_client_free(ap->http); 1404 ap->http = NULL; 1405 1406 if (data.set_sel_reg.uuid) 1407 ap->er->wps->event_cb(ap->er->wps->cb_ctx, 1408 WPS_EV_ER_SET_SELECTED_REGISTRAR, &data); 1409 } 1410 1411 1412 static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg) 1413 { 1414 struct wpabuf *buf; 1415 char *len_ptr, *body_ptr; 1416 struct sockaddr_in dst; 1417 char *url, *path; 1418 1419 if (ap->control_url == NULL) { 1420 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP"); 1421 return; 1422 } 1423 1424 if (ap->http) { 1425 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - " 1426 "ignore new request"); 1427 return; 1428 } 1429 1430 if (ap->wps) { 1431 wpa_printf(MSG_DEBUG, "WPS ER: Pending WPS operation for AP - " 1432 "skip SetSelectedRegistrar"); 1433 return; 1434 } 1435 1436 url = http_client_url_parse(ap->control_url, &dst, &path); 1437 if (url == NULL) { 1438 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL"); 1439 return; 1440 } 1441 1442 buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", "NewMessage", path, 1443 &dst, &len_ptr, &body_ptr); 1444 os_free(url); 1445 if (buf == NULL) 1446 return; 1447 1448 wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr); 1449 1450 ap->http = http_client_addr(&dst, buf, 1000, 1451 wps_er_http_set_sel_reg_cb, ap); 1452 if (ap->http == NULL) 1453 wpabuf_free(buf); 1454 } 1455 1456 1457 static int wps_er_build_selected_registrar(struct wpabuf *msg, int sel_reg) 1458 { 1459 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR); 1460 wpabuf_put_be16(msg, 1); 1461 wpabuf_put_u8(msg, !!sel_reg); 1462 return 0; 1463 } 1464 1465 1466 static int wps_er_build_dev_password_id(struct wpabuf *msg, u16 dev_passwd_id) 1467 { 1468 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID); 1469 wpabuf_put_be16(msg, 2); 1470 wpabuf_put_be16(msg, dev_passwd_id); 1471 return 0; 1472 } 1473 1474 1475 static int wps_er_build_sel_reg_config_methods(struct wpabuf *msg, 1476 u16 sel_reg_config_methods) 1477 { 1478 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS); 1479 wpabuf_put_be16(msg, 2); 1480 wpabuf_put_be16(msg, sel_reg_config_methods); 1481 return 0; 1482 } 1483 1484 1485 static int wps_er_build_uuid_r(struct wpabuf *msg, const u8 *uuid_r) 1486 { 1487 #ifdef CONFIG_WPS2 1488 wpabuf_put_be16(msg, ATTR_UUID_R); 1489 wpabuf_put_be16(msg, WPS_UUID_LEN); 1490 wpabuf_put_data(msg, uuid_r, WPS_UUID_LEN); 1491 #endif /* CONFIG_WPS2 */ 1492 return 0; 1493 } 1494 1495 1496 void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id, 1497 u16 sel_reg_config_methods) 1498 { 1499 struct wpabuf *msg; 1500 struct wps_er_ap *ap; 1501 struct wps_registrar *reg = er->wps->registrar; 1502 const u8 *auth_macs; 1503 #ifdef CONFIG_WPS2 1504 u8 bcast[ETH_ALEN]; 1505 #endif /* CONFIG_WPS2 */ 1506 size_t count; 1507 union wps_event_data data; 1508 1509 if (er->skip_set_sel_reg) { 1510 wpa_printf(MSG_DEBUG, "WPS ER: Skip SetSelectedRegistrar"); 1511 return; 1512 } 1513 1514 msg = wpabuf_alloc(500); 1515 if (msg == NULL) 1516 return; 1517 1518 auth_macs = wps_authorized_macs(reg, &count); 1519 #ifdef CONFIG_WPS2 1520 if (count == 0) { 1521 os_memset(bcast, 0xff, ETH_ALEN); 1522 auth_macs = bcast; 1523 count = 1; 1524 } 1525 #endif /* CONFIG_WPS2 */ 1526 1527 if (wps_build_version(msg) || 1528 wps_er_build_selected_registrar(msg, sel_reg) || 1529 wps_er_build_dev_password_id(msg, dev_passwd_id) || 1530 wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) || 1531 wps_build_wfa_ext(msg, 0, auth_macs, count) || 1532 wps_er_build_uuid_r(msg, er->wps->uuid)) { 1533 wpabuf_free(msg); 1534 return; 1535 } 1536 1537 os_memset(&data, 0, sizeof(data)); 1538 data.set_sel_reg.sel_reg = sel_reg; 1539 data.set_sel_reg.dev_passwd_id = dev_passwd_id; 1540 data.set_sel_reg.sel_reg_config_methods = sel_reg_config_methods; 1541 data.set_sel_reg.state = WPS_ER_SET_SEL_REG_START; 1542 1543 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 1544 if (er->set_sel_reg_uuid_filter && 1545 os_memcmp(ap->uuid, er->set_sel_reg_uuid_filter, 1546 WPS_UUID_LEN) != 0) 1547 continue; 1548 data.set_sel_reg.uuid = ap->uuid; 1549 er->wps->event_cb(er->wps->cb_ctx, 1550 WPS_EV_ER_SET_SELECTED_REGISTRAR, &data); 1551 wps_er_send_set_sel_reg(ap, msg); 1552 } 1553 1554 wpabuf_free(msg); 1555 } 1556 1557 1558 int wps_er_pbc(struct wps_er *er, const u8 *uuid) 1559 { 1560 int res; 1561 struct wps_er_ap *ap; 1562 1563 if (er == NULL || er->wps == NULL) 1564 return -1; 1565 1566 if (wps_registrar_pbc_overlap(er->wps->registrar, NULL, NULL)) { 1567 wpa_printf(MSG_DEBUG, "WPS ER: PBC overlap - do not start PBC " 1568 "mode"); 1569 return -2; 1570 } 1571 1572 ap = wps_er_ap_get(er, NULL, uuid); 1573 if (ap == NULL) { 1574 struct wps_er_sta *sta = NULL; 1575 dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) { 1576 sta = wps_er_sta_get(ap, NULL, uuid); 1577 if (sta) { 1578 uuid = ap->uuid; 1579 break; 1580 } 1581 } 1582 if (sta == NULL) 1583 return -3; /* Unknown UUID */ 1584 } 1585 1586 if (ap->ap_settings == NULL) { 1587 wpa_printf(MSG_DEBUG, "WPS ER: AP settings not known"); 1588 return -4; 1589 } 1590 1591 er->set_sel_reg_uuid_filter = uuid; 1592 res = wps_registrar_button_pushed(er->wps->registrar, NULL); 1593 er->set_sel_reg_uuid_filter = NULL; 1594 if (res) 1595 return -1; 1596 1597 return 0; 1598 } 1599 1600 1601 static void wps_er_ap_settings_cb(void *ctx, const struct wps_credential *cred) 1602 { 1603 struct wps_er_ap *ap = ctx; 1604 union wps_event_data data; 1605 1606 wpa_printf(MSG_DEBUG, "WPS ER: AP Settings received"); 1607 os_free(ap->ap_settings); 1608 ap->ap_settings = os_malloc(sizeof(*cred)); 1609 if (ap->ap_settings) { 1610 os_memcpy(ap->ap_settings, cred, sizeof(*cred)); 1611 ap->ap_settings->cred_attr = NULL; 1612 } 1613 1614 os_memset(&data, 0, sizeof(data)); 1615 data.ap_settings.uuid = ap->uuid; 1616 data.ap_settings.cred = cred; 1617 ap->er->wps->event_cb(ap->er->wps->cb_ctx, WPS_EV_ER_AP_SETTINGS, 1618 &data); 1619 } 1620 1621 1622 static void wps_er_http_put_message_cb(void *ctx, struct http_client *c, 1623 enum http_client_event event) 1624 { 1625 struct wps_er_ap *ap = ctx; 1626 struct wpabuf *reply; 1627 char *msg = NULL; 1628 1629 switch (event) { 1630 case HTTP_CLIENT_OK: 1631 wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK"); 1632 reply = http_client_get_body(c); 1633 if (reply == NULL) 1634 break; 1635 msg = os_zalloc(wpabuf_len(reply) + 1); 1636 if (msg == NULL) 1637 break; 1638 os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply)); 1639 break; 1640 case HTTP_CLIENT_FAILED: 1641 case HTTP_CLIENT_INVALID_REPLY: 1642 case HTTP_CLIENT_TIMEOUT: 1643 wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed"); 1644 if (ap->wps) { 1645 wps_deinit(ap->wps); 1646 ap->wps = NULL; 1647 } 1648 break; 1649 } 1650 http_client_free(ap->http); 1651 ap->http = NULL; 1652 1653 if (msg) { 1654 struct wpabuf *buf; 1655 enum http_reply_code ret; 1656 buf = xml_get_base64_item(msg, "NewOutMessage", &ret); 1657 os_free(msg); 1658 if (buf == NULL) { 1659 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract " 1660 "NewOutMessage from PutMessage response"); 1661 wps_deinit(ap->wps); 1662 ap->wps = NULL; 1663 return; 1664 } 1665 wps_er_ap_process(ap, buf); 1666 wpabuf_free(buf); 1667 } 1668 } 1669 1670 1671 static void wps_er_ap_put_message(struct wps_er_ap *ap, 1672 const struct wpabuf *msg) 1673 { 1674 struct wpabuf *buf; 1675 char *len_ptr, *body_ptr; 1676 struct sockaddr_in dst; 1677 char *url, *path; 1678 1679 if (ap->http) { 1680 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing " 1681 "with the AP - cannot continue learn"); 1682 return; 1683 } 1684 1685 if (ap->control_url == NULL) { 1686 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP"); 1687 return; 1688 } 1689 1690 url = http_client_url_parse(ap->control_url, &dst, &path); 1691 if (url == NULL) { 1692 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL"); 1693 return; 1694 } 1695 1696 buf = wps_er_soap_hdr(msg, "PutMessage", "NewInMessage", path, &dst, 1697 &len_ptr, &body_ptr); 1698 os_free(url); 1699 if (buf == NULL) 1700 return; 1701 1702 wps_er_soap_end(buf, "PutMessage", len_ptr, body_ptr); 1703 1704 ap->http = http_client_addr(&dst, buf, 10000, 1705 wps_er_http_put_message_cb, ap); 1706 if (ap->http == NULL) 1707 wpabuf_free(buf); 1708 } 1709 1710 1711 static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg) 1712 { 1713 enum wps_process_res res; 1714 struct wps_parse_attr attr; 1715 enum wsc_op_code op_code; 1716 1717 op_code = WSC_MSG; 1718 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) { 1719 switch (*attr.msg_type) { 1720 case WPS_WSC_ACK: 1721 op_code = WSC_ACK; 1722 break; 1723 case WPS_WSC_NACK: 1724 op_code = WSC_NACK; 1725 break; 1726 case WPS_WSC_DONE: 1727 op_code = WSC_Done; 1728 break; 1729 } 1730 } 1731 1732 res = wps_process_msg(ap->wps, op_code, msg); 1733 if (res == WPS_CONTINUE) { 1734 struct wpabuf *next = wps_get_msg(ap->wps, &op_code); 1735 if (next) { 1736 wps_er_ap_put_message(ap, next); 1737 wpabuf_free(next); 1738 } else { 1739 wpa_printf(MSG_DEBUG, "WPS ER: Failed to build " 1740 "message"); 1741 wps_deinit(ap->wps); 1742 ap->wps = NULL; 1743 } 1744 } else if (res == WPS_DONE) { 1745 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run done"); 1746 wps_deinit(ap->wps); 1747 ap->wps = NULL; 1748 } else { 1749 wpa_printf(MSG_DEBUG, "WPS ER: Failed to process message from " 1750 "AP (res=%d)", res); 1751 wps_deinit(ap->wps); 1752 ap->wps = NULL; 1753 } 1754 } 1755 1756 1757 static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1) 1758 { 1759 struct wps_config cfg; 1760 1761 if (ap->wps) { 1762 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in " 1763 "progress with this AP"); 1764 return; 1765 } 1766 1767 os_memset(&cfg, 0, sizeof(cfg)); 1768 cfg.wps = ap->er->wps; 1769 cfg.registrar = 1; 1770 ap->wps = wps_init(&cfg); 1771 if (ap->wps == NULL) 1772 return; 1773 ap->wps->ap_settings_cb = wps_er_ap_settings_cb; 1774 ap->wps->ap_settings_cb_ctx = ap; 1775 1776 wps_er_ap_process(ap, m1); 1777 } 1778 1779 1780 static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info) 1781 { 1782 struct wpabuf *info; 1783 enum http_reply_code ret; 1784 1785 wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) " 1786 "from the AP"); 1787 info = xml_get_base64_item(dev_info, "NewDeviceInfo", &ret); 1788 if (info == NULL) { 1789 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract " 1790 "NewDeviceInfo from GetDeviceInfo response"); 1791 return; 1792 } 1793 1794 ap->m1_handler(ap, info); 1795 wpabuf_free(info); 1796 } 1797 1798 1799 static void wps_er_http_get_dev_info_cb(void *ctx, struct http_client *c, 1800 enum http_client_event event) 1801 { 1802 struct wps_er_ap *ap = ctx; 1803 struct wpabuf *reply; 1804 char *dev_info = NULL; 1805 1806 switch (event) { 1807 case HTTP_CLIENT_OK: 1808 wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo OK"); 1809 reply = http_client_get_body(c); 1810 if (reply == NULL) 1811 break; 1812 dev_info = os_zalloc(wpabuf_len(reply) + 1); 1813 if (dev_info == NULL) 1814 break; 1815 os_memcpy(dev_info, wpabuf_head(reply), wpabuf_len(reply)); 1816 break; 1817 case HTTP_CLIENT_FAILED: 1818 case HTTP_CLIENT_INVALID_REPLY: 1819 case HTTP_CLIENT_TIMEOUT: 1820 wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo failed"); 1821 break; 1822 } 1823 http_client_free(ap->http); 1824 ap->http = NULL; 1825 1826 if (dev_info) { 1827 wps_er_ap_learn(ap, dev_info); 1828 os_free(dev_info); 1829 } 1830 } 1831 1832 1833 static int wps_er_send_get_device_info(struct wps_er_ap *ap, 1834 void (*m1_handler)(struct wps_er_ap *ap, 1835 struct wpabuf *m1)) 1836 { 1837 struct wpabuf *buf; 1838 char *len_ptr, *body_ptr; 1839 struct sockaddr_in dst; 1840 char *url, *path; 1841 1842 if (ap->http) { 1843 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing " 1844 "with the AP - cannot get device info"); 1845 return -1; 1846 } 1847 1848 if (ap->control_url == NULL) { 1849 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP"); 1850 return -1; 1851 } 1852 1853 url = http_client_url_parse(ap->control_url, &dst, &path); 1854 if (url == NULL) { 1855 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL"); 1856 return -1; 1857 } 1858 1859 buf = wps_er_soap_hdr(NULL, "GetDeviceInfo", NULL, path, &dst, 1860 &len_ptr, &body_ptr); 1861 os_free(url); 1862 if (buf == NULL) 1863 return -1; 1864 1865 wps_er_soap_end(buf, "GetDeviceInfo", len_ptr, body_ptr); 1866 1867 ap->http = http_client_addr(&dst, buf, 10000, 1868 wps_er_http_get_dev_info_cb, ap); 1869 if (ap->http == NULL) { 1870 wpabuf_free(buf); 1871 return -1; 1872 } 1873 1874 ap->m1_handler = m1_handler; 1875 1876 return 0; 1877 } 1878 1879 1880 int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin, 1881 size_t pin_len) 1882 { 1883 struct wps_er_ap *ap; 1884 1885 if (er == NULL) 1886 return -1; 1887 1888 ap = wps_er_ap_get(er, NULL, uuid); 1889 if (ap == NULL) { 1890 wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn " 1891 "request"); 1892 return -1; 1893 } 1894 if (ap->wps) { 1895 wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing " 1896 "with the AP - cannot start learn"); 1897 return -1; 1898 } 1899 1900 if (wps_er_send_get_device_info(ap, wps_er_ap_learn_m1) < 0) 1901 return -1; 1902 1903 er->skip_set_sel_reg = 1; 1904 wps_registrar_add_pin(er->wps->registrar, NULL, uuid, pin, pin_len, 0); 1905 er->skip_set_sel_reg = 0; 1906 1907 return 0; 1908 } 1909 1910 1911 int wps_er_set_config(struct wps_er *er, const u8 *uuid, 1912 const struct wps_credential *cred) 1913 { 1914 struct wps_er_ap *ap; 1915 1916 if (er == NULL) 1917 return -1; 1918 1919 ap = wps_er_ap_get(er, NULL, uuid); 1920 if (ap == NULL) { 1921 wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config " 1922 "request"); 1923 return -1; 1924 } 1925 1926 os_free(ap->ap_settings); 1927 ap->ap_settings = os_malloc(sizeof(*cred)); 1928 if (ap->ap_settings == NULL) 1929 return -1; 1930 os_memcpy(ap->ap_settings, cred, sizeof(*cred)); 1931 ap->ap_settings->cred_attr = NULL; 1932 wpa_printf(MSG_DEBUG, "WPS ER: Updated local AP settings based set " 1933 "config request"); 1934 1935 return 0; 1936 } 1937 1938 1939 static void wps_er_ap_config_m1(struct wps_er_ap *ap, struct wpabuf *m1) 1940 { 1941 struct wps_config cfg; 1942 1943 if (ap->wps) { 1944 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in " 1945 "progress with this AP"); 1946 return; 1947 } 1948 1949 os_memset(&cfg, 0, sizeof(cfg)); 1950 cfg.wps = ap->er->wps; 1951 cfg.registrar = 1; 1952 cfg.new_ap_settings = ap->ap_settings; 1953 ap->wps = wps_init(&cfg); 1954 if (ap->wps == NULL) 1955 return; 1956 ap->wps->ap_settings_cb = NULL; 1957 ap->wps->ap_settings_cb_ctx = NULL; 1958 1959 wps_er_ap_process(ap, m1); 1960 } 1961 1962 1963 int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin, 1964 size_t pin_len, const struct wps_credential *cred) 1965 { 1966 struct wps_er_ap *ap; 1967 1968 if (er == NULL) 1969 return -1; 1970 1971 ap = wps_er_ap_get(er, NULL, uuid); 1972 if (ap == NULL) { 1973 wpa_printf(MSG_DEBUG, "WPS ER: AP not found for config " 1974 "request"); 1975 return -1; 1976 } 1977 if (ap->wps) { 1978 wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing " 1979 "with the AP - cannot start config"); 1980 return -1; 1981 } 1982 1983 os_free(ap->ap_settings); 1984 ap->ap_settings = os_malloc(sizeof(*cred)); 1985 if (ap->ap_settings == NULL) 1986 return -1; 1987 os_memcpy(ap->ap_settings, cred, sizeof(*cred)); 1988 ap->ap_settings->cred_attr = NULL; 1989 1990 if (wps_er_send_get_device_info(ap, wps_er_ap_config_m1) < 0) 1991 return -1; 1992 1993 er->skip_set_sel_reg = 1; 1994 wps_registrar_add_pin(er->wps->registrar, NULL, uuid, pin, pin_len, 0); 1995 er->skip_set_sel_reg = 0; 1996 1997 return 0; 1998 } 1999 2000 2001 #ifdef CONFIG_WPS_NFC 2002 struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid) 2003 { 2004 struct wps_er_ap *ap; 2005 struct wpabuf *ret; 2006 struct wps_data data; 2007 2008 if (er == NULL) 2009 return NULL; 2010 2011 ap = wps_er_ap_get(er, NULL, uuid); 2012 if (ap == NULL) 2013 return NULL; 2014 if (ap->ap_settings == NULL) { 2015 wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the " 2016 "selected AP"); 2017 return NULL; 2018 } 2019 2020 ret = wpabuf_alloc(500); 2021 if (ret == NULL) 2022 return NULL; 2023 2024 os_memset(&data, 0, sizeof(data)); 2025 data.wps = er->wps; 2026 data.use_cred = ap->ap_settings; 2027 if (wps_build_version(ret) || 2028 wps_build_cred(&data, ret) || 2029 wps_build_wfa_ext(ret, 0, NULL, 0)) { 2030 wpabuf_free(ret); 2031 return NULL; 2032 } 2033 2034 return ret; 2035 } 2036 #endif /* CONFIG_WPS_NFC */ 2037