Codebase list reaver / a9c480e
Imported Upstream version 1.5.2.1 Mati Aharoni (Kali Linux Developer) 9 years ago
2 changed file(s) with 1 addition(s) and 3150 deletion(s). Raw diff Collapse all Expand all
18871887 pixie_test = 1;
18881888 //exit(0);
18891889 //here will get the pin
1890 strncpy(pixie_pin, aux_pixie_pin+9, 8);
1890 strncpy(pixie_pin, aux_pixie_pin + 12, 8);
18911891 }
18921892
18931893 }
+0
-3149
src/wps/wps_registrar.c.save less more
0 /*
1 * Wi-Fi Protected Setup - Registrar
2 * Copyright (c) 2008-2009, Jouni Malinen <[email protected]>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Alternatively, this software may be distributed under the terms of BSD
9 * license.
10 *
11 * See README and COPYING for more details.
12 */
13 #include "globule.h"
14 #include "t6.h"
15
16 #include "utils/includes.h"
17
18 #include "utils/common.h"
19 #include "utils/base64.h"
20 #include "utils/eloop.h"
21 #include "utils/uuid.h"
22 #include "utils/list.h"
23 #include "crypto/crypto.h"
24 #include "crypto/sha256.h"
25 #include "common/ieee802_11_defs.h"
26 #include "wps_i.h"
27 #include "wps_dev_attr.h"
28 #include "../misc.h"
29
30 #define WPS_WORKAROUNDS
31
32 struct wps_uuid_pin {
33 struct dl_list list;
34 u8 uuid[WPS_UUID_LEN];
35 int wildcard_uuid;
36 u8 *pin;
37 size_t pin_len;
38 #define PIN_LOCKED BIT(0)
39 #define PIN_EXPIRES BIT(1)
40 int flags;
41 struct os_time expiration;
42 };
43
44
45 static void wps_free_pin(struct wps_uuid_pin *pin)
46 {
47 os_free(pin->pin);
48 os_free(pin);
49 }
50
51
52 static void wps_remove_pin(struct wps_uuid_pin *pin)
53 {
54 dl_list_del(&pin->list);
55 wps_free_pin(pin);
56 }
57
58
59 static void wps_free_pins(struct dl_list *pins)
60 {
61 struct wps_uuid_pin *pin, *prev;
62 dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
63 wps_remove_pin(pin);
64 }
65
66
67 struct wps_pbc_session {
68 struct wps_pbc_session *next;
69 u8 addr[ETH_ALEN];
70 u8 uuid_e[WPS_UUID_LEN];
71 struct os_time timestamp;
72 };
73
74
75 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
76 {
77 struct wps_pbc_session *prev;
78
79 while (pbc) {
80 prev = pbc;
81 pbc = pbc->next;
82 os_free(prev);
83 }
84 }
85
86
87 struct wps_registrar_device {
88 struct wps_registrar_device *next;
89 struct wps_device_data dev;
90 u8 uuid[WPS_UUID_LEN];
91 };
92
93
94 struct wps_registrar {
95 struct wps_context *wps;
96
97 int pbc;
98 int selected_registrar;
99
100 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
101 size_t psk_len);
102 int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
103 struct wpabuf *probe_resp_ie);
104 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
105 const struct wps_device_data *dev);
106 void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
107 const u8 *uuid_e);
108 void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
109 u16 sel_reg_config_methods);
110 void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
111 const u8 *pri_dev_type, u16 config_methods,
112 u16 dev_password_id, u8 request_type,
113 const char *dev_name);
114 void *cb_ctx;
115
116 struct dl_list pins;
117 struct wps_pbc_session *pbc_sessions;
118
119 int skip_cred_build;
120 struct wpabuf *extra_cred;
121 int disable_auto_conf;
122 int sel_reg_union;
123 int sel_reg_dev_password_id_override;
124 int sel_reg_config_methods_override;
125 int static_wep_only;
126
127 struct wps_registrar_device *devices;
128
129 int force_pbc_overlap;
130 };
131
132
133 static int wps_set_ie(struct wps_registrar *reg);
134 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
135 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
136 void *timeout_ctx);
137
138
139 static void wps_free_devices(struct wps_registrar_device *dev)
140 {
141 struct wps_registrar_device *prev;
142
143 while (dev) {
144 prev = dev;
145 dev = dev->next;
146 wps_device_data_free(&prev->dev);
147 os_free(prev);
148 }
149 }
150
151
152 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
153 const u8 *addr)
154 {
155 struct wps_registrar_device *dev;
156
157 for (dev = reg->devices; dev; dev = dev->next) {
158 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
159 return dev;
160 }
161 return NULL;
162 }
163
164
165 static void wps_device_clone_data(struct wps_device_data *dst,
166 struct wps_device_data *src)
167 {
168 os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
169 os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
170
171 #define WPS_STRDUP(n) \
172 os_free(dst->n); \
173 dst->n = src->n ? os_strdup(src->n) : NULL
174
175 WPS_STRDUP(device_name);
176 WPS_STRDUP(manufacturer);
177 WPS_STRDUP(model_name);
178 WPS_STRDUP(model_number);
179 WPS_STRDUP(serial_number);
180 #undef WPS_STRDUP
181 }
182
183
184 int wps_device_store(struct wps_registrar *reg,
185 struct wps_device_data *dev, const u8 *uuid)
186 {
187 struct wps_registrar_device *d;
188
189 d = wps_device_get(reg, dev->mac_addr);
190 if (d == NULL) {
191 d = os_zalloc(sizeof(*d));
192 if (d == NULL)
193 return -1;
194 d->next = reg->devices;
195 reg->devices = d;
196 }
197
198 wps_device_clone_data(&d->dev, dev);
199 os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
200
201 return 0;
202 }
203
204
205 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
206 const u8 *addr, const u8 *uuid_e)
207 {
208 struct wps_pbc_session *pbc, *prev = NULL;
209 struct os_time now;
210
211 os_get_time(&now);
212
213 pbc = reg->pbc_sessions;
214 while (pbc) {
215 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
216 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
217 if (prev)
218 prev->next = pbc->next;
219 else
220 reg->pbc_sessions = pbc->next;
221 break;
222 }
223 prev = pbc;
224 pbc = pbc->next;
225 }
226
227 if (!pbc) {
228 pbc = os_zalloc(sizeof(*pbc));
229 if (pbc == NULL)
230 return;
231 os_memcpy(pbc->addr, addr, ETH_ALEN);
232 if (uuid_e)
233 os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
234 }
235
236 pbc->next = reg->pbc_sessions;
237 reg->pbc_sessions = pbc;
238 pbc->timestamp = now;
239
240 /* remove entries that have timed out */
241 prev = pbc;
242 pbc = pbc->next;
243
244 while (pbc) {
245 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
246 prev->next = NULL;
247 wps_free_pbc_sessions(pbc);
248 break;
249 }
250 prev = pbc;
251 pbc = pbc->next;
252 }
253 }
254
255
256 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
257 const u8 *addr, const u8 *uuid_e)
258 {
259 struct wps_pbc_session *pbc, *prev = NULL;
260
261 pbc = reg->pbc_sessions;
262 while (pbc) {
263 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
264 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
265 if (prev)
266 prev->next = pbc->next;
267 else
268 reg->pbc_sessions = pbc->next;
269 os_free(pbc);
270 break;
271 }
272 prev = pbc;
273 pbc = pbc->next;
274 }
275 }
276
277
278 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
279 const u8 *addr, const u8 *uuid_e)
280 {
281 int count = 0;
282 struct wps_pbc_session *pbc;
283 struct os_time now;
284
285 os_get_time(&now);
286
287 for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
288 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
289 break;
290 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
291 uuid_e == NULL ||
292 os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
293 count++;
294 }
295
296 if (addr || uuid_e)
297 count++;
298
299 return count > 1 ? 1 : 0;
300 }
301
302
303 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
304 {
305 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
306 wps->wps_state);
307 wpabuf_put_be16(msg, ATTR_WPS_STATE);
308 wpabuf_put_be16(msg, 1);
309 wpabuf_put_u8(msg, wps->wps_state);
310 return 0;
311 }
312
313
314 #ifdef CONFIG_WPS_UPNP
315 static void wps_registrar_free_pending_m2(struct wps_context *wps)
316 {
317 struct upnp_pending_message *p, *p2, *prev = NULL;
318 p = wps->upnp_msgs;
319 while (p) {
320 if (p->type == WPS_M2 || p->type == WPS_M2D) {
321 if (prev == NULL)
322 wps->upnp_msgs = p->next;
323 else
324 prev->next = p->next;
325 wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
326 p2 = p;
327 p = p->next;
328 wpabuf_free(p2->msg);
329 os_free(p2);
330 continue;
331 }
332 prev = p;
333 p = p->next;
334 }
335 }
336 #endif /* CONFIG_WPS_UPNP */
337
338
339 static int wps_build_ap_setup_locked(struct wps_context *wps,
340 struct wpabuf *msg)
341 {
342 if (wps->ap_setup_locked) {
343 wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked");
344 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
345 wpabuf_put_be16(msg, 1);
346 wpabuf_put_u8(msg, 1);
347 }
348 return 0;
349 }
350
351
352 static int wps_build_selected_registrar(struct wps_registrar *reg,
353 struct wpabuf *msg)
354 {
355 if (!reg->sel_reg_union)
356 return 0;
357 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar");
358 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
359 wpabuf_put_be16(msg, 1);
360 wpabuf_put_u8(msg, 1);
361 return 0;
362 }
363
364
365 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
366 struct wpabuf *msg)
367 {
368 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
369 if (!reg->sel_reg_union)
370 return 0;
371 if (reg->sel_reg_dev_password_id_override >= 0)
372 id = reg->sel_reg_dev_password_id_override;
373 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
374 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
375 wpabuf_put_be16(msg, 2);
376 wpabuf_put_be16(msg, id);
377 return 0;
378 }
379
380
381 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
382 struct wpabuf *msg)
383 {
384 u16 methods;
385 if (!reg->sel_reg_union)
386 return 0;
387 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
388 if (reg->pbc)
389 methods |= WPS_CONFIG_PUSHBUTTON;
390 if (reg->sel_reg_config_methods_override >= 0)
391 methods = reg->sel_reg_config_methods_override;
392 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar Config Methods (%x)",
393 methods);
394 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
395 wpabuf_put_be16(msg, 2);
396 wpabuf_put_be16(msg, methods);
397 return 0;
398 }
399
400
401 static int wps_build_probe_config_methods(struct wps_registrar *reg,
402 struct wpabuf *msg)
403 {
404 u16 methods;
405 /*
406 * These are the methods that the AP supports as an Enrollee for adding
407 * external Registrars.
408 */
409 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
410 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
411 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
412 wpabuf_put_be16(msg, 2);
413 wpabuf_put_be16(msg, methods);
414 return 0;
415 }
416
417
418 static int wps_build_config_methods_r(struct wps_registrar *reg,
419 struct wpabuf *msg)
420 {
421 u16 methods;
422 if(reg == NULL)
423 {
424 return 0;
425 }
426
427 methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_PUSHBUTTON;
428 /*
429 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
430 if (reg->pbc)
431 methods |= WPS_CONFIG_PUSHBUTTON;
432 */
433 return wps_build_config_methods(msg, methods);
434 }
435
436
437 /**
438 * wps_registrar_init - Initialize WPS Registrar data
439 * @wps: Pointer to longterm WPS context
440 * @cfg: Registrar configuration
441 * Returns: Pointer to allocated Registrar data or %NULL on failure
442 *
443 * This function is used to initialize WPS Registrar functionality. It can be
444 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
445 * runs (e.g., when run as an internal Registrar in an AP). Caller is
446 * responsible for freeing the returned data with wps_registrar_deinit() when
447 * Registrar functionality is not needed anymore.
448 */
449 struct wps_registrar *
450 wps_registrar_init(struct wps_context *wps,
451 const struct wps_registrar_config *cfg)
452 {
453 struct wps_registrar *reg = os_zalloc(sizeof(*reg));
454 if (reg == NULL)
455 return NULL;
456
457 dl_list_init(&reg->pins);
458 reg->wps = wps;
459 reg->new_psk_cb = cfg->new_psk_cb;
460 reg->set_ie_cb = cfg->set_ie_cb;
461 reg->pin_needed_cb = cfg->pin_needed_cb;
462 reg->reg_success_cb = cfg->reg_success_cb;
463 reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
464 reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
465 reg->cb_ctx = cfg->cb_ctx;
466 reg->skip_cred_build = cfg->skip_cred_build;
467 if (cfg->extra_cred) {
468 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
469 cfg->extra_cred_len);
470 if (reg->extra_cred == NULL) {
471 os_free(reg);
472 return NULL;
473 }
474 }
475 reg->disable_auto_conf = cfg->disable_auto_conf;
476 reg->sel_reg_dev_password_id_override = -1;
477 reg->sel_reg_config_methods_override = -1;
478 reg->static_wep_only = cfg->static_wep_only;
479
480 if (wps_set_ie(reg)) {
481 wps_registrar_deinit(reg);
482 return NULL;
483 }
484
485 return reg;
486 }
487
488
489 /**
490 * wps_registrar_deinit - Deinitialize WPS Registrar data
491 * @reg: Registrar data from wps_registrar_init()
492 */
493 void wps_registrar_deinit(struct wps_registrar *reg)
494 {
495 if (reg == NULL)
496 return;
497 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
498 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
499 wps_free_pins(&reg->pins);
500 wps_free_pbc_sessions(reg->pbc_sessions);
501 wpabuf_free(reg->extra_cred);
502 wps_free_devices(reg->devices);
503 os_free(reg);
504 }
505
506
507 /**
508 * wps_registrar_add_pin - Configure a new PIN for Registrar
509 * @reg: Registrar data from wps_registrar_init()
510 * @uuid: UUID-E or %NULL for wildcard (any UUID)
511 * @pin: PIN (Device Password)
512 * @pin_len: Length of pin in octets
513 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
514 * Returns: 0 on success, -1 on failure
515 */
516 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
517 const u8 *pin, size_t pin_len, int timeout)
518 {
519 struct wps_uuid_pin *p;
520
521 if(reg == NULL)
522 return -1;
523
524 p = os_zalloc(sizeof(*p));
525 if (p == NULL)
526 return -1;
527 if (uuid == NULL)
528 p->wildcard_uuid = 1;
529 else
530 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
531 p->pin = os_malloc(pin_len);
532 if (p->pin == NULL) {
533 os_free(p);
534 return -1;
535 }
536 os_memcpy(p->pin, pin, pin_len);
537 p->pin_len = pin_len;
538
539 if (timeout) {
540 p->flags |= PIN_EXPIRES;
541 os_get_time(&p->expiration);
542 p->expiration.sec += timeout;
543 }
544
545 dl_list_add(&reg->pins, &p->list);
546
547 wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
548 timeout);
549 wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
550 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
551 reg->selected_registrar = 1;
552 reg->pbc = 0;
553 wps_registrar_selected_registrar_changed(reg);
554 /* @@@ HACK: We don't use these registrar timeouts, so calling these eloop
555 * functions causes a seg fault.
556 */
557 /*eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
558 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
559 wps_registrar_set_selected_timeout,
560 reg, NULL);
561 */
562 return 0;
563 }
564
565
566 static void wps_registrar_expire_pins(struct wps_registrar *reg)
567 {
568 struct wps_uuid_pin *pin, *prev;
569 struct os_time now;
570
571 if(reg != NULL)
572 {
573 os_get_time(&now);
574 dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
575 {
576 if(pin != NULL)
577 {
578 if ((pin->flags & PIN_EXPIRES) &&
579 os_time_before(&pin->expiration, &now)) {
580 wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
581 pin->uuid, WPS_UUID_LEN);
582 wps_remove_pin(pin);
583 }
584 }
585 }
586 }
587 }
588
589
590 /**
591 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
592 * @reg: Registrar data from wps_registrar_init()
593 * @uuid: UUID-E
594 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
595 */
596 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
597 {
598 struct wps_uuid_pin *pin, *prev;
599
600 if(reg == NULL)
601 return -1;
602
603 dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
604 {
605 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
606 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
607 pin->uuid, WPS_UUID_LEN);
608 wps_remove_pin(pin);
609 return 0;
610 }
611 }
612
613 return -1;
614 }
615
616
617 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
618 const u8 *uuid, size_t *pin_len)
619 {
620 struct wps_uuid_pin *pin, *found = NULL;
621
622 if(reg == NULL)
623 return NULL;
624
625 wps_registrar_expire_pins(reg);
626
627 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
628 if (!pin->wildcard_uuid &&
629 os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
630 found = pin;
631 break;
632 }
633 }
634
635 if (!found) {
636 /* Check for wildcard UUIDs since none of the UUID-specific
637 * PINs matched */
638 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
639 if (pin->wildcard_uuid == 1) {
640 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
641 "PIN. Assigned it for this UUID-E");
642 pin->wildcard_uuid = 2;
643 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
644 found = pin;
645 break;
646 }
647 }
648 }
649
650 if (!found)
651 return NULL;
652
653 /*
654 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
655 * that could otherwise avoid PIN invalidations.
656 */
657 if (found->flags & PIN_LOCKED) {
658 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
659 "allow concurrent re-use");
660 return NULL;
661 }
662 *pin_len = found->pin_len;
663 found->flags |= PIN_LOCKED;
664 return found->pin;
665 }
666
667
668 /**
669 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
670 * @reg: Registrar data from wps_registrar_init()
671 * @uuid: UUID-E
672 * Returns: 0 on success, -1 on failure
673 *
674 * PINs are locked to enforce only one concurrent use. This function unlocks a
675 * PIN to allow it to be used again. If the specified PIN was configured using
676 * a wildcard UUID, it will be removed instead of allowing multiple uses.
677 */
678 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
679 {
680 struct wps_uuid_pin *pin;
681
682 if(reg != NULL)
683 {
684 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
685 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
686 if (pin->wildcard_uuid == 2) {
687 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
688 "wildcard PIN");
689 return wps_registrar_invalidate_pin(reg, uuid);
690 }
691 pin->flags &= ~PIN_LOCKED;
692 return 0;
693 }
694 }
695 }
696
697 return -1;
698 }
699
700
701 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
702 {
703 if(reg != NULL)
704 {
705 reg->selected_registrar = 0;
706 reg->pbc = 0;
707 wps_registrar_selected_registrar_changed(reg);
708 }
709 }
710
711
712 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
713 {
714 struct wps_registrar *reg = eloop_ctx;
715
716 if(reg != NULL)
717 {
718 wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
719 wps_pbc_timeout_event(reg->wps);
720 wps_registrar_stop_pbc(reg);
721 }
722 }
723
724
725 /**
726 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
727 * @reg: Registrar data from wps_registrar_init()
728 * Returns: 0 on success, -1 on failure
729 *
730 * This function is called on an AP when a push button is pushed to activate
731 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
732 * or when a PBC registration is completed.
733 */
734 int wps_registrar_button_pushed(struct wps_registrar *reg)
735 {
736 if(reg == NULL)
737 return -1;
738
739 if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
740 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
741 "mode");
742 wps_pbc_overlap_event(reg->wps);
743 return -1;
744 }
745 wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
746 reg->force_pbc_overlap = 0;
747 reg->selected_registrar = 1;
748 reg->pbc = 1;
749 wps_registrar_selected_registrar_changed(reg);
750
751 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
752 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
753 reg, NULL);
754 return 0;
755 }
756
757
758 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
759 {
760 if(reg != NULL)
761 {
762 wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
763 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
764 wps_registrar_stop_pbc(reg);
765 }
766 }
767
768
769 static void wps_registrar_pin_completed(struct wps_registrar *reg)
770 {
771 if(reg != NULL)
772 {
773 wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
774 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
775 reg->selected_registrar = 0;
776 wps_registrar_selected_registrar_changed(reg);
777 }
778 }
779
780
781 /**
782 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
783 * @reg: Registrar data from wps_registrar_init()
784 * @addr: MAC address of the Probe Request sender
785 * @wps_data: WPS IE contents
786 *
787 * This function is called on an AP when a Probe Request with WPS IE is
788 * received. This is used to track PBC mode use and to detect possible overlap
789 * situation with other WPS APs.
790 */
791 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
792 const struct wpabuf *wps_data)
793 {
794 struct wps_parse_attr attr;
795
796 if(reg == NULL)
797 return;
798
799 wpa_hexdump_buf(MSG_MSGDUMP,
800 "WPS: Probe Request with WPS data received",
801 wps_data);
802
803 if (wps_parse_msg(wps_data, &attr) < 0)
804 return;
805 if (!wps_version_supported(attr.version)) {
806 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
807 "version 0x%x", attr.version ? *attr.version : 0);
808 return;
809 }
810
811 if (attr.config_methods == NULL) {
812 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
813 "Probe Request");
814 return;
815 }
816
817 if (attr.dev_password_id == NULL) {
818 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
819 "in Probe Request");
820 return;
821 }
822
823 if (reg->enrollee_seen_cb && attr.uuid_e &&
824 attr.primary_dev_type && attr.request_type) {
825 char *dev_name = NULL;
826 if (attr.dev_name) {
827 dev_name = os_zalloc(attr.dev_name_len + 1);
828 if (dev_name) {
829 os_memcpy(dev_name, attr.dev_name,
830 attr.dev_name_len);
831 }
832 }
833 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
834 attr.primary_dev_type,
835 WPA_GET_BE16(attr.config_methods),
836 WPA_GET_BE16(attr.dev_password_id),
837 *attr.request_type, dev_name);
838 os_free(dev_name);
839 }
840
841 if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
842 return; /* Not PBC */
843
844 wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
845 MACSTR, MAC2STR(addr));
846 if (attr.uuid_e == NULL) {
847 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
848 "UUID-E included");
849 return;
850 }
851
852 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
853 if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
854 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
855 reg->force_pbc_overlap = 1;
856 wps_pbc_overlap_event(reg->wps);
857 }
858 }
859
860
861 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
862 const u8 *psk, size_t psk_len)
863 {
864 if(reg == NULL)
865 return 0;
866
867 if (reg->new_psk_cb == NULL)
868 return 0;
869
870 return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
871 }
872
873
874 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
875 const struct wps_device_data *dev)
876 {
877 if(reg == NULL)
878 return;
879
880 if (reg->pin_needed_cb == NULL)
881 return;
882
883 reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
884 }
885
886
887 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
888 const u8 *uuid_e)
889 {
890 if(reg == NULL)
891 return;
892
893 if (reg->reg_success_cb == NULL)
894 return;
895
896 reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
897 }
898
899
900 static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
901 struct wpabuf *probe_resp_ie)
902 {
903 if(reg == NULL)
904 return 0;
905
906 return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
907 }
908
909
910 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
911 {
912 if(reg == NULL)
913 return;
914
915 wpa_printf(MSG_DEBUG, "WPS: Enter wps_cg_set_sel_reg");
916 u16 methods = 0;
917 if (reg->set_sel_reg_cb == NULL)
918 {
919 wpa_printf(MSG_DEBUG, "WPS: Leave wps_cg_set_sel_reg early");
920 return;
921 }
922
923 wpa_printf(MSG_DEBUG, "WPS: reg->selected_registrar");
924 if (reg->selected_registrar) {
925 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
926 if (reg->pbc)
927 methods |= WPS_CONFIG_PUSHBUTTON;
928 }
929
930 wpa_printf(MSG_DEBUG, "WPS: reg->set_sel_reg_cb");
931 reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
932 reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
933 methods);
934
935 wpa_printf(MSG_DEBUG, "WPS: Leave wps_cg_set_sel_reg");
936 }
937
938
939 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
940 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
941 {
942 struct wpabuf *ie;
943 const u8 *pos, *end;
944
945 ie = wpabuf_alloc(wpabuf_len(data) + 100);
946 if (ie == NULL) {
947 wpabuf_free(data);
948 return NULL;
949 }
950
951 pos = wpabuf_head(data);
952 end = pos + wpabuf_len(data);
953
954 while (end > pos) {
955 size_t frag_len = end - pos;
956 if (frag_len > 251)
957 frag_len = 251;
958 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
959 wpabuf_put_u8(ie, 4 + frag_len);
960 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
961 wpabuf_put_data(ie, pos, frag_len);
962 pos += frag_len;
963 }
964
965 wpabuf_free(data);
966
967 return ie;
968 }
969
970
971 static int wps_set_ie(struct wps_registrar *reg)
972 {
973 struct wpabuf *beacon;
974 struct wpabuf *probe;
975
976 if (reg->set_ie_cb == NULL)
977 return 0;
978
979 wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
980
981 beacon = wpabuf_alloc(300);
982 if (beacon == NULL)
983 return -1;
984 probe = wpabuf_alloc(400);
985 if (probe == NULL) {
986 wpabuf_free(beacon);
987 return -1;
988 }
989
990 if (wps_build_version(beacon) ||
991 wps_build_wps_state(reg->wps, beacon) ||
992 wps_build_ap_setup_locked(reg->wps, beacon) ||
993 wps_build_selected_registrar(reg, beacon) ||
994 wps_build_sel_reg_dev_password_id(reg, beacon) ||
995 wps_build_sel_reg_config_methods(reg, beacon) ||
996 wps_build_version(probe) ||
997 wps_build_wps_state(reg->wps, probe) ||
998 wps_build_ap_setup_locked(reg->wps, probe) ||
999 wps_build_selected_registrar(reg, probe) ||
1000 wps_build_sel_reg_dev_password_id(reg, probe) ||
1001 wps_build_sel_reg_config_methods(reg, probe) ||
1002 wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
1003 WPS_RESP_REGISTRAR) ||
1004 wps_build_uuid_e(probe, reg->wps->uuid) ||
1005 wps_build_device_attrs(&reg->wps->dev, probe) ||
1006 wps_build_probe_config_methods(reg, probe) ||
1007 wps_build_rf_bands(&reg->wps->dev, probe)) {
1008 wpabuf_free(beacon);
1009 wpabuf_free(probe);
1010 return -1;
1011 }
1012
1013 beacon = wps_ie_encapsulate(beacon);
1014 probe = wps_ie_encapsulate(probe);
1015
1016 if (!beacon || !probe) {
1017 wpabuf_free(beacon);
1018 wpabuf_free(probe);
1019 return -1;
1020 }
1021
1022 if (reg->static_wep_only) {
1023 /*
1024 * Windows XP and Vista clients can get confused about
1025 * EAP-Identity/Request when they probe the network with
1026 * EAPOL-Start. In such a case, they may assume the network is
1027 * using IEEE 802.1X and prompt user for a certificate while
1028 * the correct (non-WPS) behavior would be to ask for the
1029 * static WEP key. As a workaround, use Microsoft Provisioning
1030 * IE to advertise that legacy 802.1X is not supported.
1031 */
1032 const u8 ms_wps[7] = {
1033 WLAN_EID_VENDOR_SPECIFIC, 5,
1034 /* Microsoft Provisioning IE (00:50:f2:5) */
1035 0x00, 0x50, 0xf2, 5,
1036 0x00 /* no legacy 802.1X or MS WPS */
1037 };
1038 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
1039 "into Beacon/Probe Response frames");
1040 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
1041 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
1042 }
1043
1044 return wps_cb_set_ie(reg, beacon, probe);
1045 }
1046
1047
1048 static int wps_get_dev_password(struct wps_data *wps)
1049 {
1050 const u8 *pin;
1051 size_t pin_len = 0;
1052
1053 os_free(wps->dev_password);
1054 wps->dev_password = NULL;
1055
1056 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e, &pin_len);
1057 if (pin == NULL) {
1058 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
1059 "the Enrollee");
1060 if(wps->wps->registrar != NULL)
1061 {
1062 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
1063 &wps->peer_dev);
1064 }
1065 return -1;
1066 }
1067
1068 wps->dev_password = os_malloc(pin_len);
1069 if (wps->dev_password == NULL)
1070 return -1;
1071 os_memcpy(wps->dev_password, pin, pin_len);
1072 wps->dev_password_len = pin_len;
1073
1074 return 0;
1075 }
1076
1077
1078 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
1079 {
1080 wpa_printf(MSG_DEBUG, "WPS: * UUID-R");
1081 wpabuf_put_be16(msg, ATTR_UUID_R);
1082 wpabuf_put_be16(msg, WPS_UUID_LEN);
1083 wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
1084 return 0;
1085 }
1086
1087
1088 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
1089 {
1090 u8 *hash;
1091 const u8 *addr[4];
1092 size_t len[4];
1093
1094 if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
1095 return -1;
1096 wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
1097 wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
1098 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
1099
1100 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
1101 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
1102 "R-Hash derivation");
1103 return -1;
1104 }
1105
1106 wpa_printf(MSG_DEBUG, "WPS: * R-Hash1");
1107 wpabuf_put_be16(msg, ATTR_R_HASH1);
1108 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1109 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1110 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1111 addr[0] = wps->snonce;
1112 len[0] = WPS_SECRET_NONCE_LEN;
1113 addr[1] = wps->psk1;
1114 len[1] = WPS_PSK_LEN;
1115 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1116 len[2] = wpabuf_len(wps->dh_pubkey_e);
1117 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1118 len[3] = wpabuf_len(wps->dh_pubkey_r);
1119 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1120 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
1121
1122 wpa_printf(MSG_DEBUG, "WPS: * R-Hash2");
1123 wpabuf_put_be16(msg, ATTR_R_HASH2);
1124 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1125 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1126 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1127 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
1128 addr[1] = wps->psk2;
1129 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1130 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
1131
1132 return 0;
1133 }
1134
1135
1136 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
1137 {
1138 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce1");
1139 wpabuf_put_be16(msg, ATTR_R_SNONCE1);
1140 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1141 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
1142 return 0;
1143 }
1144
1145
1146 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
1147 {
1148 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce2");
1149 wpabuf_put_be16(msg, ATTR_R_SNONCE2);
1150 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1151 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
1152 WPS_SECRET_NONCE_LEN);
1153 return 0;
1154 }
1155
1156
1157 static int wps_build_cred_network_idx(struct wpabuf *msg,
1158 const struct wps_credential *cred)
1159 {
1160 wpa_printf(MSG_DEBUG, "WPS: * Network Index");
1161 wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
1162 wpabuf_put_be16(msg, 1);
1163 wpabuf_put_u8(msg, 1);
1164 return 0;
1165 }
1166
1167
1168 static int wps_build_cred_ssid(struct wpabuf *msg,
1169 const struct wps_credential *cred)
1170 {
1171 wpa_printf(MSG_DEBUG, "WPS: * SSID");
1172 wpabuf_put_be16(msg, ATTR_SSID);
1173 wpabuf_put_be16(msg, cred->ssid_len);
1174 wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
1175 return 0;
1176 }
1177
1178
1179 static int wps_build_cred_auth_type(struct wpabuf *msg,
1180 const struct wps_credential *cred)
1181 {
1182 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)",
1183 cred->auth_type);
1184 wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
1185 wpabuf_put_be16(msg, 2);
1186 wpabuf_put_be16(msg, cred->auth_type);
1187 return 0;
1188 }
1189
1190
1191 static int wps_build_cred_encr_type(struct wpabuf *msg,
1192 const struct wps_credential *cred)
1193 {
1194 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)",
1195 cred->encr_type);
1196 wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
1197 wpabuf_put_be16(msg, 2);
1198 wpabuf_put_be16(msg, cred->encr_type);
1199 return 0;
1200 }
1201
1202
1203 static int wps_build_cred_network_key(struct wpabuf *msg,
1204 const struct wps_credential *cred)
1205 {
1206 wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%d)",
1207 (int) cred->key_len);
1208 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
1209 wpabuf_put_be16(msg, cred->key_len);
1210 wpabuf_put_data(msg, cred->key, cred->key_len);
1211 return 0;
1212 }
1213
1214
1215 static int wps_build_cred_mac_addr(struct wpabuf *msg,
1216 const struct wps_credential *cred)
1217 {
1218 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")",
1219 MAC2STR(cred->mac_addr));
1220 wpabuf_put_be16(msg, ATTR_MAC_ADDR);
1221 wpabuf_put_be16(msg, ETH_ALEN);
1222 wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
1223 return 0;
1224 }
1225
1226
1227 static int wps_build_credential(struct wpabuf *msg,
1228 const struct wps_credential *cred)
1229 {
1230 if (wps_build_cred_network_idx(msg, cred) ||
1231 wps_build_cred_ssid(msg, cred) ||
1232 wps_build_cred_auth_type(msg, cred) ||
1233 wps_build_cred_encr_type(msg, cred) ||
1234 wps_build_cred_network_key(msg, cred) ||
1235 wps_build_cred_mac_addr(msg, cred))
1236 return -1;
1237 return 0;
1238 }
1239
1240
1241 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
1242 {
1243 struct wpabuf *cred;
1244
1245 if (wps->wps->registrar->skip_cred_build)
1246 goto skip_cred_build;
1247
1248 wpa_printf(MSG_DEBUG, "WPS: * Credential");
1249 if (wps->use_cred) {
1250 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
1251 goto use_provided;
1252 }
1253 os_memset(&wps->cred, 0, sizeof(wps->cred));
1254
1255 os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
1256 wps->cred.ssid_len = wps->wps->ssid_len;
1257
1258 /* Select the best authentication and encryption type */
1259 if (wps->auth_type & WPS_AUTH_WPA2PSK)
1260 wps->auth_type = WPS_AUTH_WPA2PSK;
1261 else if (wps->auth_type & WPS_AUTH_WPAPSK)
1262 wps->auth_type = WPS_AUTH_WPAPSK;
1263 else if (wps->auth_type & WPS_AUTH_OPEN)
1264 wps->auth_type = WPS_AUTH_OPEN;
1265 else if (wps->auth_type & WPS_AUTH_SHARED)
1266 wps->auth_type = WPS_AUTH_SHARED;
1267 else {
1268 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
1269 wps->auth_type);
1270 return -1;
1271 }
1272 wps->cred.auth_type = wps->auth_type;
1273
1274 if (wps->auth_type == WPS_AUTH_WPA2PSK ||
1275 wps->auth_type == WPS_AUTH_WPAPSK) {
1276 if (wps->encr_type & WPS_ENCR_AES)
1277 wps->encr_type = WPS_ENCR_AES;
1278 else if (wps->encr_type & WPS_ENCR_TKIP)
1279 wps->encr_type = WPS_ENCR_TKIP;
1280 else {
1281 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1282 "type for WPA/WPA2");
1283 return -1;
1284 }
1285 } else {
1286 if (wps->encr_type & WPS_ENCR_WEP)
1287 wps->encr_type = WPS_ENCR_WEP;
1288 else if (wps->encr_type & WPS_ENCR_NONE)
1289 wps->encr_type = WPS_ENCR_NONE;
1290 else {
1291 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1292 "type for non-WPA/WPA2 mode");
1293 return -1;
1294 }
1295 }
1296 wps->cred.encr_type = wps->encr_type;
1297 /*
1298 * Set MAC address in the Credential to be the Enrollee's MAC address
1299 */
1300 os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
1301
1302 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
1303 !wps->wps->registrar->disable_auto_conf) {
1304 u8 r[16];
1305 /* Generate a random passphrase */
1306 if (os_get_random(r, sizeof(r)) < 0)
1307 return -1;
1308 os_free(wps->new_psk);
1309 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
1310 if (wps->new_psk == NULL)
1311 return -1;
1312 wps->new_psk_len--; /* remove newline */
1313 while (wps->new_psk_len &&
1314 wps->new_psk[wps->new_psk_len - 1] == '=')
1315 wps->new_psk_len--;
1316 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
1317 wps->new_psk, wps->new_psk_len);
1318 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1319 wps->cred.key_len = wps->new_psk_len;
1320 } else if (wps->use_psk_key && wps->wps->psk_set) {
1321 char hex[65];
1322 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
1323 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
1324 os_memcpy(wps->cred.key, hex, 32 * 2);
1325 wps->cred.key_len = 32 * 2;
1326 } else if (wps->wps->network_key) {
1327 os_memcpy(wps->cred.key, wps->wps->network_key,
1328 wps->wps->network_key_len);
1329 wps->cred.key_len = wps->wps->network_key_len;
1330 } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1331 char hex[65];
1332 /* Generate a random per-device PSK */
1333 os_free(wps->new_psk);
1334 wps->new_psk_len = 32;
1335 wps->new_psk = os_malloc(wps->new_psk_len);
1336 if (wps->new_psk == NULL)
1337 return -1;
1338 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
1339 os_free(wps->new_psk);
1340 wps->new_psk = NULL;
1341 return -1;
1342 }
1343 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1344 wps->new_psk, wps->new_psk_len);
1345 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1346 wps->new_psk_len);
1347 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1348 wps->cred.key_len = wps->new_psk_len * 2;
1349 }
1350
1351 use_provided:
1352 cred = wpabuf_alloc(200);
1353 if (cred == NULL)
1354 return -1;
1355
1356 if (wps_build_credential(cred, &wps->cred)) {
1357 wpabuf_free(cred);
1358 return -1;
1359 }
1360
1361 wpabuf_put_be16(msg, ATTR_CRED);
1362 wpabuf_put_be16(msg, wpabuf_len(cred));
1363 wpabuf_put_buf(msg, cred);
1364 wpabuf_free(cred);
1365
1366 skip_cred_build:
1367 if (wps->wps->registrar->extra_cred) {
1368 wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)");
1369 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1370 }
1371
1372 return 0;
1373 }
1374
1375
1376 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1377 {
1378 wpa_printf(MSG_DEBUG, "WPS: * AP Settings");
1379
1380 if (wps_build_credential(msg, &wps->cred))
1381 return -1;
1382
1383 return 0;
1384 }
1385
1386
1387 static struct wpabuf * wps_build_m2(struct wps_data *wps)
1388 {
1389 struct wpabuf *msg;
1390
1391 if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
1392 return NULL;
1393 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1394 wps->nonce_r, WPS_NONCE_LEN);
1395 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1396
1397 wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1398 msg = wpabuf_alloc(1000);
1399 if (msg == NULL)
1400 return NULL;
1401
1402 if (wps_build_version(msg) ||
1403 wps_build_msg_type(msg, WPS_M2) ||
1404 wps_build_enrollee_nonce(wps, msg) ||
1405 wps_build_registrar_nonce(wps, msg) ||
1406 wps_build_uuid_r(wps, msg) ||
1407 wps_build_public_key(wps, msg) ||
1408 wps_derive_keys(wps) ||
1409 wps_build_auth_type_flags(wps, msg) ||
1410 wps_build_encr_type_flags(wps, msg) ||
1411 wps_build_conn_type_flags(wps, msg) ||
1412 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1413 wps_build_device_attrs(&wps->wps->dev, msg) ||
1414 wps_build_rf_bands(&wps->wps->dev, msg) ||
1415 wps_build_assoc_state(wps, msg) ||
1416 wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1417 wps_build_dev_password_id(msg, wps->dev_pw_id) ||
1418 wps_build_os_version(&wps->wps->dev, msg) ||
1419 wps_build_authenticator(wps, msg)) {
1420 wpabuf_free(msg);
1421 return NULL;
1422 }
1423
1424 wps->int_reg = 1;
1425 wps->state = RECV_M3;
1426 return msg;
1427 }
1428
1429
1430 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1431 {
1432 struct wpabuf *msg;
1433 u16 err = wps->config_error;
1434
1435 wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1436 msg = wpabuf_alloc(1000);
1437 if (msg == NULL)
1438 return NULL;
1439
1440 if (wps->wps->ap && wps->wps->ap_setup_locked &&
1441 err == WPS_CFG_NO_ERROR)
1442 err = WPS_CFG_SETUP_LOCKED;
1443
1444 if (wps_build_version(msg) ||
1445 wps_build_msg_type(msg, WPS_M2D) ||
1446 wps_build_enrollee_nonce(wps, msg) ||
1447 wps_build_registrar_nonce(wps, msg) ||
1448 wps_build_uuid_r(wps, msg) ||
1449 wps_build_auth_type_flags(wps, msg) ||
1450 wps_build_encr_type_flags(wps, msg) ||
1451 wps_build_conn_type_flags(wps, msg) ||
1452 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1453 wps_build_device_attrs(&wps->wps->dev, msg) ||
1454 wps_build_rf_bands(&wps->wps->dev, msg) ||
1455 wps_build_assoc_state(wps, msg) ||
1456 wps_build_config_error(msg, err) ||
1457 wps_build_os_version(&wps->wps->dev, msg)) {
1458 wpabuf_free(msg);
1459 return NULL;
1460 }
1461
1462 wps->state = RECV_M2D_ACK;
1463 return msg;
1464 }
1465
1466
1467 static struct wpabuf * wps_build_m4(struct wps_data *wps)
1468 {
1469 struct wpabuf *msg, *plain;
1470
1471 wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1472
1473 wpa_printf(MSG_DEBUG, "WPS: Dev Password Len: %d", wps->dev_password_len);
1474 wpa_printf(MSG_DEBUG, "WPS: Dev Password: %s", wps->dev_password);
1475
1476 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1477
1478 plain = wpabuf_alloc(200);
1479 if (plain == NULL)
1480 return NULL;
1481
1482 msg = wpabuf_alloc(1000);
1483 if (msg == NULL) {
1484 wpabuf_free(plain);
1485 return NULL;
1486 }
1487
1488 wpa_printf(MSG_DEBUG, "Allocs OK, building M4 packet");
1489
1490 if (wps_build_version(msg) ||
1491 wps_build_msg_type(msg, WPS_M4) ||
1492 wps_build_enrollee_nonce(wps, msg) ||
1493 wps_build_r_hash(wps, msg) ||
1494 wps_build_r_snonce1(wps, plain) ||
1495 wps_build_key_wrap_auth(wps, plain) ||
1496 wps_build_encr_settings(wps, msg, plain) ||
1497 wps_build_authenticator(wps, msg)) {
1498 wpabuf_free(plain);
1499 wpabuf_free(msg);
1500 return NULL;
1501 }
1502 wpabuf_free(plain);
1503
1504 wps->state = RECV_M5;
1505 return msg;
1506 }
1507
1508
1509 static struct wpabuf * wps_build_m6(struct wps_data *wps)
1510 {
1511 struct wpabuf *msg, *plain;
1512
1513 wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1514
1515 plain = wpabuf_alloc(200);
1516 if (plain == NULL)
1517 return NULL;
1518
1519 msg = wpabuf_alloc(1000);
1520 if (msg == NULL) {
1521 wpabuf_free(plain);
1522 return NULL;
1523 }
1524
1525 if (wps_build_version(msg) ||
1526 wps_build_msg_type(msg, WPS_M6) ||
1527 wps_build_enrollee_nonce(wps, msg) ||
1528 wps_build_r_snonce2(wps, plain) ||
1529 wps_build_key_wrap_auth(wps, plain) ||
1530 wps_build_encr_settings(wps, msg, plain) ||
1531 wps_build_authenticator(wps, msg)) {
1532 wpabuf_free(plain);
1533 wpabuf_free(msg);
1534 return NULL;
1535 }
1536 wpabuf_free(plain);
1537
1538 wps->wps_pin_revealed = 1;
1539 wps->state = RECV_M7;
1540 return msg;
1541 }
1542
1543
1544 static struct wpabuf * wps_build_m8(struct wps_data *wps)
1545 {
1546 struct wpabuf *msg, *plain;
1547
1548 wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1549
1550 plain = wpabuf_alloc(500);
1551 if (plain == NULL)
1552 return NULL;
1553
1554 msg = wpabuf_alloc(1000);
1555 if (msg == NULL) {
1556 wpabuf_free(plain);
1557 return NULL;
1558 }
1559
1560 if (wps_build_version(msg) ||
1561 wps_build_msg_type(msg, WPS_M8) ||
1562 wps_build_enrollee_nonce(wps, msg) ||
1563 ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
1564 (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
1565 wps_build_key_wrap_auth(wps, plain) ||
1566 wps_build_encr_settings(wps, msg, plain) ||
1567 wps_build_authenticator(wps, msg)) {
1568 wpabuf_free(plain);
1569 wpabuf_free(msg);
1570 return NULL;
1571 }
1572 wpabuf_free(plain);
1573
1574 wps->state = RECV_DONE;
1575 return msg;
1576 }
1577
1578
1579 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
1580 {
1581 struct wpabuf *msg;
1582
1583 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
1584
1585 msg = wpabuf_alloc(1000);
1586 if (msg == NULL)
1587 return NULL;
1588
1589 if (wps_build_version(msg) ||
1590 wps_build_msg_type(msg, WPS_WSC_ACK) ||
1591 wps_build_enrollee_nonce(wps, msg) ||
1592 wps_build_registrar_nonce(wps, msg)) {
1593 wpabuf_free(msg);
1594 return NULL;
1595 }
1596
1597 return msg;
1598 }
1599
1600
1601 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
1602 {
1603 struct wpabuf *msg;
1604
1605 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
1606
1607 msg = wpabuf_alloc(1000);
1608 if (msg == NULL)
1609 return NULL;
1610
1611 if (wps_build_version(msg) ||
1612 wps_build_msg_type(msg, WPS_WSC_NACK) ||
1613 wps_build_enrollee_nonce(wps, msg) ||
1614 wps_build_registrar_nonce(wps, msg) ||
1615 wps_build_config_error(msg, wps->config_error)) {
1616 wpabuf_free(msg);
1617 return NULL;
1618 }
1619
1620 return msg;
1621 }
1622
1623
1624 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1625 enum wsc_op_code *op_code,
1626 int type)
1627 {
1628 struct wpabuf *msg = NULL;
1629
1630 if(wps->wps->registrar != NULL)
1631 {
1632 switch (type)
1633 {
1634 case SEND_M2:
1635 if(wps_get_dev_password(wps) >= 0)
1636 {
1637 msg = wps_build_m2(wps);
1638 cprintf(VERBOSE, "[+] Sending M2 message\n");
1639 *op_code = WSC_MSG;
1640 break;
1641 }
1642 /* Fall through */
1643 case SEND_WSC_NACK:
1644 msg = wps_build_wsc_nack(wps);
1645 cprintf(VERBOSE, "[+] Sending WSC NACK\n");
1646 *op_code = WSC_NACK;
1647 break;
1648 case SEND_M4:
1649 msg = wps_build_m4(wps);
1650 cprintf(VERBOSE, "[+] Sending M4 message\n");
1651 *op_code = WSC_MSG;
1652 break;
1653 case SEND_M6:
1654 msg = wps_build_m6(wps);
1655 cprintf(VERBOSE, "[+] Sending M6 message\n");
1656 *op_code = WSC_MSG;
1657 break;
1658 case SEND_M8:
1659 msg = wps_build_m8(wps);
1660 cprintf(VERBOSE, "[+] Sending M8 message\n");
1661 *op_code = WSC_MSG;
1662 break;
1663 case RECV_DONE:
1664 msg = wps_build_wsc_ack(wps);
1665 cprintf(VERBOSE, "[+] Sending WSC ACK\n");
1666 *op_code = WSC_ACK;
1667 break;
1668 default:
1669 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
1670 "a message", wps->state);
1671 msg = NULL;
1672 break;
1673 }
1674 }
1675
1676 if (*op_code == WSC_MSG && msg)
1677 {
1678 /* Save a copy of the last message for Authenticator derivation
1679 */
1680 wpabuf_free(wps->last_msg);
1681 wps->last_msg = wpabuf_dup(msg);
1682 }
1683
1684 return msg;
1685 }
1686
1687
1688 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
1689 {
1690 if (e_nonce == NULL) {
1691 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
1692 return -1;
1693 }
1694
1695 os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
1696 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
1697 wps->nonce_e, WPS_NONCE_LEN);
1698
1699 /****** ADD THIS PART ******/
1700 memset(cmd_pixie,0,sizeof(cmd_pixie));
1701 memset(cmd_pixie_aux,0,sizeof(cmd_pixie_aux));
1702 strcat(cmd_pixie,"pixiewps ");
1703
1704 if(globule->op_pixie==2)
1705 {
1706 strcat(cmd_pixie," -n ");
1707 }
1708 printf("[P] E-Nonce: ");
1709 int pixiecnt = 0;
1710 for (; pixiecnt < WPS_NONCE_LEN; pixiecnt++) {
1711 printf("%02x", wps->nonce_e[pixiecnt]);
1712 if(globule->op_pixie==2)
1713 {
1714 sprintf(cmd_pixie_aux, "%02x", wps->nonce_e[pixiecnt]);
1715 strcat(cmd_pixie,cmd_pixie_aux);
1716 }
1717 if (pixiecnt != WPS_NONCE_LEN - 1) {
1718 printf(":");
1719 if(globule->op_pixie==2)
1720 {
1721 strcat(cmd_pixie,":");
1722 }
1723 }
1724 }
1725 printf("\n");
1726 /******/
1727
1728
1729 return 0;
1730 }
1731
1732
1733 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
1734 {
1735 if (r_nonce == NULL) {
1736 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
1737 return -1;
1738 }
1739
1740 if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
1741 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
1742 return -1;
1743 }
1744
1745 return 0;
1746 }
1747
1748
1749 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
1750 {
1751 if (uuid_e == NULL) {
1752 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
1753 return -1;
1754 }
1755
1756 os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
1757 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
1758
1759 return 0;
1760 }
1761
1762
1763 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
1764 {
1765 if (pw_id == NULL) {
1766 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
1767 return -1;
1768 }
1769
1770 wps->dev_pw_id = WPA_GET_BE16(pw_id);
1771 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
1772
1773 return 0;
1774 }
1775
1776
1777 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
1778 {
1779 if (e_hash1 == NULL) {
1780 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
1781 return -1;
1782 }
1783
1784 os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
1785 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
1786
1787 /****** ADD THIS PART ******/
1788 strcat(cmd_pixie," -s ");
1789 printf("[P] E-Hash1: ");
1790 int pixiecnt = 0;
1791 for (; pixiecnt < WPS_HASH_LEN; pixiecnt++) {
1792 printf("%02x", wps->peer_hash1[pixiecnt]);
1793 sprintf(cmd_pixie_aux, "%02x", wps->peer_hash1[pixiecnt]);
1794 strcat(cmd_pixie,cmd_pixie_aux);
1795 if (pixiecnt != WPS_HASH_LEN - 1) {
1796 printf(":");
1797 strcat(cmd_pixie,":");
1798 }
1799 }
1800 printf("\n");
1801 /******/
1802
1803
1804 return 0;
1805 }
1806
1807
1808 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
1809 {
1810 if (e_hash2 == NULL) {
1811 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
1812 return -1;
1813 }
1814
1815 os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
1816 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
1817
1818 /****** ADD THIS PART ******/
1819 strcat(cmd_pixie," -z ");
1820 printf("[P] E-Hash2: ");
1821 int pixiecnt = 0;
1822 for (; pixiecnt < WPS_HASH_LEN; pixiecnt++) {
1823 printf("%02x", wps->peer_hash2[pixiecnt]);
1824 sprintf(cmd_pixie_aux, "%02x", wps->peer_hash2[pixiecnt]);
1825 strcat(cmd_pixie,cmd_pixie_aux);
1826 if (pixiecnt != WPS_HASH_LEN - 1) {
1827 printf(":");
1828 strcat(cmd_pixie,":");
1829 }
1830 }
1831 printf("\n");
1832 /******/
1833
1834 if(globule->op_pixie==1 || globule->op_pixie==2){
1835 strcat(cmd_pixie," -S ");
1836 }
1837 //sprintf(cmd_pixie,"%s -S",cmd_pixie);
1838
1839
1840 if(globule->op_pixie==1 || globule->op_pixie==2 || globule->op_pixie==3)
1841 {
1842
1843 FILE *fpixe;
1844
1845 if ((fpixe = popen(cmd_pixie, "r")) == NULL) {
1846 printf("Error opening pipe!\n");
1847 //return -1;
1848 }
1849
1850 int pixie_test=0;
1851 char pixie_pin[16];
1852 char *aux_pixie_pin;
1853
1854 memset(pixie_pin, 0, sizeof(pixie_pin));
1855
1856 while (fgets(pixie_buf_aux, 4000, fpixe) != NULL) {
1857
1858 printf("[Pixie-Dust] %s", pixie_buf_aux);
1859
1860 aux_pixie_pin = strstr(pixie_buf_aux,"WPS pin not found");
1861 if( aux_pixie_pin != NULL)
1862 {
1863 pixie_test = 0;
1864 //exit(0);
1865 }
1866 else
1867 {
1868 //output pixiewps change?
1869 exit(0);
1870 }
1871
1872 aux_pixie_pin = strstr(pixie_buf_aux,,"WPS pin:");
1873 if(aux_pixie_pin)!= NULL)
1874 {
1875 pixie_test = 1;
1876 //exit(0);
1877 //here will get the pin
1878 strncpy(pixie_pin, aux_pixie_pin+9, 8);
1879 }
1880 else
1881 {
1882 //output pixiewps is change?
1883 exit(0);
1884 }
1885
1886
1887
1888 }
1889
1890 if(pixie_test == 1)
1891 {
1892 //here will make the test to get pass
1893
1894 FILE *fpixe_test;
1895
1896
1897
1898 if ((fpixe_test = popen(cmd_pixie, "r")) == NULL) {
1899 printf("Error opening pipe!\n");
1900 //return -1;
1901 }
1902
1903
1904
1905
1906 exit(0);
1907 }
1908 else
1909 {
1910 exit(0);
1911 }
1912
1913
1914 if(pclose(fpixe)) {
1915 //printf("Command not found or exited with error status\n");
1916 //return -1;
1917 }
1918
1919 }
1920
1921 //printf(" %s ",cmd_pixie);
1922
1923
1924 return 0;
1925 }
1926
1927
1928 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
1929 {
1930 u8 hash[SHA256_MAC_LEN];
1931 const u8 *addr[4];
1932 size_t len[4];
1933
1934 if (e_snonce1 == NULL) {
1935 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
1936 return -1;
1937 }
1938
1939 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
1940 WPS_SECRET_NONCE_LEN);
1941
1942 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1943 addr[0] = e_snonce1;
1944 len[0] = WPS_SECRET_NONCE_LEN;
1945 addr[1] = wps->psk1;
1946 len[1] = WPS_PSK_LEN;
1947 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1948 len[2] = wpabuf_len(wps->dh_pubkey_e);
1949 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1950 len[3] = wpabuf_len(wps->dh_pubkey_r);
1951 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1952
1953 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
1954 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
1955 "not match with the pre-committed value");
1956 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1957 wps_pwd_auth_fail_event(wps->wps, 0, 1);
1958 return -1;
1959 }
1960
1961 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
1962 "half of the device password");
1963
1964 return 0;
1965 }
1966
1967
1968 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
1969 {
1970 u8 hash[SHA256_MAC_LEN];
1971 const u8 *addr[4];
1972 size_t len[4];
1973
1974 if (e_snonce2 == NULL) {
1975 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
1976 return -1;
1977 }
1978
1979 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
1980 WPS_SECRET_NONCE_LEN);
1981
1982 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1983 addr[0] = e_snonce2;
1984 len[0] = WPS_SECRET_NONCE_LEN;
1985 addr[1] = wps->psk2;
1986 len[1] = WPS_PSK_LEN;
1987 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1988 len[2] = wpabuf_len(wps->dh_pubkey_e);
1989 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1990 len[3] = wpabuf_len(wps->dh_pubkey_r);
1991 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1992
1993 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
1994 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
1995 "not match with the pre-committed value");
1996 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
1997 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1998 wps_pwd_auth_fail_event(wps->wps, 0, 2);
1999 return -1;
2000 }
2001
2002 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
2003 "half of the device password");
2004 wps->wps_pin_revealed = 0;
2005 wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
2006
2007 return 0;
2008 }
2009
2010
2011 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
2012 {
2013 if (mac_addr == NULL) {
2014 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
2015 return -1;
2016 }
2017
2018 wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
2019 MAC2STR(mac_addr));
2020 os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
2021 os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
2022
2023 return 0;
2024 }
2025
2026
2027 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
2028 size_t pk_len)
2029 {
2030 if (pk == NULL || pk_len == 0) {
2031 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
2032 return -1;
2033 }
2034
2035 #ifdef CONFIG_WPS_OOB
2036 if (wps->wps->oob_conf.pubkey_hash != NULL) {
2037 const u8 *addr[1];
2038 u8 hash[WPS_HASH_LEN];
2039
2040 addr[0] = pk;
2041 sha256_vector(1, addr, &pk_len, hash);
2042 if (os_memcmp(hash,
2043 wpabuf_head(wps->wps->oob_conf.pubkey_hash),
2044 WPS_OOB_PUBKEY_HASH_LEN) != 0) {
2045 wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
2046 return -1;
2047 }
2048 }
2049 #endif /* CONFIG_WPS_OOB */
2050
2051 wpabuf_free(wps->dh_pubkey_e);
2052 wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
2053 if (wps->dh_pubkey_e == NULL)
2054 return -1;
2055
2056 /****** ADD THIS PART ******/
2057 // memset (cmd_pixie,0,sizeof(cmd_pixie));
2058 strcat(cmd_pixie," -e ");
2059 //sprintf( cmd_pixie, "", cmd_pixie, str2);
2060
2061 printf("[P] PKE: ");
2062 int pixiecnt = 0;
2063 for (; pixiecnt < 192; pixiecnt++) {
2064 printf("%02x", pk[pixiecnt]);
2065 sprintf(cmd_pixie_aux, "%02x", pk[pixiecnt]);
2066 strcat(cmd_pixie,cmd_pixie_aux);
2067 if (pixiecnt != 191) {
2068 printf(":");
2069 strcat(cmd_pixie,":");
2070 }
2071 }
2072 printf("\n");
2073 /******/
2074
2075 return 0;
2076 }
2077
2078
2079 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
2080 {
2081 u16 auth_types;
2082
2083 if (auth == NULL) {
2084 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
2085 "received");
2086 return -1;
2087 }
2088
2089 auth_types = WPA_GET_BE16(auth);
2090
2091 wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
2092 auth_types);
2093 wps->auth_type = wps->wps->auth_types & auth_types;
2094 if (wps->auth_type == 0) {
2095 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2096 "authentication types (own 0x%x Enrollee 0x%x)",
2097 wps->wps->auth_types, auth_types);
2098 #ifdef WPS_WORKAROUNDS
2099 /*
2100 * Some deployed implementations seem to advertise incorrect
2101 * information in this attribute. For example, Linksys WRT350N
2102 * seems to have a byteorder bug that breaks this negotiation.
2103 * In order to interoperate with existing implementations,
2104 * assume that the Enrollee supports everything we do.
2105 */
2106 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2107 "does not advertise supported authentication types "
2108 "correctly");
2109 wps->auth_type = wps->wps->auth_types;
2110 #else /* WPS_WORKAROUNDS */
2111 return -1;
2112 #endif /* WPS_WORKAROUNDS */
2113 }
2114
2115 return 0;
2116 }
2117
2118
2119 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
2120 {
2121 u16 encr_types;
2122
2123 if (encr == NULL) {
2124 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
2125 "received");
2126 return -1;
2127 }
2128
2129 encr_types = WPA_GET_BE16(encr);
2130
2131 wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
2132 encr_types);
2133 wps->encr_type = wps->wps->encr_types & encr_types;
2134 if (wps->encr_type == 0) {
2135 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2136 "encryption types (own 0x%x Enrollee 0x%x)",
2137 wps->wps->encr_types, encr_types);
2138 #ifdef WPS_WORKAROUNDS
2139 /*
2140 * Some deployed implementations seem to advertise incorrect
2141 * information in this attribute. For example, Linksys WRT350N
2142 * seems to have a byteorder bug that breaks this negotiation.
2143 * In order to interoperate with existing implementations,
2144 * assume that the Enrollee supports everything we do.
2145 */
2146 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2147 "does not advertise supported encryption types "
2148 "correctly");
2149 wps->encr_type = wps->wps->encr_types;
2150 #else /* WPS_WORKAROUNDS */
2151 return -1;
2152 #endif /* WPS_WORKAROUNDS */
2153 }
2154
2155 return 0;
2156 }
2157
2158
2159 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
2160 {
2161 if (conn == NULL) {
2162 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
2163 "received");
2164 return -1;
2165 }
2166
2167 wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
2168 *conn);
2169
2170 return 0;
2171 }
2172
2173
2174 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
2175 {
2176 u16 m;
2177
2178 if (methods == NULL) {
2179 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
2180 return -1;
2181 }
2182
2183 m = WPA_GET_BE16(methods);
2184
2185 wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
2186 "%s%s%s%s%s%s%s%s%s", m,
2187 m & WPS_CONFIG_USBA ? " [USBA]" : "",
2188 m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
2189 m & WPS_CONFIG_LABEL ? " [Label]" : "",
2190 m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
2191 m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
2192 m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
2193 m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
2194 m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
2195 m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
2196
2197 if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
2198 /*
2199 * The Enrollee does not have a display so it is unlikely to be
2200 * able to show the passphrase to a user and as such, could
2201 * benefit from receiving PSK to reduce key derivation time.
2202 */
2203 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
2204 "Enrollee not supporting display");
2205 wps->use_psk_key = 1;
2206 }
2207
2208 return 0;
2209 }
2210
2211
2212 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
2213 {
2214 if (state == NULL) {
2215 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
2216 "received");
2217 return -1;
2218 }
2219
2220 wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2221 *state);
2222
2223 return 0;
2224 }
2225
2226
2227 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
2228 {
2229 u16 a;
2230
2231 if (assoc == NULL) {
2232 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
2233 return -1;
2234 }
2235
2236 a = WPA_GET_BE16(assoc);
2237 wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
2238
2239 return 0;
2240 }
2241
2242
2243 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
2244 {
2245 u16 e;
2246
2247 if (err == NULL) {
2248 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
2249 return -1;
2250 }
2251
2252 e = WPA_GET_BE16(err);
2253 wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
2254
2255 return 0;
2256 }
2257
2258
2259 static enum wps_process_res wps_process_m1(struct wps_data *wps,
2260 struct wps_parse_attr *attr)
2261 {
2262 wpa_printf(MSG_DEBUG, "WPS: Received M1");
2263
2264 if (wps->state != RECV_M1) {
2265 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2266 "receiving M1", wps->state);
2267 return WPS_FAILURE;
2268 }
2269
2270 if (wps_process_uuid_e(wps, attr->uuid_e) ||
2271 wps_process_mac_addr(wps, attr->mac_addr) ||
2272 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
2273 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
2274 wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
2275 wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
2276 wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
2277 wps_process_config_methods(wps, attr->config_methods) ||
2278 wps_process_wps_state(wps, attr->wps_state) ||
2279 wps_process_device_attrs(&wps->peer_dev, attr) ||
2280 wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
2281 wps_process_assoc_state(wps, attr->assoc_state) ||
2282 wps_process_dev_password_id(wps, attr->dev_password_id) ||
2283 wps_process_config_error(wps, attr->config_error) ||
2284 wps_process_os_version(&wps->peer_dev, attr->os_version))
2285 return WPS_FAILURE;
2286
2287 wpa_printf(MSG_DEBUG, "WPS: M1 Processed");
2288
2289 if (wps->dev_pw_id < 0x10 &&
2290 wps->dev_pw_id != DEV_PW_DEFAULT &&
2291 wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
2292 wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
2293 wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
2294 (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
2295 !wps->wps->registrar->pbc)) {
2296 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
2297 wps->dev_pw_id);
2298 wps->state = SEND_M2D;
2299 return WPS_CONTINUE;
2300 }
2301
2302 wpa_printf(MSG_DEBUG, "WPS: dev_pw_id checked");
2303
2304 #ifdef CONFIG_WPS_OOB
2305 if (wps->dev_pw_id >= 0x10 &&
2306 wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
2307 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
2308 "%d mismatch", wps->dev_pw_id);
2309 wps->state = SEND_M2D;
2310 return WPS_CONTINUE;
2311 }
2312 #endif /* CONFIG_WPS_OOB */
2313
2314 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
2315 if (wps->wps->registrar->force_pbc_overlap ||
2316 wps_registrar_pbc_overlap(wps->wps->registrar,
2317 wps->mac_addr_e, wps->uuid_e)) {
2318 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
2319 "negotiation");
2320 wps->state = SEND_M2D;
2321 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2322 wps_pbc_overlap_event(wps->wps);
2323 wps->wps->registrar->force_pbc_overlap = 1;
2324 return WPS_CONTINUE;
2325 }
2326 wps_registrar_add_pbc_session(wps->wps->registrar,
2327 wps->mac_addr_e, wps->uuid_e);
2328 wps->pbc = 1;
2329 }
2330
2331 wpa_printf(MSG_DEBUG, "WPS: PBC Checked");
2332
2333 #ifdef WPS_WORKAROUNDS
2334 /*
2335 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
2336 * passphrase format. To avoid interop issues, force PSK format to be
2337 * used.
2338 */
2339 if (!wps->use_psk_key &&
2340 wps->peer_dev.manufacturer &&
2341 os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
2342 wps->peer_dev.model_name &&
2343 os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
2344 wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
2345 "PSK format");
2346 wps->use_psk_key = 1;
2347 }
2348 #endif /* WPS_WORKAROUNDS */
2349 wpa_printf(MSG_DEBUG, "WPS: Entering State SEND_M2");
2350
2351 wps->state = SEND_M2;
2352 return WPS_CONTINUE;
2353 }
2354
2355
2356 static enum wps_process_res wps_process_m3(struct wps_data *wps,
2357 const struct wpabuf *msg,
2358 struct wps_parse_attr *attr)
2359 {
2360 wpa_printf(MSG_DEBUG, "WPS: Received M3");
2361
2362 if (wps->state != RECV_M3) {
2363 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2364 "receiving M3", wps->state);
2365 wps->state = SEND_WSC_NACK;
2366 return WPS_CONTINUE;
2367 }
2368
2369 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2370 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2371 "session overlap");
2372 wps->state = SEND_WSC_NACK;
2373 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2374 return WPS_CONTINUE;
2375 }
2376
2377 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2378 wps_process_authenticator(wps, attr->authenticator, msg) ||
2379 wps_process_e_hash1(wps, attr->e_hash1) ||
2380 wps_process_e_hash2(wps, attr->e_hash2)) {
2381 wps->state = SEND_WSC_NACK;
2382 return WPS_CONTINUE;
2383 }
2384
2385 wps->state = SEND_M4;
2386 return WPS_CONTINUE;
2387 }
2388
2389
2390 static enum wps_process_res wps_process_m5(struct wps_data *wps,
2391 const struct wpabuf *msg,
2392 struct wps_parse_attr *attr)
2393 {
2394 struct wpabuf *decrypted;
2395 struct wps_parse_attr eattr;
2396
2397 wpa_printf(MSG_DEBUG, "WPS: Received M5");
2398
2399 if (wps->state != RECV_M5) {
2400 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2401 "receiving M5", wps->state);
2402 wps->state = SEND_WSC_NACK;
2403 return WPS_CONTINUE;
2404 }
2405
2406 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2407 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2408 "session overlap");
2409 wps->state = SEND_WSC_NACK;
2410 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2411 return WPS_CONTINUE;
2412 }
2413
2414 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2415 wps_process_authenticator(wps, attr->authenticator, msg)) {
2416 wps->state = SEND_WSC_NACK;
2417 return WPS_CONTINUE;
2418 }
2419
2420 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2421 attr->encr_settings_len);
2422 if (decrypted == NULL) {
2423 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2424 "Settings attribute");
2425 wps->state = SEND_WSC_NACK;
2426 return WPS_CONTINUE;
2427 }
2428
2429 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2430 "attribute");
2431 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2432 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2433 wps_process_e_snonce1(wps, eattr.e_snonce1)) {
2434 wpabuf_free(decrypted);
2435 wps->state = SEND_WSC_NACK;
2436 return WPS_CONTINUE;
2437 }
2438 wpabuf_free(decrypted);
2439
2440 wps->state = SEND_M6;
2441 return WPS_CONTINUE;
2442 }
2443
2444
2445 static void wps_sta_cred_cb(struct wps_data *wps)
2446 {
2447 /*
2448 * Update credential to only include a single authentication and
2449 * encryption type in case the AP configuration includes more than one
2450 * option.
2451 */
2452 if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
2453 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
2454 else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
2455 wps->cred.auth_type = WPS_AUTH_WPAPSK;
2456 if (wps->cred.encr_type & WPS_ENCR_AES)
2457 wps->cred.encr_type = WPS_ENCR_AES;
2458 else if (wps->cred.encr_type & WPS_ENCR_TKIP)
2459 wps->cred.encr_type = WPS_ENCR_TKIP;
2460 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
2461 "AP configuration");
2462 if (wps->wps->cred_cb)
2463 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2464 }
2465
2466
2467 static void wps_cred_update(struct wps_credential *dst,
2468 struct wps_credential *src)
2469 {
2470 os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
2471 dst->ssid_len = src->ssid_len;
2472 dst->auth_type = src->auth_type;
2473 dst->encr_type = src->encr_type;
2474 dst->key_idx = src->key_idx;
2475 os_memcpy(dst->key, src->key, sizeof(dst->key));
2476 dst->key_len = src->key_len;
2477 }
2478
2479
2480 static int wps_process_ap_settings_r(struct wps_data *wps,
2481 struct wps_parse_attr *attr)
2482 {
2483 if (wps->wps->ap || wps->er)
2484 return 0;
2485
2486 /* AP Settings Attributes in M7 when Enrollee is an AP */
2487 if (wps_process_ap_settings(attr, &wps->cred) < 0)
2488 return -1;
2489
2490 /* @@@ Save a copy of the network key and ssid directly to the wps_data structure @@@ */
2491 if(wps->cred.key_len > 0)
2492 {
2493 wps->key = strdup(wps->cred.key);
2494 }
2495 if(wps->cred.ssid_len > 0)
2496 {
2497 wps->essid = strdup(wps->cred.ssid);
2498 }
2499
2500 if (wps->new_ap_settings) {
2501 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
2502 "new settings");
2503 wps_cred_update(&wps->cred, wps->new_ap_settings);
2504 return 0;
2505 } else {
2506 /*
2507 * Use the AP PIN only to receive the current AP settings, not
2508 * to reconfigure the AP.
2509 */
2510 if (wps->ap_settings_cb) {
2511 wps->ap_settings_cb(wps->ap_settings_cb_ctx,
2512 &wps->cred);
2513 return 1;
2514 }
2515 wps_sta_cred_cb(wps);
2516 return 1;
2517 }
2518 }
2519
2520
2521 static enum wps_process_res wps_process_m7(struct wps_data *wps,
2522 const struct wpabuf *msg,
2523 struct wps_parse_attr *attr)
2524 {
2525 struct wpabuf *decrypted;
2526 struct wps_parse_attr eattr;
2527
2528 wpa_printf(MSG_DEBUG, "WPS: Received M7");
2529
2530 if (wps->state != RECV_M7) {
2531 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2532 "receiving M7", wps->state);
2533 wps->state = SEND_WSC_NACK;
2534 return WPS_CONTINUE;
2535 }
2536
2537 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2538 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2539 "session overlap");
2540 wps->state = SEND_WSC_NACK;
2541 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2542 return WPS_CONTINUE;
2543 }
2544
2545 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2546 wps_process_authenticator(wps, attr->authenticator, msg)) {
2547 wps->state = SEND_WSC_NACK;
2548 return WPS_CONTINUE;
2549 }
2550
2551 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2552 attr->encr_settings_len);
2553 if (decrypted == NULL) {
2554 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
2555 "Settings attribute");
2556 wps->state = SEND_WSC_NACK;
2557 return WPS_CONTINUE;
2558 }
2559
2560 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2561 "attribute");
2562
2563 /* @@@ One of these fails, but we don't really care. We just want the ap settings */
2564 /*
2565 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2566 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2567 wps_process_e_snonce2(wps, eattr.e_snonce2) ||
2568 wps_process_ap_settings_r(wps, &eattr)) {
2569 wpabuf_free(decrypted);
2570 wps->state = SEND_WSC_NACK;
2571 return WPS_CONTINUE;
2572 }
2573 */
2574
2575 if(wps_parse_msg(decrypted, &eattr) >= 0)
2576 {
2577 wps_process_ap_settings_r(wps, &eattr);
2578 }
2579
2580 wpabuf_free(decrypted);
2581
2582 wps->state = SEND_M8;
2583 return WPS_CONTINUE;
2584 }
2585
2586
2587 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
2588 const struct wpabuf *msg)
2589 {
2590 struct wps_parse_attr attr;
2591 enum wps_process_res ret = WPS_CONTINUE;
2592
2593 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
2594
2595 if (wps_parse_msg(msg, &attr) < 0)
2596 return WPS_FAILURE;
2597
2598 wpa_printf(MSG_DEBUG, "WPS: Parsed WSC_MSG");
2599
2600 if (!wps_version_supported(attr.version)) {
2601 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2602 attr.version ? *attr.version : 0);
2603 return WPS_FAILURE;
2604 }
2605
2606 if (attr.msg_type == NULL) {
2607 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2608 return WPS_FAILURE;
2609 }
2610
2611 if (*attr.msg_type != WPS_M1 &&
2612 (attr.registrar_nonce == NULL ||
2613 os_memcmp(wps->nonce_r, attr.registrar_nonce,
2614 WPS_NONCE_LEN != 0))) {
2615 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2616 return WPS_FAILURE;
2617 }
2618
2619 switch (*attr.msg_type) {
2620 case WPS_M1:
2621 #ifdef CONFIG_WPS_UPNP
2622 if (wps->wps->wps_upnp && attr.mac_addr) {
2623 /* Remove old pending messages when starting new run */
2624 wps_free_pending_msgs(wps->wps->upnp_msgs);
2625 wps->wps->upnp_msgs = NULL;
2626
2627 upnp_wps_device_send_wlan_event(
2628 wps->wps->wps_upnp, attr.mac_addr,
2629 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
2630 }
2631 #endif /* CONFIG_WPS_UPNP */
2632 ret = wps_process_m1(wps, &attr);
2633 break;
2634 case WPS_M3:
2635 ret = wps_process_m3(wps, msg, &attr);
2636 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2637 wps_fail_event(wps->wps, WPS_M3);
2638 break;
2639 case WPS_M5:
2640 ret = wps_process_m5(wps, msg, &attr);
2641 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2642 wps_fail_event(wps->wps, WPS_M5);
2643 break;
2644 case WPS_M7:
2645 ret = wps_process_m7(wps, msg, &attr);
2646 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2647 wps_fail_event(wps->wps, WPS_M7);
2648 break;
2649 default:
2650 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
2651 *attr.msg_type);
2652 return WPS_FAILURE;
2653 }
2654
2655 if (ret == WPS_CONTINUE) {
2656 /* Save a copy of the last message for Authenticator derivation
2657 */
2658
2659 wpa_printf(MSG_DEBUG, "WPS: WPS_CONTINUE, Freeing Last Message");
2660 wpabuf_free(wps->last_msg);
2661 wpa_printf(MSG_DEBUG, "WPS: WPS_CONTINUE, Saving Last Message");
2662 wps->last_msg = wpabuf_dup(msg);
2663 }
2664
2665 wpa_printf(MSG_DEBUG, "WPS: returning");
2666 return ret;
2667 }
2668
2669
2670 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
2671 const struct wpabuf *msg)
2672 {
2673 struct wps_parse_attr attr;
2674
2675 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
2676
2677 if (wps_parse_msg(msg, &attr) < 0)
2678 return WPS_FAILURE;
2679
2680 if (!wps_version_supported(attr.version)) {
2681 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2682 attr.version ? *attr.version : 0);
2683 return WPS_FAILURE;
2684 }
2685
2686 if (attr.msg_type == NULL) {
2687 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2688 return WPS_FAILURE;
2689 }
2690
2691 if (*attr.msg_type != WPS_WSC_ACK) {
2692 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2693 *attr.msg_type);
2694 return WPS_FAILURE;
2695 }
2696
2697 #ifdef CONFIG_WPS_UPNP
2698 if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
2699 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2700 if (wps->wps->upnp_msgs)
2701 return WPS_CONTINUE;
2702 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2703 "external Registrar");
2704 return WPS_PENDING;
2705 }
2706 #endif /* CONFIG_WPS_UPNP */
2707
2708 if (attr.registrar_nonce == NULL ||
2709 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2710 {
2711 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2712 return WPS_FAILURE;
2713 }
2714
2715 if (attr.enrollee_nonce == NULL ||
2716 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2717 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2718 return WPS_FAILURE;
2719 }
2720
2721 if (wps->state == RECV_M2D_ACK) {
2722 #ifdef CONFIG_WPS_UPNP
2723 if (wps->wps->wps_upnp &&
2724 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2725 if (wps->wps->upnp_msgs)
2726 return WPS_CONTINUE;
2727 if (wps->ext_reg == 0)
2728 wps->ext_reg = 1;
2729 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2730 "external Registrar");
2731 return WPS_PENDING;
2732 }
2733 #endif /* CONFIG_WPS_UPNP */
2734
2735 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
2736 "terminate negotiation");
2737 }
2738
2739 return WPS_FAILURE;
2740 }
2741
2742
2743 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
2744 const struct wpabuf *msg)
2745 {
2746 struct wps_parse_attr attr;
2747 int old_state;
2748
2749 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
2750
2751 old_state = wps->state;
2752 wps->state = SEND_WSC_NACK;
2753
2754 if (wps_parse_msg(msg, &attr) < 0)
2755 return WPS_FAILURE;
2756
2757 if (!wps_version_supported(attr.version)) {
2758 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2759 attr.version ? *attr.version : 0);
2760 return WPS_FAILURE;
2761 }
2762
2763 if (attr.msg_type == NULL) {
2764 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2765 return WPS_FAILURE;
2766 }
2767
2768 if (*attr.msg_type != WPS_WSC_NACK) {
2769 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2770 *attr.msg_type);
2771 return WPS_FAILURE;
2772 }
2773
2774 #ifdef CONFIG_WPS_UPNP
2775 if (wps->wps->wps_upnp && wps->ext_reg) {
2776 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2777 "Registrar terminated by the Enrollee");
2778 return WPS_FAILURE;
2779 }
2780 #endif /* CONFIG_WPS_UPNP */
2781
2782 if (attr.registrar_nonce == NULL ||
2783 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2784 {
2785 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2786 return WPS_FAILURE;
2787 }
2788
2789 if (attr.enrollee_nonce == NULL ||
2790 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2791 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2792 return WPS_FAILURE;
2793 }
2794
2795 if (attr.config_error == NULL) {
2796 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
2797 "in WSC_NACK");
2798 return WPS_FAILURE;
2799 }
2800
2801 wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
2802 "Configuration Error %d", WPA_GET_BE16(attr.config_error));
2803
2804 switch (old_state) {
2805 case RECV_M3:
2806 wps_fail_event(wps->wps, WPS_M2);
2807 break;
2808 case RECV_M5:
2809 wps_fail_event(wps->wps, WPS_M4);
2810 break;
2811 case RECV_M7:
2812 wps_fail_event(wps->wps, WPS_M6);
2813 break;
2814 case RECV_DONE:
2815 wps_fail_event(wps->wps, WPS_M8);
2816 break;
2817 default:
2818 break;
2819 }
2820
2821 return WPS_FAILURE;
2822 }
2823
2824
2825 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
2826 const struct wpabuf *msg)
2827 {
2828 struct wps_parse_attr attr;
2829
2830 wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
2831
2832 if (wps->state != RECV_DONE &&
2833 (!wps->wps->wps_upnp || !wps->ext_reg)) {
2834 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2835 "receiving WSC_Done", wps->state);
2836 return WPS_FAILURE;
2837 }
2838
2839 if (wps_parse_msg(msg, &attr) < 0)
2840 return WPS_FAILURE;
2841
2842 if (!wps_version_supported(attr.version)) {
2843 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2844 attr.version ? *attr.version : 0);
2845 return WPS_FAILURE;
2846 }
2847
2848 if (attr.msg_type == NULL) {
2849 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2850 return WPS_FAILURE;
2851 }
2852
2853 if (*attr.msg_type != WPS_WSC_DONE) {
2854 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2855 *attr.msg_type);
2856 return WPS_FAILURE;
2857 }
2858
2859 #ifdef CONFIG_WPS_UPNP
2860 if (wps->wps->wps_upnp && wps->ext_reg) {
2861 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2862 "Registrar completed successfully");
2863 wps_device_store(wps->wps->registrar, &wps->peer_dev,
2864 wps->uuid_e);
2865 return WPS_DONE;
2866 }
2867 #endif /* CONFIG_WPS_UPNP */
2868
2869 if (attr.registrar_nonce == NULL ||
2870 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2871 {
2872 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2873 return WPS_FAILURE;
2874 }
2875
2876 if (attr.enrollee_nonce == NULL ||
2877 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2878 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2879 return WPS_FAILURE;
2880 }
2881
2882 wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
2883 /* @@@ We don't need any of this, since we're just cracking keys
2884 *
2885 wps_device_store(wps->wps->registrar, &wps->peer_dev,
2886 wps->uuid_e);
2887
2888 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
2889 wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
2890 struct wps_credential cred;
2891
2892 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
2893 "on first Enrollee connection");
2894
2895 os_memset(&cred, 0, sizeof(cred));
2896 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
2897 cred.ssid_len = wps->wps->ssid_len;
2898 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
2899 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
2900 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
2901 cred.key_len = wps->new_psk_len;
2902
2903 wps->wps->wps_state = WPS_STATE_CONFIGURED;
2904 wpa_hexdump_ascii_key(MSG_DEBUG,
2905 "WPS: Generated random passphrase",
2906 wps->new_psk, wps->new_psk_len);
2907 if (wps->wps->cred_cb)
2908 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
2909
2910 os_free(wps->new_psk);
2911 wps->new_psk = NULL;
2912 }
2913
2914 if (!wps->wps->ap && !wps->er)
2915 wps_sta_cred_cb(wps);
2916
2917 if (wps->new_psk) {
2918 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
2919 wps->new_psk, wps->new_psk_len)) {
2920 wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
2921 "new PSK");
2922 }
2923 os_free(wps->new_psk);
2924 wps->new_psk = NULL;
2925 }
2926
2927 wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
2928
2929 if (wps->pbc) {
2930 wps_registrar_remove_pbc_session(wps->wps->registrar,
2931 wps->mac_addr_e, wps->uuid_e);
2932 wps_registrar_pbc_completed(wps->wps->registrar);
2933 } else {
2934 wps_registrar_pin_completed(wps->wps->registrar);
2935 }
2936 *
2937 */
2938
2939 wps_success_event(wps->wps);
2940
2941 return WPS_DONE;
2942 }
2943
2944
2945 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
2946 enum wsc_op_code op_code,
2947 const struct wpabuf *msg)
2948 {
2949 enum wps_process_res ret;
2950
2951 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
2952 "op_code=%d)",
2953 (unsigned long) wpabuf_len(msg), op_code);
2954
2955 #ifdef CONFIG_WPS_UPNP
2956 if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
2957 struct wps_parse_attr attr;
2958 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
2959 *attr.msg_type == WPS_M3)
2960 wps->ext_reg = 2; /* past M2/M2D phase */
2961 }
2962 if (wps->ext_reg > 1)
2963 wps_registrar_free_pending_m2(wps->wps);
2964 if (wps->wps->wps_upnp && wps->ext_reg &&
2965 wps->wps->upnp_msgs == NULL &&
2966 (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
2967 {
2968 struct wps_parse_attr attr;
2969 int type;
2970 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
2971 type = -1;
2972 else
2973 type = *attr.msg_type;
2974 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
2975 " to external Registrar for processing", type);
2976 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
2977 wps->mac_addr_e,
2978 UPNP_WPS_WLANEVENT_TYPE_EAP,
2979 msg);
2980 if (op_code == WSC_MSG)
2981 return WPS_PENDING;
2982 } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
2983 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
2984 "external Registrar");
2985 return WPS_CONTINUE;
2986 }
2987 #endif /* CONFIG_WPS_UPNP */
2988
2989 switch (op_code) {
2990 case WSC_MSG:
2991 return wps_process_wsc_msg(wps, msg);
2992 case WSC_ACK:
2993 return wps_process_wsc_ack(wps, msg);
2994 case WSC_NACK:
2995 return wps_process_wsc_nack(wps, msg);
2996 case WSC_Done:
2997 ret = wps_process_wsc_done(wps, msg);
2998 if (ret == WPS_FAILURE) {
2999 wps->state = SEND_WSC_NACK;
3000 wps_fail_event(wps->wps, WPS_WSC_DONE);
3001 }
3002 return ret;
3003 default:
3004 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
3005 return WPS_FAILURE;
3006 }
3007 }
3008
3009
3010 int wps_registrar_update_ie(struct wps_registrar *reg)
3011 {
3012 return wps_set_ie(reg);
3013 }
3014
3015
3016 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
3017 void *timeout_ctx)
3018 {
3019 struct wps_registrar *reg = eloop_ctx;
3020
3021 wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
3022 "unselect internal Registrar");
3023 reg->selected_registrar = 0;
3024 reg->pbc = 0;
3025 wps_registrar_selected_registrar_changed(reg);
3026 }
3027
3028
3029 #ifdef CONFIG_WPS_UPNP
3030 static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
3031 struct subscription *s)
3032 {
3033 wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
3034 "config_methods=0x%x)",
3035 s->dev_password_id, s->config_methods);
3036 reg->sel_reg_union = 1;
3037 if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
3038 reg->sel_reg_dev_password_id_override = s->dev_password_id;
3039 if (reg->sel_reg_config_methods_override == -1)
3040 reg->sel_reg_config_methods_override = 0;
3041 reg->sel_reg_config_methods_override |= s->config_methods;
3042 }
3043 #endif /* CONFIG_WPS_UPNP */
3044
3045
3046 static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
3047 {
3048 #ifdef CONFIG_WPS_UPNP
3049 struct subscription *s;
3050
3051 if (reg->wps->wps_upnp == NULL)
3052 return;
3053
3054 dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
3055 struct subscription, list) {
3056 struct subscr_addr *sa;
3057 sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
3058 if (sa) {
3059 wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
3060 inet_ntoa(sa->saddr.sin_addr),
3061 ntohs(sa->saddr.sin_port));
3062 }
3063 if (s->selected_registrar)
3064 wps_registrar_sel_reg_add(reg, s);
3065 else
3066 wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
3067 "selected");
3068 }
3069 #endif /* CONFIG_WPS_UPNP */
3070 }
3071
3072
3073 /**
3074 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
3075 * @reg: Registrar data from wps_registrar_init()
3076 *
3077 * This function is called when selected registrar state changes, e.g., when an
3078 * AP receives a SetSelectedRegistrar UPnP message.
3079 */
3080 void wps_registrar_selected_registrar_changed(struct wps_registrar *reg)
3081 {
3082 wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
3083
3084 reg->sel_reg_union = reg->selected_registrar;
3085 reg->sel_reg_dev_password_id_override = -1;
3086 reg->sel_reg_config_methods_override = -1;
3087 if (reg->selected_registrar) {
3088 reg->sel_reg_config_methods_override =
3089 reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
3090 if (reg->pbc) {
3091 reg->sel_reg_dev_password_id_override =
3092 DEV_PW_PUSHBUTTON;
3093 reg->sel_reg_config_methods_override |=
3094 WPS_CONFIG_PUSHBUTTON;
3095 }
3096 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
3097 "(pbc=%d)", reg->pbc);
3098 } else
3099 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
3100
3101 wpa_printf(MSG_DEBUG, "WPS: sel_reg_union");
3102
3103 wps_registrar_sel_reg_union(reg);
3104
3105 wpa_printf(MSG_DEBUG, "WPS: set_ie");
3106 wps_set_ie(reg);
3107 wpa_printf(MSG_DEBUG, "WPS: cb_set_sel_reg");
3108 wps_cb_set_sel_reg(reg);
3109 wpa_printf(MSG_DEBUG, "WPS: return from wps_selected_registrar_changed");
3110 }
3111
3112
3113 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
3114 char *buf, size_t buflen)
3115 {
3116 struct wps_registrar_device *d;
3117 int len = 0, ret;
3118 char uuid[40];
3119 char devtype[WPS_DEV_TYPE_BUFSIZE];
3120
3121 d = wps_device_get(reg, addr);
3122 if (d == NULL)
3123 return 0;
3124 if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
3125 return 0;
3126
3127 ret = os_snprintf(buf + len, buflen - len,
3128 "wpsUuid=%s\n"
3129 "wpsPrimaryDeviceType=%s\n"
3130 "wpsDeviceName=%s\n"
3131 "wpsManufacturer=%s\n"
3132 "wpsModelName=%s\n"
3133 "wpsModelNumber=%s\n"
3134 "wpsSerialNumber=%s\n",
3135 uuid,
3136 wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
3137 sizeof(devtype)),
3138 d->dev.device_name ? d->dev.device_name : "",
3139 d->dev.manufacturer ? d->dev.manufacturer : "",
3140 d->dev.model_name ? d->dev.model_name : "",
3141 d->dev.model_number ? d->dev.model_number : "",
3142 d->dev.serial_number ? d->dev.serial_number : "");
3143 if (ret < 0 || (size_t) ret >= buflen - len)
3144 return len;
3145 len += ret;
3146
3147 return len;
3148 }