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