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