00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "sha256.h"
00020 #include "base64.h"
00021 #include "ieee802_11_defs.h"
00022 #include "eloop.h"
00023 #include "wps_i.h"
00024 #include "wps_dev_attr.h"
00025 #include "wps_upnp.h"
00026 #include "crypto.h"
00027 #include "uuid.h"
00028
00029 #define WPS_WORKAROUNDS
00030
00031 struct wps_uuid_pin {
00032 struct wps_uuid_pin *next;
00033 u8 uuid[WPS_UUID_LEN];
00034 int wildcard_uuid;
00035 u8 *pin;
00036 size_t pin_len;
00037 #define PIN_LOCKED BIT(0)
00038 #define PIN_EXPIRES BIT(1)
00039 int flags;
00040 struct os_time expiration;
00041 };
00042
00043
00044 static void wps_free_pin(struct wps_uuid_pin *pin)
00045 {
00046 os_free(pin->pin);
00047 os_free(pin);
00048 }
00049
00050
00051 static void wps_free_pins(struct wps_uuid_pin *pins)
00052 {
00053 struct wps_uuid_pin *pin, *prev;
00054
00055 pin = pins;
00056 while (pin) {
00057 prev = pin;
00058 pin = pin->next;
00059 wps_free_pin(prev);
00060 }
00061 }
00062
00063
00064 struct wps_pbc_session {
00065 struct wps_pbc_session *next;
00066 u8 addr[ETH_ALEN];
00067 u8 uuid_e[WPS_UUID_LEN];
00068 struct os_time timestamp;
00069 };
00070
00071
00072 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
00073 {
00074 struct wps_pbc_session *prev;
00075
00076 while (pbc) {
00077 prev = pbc;
00078 pbc = pbc->next;
00079 os_free(prev);
00080 }
00081 }
00082
00083
00084 struct wps_registrar_device {
00085 struct wps_registrar_device *next;
00086 struct wps_device_data dev;
00087 u8 uuid[WPS_UUID_LEN];
00088 };
00089
00090
00091 struct wps_registrar {
00092 struct wps_context *wps;
00093
00094 int pbc;
00095 int selected_registrar;
00096
00097 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
00098 size_t psk_len);
00099 int (*set_ie_cb)(void *ctx, const u8 *beacon_ie, size_t beacon_ie_len,
00100 const u8 *probe_resp_ie, size_t probe_resp_ie_len);
00101 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
00102 const struct wps_device_data *dev);
00103 void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
00104 const u8 *uuid_e);
00105 void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
00106 u16 sel_reg_config_methods);
00107 void *cb_ctx;
00108
00109 struct wps_uuid_pin *pins;
00110 struct wps_pbc_session *pbc_sessions;
00111
00112 int skip_cred_build;
00113 struct wpabuf *extra_cred;
00114 int disable_auto_conf;
00115 int sel_reg_dev_password_id_override;
00116 int sel_reg_config_methods_override;
00117 int static_wep_only;
00118
00119 struct wps_registrar_device *devices;
00120
00121 int force_pbc_overlap;
00122 };
00123
00124
00125 static int wps_set_ie(struct wps_registrar *reg);
00126 static void wps_cb_set_sel_reg(struct wps_registrar *reg);
00127 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
00128 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
00129 void *timeout_ctx);
00130
00131
00132 static void wps_free_devices(struct wps_registrar_device *dev)
00133 {
00134 struct wps_registrar_device *prev;
00135
00136 while (dev) {
00137 prev = dev;
00138 dev = dev->next;
00139 wps_device_data_free(&prev->dev);
00140 os_free(prev);
00141 }
00142 }
00143
00144
00145 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
00146 const u8 *addr)
00147 {
00148 struct wps_registrar_device *dev;
00149
00150 for (dev = reg->devices; dev; dev = dev->next) {
00151 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
00152 return dev;
00153 }
00154 return NULL;
00155 }
00156
00157
00158 static void wps_device_clone_data(struct wps_device_data *dst,
00159 struct wps_device_data *src)
00160 {
00161 os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
00162 dst->categ = src->categ;
00163 dst->oui = src->oui;
00164 dst->sub_categ = src->sub_categ;
00165
00166 #define WPS_STRDUP(n) \
00167 os_free(dst->n); \
00168 dst->n = src->n ? os_strdup(src->n) : NULL
00169
00170 WPS_STRDUP(device_name);
00171 WPS_STRDUP(manufacturer);
00172 WPS_STRDUP(model_name);
00173 WPS_STRDUP(model_number);
00174 WPS_STRDUP(serial_number);
00175 #undef WPS_STRDUP
00176 }
00177
00178
00179 int wps_device_store(struct wps_registrar *reg,
00180 struct wps_device_data *dev, const u8 *uuid)
00181 {
00182 struct wps_registrar_device *d;
00183
00184 d = wps_device_get(reg, dev->mac_addr);
00185 if (d == NULL) {
00186 d = os_zalloc(sizeof(*d));
00187 if (d == NULL)
00188 return -1;
00189 d->next = reg->devices;
00190 reg->devices = d;
00191 }
00192
00193 wps_device_clone_data(&d->dev, dev);
00194 os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
00195
00196 return 0;
00197 }
00198
00199
00200 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
00201 const u8 *addr, const u8 *uuid_e)
00202 {
00203 struct wps_pbc_session *pbc, *prev = NULL;
00204 struct os_time now;
00205
00206 os_get_time(&now);
00207
00208 pbc = reg->pbc_sessions;
00209 while (pbc) {
00210 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00211 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00212 if (prev)
00213 prev->next = pbc->next;
00214 else
00215 reg->pbc_sessions = pbc->next;
00216 break;
00217 }
00218 prev = pbc;
00219 pbc = pbc->next;
00220 }
00221
00222 if (!pbc) {
00223 pbc = os_zalloc(sizeof(*pbc));
00224 if (pbc == NULL)
00225 return;
00226 os_memcpy(pbc->addr, addr, ETH_ALEN);
00227 if (uuid_e)
00228 os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
00229 }
00230
00231 pbc->next = reg->pbc_sessions;
00232 reg->pbc_sessions = pbc;
00233 pbc->timestamp = now;
00234
00235
00236 prev = pbc;
00237 pbc = pbc->next;
00238
00239 while (pbc) {
00240 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
00241 prev->next = NULL;
00242 wps_free_pbc_sessions(pbc);
00243 break;
00244 }
00245 prev = pbc;
00246 pbc = pbc->next;
00247 }
00248 }
00249
00250
00251 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
00252 const u8 *addr, const u8 *uuid_e)
00253 {
00254 struct wps_pbc_session *pbc, *prev = NULL;
00255
00256 pbc = reg->pbc_sessions;
00257 while (pbc) {
00258 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00259 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00260 if (prev)
00261 prev->next = pbc->next;
00262 else
00263 reg->pbc_sessions = pbc->next;
00264 os_free(pbc);
00265 break;
00266 }
00267 prev = pbc;
00268 pbc = pbc->next;
00269 }
00270 }
00271
00272
00273 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
00274 const u8 *addr, const u8 *uuid_e)
00275 {
00276 int count = 0;
00277 struct wps_pbc_session *pbc;
00278 struct os_time now;
00279
00280 os_get_time(&now);
00281
00282 for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
00283 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
00284 break;
00285 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
00286 uuid_e == NULL ||
00287 os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
00288 count++;
00289 }
00290
00291 if (addr || uuid_e)
00292 count++;
00293
00294 return count > 1 ? 1 : 0;
00295 }
00296
00297
00298 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
00299 {
00300 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
00301 wps->wps_state);
00302 wpabuf_put_be16(msg, ATTR_WPS_STATE);
00303 wpabuf_put_be16(msg, 1);
00304 wpabuf_put_u8(msg, wps->wps_state);
00305 return 0;
00306 }
00307
00308
00309 #ifdef CONFIG_WPS_UPNP
00310 static void wps_registrar_free_pending_m2(struct wps_context *wps)
00311 {
00312 struct upnp_pending_message *p, *p2, *prev = NULL;
00313 p = wps->upnp_msgs;
00314 while (p) {
00315 if (p->type == WPS_M2 || p->type == WPS_M2D) {
00316 if (prev == NULL)
00317 wps->upnp_msgs = p->next;
00318 else
00319 prev->next = p->next;
00320 wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
00321 p2 = p;
00322 p = p->next;
00323 wpabuf_free(p2->msg);
00324 os_free(p2);
00325 continue;
00326 }
00327 prev = p;
00328 p = p->next;
00329 }
00330 }
00331 #endif
00332
00333
00334 static int wps_build_ap_setup_locked(struct wps_context *wps,
00335 struct wpabuf *msg)
00336 {
00337 if (wps->ap_setup_locked) {
00338 wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked");
00339 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
00340 wpabuf_put_be16(msg, 1);
00341 wpabuf_put_u8(msg, 1);
00342 }
00343 return 0;
00344 }
00345
00346
00347 static int wps_build_selected_registrar(struct wps_registrar *reg,
00348 struct wpabuf *msg)
00349 {
00350 if (!reg->selected_registrar)
00351 return 0;
00352 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar");
00353 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
00354 wpabuf_put_be16(msg, 1);
00355 wpabuf_put_u8(msg, 1);
00356 return 0;
00357 }
00358
00359
00360 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
00361 struct wpabuf *msg)
00362 {
00363 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
00364 if (!reg->selected_registrar)
00365 return 0;
00366 if (reg->sel_reg_dev_password_id_override >= 0)
00367 id = reg->sel_reg_dev_password_id_override;
00368 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
00369 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
00370 wpabuf_put_be16(msg, 2);
00371 wpabuf_put_be16(msg, id);
00372 return 0;
00373 }
00374
00375
00376 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
00377 struct wpabuf *msg)
00378 {
00379 u16 methods;
00380 if (!reg->selected_registrar)
00381 return 0;
00382 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00383 if (reg->pbc)
00384 methods |= WPS_CONFIG_PUSHBUTTON;
00385 if (reg->sel_reg_config_methods_override >= 0)
00386 methods = reg->sel_reg_config_methods_override;
00387 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar Config Methods (%x)",
00388 methods);
00389 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
00390 wpabuf_put_be16(msg, 2);
00391 wpabuf_put_be16(msg, methods);
00392 return 0;
00393 }
00394
00395
00396 static int wps_build_probe_config_methods(struct wps_registrar *reg,
00397 struct wpabuf *msg)
00398 {
00399 u16 methods;
00400 methods = 0;
00401 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
00402 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
00403 wpabuf_put_be16(msg, 2);
00404 wpabuf_put_be16(msg, methods);
00405 return 0;
00406 }
00407
00408
00409 static int wps_build_config_methods_r(struct wps_registrar *reg,
00410 struct wpabuf *msg)
00411 {
00412 u16 methods;
00413 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00414 if (reg->pbc)
00415 methods |= WPS_CONFIG_PUSHBUTTON;
00416 return wps_build_config_methods(msg, methods);
00417 }
00418
00419
00420 static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
00421 {
00422 u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
00423 wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", resp);
00424 wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
00425 wpabuf_put_be16(msg, 1);
00426 wpabuf_put_u8(msg, resp);
00427 return 0;
00428 }
00429
00430
00444 struct wps_registrar *
00445 wps_registrar_init(struct wps_context *wps,
00446 const struct wps_registrar_config *cfg)
00447 {
00448 struct wps_registrar *reg = os_zalloc(sizeof(*reg));
00449 if (reg == NULL)
00450 return NULL;
00451
00452 reg->wps = wps;
00453 reg->new_psk_cb = cfg->new_psk_cb;
00454 reg->set_ie_cb = cfg->set_ie_cb;
00455 reg->pin_needed_cb = cfg->pin_needed_cb;
00456 reg->reg_success_cb = cfg->reg_success_cb;
00457 reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
00458 reg->cb_ctx = cfg->cb_ctx;
00459 reg->skip_cred_build = cfg->skip_cred_build;
00460 if (cfg->extra_cred) {
00461 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
00462 cfg->extra_cred_len);
00463 if (reg->extra_cred == NULL) {
00464 os_free(reg);
00465 return NULL;
00466 }
00467 }
00468 reg->disable_auto_conf = cfg->disable_auto_conf;
00469 reg->sel_reg_dev_password_id_override = -1;
00470 reg->sel_reg_config_methods_override = -1;
00471 reg->static_wep_only = cfg->static_wep_only;
00472
00473 if (wps_set_ie(reg)) {
00474 wps_registrar_deinit(reg);
00475 return NULL;
00476 }
00477
00478 return reg;
00479 }
00480
00481
00487 void wps_registrar_deinit(struct wps_registrar *reg)
00488 {
00489 if (reg == NULL)
00490 return;
00491 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00492 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00493 wps_free_pins(reg->pins);
00494 wps_free_pbc_sessions(reg->pbc_sessions);
00495 wpabuf_free(reg->extra_cred);
00496 wps_free_devices(reg->devices);
00497 os_free(reg);
00498 }
00499
00500
00511 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
00512 const u8 *pin, size_t pin_len, int timeout)
00513 {
00514 struct wps_uuid_pin *p;
00515
00516 p = os_zalloc(sizeof(*p));
00517 if (p == NULL)
00518 return -1;
00519 if (uuid == NULL)
00520 p->wildcard_uuid = 1;
00521 else
00522 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
00523 p->pin = os_malloc(pin_len);
00524 if (p->pin == NULL) {
00525 os_free(p);
00526 return -1;
00527 }
00528 os_memcpy(p->pin, pin, pin_len);
00529 p->pin_len = pin_len;
00530
00531 if (timeout) {
00532 p->flags |= PIN_EXPIRES;
00533 os_get_time(&p->expiration);
00534 p->expiration.sec += timeout;
00535 }
00536
00537 p->next = reg->pins;
00538 reg->pins = p;
00539
00540 wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
00541 timeout);
00542 wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
00543 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
00544 reg->selected_registrar = 1;
00545 reg->pbc = 0;
00546 wps_set_ie(reg);
00547 wps_cb_set_sel_reg(reg);
00548 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00549 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
00550 wps_registrar_set_selected_timeout,
00551 reg, NULL);
00552
00553 return 0;
00554 }
00555
00556
00557 static void wps_registrar_expire_pins(struct wps_registrar *reg)
00558 {
00559 struct wps_uuid_pin *pin, *prev, *del;
00560 struct os_time now;
00561
00562 os_get_time(&now);
00563 prev = NULL;
00564 pin = reg->pins;
00565 while (pin) {
00566 if ((pin->flags & PIN_EXPIRES) &&
00567 os_time_before(&pin->expiration, &now)) {
00568 if (prev == NULL)
00569 reg->pins = pin->next;
00570 else
00571 prev->next = pin->next;
00572 del = pin;
00573 pin = pin->next;
00574 wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
00575 del->uuid, WPS_UUID_LEN);
00576 wps_free_pin(del);
00577 continue;
00578 }
00579 prev = pin;
00580 pin = pin->next;
00581 }
00582 }
00583
00584
00592 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
00593 {
00594 struct wps_uuid_pin *pin, *prev;
00595
00596 prev = NULL;
00597 pin = reg->pins;
00598 while (pin) {
00599 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00600 if (prev == NULL)
00601 reg->pins = pin->next;
00602 else
00603 prev->next = pin->next;
00604 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
00605 pin->uuid, WPS_UUID_LEN);
00606 wps_free_pin(pin);
00607 return 0;
00608 }
00609 prev = pin;
00610 pin = pin->next;
00611 }
00612
00613 return -1;
00614 }
00615
00616
00617 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
00618 const u8 *uuid, size_t *pin_len)
00619 {
00620 struct wps_uuid_pin *pin;
00621
00622 wps_registrar_expire_pins(reg);
00623
00624 pin = reg->pins;
00625 while (pin) {
00626 if (!pin->wildcard_uuid &&
00627 os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
00628 break;
00629 pin = pin->next;
00630 }
00631
00632 if (!pin) {
00633
00634
00635 pin = reg->pins;
00636 while (pin) {
00637 if (pin->wildcard_uuid == 1) {
00638 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
00639 "PIN. Assigned it for this UUID-E");
00640 pin->wildcard_uuid = 2;
00641 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
00642 break;
00643 }
00644 pin = pin->next;
00645 }
00646 }
00647
00648 if (!pin)
00649 return NULL;
00650
00651
00652
00653
00654
00655 if (pin->flags & PIN_LOCKED) {
00656 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
00657 "allow concurrent re-use");
00658 return NULL;
00659 }
00660 *pin_len = pin->pin_len;
00661 pin->flags |= PIN_LOCKED;
00662 return pin->pin;
00663 }
00664
00665
00677 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
00678 {
00679 struct wps_uuid_pin *pin;
00680
00681 pin = reg->pins;
00682 while (pin) {
00683 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00684 if (pin->wildcard_uuid == 2) {
00685 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
00686 "wildcard PIN");
00687 return wps_registrar_invalidate_pin(reg, uuid);
00688 }
00689 pin->flags &= ~PIN_LOCKED;
00690 return 0;
00691 }
00692 pin = pin->next;
00693 }
00694
00695 return -1;
00696 }
00697
00698
00699 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
00700 {
00701 reg->selected_registrar = 0;
00702 reg->pbc = 0;
00703 wps_set_ie(reg);
00704 wps_cb_set_sel_reg(reg);
00705 }
00706
00707
00708 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
00709 {
00710 struct wps_registrar *reg = eloop_ctx;
00711
00712 wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
00713 wps_pbc_timeout_event(reg->wps);
00714 wps_registrar_stop_pbc(reg);
00715 }
00716
00717
00728 int wps_registrar_button_pushed(struct wps_registrar *reg)
00729 {
00730 if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
00731 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
00732 "mode");
00733 wps_pbc_overlap_event(reg->wps);
00734 return -1;
00735 }
00736 wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
00737 reg->force_pbc_overlap = 0;
00738 reg->selected_registrar = 1;
00739 reg->pbc = 1;
00740 wps_set_ie(reg);
00741 wps_cb_set_sel_reg(reg);
00742
00743 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00744 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
00745 reg, NULL);
00746 return 0;
00747 }
00748
00749
00750 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
00751 {
00752 wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
00753 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00754 wps_registrar_stop_pbc(reg);
00755 }
00756
00757 static void wps_registrar_pin_completed(struct wps_registrar *reg)
00758 {
00759 wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
00760 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00761 reg->selected_registrar = 0;
00762 wps_set_ie(reg);
00763 wps_cb_set_sel_reg(reg);
00764 }
00765
00766
00778 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
00779 const struct wpabuf *wps_data)
00780 {
00781 struct wps_parse_attr attr;
00782 u16 methods;
00783
00784 wpa_hexdump_buf(MSG_MSGDUMP,
00785 "WPS: Probe Request with WPS data received",
00786 wps_data);
00787
00788 if (wps_parse_msg(wps_data, &attr) < 0)
00789 return;
00790 if (!wps_version_supported(attr.version)) {
00791 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
00792 "version 0x%x", attr.version ? *attr.version : 0);
00793 return;
00794 }
00795
00796 if (attr.config_methods == NULL) {
00797 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
00798 "Probe Request");
00799 return;
00800 }
00801
00802 methods = WPA_GET_BE16(attr.config_methods);
00803 if (!(methods & WPS_CONFIG_PUSHBUTTON))
00804 return;
00805
00806 wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
00807 MACSTR, MAC2STR(addr));
00808
00809 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
00810 if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
00811 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
00812 reg->force_pbc_overlap = 1;
00813 wps_pbc_overlap_event(reg->wps);
00814 }
00815 }
00816
00817
00818 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
00819 const u8 *psk, size_t psk_len)
00820 {
00821 if (reg->new_psk_cb == NULL)
00822 return 0;
00823
00824 return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
00825 }
00826
00827
00828 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
00829 const struct wps_device_data *dev)
00830 {
00831 if (reg->pin_needed_cb == NULL)
00832 return;
00833
00834 reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
00835 }
00836
00837
00838 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
00839 const u8 *uuid_e)
00840 {
00841 if (reg->reg_success_cb == NULL)
00842 return;
00843
00844 reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
00845 }
00846
00847
00848 static int wps_cb_set_ie(struct wps_registrar *reg,
00849 const struct wpabuf *beacon_ie,
00850 const struct wpabuf *probe_resp_ie)
00851 {
00852 if (reg->set_ie_cb == NULL)
00853 return 0;
00854
00855 return reg->set_ie_cb(reg->cb_ctx, wpabuf_head(beacon_ie),
00856 wpabuf_len(beacon_ie),
00857 wpabuf_head(probe_resp_ie),
00858 wpabuf_len(probe_resp_ie));
00859 }
00860
00861
00862 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
00863 {
00864 u16 methods = 0;
00865 if (reg->set_sel_reg_cb == NULL)
00866 return;
00867
00868 if (reg->selected_registrar) {
00869 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00870 if (reg->pbc)
00871 methods |= WPS_CONFIG_PUSHBUTTON;
00872 }
00873
00874 reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
00875 reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
00876 methods);
00877 }
00878
00879
00880
00881 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
00882 {
00883 struct wpabuf *ie;
00884 const u8 *pos, *end;
00885
00886 ie = wpabuf_alloc(wpabuf_len(data) + 100);
00887 if (ie == NULL) {
00888 wpabuf_free(data);
00889 return NULL;
00890 }
00891
00892 pos = wpabuf_head(data);
00893 end = pos + wpabuf_len(data);
00894
00895 while (end > pos) {
00896 size_t frag_len = end - pos;
00897 if (frag_len > 251)
00898 frag_len = 251;
00899 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
00900 wpabuf_put_u8(ie, 4 + frag_len);
00901 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
00902 wpabuf_put_data(ie, pos, frag_len);
00903 pos += frag_len;
00904 }
00905
00906 wpabuf_free(data);
00907
00908 return ie;
00909 }
00910
00911
00912 static int wps_set_ie(struct wps_registrar *reg)
00913 {
00914 struct wpabuf *beacon;
00915 struct wpabuf *probe;
00916 int ret;
00917
00918 wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
00919
00920 beacon = wpabuf_alloc(300);
00921 if (beacon == NULL)
00922 return -1;
00923 probe = wpabuf_alloc(400);
00924 if (probe == NULL) {
00925 wpabuf_free(beacon);
00926 return -1;
00927 }
00928
00929 if (wps_build_version(beacon) ||
00930 wps_build_wps_state(reg->wps, beacon) ||
00931 wps_build_ap_setup_locked(reg->wps, beacon) ||
00932 wps_build_selected_registrar(reg, beacon) ||
00933 wps_build_sel_reg_dev_password_id(reg, beacon) ||
00934 wps_build_sel_reg_config_methods(reg, beacon) ||
00935 wps_build_version(probe) ||
00936 wps_build_wps_state(reg->wps, probe) ||
00937 wps_build_ap_setup_locked(reg->wps, probe) ||
00938 wps_build_selected_registrar(reg, probe) ||
00939 wps_build_sel_reg_dev_password_id(reg, probe) ||
00940 wps_build_sel_reg_config_methods(reg, probe) ||
00941 wps_build_resp_type(reg, probe) ||
00942 wps_build_uuid_e(probe, reg->wps->uuid) ||
00943 wps_build_device_attrs(®->wps->dev, probe) ||
00944 wps_build_probe_config_methods(reg, probe) ||
00945 wps_build_rf_bands(®->wps->dev, probe)) {
00946 wpabuf_free(beacon);
00947 wpabuf_free(probe);
00948 return -1;
00949 }
00950
00951 beacon = wps_ie_encapsulate(beacon);
00952 probe = wps_ie_encapsulate(probe);
00953
00954 if (!beacon || !probe) {
00955 wpabuf_free(beacon);
00956 wpabuf_free(probe);
00957 return -1;
00958 }
00959
00960 if (reg->static_wep_only) {
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 const u8 ms_wps[7] = {
00971 WLAN_EID_VENDOR_SPECIFIC, 5,
00972
00973 0x00, 0x50, 0xf2, 5,
00974 0x00
00975 };
00976 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
00977 "into Beacon/Probe Response frames");
00978 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
00979 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
00980 }
00981
00982 ret = wps_cb_set_ie(reg, beacon, probe);
00983 wpabuf_free(beacon);
00984 wpabuf_free(probe);
00985
00986 return ret;
00987 }
00988
00989
00990 static int wps_get_dev_password(struct wps_data *wps)
00991 {
00992 const u8 *pin;
00993 size_t pin_len = 0;
00994
00995 os_free(wps->dev_password);
00996 wps->dev_password = NULL;
00997
00998 if (wps->pbc) {
00999 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
01000 pin = (const u8 *) "00000000";
01001 pin_len = 8;
01002 } else {
01003 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
01004 &pin_len);
01005 }
01006 if (pin == NULL) {
01007 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
01008 "the Enrollee");
01009 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
01010 &wps->peer_dev);
01011 return -1;
01012 }
01013
01014 wps->dev_password = os_malloc(pin_len);
01015 if (wps->dev_password == NULL)
01016 return -1;
01017 os_memcpy(wps->dev_password, pin, pin_len);
01018 wps->dev_password_len = pin_len;
01019
01020 return 0;
01021 }
01022
01023
01024 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
01025 {
01026 wpa_printf(MSG_DEBUG, "WPS: * UUID-R");
01027 wpabuf_put_be16(msg, ATTR_UUID_R);
01028 wpabuf_put_be16(msg, WPS_UUID_LEN);
01029 wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
01030 return 0;
01031 }
01032
01033
01034 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
01035 {
01036 u8 *hash;
01037 const u8 *addr[4];
01038 size_t len[4];
01039
01040 if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
01041 return -1;
01042 wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
01043 wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
01044 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
01045
01046 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
01047 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
01048 "R-Hash derivation");
01049 return -1;
01050 }
01051
01052 wpa_printf(MSG_DEBUG, "WPS: * R-Hash1");
01053 wpabuf_put_be16(msg, ATTR_R_HASH1);
01054 wpabuf_put_be16(msg, SHA256_MAC_LEN);
01055 hash = wpabuf_put(msg, SHA256_MAC_LEN);
01056
01057 addr[0] = wps->snonce;
01058 len[0] = WPS_SECRET_NONCE_LEN;
01059 addr[1] = wps->psk1;
01060 len[1] = WPS_PSK_LEN;
01061 addr[2] = wpabuf_head(wps->dh_pubkey_e);
01062 len[2] = wpabuf_len(wps->dh_pubkey_e);
01063 addr[3] = wpabuf_head(wps->dh_pubkey_r);
01064 len[3] = wpabuf_len(wps->dh_pubkey_r);
01065 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01066 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
01067
01068 wpa_printf(MSG_DEBUG, "WPS: * R-Hash2");
01069 wpabuf_put_be16(msg, ATTR_R_HASH2);
01070 wpabuf_put_be16(msg, SHA256_MAC_LEN);
01071 hash = wpabuf_put(msg, SHA256_MAC_LEN);
01072
01073 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
01074 addr[1] = wps->psk2;
01075 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01076 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
01077
01078 return 0;
01079 }
01080
01081
01082 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
01083 {
01084 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce1");
01085 wpabuf_put_be16(msg, ATTR_R_SNONCE1);
01086 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01087 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
01088 return 0;
01089 }
01090
01091
01092 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
01093 {
01094 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce2");
01095 wpabuf_put_be16(msg, ATTR_R_SNONCE2);
01096 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01097 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
01098 WPS_SECRET_NONCE_LEN);
01099 return 0;
01100 }
01101
01102
01103 static int wps_build_cred_network_idx(struct wpabuf *msg,
01104 const struct wps_credential *cred)
01105 {
01106 wpa_printf(MSG_DEBUG, "WPS: * Network Index");
01107 wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
01108 wpabuf_put_be16(msg, 1);
01109 wpabuf_put_u8(msg, 1);
01110 return 0;
01111 }
01112
01113
01114 static int wps_build_cred_ssid(struct wpabuf *msg,
01115 const struct wps_credential *cred)
01116 {
01117 wpa_printf(MSG_DEBUG, "WPS: * SSID");
01118 wpabuf_put_be16(msg, ATTR_SSID);
01119 wpabuf_put_be16(msg, cred->ssid_len);
01120 wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
01121 return 0;
01122 }
01123
01124
01125 static int wps_build_cred_auth_type(struct wpabuf *msg,
01126 const struct wps_credential *cred)
01127 {
01128 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)",
01129 cred->auth_type);
01130 wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
01131 wpabuf_put_be16(msg, 2);
01132 wpabuf_put_be16(msg, cred->auth_type);
01133 return 0;
01134 }
01135
01136
01137 static int wps_build_cred_encr_type(struct wpabuf *msg,
01138 const struct wps_credential *cred)
01139 {
01140 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)",
01141 cred->encr_type);
01142 wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
01143 wpabuf_put_be16(msg, 2);
01144 wpabuf_put_be16(msg, cred->encr_type);
01145 return 0;
01146 }
01147
01148
01149 static int wps_build_cred_network_key(struct wpabuf *msg,
01150 const const struct wps_credential *cred)
01151 {
01152 wpa_printf(MSG_DEBUG, "WPS: * Network Key");
01153 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
01154 wpabuf_put_be16(msg, cred->key_len);
01155 wpabuf_put_data(msg, cred->key, cred->key_len);
01156 return 0;
01157 }
01158
01159
01160 static int wps_build_cred_mac_addr(struct wpabuf *msg,
01161 const struct wps_credential *cred)
01162 {
01163 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")",
01164 MAC2STR(cred->mac_addr));
01165 wpabuf_put_be16(msg, ATTR_MAC_ADDR);
01166 wpabuf_put_be16(msg, ETH_ALEN);
01167 wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
01168 return 0;
01169 }
01170
01171
01172 static int wps_build_credential(struct wpabuf *msg,
01173 const struct wps_credential *cred)
01174 {
01175 if (wps_build_cred_network_idx(msg, cred) ||
01176 wps_build_cred_ssid(msg, cred) ||
01177 wps_build_cred_auth_type(msg, cred) ||
01178 wps_build_cred_encr_type(msg, cred) ||
01179 wps_build_cred_network_key(msg, cred) ||
01180 wps_build_cred_mac_addr(msg, cred))
01181 return -1;
01182 return 0;
01183 }
01184
01185
01186 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
01187 {
01188 struct wpabuf *cred;
01189
01190 if (wps->wps->registrar->skip_cred_build)
01191 goto skip_cred_build;
01192
01193 wpa_printf(MSG_DEBUG, "WPS: * Credential");
01194 if (wps->use_cred) {
01195 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
01196 goto use_provided;
01197 }
01198 os_memset(&wps->cred, 0, sizeof(wps->cred));
01199
01200 os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
01201 wps->cred.ssid_len = wps->wps->ssid_len;
01202
01203
01204 if (wps->auth_type & WPS_AUTH_WPA2PSK)
01205 wps->auth_type = WPS_AUTH_WPA2PSK;
01206 else if (wps->auth_type & WPS_AUTH_WPAPSK)
01207 wps->auth_type = WPS_AUTH_WPAPSK;
01208 else if (wps->auth_type & WPS_AUTH_OPEN)
01209 wps->auth_type = WPS_AUTH_OPEN;
01210 else if (wps->auth_type & WPS_AUTH_SHARED)
01211 wps->auth_type = WPS_AUTH_SHARED;
01212 else {
01213 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
01214 wps->auth_type);
01215 return -1;
01216 }
01217 wps->cred.auth_type = wps->auth_type;
01218
01219 if (wps->auth_type == WPS_AUTH_WPA2PSK ||
01220 wps->auth_type == WPS_AUTH_WPAPSK) {
01221 if (wps->encr_type & WPS_ENCR_AES)
01222 wps->encr_type = WPS_ENCR_AES;
01223 else if (wps->encr_type & WPS_ENCR_TKIP)
01224 wps->encr_type = WPS_ENCR_TKIP;
01225 else {
01226 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01227 "type for WPA/WPA2");
01228 return -1;
01229 }
01230 } else {
01231 if (wps->encr_type & WPS_ENCR_WEP)
01232 wps->encr_type = WPS_ENCR_WEP;
01233 else if (wps->encr_type & WPS_ENCR_NONE)
01234 wps->encr_type = WPS_ENCR_NONE;
01235 else {
01236 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01237 "type for non-WPA/WPA2 mode");
01238 return -1;
01239 }
01240 }
01241 wps->cred.encr_type = wps->encr_type;
01242
01243
01244
01245 os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
01246
01247 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
01248 !wps->wps->registrar->disable_auto_conf) {
01249 u8 r[16];
01250
01251 if (os_get_random(r, sizeof(r)) < 0)
01252 return -1;
01253 os_free(wps->new_psk);
01254 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
01255 if (wps->new_psk == NULL)
01256 return -1;
01257 wps->new_psk_len--;
01258 while (wps->new_psk_len &&
01259 wps->new_psk[wps->new_psk_len - 1] == '=')
01260 wps->new_psk_len--;
01261 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
01262 wps->new_psk, wps->new_psk_len);
01263 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
01264 wps->cred.key_len = wps->new_psk_len;
01265 } else if (wps->wps->network_key) {
01266 os_memcpy(wps->cred.key, wps->wps->network_key,
01267 wps->wps->network_key_len);
01268 wps->cred.key_len = wps->wps->network_key_len;
01269 } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
01270 char hex[65];
01271
01272 os_free(wps->new_psk);
01273 wps->new_psk_len = 32;
01274 wps->new_psk = os_malloc(wps->new_psk_len);
01275 if (wps->new_psk == NULL)
01276 return -1;
01277 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
01278 os_free(wps->new_psk);
01279 wps->new_psk = NULL;
01280 return -1;
01281 }
01282 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
01283 wps->new_psk, wps->new_psk_len);
01284 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
01285 wps->new_psk_len);
01286 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
01287 wps->cred.key_len = wps->new_psk_len * 2;
01288 }
01289
01290 use_provided:
01291 cred = wpabuf_alloc(200);
01292 if (cred == NULL)
01293 return -1;
01294
01295 if (wps_build_credential(cred, &wps->cred)) {
01296 wpabuf_free(cred);
01297 return -1;
01298 }
01299
01300 wpabuf_put_be16(msg, ATTR_CRED);
01301 wpabuf_put_be16(msg, wpabuf_len(cred));
01302 wpabuf_put_buf(msg, cred);
01303 wpabuf_free(cred);
01304
01305 skip_cred_build:
01306 if (wps->wps->registrar->extra_cred) {
01307 wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)");
01308 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
01309 }
01310
01311 return 0;
01312 }
01313
01314
01315 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
01316 {
01317 wpa_printf(MSG_DEBUG, "WPS: * AP Settings");
01318
01319 if (wps_build_credential(msg, &wps->cred))
01320 return -1;
01321
01322 return 0;
01323 }
01324
01325
01326 static struct wpabuf * wps_build_m2(struct wps_data *wps)
01327 {
01328 struct wpabuf *msg;
01329
01330 if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
01331 return NULL;
01332 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
01333 wps->nonce_r, WPS_NONCE_LEN);
01334 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
01335
01336 wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
01337 msg = wpabuf_alloc(1000);
01338 if (msg == NULL)
01339 return NULL;
01340
01341 if (wps_build_version(msg) ||
01342 wps_build_msg_type(msg, WPS_M2) ||
01343 wps_build_enrollee_nonce(wps, msg) ||
01344 wps_build_registrar_nonce(wps, msg) ||
01345 wps_build_uuid_r(wps, msg) ||
01346 wps_build_public_key(wps, msg) ||
01347 wps_derive_keys(wps) ||
01348 wps_build_auth_type_flags(wps, msg) ||
01349 wps_build_encr_type_flags(wps, msg) ||
01350 wps_build_conn_type_flags(wps, msg) ||
01351 wps_build_config_methods_r(wps->wps->registrar, msg) ||
01352 wps_build_device_attrs(&wps->wps->dev, msg) ||
01353 wps_build_rf_bands(&wps->wps->dev, msg) ||
01354 wps_build_assoc_state(wps, msg) ||
01355 wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
01356 wps_build_dev_password_id(msg, wps->dev_pw_id) ||
01357 wps_build_os_version(&wps->wps->dev, msg) ||
01358 wps_build_authenticator(wps, msg)) {
01359 wpabuf_free(msg);
01360 return NULL;
01361 }
01362
01363 wps->state = RECV_M3;
01364 return msg;
01365 }
01366
01367
01368 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
01369 {
01370 struct wpabuf *msg;
01371 u16 err = wps->config_error;
01372
01373 wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
01374 msg = wpabuf_alloc(1000);
01375 if (msg == NULL)
01376 return NULL;
01377
01378 if (wps->wps->ap && wps->wps->ap_setup_locked &&
01379 err == WPS_CFG_NO_ERROR)
01380 err = WPS_CFG_SETUP_LOCKED;
01381
01382 if (wps_build_version(msg) ||
01383 wps_build_msg_type(msg, WPS_M2D) ||
01384 wps_build_enrollee_nonce(wps, msg) ||
01385 wps_build_registrar_nonce(wps, msg) ||
01386 wps_build_uuid_r(wps, msg) ||
01387 wps_build_auth_type_flags(wps, msg) ||
01388 wps_build_encr_type_flags(wps, msg) ||
01389 wps_build_conn_type_flags(wps, msg) ||
01390 wps_build_config_methods_r(wps->wps->registrar, msg) ||
01391 wps_build_device_attrs(&wps->wps->dev, msg) ||
01392 wps_build_rf_bands(&wps->wps->dev, msg) ||
01393 wps_build_assoc_state(wps, msg) ||
01394 wps_build_config_error(msg, err) ||
01395 wps_build_os_version(&wps->wps->dev, msg)) {
01396 wpabuf_free(msg);
01397 return NULL;
01398 }
01399
01400 wps->state = RECV_M2D_ACK;
01401 return msg;
01402 }
01403
01404
01405 static struct wpabuf * wps_build_m4(struct wps_data *wps)
01406 {
01407 struct wpabuf *msg, *plain;
01408
01409 wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
01410
01411 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
01412
01413 plain = wpabuf_alloc(200);
01414 if (plain == NULL)
01415 return NULL;
01416
01417 msg = wpabuf_alloc(1000);
01418 if (msg == NULL) {
01419 wpabuf_free(plain);
01420 return NULL;
01421 }
01422
01423 if (wps_build_version(msg) ||
01424 wps_build_msg_type(msg, WPS_M4) ||
01425 wps_build_enrollee_nonce(wps, msg) ||
01426 wps_build_r_hash(wps, msg) ||
01427 wps_build_r_snonce1(wps, plain) ||
01428 wps_build_key_wrap_auth(wps, plain) ||
01429 wps_build_encr_settings(wps, msg, plain) ||
01430 wps_build_authenticator(wps, msg)) {
01431 wpabuf_free(plain);
01432 wpabuf_free(msg);
01433 return NULL;
01434 }
01435 wpabuf_free(plain);
01436
01437 wps->state = RECV_M5;
01438 return msg;
01439 }
01440
01441
01442 static struct wpabuf * wps_build_m6(struct wps_data *wps)
01443 {
01444 struct wpabuf *msg, *plain;
01445
01446 wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
01447
01448 plain = wpabuf_alloc(200);
01449 if (plain == NULL)
01450 return NULL;
01451
01452 msg = wpabuf_alloc(1000);
01453 if (msg == NULL) {
01454 wpabuf_free(plain);
01455 return NULL;
01456 }
01457
01458 if (wps_build_version(msg) ||
01459 wps_build_msg_type(msg, WPS_M6) ||
01460 wps_build_enrollee_nonce(wps, msg) ||
01461 wps_build_r_snonce2(wps, plain) ||
01462 wps_build_key_wrap_auth(wps, plain) ||
01463 wps_build_encr_settings(wps, msg, plain) ||
01464 wps_build_authenticator(wps, msg)) {
01465 wpabuf_free(plain);
01466 wpabuf_free(msg);
01467 return NULL;
01468 }
01469 wpabuf_free(plain);
01470
01471 wps->wps_pin_revealed = 1;
01472 wps->state = RECV_M7;
01473 return msg;
01474 }
01475
01476
01477 static struct wpabuf * wps_build_m8(struct wps_data *wps)
01478 {
01479 struct wpabuf *msg, *plain;
01480
01481 wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
01482
01483 plain = wpabuf_alloc(500);
01484 if (plain == NULL)
01485 return NULL;
01486
01487 msg = wpabuf_alloc(1000);
01488 if (msg == NULL) {
01489 wpabuf_free(plain);
01490 return NULL;
01491 }
01492
01493 if (wps_build_version(msg) ||
01494 wps_build_msg_type(msg, WPS_M8) ||
01495 wps_build_enrollee_nonce(wps, msg) ||
01496 ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
01497 (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
01498 wps_build_key_wrap_auth(wps, plain) ||
01499 wps_build_encr_settings(wps, msg, plain) ||
01500 wps_build_authenticator(wps, msg)) {
01501 wpabuf_free(plain);
01502 wpabuf_free(msg);
01503 return NULL;
01504 }
01505 wpabuf_free(plain);
01506
01507 wps->state = RECV_DONE;
01508 return msg;
01509 }
01510
01511
01512 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
01513 {
01514 struct wpabuf *msg;
01515
01516 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
01517
01518 msg = wpabuf_alloc(1000);
01519 if (msg == NULL)
01520 return NULL;
01521
01522 if (wps_build_version(msg) ||
01523 wps_build_msg_type(msg, WPS_WSC_ACK) ||
01524 wps_build_enrollee_nonce(wps, msg) ||
01525 wps_build_registrar_nonce(wps, msg)) {
01526 wpabuf_free(msg);
01527 return NULL;
01528 }
01529
01530 return msg;
01531 }
01532
01533
01534 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
01535 {
01536 struct wpabuf *msg;
01537
01538 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
01539
01540 msg = wpabuf_alloc(1000);
01541 if (msg == NULL)
01542 return NULL;
01543
01544 if (wps_build_version(msg) ||
01545 wps_build_msg_type(msg, WPS_WSC_NACK) ||
01546 wps_build_enrollee_nonce(wps, msg) ||
01547 wps_build_registrar_nonce(wps, msg) ||
01548 wps_build_config_error(msg, wps->config_error)) {
01549 wpabuf_free(msg);
01550 return NULL;
01551 }
01552
01553 return msg;
01554 }
01555
01556
01557 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
01558 enum wsc_op_code *op_code)
01559 {
01560 struct wpabuf *msg;
01561
01562 #ifdef CONFIG_WPS_UPNP
01563 if (wps->wps->wps_upnp) {
01564 struct upnp_pending_message *p, *prev = NULL;
01565 if (wps->ext_reg > 1)
01566 wps_registrar_free_pending_m2(wps->wps);
01567 p = wps->wps->upnp_msgs;
01568
01569 while (p && p->next) {
01570 prev = p;
01571 p = p->next;
01572 }
01573 if (p) {
01574 wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
01575 "UPnP");
01576 if (prev)
01577 prev->next = NULL;
01578 else
01579 wps->wps->upnp_msgs = NULL;
01580 msg = p->msg;
01581 switch (p->type) {
01582 case WPS_WSC_ACK:
01583 *op_code = WSC_ACK;
01584 break;
01585 case WPS_WSC_NACK:
01586 *op_code = WSC_NACK;
01587 break;
01588 default:
01589 *op_code = WSC_MSG;
01590 break;
01591 }
01592 os_free(p);
01593 if (wps->ext_reg == 0)
01594 wps->ext_reg = 1;
01595 return msg;
01596 }
01597 }
01598 if (wps->ext_reg) {
01599 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
01600 "pending message available");
01601 return NULL;
01602 }
01603 #endif
01604
01605 switch (wps->state) {
01606 case SEND_M2:
01607 if (wps_get_dev_password(wps) < 0)
01608 msg = wps_build_m2d(wps);
01609 else
01610 msg = wps_build_m2(wps);
01611 *op_code = WSC_MSG;
01612 break;
01613 case SEND_M2D:
01614 msg = wps_build_m2d(wps);
01615 *op_code = WSC_MSG;
01616 break;
01617 case SEND_M4:
01618 msg = wps_build_m4(wps);
01619 *op_code = WSC_MSG;
01620 break;
01621 case SEND_M6:
01622 msg = wps_build_m6(wps);
01623 *op_code = WSC_MSG;
01624 break;
01625 case SEND_M8:
01626 msg = wps_build_m8(wps);
01627 *op_code = WSC_MSG;
01628 break;
01629 case RECV_DONE:
01630 msg = wps_build_wsc_ack(wps);
01631 *op_code = WSC_ACK;
01632 break;
01633 case SEND_WSC_NACK:
01634 msg = wps_build_wsc_nack(wps);
01635 *op_code = WSC_NACK;
01636 break;
01637 default:
01638 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
01639 "a message", wps->state);
01640 msg = NULL;
01641 break;
01642 }
01643
01644 if (*op_code == WSC_MSG && msg) {
01645
01646
01647 wpabuf_free(wps->last_msg);
01648 wps->last_msg = wpabuf_dup(msg);
01649 }
01650
01651 return msg;
01652 }
01653
01654
01655 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
01656 {
01657 if (e_nonce == NULL) {
01658 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
01659 return -1;
01660 }
01661
01662 os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
01663 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
01664 wps->nonce_e, WPS_NONCE_LEN);
01665
01666 return 0;
01667 }
01668
01669
01670 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
01671 {
01672 if (r_nonce == NULL) {
01673 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
01674 return -1;
01675 }
01676
01677 if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
01678 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
01679 return -1;
01680 }
01681
01682 return 0;
01683 }
01684
01685
01686 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
01687 {
01688 if (uuid_e == NULL) {
01689 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
01690 return -1;
01691 }
01692
01693 os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
01694 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
01695
01696 return 0;
01697 }
01698
01699
01700 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
01701 {
01702 if (pw_id == NULL) {
01703 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
01704 return -1;
01705 }
01706
01707 wps->dev_pw_id = WPA_GET_BE16(pw_id);
01708 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
01709
01710 return 0;
01711 }
01712
01713
01714 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
01715 {
01716 if (e_hash1 == NULL) {
01717 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
01718 return -1;
01719 }
01720
01721 os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
01722 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
01723
01724 return 0;
01725 }
01726
01727
01728 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
01729 {
01730 if (e_hash2 == NULL) {
01731 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
01732 return -1;
01733 }
01734
01735 os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
01736 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
01737
01738 return 0;
01739 }
01740
01741
01742 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
01743 {
01744 u8 hash[SHA256_MAC_LEN];
01745 const u8 *addr[4];
01746 size_t len[4];
01747
01748 if (e_snonce1 == NULL) {
01749 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
01750 return -1;
01751 }
01752
01753 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
01754 WPS_SECRET_NONCE_LEN);
01755
01756
01757 addr[0] = e_snonce1;
01758 len[0] = WPS_SECRET_NONCE_LEN;
01759 addr[1] = wps->psk1;
01760 len[1] = WPS_PSK_LEN;
01761 addr[2] = wpabuf_head(wps->dh_pubkey_e);
01762 len[2] = wpabuf_len(wps->dh_pubkey_e);
01763 addr[3] = wpabuf_head(wps->dh_pubkey_r);
01764 len[3] = wpabuf_len(wps->dh_pubkey_r);
01765 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01766
01767 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
01768 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
01769 "not match with the pre-committed value");
01770 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01771 wps_pwd_auth_fail_event(wps->wps, 0, 1);
01772 return -1;
01773 }
01774
01775 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
01776 "half of the device password");
01777
01778 return 0;
01779 }
01780
01781
01782 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
01783 {
01784 u8 hash[SHA256_MAC_LEN];
01785 const u8 *addr[4];
01786 size_t len[4];
01787
01788 if (e_snonce2 == NULL) {
01789 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
01790 return -1;
01791 }
01792
01793 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
01794 WPS_SECRET_NONCE_LEN);
01795
01796
01797 addr[0] = e_snonce2;
01798 len[0] = WPS_SECRET_NONCE_LEN;
01799 addr[1] = wps->psk2;
01800 len[1] = WPS_PSK_LEN;
01801 addr[2] = wpabuf_head(wps->dh_pubkey_e);
01802 len[2] = wpabuf_len(wps->dh_pubkey_e);
01803 addr[3] = wpabuf_head(wps->dh_pubkey_r);
01804 len[3] = wpabuf_len(wps->dh_pubkey_r);
01805 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01806
01807 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
01808 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
01809 "not match with the pre-committed value");
01810 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
01811 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01812 wps_pwd_auth_fail_event(wps->wps, 0, 2);
01813 return -1;
01814 }
01815
01816 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
01817 "half of the device password");
01818 wps->wps_pin_revealed = 0;
01819 wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
01820
01821 return 0;
01822 }
01823
01824
01825 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
01826 {
01827 if (mac_addr == NULL) {
01828 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
01829 return -1;
01830 }
01831
01832 wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
01833 MAC2STR(mac_addr));
01834 os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
01835 os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
01836
01837 return 0;
01838 }
01839
01840
01841 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
01842 size_t pk_len)
01843 {
01844 if (pk == NULL || pk_len == 0) {
01845 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
01846 return -1;
01847 }
01848
01849 #ifdef CONFIG_WPS_OOB
01850 if (wps->wps->oob_conf.pubkey_hash != NULL) {
01851 const u8 *addr[1];
01852 u8 hash[WPS_HASH_LEN];
01853
01854 addr[0] = pk;
01855 sha256_vector(1, addr, &pk_len, hash);
01856 if (os_memcmp(hash,
01857 wpabuf_head(wps->wps->oob_conf.pubkey_hash),
01858 WPS_OOB_PUBKEY_HASH_LEN) != 0) {
01859 wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
01860 return -1;
01861 }
01862 }
01863 #endif
01864
01865 wpabuf_free(wps->dh_pubkey_e);
01866 wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
01867 if (wps->dh_pubkey_e == NULL)
01868 return -1;
01869
01870 return 0;
01871 }
01872
01873
01874 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
01875 {
01876 u16 auth_types;
01877
01878 if (auth == NULL) {
01879 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
01880 "received");
01881 return -1;
01882 }
01883
01884 auth_types = WPA_GET_BE16(auth);
01885
01886 wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
01887 auth_types);
01888 wps->auth_type = wps->wps->auth_types & auth_types;
01889 if (wps->auth_type == 0) {
01890 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01891 "authentication types (own 0x%x Enrollee 0x%x)",
01892 wps->wps->auth_types, auth_types);
01893 #ifdef WPS_WORKAROUNDS
01894
01895
01896
01897
01898
01899
01900
01901 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01902 "does not advertise supported authentication types "
01903 "correctly");
01904 wps->auth_type = wps->wps->auth_types;
01905 #else
01906 return -1;
01907 #endif
01908 }
01909
01910 return 0;
01911 }
01912
01913
01914 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
01915 {
01916 u16 encr_types;
01917
01918 if (encr == NULL) {
01919 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
01920 "received");
01921 return -1;
01922 }
01923
01924 encr_types = WPA_GET_BE16(encr);
01925
01926 wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
01927 encr_types);
01928 wps->encr_type = wps->wps->encr_types & encr_types;
01929 if (wps->encr_type == 0) {
01930 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01931 "encryption types (own 0x%x Enrollee 0x%x)",
01932 wps->wps->encr_types, encr_types);
01933 #ifdef WPS_WORKAROUNDS
01934
01935
01936
01937
01938
01939
01940
01941 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01942 "does not advertise supported encryption types "
01943 "correctly");
01944 wps->encr_type = wps->wps->encr_types;
01945 #else
01946 return -1;
01947 #endif
01948 }
01949
01950 return 0;
01951 }
01952
01953
01954 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
01955 {
01956 if (conn == NULL) {
01957 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
01958 "received");
01959 return -1;
01960 }
01961
01962 wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
01963 *conn);
01964
01965 return 0;
01966 }
01967
01968
01969 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
01970 {
01971 u16 m;
01972
01973 if (methods == NULL) {
01974 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
01975 return -1;
01976 }
01977
01978 m = WPA_GET_BE16(methods);
01979
01980 wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x", m);
01981
01982 return 0;
01983 }
01984
01985
01986 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
01987 {
01988 if (state == NULL) {
01989 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
01990 "received");
01991 return -1;
01992 }
01993
01994 wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
01995 *state);
01996
01997 return 0;
01998 }
01999
02000
02001 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
02002 {
02003 u16 a;
02004
02005 if (assoc == NULL) {
02006 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
02007 return -1;
02008 }
02009
02010 a = WPA_GET_BE16(assoc);
02011 wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
02012
02013 return 0;
02014 }
02015
02016
02017 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
02018 {
02019 u16 e;
02020
02021 if (err == NULL) {
02022 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
02023 return -1;
02024 }
02025
02026 e = WPA_GET_BE16(err);
02027 wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
02028
02029 return 0;
02030 }
02031
02032
02033 static enum wps_process_res wps_process_m1(struct wps_data *wps,
02034 struct wps_parse_attr *attr)
02035 {
02036 wpa_printf(MSG_DEBUG, "WPS: Received M1");
02037
02038 if (wps->state != RECV_M1) {
02039 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02040 "receiving M1", wps->state);
02041 return WPS_FAILURE;
02042 }
02043
02044 if (wps_process_uuid_e(wps, attr->uuid_e) ||
02045 wps_process_mac_addr(wps, attr->mac_addr) ||
02046 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
02047 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
02048 wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
02049 wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
02050 wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
02051 wps_process_config_methods(wps, attr->config_methods) ||
02052 wps_process_wps_state(wps, attr->wps_state) ||
02053 wps_process_device_attrs(&wps->peer_dev, attr) ||
02054 wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
02055 wps_process_assoc_state(wps, attr->assoc_state) ||
02056 wps_process_dev_password_id(wps, attr->dev_password_id) ||
02057 wps_process_config_error(wps, attr->config_error) ||
02058 wps_process_os_version(&wps->peer_dev, attr->os_version))
02059 return WPS_FAILURE;
02060
02061 if (wps->dev_pw_id < 0x10 &&
02062 wps->dev_pw_id != DEV_PW_DEFAULT &&
02063 wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
02064 wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
02065 wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
02066 (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
02067 !wps->wps->registrar->pbc)) {
02068 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
02069 wps->dev_pw_id);
02070 wps->state = SEND_M2D;
02071 return WPS_CONTINUE;
02072 }
02073
02074 #ifdef CONFIG_WPS_OOB
02075 if (wps->dev_pw_id >= 0x10 &&
02076 wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
02077 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
02078 "%d mismatch", wps->dev_pw_id);
02079 wps->state = SEND_M2D;
02080 return WPS_CONTINUE;
02081 }
02082 #endif
02083
02084 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
02085 if (wps->wps->registrar->force_pbc_overlap ||
02086 wps_registrar_pbc_overlap(wps->wps->registrar,
02087 wps->mac_addr_e, wps->uuid_e)) {
02088 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
02089 "negotiation");
02090 wps->state = SEND_M2D;
02091 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02092 wps_pbc_overlap_event(wps->wps);
02093 wps->wps->registrar->force_pbc_overlap = 1;
02094 return WPS_CONTINUE;
02095 }
02096 wps_registrar_add_pbc_session(wps->wps->registrar,
02097 wps->mac_addr_e, wps->uuid_e);
02098 wps->pbc = 1;
02099 }
02100
02101 wps->state = SEND_M2;
02102 return WPS_CONTINUE;
02103 }
02104
02105
02106 static enum wps_process_res wps_process_m3(struct wps_data *wps,
02107 const struct wpabuf *msg,
02108 struct wps_parse_attr *attr)
02109 {
02110 wpa_printf(MSG_DEBUG, "WPS: Received M3");
02111
02112 if (wps->state != RECV_M3) {
02113 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02114 "receiving M3", wps->state);
02115 wps->state = SEND_WSC_NACK;
02116 return WPS_CONTINUE;
02117 }
02118
02119 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02120 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02121 "session overlap");
02122 wps->state = SEND_WSC_NACK;
02123 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02124 return WPS_CONTINUE;
02125 }
02126
02127 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02128 wps_process_authenticator(wps, attr->authenticator, msg) ||
02129 wps_process_e_hash1(wps, attr->e_hash1) ||
02130 wps_process_e_hash2(wps, attr->e_hash2)) {
02131 wps->state = SEND_WSC_NACK;
02132 return WPS_CONTINUE;
02133 }
02134
02135 wps->state = SEND_M4;
02136 return WPS_CONTINUE;
02137 }
02138
02139
02140 static enum wps_process_res wps_process_m5(struct wps_data *wps,
02141 const struct wpabuf *msg,
02142 struct wps_parse_attr *attr)
02143 {
02144 struct wpabuf *decrypted;
02145 struct wps_parse_attr eattr;
02146
02147 wpa_printf(MSG_DEBUG, "WPS: Received M5");
02148
02149 if (wps->state != RECV_M5) {
02150 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02151 "receiving M5", wps->state);
02152 wps->state = SEND_WSC_NACK;
02153 return WPS_CONTINUE;
02154 }
02155
02156 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02157 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02158 "session overlap");
02159 wps->state = SEND_WSC_NACK;
02160 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02161 return WPS_CONTINUE;
02162 }
02163
02164 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02165 wps_process_authenticator(wps, attr->authenticator, msg)) {
02166 wps->state = SEND_WSC_NACK;
02167 return WPS_CONTINUE;
02168 }
02169
02170 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02171 attr->encr_settings_len);
02172 if (decrypted == NULL) {
02173 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
02174 "Settings attribute");
02175 wps->state = SEND_WSC_NACK;
02176 return WPS_CONTINUE;
02177 }
02178
02179 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02180 "attribute");
02181 if (wps_parse_msg(decrypted, &eattr) < 0 ||
02182 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02183 wps_process_e_snonce1(wps, eattr.e_snonce1)) {
02184 wpabuf_free(decrypted);
02185 wps->state = SEND_WSC_NACK;
02186 return WPS_CONTINUE;
02187 }
02188 wpabuf_free(decrypted);
02189
02190 wps->state = SEND_M6;
02191 return WPS_CONTINUE;
02192 }
02193
02194
02195 static void wps_sta_cred_cb(struct wps_data *wps)
02196 {
02197
02198
02199
02200
02201
02202 if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
02203 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
02204 else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
02205 wps->cred.auth_type = WPS_AUTH_WPAPSK;
02206 if (wps->cred.encr_type & WPS_ENCR_AES)
02207 wps->cred.encr_type = WPS_ENCR_AES;
02208 else if (wps->cred.encr_type & WPS_ENCR_TKIP)
02209 wps->cred.encr_type = WPS_ENCR_TKIP;
02210 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
02211 "AP configuration");
02212 if (wps->wps->cred_cb)
02213 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
02214 }
02215
02216
02217 static void wps_cred_update(struct wps_credential *dst,
02218 struct wps_credential *src)
02219 {
02220 os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
02221 dst->ssid_len = src->ssid_len;
02222 dst->auth_type = src->auth_type;
02223 dst->encr_type = src->encr_type;
02224 dst->key_idx = src->key_idx;
02225 os_memcpy(dst->key, src->key, sizeof(dst->key));
02226 dst->key_len = src->key_len;
02227 }
02228
02229
02230 static int wps_process_ap_settings_r(struct wps_data *wps,
02231 struct wps_parse_attr *attr)
02232 {
02233 if (wps->wps->ap || wps->er)
02234 return 0;
02235
02236
02237 if (wps_process_ap_settings(attr, &wps->cred) < 0)
02238 return -1;
02239
02240 wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
02241
02242 if (wps->new_ap_settings) {
02243 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
02244 "new settings");
02245 wps_cred_update(&wps->cred, wps->new_ap_settings);
02246 return 0;
02247 } else {
02248
02249
02250
02251
02252 if (wps->ap_settings_cb) {
02253 wps->ap_settings_cb(wps->ap_settings_cb_ctx,
02254 &wps->cred);
02255 return 1;
02256 }
02257 wps_sta_cred_cb(wps);
02258 return 1;
02259 }
02260 }
02261
02262
02263 static enum wps_process_res wps_process_m7(struct wps_data *wps,
02264 const struct wpabuf *msg,
02265 struct wps_parse_attr *attr)
02266 {
02267 struct wpabuf *decrypted;
02268 struct wps_parse_attr eattr;
02269
02270 wpa_printf(MSG_DEBUG, "WPS: Received M7");
02271
02272 if (wps->state != RECV_M7) {
02273 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02274 "receiving M7", wps->state);
02275 wps->state = SEND_WSC_NACK;
02276 return WPS_CONTINUE;
02277 }
02278
02279 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02280 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02281 "session overlap");
02282 wps->state = SEND_WSC_NACK;
02283 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02284 return WPS_CONTINUE;
02285 }
02286
02287 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02288 wps_process_authenticator(wps, attr->authenticator, msg)) {
02289 wps->state = SEND_WSC_NACK;
02290 return WPS_CONTINUE;
02291 }
02292
02293 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02294 attr->encr_settings_len);
02295 if (decrypted == NULL) {
02296 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
02297 "Settings attribute");
02298 wps->state = SEND_WSC_NACK;
02299 return WPS_CONTINUE;
02300 }
02301
02302 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02303 "attribute");
02304 if (wps_parse_msg(decrypted, &eattr) < 0 ||
02305 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02306 wps_process_e_snonce2(wps, eattr.e_snonce2) ||
02307 wps_process_ap_settings_r(wps, &eattr)) {
02308 wpabuf_free(decrypted);
02309 wps->state = SEND_WSC_NACK;
02310 return WPS_CONTINUE;
02311 }
02312
02313 wpabuf_free(decrypted);
02314
02315 wps->state = SEND_M8;
02316 return WPS_CONTINUE;
02317 }
02318
02319
02320 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
02321 const struct wpabuf *msg)
02322 {
02323 struct wps_parse_attr attr;
02324 enum wps_process_res ret = WPS_CONTINUE;
02325
02326 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
02327
02328 if (wps_parse_msg(msg, &attr) < 0)
02329 return WPS_FAILURE;
02330
02331 if (!wps_version_supported(attr.version)) {
02332 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02333 attr.version ? *attr.version : 0);
02334 return WPS_FAILURE;
02335 }
02336
02337 if (attr.msg_type == NULL) {
02338 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02339 return WPS_FAILURE;
02340 }
02341
02342 if (*attr.msg_type != WPS_M1 &&
02343 (attr.registrar_nonce == NULL ||
02344 os_memcmp(wps->nonce_r, attr.registrar_nonce,
02345 WPS_NONCE_LEN != 0))) {
02346 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02347 return WPS_FAILURE;
02348 }
02349
02350 switch (*attr.msg_type) {
02351 case WPS_M1:
02352 #ifdef CONFIG_WPS_UPNP
02353 if (wps->wps->wps_upnp && attr.mac_addr) {
02354
02355 wps_free_pending_msgs(wps->wps->upnp_msgs);
02356 wps->wps->upnp_msgs = NULL;
02357
02358 upnp_wps_device_send_wlan_event(
02359 wps->wps->wps_upnp, attr.mac_addr,
02360 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
02361 }
02362 #endif
02363 ret = wps_process_m1(wps, &attr);
02364 break;
02365 case WPS_M3:
02366 ret = wps_process_m3(wps, msg, &attr);
02367 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02368 wps_fail_event(wps->wps, WPS_M3);
02369 break;
02370 case WPS_M5:
02371 ret = wps_process_m5(wps, msg, &attr);
02372 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02373 wps_fail_event(wps->wps, WPS_M5);
02374 break;
02375 case WPS_M7:
02376 ret = wps_process_m7(wps, msg, &attr);
02377 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02378 wps_fail_event(wps->wps, WPS_M7);
02379 break;
02380 default:
02381 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
02382 *attr.msg_type);
02383 return WPS_FAILURE;
02384 }
02385
02386 if (ret == WPS_CONTINUE) {
02387
02388
02389 wpabuf_free(wps->last_msg);
02390 wps->last_msg = wpabuf_dup(msg);
02391 }
02392
02393 return ret;
02394 }
02395
02396
02397 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
02398 const struct wpabuf *msg)
02399 {
02400 struct wps_parse_attr attr;
02401
02402 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
02403
02404 if (wps_parse_msg(msg, &attr) < 0)
02405 return WPS_FAILURE;
02406
02407 if (!wps_version_supported(attr.version)) {
02408 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02409 attr.version ? *attr.version : 0);
02410 return WPS_FAILURE;
02411 }
02412
02413 if (attr.msg_type == NULL) {
02414 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02415 return WPS_FAILURE;
02416 }
02417
02418 if (*attr.msg_type != WPS_WSC_ACK) {
02419 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02420 *attr.msg_type);
02421 return WPS_FAILURE;
02422 }
02423
02424 #ifdef CONFIG_WPS_UPNP
02425 if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
02426 upnp_wps_subscribers(wps->wps->wps_upnp)) {
02427 if (wps->wps->upnp_msgs)
02428 return WPS_CONTINUE;
02429 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02430 "external Registrar");
02431 return WPS_PENDING;
02432 }
02433 #endif
02434
02435 if (attr.registrar_nonce == NULL ||
02436 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02437 {
02438 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02439 return WPS_FAILURE;
02440 }
02441
02442 if (attr.enrollee_nonce == NULL ||
02443 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02444 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02445 return WPS_FAILURE;
02446 }
02447
02448 if (wps->state == RECV_M2D_ACK) {
02449 #ifdef CONFIG_WPS_UPNP
02450 if (wps->wps->wps_upnp &&
02451 upnp_wps_subscribers(wps->wps->wps_upnp)) {
02452 if (wps->wps->upnp_msgs)
02453 return WPS_CONTINUE;
02454 if (wps->ext_reg == 0)
02455 wps->ext_reg = 1;
02456 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02457 "external Registrar");
02458 return WPS_PENDING;
02459 }
02460 #endif
02461
02462 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
02463 "terminate negotiation");
02464 }
02465
02466 return WPS_FAILURE;
02467 }
02468
02469
02470 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
02471 const struct wpabuf *msg)
02472 {
02473 struct wps_parse_attr attr;
02474 int old_state;
02475
02476 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
02477
02478 old_state = wps->state;
02479 wps->state = SEND_WSC_NACK;
02480
02481 if (wps_parse_msg(msg, &attr) < 0)
02482 return WPS_FAILURE;
02483
02484 if (!wps_version_supported(attr.version)) {
02485 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02486 attr.version ? *attr.version : 0);
02487 return WPS_FAILURE;
02488 }
02489
02490 if (attr.msg_type == NULL) {
02491 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02492 return WPS_FAILURE;
02493 }
02494
02495 if (*attr.msg_type != WPS_WSC_NACK) {
02496 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02497 *attr.msg_type);
02498 return WPS_FAILURE;
02499 }
02500
02501 #ifdef CONFIG_WPS_UPNP
02502 if (wps->wps->wps_upnp && wps->ext_reg) {
02503 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02504 "Registrar terminated by the Enrollee");
02505 return WPS_FAILURE;
02506 }
02507 #endif
02508
02509 if (attr.registrar_nonce == NULL ||
02510 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02511 {
02512 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02513 return WPS_FAILURE;
02514 }
02515
02516 if (attr.enrollee_nonce == NULL ||
02517 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02518 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02519 return WPS_FAILURE;
02520 }
02521
02522 if (attr.config_error == NULL) {
02523 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
02524 "in WSC_NACK");
02525 return WPS_FAILURE;
02526 }
02527
02528 wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
02529 "Configuration Error %d", WPA_GET_BE16(attr.config_error));
02530
02531 switch (old_state) {
02532 case RECV_M3:
02533 wps_fail_event(wps->wps, WPS_M2);
02534 break;
02535 case RECV_M5:
02536 wps_fail_event(wps->wps, WPS_M4);
02537 break;
02538 case RECV_M7:
02539 wps_fail_event(wps->wps, WPS_M6);
02540 break;
02541 case RECV_DONE:
02542 wps_fail_event(wps->wps, WPS_M8);
02543 break;
02544 default:
02545 break;
02546 }
02547
02548 return WPS_FAILURE;
02549 }
02550
02551
02552 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
02553 const struct wpabuf *msg)
02554 {
02555 struct wps_parse_attr attr;
02556
02557 wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
02558
02559 if (wps->state != RECV_DONE &&
02560 (!wps->wps->wps_upnp || !wps->ext_reg)) {
02561 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02562 "receiving WSC_Done", wps->state);
02563 return WPS_FAILURE;
02564 }
02565
02566 if (wps_parse_msg(msg, &attr) < 0)
02567 return WPS_FAILURE;
02568
02569 if (!wps_version_supported(attr.version)) {
02570 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02571 attr.version ? *attr.version : 0);
02572 return WPS_FAILURE;
02573 }
02574
02575 if (attr.msg_type == NULL) {
02576 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02577 return WPS_FAILURE;
02578 }
02579
02580 if (*attr.msg_type != WPS_WSC_DONE) {
02581 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02582 *attr.msg_type);
02583 return WPS_FAILURE;
02584 }
02585
02586 #ifdef CONFIG_WPS_UPNP
02587 if (wps->wps->wps_upnp && wps->ext_reg) {
02588 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02589 "Registrar completed successfully");
02590 wps_device_store(wps->wps->registrar, &wps->peer_dev,
02591 wps->uuid_e);
02592 return WPS_DONE;
02593 }
02594 #endif
02595
02596 if (attr.registrar_nonce == NULL ||
02597 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02598 {
02599 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02600 return WPS_FAILURE;
02601 }
02602
02603 if (attr.enrollee_nonce == NULL ||
02604 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02605 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02606 return WPS_FAILURE;
02607 }
02608
02609 wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
02610 wps_device_store(wps->wps->registrar, &wps->peer_dev,
02611 wps->uuid_e);
02612
02613 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
02614 wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
02615 struct wps_credential cred;
02616
02617 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
02618 "on first Enrollee connection");
02619
02620 os_memset(&cred, 0, sizeof(cred));
02621 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
02622 cred.ssid_len = wps->wps->ssid_len;
02623 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
02624 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
02625 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
02626 cred.key_len = wps->new_psk_len;
02627
02628 wps->wps->wps_state = WPS_STATE_CONFIGURED;
02629 wpa_hexdump_ascii_key(MSG_DEBUG,
02630 "WPS: Generated random passphrase",
02631 wps->new_psk, wps->new_psk_len);
02632 if (wps->wps->cred_cb)
02633 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
02634
02635 os_free(wps->new_psk);
02636 wps->new_psk = NULL;
02637 }
02638
02639 if (!wps->wps->ap && !wps->er)
02640 wps_sta_cred_cb(wps);
02641
02642 if (wps->new_psk) {
02643 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
02644 wps->new_psk, wps->new_psk_len)) {
02645 wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
02646 "new PSK");
02647 }
02648 os_free(wps->new_psk);
02649 wps->new_psk = NULL;
02650 }
02651
02652 wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
02653
02654 if (wps->pbc) {
02655 wps_registrar_remove_pbc_session(wps->wps->registrar,
02656 wps->mac_addr_e, wps->uuid_e);
02657 wps_registrar_pbc_completed(wps->wps->registrar);
02658 } else {
02659 wps_registrar_pin_completed(wps->wps->registrar);
02660 }
02661
02662 wps_success_event(wps->wps);
02663
02664 return WPS_DONE;
02665 }
02666
02667
02668 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
02669 enum wsc_op_code op_code,
02670 const struct wpabuf *msg)
02671 {
02672 enum wps_process_res ret;
02673
02674 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
02675 "op_code=%d)",
02676 (unsigned long) wpabuf_len(msg), op_code);
02677
02678 #ifdef CONFIG_WPS_UPNP
02679 if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
02680 struct wps_parse_attr attr;
02681 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
02682 *attr.msg_type == WPS_M3)
02683 wps->ext_reg = 2;
02684 }
02685 if (wps->ext_reg > 1)
02686 wps_registrar_free_pending_m2(wps->wps);
02687 if (wps->wps->wps_upnp && wps->ext_reg &&
02688 wps->wps->upnp_msgs == NULL &&
02689 (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
02690 {
02691 struct wps_parse_attr attr;
02692 int type;
02693 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
02694 type = -1;
02695 else
02696 type = *attr.msg_type;
02697 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
02698 " to external Registrar for processing", type);
02699 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
02700 wps->mac_addr_e,
02701 UPNP_WPS_WLANEVENT_TYPE_EAP,
02702 msg);
02703 if (op_code == WSC_MSG)
02704 return WPS_PENDING;
02705 } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
02706 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
02707 "external Registrar");
02708 return WPS_CONTINUE;
02709 }
02710 #endif
02711
02712 switch (op_code) {
02713 case WSC_MSG:
02714 return wps_process_wsc_msg(wps, msg);
02715 case WSC_ACK:
02716 return wps_process_wsc_ack(wps, msg);
02717 case WSC_NACK:
02718 return wps_process_wsc_nack(wps, msg);
02719 case WSC_Done:
02720 ret = wps_process_wsc_done(wps, msg);
02721 if (ret == WPS_FAILURE) {
02722 wps->state = SEND_WSC_NACK;
02723 wps_fail_event(wps->wps, WPS_WSC_DONE);
02724 }
02725 return ret;
02726 default:
02727 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
02728 return WPS_FAILURE;
02729 }
02730 }
02731
02732
02733 int wps_registrar_update_ie(struct wps_registrar *reg)
02734 {
02735 return wps_set_ie(reg);
02736 }
02737
02738
02739 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
02740 void *timeout_ctx)
02741 {
02742 struct wps_registrar *reg = eloop_ctx;
02743
02744 wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar timed out - "
02745 "unselect Registrar");
02746 reg->selected_registrar = 0;
02747 reg->pbc = 0;
02748 reg->sel_reg_dev_password_id_override = -1;
02749 reg->sel_reg_config_methods_override = -1;
02750 wps_set_ie(reg);
02751 wps_cb_set_sel_reg(reg);
02752 }
02753
02754
02765 int wps_registrar_set_selected_registrar(struct wps_registrar *reg,
02766 const struct wpabuf *msg)
02767 {
02768 struct wps_parse_attr attr;
02769
02770 wpa_hexdump_buf(MSG_MSGDUMP, "WPS: SetSelectedRegistrar attributes",
02771 msg);
02772
02773 if (wps_parse_msg(msg, &attr) < 0)
02774 return -1;
02775 if (!wps_version_supported(attr.version)) {
02776 wpa_printf(MSG_DEBUG, "WPS: Unsupported SetSelectedRegistrar "
02777 "version 0x%x", attr.version ? *attr.version : 0);
02778 return -1;
02779 }
02780
02781 if (attr.selected_registrar == NULL ||
02782 *attr.selected_registrar == 0) {
02783 wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar: Disable "
02784 "Selected Registrar");
02785 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg,
02786 NULL);
02787 wps_registrar_set_selected_timeout(reg, NULL);
02788 return 0;
02789 }
02790
02791 reg->selected_registrar = 1;
02792 reg->sel_reg_dev_password_id_override = attr.dev_password_id ?
02793 WPA_GET_BE16(attr.dev_password_id) : DEV_PW_DEFAULT;
02794 reg->sel_reg_config_methods_override = attr.sel_reg_config_methods ?
02795 WPA_GET_BE16(attr.sel_reg_config_methods) : -1;
02796 wps_set_ie(reg);
02797
02798 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
02799 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
02800 wps_registrar_set_selected_timeout,
02801 reg, NULL);
02802 return 0;
02803 }
02804
02805
02806 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
02807 char *buf, size_t buflen)
02808 {
02809 struct wps_registrar_device *d;
02810 int len = 0, ret;
02811 char uuid[40];
02812
02813 d = wps_device_get(reg, addr);
02814 if (d == NULL)
02815 return 0;
02816 if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
02817 return 0;
02818
02819 ret = os_snprintf(buf + len, buflen - len,
02820 "wpsUuid=%s\n"
02821 "wpsPrimaryDeviceType=%u-%08X-%u\n"
02822 "wpsDeviceName=%s\n"
02823 "wpsManufacturer=%s\n"
02824 "wpsModelName=%s\n"
02825 "wpsModelNumber=%s\n"
02826 "wpsSerialNumber=%s\n",
02827 uuid,
02828 d->dev.categ, d->dev.oui, d->dev.sub_categ,
02829 d->dev.device_name ? d->dev.device_name : "",
02830 d->dev.manufacturer ? d->dev.manufacturer : "",
02831 d->dev.model_name ? d->dev.model_name : "",
02832 d->dev.model_number ? d->dev.model_number : "",
02833 d->dev.serial_number ? d->dev.serial_number : "");
02834 if (ret < 0 || (size_t) ret >= buflen - len)
02835 return len;
02836 len += ret;
02837
02838 return len;
02839 }
02840