2 * Wi-Fi Protected Setup - Registrar
3 * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/base64.h"
19 #include "utils/eloop.h"
20 #include "utils/uuid.h"
21 #include "utils/list.h"
22 #include "crypto/crypto.h"
23 #include "crypto/sha256.h"
24 #include "common/ieee802_11_defs.h"
26 #include "wps_dev_attr.h"
28 #include "wps_upnp_i.h"
30 #define WPS_WORKAROUNDS
34 u8 uuid
[WPS_UUID_LEN
];
38 #define PIN_LOCKED BIT(0)
39 #define PIN_EXPIRES BIT(1)
41 struct os_time expiration
;
45 static void wps_free_pin(struct wps_uuid_pin
*pin
)
52 static void wps_remove_pin(struct wps_uuid_pin
*pin
)
54 dl_list_del(&pin
->list
);
59 static void wps_free_pins(struct dl_list
*pins
)
61 struct wps_uuid_pin
*pin
, *prev
;
62 dl_list_for_each_safe(pin
, prev
, pins
, struct wps_uuid_pin
, list
)
67 struct wps_pbc_session
{
68 struct wps_pbc_session
*next
;
70 u8 uuid_e
[WPS_UUID_LEN
];
71 struct os_time timestamp
;
75 static void wps_free_pbc_sessions(struct wps_pbc_session
*pbc
)
77 struct wps_pbc_session
*prev
;
87 struct wps_registrar_device
{
88 struct wps_registrar_device
*next
;
89 struct wps_device_data dev
;
90 u8 uuid
[WPS_UUID_LEN
];
94 struct wps_registrar
{
95 struct wps_context
*wps
;
98 int selected_registrar
;
100 int (*new_psk_cb
)(void *ctx
, const u8
*mac_addr
, const u8
*psk
,
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
,
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
);
117 struct wps_pbc_session
*pbc_sessions
;
120 struct wpabuf
*extra_cred
;
121 int disable_auto_conf
;
123 int sel_reg_dev_password_id_override
;
124 int sel_reg_config_methods_override
;
127 struct wps_registrar_device
*devices
;
129 int force_pbc_overlap
;
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
,
139 static void wps_free_devices(struct wps_registrar_device
*dev
)
141 struct wps_registrar_device
*prev
;
146 wps_device_data_free(&prev
->dev
);
152 static struct wps_registrar_device
* wps_device_get(struct wps_registrar
*reg
,
155 struct wps_registrar_device
*dev
;
157 for (dev
= reg
->devices
; dev
; dev
= dev
->next
) {
158 if (os_memcmp(dev
->dev
.mac_addr
, addr
, ETH_ALEN
) == 0)
165 static void wps_device_clone_data(struct wps_device_data
*dst
,
166 struct wps_device_data
*src
)
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
);
171 #define WPS_STRDUP(n) \
173 dst->n = src->n ? os_strdup(src->n) : NULL
175 WPS_STRDUP(device_name
);
176 WPS_STRDUP(manufacturer
);
177 WPS_STRDUP(model_name
);
178 WPS_STRDUP(model_number
);
179 WPS_STRDUP(serial_number
);
184 int wps_device_store(struct wps_registrar
*reg
,
185 struct wps_device_data
*dev
, const u8
*uuid
)
187 struct wps_registrar_device
*d
;
189 d
= wps_device_get(reg
, dev
->mac_addr
);
191 d
= os_zalloc(sizeof(*d
));
194 d
->next
= reg
->devices
;
198 wps_device_clone_data(&d
->dev
, dev
);
199 os_memcpy(d
->uuid
, uuid
, WPS_UUID_LEN
);
205 static void wps_registrar_add_pbc_session(struct wps_registrar
*reg
,
206 const u8
*addr
, const u8
*uuid_e
)
208 struct wps_pbc_session
*pbc
, *prev
= NULL
;
213 pbc
= reg
->pbc_sessions
;
215 if (os_memcmp(pbc
->addr
, addr
, ETH_ALEN
) == 0 &&
216 os_memcmp(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
) == 0) {
218 prev
->next
= pbc
->next
;
220 reg
->pbc_sessions
= pbc
->next
;
228 pbc
= os_zalloc(sizeof(*pbc
));
231 os_memcpy(pbc
->addr
, addr
, ETH_ALEN
);
233 os_memcpy(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
);
236 pbc
->next
= reg
->pbc_sessions
;
237 reg
->pbc_sessions
= pbc
;
238 pbc
->timestamp
= now
;
240 /* remove entries that have timed out */
245 if (now
.sec
> pbc
->timestamp
.sec
+ WPS_PBC_WALK_TIME
) {
247 wps_free_pbc_sessions(pbc
);
256 static void wps_registrar_remove_pbc_session(struct wps_registrar
*reg
,
257 const u8
*addr
, const u8
*uuid_e
)
259 struct wps_pbc_session
*pbc
, *prev
= NULL
;
261 pbc
= reg
->pbc_sessions
;
263 if (os_memcmp(pbc
->addr
, addr
, ETH_ALEN
) == 0 &&
264 os_memcmp(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
) == 0) {
266 prev
->next
= pbc
->next
;
268 reg
->pbc_sessions
= pbc
->next
;
278 static int wps_registrar_pbc_overlap(struct wps_registrar
*reg
,
279 const u8
*addr
, const u8
*uuid_e
)
282 struct wps_pbc_session
*pbc
;
287 for (pbc
= reg
->pbc_sessions
; pbc
; pbc
= pbc
->next
) {
288 if (now
.sec
> pbc
->timestamp
.sec
+ WPS_PBC_WALK_TIME
)
290 if (addr
== NULL
|| os_memcmp(addr
, pbc
->addr
, ETH_ALEN
) ||
292 os_memcmp(uuid_e
, pbc
->uuid_e
, WPS_UUID_LEN
))
299 return count
> 1 ? 1 : 0;
303 static int wps_build_wps_state(struct wps_context
*wps
, struct wpabuf
*msg
)
305 wpa_printf(MSG_DEBUG
, "WPS: * Wi-Fi Protected Setup State (%d)",
307 wpabuf_put_be16(msg
, ATTR_WPS_STATE
);
308 wpabuf_put_be16(msg
, 1);
309 wpabuf_put_u8(msg
, wps
->wps_state
);
314 #ifdef CONFIG_WPS_UPNP
315 static void wps_registrar_free_pending_m2(struct wps_context
*wps
)
317 struct upnp_pending_message
*p
, *p2
, *prev
= NULL
;
320 if (p
->type
== WPS_M2
|| p
->type
== WPS_M2D
) {
322 wps
->upnp_msgs
= p
->next
;
324 prev
->next
= p
->next
;
325 wpa_printf(MSG_DEBUG
, "WPS UPnP: Drop pending M2/M2D");
328 wpabuf_free(p2
->msg
);
336 #endif /* CONFIG_WPS_UPNP */
339 static int wps_build_ap_setup_locked(struct wps_context
*wps
,
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);
352 static int wps_build_selected_registrar(struct wps_registrar
*reg
,
355 if (!reg
->sel_reg_union
)
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);
365 static int wps_build_sel_reg_dev_password_id(struct wps_registrar
*reg
,
368 u16 id
= reg
->pbc
? DEV_PW_PUSHBUTTON
: DEV_PW_DEFAULT
;
369 if (!reg
->sel_reg_union
)
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
);
381 static int wps_build_sel_reg_config_methods(struct wps_registrar
*reg
,
385 if (!reg
->sel_reg_union
)
387 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
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)",
394 wpabuf_put_be16(msg
, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS
);
395 wpabuf_put_be16(msg
, 2);
396 wpabuf_put_be16(msg
, methods
);
401 static int wps_build_probe_config_methods(struct wps_registrar
*reg
,
406 * These are the methods that the AP supports as an Enrollee for adding
407 * external Registrars.
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
);
418 static int wps_build_config_methods_r(struct wps_registrar
*reg
,
422 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
424 methods
|= WPS_CONFIG_PUSHBUTTON
;
425 return wps_build_config_methods(msg
, methods
);
430 * wps_registrar_init - Initialize WPS Registrar data
431 * @wps: Pointer to longterm WPS context
432 * @cfg: Registrar configuration
433 * Returns: Pointer to allocated Registrar data or %NULL on failure
435 * This function is used to initialize WPS Registrar functionality. It can be
436 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
437 * runs (e.g., when run as an internal Registrar in an AP). Caller is
438 * responsible for freeing the returned data with wps_registrar_deinit() when
439 * Registrar functionality is not needed anymore.
441 struct wps_registrar
*
442 wps_registrar_init(struct wps_context
*wps
,
443 const struct wps_registrar_config
*cfg
)
445 struct wps_registrar
*reg
= os_zalloc(sizeof(*reg
));
449 dl_list_init(®
->pins
);
451 reg
->new_psk_cb
= cfg
->new_psk_cb
;
452 reg
->set_ie_cb
= cfg
->set_ie_cb
;
453 reg
->pin_needed_cb
= cfg
->pin_needed_cb
;
454 reg
->reg_success_cb
= cfg
->reg_success_cb
;
455 reg
->set_sel_reg_cb
= cfg
->set_sel_reg_cb
;
456 reg
->enrollee_seen_cb
= cfg
->enrollee_seen_cb
;
457 reg
->cb_ctx
= cfg
->cb_ctx
;
458 reg
->skip_cred_build
= cfg
->skip_cred_build
;
459 if (cfg
->extra_cred
) {
460 reg
->extra_cred
= wpabuf_alloc_copy(cfg
->extra_cred
,
461 cfg
->extra_cred_len
);
462 if (reg
->extra_cred
== NULL
) {
467 reg
->disable_auto_conf
= cfg
->disable_auto_conf
;
468 reg
->sel_reg_dev_password_id_override
= -1;
469 reg
->sel_reg_config_methods_override
= -1;
470 reg
->static_wep_only
= cfg
->static_wep_only
;
472 if (wps_set_ie(reg
)) {
473 wps_registrar_deinit(reg
);
482 * wps_registrar_deinit - Deinitialize WPS Registrar data
483 * @reg: Registrar data from wps_registrar_init()
485 void wps_registrar_deinit(struct wps_registrar
*reg
)
489 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
490 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
491 wps_free_pins(®
->pins
);
492 wps_free_pbc_sessions(reg
->pbc_sessions
);
493 wpabuf_free(reg
->extra_cred
);
494 wps_free_devices(reg
->devices
);
500 * wps_registrar_add_pin - Configure a new PIN for Registrar
501 * @reg: Registrar data from wps_registrar_init()
502 * @uuid: UUID-E or %NULL for wildcard (any UUID)
503 * @pin: PIN (Device Password)
504 * @pin_len: Length of pin in octets
505 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
506 * Returns: 0 on success, -1 on failure
508 int wps_registrar_add_pin(struct wps_registrar
*reg
, const u8
*uuid
,
509 const u8
*pin
, size_t pin_len
, int timeout
)
511 struct wps_uuid_pin
*p
;
513 p
= os_zalloc(sizeof(*p
));
517 p
->wildcard_uuid
= 1;
519 os_memcpy(p
->uuid
, uuid
, WPS_UUID_LEN
);
520 p
->pin
= os_malloc(pin_len
);
521 if (p
->pin
== NULL
) {
525 os_memcpy(p
->pin
, pin
, pin_len
);
526 p
->pin_len
= pin_len
;
529 p
->flags
|= PIN_EXPIRES
;
530 os_get_time(&p
->expiration
);
531 p
->expiration
.sec
+= timeout
;
534 dl_list_add(®
->pins
, &p
->list
);
536 wpa_printf(MSG_DEBUG
, "WPS: A new PIN configured (timeout=%d)",
538 wpa_hexdump(MSG_DEBUG
, "WPS: UUID", uuid
, WPS_UUID_LEN
);
539 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: PIN", pin
, pin_len
);
540 reg
->selected_registrar
= 1;
542 wps_registrar_selected_registrar_changed(reg
);
543 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
544 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0,
545 wps_registrar_set_selected_timeout
,
552 static void wps_registrar_expire_pins(struct wps_registrar
*reg
)
554 struct wps_uuid_pin
*pin
, *prev
;
558 dl_list_for_each_safe(pin
, prev
, ®
->pins
, struct wps_uuid_pin
, list
)
560 if ((pin
->flags
& PIN_EXPIRES
) &&
561 os_time_before(&pin
->expiration
, &now
)) {
562 wpa_hexdump(MSG_DEBUG
, "WPS: Expired PIN for UUID",
563 pin
->uuid
, WPS_UUID_LEN
);
571 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
572 * @reg: Registrar data from wps_registrar_init()
574 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
576 int wps_registrar_invalidate_pin(struct wps_registrar
*reg
, const u8
*uuid
)
578 struct wps_uuid_pin
*pin
, *prev
;
580 dl_list_for_each_safe(pin
, prev
, ®
->pins
, struct wps_uuid_pin
, list
)
582 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
583 wpa_hexdump(MSG_DEBUG
, "WPS: Invalidated PIN for UUID",
584 pin
->uuid
, WPS_UUID_LEN
);
594 static const u8
* wps_registrar_get_pin(struct wps_registrar
*reg
,
595 const u8
*uuid
, size_t *pin_len
)
597 struct wps_uuid_pin
*pin
, *found
= NULL
;
599 wps_registrar_expire_pins(reg
);
601 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
602 if (!pin
->wildcard_uuid
&&
603 os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
610 /* Check for wildcard UUIDs since none of the UUID-specific
612 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
613 if (pin
->wildcard_uuid
== 1) {
614 wpa_printf(MSG_DEBUG
, "WPS: Found a wildcard "
615 "PIN. Assigned it for this UUID-E");
616 pin
->wildcard_uuid
= 2;
617 os_memcpy(pin
->uuid
, uuid
, WPS_UUID_LEN
);
628 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
629 * that could otherwise avoid PIN invalidations.
631 if (found
->flags
& PIN_LOCKED
) {
632 wpa_printf(MSG_DEBUG
, "WPS: Selected PIN locked - do not "
633 "allow concurrent re-use");
636 *pin_len
= found
->pin_len
;
637 found
->flags
|= PIN_LOCKED
;
643 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
644 * @reg: Registrar data from wps_registrar_init()
646 * Returns: 0 on success, -1 on failure
648 * PINs are locked to enforce only one concurrent use. This function unlocks a
649 * PIN to allow it to be used again. If the specified PIN was configured using
650 * a wildcard UUID, it will be removed instead of allowing multiple uses.
652 int wps_registrar_unlock_pin(struct wps_registrar
*reg
, const u8
*uuid
)
654 struct wps_uuid_pin
*pin
;
656 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
657 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
658 if (pin
->wildcard_uuid
== 2) {
659 wpa_printf(MSG_DEBUG
, "WPS: Invalidating used "
661 return wps_registrar_invalidate_pin(reg
, uuid
);
663 pin
->flags
&= ~PIN_LOCKED
;
672 static void wps_registrar_stop_pbc(struct wps_registrar
*reg
)
674 reg
->selected_registrar
= 0;
676 wps_registrar_selected_registrar_changed(reg
);
680 static void wps_registrar_pbc_timeout(void *eloop_ctx
, void *timeout_ctx
)
682 struct wps_registrar
*reg
= eloop_ctx
;
684 wpa_printf(MSG_DEBUG
, "WPS: PBC timed out - disable PBC mode");
685 wps_pbc_timeout_event(reg
->wps
);
686 wps_registrar_stop_pbc(reg
);
691 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
692 * @reg: Registrar data from wps_registrar_init()
693 * Returns: 0 on success, -1 on failure
695 * This function is called on an AP when a push button is pushed to activate
696 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
697 * or when a PBC registration is completed.
699 int wps_registrar_button_pushed(struct wps_registrar
*reg
)
701 if (wps_registrar_pbc_overlap(reg
, NULL
, NULL
)) {
702 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - do not start PBC "
704 wps_pbc_overlap_event(reg
->wps
);
707 wpa_printf(MSG_DEBUG
, "WPS: Button pushed - PBC mode started");
708 reg
->force_pbc_overlap
= 0;
709 reg
->selected_registrar
= 1;
711 wps_registrar_selected_registrar_changed(reg
);
713 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
714 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0, wps_registrar_pbc_timeout
,
720 static void wps_registrar_pbc_completed(struct wps_registrar
*reg
)
722 wpa_printf(MSG_DEBUG
, "WPS: PBC completed - stopping PBC mode");
723 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
724 wps_registrar_stop_pbc(reg
);
728 static void wps_registrar_pin_completed(struct wps_registrar
*reg
)
730 wpa_printf(MSG_DEBUG
, "WPS: PIN completed using internal Registrar");
731 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
732 reg
->selected_registrar
= 0;
733 wps_registrar_selected_registrar_changed(reg
);
738 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
739 * @reg: Registrar data from wps_registrar_init()
740 * @addr: MAC address of the Probe Request sender
741 * @wps_data: WPS IE contents
743 * This function is called on an AP when a Probe Request with WPS IE is
744 * received. This is used to track PBC mode use and to detect possible overlap
745 * situation with other WPS APs.
747 void wps_registrar_probe_req_rx(struct wps_registrar
*reg
, const u8
*addr
,
748 const struct wpabuf
*wps_data
)
750 struct wps_parse_attr attr
;
752 wpa_hexdump_buf(MSG_MSGDUMP
,
753 "WPS: Probe Request with WPS data received",
756 if (wps_parse_msg(wps_data
, &attr
) < 0)
758 if (!wps_version_supported(attr
.version
)) {
759 wpa_printf(MSG_DEBUG
, "WPS: Unsupported ProbeReq WPS IE "
760 "version 0x%x", attr
.version
? *attr
.version
: 0);
764 if (attr
.config_methods
== NULL
) {
765 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods attribute in "
770 if (attr
.dev_password_id
== NULL
) {
771 wpa_printf(MSG_DEBUG
, "WPS: No Device Password Id attribute "
776 if (reg
->enrollee_seen_cb
&& attr
.uuid_e
&&
777 attr
.primary_dev_type
&& attr
.request_type
) {
778 char *dev_name
= NULL
;
780 dev_name
= os_zalloc(attr
.dev_name_len
+ 1);
782 os_memcpy(dev_name
, attr
.dev_name
,
786 reg
->enrollee_seen_cb(reg
->cb_ctx
, addr
, attr
.uuid_e
,
787 attr
.primary_dev_type
,
788 WPA_GET_BE16(attr
.config_methods
),
789 WPA_GET_BE16(attr
.dev_password_id
),
790 *attr
.request_type
, dev_name
);
794 if (WPA_GET_BE16(attr
.dev_password_id
) != DEV_PW_PUSHBUTTON
)
795 return; /* Not PBC */
797 wpa_printf(MSG_DEBUG
, "WPS: Probe Request for PBC received from "
798 MACSTR
, MAC2STR(addr
));
799 if (attr
.uuid_e
== NULL
) {
800 wpa_printf(MSG_DEBUG
, "WPS: Invalid Probe Request WPS IE: No "
805 wps_registrar_add_pbc_session(reg
, addr
, attr
.uuid_e
);
806 if (wps_registrar_pbc_overlap(reg
, addr
, attr
.uuid_e
)) {
807 wpa_printf(MSG_DEBUG
, "WPS: PBC session overlap detected");
808 reg
->force_pbc_overlap
= 1;
809 wps_pbc_overlap_event(reg
->wps
);
814 static int wps_cb_new_psk(struct wps_registrar
*reg
, const u8
*mac_addr
,
815 const u8
*psk
, size_t psk_len
)
817 if (reg
->new_psk_cb
== NULL
)
820 return reg
->new_psk_cb(reg
->cb_ctx
, mac_addr
, psk
, psk_len
);
824 static void wps_cb_pin_needed(struct wps_registrar
*reg
, const u8
*uuid_e
,
825 const struct wps_device_data
*dev
)
827 if (reg
->pin_needed_cb
== NULL
)
830 reg
->pin_needed_cb(reg
->cb_ctx
, uuid_e
, dev
);
834 static void wps_cb_reg_success(struct wps_registrar
*reg
, const u8
*mac_addr
,
837 if (reg
->reg_success_cb
== NULL
)
840 reg
->reg_success_cb(reg
->cb_ctx
, mac_addr
, uuid_e
);
844 static int wps_cb_set_ie(struct wps_registrar
*reg
, struct wpabuf
*beacon_ie
,
845 struct wpabuf
*probe_resp_ie
)
847 return reg
->set_ie_cb(reg
->cb_ctx
, beacon_ie
, probe_resp_ie
);
851 static void wps_cb_set_sel_reg(struct wps_registrar
*reg
)
854 if (reg
->set_sel_reg_cb
== NULL
)
857 if (reg
->selected_registrar
) {
858 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
860 methods
|= WPS_CONFIG_PUSHBUTTON
;
863 reg
->set_sel_reg_cb(reg
->cb_ctx
, reg
->selected_registrar
,
864 reg
->pbc
? DEV_PW_PUSHBUTTON
: DEV_PW_DEFAULT
,
869 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
870 static struct wpabuf
* wps_ie_encapsulate(struct wpabuf
*data
)
875 ie
= wpabuf_alloc(wpabuf_len(data
) + 100);
881 pos
= wpabuf_head(data
);
882 end
= pos
+ wpabuf_len(data
);
885 size_t frag_len
= end
- pos
;
888 wpabuf_put_u8(ie
, WLAN_EID_VENDOR_SPECIFIC
);
889 wpabuf_put_u8(ie
, 4 + frag_len
);
890 wpabuf_put_be32(ie
, WPS_DEV_OUI_WFA
);
891 wpabuf_put_data(ie
, pos
, frag_len
);
901 static int wps_set_ie(struct wps_registrar
*reg
)
903 struct wpabuf
*beacon
;
904 struct wpabuf
*probe
;
906 if (reg
->set_ie_cb
== NULL
)
909 wpa_printf(MSG_DEBUG
, "WPS: Build Beacon and Probe Response IEs");
911 beacon
= wpabuf_alloc(300);
914 probe
= wpabuf_alloc(400);
920 if (wps_build_version(beacon
) ||
921 wps_build_wps_state(reg
->wps
, beacon
) ||
922 wps_build_ap_setup_locked(reg
->wps
, beacon
) ||
923 wps_build_selected_registrar(reg
, beacon
) ||
924 wps_build_sel_reg_dev_password_id(reg
, beacon
) ||
925 wps_build_sel_reg_config_methods(reg
, beacon
) ||
926 wps_build_version(probe
) ||
927 wps_build_wps_state(reg
->wps
, probe
) ||
928 wps_build_ap_setup_locked(reg
->wps
, probe
) ||
929 wps_build_selected_registrar(reg
, probe
) ||
930 wps_build_sel_reg_dev_password_id(reg
, probe
) ||
931 wps_build_sel_reg_config_methods(reg
, probe
) ||
932 wps_build_resp_type(probe
, reg
->wps
->ap
? WPS_RESP_AP
:
933 WPS_RESP_REGISTRAR
) ||
934 wps_build_uuid_e(probe
, reg
->wps
->uuid
) ||
935 wps_build_device_attrs(®
->wps
->dev
, probe
) ||
936 wps_build_probe_config_methods(reg
, probe
) ||
937 wps_build_rf_bands(®
->wps
->dev
, probe
)) {
943 beacon
= wps_ie_encapsulate(beacon
);
944 probe
= wps_ie_encapsulate(probe
);
946 if (!beacon
|| !probe
) {
952 if (reg
->static_wep_only
) {
954 * Windows XP and Vista clients can get confused about
955 * EAP-Identity/Request when they probe the network with
956 * EAPOL-Start. In such a case, they may assume the network is
957 * using IEEE 802.1X and prompt user for a certificate while
958 * the correct (non-WPS) behavior would be to ask for the
959 * static WEP key. As a workaround, use Microsoft Provisioning
960 * IE to advertise that legacy 802.1X is not supported.
962 const u8 ms_wps
[7] = {
963 WLAN_EID_VENDOR_SPECIFIC
, 5,
964 /* Microsoft Provisioning IE (00:50:f2:5) */
966 0x00 /* no legacy 802.1X or MS WPS */
968 wpa_printf(MSG_DEBUG
, "WPS: Add Microsoft Provisioning IE "
969 "into Beacon/Probe Response frames");
970 wpabuf_put_data(beacon
, ms_wps
, sizeof(ms_wps
));
971 wpabuf_put_data(probe
, ms_wps
, sizeof(ms_wps
));
974 return wps_cb_set_ie(reg
, beacon
, probe
);
978 static int wps_get_dev_password(struct wps_data
*wps
)
983 os_free(wps
->dev_password
);
984 wps
->dev_password
= NULL
;
987 wpa_printf(MSG_DEBUG
, "WPS: Use default PIN for PBC");
988 pin
= (const u8
*) "00000000";
991 pin
= wps_registrar_get_pin(wps
->wps
->registrar
, wps
->uuid_e
,
995 wpa_printf(MSG_DEBUG
, "WPS: No Device Password available for "
997 wps_cb_pin_needed(wps
->wps
->registrar
, wps
->uuid_e
,
1002 wps
->dev_password
= os_malloc(pin_len
);
1003 if (wps
->dev_password
== NULL
)
1005 os_memcpy(wps
->dev_password
, pin
, pin_len
);
1006 wps
->dev_password_len
= pin_len
;
1012 static int wps_build_uuid_r(struct wps_data
*wps
, struct wpabuf
*msg
)
1014 wpa_printf(MSG_DEBUG
, "WPS: * UUID-R");
1015 wpabuf_put_be16(msg
, ATTR_UUID_R
);
1016 wpabuf_put_be16(msg
, WPS_UUID_LEN
);
1017 wpabuf_put_data(msg
, wps
->uuid_r
, WPS_UUID_LEN
);
1022 static int wps_build_r_hash(struct wps_data
*wps
, struct wpabuf
*msg
)
1028 if (os_get_random(wps
->snonce
, 2 * WPS_SECRET_NONCE_LEN
) < 0)
1030 wpa_hexdump(MSG_DEBUG
, "WPS: R-S1", wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1031 wpa_hexdump(MSG_DEBUG
, "WPS: R-S2",
1032 wps
->snonce
+ WPS_SECRET_NONCE_LEN
, WPS_SECRET_NONCE_LEN
);
1034 if (wps
->dh_pubkey_e
== NULL
|| wps
->dh_pubkey_r
== NULL
) {
1035 wpa_printf(MSG_DEBUG
, "WPS: DH public keys not available for "
1036 "R-Hash derivation");
1040 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash1");
1041 wpabuf_put_be16(msg
, ATTR_R_HASH1
);
1042 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1043 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1044 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1045 addr
[0] = wps
->snonce
;
1046 len
[0] = WPS_SECRET_NONCE_LEN
;
1047 addr
[1] = wps
->psk1
;
1048 len
[1] = WPS_PSK_LEN
;
1049 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1050 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1051 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1052 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1053 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1054 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash1", hash
, SHA256_MAC_LEN
);
1056 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash2");
1057 wpabuf_put_be16(msg
, ATTR_R_HASH2
);
1058 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1059 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1060 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1061 addr
[0] = wps
->snonce
+ WPS_SECRET_NONCE_LEN
;
1062 addr
[1] = wps
->psk2
;
1063 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1064 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash2", hash
, SHA256_MAC_LEN
);
1070 static int wps_build_r_snonce1(struct wps_data
*wps
, struct wpabuf
*msg
)
1072 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce1");
1073 wpabuf_put_be16(msg
, ATTR_R_SNONCE1
);
1074 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1075 wpabuf_put_data(msg
, wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1080 static int wps_build_r_snonce2(struct wps_data
*wps
, struct wpabuf
*msg
)
1082 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce2");
1083 wpabuf_put_be16(msg
, ATTR_R_SNONCE2
);
1084 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1085 wpabuf_put_data(msg
, wps
->snonce
+ WPS_SECRET_NONCE_LEN
,
1086 WPS_SECRET_NONCE_LEN
);
1091 static int wps_build_cred_network_idx(struct wpabuf
*msg
,
1092 const struct wps_credential
*cred
)
1094 wpa_printf(MSG_DEBUG
, "WPS: * Network Index");
1095 wpabuf_put_be16(msg
, ATTR_NETWORK_INDEX
);
1096 wpabuf_put_be16(msg
, 1);
1097 wpabuf_put_u8(msg
, 1);
1102 static int wps_build_cred_ssid(struct wpabuf
*msg
,
1103 const struct wps_credential
*cred
)
1105 wpa_printf(MSG_DEBUG
, "WPS: * SSID");
1106 wpabuf_put_be16(msg
, ATTR_SSID
);
1107 wpabuf_put_be16(msg
, cred
->ssid_len
);
1108 wpabuf_put_data(msg
, cred
->ssid
, cred
->ssid_len
);
1113 static int wps_build_cred_auth_type(struct wpabuf
*msg
,
1114 const struct wps_credential
*cred
)
1116 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type (0x%x)",
1118 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE
);
1119 wpabuf_put_be16(msg
, 2);
1120 wpabuf_put_be16(msg
, cred
->auth_type
);
1125 static int wps_build_cred_encr_type(struct wpabuf
*msg
,
1126 const struct wps_credential
*cred
)
1128 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type (0x%x)",
1130 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE
);
1131 wpabuf_put_be16(msg
, 2);
1132 wpabuf_put_be16(msg
, cred
->encr_type
);
1137 static int wps_build_cred_network_key(struct wpabuf
*msg
,
1138 const struct wps_credential
*cred
)
1140 wpa_printf(MSG_DEBUG
, "WPS: * Network Key (len=%d)",
1141 (int) cred
->key_len
);
1142 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
1143 wpabuf_put_be16(msg
, cred
->key_len
);
1144 wpabuf_put_data(msg
, cred
->key
, cred
->key_len
);
1149 static int wps_build_cred_mac_addr(struct wpabuf
*msg
,
1150 const struct wps_credential
*cred
)
1152 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address (" MACSTR
")",
1153 MAC2STR(cred
->mac_addr
));
1154 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
1155 wpabuf_put_be16(msg
, ETH_ALEN
);
1156 wpabuf_put_data(msg
, cred
->mac_addr
, ETH_ALEN
);
1161 static int wps_build_credential(struct wpabuf
*msg
,
1162 const struct wps_credential
*cred
)
1164 if (wps_build_cred_network_idx(msg
, cred
) ||
1165 wps_build_cred_ssid(msg
, cred
) ||
1166 wps_build_cred_auth_type(msg
, cred
) ||
1167 wps_build_cred_encr_type(msg
, cred
) ||
1168 wps_build_cred_network_key(msg
, cred
) ||
1169 wps_build_cred_mac_addr(msg
, cred
))
1175 int wps_build_cred(struct wps_data
*wps
, struct wpabuf
*msg
)
1177 struct wpabuf
*cred
;
1179 if (wps
->wps
->registrar
->skip_cred_build
)
1180 goto skip_cred_build
;
1182 wpa_printf(MSG_DEBUG
, "WPS: * Credential");
1183 if (wps
->use_cred
) {
1184 os_memcpy(&wps
->cred
, wps
->use_cred
, sizeof(wps
->cred
));
1187 os_memset(&wps
->cred
, 0, sizeof(wps
->cred
));
1189 os_memcpy(wps
->cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
1190 wps
->cred
.ssid_len
= wps
->wps
->ssid_len
;
1192 /* Select the best authentication and encryption type */
1193 if (wps
->auth_type
& WPS_AUTH_WPA2PSK
)
1194 wps
->auth_type
= WPS_AUTH_WPA2PSK
;
1195 else if (wps
->auth_type
& WPS_AUTH_WPAPSK
)
1196 wps
->auth_type
= WPS_AUTH_WPAPSK
;
1197 else if (wps
->auth_type
& WPS_AUTH_OPEN
)
1198 wps
->auth_type
= WPS_AUTH_OPEN
;
1199 else if (wps
->auth_type
& WPS_AUTH_SHARED
)
1200 wps
->auth_type
= WPS_AUTH_SHARED
;
1202 wpa_printf(MSG_DEBUG
, "WPS: Unsupported auth_type 0x%x",
1206 wps
->cred
.auth_type
= wps
->auth_type
;
1208 if (wps
->auth_type
== WPS_AUTH_WPA2PSK
||
1209 wps
->auth_type
== WPS_AUTH_WPAPSK
) {
1210 if (wps
->encr_type
& WPS_ENCR_AES
)
1211 wps
->encr_type
= WPS_ENCR_AES
;
1212 else if (wps
->encr_type
& WPS_ENCR_TKIP
)
1213 wps
->encr_type
= WPS_ENCR_TKIP
;
1215 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1216 "type for WPA/WPA2");
1220 if (wps
->encr_type
& WPS_ENCR_WEP
)
1221 wps
->encr_type
= WPS_ENCR_WEP
;
1222 else if (wps
->encr_type
& WPS_ENCR_NONE
)
1223 wps
->encr_type
= WPS_ENCR_NONE
;
1225 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1226 "type for non-WPA/WPA2 mode");
1230 wps
->cred
.encr_type
= wps
->encr_type
;
1232 * Set MAC address in the Credential to be the Enrollee's MAC address
1234 os_memcpy(wps
->cred
.mac_addr
, wps
->mac_addr_e
, ETH_ALEN
);
1236 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->wps
->ap
&&
1237 !wps
->wps
->registrar
->disable_auto_conf
) {
1239 /* Generate a random passphrase */
1240 if (os_get_random(r
, sizeof(r
)) < 0)
1242 os_free(wps
->new_psk
);
1243 wps
->new_psk
= base64_encode(r
, sizeof(r
), &wps
->new_psk_len
);
1244 if (wps
->new_psk
== NULL
)
1246 wps
->new_psk_len
--; /* remove newline */
1247 while (wps
->new_psk_len
&&
1248 wps
->new_psk
[wps
->new_psk_len
- 1] == '=')
1250 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: Generated passphrase",
1251 wps
->new_psk
, wps
->new_psk_len
);
1252 os_memcpy(wps
->cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
1253 wps
->cred
.key_len
= wps
->new_psk_len
;
1254 } else if (wps
->use_psk_key
&& wps
->wps
->psk_set
) {
1256 wpa_printf(MSG_DEBUG
, "WPS: Use PSK format for Network Key");
1257 wpa_snprintf_hex(hex
, sizeof(hex
), wps
->wps
->psk
, 32);
1258 os_memcpy(wps
->cred
.key
, hex
, 32 * 2);
1259 wps
->cred
.key_len
= 32 * 2;
1260 } else if (wps
->wps
->network_key
) {
1261 os_memcpy(wps
->cred
.key
, wps
->wps
->network_key
,
1262 wps
->wps
->network_key_len
);
1263 wps
->cred
.key_len
= wps
->wps
->network_key_len
;
1264 } else if (wps
->auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) {
1266 /* Generate a random per-device PSK */
1267 os_free(wps
->new_psk
);
1268 wps
->new_psk_len
= 32;
1269 wps
->new_psk
= os_malloc(wps
->new_psk_len
);
1270 if (wps
->new_psk
== NULL
)
1272 if (os_get_random(wps
->new_psk
, wps
->new_psk_len
) < 0) {
1273 os_free(wps
->new_psk
);
1274 wps
->new_psk
= NULL
;
1277 wpa_hexdump_key(MSG_DEBUG
, "WPS: Generated per-device PSK",
1278 wps
->new_psk
, wps
->new_psk_len
);
1279 wpa_snprintf_hex(hex
, sizeof(hex
), wps
->new_psk
,
1281 os_memcpy(wps
->cred
.key
, hex
, wps
->new_psk_len
* 2);
1282 wps
->cred
.key_len
= wps
->new_psk_len
* 2;
1286 cred
= wpabuf_alloc(200);
1290 if (wps_build_credential(cred
, &wps
->cred
)) {
1295 wpabuf_put_be16(msg
, ATTR_CRED
);
1296 wpabuf_put_be16(msg
, wpabuf_len(cred
));
1297 wpabuf_put_buf(msg
, cred
);
1301 if (wps
->wps
->registrar
->extra_cred
) {
1302 wpa_printf(MSG_DEBUG
, "WPS: * Credential (pre-configured)");
1303 wpabuf_put_buf(msg
, wps
->wps
->registrar
->extra_cred
);
1310 static int wps_build_ap_settings(struct wps_data
*wps
, struct wpabuf
*msg
)
1312 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings");
1314 if (wps_build_credential(msg
, &wps
->cred
))
1321 static struct wpabuf
* wps_build_m2(struct wps_data
*wps
)
1325 if (os_get_random(wps
->nonce_r
, WPS_NONCE_LEN
) < 0)
1327 wpa_hexdump(MSG_DEBUG
, "WPS: Registrar Nonce",
1328 wps
->nonce_r
, WPS_NONCE_LEN
);
1329 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-R", wps
->uuid_r
, WPS_UUID_LEN
);
1331 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2");
1332 msg
= wpabuf_alloc(1000);
1336 if (wps_build_version(msg
) ||
1337 wps_build_msg_type(msg
, WPS_M2
) ||
1338 wps_build_enrollee_nonce(wps
, msg
) ||
1339 wps_build_registrar_nonce(wps
, msg
) ||
1340 wps_build_uuid_r(wps
, msg
) ||
1341 wps_build_public_key(wps
, msg
) ||
1342 wps_derive_keys(wps
) ||
1343 wps_build_auth_type_flags(wps
, msg
) ||
1344 wps_build_encr_type_flags(wps
, msg
) ||
1345 wps_build_conn_type_flags(wps
, msg
) ||
1346 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1347 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1348 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1349 wps_build_assoc_state(wps
, msg
) ||
1350 wps_build_config_error(msg
, WPS_CFG_NO_ERROR
) ||
1351 wps_build_dev_password_id(msg
, wps
->dev_pw_id
) ||
1352 wps_build_os_version(&wps
->wps
->dev
, msg
) ||
1353 wps_build_authenticator(wps
, msg
)) {
1359 wps
->state
= RECV_M3
;
1364 static struct wpabuf
* wps_build_m2d(struct wps_data
*wps
)
1367 u16 err
= wps
->config_error
;
1369 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2D");
1370 msg
= wpabuf_alloc(1000);
1374 if (wps
->wps
->ap
&& wps
->wps
->ap_setup_locked
&&
1375 err
== WPS_CFG_NO_ERROR
)
1376 err
= WPS_CFG_SETUP_LOCKED
;
1378 if (wps_build_version(msg
) ||
1379 wps_build_msg_type(msg
, WPS_M2D
) ||
1380 wps_build_enrollee_nonce(wps
, msg
) ||
1381 wps_build_registrar_nonce(wps
, msg
) ||
1382 wps_build_uuid_r(wps
, msg
) ||
1383 wps_build_auth_type_flags(wps
, msg
) ||
1384 wps_build_encr_type_flags(wps
, msg
) ||
1385 wps_build_conn_type_flags(wps
, msg
) ||
1386 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1387 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1388 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1389 wps_build_assoc_state(wps
, msg
) ||
1390 wps_build_config_error(msg
, err
) ||
1391 wps_build_os_version(&wps
->wps
->dev
, msg
)) {
1396 wps
->state
= RECV_M2D_ACK
;
1401 static struct wpabuf
* wps_build_m4(struct wps_data
*wps
)
1403 struct wpabuf
*msg
, *plain
;
1405 wpa_printf(MSG_DEBUG
, "WPS: Building Message M4");
1407 wps_derive_psk(wps
, wps
->dev_password
, wps
->dev_password_len
);
1409 plain
= wpabuf_alloc(200);
1413 msg
= wpabuf_alloc(1000);
1419 if (wps_build_version(msg
) ||
1420 wps_build_msg_type(msg
, WPS_M4
) ||
1421 wps_build_enrollee_nonce(wps
, msg
) ||
1422 wps_build_r_hash(wps
, msg
) ||
1423 wps_build_r_snonce1(wps
, plain
) ||
1424 wps_build_key_wrap_auth(wps
, plain
) ||
1425 wps_build_encr_settings(wps
, msg
, plain
) ||
1426 wps_build_authenticator(wps
, msg
)) {
1433 wps
->state
= RECV_M5
;
1438 static struct wpabuf
* wps_build_m6(struct wps_data
*wps
)
1440 struct wpabuf
*msg
, *plain
;
1442 wpa_printf(MSG_DEBUG
, "WPS: Building Message M6");
1444 plain
= wpabuf_alloc(200);
1448 msg
= wpabuf_alloc(1000);
1454 if (wps_build_version(msg
) ||
1455 wps_build_msg_type(msg
, WPS_M6
) ||
1456 wps_build_enrollee_nonce(wps
, msg
) ||
1457 wps_build_r_snonce2(wps
, plain
) ||
1458 wps_build_key_wrap_auth(wps
, plain
) ||
1459 wps_build_encr_settings(wps
, msg
, plain
) ||
1460 wps_build_authenticator(wps
, msg
)) {
1467 wps
->wps_pin_revealed
= 1;
1468 wps
->state
= RECV_M7
;
1473 static struct wpabuf
* wps_build_m8(struct wps_data
*wps
)
1475 struct wpabuf
*msg
, *plain
;
1477 wpa_printf(MSG_DEBUG
, "WPS: Building Message M8");
1479 plain
= wpabuf_alloc(500);
1483 msg
= wpabuf_alloc(1000);
1489 if (wps_build_version(msg
) ||
1490 wps_build_msg_type(msg
, WPS_M8
) ||
1491 wps_build_enrollee_nonce(wps
, msg
) ||
1492 ((wps
->wps
->ap
|| wps
->er
) && wps_build_cred(wps
, plain
)) ||
1493 (!wps
->wps
->ap
&& !wps
->er
&& wps_build_ap_settings(wps
, plain
)) ||
1494 wps_build_key_wrap_auth(wps
, plain
) ||
1495 wps_build_encr_settings(wps
, msg
, plain
) ||
1496 wps_build_authenticator(wps
, msg
)) {
1503 wps
->state
= RECV_DONE
;
1508 static struct wpabuf
* wps_build_wsc_ack(struct wps_data
*wps
)
1512 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_ACK");
1514 msg
= wpabuf_alloc(1000);
1518 if (wps_build_version(msg
) ||
1519 wps_build_msg_type(msg
, WPS_WSC_ACK
) ||
1520 wps_build_enrollee_nonce(wps
, msg
) ||
1521 wps_build_registrar_nonce(wps
, msg
)) {
1530 static struct wpabuf
* wps_build_wsc_nack(struct wps_data
*wps
)
1534 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_NACK");
1536 msg
= wpabuf_alloc(1000);
1540 if (wps_build_version(msg
) ||
1541 wps_build_msg_type(msg
, WPS_WSC_NACK
) ||
1542 wps_build_enrollee_nonce(wps
, msg
) ||
1543 wps_build_registrar_nonce(wps
, msg
) ||
1544 wps_build_config_error(msg
, wps
->config_error
)) {
1553 struct wpabuf
* wps_registrar_get_msg(struct wps_data
*wps
,
1554 enum wsc_op_code
*op_code
)
1558 #ifdef CONFIG_WPS_UPNP
1559 if (!wps
->int_reg
&& wps
->wps
->wps_upnp
) {
1560 struct upnp_pending_message
*p
, *prev
= NULL
;
1561 if (wps
->ext_reg
> 1)
1562 wps_registrar_free_pending_m2(wps
->wps
);
1563 p
= wps
->wps
->upnp_msgs
;
1564 /* TODO: check pending message MAC address */
1565 while (p
&& p
->next
) {
1570 wpa_printf(MSG_DEBUG
, "WPS: Use pending message from "
1575 wps
->wps
->upnp_msgs
= NULL
;
1582 *op_code
= WSC_NACK
;
1589 if (wps
->ext_reg
== 0)
1595 wpa_printf(MSG_DEBUG
, "WPS: Using external Registrar, but no "
1596 "pending message available");
1599 #endif /* CONFIG_WPS_UPNP */
1601 switch (wps
->state
) {
1603 if (wps_get_dev_password(wps
) < 0)
1604 msg
= wps_build_m2d(wps
);
1606 msg
= wps_build_m2(wps
);
1610 msg
= wps_build_m2d(wps
);
1614 msg
= wps_build_m4(wps
);
1618 msg
= wps_build_m6(wps
);
1622 msg
= wps_build_m8(wps
);
1626 msg
= wps_build_wsc_ack(wps
);
1630 msg
= wps_build_wsc_nack(wps
);
1631 *op_code
= WSC_NACK
;
1634 wpa_printf(MSG_DEBUG
, "WPS: Unsupported state %d for building "
1635 "a message", wps
->state
);
1640 if (*op_code
== WSC_MSG
&& msg
) {
1641 /* Save a copy of the last message for Authenticator derivation
1643 wpabuf_free(wps
->last_msg
);
1644 wps
->last_msg
= wpabuf_dup(msg
);
1651 static int wps_process_enrollee_nonce(struct wps_data
*wps
, const u8
*e_nonce
)
1653 if (e_nonce
== NULL
) {
1654 wpa_printf(MSG_DEBUG
, "WPS: No Enrollee Nonce received");
1658 os_memcpy(wps
->nonce_e
, e_nonce
, WPS_NONCE_LEN
);
1659 wpa_hexdump(MSG_DEBUG
, "WPS: Enrollee Nonce",
1660 wps
->nonce_e
, WPS_NONCE_LEN
);
1666 static int wps_process_registrar_nonce(struct wps_data
*wps
, const u8
*r_nonce
)
1668 if (r_nonce
== NULL
) {
1669 wpa_printf(MSG_DEBUG
, "WPS: No Registrar Nonce received");
1673 if (os_memcmp(wps
->nonce_r
, r_nonce
, WPS_NONCE_LEN
) != 0) {
1674 wpa_printf(MSG_DEBUG
, "WPS: Invalid Registrar Nonce received");
1682 static int wps_process_uuid_e(struct wps_data
*wps
, const u8
*uuid_e
)
1684 if (uuid_e
== NULL
) {
1685 wpa_printf(MSG_DEBUG
, "WPS: No UUID-E received");
1689 os_memcpy(wps
->uuid_e
, uuid_e
, WPS_UUID_LEN
);
1690 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-E", wps
->uuid_e
, WPS_UUID_LEN
);
1696 static int wps_process_dev_password_id(struct wps_data
*wps
, const u8
*pw_id
)
1698 if (pw_id
== NULL
) {
1699 wpa_printf(MSG_DEBUG
, "WPS: No Device Password ID received");
1703 wps
->dev_pw_id
= WPA_GET_BE16(pw_id
);
1704 wpa_printf(MSG_DEBUG
, "WPS: Device Password ID %d", wps
->dev_pw_id
);
1710 static int wps_process_e_hash1(struct wps_data
*wps
, const u8
*e_hash1
)
1712 if (e_hash1
== NULL
) {
1713 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash1 received");
1717 os_memcpy(wps
->peer_hash1
, e_hash1
, WPS_HASH_LEN
);
1718 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash1", wps
->peer_hash1
, WPS_HASH_LEN
);
1724 static int wps_process_e_hash2(struct wps_data
*wps
, const u8
*e_hash2
)
1726 if (e_hash2
== NULL
) {
1727 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash2 received");
1731 os_memcpy(wps
->peer_hash2
, e_hash2
, WPS_HASH_LEN
);
1732 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash2", wps
->peer_hash2
, WPS_HASH_LEN
);
1738 static int wps_process_e_snonce1(struct wps_data
*wps
, const u8
*e_snonce1
)
1740 u8 hash
[SHA256_MAC_LEN
];
1744 if (e_snonce1
== NULL
) {
1745 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce1 received");
1749 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce1", e_snonce1
,
1750 WPS_SECRET_NONCE_LEN
);
1752 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1753 addr
[0] = e_snonce1
;
1754 len
[0] = WPS_SECRET_NONCE_LEN
;
1755 addr
[1] = wps
->psk1
;
1756 len
[1] = WPS_PSK_LEN
;
1757 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1758 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1759 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1760 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1761 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1763 if (os_memcmp(wps
->peer_hash1
, hash
, WPS_HASH_LEN
) != 0) {
1764 wpa_printf(MSG_DEBUG
, "WPS: E-Hash1 derived from E-S1 does "
1765 "not match with the pre-committed value");
1766 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1767 wps_pwd_auth_fail_event(wps
->wps
, 0, 1);
1771 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the first "
1772 "half of the device password");
1778 static int wps_process_e_snonce2(struct wps_data
*wps
, const u8
*e_snonce2
)
1780 u8 hash
[SHA256_MAC_LEN
];
1784 if (e_snonce2
== NULL
) {
1785 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce2 received");
1789 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce2", e_snonce2
,
1790 WPS_SECRET_NONCE_LEN
);
1792 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1793 addr
[0] = e_snonce2
;
1794 len
[0] = WPS_SECRET_NONCE_LEN
;
1795 addr
[1] = wps
->psk2
;
1796 len
[1] = WPS_PSK_LEN
;
1797 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1798 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1799 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1800 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1801 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1803 if (os_memcmp(wps
->peer_hash2
, hash
, WPS_HASH_LEN
) != 0) {
1804 wpa_printf(MSG_DEBUG
, "WPS: E-Hash2 derived from E-S2 does "
1805 "not match with the pre-committed value");
1806 wps_registrar_invalidate_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1807 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1808 wps_pwd_auth_fail_event(wps
->wps
, 0, 2);
1812 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the second "
1813 "half of the device password");
1814 wps
->wps_pin_revealed
= 0;
1815 wps_registrar_unlock_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1821 static int wps_process_mac_addr(struct wps_data
*wps
, const u8
*mac_addr
)
1823 if (mac_addr
== NULL
) {
1824 wpa_printf(MSG_DEBUG
, "WPS: No MAC Address received");
1828 wpa_printf(MSG_DEBUG
, "WPS: Enrollee MAC Address " MACSTR
,
1830 os_memcpy(wps
->mac_addr_e
, mac_addr
, ETH_ALEN
);
1831 os_memcpy(wps
->peer_dev
.mac_addr
, mac_addr
, ETH_ALEN
);
1837 static int wps_process_pubkey(struct wps_data
*wps
, const u8
*pk
,
1840 if (pk
== NULL
|| pk_len
== 0) {
1841 wpa_printf(MSG_DEBUG
, "WPS: No Public Key received");
1845 #ifdef CONFIG_WPS_OOB
1846 if (wps
->wps
->oob_conf
.pubkey_hash
!= NULL
) {
1848 u8 hash
[WPS_HASH_LEN
];
1851 sha256_vector(1, addr
, &pk_len
, hash
);
1853 wpabuf_head(wps
->wps
->oob_conf
.pubkey_hash
),
1854 WPS_OOB_PUBKEY_HASH_LEN
) != 0) {
1855 wpa_printf(MSG_ERROR
, "WPS: Public Key hash error");
1859 #endif /* CONFIG_WPS_OOB */
1861 wpabuf_free(wps
->dh_pubkey_e
);
1862 wps
->dh_pubkey_e
= wpabuf_alloc_copy(pk
, pk_len
);
1863 if (wps
->dh_pubkey_e
== NULL
)
1870 static int wps_process_auth_type_flags(struct wps_data
*wps
, const u8
*auth
)
1875 wpa_printf(MSG_DEBUG
, "WPS: No Authentication Type flags "
1880 auth_types
= WPA_GET_BE16(auth
);
1882 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Authentication Type flags 0x%x",
1884 wps
->auth_type
= wps
->wps
->auth_types
& auth_types
;
1885 if (wps
->auth_type
== 0) {
1886 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1887 "authentication types (own 0x%x Enrollee 0x%x)",
1888 wps
->wps
->auth_types
, auth_types
);
1889 #ifdef WPS_WORKAROUNDS
1891 * Some deployed implementations seem to advertise incorrect
1892 * information in this attribute. For example, Linksys WRT350N
1893 * seems to have a byteorder bug that breaks this negotiation.
1894 * In order to interoperate with existing implementations,
1895 * assume that the Enrollee supports everything we do.
1897 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1898 "does not advertise supported authentication types "
1900 wps
->auth_type
= wps
->wps
->auth_types
;
1901 #else /* WPS_WORKAROUNDS */
1903 #endif /* WPS_WORKAROUNDS */
1910 static int wps_process_encr_type_flags(struct wps_data
*wps
, const u8
*encr
)
1915 wpa_printf(MSG_DEBUG
, "WPS: No Encryption Type flags "
1920 encr_types
= WPA_GET_BE16(encr
);
1922 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Encryption Type flags 0x%x",
1924 wps
->encr_type
= wps
->wps
->encr_types
& encr_types
;
1925 if (wps
->encr_type
== 0) {
1926 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1927 "encryption types (own 0x%x Enrollee 0x%x)",
1928 wps
->wps
->encr_types
, encr_types
);
1929 #ifdef WPS_WORKAROUNDS
1931 * Some deployed implementations seem to advertise incorrect
1932 * information in this attribute. For example, Linksys WRT350N
1933 * seems to have a byteorder bug that breaks this negotiation.
1934 * In order to interoperate with existing implementations,
1935 * assume that the Enrollee supports everything we do.
1937 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1938 "does not advertise supported encryption types "
1940 wps
->encr_type
= wps
->wps
->encr_types
;
1941 #else /* WPS_WORKAROUNDS */
1943 #endif /* WPS_WORKAROUNDS */
1950 static int wps_process_conn_type_flags(struct wps_data
*wps
, const u8
*conn
)
1953 wpa_printf(MSG_DEBUG
, "WPS: No Connection Type flags "
1958 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Connection Type flags 0x%x",
1965 static int wps_process_config_methods(struct wps_data
*wps
, const u8
*methods
)
1969 if (methods
== NULL
) {
1970 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods received");
1974 m
= WPA_GET_BE16(methods
);
1976 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Config Methods 0x%x"
1977 "%s%s%s%s%s%s%s%s%s", m
,
1978 m
& WPS_CONFIG_USBA
? " [USBA]" : "",
1979 m
& WPS_CONFIG_ETHERNET
? " [Ethernet]" : "",
1980 m
& WPS_CONFIG_LABEL
? " [Label]" : "",
1981 m
& WPS_CONFIG_DISPLAY
? " [Display]" : "",
1982 m
& WPS_CONFIG_EXT_NFC_TOKEN
? " [Ext NFC Token]" : "",
1983 m
& WPS_CONFIG_INT_NFC_TOKEN
? " [Int NFC Token]" : "",
1984 m
& WPS_CONFIG_NFC_INTERFACE
? " [NFC]" : "",
1985 m
& WPS_CONFIG_PUSHBUTTON
? " [PBC]" : "",
1986 m
& WPS_CONFIG_KEYPAD
? " [Keypad]" : "");
1988 if (!(m
& WPS_CONFIG_DISPLAY
) && !wps
->use_psk_key
) {
1990 * The Enrollee does not have a display so it is unlikely to be
1991 * able to show the passphrase to a user and as such, could
1992 * benefit from receiving PSK to reduce key derivation time.
1994 wpa_printf(MSG_DEBUG
, "WPS: Prefer PSK format key due to "
1995 "Enrollee not supporting display");
1996 wps
->use_psk_key
= 1;
2003 static int wps_process_wps_state(struct wps_data
*wps
, const u8
*state
)
2005 if (state
== NULL
) {
2006 wpa_printf(MSG_DEBUG
, "WPS: No Wi-Fi Protected Setup State "
2011 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2018 static int wps_process_assoc_state(struct wps_data
*wps
, const u8
*assoc
)
2022 if (assoc
== NULL
) {
2023 wpa_printf(MSG_DEBUG
, "WPS: No Association State received");
2027 a
= WPA_GET_BE16(assoc
);
2028 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Association State %d", a
);
2034 static int wps_process_config_error(struct wps_data
*wps
, const u8
*err
)
2039 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error received");
2043 e
= WPA_GET_BE16(err
);
2044 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Configuration Error %d", e
);
2050 static enum wps_process_res
wps_process_m1(struct wps_data
*wps
,
2051 struct wps_parse_attr
*attr
)
2053 wpa_printf(MSG_DEBUG
, "WPS: Received M1");
2055 if (wps
->state
!= RECV_M1
) {
2056 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2057 "receiving M1", wps
->state
);
2061 if (wps_process_uuid_e(wps
, attr
->uuid_e
) ||
2062 wps_process_mac_addr(wps
, attr
->mac_addr
) ||
2063 wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
2064 wps_process_pubkey(wps
, attr
->public_key
, attr
->public_key_len
) ||
2065 wps_process_auth_type_flags(wps
, attr
->auth_type_flags
) ||
2066 wps_process_encr_type_flags(wps
, attr
->encr_type_flags
) ||
2067 wps_process_conn_type_flags(wps
, attr
->conn_type_flags
) ||
2068 wps_process_config_methods(wps
, attr
->config_methods
) ||
2069 wps_process_wps_state(wps
, attr
->wps_state
) ||
2070 wps_process_device_attrs(&wps
->peer_dev
, attr
) ||
2071 wps_process_rf_bands(&wps
->peer_dev
, attr
->rf_bands
) ||
2072 wps_process_assoc_state(wps
, attr
->assoc_state
) ||
2073 wps_process_dev_password_id(wps
, attr
->dev_password_id
) ||
2074 wps_process_config_error(wps
, attr
->config_error
) ||
2075 wps_process_os_version(&wps
->peer_dev
, attr
->os_version
))
2078 if (wps
->dev_pw_id
< 0x10 &&
2079 wps
->dev_pw_id
!= DEV_PW_DEFAULT
&&
2080 wps
->dev_pw_id
!= DEV_PW_USER_SPECIFIED
&&
2081 wps
->dev_pw_id
!= DEV_PW_MACHINE_SPECIFIED
&&
2082 wps
->dev_pw_id
!= DEV_PW_REGISTRAR_SPECIFIED
&&
2083 (wps
->dev_pw_id
!= DEV_PW_PUSHBUTTON
||
2084 !wps
->wps
->registrar
->pbc
)) {
2085 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Device Password ID %d",
2087 wps
->state
= SEND_M2D
;
2088 return WPS_CONTINUE
;
2091 #ifdef CONFIG_WPS_OOB
2092 if (wps
->dev_pw_id
>= 0x10 &&
2093 wps
->dev_pw_id
!= wps
->wps
->oob_dev_pw_id
) {
2094 wpa_printf(MSG_DEBUG
, "WPS: OOB Device Password ID "
2095 "%d mismatch", wps
->dev_pw_id
);
2096 wps
->state
= SEND_M2D
;
2097 return WPS_CONTINUE
;
2099 #endif /* CONFIG_WPS_OOB */
2101 if (wps
->dev_pw_id
== DEV_PW_PUSHBUTTON
) {
2102 if (wps
->wps
->registrar
->force_pbc_overlap
||
2103 wps_registrar_pbc_overlap(wps
->wps
->registrar
,
2104 wps
->mac_addr_e
, wps
->uuid_e
)) {
2105 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - deny PBC "
2107 wps
->state
= SEND_M2D
;
2108 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2109 wps_pbc_overlap_event(wps
->wps
);
2110 wps
->wps
->registrar
->force_pbc_overlap
= 1;
2111 return WPS_CONTINUE
;
2113 wps_registrar_add_pbc_session(wps
->wps
->registrar
,
2114 wps
->mac_addr_e
, wps
->uuid_e
);
2118 #ifdef WPS_WORKAROUNDS
2120 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
2121 * passphrase format. To avoid interop issues, force PSK format to be
2124 if (!wps
->use_psk_key
&&
2125 wps
->peer_dev
.manufacturer
&&
2126 os_strncmp(wps
->peer_dev
.manufacturer
, "Apple ", 6) == 0 &&
2127 wps
->peer_dev
.model_name
&&
2128 os_strcmp(wps
->peer_dev
.model_name
, "AirPort") == 0) {
2129 wpa_printf(MSG_DEBUG
, "WPS: Workaround - Force Network Key in "
2131 wps
->use_psk_key
= 1;
2133 #endif /* WPS_WORKAROUNDS */
2135 wps
->state
= SEND_M2
;
2136 return WPS_CONTINUE
;
2140 static enum wps_process_res
wps_process_m3(struct wps_data
*wps
,
2141 const struct wpabuf
*msg
,
2142 struct wps_parse_attr
*attr
)
2144 wpa_printf(MSG_DEBUG
, "WPS: Received M3");
2146 if (wps
->state
!= RECV_M3
) {
2147 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2148 "receiving M3", wps
->state
);
2149 wps
->state
= SEND_WSC_NACK
;
2150 return WPS_CONTINUE
;
2153 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2154 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2156 wps
->state
= SEND_WSC_NACK
;
2157 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2158 return WPS_CONTINUE
;
2161 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2162 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
2163 wps_process_e_hash1(wps
, attr
->e_hash1
) ||
2164 wps_process_e_hash2(wps
, attr
->e_hash2
)) {
2165 wps
->state
= SEND_WSC_NACK
;
2166 return WPS_CONTINUE
;
2169 wps
->state
= SEND_M4
;
2170 return WPS_CONTINUE
;
2174 static enum wps_process_res
wps_process_m5(struct wps_data
*wps
,
2175 const struct wpabuf
*msg
,
2176 struct wps_parse_attr
*attr
)
2178 struct wpabuf
*decrypted
;
2179 struct wps_parse_attr eattr
;
2181 wpa_printf(MSG_DEBUG
, "WPS: Received M5");
2183 if (wps
->state
!= RECV_M5
) {
2184 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2185 "receiving M5", wps
->state
);
2186 wps
->state
= SEND_WSC_NACK
;
2187 return WPS_CONTINUE
;
2190 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2191 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2193 wps
->state
= SEND_WSC_NACK
;
2194 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2195 return WPS_CONTINUE
;
2198 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2199 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2200 wps
->state
= SEND_WSC_NACK
;
2201 return WPS_CONTINUE
;
2204 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2205 attr
->encr_settings_len
);
2206 if (decrypted
== NULL
) {
2207 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
2208 "Settings attribute");
2209 wps
->state
= SEND_WSC_NACK
;
2210 return WPS_CONTINUE
;
2213 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2215 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2216 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2217 wps_process_e_snonce1(wps
, eattr
.e_snonce1
)) {
2218 wpabuf_free(decrypted
);
2219 wps
->state
= SEND_WSC_NACK
;
2220 return WPS_CONTINUE
;
2222 wpabuf_free(decrypted
);
2224 wps
->state
= SEND_M6
;
2225 return WPS_CONTINUE
;
2229 static void wps_sta_cred_cb(struct wps_data
*wps
)
2232 * Update credential to only include a single authentication and
2233 * encryption type in case the AP configuration includes more than one
2236 if (wps
->cred
.auth_type
& WPS_AUTH_WPA2PSK
)
2237 wps
->cred
.auth_type
= WPS_AUTH_WPA2PSK
;
2238 else if (wps
->cred
.auth_type
& WPS_AUTH_WPAPSK
)
2239 wps
->cred
.auth_type
= WPS_AUTH_WPAPSK
;
2240 if (wps
->cred
.encr_type
& WPS_ENCR_AES
)
2241 wps
->cred
.encr_type
= WPS_ENCR_AES
;
2242 else if (wps
->cred
.encr_type
& WPS_ENCR_TKIP
)
2243 wps
->cred
.encr_type
= WPS_ENCR_TKIP
;
2244 wpa_printf(MSG_DEBUG
, "WPS: Update local configuration based on the "
2245 "AP configuration");
2246 if (wps
->wps
->cred_cb
)
2247 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &wps
->cred
);
2251 static void wps_cred_update(struct wps_credential
*dst
,
2252 struct wps_credential
*src
)
2254 os_memcpy(dst
->ssid
, src
->ssid
, sizeof(dst
->ssid
));
2255 dst
->ssid_len
= src
->ssid_len
;
2256 dst
->auth_type
= src
->auth_type
;
2257 dst
->encr_type
= src
->encr_type
;
2258 dst
->key_idx
= src
->key_idx
;
2259 os_memcpy(dst
->key
, src
->key
, sizeof(dst
->key
));
2260 dst
->key_len
= src
->key_len
;
2264 static int wps_process_ap_settings_r(struct wps_data
*wps
,
2265 struct wps_parse_attr
*attr
)
2267 if (wps
->wps
->ap
|| wps
->er
)
2270 /* AP Settings Attributes in M7 when Enrollee is an AP */
2271 if (wps_process_ap_settings(attr
, &wps
->cred
) < 0)
2274 wpa_printf(MSG_INFO
, "WPS: Received old AP configuration from AP");
2276 if (wps
->new_ap_settings
) {
2277 wpa_printf(MSG_INFO
, "WPS: Update AP configuration based on "
2279 wps_cred_update(&wps
->cred
, wps
->new_ap_settings
);
2283 * Use the AP PIN only to receive the current AP settings, not
2284 * to reconfigure the AP.
2286 if (wps
->ap_settings_cb
) {
2287 wps
->ap_settings_cb(wps
->ap_settings_cb_ctx
,
2291 wps_sta_cred_cb(wps
);
2297 static enum wps_process_res
wps_process_m7(struct wps_data
*wps
,
2298 const struct wpabuf
*msg
,
2299 struct wps_parse_attr
*attr
)
2301 struct wpabuf
*decrypted
;
2302 struct wps_parse_attr eattr
;
2304 wpa_printf(MSG_DEBUG
, "WPS: Received M7");
2306 if (wps
->state
!= RECV_M7
) {
2307 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2308 "receiving M7", wps
->state
);
2309 wps
->state
= SEND_WSC_NACK
;
2310 return WPS_CONTINUE
;
2313 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2314 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2316 wps
->state
= SEND_WSC_NACK
;
2317 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2318 return WPS_CONTINUE
;
2321 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2322 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2323 wps
->state
= SEND_WSC_NACK
;
2324 return WPS_CONTINUE
;
2327 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2328 attr
->encr_settings_len
);
2329 if (decrypted
== NULL
) {
2330 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypt Encrypted "
2331 "Settings attribute");
2332 wps
->state
= SEND_WSC_NACK
;
2333 return WPS_CONTINUE
;
2336 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2338 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2339 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2340 wps_process_e_snonce2(wps
, eattr
.e_snonce2
) ||
2341 wps_process_ap_settings_r(wps
, &eattr
)) {
2342 wpabuf_free(decrypted
);
2343 wps
->state
= SEND_WSC_NACK
;
2344 return WPS_CONTINUE
;
2347 wpabuf_free(decrypted
);
2349 wps
->state
= SEND_M8
;
2350 return WPS_CONTINUE
;
2354 static enum wps_process_res
wps_process_wsc_msg(struct wps_data
*wps
,
2355 const struct wpabuf
*msg
)
2357 struct wps_parse_attr attr
;
2358 enum wps_process_res ret
= WPS_CONTINUE
;
2360 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_MSG");
2362 if (wps_parse_msg(msg
, &attr
) < 0)
2365 if (!wps_version_supported(attr
.version
)) {
2366 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2367 attr
.version
? *attr
.version
: 0);
2371 if (attr
.msg_type
== NULL
) {
2372 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2376 if (*attr
.msg_type
!= WPS_M1
&&
2377 (attr
.registrar_nonce
== NULL
||
2378 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
,
2379 WPS_NONCE_LEN
!= 0))) {
2380 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2384 switch (*attr
.msg_type
) {
2386 #ifdef CONFIG_WPS_UPNP
2387 if (wps
->wps
->wps_upnp
&& attr
.mac_addr
) {
2388 /* Remove old pending messages when starting new run */
2389 wps_free_pending_msgs(wps
->wps
->upnp_msgs
);
2390 wps
->wps
->upnp_msgs
= NULL
;
2392 upnp_wps_device_send_wlan_event(
2393 wps
->wps
->wps_upnp
, attr
.mac_addr
,
2394 UPNP_WPS_WLANEVENT_TYPE_EAP
, msg
);
2396 #endif /* CONFIG_WPS_UPNP */
2397 ret
= wps_process_m1(wps
, &attr
);
2400 ret
= wps_process_m3(wps
, msg
, &attr
);
2401 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2402 wps_fail_event(wps
->wps
, WPS_M3
);
2405 ret
= wps_process_m5(wps
, msg
, &attr
);
2406 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2407 wps_fail_event(wps
->wps
, WPS_M5
);
2410 ret
= wps_process_m7(wps
, msg
, &attr
);
2411 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2412 wps_fail_event(wps
->wps
, WPS_M7
);
2415 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Message Type %d",
2420 if (ret
== WPS_CONTINUE
) {
2421 /* Save a copy of the last message for Authenticator derivation
2423 wpabuf_free(wps
->last_msg
);
2424 wps
->last_msg
= wpabuf_dup(msg
);
2431 static enum wps_process_res
wps_process_wsc_ack(struct wps_data
*wps
,
2432 const struct wpabuf
*msg
)
2434 struct wps_parse_attr attr
;
2436 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_ACK");
2438 if (wps_parse_msg(msg
, &attr
) < 0)
2441 if (!wps_version_supported(attr
.version
)) {
2442 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2443 attr
.version
? *attr
.version
: 0);
2447 if (attr
.msg_type
== NULL
) {
2448 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2452 if (*attr
.msg_type
!= WPS_WSC_ACK
) {
2453 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2458 #ifdef CONFIG_WPS_UPNP
2459 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& wps
->state
== RECV_M2D_ACK
&&
2460 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2461 if (wps
->wps
->upnp_msgs
)
2462 return WPS_CONTINUE
;
2463 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2464 "external Registrar");
2467 #endif /* CONFIG_WPS_UPNP */
2469 if (attr
.registrar_nonce
== NULL
||
2470 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2472 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2476 if (attr
.enrollee_nonce
== NULL
||
2477 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2478 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2482 if (wps
->state
== RECV_M2D_ACK
) {
2483 #ifdef CONFIG_WPS_UPNP
2484 if (wps
->wps
->wps_upnp
&&
2485 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2486 if (wps
->wps
->upnp_msgs
)
2487 return WPS_CONTINUE
;
2488 if (wps
->ext_reg
== 0)
2490 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2491 "external Registrar");
2494 #endif /* CONFIG_WPS_UPNP */
2496 wpa_printf(MSG_DEBUG
, "WPS: No more registrars available - "
2497 "terminate negotiation");
2504 static enum wps_process_res
wps_process_wsc_nack(struct wps_data
*wps
,
2505 const struct wpabuf
*msg
)
2507 struct wps_parse_attr attr
;
2510 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_NACK");
2512 old_state
= wps
->state
;
2513 wps
->state
= SEND_WSC_NACK
;
2515 if (wps_parse_msg(msg
, &attr
) < 0)
2518 if (!wps_version_supported(attr
.version
)) {
2519 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2520 attr
.version
? *attr
.version
: 0);
2524 if (attr
.msg_type
== NULL
) {
2525 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2529 if (*attr
.msg_type
!= WPS_WSC_NACK
) {
2530 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2535 #ifdef CONFIG_WPS_UPNP
2536 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2537 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2538 "Registrar terminated by the Enrollee");
2541 #endif /* CONFIG_WPS_UPNP */
2543 if (attr
.registrar_nonce
== NULL
||
2544 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2546 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2550 if (attr
.enrollee_nonce
== NULL
||
2551 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2552 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2556 if (attr
.config_error
== NULL
) {
2557 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error attribute "
2562 wpa_printf(MSG_DEBUG
, "WPS: Enrollee terminated negotiation with "
2563 "Configuration Error %d", WPA_GET_BE16(attr
.config_error
));
2565 switch (old_state
) {
2567 wps_fail_event(wps
->wps
, WPS_M2
);
2570 wps_fail_event(wps
->wps
, WPS_M4
);
2573 wps_fail_event(wps
->wps
, WPS_M6
);
2576 wps_fail_event(wps
->wps
, WPS_M8
);
2586 static enum wps_process_res
wps_process_wsc_done(struct wps_data
*wps
,
2587 const struct wpabuf
*msg
)
2589 struct wps_parse_attr attr
;
2591 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_Done");
2593 if (wps
->state
!= RECV_DONE
&&
2594 (!wps
->wps
->wps_upnp
|| !wps
->ext_reg
)) {
2595 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2596 "receiving WSC_Done", wps
->state
);
2600 if (wps_parse_msg(msg
, &attr
) < 0)
2603 if (!wps_version_supported(attr
.version
)) {
2604 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2605 attr
.version
? *attr
.version
: 0);
2609 if (attr
.msg_type
== NULL
) {
2610 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2614 if (*attr
.msg_type
!= WPS_WSC_DONE
) {
2615 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2620 #ifdef CONFIG_WPS_UPNP
2621 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2622 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2623 "Registrar completed successfully");
2624 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2628 #endif /* CONFIG_WPS_UPNP */
2630 if (attr
.registrar_nonce
== NULL
||
2631 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2633 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2637 if (attr
.enrollee_nonce
== NULL
||
2638 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2639 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2643 wpa_printf(MSG_DEBUG
, "WPS: Negotiation completed successfully");
2644 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2647 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->new_psk
&&
2648 wps
->wps
->ap
&& !wps
->wps
->registrar
->disable_auto_conf
) {
2649 struct wps_credential cred
;
2651 wpa_printf(MSG_DEBUG
, "WPS: Moving to Configured state based "
2652 "on first Enrollee connection");
2654 os_memset(&cred
, 0, sizeof(cred
));
2655 os_memcpy(cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
2656 cred
.ssid_len
= wps
->wps
->ssid_len
;
2657 cred
.auth_type
= WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
;
2658 cred
.encr_type
= WPS_ENCR_TKIP
| WPS_ENCR_AES
;
2659 os_memcpy(cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
2660 cred
.key_len
= wps
->new_psk_len
;
2662 wps
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
2663 wpa_hexdump_ascii_key(MSG_DEBUG
,
2664 "WPS: Generated random passphrase",
2665 wps
->new_psk
, wps
->new_psk_len
);
2666 if (wps
->wps
->cred_cb
)
2667 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &cred
);
2669 os_free(wps
->new_psk
);
2670 wps
->new_psk
= NULL
;
2673 if (!wps
->wps
->ap
&& !wps
->er
)
2674 wps_sta_cred_cb(wps
);
2677 if (wps_cb_new_psk(wps
->wps
->registrar
, wps
->mac_addr_e
,
2678 wps
->new_psk
, wps
->new_psk_len
)) {
2679 wpa_printf(MSG_DEBUG
, "WPS: Failed to configure the "
2682 os_free(wps
->new_psk
);
2683 wps
->new_psk
= NULL
;
2686 wps_cb_reg_success(wps
->wps
->registrar
, wps
->mac_addr_e
, wps
->uuid_e
);
2689 wps_registrar_remove_pbc_session(wps
->wps
->registrar
,
2690 wps
->mac_addr_e
, wps
->uuid_e
);
2691 wps_registrar_pbc_completed(wps
->wps
->registrar
);
2693 wps_registrar_pin_completed(wps
->wps
->registrar
);
2696 wps_success_event(wps
->wps
);
2702 enum wps_process_res
wps_registrar_process_msg(struct wps_data
*wps
,
2703 enum wsc_op_code op_code
,
2704 const struct wpabuf
*msg
)
2706 enum wps_process_res ret
;
2708 wpa_printf(MSG_DEBUG
, "WPS: Processing received message (len=%lu "
2710 (unsigned long) wpabuf_len(msg
), op_code
);
2712 #ifdef CONFIG_WPS_UPNP
2713 if (wps
->wps
->wps_upnp
&& op_code
== WSC_MSG
&& wps
->ext_reg
== 1) {
2714 struct wps_parse_attr attr
;
2715 if (wps_parse_msg(msg
, &attr
) == 0 && attr
.msg_type
&&
2716 *attr
.msg_type
== WPS_M3
)
2717 wps
->ext_reg
= 2; /* past M2/M2D phase */
2719 if (wps
->ext_reg
> 1)
2720 wps_registrar_free_pending_m2(wps
->wps
);
2721 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&&
2722 wps
->wps
->upnp_msgs
== NULL
&&
2723 (op_code
== WSC_MSG
|| op_code
== WSC_Done
|| op_code
== WSC_NACK
))
2725 struct wps_parse_attr attr
;
2727 if (wps_parse_msg(msg
, &attr
) < 0 || attr
.msg_type
== NULL
)
2730 type
= *attr
.msg_type
;
2731 wpa_printf(MSG_DEBUG
, "WPS: Sending received message (type %d)"
2732 " to external Registrar for processing", type
);
2733 upnp_wps_device_send_wlan_event(wps
->wps
->wps_upnp
,
2735 UPNP_WPS_WLANEVENT_TYPE_EAP
,
2737 if (op_code
== WSC_MSG
)
2739 } else if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& op_code
== WSC_MSG
) {
2740 wpa_printf(MSG_DEBUG
, "WPS: Skip internal processing - using "
2741 "external Registrar");
2742 return WPS_CONTINUE
;
2744 #endif /* CONFIG_WPS_UPNP */
2748 return wps_process_wsc_msg(wps
, msg
);
2750 return wps_process_wsc_ack(wps
, msg
);
2752 return wps_process_wsc_nack(wps
, msg
);
2754 ret
= wps_process_wsc_done(wps
, msg
);
2755 if (ret
== WPS_FAILURE
) {
2756 wps
->state
= SEND_WSC_NACK
;
2757 wps_fail_event(wps
->wps
, WPS_WSC_DONE
);
2761 wpa_printf(MSG_DEBUG
, "WPS: Unsupported op_code %d", op_code
);
2767 int wps_registrar_update_ie(struct wps_registrar
*reg
)
2769 return wps_set_ie(reg
);
2773 static void wps_registrar_set_selected_timeout(void *eloop_ctx
,
2776 struct wps_registrar
*reg
= eloop_ctx
;
2778 wpa_printf(MSG_DEBUG
, "WPS: Selected Registrar timeout - "
2779 "unselect internal Registrar");
2780 reg
->selected_registrar
= 0;
2782 wps_registrar_selected_registrar_changed(reg
);
2786 #ifdef CONFIG_WPS_UPNP
2787 static void wps_registrar_sel_reg_add(struct wps_registrar
*reg
,
2788 struct subscription
*s
)
2790 wpa_printf(MSG_DEBUG
, "WPS: External Registrar selected (dev_pw_id=%d "
2791 "config_methods=0x%x)",
2792 s
->dev_password_id
, s
->config_methods
);
2793 reg
->sel_reg_union
= 1;
2794 if (reg
->sel_reg_dev_password_id_override
!= DEV_PW_PUSHBUTTON
)
2795 reg
->sel_reg_dev_password_id_override
= s
->dev_password_id
;
2796 if (reg
->sel_reg_config_methods_override
== -1)
2797 reg
->sel_reg_config_methods_override
= 0;
2798 reg
->sel_reg_config_methods_override
|= s
->config_methods
;
2800 #endif /* CONFIG_WPS_UPNP */
2803 static void wps_registrar_sel_reg_union(struct wps_registrar
*reg
)
2805 #ifdef CONFIG_WPS_UPNP
2806 struct subscription
*s
;
2808 if (reg
->wps
->wps_upnp
== NULL
)
2811 dl_list_for_each(s
, ®
->wps
->wps_upnp
->subscriptions
,
2812 struct subscription
, list
) {
2813 struct subscr_addr
*sa
;
2814 sa
= dl_list_first(&s
->addr_list
, struct subscr_addr
, list
);
2816 wpa_printf(MSG_DEBUG
, "WPS: External Registrar %s:%d",
2817 inet_ntoa(sa
->saddr
.sin_addr
),
2818 ntohs(sa
->saddr
.sin_port
));
2820 if (s
->selected_registrar
)
2821 wps_registrar_sel_reg_add(reg
, s
);
2823 wpa_printf(MSG_DEBUG
, "WPS: External Registrar not "
2826 #endif /* CONFIG_WPS_UPNP */
2831 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
2832 * @reg: Registrar data from wps_registrar_init()
2834 * This function is called when selected registrar state changes, e.g., when an
2835 * AP receives a SetSelectedRegistrar UPnP message.
2837 void wps_registrar_selected_registrar_changed(struct wps_registrar
*reg
)
2839 wpa_printf(MSG_DEBUG
, "WPS: Selected registrar information changed");
2841 reg
->sel_reg_union
= reg
->selected_registrar
;
2842 reg
->sel_reg_dev_password_id_override
= -1;
2843 reg
->sel_reg_config_methods_override
= -1;
2844 if (reg
->selected_registrar
) {
2845 reg
->sel_reg_config_methods_override
=
2846 reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
2848 reg
->sel_reg_dev_password_id_override
=
2850 reg
->sel_reg_config_methods_override
|=
2851 WPS_CONFIG_PUSHBUTTON
;
2853 wpa_printf(MSG_DEBUG
, "WPS: Internal Registrar selected "
2854 "(pbc=%d)", reg
->pbc
);
2856 wpa_printf(MSG_DEBUG
, "WPS: Internal Registrar not selected");
2858 wps_registrar_sel_reg_union(reg
);
2861 wps_cb_set_sel_reg(reg
);
2865 int wps_registrar_get_info(struct wps_registrar
*reg
, const u8
*addr
,
2866 char *buf
, size_t buflen
)
2868 struct wps_registrar_device
*d
;
2871 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
2873 d
= wps_device_get(reg
, addr
);
2876 if (uuid_bin2str(d
->uuid
, uuid
, sizeof(uuid
)))
2879 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2881 "wpsPrimaryDeviceType=%s\n"
2882 "wpsDeviceName=%s\n"
2883 "wpsManufacturer=%s\n"
2885 "wpsModelNumber=%s\n"
2886 "wpsSerialNumber=%s\n",
2888 wps_dev_type_bin2str(d
->dev
.pri_dev_type
, devtype
,
2890 d
->dev
.device_name
? d
->dev
.device_name
: "",
2891 d
->dev
.manufacturer
? d
->dev
.manufacturer
: "",
2892 d
->dev
.model_name
? d
->dev
.model_name
: "",
2893 d
->dev
.model_number
? d
->dev
.model_number
: "",
2894 d
->dev
.serial_number
? d
->dev
.serial_number
: "");
2895 if (ret
< 0 || (size_t) ret
>= buflen
- len
)