00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "base64.h"
00020 #include "uuid.h"
00021 #include "eloop.h"
00022 #include "httpread.h"
00023 #include "http_client.h"
00024 #include "http_server.h"
00025 #include "upnp_xml.h"
00026 #include "wps_i.h"
00027 #include "wps_upnp.h"
00028 #include "wps_upnp_i.h"
00029 #include "wps_er.h"
00030
00031
00032 static void wps_er_ap_timeout(void *eloop_data, void *user_ctx);
00033 static void wps_er_sta_timeout(void *eloop_data, void *user_ctx);
00034 static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg);
00035 static int wps_er_send_get_device_info(struct wps_er_ap *ap,
00036 void (*m1_handler)(struct wps_er_ap *ap,
00037 struct wpabuf *m1));
00038
00039
00040 static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
00041 enum wps_event event)
00042 {
00043 union wps_event_data data;
00044 struct wps_event_er_enrollee *ev = &data.enrollee;
00045
00046 if (wps->event_cb == NULL)
00047 return;
00048
00049 os_memset(&data, 0, sizeof(data));
00050 ev->uuid = sta->uuid;
00051 ev->mac_addr = sta->addr;
00052 ev->m1_received = sta->m1_received;
00053 ev->config_methods = sta->config_methods;
00054 ev->dev_passwd_id = sta->dev_passwd_id;
00055 ev->pri_dev_type = sta->pri_dev_type;
00056 ev->dev_name = sta->dev_name;
00057 ev->manufacturer = sta->manufacturer;
00058 ev->model_name = sta->model_name;
00059 ev->model_number = sta->model_number;
00060 ev->serial_number = sta->serial_number;
00061 wps->event_cb(wps->cb_ctx, event, &data);
00062 }
00063
00064
00065 static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
00066 {
00067 struct wps_er_sta *sta = ap->sta;
00068 while (sta) {
00069 if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
00070 return sta;
00071 sta = sta->next;
00072 }
00073 return NULL;
00074 }
00075
00076
00077 static void wps_er_sta_free(struct wps_er_sta *sta)
00078 {
00079 wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE);
00080 if (sta->wps)
00081 wps_deinit(sta->wps);
00082 os_free(sta->manufacturer);
00083 os_free(sta->model_name);
00084 os_free(sta->model_number);
00085 os_free(sta->serial_number);
00086 os_free(sta->dev_name);
00087 http_client_free(sta->http);
00088 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
00089 os_free(sta);
00090 }
00091
00092
00093 static void wps_er_sta_unlink(struct wps_er_sta *sta)
00094 {
00095 struct wps_er_sta *prev, *tmp;
00096 struct wps_er_ap *ap = sta->ap;
00097 tmp = ap->sta;
00098 prev = NULL;
00099 while (tmp) {
00100 if (tmp == sta) {
00101 if (prev)
00102 prev->next = sta->next;
00103 else
00104 ap->sta = sta->next;
00105 return;
00106 }
00107 prev = tmp;
00108 tmp = tmp->next;
00109 }
00110 }
00111
00112
00113 static void wps_er_sta_remove_all(struct wps_er_ap *ap)
00114 {
00115 struct wps_er_sta *prev, *sta;
00116
00117 sta = ap->sta;
00118 ap->sta = NULL;
00119
00120 while (sta) {
00121 prev = sta;
00122 sta = sta->next;
00123 wps_er_sta_free(prev);
00124 }
00125 }
00126
00127
00128 static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
00129 struct in_addr *addr, const u8 *uuid)
00130 {
00131 struct wps_er_ap *ap;
00132 for (ap = er->ap; ap; ap = ap->next) {
00133 if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
00134 (uuid == NULL ||
00135 os_memcmp(uuid, ap->uuid, WPS_UUID_LEN) == 0))
00136 break;
00137 }
00138 return ap;
00139 }
00140
00141
00142 static struct wps_er_ap * wps_er_ap_get_id(struct wps_er *er, unsigned int id)
00143 {
00144 struct wps_er_ap *ap;
00145 for (ap = er->ap; ap; ap = ap->next) {
00146 if (ap->id == id)
00147 break;
00148 }
00149 return ap;
00150 }
00151
00152
00153 static void wps_er_ap_event(struct wps_context *wps, struct wps_er_ap *ap,
00154 enum wps_event event)
00155 {
00156 union wps_event_data data;
00157 struct wps_event_er_ap *evap = &data.ap;
00158
00159 if (wps->event_cb == NULL)
00160 return;
00161
00162 os_memset(&data, 0, sizeof(data));
00163 evap->uuid = ap->uuid;
00164 evap->friendly_name = ap->friendly_name;
00165 evap->manufacturer = ap->manufacturer;
00166 evap->manufacturer_url = ap->manufacturer_url;
00167 evap->model_description = ap->model_description;
00168 evap->model_name = ap->model_name;
00169 evap->model_number = ap->model_number;
00170 evap->model_url = ap->model_url;
00171 evap->serial_number = ap->serial_number;
00172 evap->upc = ap->upc;
00173 evap->pri_dev_type = ap->pri_dev_type;
00174 evap->wps_state = ap->wps_state;
00175 evap->mac_addr = ap->mac_addr;
00176 wps->event_cb(wps->cb_ctx, event, &data);
00177 }
00178
00179
00180 static void wps_er_ap_free(struct wps_er *er, struct wps_er_ap *ap)
00181 {
00182
00183
00184 wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)",
00185 inet_ntoa(ap->addr), ap->location);
00186 eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
00187 wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE);
00188 os_free(ap->location);
00189 http_client_free(ap->http);
00190 if (ap->wps)
00191 wps_deinit(ap->wps);
00192
00193 os_free(ap->friendly_name);
00194 os_free(ap->manufacturer);
00195 os_free(ap->manufacturer_url);
00196 os_free(ap->model_description);
00197 os_free(ap->model_name);
00198 os_free(ap->model_number);
00199 os_free(ap->model_url);
00200 os_free(ap->serial_number);
00201 os_free(ap->udn);
00202 os_free(ap->upc);
00203
00204 os_free(ap->scpd_url);
00205 os_free(ap->control_url);
00206 os_free(ap->event_sub_url);
00207
00208 os_free(ap->ap_settings);
00209
00210 wps_er_sta_remove_all(ap);
00211
00212 os_free(ap);
00213 }
00214
00215
00216 static void wps_er_ap_unlink(struct wps_er *er, struct wps_er_ap *ap)
00217 {
00218 struct wps_er_ap *prev, *tmp;
00219 tmp = er->ap;
00220 prev = NULL;
00221 while (tmp) {
00222 if (tmp == ap) {
00223 if (prev)
00224 prev->next = ap->next;
00225 else
00226 er->ap = ap->next;
00227 return;
00228 }
00229 prev = tmp;
00230 tmp = tmp->next;
00231 }
00232 }
00233
00234
00235 static void wps_er_ap_timeout(void *eloop_data, void *user_ctx)
00236 {
00237 struct wps_er *er = eloop_data;
00238 struct wps_er_ap *ap = user_ctx;
00239 wpa_printf(MSG_DEBUG, "WPS ER: AP advertisement timed out");
00240 wps_er_ap_unlink(er, ap);
00241 wps_er_ap_free(er, ap);
00242 }
00243
00244
00245 static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c,
00246 enum http_client_event event)
00247 {
00248 struct wps_er_ap *ap = ctx;
00249
00250 switch (event) {
00251 case HTTP_CLIENT_OK:
00252 wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events");
00253 wps_er_ap_event(ap->er->wps, ap, WPS_EV_ER_AP_ADD);
00254 break;
00255 case HTTP_CLIENT_FAILED:
00256 case HTTP_CLIENT_INVALID_REPLY:
00257 case HTTP_CLIENT_TIMEOUT:
00258 wpa_printf(MSG_DEBUG, "WPS ER: Failed to subscribe to events");
00259 break;
00260 }
00261 http_client_free(ap->http);
00262 ap->http = NULL;
00263 }
00264
00265
00266 static void wps_er_subscribe(struct wps_er_ap *ap)
00267 {
00268 struct wpabuf *req;
00269 struct sockaddr_in dst;
00270 char *url, *path;
00271
00272 if (ap->event_sub_url == NULL) {
00273 wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
00274 "subscribe");
00275 return;
00276 }
00277 if (ap->http) {
00278 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
00279 "send subscribe request");
00280 return;
00281 }
00282
00283 url = http_client_url_parse(ap->event_sub_url, &dst, &path);
00284 if (url == NULL) {
00285 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
00286 return;
00287 }
00288
00289 req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
00290 if (req == NULL) {
00291 os_free(url);
00292 return;
00293 }
00294 wpabuf_printf(req,
00295 "SUBSCRIBE %s HTTP/1.1\r\n"
00296 "HOST: %s:%d\r\n"
00297 "CALLBACK: <http://%s:%d/event/%u/%u>\r\n"
00298 "NT: upnp:event\r\n"
00299 "TIMEOUT: Second-%d\r\n"
00300 "\r\n",
00301 path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port),
00302 ap->er->ip_addr_text, ap->er->http_port,
00303 ap->er->event_id, ap->id, 1800);
00304 os_free(url);
00305 wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request",
00306 wpabuf_head(req), wpabuf_len(req));
00307
00308 ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb,
00309 ap);
00310 if (ap->http == NULL)
00311 wpabuf_free(req);
00312 }
00313
00314
00315 static void wps_er_ap_get_m1(struct wps_er_ap *ap, struct wpabuf *m1)
00316 {
00317 struct wps_parse_attr attr;
00318
00319 if (wps_parse_msg(m1, &attr) < 0) {
00320 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse M1");
00321 return;
00322 }
00323 if (attr.primary_dev_type)
00324 os_memcpy(ap->pri_dev_type, attr.primary_dev_type, 8);
00325 if (attr.wps_state)
00326 ap->wps_state = *attr.wps_state;
00327 if (attr.mac_addr)
00328 os_memcpy(ap->mac_addr, attr.mac_addr, ETH_ALEN);
00329
00330 wps_er_subscribe(ap);
00331 }
00332
00333
00334 static void wps_er_get_device_info(struct wps_er_ap *ap)
00335 {
00336 wps_er_send_get_device_info(ap, wps_er_ap_get_m1);
00337 }
00338
00339
00340 static void wps_er_parse_device_description(struct wps_er_ap *ap,
00341 struct wpabuf *reply)
00342 {
00343
00344 const char *data = wpabuf_head(reply);
00345 char *pos;
00346
00347 wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info",
00348 wpabuf_head(reply), wpabuf_len(reply));
00349
00350 ap->friendly_name = xml_get_first_item(data, "friendlyName");
00351 wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name);
00352
00353 ap->manufacturer = xml_get_first_item(data, "manufacturer");
00354 wpa_printf(MSG_DEBUG, "WPS ER: manufacturer='%s'", ap->manufacturer);
00355
00356 ap->manufacturer_url = xml_get_first_item(data, "manufacturerURL");
00357 wpa_printf(MSG_DEBUG, "WPS ER: manufacturerURL='%s'",
00358 ap->manufacturer_url);
00359
00360 ap->model_description = xml_get_first_item(data, "modelDescription");
00361 wpa_printf(MSG_DEBUG, "WPS ER: modelDescription='%s'",
00362 ap->model_description);
00363
00364 ap->model_name = xml_get_first_item(data, "modelName");
00365 wpa_printf(MSG_DEBUG, "WPS ER: modelName='%s'", ap->model_name);
00366
00367 ap->model_number = xml_get_first_item(data, "modelNumber");
00368 wpa_printf(MSG_DEBUG, "WPS ER: modelNumber='%s'", ap->model_number);
00369
00370 ap->model_url = xml_get_first_item(data, "modelURL");
00371 wpa_printf(MSG_DEBUG, "WPS ER: modelURL='%s'", ap->model_url);
00372
00373 ap->serial_number = xml_get_first_item(data, "serialNumber");
00374 wpa_printf(MSG_DEBUG, "WPS ER: serialNumber='%s'", ap->serial_number);
00375
00376 ap->udn = xml_get_first_item(data, "UDN");
00377 wpa_printf(MSG_DEBUG, "WPS ER: UDN='%s'", ap->udn);
00378 pos = os_strstr(ap->udn, "uuid:");
00379 if (pos) {
00380 pos += 5;
00381 uuid_str2bin(pos, ap->uuid);
00382 }
00383
00384 ap->upc = xml_get_first_item(data, "UPC");
00385 wpa_printf(MSG_DEBUG, "WPS ER: UPC='%s'", ap->upc);
00386
00387 ap->scpd_url = http_link_update(
00388 xml_get_first_item(data, "SCPDURL"), ap->location);
00389 wpa_printf(MSG_DEBUG, "WPS ER: SCPDURL='%s'", ap->scpd_url);
00390
00391 ap->control_url = http_link_update(
00392 xml_get_first_item(data, "controlURL"), ap->location);
00393 wpa_printf(MSG_DEBUG, "WPS ER: controlURL='%s'", ap->control_url);
00394
00395 ap->event_sub_url = http_link_update(
00396 xml_get_first_item(data, "eventSubURL"), ap->location);
00397 wpa_printf(MSG_DEBUG, "WPS ER: eventSubURL='%s'", ap->event_sub_url);
00398 }
00399
00400
00401 static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
00402 enum http_client_event event)
00403 {
00404 struct wps_er_ap *ap = ctx;
00405 struct wpabuf *reply;
00406 int ok = 0;
00407
00408 switch (event) {
00409 case HTTP_CLIENT_OK:
00410 reply = http_client_get_body(c);
00411 if (reply == NULL)
00412 break;
00413 wps_er_parse_device_description(ap, reply);
00414 ok = 1;
00415 break;
00416 case HTTP_CLIENT_FAILED:
00417 case HTTP_CLIENT_INVALID_REPLY:
00418 case HTTP_CLIENT_TIMEOUT:
00419 wpa_printf(MSG_DEBUG, "WPS ER: Failed to fetch device info");
00420 break;
00421 }
00422 http_client_free(ap->http);
00423 ap->http = NULL;
00424 if (ok)
00425 wps_er_get_device_info(ap);
00426 }
00427
00428
00429 void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
00430 const char *location, int max_age)
00431 {
00432 struct wps_er_ap *ap;
00433
00434 ap = wps_er_ap_get(er, addr, uuid);
00435 if (ap) {
00436
00437 eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
00438 eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
00439 return;
00440 }
00441
00442 ap = os_zalloc(sizeof(*ap));
00443 if (ap == NULL)
00444 return;
00445 ap->er = er;
00446 ap->id = ++er->next_ap_id;
00447 ap->location = os_strdup(location);
00448 if (ap->location == NULL) {
00449 os_free(ap);
00450 return;
00451 }
00452 ap->next = er->ap;
00453 er->ap = ap;
00454
00455 ap->addr.s_addr = addr->s_addr;
00456 os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
00457 eloop_register_timeout(max_age, 0, wps_er_ap_timeout, er, ap);
00458
00459 wpa_printf(MSG_DEBUG, "WPS ER: Added AP entry for %s (%s)",
00460 inet_ntoa(ap->addr), ap->location);
00461
00462
00463 ap->http = http_client_url(ap->location, NULL, 10000,
00464 wps_er_http_dev_desc_cb, ap);
00465 }
00466
00467
00468 void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr)
00469 {
00470 struct wps_er_ap *prev = NULL, *ap = er->ap;
00471
00472 while (ap) {
00473 if (ap->addr.s_addr == addr->s_addr) {
00474 if (prev)
00475 prev->next = ap->next;
00476 else
00477 er->ap = ap->next;
00478 wps_er_ap_free(er, ap);
00479 return;
00480 }
00481 prev = ap;
00482 ap = ap->next;
00483 }
00484 }
00485
00486
00487 static void wps_er_ap_remove_all(struct wps_er *er)
00488 {
00489 struct wps_er_ap *prev, *ap;
00490
00491 ap = er->ap;
00492 er->ap = NULL;
00493
00494 while (ap) {
00495 prev = ap;
00496 ap = ap->next;
00497 wps_er_ap_free(er, prev);
00498 }
00499 }
00500
00501
00502 static void http_put_date(struct wpabuf *buf)
00503 {
00504 wpabuf_put_str(buf, "Date: ");
00505 format_date(buf);
00506 wpabuf_put_str(buf, "\r\n");
00507 }
00508
00509
00510 static void wps_er_http_resp_not_found(struct http_request *req)
00511 {
00512 struct wpabuf *buf;
00513 buf = wpabuf_alloc(200);
00514 if (buf == NULL) {
00515 http_request_deinit(req);
00516 return;
00517 }
00518
00519 wpabuf_put_str(buf,
00520 "HTTP/1.1 404 Not Found\r\n"
00521 "Server: unspecified, UPnP/1.0, unspecified\r\n"
00522 "Connection: close\r\n");
00523 http_put_date(buf);
00524 wpabuf_put_str(buf, "\r\n");
00525 http_request_send_and_deinit(req, buf);
00526 }
00527
00528
00529 static void wps_er_http_resp_ok(struct http_request *req)
00530 {
00531 struct wpabuf *buf;
00532 buf = wpabuf_alloc(200);
00533 if (buf == NULL) {
00534 http_request_deinit(req);
00535 return;
00536 }
00537
00538 wpabuf_put_str(buf,
00539 "HTTP/1.1 200 OK\r\n"
00540 "Server: unspecified, UPnP/1.0, unspecified\r\n"
00541 "Connection: close\r\n"
00542 "Content-Length: 0\r\n");
00543 http_put_date(buf);
00544 wpabuf_put_str(buf, "\r\n");
00545 http_request_send_and_deinit(req, buf);
00546 }
00547
00548
00549 static void wps_er_sta_timeout(void *eloop_data, void *user_ctx)
00550 {
00551 struct wps_er_sta *sta = eloop_data;
00552 wpa_printf(MSG_DEBUG, "WPS ER: STA entry timed out");
00553 wps_er_sta_unlink(sta);
00554 wps_er_sta_free(sta);
00555 }
00556
00557
00558 static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
00559 const u8 *addr,
00560 struct wps_parse_attr *attr,
00561 int probe_req)
00562 {
00563 struct wps_er_sta *sta = wps_er_sta_get(ap, addr);
00564 int new_sta = 0;
00565 int m1;
00566
00567 m1 = !probe_req && attr->msg_type && *attr->msg_type == WPS_M1;
00568
00569 if (sta == NULL) {
00570
00571
00572
00573
00574
00575 if (!probe_req && !m1)
00576 return NULL;
00577
00578 sta = os_zalloc(sizeof(*sta));
00579 if (sta == NULL)
00580 return NULL;
00581 os_memcpy(sta->addr, addr, ETH_ALEN);
00582 sta->ap = ap;
00583 sta->next = ap->sta;
00584 ap->sta = sta;
00585 new_sta = 1;
00586 }
00587
00588 if (m1)
00589 sta->m1_received = 1;
00590
00591 if (attr->config_methods && (!probe_req || !sta->m1_received))
00592 sta->config_methods = WPA_GET_BE16(attr->config_methods);
00593 if (attr->uuid_e && (!probe_req || !sta->m1_received))
00594 os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN);
00595 if (attr->primary_dev_type && (!probe_req || !sta->m1_received))
00596 os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8);
00597 if (attr->dev_password_id && (!probe_req || !sta->m1_received))
00598 sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id);
00599
00600 if (attr->manufacturer) {
00601 os_free(sta->manufacturer);
00602 sta->manufacturer = os_malloc(attr->manufacturer_len + 1);
00603 if (sta->manufacturer) {
00604 os_memcpy(sta->manufacturer, attr->manufacturer,
00605 attr->manufacturer_len);
00606 sta->manufacturer[attr->manufacturer_len] = '\0';
00607 }
00608 }
00609
00610 if (attr->model_name) {
00611 os_free(sta->model_name);
00612 sta->model_name = os_malloc(attr->model_name_len + 1);
00613 if (sta->model_name) {
00614 os_memcpy(sta->model_name, attr->model_name,
00615 attr->model_name_len);
00616 sta->model_name[attr->model_name_len] = '\0';
00617 }
00618 }
00619
00620 if (attr->model_number) {
00621 os_free(sta->model_number);
00622 sta->model_number = os_malloc(attr->model_number_len + 1);
00623 if (sta->model_number) {
00624 os_memcpy(sta->model_number, attr->model_number,
00625 attr->model_number_len);
00626 sta->model_number[attr->model_number_len] = '\0';
00627 }
00628 }
00629
00630 if (attr->serial_number) {
00631 os_free(sta->serial_number);
00632 sta->serial_number = os_malloc(attr->serial_number_len + 1);
00633 if (sta->serial_number) {
00634 os_memcpy(sta->serial_number, attr->serial_number,
00635 attr->serial_number_len);
00636 sta->serial_number[attr->serial_number_len] = '\0';
00637 }
00638 }
00639
00640 if (attr->dev_name) {
00641 os_free(sta->dev_name);
00642 sta->dev_name = os_malloc(attr->dev_name_len + 1);
00643 if (sta->dev_name) {
00644 os_memcpy(sta->dev_name, attr->dev_name,
00645 attr->dev_name_len);
00646 sta->dev_name[attr->dev_name_len] = '\0';
00647 }
00648 }
00649
00650 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
00651 eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL);
00652
00653 if (m1 || new_sta)
00654 wps_er_sta_event(ap->er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
00655
00656 return sta;
00657 }
00658
00659
00660 static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
00661 const u8 *addr,
00662 struct wpabuf *msg)
00663 {
00664 struct wps_parse_attr attr;
00665
00666 wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - Probe Request - from "
00667 MACSTR, MAC2STR(addr));
00668 wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
00669 "(TLVs from Probe Request)", msg);
00670
00671 if (wps_parse_msg(msg, &attr) < 0) {
00672 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
00673 "WLANEvent message");
00674 return;
00675 }
00676
00677 wps_er_add_sta_data(ap, addr, &attr, 1);
00678 }
00679
00680
00681 static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c,
00682 enum http_client_event event)
00683 {
00684 struct wps_er_sta *sta = ctx;
00685
00686 switch (event) {
00687 case HTTP_CLIENT_OK:
00688 wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK");
00689 break;
00690 case HTTP_CLIENT_FAILED:
00691 case HTTP_CLIENT_INVALID_REPLY:
00692 case HTTP_CLIENT_TIMEOUT:
00693 wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed");
00694 break;
00695 }
00696 http_client_free(sta->http);
00697 sta->http = NULL;
00698 }
00699
00700
00701 static const char *soap_prefix =
00702 "<?xml version=\"1.0\"?>\n"
00703 "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
00704 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
00705 "<s:Body>\n";
00706 static const char *soap_postfix =
00707 "</s:Body>\n</s:Envelope>\n";
00708 static const char *urn_wfawlanconfig =
00709 "urn:schemas-wifialliance-org:service:WFAWLANConfig:1";
00710
00711 static struct wpabuf * wps_er_soap_hdr(const struct wpabuf *msg,
00712 const char *name, const char *arg_name,
00713 const char *path,
00714 const struct sockaddr_in *dst,
00715 char **len_ptr, char **body_ptr)
00716 {
00717 unsigned char *encoded;
00718 size_t encoded_len;
00719 struct wpabuf *buf;
00720
00721 if (msg) {
00722 encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg),
00723 &encoded_len);
00724 if (encoded == NULL)
00725 return NULL;
00726 } else {
00727 encoded = NULL;
00728 encoded_len = 0;
00729 }
00730
00731 buf = wpabuf_alloc(1000 + encoded_len);
00732 if (buf == NULL) {
00733 os_free(encoded);
00734 return NULL;
00735 }
00736
00737 wpabuf_printf(buf,
00738 "POST %s HTTP/1.1\r\n"
00739 "Host: %s:%d\r\n"
00740 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
00741 "Content-Length: ",
00742 path, inet_ntoa(dst->sin_addr), ntohs(dst->sin_port));
00743
00744 *len_ptr = wpabuf_put(buf, 0);
00745 wpabuf_printf(buf,
00746 " \r\n"
00747 "SOAPACTION: \"%s#%s\"\r\n"
00748 "\r\n",
00749 urn_wfawlanconfig, name);
00750
00751 *body_ptr = wpabuf_put(buf, 0);
00752
00753 wpabuf_put_str(buf, soap_prefix);
00754 wpabuf_printf(buf, "<u:%s xmlns:u=\"", name);
00755 wpabuf_put_str(buf, urn_wfawlanconfig);
00756 wpabuf_put_str(buf, "\">\n");
00757 if (encoded) {
00758 wpabuf_printf(buf, "<%s>%s</%s>\n",
00759 arg_name, (char *) encoded, arg_name);
00760 os_free(encoded);
00761 }
00762
00763 return buf;
00764 }
00765
00766
00767 static void wps_er_soap_end(struct wpabuf *buf, const char *name,
00768 char *len_ptr, char *body_ptr)
00769 {
00770 char len_buf[10];
00771 wpabuf_printf(buf, "</u:%s>\n", name);
00772 wpabuf_put_str(buf, soap_postfix);
00773 os_snprintf(len_buf, sizeof(len_buf), "%d",
00774 (int) ((char *) wpabuf_put(buf, 0) - body_ptr));
00775 os_memcpy(len_ptr, len_buf, os_strlen(len_buf));
00776 }
00777
00778
00779 static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
00780 {
00781 struct wpabuf *buf;
00782 char *len_ptr, *body_ptr;
00783 struct sockaddr_in dst;
00784 char *url, *path;
00785
00786 if (sta->http) {
00787 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
00788 "ignore new request");
00789 wpabuf_free(msg);
00790 return;
00791 }
00792
00793 if (sta->ap->control_url == NULL) {
00794 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
00795 wpabuf_free(msg);
00796 return;
00797 }
00798
00799 url = http_client_url_parse(sta->ap->control_url, &dst, &path);
00800 if (url == NULL) {
00801 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
00802 wpabuf_free(msg);
00803 return;
00804 }
00805
00806 buf = wps_er_soap_hdr(msg, "PutWLANResponse", "NewMessage", path, &dst,
00807 &len_ptr, &body_ptr);
00808 wpabuf_free(msg);
00809 os_free(url);
00810 if (buf == NULL)
00811 return;
00812 wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n",
00813 UPNP_WPS_WLANEVENT_TYPE_EAP);
00814 wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n",
00815 MAC2STR(sta->addr));
00816
00817 wps_er_soap_end(buf, "PutWLANResponse", len_ptr, body_ptr);
00818
00819 sta->http = http_client_addr(&dst, buf, 1000,
00820 wps_er_http_put_wlan_response_cb, sta);
00821 if (sta->http == NULL)
00822 wpabuf_free(buf);
00823 }
00824
00825
00826 static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg,
00827 enum wsc_op_code op_code)
00828 {
00829 enum wps_process_res res;
00830
00831 res = wps_process_msg(sta->wps, op_code, msg);
00832 if (res == WPS_CONTINUE) {
00833 struct wpabuf *next = wps_get_msg(sta->wps, &op_code);
00834 if (next)
00835 wps_er_sta_send_msg(sta, next);
00836 } else {
00837 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run %s with the "
00838 "enrollee (res=%d)",
00839 res == WPS_DONE ? "succeeded" : "failed", res);
00840 wps_deinit(sta->wps);
00841 sta->wps = NULL;
00842 if (res == WPS_DONE) {
00843
00844 eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
00845 eloop_register_timeout(10, 0, wps_er_sta_timeout, sta,
00846 NULL);
00847 }
00848 }
00849 }
00850
00851
00852 static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg)
00853 {
00854 struct wps_config cfg;
00855
00856 if (sta->wps)
00857 wps_deinit(sta->wps);
00858
00859 os_memset(&cfg, 0, sizeof(cfg));
00860 cfg.wps = sta->ap->er->wps;
00861 cfg.registrar = 1;
00862 cfg.peer_addr = sta->addr;
00863
00864 sta->wps = wps_init(&cfg);
00865 if (sta->wps == NULL)
00866 return;
00867 sta->wps->er = 1;
00868 sta->wps->use_cred = sta->ap->ap_settings;
00869
00870 wps_er_sta_process(sta, msg, WSC_MSG);
00871 }
00872
00873
00874 static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
00875 struct wpabuf *msg)
00876 {
00877 struct wps_parse_attr attr;
00878 struct wps_er_sta *sta;
00879
00880 wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
00881 MAC2STR(addr));
00882 wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
00883 "(TLVs from EAP-WSC)", msg);
00884
00885 if (wps_parse_msg(msg, &attr) < 0) {
00886 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
00887 "WLANEvent message");
00888 return;
00889 }
00890
00891 sta = wps_er_add_sta_data(ap, addr, &attr, 0);
00892 if (sta == NULL)
00893 return;
00894
00895 if (attr.msg_type && *attr.msg_type == WPS_M1)
00896 wps_er_sta_start(sta, msg);
00897 else if (sta->wps) {
00898 enum wsc_op_code op_code = WSC_MSG;
00899 if (attr.msg_type) {
00900 switch (*attr.msg_type) {
00901 case WPS_WSC_ACK:
00902 op_code = WSC_ACK;
00903 break;
00904 case WPS_WSC_NACK:
00905 op_code = WSC_NACK;
00906 break;
00907 case WPS_WSC_DONE:
00908 op_code = WSC_Done;
00909 break;
00910 }
00911 }
00912 wps_er_sta_process(sta, msg, op_code);
00913 }
00914 }
00915
00916
00917 static void wps_er_process_wlanevent(struct wps_er_ap *ap,
00918 struct wpabuf *event)
00919 {
00920 u8 *data;
00921 u8 wlan_event_type;
00922 u8 wlan_event_mac[ETH_ALEN];
00923 struct wpabuf msg;
00924
00925 wpa_hexdump(MSG_MSGDUMP, "WPS ER: Received WLANEvent",
00926 wpabuf_head(event), wpabuf_len(event));
00927 if (wpabuf_len(event) < 1 + 17) {
00928 wpa_printf(MSG_DEBUG, "WPS ER: Too short WLANEvent");
00929 return;
00930 }
00931
00932 data = wpabuf_mhead(event);
00933 wlan_event_type = data[0];
00934 if (hwaddr_aton((char *) data + 1, wlan_event_mac) < 0) {
00935 wpa_printf(MSG_DEBUG, "WPS ER: Invalid WLANEventMAC in "
00936 "WLANEvent");
00937 return;
00938 }
00939
00940 wpabuf_set(&msg, data + 1 + 17, wpabuf_len(event) - (1 + 17));
00941
00942 switch (wlan_event_type) {
00943 case 1:
00944 wps_er_process_wlanevent_probe_req(ap, wlan_event_mac, &msg);
00945 break;
00946 case 2:
00947 wps_er_process_wlanevent_eap(ap, wlan_event_mac, &msg);
00948 break;
00949 default:
00950 wpa_printf(MSG_DEBUG, "WPS ER: Unknown WLANEventType %d",
00951 wlan_event_type);
00952 break;
00953 }
00954 }
00955
00956
00957 static void wps_er_http_event(struct wps_er *er, struct http_request *req,
00958 unsigned int ap_id)
00959 {
00960 struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id);
00961 struct wpabuf *event;
00962 enum http_reply_code ret;
00963
00964 if (ap == NULL) {
00965 wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id "
00966 "%u", ap_id);
00967 wps_er_http_resp_not_found(req);
00968 return;
00969 }
00970 wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s",
00971 ap_id, http_request_get_data(req));
00972
00973 event = xml_get_base64_item(http_request_get_data(req), "WLANEvent",
00974 &ret);
00975 if (event == NULL) {
00976 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent "
00977 "from the event notification");
00978
00979
00980
00981
00982 wps_er_http_resp_ok(req);
00983 return;
00984 }
00985
00986 wps_er_process_wlanevent(ap, event);
00987
00988 wpabuf_free(event);
00989 wps_er_http_resp_ok(req);
00990 }
00991
00992
00993 static void wps_er_http_notify(struct wps_er *er, struct http_request *req)
00994 {
00995 char *uri = http_request_get_uri(req);
00996
00997 if (os_strncmp(uri, "/event/", 7) == 0) {
00998 unsigned int event_id;
00999 char *pos;
01000 event_id = atoi(uri + 7);
01001 if (event_id != er->event_id) {
01002 wpa_printf(MSG_DEBUG, "WPS ER: HTTP event for an "
01003 "unknown event id %u", event_id);
01004 return;
01005 }
01006 pos = os_strchr(uri + 7, '/');
01007 if (pos == NULL)
01008 return;
01009 pos++;
01010 wps_er_http_event(er, req, atoi(pos));
01011 } else {
01012 wpa_printf(MSG_DEBUG, "WPS ER: Unknown HTTP NOTIFY for '%s'",
01013 uri);
01014 wps_er_http_resp_not_found(req);
01015 }
01016 }
01017
01018
01019 static void wps_er_http_req(void *ctx, struct http_request *req)
01020 {
01021 struct wps_er *er = ctx;
01022 struct sockaddr_in *cli = http_request_get_cli_addr(req);
01023 enum httpread_hdr_type type = http_request_get_type(req);
01024 struct wpabuf *buf;
01025
01026 wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from "
01027 "%s:%d",
01028 http_request_get_uri(req), type,
01029 inet_ntoa(cli->sin_addr), ntohs(cli->sin_port));
01030
01031 switch (type) {
01032 case HTTPREAD_HDR_TYPE_NOTIFY:
01033 wps_er_http_notify(er, req);
01034 break;
01035 default:
01036 wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type "
01037 "%d", type);
01038 buf = wpabuf_alloc(200);
01039 if (buf == NULL) {
01040 http_request_deinit(req);
01041 return;
01042 }
01043 wpabuf_put_str(buf,
01044 "HTTP/1.1 501 Unimplemented\r\n"
01045 "Connection: close\r\n");
01046 http_put_date(buf);
01047 wpabuf_put_str(buf, "\r\n");
01048 http_request_send_and_deinit(req, buf);
01049 break;
01050 }
01051 }
01052
01053
01054 struct wps_er *
01055 wps_er_init(struct wps_context *wps, const char *ifname)
01056 {
01057 struct wps_er *er;
01058 struct in_addr addr;
01059
01060 er = os_zalloc(sizeof(*er));
01061 if (er == NULL)
01062 return NULL;
01063
01064 er->multicast_sd = -1;
01065 er->ssdp_sd = -1;
01066
01067 os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
01068 er->wps = wps;
01069 os_get_random((unsigned char *) &er->event_id, sizeof(er->event_id));
01070
01071 if (get_netif_info(ifname,
01072 &er->ip_addr, &er->ip_addr_text,
01073 er->mac_addr, &er->mac_addr_text)) {
01074 wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
01075 "for %s. Does it have IP address?", ifname);
01076 wps_er_deinit(er);
01077 return NULL;
01078 }
01079
01080 if (wps_er_ssdp_init(er) < 0) {
01081 wps_er_deinit(er);
01082 return NULL;
01083 }
01084
01085 addr.s_addr = er->ip_addr;
01086 er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
01087 if (er->http_srv == NULL) {
01088 wps_er_deinit(er);
01089 return NULL;
01090 }
01091 er->http_port = http_server_get_port(er->http_srv);
01092
01093 wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s "
01094 "mac_addr=%s)",
01095 er->ifname, er->ip_addr_text, er->mac_addr_text);
01096
01097 return er;
01098 }
01099
01100
01101 void wps_er_refresh(struct wps_er *er)
01102 {
01103 struct wps_er_ap *ap;
01104 struct wps_er_sta *sta;
01105
01106 for (ap = er->ap; ap; ap = ap->next) {
01107 wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_ADD);
01108 for (sta = ap->sta; sta; sta = sta->next)
01109 wps_er_sta_event(er->wps, sta, WPS_EV_ER_ENROLLEE_ADD);
01110 }
01111
01112 wps_er_send_ssdp_msearch(er);
01113 }
01114
01115
01116 void wps_er_deinit(struct wps_er *er)
01117 {
01118 if (er == NULL)
01119 return;
01120 http_server_deinit(er->http_srv);
01121 wps_er_ap_remove_all(er);
01122 wps_er_ssdp_deinit(er);
01123 os_free(er->ip_addr_text);
01124 os_free(er->mac_addr_text);
01125 os_free(er);
01126 }
01127
01128
01129 static void wps_er_http_set_sel_reg_cb(void *ctx, struct http_client *c,
01130 enum http_client_event event)
01131 {
01132 struct wps_er_ap *ap = ctx;
01133
01134 switch (event) {
01135 case HTTP_CLIENT_OK:
01136 wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar OK");
01137 break;
01138 case HTTP_CLIENT_FAILED:
01139 case HTTP_CLIENT_INVALID_REPLY:
01140 case HTTP_CLIENT_TIMEOUT:
01141 wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar failed");
01142 break;
01143 }
01144 http_client_free(ap->http);
01145 ap->http = NULL;
01146 }
01147
01148
01149 static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg)
01150 {
01151 struct wpabuf *buf;
01152 char *len_ptr, *body_ptr;
01153 struct sockaddr_in dst;
01154 char *url, *path;
01155
01156 if (ap->control_url == NULL) {
01157 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
01158 return;
01159 }
01160
01161 if (ap->http) {
01162 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - "
01163 "ignore new request");
01164 return;
01165 }
01166
01167 url = http_client_url_parse(ap->control_url, &dst, &path);
01168 if (url == NULL) {
01169 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
01170 return;
01171 }
01172
01173 buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", "NewMessage", path,
01174 &dst, &len_ptr, &body_ptr);
01175 os_free(url);
01176 if (buf == NULL)
01177 return;
01178
01179 wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr);
01180
01181 ap->http = http_client_addr(&dst, buf, 1000,
01182 wps_er_http_set_sel_reg_cb, ap);
01183 if (ap->http == NULL)
01184 wpabuf_free(buf);
01185 }
01186
01187
01188 static int wps_er_build_selected_registrar(struct wpabuf *msg, int sel_reg)
01189 {
01190 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
01191 wpabuf_put_be16(msg, 1);
01192 wpabuf_put_u8(msg, !!sel_reg);
01193 return 0;
01194 }
01195
01196
01197 static int wps_er_build_dev_password_id(struct wpabuf *msg, u16 dev_passwd_id)
01198 {
01199 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
01200 wpabuf_put_be16(msg, 2);
01201 wpabuf_put_be16(msg, dev_passwd_id);
01202 return 0;
01203 }
01204
01205
01206 static int wps_er_build_sel_reg_config_methods(struct wpabuf *msg,
01207 u16 sel_reg_config_methods)
01208 {
01209 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
01210 wpabuf_put_be16(msg, 2);
01211 wpabuf_put_be16(msg, sel_reg_config_methods);
01212 return 0;
01213 }
01214
01215
01216 void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
01217 u16 sel_reg_config_methods)
01218 {
01219 struct wpabuf *msg;
01220 struct wps_er_ap *ap;
01221
01222 msg = wpabuf_alloc(500);
01223 if (msg == NULL)
01224 return;
01225
01226 if (wps_build_version(msg) ||
01227 wps_er_build_selected_registrar(msg, sel_reg) ||
01228 wps_er_build_dev_password_id(msg, dev_passwd_id) ||
01229 wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods)) {
01230 wpabuf_free(msg);
01231 return;
01232 }
01233
01234 for (ap = er->ap; ap; ap = ap->next)
01235 wps_er_send_set_sel_reg(ap, msg);
01236
01237 wpabuf_free(msg);
01238 }
01239
01240
01241 int wps_er_pbc(struct wps_er *er, const u8 *uuid)
01242 {
01243 if (er == NULL || er->wps == NULL)
01244 return -1;
01245
01246
01247
01248
01249
01250
01251
01252 if (wps_registrar_button_pushed(er->wps->registrar))
01253 return -1;
01254
01255 return 0;
01256 }
01257
01258
01259 static void wps_er_ap_settings_cb(void *ctx, const struct wps_credential *cred)
01260 {
01261 struct wps_er_ap *ap = ctx;
01262 wpa_printf(MSG_DEBUG, "WPS ER: AP Settings received");
01263 os_free(ap->ap_settings);
01264 ap->ap_settings = os_malloc(sizeof(*cred));
01265 if (ap->ap_settings) {
01266 os_memcpy(ap->ap_settings, cred, sizeof(*cred));
01267 ap->ap_settings->cred_attr = NULL;
01268 }
01269
01270
01271 }
01272
01273
01274 static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
01275 enum http_client_event event)
01276 {
01277 struct wps_er_ap *ap = ctx;
01278 struct wpabuf *reply;
01279 char *msg = NULL;
01280
01281 switch (event) {
01282 case HTTP_CLIENT_OK:
01283 wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK");
01284 reply = http_client_get_body(c);
01285 if (reply == NULL)
01286 break;
01287 msg = os_zalloc(wpabuf_len(reply) + 1);
01288 if (msg == NULL)
01289 break;
01290 os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply));
01291 break;
01292 case HTTP_CLIENT_FAILED:
01293 case HTTP_CLIENT_INVALID_REPLY:
01294 case HTTP_CLIENT_TIMEOUT:
01295 wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed");
01296 if (ap->wps) {
01297 wps_deinit(ap->wps);
01298 ap->wps = NULL;
01299 }
01300 break;
01301 }
01302 http_client_free(ap->http);
01303 ap->http = NULL;
01304
01305 if (msg) {
01306 struct wpabuf *buf;
01307 enum http_reply_code ret;
01308 buf = xml_get_base64_item(msg, "NewOutMessage", &ret);
01309 os_free(msg);
01310 if (buf == NULL) {
01311 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
01312 "NewOutMessage from PutMessage response");
01313 return;
01314 }
01315 wps_er_ap_process(ap, buf);
01316 wpabuf_free(buf);
01317 }
01318 }
01319
01320
01321 static void wps_er_ap_put_message(struct wps_er_ap *ap,
01322 const struct wpabuf *msg)
01323 {
01324 struct wpabuf *buf;
01325 char *len_ptr, *body_ptr;
01326 struct sockaddr_in dst;
01327 char *url, *path;
01328
01329 if (ap->http) {
01330 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
01331 "with the AP - cannot continue learn");
01332 return;
01333 }
01334
01335 if (ap->control_url == NULL) {
01336 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
01337 return;
01338 }
01339
01340 url = http_client_url_parse(ap->control_url, &dst, &path);
01341 if (url == NULL) {
01342 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
01343 return;
01344 }
01345
01346 buf = wps_er_soap_hdr(msg, "PutMessage", "NewInMessage", path, &dst,
01347 &len_ptr, &body_ptr);
01348 os_free(url);
01349 if (buf == NULL)
01350 return;
01351
01352 wps_er_soap_end(buf, "PutMessage", len_ptr, body_ptr);
01353
01354 ap->http = http_client_addr(&dst, buf, 10000,
01355 wps_er_http_put_message_cb, ap);
01356 if (ap->http == NULL)
01357 wpabuf_free(buf);
01358 }
01359
01360
01361 static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg)
01362 {
01363 enum wps_process_res res;
01364
01365 res = wps_process_msg(ap->wps, WSC_MSG, msg);
01366 if (res == WPS_CONTINUE) {
01367 enum wsc_op_code op_code;
01368 struct wpabuf *next = wps_get_msg(ap->wps, &op_code);
01369 if (next) {
01370 wps_er_ap_put_message(ap, next);
01371 wpabuf_free(next);
01372 } else {
01373 wpa_printf(MSG_DEBUG, "WPS ER: Failed to build "
01374 "message");
01375 wps_deinit(ap->wps);
01376 ap->wps = NULL;
01377 }
01378 } else {
01379 wpa_printf(MSG_DEBUG, "WPS ER: Failed to process message from "
01380 "AP (res=%d)", res);
01381 wps_deinit(ap->wps);
01382 ap->wps = NULL;
01383 }
01384 }
01385
01386
01387 static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1)
01388 {
01389 struct wps_config cfg;
01390
01391 if (ap->wps) {
01392 wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in "
01393 "progress with this AP");
01394 return;
01395 }
01396
01397 os_memset(&cfg, 0, sizeof(cfg));
01398 cfg.wps = ap->er->wps;
01399 cfg.registrar = 1;
01400 ap->wps = wps_init(&cfg);
01401 if (ap->wps == NULL)
01402 return;
01403 ap->wps->ap_settings_cb = wps_er_ap_settings_cb;
01404 ap->wps->ap_settings_cb_ctx = ap;
01405
01406 wps_er_ap_process(ap, m1);
01407 }
01408
01409
01410 static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
01411 {
01412 struct wpabuf *info;
01413 enum http_reply_code ret;
01414
01415 wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) "
01416 "from the AP");
01417 info = xml_get_base64_item(dev_info, "NewDeviceInfo", &ret);
01418 if (info == NULL) {
01419 wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
01420 "NewDeviceInfo from GetDeviceInfo response");
01421 return;
01422 }
01423
01424 ap->m1_handler(ap, info);
01425 wpabuf_free(info);
01426 }
01427
01428
01429 static void wps_er_http_get_dev_info_cb(void *ctx, struct http_client *c,
01430 enum http_client_event event)
01431 {
01432 struct wps_er_ap *ap = ctx;
01433 struct wpabuf *reply;
01434 char *dev_info = NULL;
01435
01436 switch (event) {
01437 case HTTP_CLIENT_OK:
01438 wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo OK");
01439 reply = http_client_get_body(c);
01440 if (reply == NULL)
01441 break;
01442 dev_info = os_zalloc(wpabuf_len(reply) + 1);
01443 if (dev_info == NULL)
01444 break;
01445 os_memcpy(dev_info, wpabuf_head(reply), wpabuf_len(reply));
01446 break;
01447 case HTTP_CLIENT_FAILED:
01448 case HTTP_CLIENT_INVALID_REPLY:
01449 case HTTP_CLIENT_TIMEOUT:
01450 wpa_printf(MSG_DEBUG, "WPS ER: GetDeviceInfo failed");
01451 break;
01452 }
01453 http_client_free(ap->http);
01454 ap->http = NULL;
01455
01456 if (dev_info) {
01457 wps_er_ap_learn(ap, dev_info);
01458 os_free(dev_info);
01459 }
01460 }
01461
01462
01463 static int wps_er_send_get_device_info(struct wps_er_ap *ap,
01464 void (*m1_handler)(struct wps_er_ap *ap,
01465 struct wpabuf *m1))
01466 {
01467 struct wpabuf *buf;
01468 char *len_ptr, *body_ptr;
01469 struct sockaddr_in dst;
01470 char *url, *path;
01471
01472 if (ap->http) {
01473 wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
01474 "with the AP - cannot get device info");
01475 return -1;
01476 }
01477
01478 if (ap->control_url == NULL) {
01479 wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
01480 return -1;
01481 }
01482
01483 url = http_client_url_parse(ap->control_url, &dst, &path);
01484 if (url == NULL) {
01485 wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
01486 return -1;
01487 }
01488
01489 buf = wps_er_soap_hdr(NULL, "GetDeviceInfo", NULL, path, &dst,
01490 &len_ptr, &body_ptr);
01491 os_free(url);
01492 if (buf == NULL)
01493 return -1;
01494
01495 wps_er_soap_end(buf, "GetDeviceInfo", len_ptr, body_ptr);
01496
01497 ap->http = http_client_addr(&dst, buf, 10000,
01498 wps_er_http_get_dev_info_cb, ap);
01499 if (ap->http == NULL) {
01500 wpabuf_free(buf);
01501 return -1;
01502 }
01503
01504 ap->m1_handler = m1_handler;
01505
01506 return 0;
01507 }
01508
01509
01510 int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
01511 size_t pin_len)
01512 {
01513 struct wps_er_ap *ap;
01514
01515 if (er == NULL)
01516 return -1;
01517
01518 ap = wps_er_ap_get(er, NULL, uuid);
01519 if (ap == NULL) {
01520 wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
01521 "request");
01522 return -1;
01523 }
01524 if (ap->wps) {
01525 wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
01526 "with the AP - cannot start learn");
01527 return -1;
01528 }
01529
01530 if (wps_er_send_get_device_info(ap, wps_er_ap_learn_m1) < 0)
01531 return -1;
01532
01533
01534 wps_registrar_add_pin(er->wps->registrar, uuid, pin, pin_len, 0);
01535
01536 return 0;
01537 }
01538