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 wpa_printf(MSG_DEBUG
, "WPS: * Config Methods (%x)", methods
);
407 wpabuf_put_be16(msg
, ATTR_CONFIG_METHODS
);
408 wpabuf_put_be16(msg
, 2);
409 wpabuf_put_be16(msg
, methods
);
414 static int wps_build_config_methods_r(struct wps_registrar
*reg
,
418 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
420 methods
|= WPS_CONFIG_PUSHBUTTON
;
421 return wps_build_config_methods(msg
, methods
);
425 static int wps_build_resp_type(struct wps_registrar
*reg
, struct wpabuf
*msg
)
427 u8 resp
= reg
->wps
->ap
? WPS_RESP_AP
: WPS_RESP_REGISTRAR
;
428 wpa_printf(MSG_DEBUG
, "WPS: * Response Type (%d)", resp
);
429 wpabuf_put_be16(msg
, ATTR_RESPONSE_TYPE
);
430 wpabuf_put_be16(msg
, 1);
431 wpabuf_put_u8(msg
, resp
);
437 * wps_registrar_init - Initialize WPS Registrar data
438 * @wps: Pointer to longterm WPS context
439 * @cfg: Registrar configuration
440 * Returns: Pointer to allocated Registrar data or %NULL on failure
442 * This function is used to initialize WPS Registrar functionality. It can be
443 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
444 * runs (e.g., when run as an internal Registrar in an AP). Caller is
445 * responsible for freeing the returned data with wps_registrar_deinit() when
446 * Registrar functionality is not needed anymore.
448 struct wps_registrar
*
449 wps_registrar_init(struct wps_context
*wps
,
450 const struct wps_registrar_config
*cfg
)
452 struct wps_registrar
*reg
= os_zalloc(sizeof(*reg
));
456 dl_list_init(®
->pins
);
458 reg
->new_psk_cb
= cfg
->new_psk_cb
;
459 reg
->set_ie_cb
= cfg
->set_ie_cb
;
460 reg
->pin_needed_cb
= cfg
->pin_needed_cb
;
461 reg
->reg_success_cb
= cfg
->reg_success_cb
;
462 reg
->set_sel_reg_cb
= cfg
->set_sel_reg_cb
;
463 reg
->enrollee_seen_cb
= cfg
->enrollee_seen_cb
;
464 reg
->cb_ctx
= cfg
->cb_ctx
;
465 reg
->skip_cred_build
= cfg
->skip_cred_build
;
466 if (cfg
->extra_cred
) {
467 reg
->extra_cred
= wpabuf_alloc_copy(cfg
->extra_cred
,
468 cfg
->extra_cred_len
);
469 if (reg
->extra_cred
== NULL
) {
474 reg
->disable_auto_conf
= cfg
->disable_auto_conf
;
475 reg
->sel_reg_dev_password_id_override
= -1;
476 reg
->sel_reg_config_methods_override
= -1;
477 reg
->static_wep_only
= cfg
->static_wep_only
;
479 if (wps_set_ie(reg
)) {
480 wps_registrar_deinit(reg
);
489 * wps_registrar_deinit - Deinitialize WPS Registrar data
490 * @reg: Registrar data from wps_registrar_init()
492 void wps_registrar_deinit(struct wps_registrar
*reg
)
496 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
497 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
498 wps_free_pins(®
->pins
);
499 wps_free_pbc_sessions(reg
->pbc_sessions
);
500 wpabuf_free(reg
->extra_cred
);
501 wps_free_devices(reg
->devices
);
507 * wps_registrar_add_pin - Configure a new PIN for Registrar
508 * @reg: Registrar data from wps_registrar_init()
509 * @uuid: UUID-E or %NULL for wildcard (any UUID)
510 * @pin: PIN (Device Password)
511 * @pin_len: Length of pin in octets
512 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
513 * Returns: 0 on success, -1 on failure
515 int wps_registrar_add_pin(struct wps_registrar
*reg
, const u8
*uuid
,
516 const u8
*pin
, size_t pin_len
, int timeout
)
518 struct wps_uuid_pin
*p
;
520 p
= os_zalloc(sizeof(*p
));
524 p
->wildcard_uuid
= 1;
526 os_memcpy(p
->uuid
, uuid
, WPS_UUID_LEN
);
527 p
->pin
= os_malloc(pin_len
);
528 if (p
->pin
== NULL
) {
532 os_memcpy(p
->pin
, pin
, pin_len
);
533 p
->pin_len
= pin_len
;
536 p
->flags
|= PIN_EXPIRES
;
537 os_get_time(&p
->expiration
);
538 p
->expiration
.sec
+= timeout
;
541 dl_list_add(®
->pins
, &p
->list
);
543 wpa_printf(MSG_DEBUG
, "WPS: A new PIN configured (timeout=%d)",
545 wpa_hexdump(MSG_DEBUG
, "WPS: UUID", uuid
, WPS_UUID_LEN
);
546 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: PIN", pin
, pin_len
);
547 reg
->selected_registrar
= 1;
549 wps_registrar_selected_registrar_changed(reg
);
550 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
551 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0,
552 wps_registrar_set_selected_timeout
,
559 static void wps_registrar_expire_pins(struct wps_registrar
*reg
)
561 struct wps_uuid_pin
*pin
, *prev
;
565 dl_list_for_each_safe(pin
, prev
, ®
->pins
, struct wps_uuid_pin
, list
)
567 if ((pin
->flags
& PIN_EXPIRES
) &&
568 os_time_before(&pin
->expiration
, &now
)) {
569 wpa_hexdump(MSG_DEBUG
, "WPS: Expired PIN for UUID",
570 pin
->uuid
, WPS_UUID_LEN
);
578 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
579 * @reg: Registrar data from wps_registrar_init()
581 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
583 int wps_registrar_invalidate_pin(struct wps_registrar
*reg
, const u8
*uuid
)
585 struct wps_uuid_pin
*pin
, *prev
;
587 dl_list_for_each_safe(pin
, prev
, ®
->pins
, struct wps_uuid_pin
, list
)
589 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
590 wpa_hexdump(MSG_DEBUG
, "WPS: Invalidated PIN for UUID",
591 pin
->uuid
, WPS_UUID_LEN
);
601 static const u8
* wps_registrar_get_pin(struct wps_registrar
*reg
,
602 const u8
*uuid
, size_t *pin_len
)
604 struct wps_uuid_pin
*pin
, *found
= NULL
;
606 wps_registrar_expire_pins(reg
);
608 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
609 if (!pin
->wildcard_uuid
&&
610 os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
617 /* Check for wildcard UUIDs since none of the UUID-specific
619 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
620 if (pin
->wildcard_uuid
== 1) {
621 wpa_printf(MSG_DEBUG
, "WPS: Found a wildcard "
622 "PIN. Assigned it for this UUID-E");
623 pin
->wildcard_uuid
= 2;
624 os_memcpy(pin
->uuid
, uuid
, WPS_UUID_LEN
);
635 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
636 * that could otherwise avoid PIN invalidations.
638 if (found
->flags
& PIN_LOCKED
) {
639 wpa_printf(MSG_DEBUG
, "WPS: Selected PIN locked - do not "
640 "allow concurrent re-use");
643 *pin_len
= found
->pin_len
;
644 found
->flags
|= PIN_LOCKED
;
650 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
651 * @reg: Registrar data from wps_registrar_init()
653 * Returns: 0 on success, -1 on failure
655 * PINs are locked to enforce only one concurrent use. This function unlocks a
656 * PIN to allow it to be used again. If the specified PIN was configured using
657 * a wildcard UUID, it will be removed instead of allowing multiple uses.
659 int wps_registrar_unlock_pin(struct wps_registrar
*reg
, const u8
*uuid
)
661 struct wps_uuid_pin
*pin
;
663 dl_list_for_each(pin
, ®
->pins
, struct wps_uuid_pin
, list
) {
664 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
665 if (pin
->wildcard_uuid
== 2) {
666 wpa_printf(MSG_DEBUG
, "WPS: Invalidating used "
668 return wps_registrar_invalidate_pin(reg
, uuid
);
670 pin
->flags
&= ~PIN_LOCKED
;
679 static void wps_registrar_stop_pbc(struct wps_registrar
*reg
)
681 reg
->selected_registrar
= 0;
683 wps_registrar_selected_registrar_changed(reg
);
687 static void wps_registrar_pbc_timeout(void *eloop_ctx
, void *timeout_ctx
)
689 struct wps_registrar
*reg
= eloop_ctx
;
691 wpa_printf(MSG_DEBUG
, "WPS: PBC timed out - disable PBC mode");
692 wps_pbc_timeout_event(reg
->wps
);
693 wps_registrar_stop_pbc(reg
);
698 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
699 * @reg: Registrar data from wps_registrar_init()
700 * Returns: 0 on success, -1 on failure
702 * This function is called on an AP when a push button is pushed to activate
703 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
704 * or when a PBC registration is completed.
706 int wps_registrar_button_pushed(struct wps_registrar
*reg
)
708 if (wps_registrar_pbc_overlap(reg
, NULL
, NULL
)) {
709 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - do not start PBC "
711 wps_pbc_overlap_event(reg
->wps
);
714 wpa_printf(MSG_DEBUG
, "WPS: Button pushed - PBC mode started");
715 reg
->force_pbc_overlap
= 0;
716 reg
->selected_registrar
= 1;
718 wps_registrar_selected_registrar_changed(reg
);
720 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
721 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0, wps_registrar_pbc_timeout
,
727 static void wps_registrar_pbc_completed(struct wps_registrar
*reg
)
729 wpa_printf(MSG_DEBUG
, "WPS: PBC completed - stopping PBC mode");
730 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
731 wps_registrar_stop_pbc(reg
);
735 static void wps_registrar_pin_completed(struct wps_registrar
*reg
)
737 wpa_printf(MSG_DEBUG
, "WPS: PIN completed using internal Registrar");
738 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
739 reg
->selected_registrar
= 0;
740 wps_registrar_selected_registrar_changed(reg
);
745 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
746 * @reg: Registrar data from wps_registrar_init()
747 * @addr: MAC address of the Probe Request sender
748 * @wps_data: WPS IE contents
750 * This function is called on an AP when a Probe Request with WPS IE is
751 * received. This is used to track PBC mode use and to detect possible overlap
752 * situation with other WPS APs.
754 void wps_registrar_probe_req_rx(struct wps_registrar
*reg
, const u8
*addr
,
755 const struct wpabuf
*wps_data
)
757 struct wps_parse_attr attr
;
760 wpa_hexdump_buf(MSG_MSGDUMP
,
761 "WPS: Probe Request with WPS data received",
764 if (wps_parse_msg(wps_data
, &attr
) < 0)
766 if (!wps_version_supported(attr
.version
)) {
767 wpa_printf(MSG_DEBUG
, "WPS: Unsupported ProbeReq WPS IE "
768 "version 0x%x", attr
.version
? *attr
.version
: 0);
772 if (attr
.config_methods
== NULL
) {
773 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods attribute in "
778 if (reg
->enrollee_seen_cb
&& attr
.dev_password_id
&& attr
.uuid_e
&&
779 attr
.primary_dev_type
&& attr
.request_type
) {
780 char *dev_name
= NULL
;
782 dev_name
= os_zalloc(attr
.dev_name_len
+ 1);
784 os_memcpy(dev_name
, attr
.dev_name
,
788 reg
->enrollee_seen_cb(reg
->cb_ctx
, addr
, attr
.uuid_e
,
789 attr
.primary_dev_type
,
790 WPA_GET_BE16(attr
.config_methods
),
791 WPA_GET_BE16(attr
.dev_password_id
),
792 *attr
.request_type
, dev_name
);
796 methods
= WPA_GET_BE16(attr
.config_methods
);
797 if (!(methods
& WPS_CONFIG_PUSHBUTTON
))
798 return; /* Not PBC */
800 wpa_printf(MSG_DEBUG
, "WPS: Probe Request for PBC received from "
801 MACSTR
, MAC2STR(addr
));
802 if (attr
.uuid_e
== NULL
) {
803 wpa_printf(MSG_DEBUG
, "WPS: Invalid Probe Request WPS IE: No "
808 wps_registrar_add_pbc_session(reg
, addr
, attr
.uuid_e
);
809 if (wps_registrar_pbc_overlap(reg
, addr
, attr
.uuid_e
)) {
810 wpa_printf(MSG_DEBUG
, "WPS: PBC session overlap detected");
811 reg
->force_pbc_overlap
= 1;
812 wps_pbc_overlap_event(reg
->wps
);
817 static int wps_cb_new_psk(struct wps_registrar
*reg
, const u8
*mac_addr
,
818 const u8
*psk
, size_t psk_len
)
820 if (reg
->new_psk_cb
== NULL
)
823 return reg
->new_psk_cb(reg
->cb_ctx
, mac_addr
, psk
, psk_len
);
827 static void wps_cb_pin_needed(struct wps_registrar
*reg
, const u8
*uuid_e
,
828 const struct wps_device_data
*dev
)
830 if (reg
->pin_needed_cb
== NULL
)
833 reg
->pin_needed_cb(reg
->cb_ctx
, uuid_e
, dev
);
837 static void wps_cb_reg_success(struct wps_registrar
*reg
, const u8
*mac_addr
,
840 if (reg
->reg_success_cb
== NULL
)
843 reg
->reg_success_cb(reg
->cb_ctx
, mac_addr
, uuid_e
);
847 static int wps_cb_set_ie(struct wps_registrar
*reg
, struct wpabuf
*beacon_ie
,
848 struct wpabuf
*probe_resp_ie
)
850 return reg
->set_ie_cb(reg
->cb_ctx
, beacon_ie
, probe_resp_ie
);
854 static void wps_cb_set_sel_reg(struct wps_registrar
*reg
)
857 if (reg
->set_sel_reg_cb
== NULL
)
860 if (reg
->selected_registrar
) {
861 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
863 methods
|= WPS_CONFIG_PUSHBUTTON
;
866 reg
->set_sel_reg_cb(reg
->cb_ctx
, reg
->selected_registrar
,
867 reg
->pbc
? DEV_PW_PUSHBUTTON
: DEV_PW_DEFAULT
,
872 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
873 static struct wpabuf
* wps_ie_encapsulate(struct wpabuf
*data
)
878 ie
= wpabuf_alloc(wpabuf_len(data
) + 100);
884 pos
= wpabuf_head(data
);
885 end
= pos
+ wpabuf_len(data
);
888 size_t frag_len
= end
- pos
;
891 wpabuf_put_u8(ie
, WLAN_EID_VENDOR_SPECIFIC
);
892 wpabuf_put_u8(ie
, 4 + frag_len
);
893 wpabuf_put_be32(ie
, WPS_DEV_OUI_WFA
);
894 wpabuf_put_data(ie
, pos
, frag_len
);
904 static int wps_set_ie(struct wps_registrar
*reg
)
906 struct wpabuf
*beacon
;
907 struct wpabuf
*probe
;
909 if (reg
->set_ie_cb
== NULL
)
912 wpa_printf(MSG_DEBUG
, "WPS: Build Beacon and Probe Response IEs");
914 beacon
= wpabuf_alloc(300);
917 probe
= wpabuf_alloc(400);
923 if (wps_build_version(beacon
) ||
924 wps_build_wps_state(reg
->wps
, beacon
) ||
925 wps_build_ap_setup_locked(reg
->wps
, beacon
) ||
926 wps_build_selected_registrar(reg
, beacon
) ||
927 wps_build_sel_reg_dev_password_id(reg
, beacon
) ||
928 wps_build_sel_reg_config_methods(reg
, beacon
) ||
929 wps_build_version(probe
) ||
930 wps_build_wps_state(reg
->wps
, probe
) ||
931 wps_build_ap_setup_locked(reg
->wps
, probe
) ||
932 wps_build_selected_registrar(reg
, probe
) ||
933 wps_build_sel_reg_dev_password_id(reg
, probe
) ||
934 wps_build_sel_reg_config_methods(reg
, probe
) ||
935 wps_build_resp_type(reg
, probe
) ||
936 wps_build_uuid_e(probe
, reg
->wps
->uuid
) ||
937 wps_build_device_attrs(®
->wps
->dev
, probe
) ||
938 wps_build_probe_config_methods(reg
, probe
) ||
939 wps_build_rf_bands(®
->wps
->dev
, probe
)) {
945 beacon
= wps_ie_encapsulate(beacon
);
946 probe
= wps_ie_encapsulate(probe
);
948 if (!beacon
|| !probe
) {
954 if (reg
->static_wep_only
) {
956 * Windows XP and Vista clients can get confused about
957 * EAP-Identity/Request when they probe the network with
958 * EAPOL-Start. In such a case, they may assume the network is
959 * using IEEE 802.1X and prompt user for a certificate while
960 * the correct (non-WPS) behavior would be to ask for the
961 * static WEP key. As a workaround, use Microsoft Provisioning
962 * IE to advertise that legacy 802.1X is not supported.
964 const u8 ms_wps
[7] = {
965 WLAN_EID_VENDOR_SPECIFIC
, 5,
966 /* Microsoft Provisioning IE (00:50:f2:5) */
968 0x00 /* no legacy 802.1X or MS WPS */
970 wpa_printf(MSG_DEBUG
, "WPS: Add Microsoft Provisioning IE "
971 "into Beacon/Probe Response frames");
972 wpabuf_put_data(beacon
, ms_wps
, sizeof(ms_wps
));
973 wpabuf_put_data(probe
, ms_wps
, sizeof(ms_wps
));
976 return wps_cb_set_ie(reg
, beacon
, probe
);
980 static int wps_get_dev_password(struct wps_data
*wps
)
985 os_free(wps
->dev_password
);
986 wps
->dev_password
= NULL
;
989 wpa_printf(MSG_DEBUG
, "WPS: Use default PIN for PBC");
990 pin
= (const u8
*) "00000000";
993 pin
= wps_registrar_get_pin(wps
->wps
->registrar
, wps
->uuid_e
,
997 wpa_printf(MSG_DEBUG
, "WPS: No Device Password available for "
999 wps_cb_pin_needed(wps
->wps
->registrar
, wps
->uuid_e
,
1004 wps
->dev_password
= os_malloc(pin_len
);
1005 if (wps
->dev_password
== NULL
)
1007 os_memcpy(wps
->dev_password
, pin
, pin_len
);
1008 wps
->dev_password_len
= pin_len
;
1014 static int wps_build_uuid_r(struct wps_data
*wps
, struct wpabuf
*msg
)
1016 wpa_printf(MSG_DEBUG
, "WPS: * UUID-R");
1017 wpabuf_put_be16(msg
, ATTR_UUID_R
);
1018 wpabuf_put_be16(msg
, WPS_UUID_LEN
);
1019 wpabuf_put_data(msg
, wps
->uuid_r
, WPS_UUID_LEN
);
1024 static int wps_build_r_hash(struct wps_data
*wps
, struct wpabuf
*msg
)
1030 if (os_get_random(wps
->snonce
, 2 * WPS_SECRET_NONCE_LEN
) < 0)
1032 wpa_hexdump(MSG_DEBUG
, "WPS: R-S1", wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1033 wpa_hexdump(MSG_DEBUG
, "WPS: R-S2",
1034 wps
->snonce
+ WPS_SECRET_NONCE_LEN
, WPS_SECRET_NONCE_LEN
);
1036 if (wps
->dh_pubkey_e
== NULL
|| wps
->dh_pubkey_r
== NULL
) {
1037 wpa_printf(MSG_DEBUG
, "WPS: DH public keys not available for "
1038 "R-Hash derivation");
1042 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash1");
1043 wpabuf_put_be16(msg
, ATTR_R_HASH1
);
1044 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1045 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1046 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1047 addr
[0] = wps
->snonce
;
1048 len
[0] = WPS_SECRET_NONCE_LEN
;
1049 addr
[1] = wps
->psk1
;
1050 len
[1] = WPS_PSK_LEN
;
1051 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1052 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1053 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1054 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1055 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1056 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash1", hash
, SHA256_MAC_LEN
);
1058 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash2");
1059 wpabuf_put_be16(msg
, ATTR_R_HASH2
);
1060 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1061 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1062 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1063 addr
[0] = wps
->snonce
+ WPS_SECRET_NONCE_LEN
;
1064 addr
[1] = wps
->psk2
;
1065 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1066 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash2", hash
, SHA256_MAC_LEN
);
1072 static int wps_build_r_snonce1(struct wps_data
*wps
, struct wpabuf
*msg
)
1074 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce1");
1075 wpabuf_put_be16(msg
, ATTR_R_SNONCE1
);
1076 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1077 wpabuf_put_data(msg
, wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1082 static int wps_build_r_snonce2(struct wps_data
*wps
, struct wpabuf
*msg
)
1084 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce2");
1085 wpabuf_put_be16(msg
, ATTR_R_SNONCE2
);
1086 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1087 wpabuf_put_data(msg
, wps
->snonce
+ WPS_SECRET_NONCE_LEN
,
1088 WPS_SECRET_NONCE_LEN
);
1093 static int wps_build_cred_network_idx(struct wpabuf
*msg
,
1094 const struct wps_credential
*cred
)
1096 wpa_printf(MSG_DEBUG
, "WPS: * Network Index");
1097 wpabuf_put_be16(msg
, ATTR_NETWORK_INDEX
);
1098 wpabuf_put_be16(msg
, 1);
1099 wpabuf_put_u8(msg
, 1);
1104 static int wps_build_cred_ssid(struct wpabuf
*msg
,
1105 const struct wps_credential
*cred
)
1107 wpa_printf(MSG_DEBUG
, "WPS: * SSID");
1108 wpabuf_put_be16(msg
, ATTR_SSID
);
1109 wpabuf_put_be16(msg
, cred
->ssid_len
);
1110 wpabuf_put_data(msg
, cred
->ssid
, cred
->ssid_len
);
1115 static int wps_build_cred_auth_type(struct wpabuf
*msg
,
1116 const struct wps_credential
*cred
)
1118 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type (0x%x)",
1120 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE
);
1121 wpabuf_put_be16(msg
, 2);
1122 wpabuf_put_be16(msg
, cred
->auth_type
);
1127 static int wps_build_cred_encr_type(struct wpabuf
*msg
,
1128 const struct wps_credential
*cred
)
1130 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type (0x%x)",
1132 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE
);
1133 wpabuf_put_be16(msg
, 2);
1134 wpabuf_put_be16(msg
, cred
->encr_type
);
1139 static int wps_build_cred_network_key(struct wpabuf
*msg
,
1140 const struct wps_credential
*cred
)
1142 wpa_printf(MSG_DEBUG
, "WPS: * Network Key (len=%d)",
1143 (int) cred
->key_len
);
1144 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
1145 wpabuf_put_be16(msg
, cred
->key_len
);
1146 wpabuf_put_data(msg
, cred
->key
, cred
->key_len
);
1151 static int wps_build_cred_mac_addr(struct wpabuf
*msg
,
1152 const struct wps_credential
*cred
)
1154 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address (" MACSTR
")",
1155 MAC2STR(cred
->mac_addr
));
1156 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
1157 wpabuf_put_be16(msg
, ETH_ALEN
);
1158 wpabuf_put_data(msg
, cred
->mac_addr
, ETH_ALEN
);
1163 static int wps_build_credential(struct wpabuf
*msg
,
1164 const struct wps_credential
*cred
)
1166 if (wps_build_cred_network_idx(msg
, cred
) ||
1167 wps_build_cred_ssid(msg
, cred
) ||
1168 wps_build_cred_auth_type(msg
, cred
) ||
1169 wps_build_cred_encr_type(msg
, cred
) ||
1170 wps_build_cred_network_key(msg
, cred
) ||
1171 wps_build_cred_mac_addr(msg
, cred
))
1177 int wps_build_cred(struct wps_data
*wps
, struct wpabuf
*msg
)
1179 struct wpabuf
*cred
;
1181 if (wps
->wps
->registrar
->skip_cred_build
)
1182 goto skip_cred_build
;
1184 wpa_printf(MSG_DEBUG
, "WPS: * Credential");
1185 if (wps
->use_cred
) {
1186 os_memcpy(&wps
->cred
, wps
->use_cred
, sizeof(wps
->cred
));
1189 os_memset(&wps
->cred
, 0, sizeof(wps
->cred
));
1191 os_memcpy(wps
->cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
1192 wps
->cred
.ssid_len
= wps
->wps
->ssid_len
;
1194 /* Select the best authentication and encryption type */
1195 if (wps
->auth_type
& WPS_AUTH_WPA2PSK
)
1196 wps
->auth_type
= WPS_AUTH_WPA2PSK
;
1197 else if (wps
->auth_type
& WPS_AUTH_WPAPSK
)
1198 wps
->auth_type
= WPS_AUTH_WPAPSK
;
1199 else if (wps
->auth_type
& WPS_AUTH_OPEN
)
1200 wps
->auth_type
= WPS_AUTH_OPEN
;
1201 else if (wps
->auth_type
& WPS_AUTH_SHARED
)
1202 wps
->auth_type
= WPS_AUTH_SHARED
;
1204 wpa_printf(MSG_DEBUG
, "WPS: Unsupported auth_type 0x%x",
1208 wps
->cred
.auth_type
= wps
->auth_type
;
1210 if (wps
->auth_type
== WPS_AUTH_WPA2PSK
||
1211 wps
->auth_type
== WPS_AUTH_WPAPSK
) {
1212 if (wps
->encr_type
& WPS_ENCR_AES
)
1213 wps
->encr_type
= WPS_ENCR_AES
;
1214 else if (wps
->encr_type
& WPS_ENCR_TKIP
)
1215 wps
->encr_type
= WPS_ENCR_TKIP
;
1217 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1218 "type for WPA/WPA2");
1222 if (wps
->encr_type
& WPS_ENCR_WEP
)
1223 wps
->encr_type
= WPS_ENCR_WEP
;
1224 else if (wps
->encr_type
& WPS_ENCR_NONE
)
1225 wps
->encr_type
= WPS_ENCR_NONE
;
1227 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1228 "type for non-WPA/WPA2 mode");
1232 wps
->cred
.encr_type
= wps
->encr_type
;
1234 * Set MAC address in the Credential to be the Enrollee's MAC address
1236 os_memcpy(wps
->cred
.mac_addr
, wps
->mac_addr_e
, ETH_ALEN
);
1238 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->wps
->ap
&&
1239 !wps
->wps
->registrar
->disable_auto_conf
) {
1241 /* Generate a random passphrase */
1242 if (os_get_random(r
, sizeof(r
)) < 0)
1244 os_free(wps
->new_psk
);
1245 wps
->new_psk
= base64_encode(r
, sizeof(r
), &wps
->new_psk_len
);
1246 if (wps
->new_psk
== NULL
)
1248 wps
->new_psk_len
--; /* remove newline */
1249 while (wps
->new_psk_len
&&
1250 wps
->new_psk
[wps
->new_psk_len
- 1] == '=')
1252 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: Generated passphrase",
1253 wps
->new_psk
, wps
->new_psk_len
);
1254 os_memcpy(wps
->cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
1255 wps
->cred
.key_len
= wps
->new_psk_len
;
1256 } else if (wps
->use_psk_key
&& wps
->wps
->psk_set
) {
1258 wpa_printf(MSG_DEBUG
, "WPS: Use PSK format for Network Key");
1259 wpa_snprintf_hex(hex
, sizeof(hex
), wps
->wps
->psk
, 32);
1260 os_memcpy(wps
->cred
.key
, hex
, 32 * 2);
1261 wps
->cred
.key_len
= 32 * 2;
1262 } else if (wps
->wps
->network_key
) {
1263 os_memcpy(wps
->cred
.key
, wps
->wps
->network_key
,
1264 wps
->wps
->network_key_len
);
1265 wps
->cred
.key_len
= wps
->wps
->network_key_len
;
1266 } else if (wps
->auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) {
1268 /* Generate a random per-device PSK */
1269 os_free(wps
->new_psk
);
1270 wps
->new_psk_len
= 32;
1271 wps
->new_psk
= os_malloc(wps
->new_psk_len
);
1272 if (wps
->new_psk
== NULL
)
1274 if (os_get_random(wps
->new_psk
, wps
->new_psk_len
) < 0) {
1275 os_free(wps
->new_psk
);
1276 wps
->new_psk
= NULL
;
1279 wpa_hexdump_key(MSG_DEBUG
, "WPS: Generated per-device PSK",
1280 wps
->new_psk
, wps
->new_psk_len
);
1281 wpa_snprintf_hex(hex
, sizeof(hex
), wps
->new_psk
,
1283 os_memcpy(wps
->cred
.key
, hex
, wps
->new_psk_len
* 2);
1284 wps
->cred
.key_len
= wps
->new_psk_len
* 2;
1288 cred
= wpabuf_alloc(200);
1292 if (wps_build_credential(cred
, &wps
->cred
)) {
1297 wpabuf_put_be16(msg
, ATTR_CRED
);
1298 wpabuf_put_be16(msg
, wpabuf_len(cred
));
1299 wpabuf_put_buf(msg
, cred
);
1303 if (wps
->wps
->registrar
->extra_cred
) {
1304 wpa_printf(MSG_DEBUG
, "WPS: * Credential (pre-configured)");
1305 wpabuf_put_buf(msg
, wps
->wps
->registrar
->extra_cred
);
1312 static int wps_build_ap_settings(struct wps_data
*wps
, struct wpabuf
*msg
)
1314 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings");
1316 if (wps_build_credential(msg
, &wps
->cred
))
1323 static struct wpabuf
* wps_build_m2(struct wps_data
*wps
)
1327 if (os_get_random(wps
->nonce_r
, WPS_NONCE_LEN
) < 0)
1329 wpa_hexdump(MSG_DEBUG
, "WPS: Registrar Nonce",
1330 wps
->nonce_r
, WPS_NONCE_LEN
);
1331 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-R", wps
->uuid_r
, WPS_UUID_LEN
);
1333 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2");
1334 msg
= wpabuf_alloc(1000);
1338 if (wps_build_version(msg
) ||
1339 wps_build_msg_type(msg
, WPS_M2
) ||
1340 wps_build_enrollee_nonce(wps
, msg
) ||
1341 wps_build_registrar_nonce(wps
, msg
) ||
1342 wps_build_uuid_r(wps
, msg
) ||
1343 wps_build_public_key(wps
, msg
) ||
1344 wps_derive_keys(wps
) ||
1345 wps_build_auth_type_flags(wps
, msg
) ||
1346 wps_build_encr_type_flags(wps
, msg
) ||
1347 wps_build_conn_type_flags(wps
, msg
) ||
1348 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1349 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1350 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1351 wps_build_assoc_state(wps
, msg
) ||
1352 wps_build_config_error(msg
, WPS_CFG_NO_ERROR
) ||
1353 wps_build_dev_password_id(msg
, wps
->dev_pw_id
) ||
1354 wps_build_os_version(&wps
->wps
->dev
, msg
) ||
1355 wps_build_authenticator(wps
, msg
)) {
1360 wps
->state
= RECV_M3
;
1365 static struct wpabuf
* wps_build_m2d(struct wps_data
*wps
)
1368 u16 err
= wps
->config_error
;
1370 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2D");
1371 msg
= wpabuf_alloc(1000);
1375 if (wps
->wps
->ap
&& wps
->wps
->ap_setup_locked
&&
1376 err
== WPS_CFG_NO_ERROR
)
1377 err
= WPS_CFG_SETUP_LOCKED
;
1379 if (wps_build_version(msg
) ||
1380 wps_build_msg_type(msg
, WPS_M2D
) ||
1381 wps_build_enrollee_nonce(wps
, msg
) ||
1382 wps_build_registrar_nonce(wps
, msg
) ||
1383 wps_build_uuid_r(wps
, msg
) ||
1384 wps_build_auth_type_flags(wps
, msg
) ||
1385 wps_build_encr_type_flags(wps
, msg
) ||
1386 wps_build_conn_type_flags(wps
, msg
) ||
1387 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1388 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1389 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1390 wps_build_assoc_state(wps
, msg
) ||
1391 wps_build_config_error(msg
, err
) ||
1392 wps_build_os_version(&wps
->wps
->dev
, msg
)) {
1397 wps
->state
= RECV_M2D_ACK
;
1402 static struct wpabuf
* wps_build_m4(struct wps_data
*wps
)
1404 struct wpabuf
*msg
, *plain
;
1406 wpa_printf(MSG_DEBUG
, "WPS: Building Message M4");
1408 wps_derive_psk(wps
, wps
->dev_password
, wps
->dev_password_len
);
1410 plain
= wpabuf_alloc(200);
1414 msg
= wpabuf_alloc(1000);
1420 if (wps_build_version(msg
) ||
1421 wps_build_msg_type(msg
, WPS_M4
) ||
1422 wps_build_enrollee_nonce(wps
, msg
) ||
1423 wps_build_r_hash(wps
, msg
) ||
1424 wps_build_r_snonce1(wps
, plain
) ||
1425 wps_build_key_wrap_auth(wps
, plain
) ||
1426 wps_build_encr_settings(wps
, msg
, plain
) ||
1427 wps_build_authenticator(wps
, msg
)) {
1434 wps
->state
= RECV_M5
;
1439 static struct wpabuf
* wps_build_m6(struct wps_data
*wps
)
1441 struct wpabuf
*msg
, *plain
;
1443 wpa_printf(MSG_DEBUG
, "WPS: Building Message M6");
1445 plain
= wpabuf_alloc(200);
1449 msg
= wpabuf_alloc(1000);
1455 if (wps_build_version(msg
) ||
1456 wps_build_msg_type(msg
, WPS_M6
) ||
1457 wps_build_enrollee_nonce(wps
, msg
) ||
1458 wps_build_r_snonce2(wps
, plain
) ||
1459 wps_build_key_wrap_auth(wps
, plain
) ||
1460 wps_build_encr_settings(wps
, msg
, plain
) ||
1461 wps_build_authenticator(wps
, msg
)) {
1468 wps
->wps_pin_revealed
= 1;
1469 wps
->state
= RECV_M7
;
1474 static struct wpabuf
* wps_build_m8(struct wps_data
*wps
)
1476 struct wpabuf
*msg
, *plain
;
1478 wpa_printf(MSG_DEBUG
, "WPS: Building Message M8");
1480 plain
= wpabuf_alloc(500);
1484 msg
= wpabuf_alloc(1000);
1490 if (wps_build_version(msg
) ||
1491 wps_build_msg_type(msg
, WPS_M8
) ||
1492 wps_build_enrollee_nonce(wps
, msg
) ||
1493 ((wps
->wps
->ap
|| wps
->er
) && wps_build_cred(wps
, plain
)) ||
1494 (!wps
->wps
->ap
&& !wps
->er
&& wps_build_ap_settings(wps
, plain
)) ||
1495 wps_build_key_wrap_auth(wps
, plain
) ||
1496 wps_build_encr_settings(wps
, msg
, plain
) ||
1497 wps_build_authenticator(wps
, msg
)) {
1504 wps
->state
= RECV_DONE
;
1509 static struct wpabuf
* wps_build_wsc_ack(struct wps_data
*wps
)
1513 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_ACK");
1515 msg
= wpabuf_alloc(1000);
1519 if (wps_build_version(msg
) ||
1520 wps_build_msg_type(msg
, WPS_WSC_ACK
) ||
1521 wps_build_enrollee_nonce(wps
, msg
) ||
1522 wps_build_registrar_nonce(wps
, msg
)) {
1531 static struct wpabuf
* wps_build_wsc_nack(struct wps_data
*wps
)
1535 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_NACK");
1537 msg
= wpabuf_alloc(1000);
1541 if (wps_build_version(msg
) ||
1542 wps_build_msg_type(msg
, WPS_WSC_NACK
) ||
1543 wps_build_enrollee_nonce(wps
, msg
) ||
1544 wps_build_registrar_nonce(wps
, msg
) ||
1545 wps_build_config_error(msg
, wps
->config_error
)) {
1554 struct wpabuf
* wps_registrar_get_msg(struct wps_data
*wps
,
1555 enum wsc_op_code
*op_code
)
1559 #ifdef CONFIG_WPS_UPNP
1560 if (wps
->wps
->wps_upnp
) {
1561 struct upnp_pending_message
*p
, *prev
= NULL
;
1562 if (wps
->ext_reg
> 1)
1563 wps_registrar_free_pending_m2(wps
->wps
);
1564 p
= wps
->wps
->upnp_msgs
;
1565 /* TODO: check pending message MAC address */
1566 while (p
&& p
->next
) {
1571 wpa_printf(MSG_DEBUG
, "WPS: Use pending message from "
1576 wps
->wps
->upnp_msgs
= NULL
;
1583 *op_code
= WSC_NACK
;
1590 if (wps
->ext_reg
== 0)
1596 wpa_printf(MSG_DEBUG
, "WPS: Using external Registrar, but no "
1597 "pending message available");
1600 #endif /* CONFIG_WPS_UPNP */
1602 switch (wps
->state
) {
1604 if (wps_get_dev_password(wps
) < 0)
1605 msg
= wps_build_m2d(wps
);
1607 msg
= wps_build_m2(wps
);
1611 msg
= wps_build_m2d(wps
);
1615 msg
= wps_build_m4(wps
);
1619 msg
= wps_build_m6(wps
);
1623 msg
= wps_build_m8(wps
);
1627 msg
= wps_build_wsc_ack(wps
);
1631 msg
= wps_build_wsc_nack(wps
);
1632 *op_code
= WSC_NACK
;
1635 wpa_printf(MSG_DEBUG
, "WPS: Unsupported state %d for building "
1636 "a message", wps
->state
);
1641 if (*op_code
== WSC_MSG
&& msg
) {
1642 /* Save a copy of the last message for Authenticator derivation
1644 wpabuf_free(wps
->last_msg
);
1645 wps
->last_msg
= wpabuf_dup(msg
);
1652 static int wps_process_enrollee_nonce(struct wps_data
*wps
, const u8
*e_nonce
)
1654 if (e_nonce
== NULL
) {
1655 wpa_printf(MSG_DEBUG
, "WPS: No Enrollee Nonce received");
1659 os_memcpy(wps
->nonce_e
, e_nonce
, WPS_NONCE_LEN
);
1660 wpa_hexdump(MSG_DEBUG
, "WPS: Enrollee Nonce",
1661 wps
->nonce_e
, WPS_NONCE_LEN
);
1667 static int wps_process_registrar_nonce(struct wps_data
*wps
, const u8
*r_nonce
)
1669 if (r_nonce
== NULL
) {
1670 wpa_printf(MSG_DEBUG
, "WPS: No Registrar Nonce received");
1674 if (os_memcmp(wps
->nonce_r
, r_nonce
, WPS_NONCE_LEN
) != 0) {
1675 wpa_printf(MSG_DEBUG
, "WPS: Invalid Registrar Nonce received");
1683 static int wps_process_uuid_e(struct wps_data
*wps
, const u8
*uuid_e
)
1685 if (uuid_e
== NULL
) {
1686 wpa_printf(MSG_DEBUG
, "WPS: No UUID-E received");
1690 os_memcpy(wps
->uuid_e
, uuid_e
, WPS_UUID_LEN
);
1691 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-E", wps
->uuid_e
, WPS_UUID_LEN
);
1697 static int wps_process_dev_password_id(struct wps_data
*wps
, const u8
*pw_id
)
1699 if (pw_id
== NULL
) {
1700 wpa_printf(MSG_DEBUG
, "WPS: No Device Password ID received");
1704 wps
->dev_pw_id
= WPA_GET_BE16(pw_id
);
1705 wpa_printf(MSG_DEBUG
, "WPS: Device Password ID %d", wps
->dev_pw_id
);
1711 static int wps_process_e_hash1(struct wps_data
*wps
, const u8
*e_hash1
)
1713 if (e_hash1
== NULL
) {
1714 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash1 received");
1718 os_memcpy(wps
->peer_hash1
, e_hash1
, WPS_HASH_LEN
);
1719 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash1", wps
->peer_hash1
, WPS_HASH_LEN
);
1725 static int wps_process_e_hash2(struct wps_data
*wps
, const u8
*e_hash2
)
1727 if (e_hash2
== NULL
) {
1728 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash2 received");
1732 os_memcpy(wps
->peer_hash2
, e_hash2
, WPS_HASH_LEN
);
1733 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash2", wps
->peer_hash2
, WPS_HASH_LEN
);
1739 static int wps_process_e_snonce1(struct wps_data
*wps
, const u8
*e_snonce1
)
1741 u8 hash
[SHA256_MAC_LEN
];
1745 if (e_snonce1
== NULL
) {
1746 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce1 received");
1750 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce1", e_snonce1
,
1751 WPS_SECRET_NONCE_LEN
);
1753 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1754 addr
[0] = e_snonce1
;
1755 len
[0] = WPS_SECRET_NONCE_LEN
;
1756 addr
[1] = wps
->psk1
;
1757 len
[1] = WPS_PSK_LEN
;
1758 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1759 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1760 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1761 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1762 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1764 if (os_memcmp(wps
->peer_hash1
, hash
, WPS_HASH_LEN
) != 0) {
1765 wpa_printf(MSG_DEBUG
, "WPS: E-Hash1 derived from E-S1 does "
1766 "not match with the pre-committed value");
1767 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1768 wps_pwd_auth_fail_event(wps
->wps
, 0, 1);
1772 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the first "
1773 "half of the device password");
1779 static int wps_process_e_snonce2(struct wps_data
*wps
, const u8
*e_snonce2
)
1781 u8 hash
[SHA256_MAC_LEN
];
1785 if (e_snonce2
== NULL
) {
1786 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce2 received");
1790 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce2", e_snonce2
,
1791 WPS_SECRET_NONCE_LEN
);
1793 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1794 addr
[0] = e_snonce2
;
1795 len
[0] = WPS_SECRET_NONCE_LEN
;
1796 addr
[1] = wps
->psk2
;
1797 len
[1] = WPS_PSK_LEN
;
1798 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1799 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1800 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1801 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1802 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1804 if (os_memcmp(wps
->peer_hash2
, hash
, WPS_HASH_LEN
) != 0) {
1805 wpa_printf(MSG_DEBUG
, "WPS: E-Hash2 derived from E-S2 does "
1806 "not match with the pre-committed value");
1807 wps_registrar_invalidate_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1808 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1809 wps_pwd_auth_fail_event(wps
->wps
, 0, 2);
1813 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the second "
1814 "half of the device password");
1815 wps
->wps_pin_revealed
= 0;
1816 wps_registrar_unlock_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1822 static int wps_process_mac_addr(struct wps_data
*wps
, const u8
*mac_addr
)
1824 if (mac_addr
== NULL
) {
1825 wpa_printf(MSG_DEBUG
, "WPS: No MAC Address received");
1829 wpa_printf(MSG_DEBUG
, "WPS: Enrollee MAC Address " MACSTR
,
1831 os_memcpy(wps
->mac_addr_e
, mac_addr
, ETH_ALEN
);
1832 os_memcpy(wps
->peer_dev
.mac_addr
, mac_addr
, ETH_ALEN
);
1838 static int wps_process_pubkey(struct wps_data
*wps
, const u8
*pk
,
1841 if (pk
== NULL
|| pk_len
== 0) {
1842 wpa_printf(MSG_DEBUG
, "WPS: No Public Key received");
1846 #ifdef CONFIG_WPS_OOB
1847 if (wps
->wps
->oob_conf
.pubkey_hash
!= NULL
) {
1849 u8 hash
[WPS_HASH_LEN
];
1852 sha256_vector(1, addr
, &pk_len
, hash
);
1854 wpabuf_head(wps
->wps
->oob_conf
.pubkey_hash
),
1855 WPS_OOB_PUBKEY_HASH_LEN
) != 0) {
1856 wpa_printf(MSG_ERROR
, "WPS: Public Key hash error");
1860 #endif /* CONFIG_WPS_OOB */
1862 wpabuf_free(wps
->dh_pubkey_e
);
1863 wps
->dh_pubkey_e
= wpabuf_alloc_copy(pk
, pk_len
);
1864 if (wps
->dh_pubkey_e
== NULL
)
1871 static int wps_process_auth_type_flags(struct wps_data
*wps
, const u8
*auth
)
1876 wpa_printf(MSG_DEBUG
, "WPS: No Authentication Type flags "
1881 auth_types
= WPA_GET_BE16(auth
);
1883 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Authentication Type flags 0x%x",
1885 wps
->auth_type
= wps
->wps
->auth_types
& auth_types
;
1886 if (wps
->auth_type
== 0) {
1887 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1888 "authentication types (own 0x%x Enrollee 0x%x)",
1889 wps
->wps
->auth_types
, auth_types
);
1890 #ifdef WPS_WORKAROUNDS
1892 * Some deployed implementations seem to advertise incorrect
1893 * information in this attribute. For example, Linksys WRT350N
1894 * seems to have a byteorder bug that breaks this negotiation.
1895 * In order to interoperate with existing implementations,
1896 * assume that the Enrollee supports everything we do.
1898 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1899 "does not advertise supported authentication types "
1901 wps
->auth_type
= wps
->wps
->auth_types
;
1902 #else /* WPS_WORKAROUNDS */
1904 #endif /* WPS_WORKAROUNDS */
1911 static int wps_process_encr_type_flags(struct wps_data
*wps
, const u8
*encr
)
1916 wpa_printf(MSG_DEBUG
, "WPS: No Encryption Type flags "
1921 encr_types
= WPA_GET_BE16(encr
);
1923 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Encryption Type flags 0x%x",
1925 wps
->encr_type
= wps
->wps
->encr_types
& encr_types
;
1926 if (wps
->encr_type
== 0) {
1927 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1928 "encryption types (own 0x%x Enrollee 0x%x)",
1929 wps
->wps
->encr_types
, encr_types
);
1930 #ifdef WPS_WORKAROUNDS
1932 * Some deployed implementations seem to advertise incorrect
1933 * information in this attribute. For example, Linksys WRT350N
1934 * seems to have a byteorder bug that breaks this negotiation.
1935 * In order to interoperate with existing implementations,
1936 * assume that the Enrollee supports everything we do.
1938 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1939 "does not advertise supported encryption types "
1941 wps
->encr_type
= wps
->wps
->encr_types
;
1942 #else /* WPS_WORKAROUNDS */
1944 #endif /* WPS_WORKAROUNDS */
1951 static int wps_process_conn_type_flags(struct wps_data
*wps
, const u8
*conn
)
1954 wpa_printf(MSG_DEBUG
, "WPS: No Connection Type flags "
1959 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Connection Type flags 0x%x",
1966 static int wps_process_config_methods(struct wps_data
*wps
, const u8
*methods
)
1970 if (methods
== NULL
) {
1971 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods received");
1975 m
= WPA_GET_BE16(methods
);
1977 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Config Methods 0x%x"
1978 "%s%s%s%s%s%s%s%s%s", m
,
1979 m
& WPS_CONFIG_USBA
? " [USBA]" : "",
1980 m
& WPS_CONFIG_ETHERNET
? " [Ethernet]" : "",
1981 m
& WPS_CONFIG_LABEL
? " [Label]" : "",
1982 m
& WPS_CONFIG_DISPLAY
? " [Display]" : "",
1983 m
& WPS_CONFIG_EXT_NFC_TOKEN
? " [Ext NFC Token]" : "",
1984 m
& WPS_CONFIG_INT_NFC_TOKEN
? " [Int NFC Token]" : "",
1985 m
& WPS_CONFIG_NFC_INTERFACE
? " [NFC]" : "",
1986 m
& WPS_CONFIG_PUSHBUTTON
? " [PBC]" : "",
1987 m
& WPS_CONFIG_KEYPAD
? " [Keypad]" : "");
1989 if (!(m
& WPS_CONFIG_DISPLAY
) && !wps
->use_psk_key
) {
1991 * The Enrollee does not have a display so it is unlikely to be
1992 * able to show the passphrase to a user and as such, could
1993 * benefit from receiving PSK to reduce key derivation time.
1995 wpa_printf(MSG_DEBUG
, "WPS: Prefer PSK format key due to "
1996 "Enrollee not supporting display");
1997 wps
->use_psk_key
= 1;
2004 static int wps_process_wps_state(struct wps_data
*wps
, const u8
*state
)
2006 if (state
== NULL
) {
2007 wpa_printf(MSG_DEBUG
, "WPS: No Wi-Fi Protected Setup State "
2012 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2019 static int wps_process_assoc_state(struct wps_data
*wps
, const u8
*assoc
)
2023 if (assoc
== NULL
) {
2024 wpa_printf(MSG_DEBUG
, "WPS: No Association State received");
2028 a
= WPA_GET_BE16(assoc
);
2029 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Association State %d", a
);
2035 static int wps_process_config_error(struct wps_data
*wps
, const u8
*err
)
2040 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error received");
2044 e
= WPA_GET_BE16(err
);
2045 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Configuration Error %d", e
);
2051 static enum wps_process_res
wps_process_m1(struct wps_data
*wps
,
2052 struct wps_parse_attr
*attr
)
2054 wpa_printf(MSG_DEBUG
, "WPS: Received M1");
2056 if (wps
->state
!= RECV_M1
) {
2057 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2058 "receiving M1", wps
->state
);
2062 if (wps_process_uuid_e(wps
, attr
->uuid_e
) ||
2063 wps_process_mac_addr(wps
, attr
->mac_addr
) ||
2064 wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
2065 wps_process_pubkey(wps
, attr
->public_key
, attr
->public_key_len
) ||
2066 wps_process_auth_type_flags(wps
, attr
->auth_type_flags
) ||
2067 wps_process_encr_type_flags(wps
, attr
->encr_type_flags
) ||
2068 wps_process_conn_type_flags(wps
, attr
->conn_type_flags
) ||
2069 wps_process_config_methods(wps
, attr
->config_methods
) ||
2070 wps_process_wps_state(wps
, attr
->wps_state
) ||
2071 wps_process_device_attrs(&wps
->peer_dev
, attr
) ||
2072 wps_process_rf_bands(&wps
->peer_dev
, attr
->rf_bands
) ||
2073 wps_process_assoc_state(wps
, attr
->assoc_state
) ||
2074 wps_process_dev_password_id(wps
, attr
->dev_password_id
) ||
2075 wps_process_config_error(wps
, attr
->config_error
) ||
2076 wps_process_os_version(&wps
->peer_dev
, attr
->os_version
))
2079 if (wps
->dev_pw_id
< 0x10 &&
2080 wps
->dev_pw_id
!= DEV_PW_DEFAULT
&&
2081 wps
->dev_pw_id
!= DEV_PW_USER_SPECIFIED
&&
2082 wps
->dev_pw_id
!= DEV_PW_MACHINE_SPECIFIED
&&
2083 wps
->dev_pw_id
!= DEV_PW_REGISTRAR_SPECIFIED
&&
2084 (wps
->dev_pw_id
!= DEV_PW_PUSHBUTTON
||
2085 !wps
->wps
->registrar
->pbc
)) {
2086 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Device Password ID %d",
2088 wps
->state
= SEND_M2D
;
2089 return WPS_CONTINUE
;
2092 #ifdef CONFIG_WPS_OOB
2093 if (wps
->dev_pw_id
>= 0x10 &&
2094 wps
->dev_pw_id
!= wps
->wps
->oob_dev_pw_id
) {
2095 wpa_printf(MSG_DEBUG
, "WPS: OOB Device Password ID "
2096 "%d mismatch", wps
->dev_pw_id
);
2097 wps
->state
= SEND_M2D
;
2098 return WPS_CONTINUE
;
2100 #endif /* CONFIG_WPS_OOB */
2102 if (wps
->dev_pw_id
== DEV_PW_PUSHBUTTON
) {
2103 if (wps
->wps
->registrar
->force_pbc_overlap
||
2104 wps_registrar_pbc_overlap(wps
->wps
->registrar
,
2105 wps
->mac_addr_e
, wps
->uuid_e
)) {
2106 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - deny PBC "
2108 wps
->state
= SEND_M2D
;
2109 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2110 wps_pbc_overlap_event(wps
->wps
);
2111 wps
->wps
->registrar
->force_pbc_overlap
= 1;
2112 return WPS_CONTINUE
;
2114 wps_registrar_add_pbc_session(wps
->wps
->registrar
,
2115 wps
->mac_addr_e
, wps
->uuid_e
);
2119 wps
->state
= SEND_M2
;
2120 return WPS_CONTINUE
;
2124 static enum wps_process_res
wps_process_m3(struct wps_data
*wps
,
2125 const struct wpabuf
*msg
,
2126 struct wps_parse_attr
*attr
)
2128 wpa_printf(MSG_DEBUG
, "WPS: Received M3");
2130 if (wps
->state
!= RECV_M3
) {
2131 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2132 "receiving M3", wps
->state
);
2133 wps
->state
= SEND_WSC_NACK
;
2134 return WPS_CONTINUE
;
2137 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2138 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2140 wps
->state
= SEND_WSC_NACK
;
2141 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2142 return WPS_CONTINUE
;
2145 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2146 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
2147 wps_process_e_hash1(wps
, attr
->e_hash1
) ||
2148 wps_process_e_hash2(wps
, attr
->e_hash2
)) {
2149 wps
->state
= SEND_WSC_NACK
;
2150 return WPS_CONTINUE
;
2153 wps
->state
= SEND_M4
;
2154 return WPS_CONTINUE
;
2158 static enum wps_process_res
wps_process_m5(struct wps_data
*wps
,
2159 const struct wpabuf
*msg
,
2160 struct wps_parse_attr
*attr
)
2162 struct wpabuf
*decrypted
;
2163 struct wps_parse_attr eattr
;
2165 wpa_printf(MSG_DEBUG
, "WPS: Received M5");
2167 if (wps
->state
!= RECV_M5
) {
2168 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2169 "receiving M5", wps
->state
);
2170 wps
->state
= SEND_WSC_NACK
;
2171 return WPS_CONTINUE
;
2174 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2175 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2177 wps
->state
= SEND_WSC_NACK
;
2178 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2179 return WPS_CONTINUE
;
2182 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2183 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2184 wps
->state
= SEND_WSC_NACK
;
2185 return WPS_CONTINUE
;
2188 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2189 attr
->encr_settings_len
);
2190 if (decrypted
== NULL
) {
2191 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
2192 "Settings attribute");
2193 wps
->state
= SEND_WSC_NACK
;
2194 return WPS_CONTINUE
;
2197 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2199 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2200 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2201 wps_process_e_snonce1(wps
, eattr
.e_snonce1
)) {
2202 wpabuf_free(decrypted
);
2203 wps
->state
= SEND_WSC_NACK
;
2204 return WPS_CONTINUE
;
2206 wpabuf_free(decrypted
);
2208 wps
->state
= SEND_M6
;
2209 return WPS_CONTINUE
;
2213 static void wps_sta_cred_cb(struct wps_data
*wps
)
2216 * Update credential to only include a single authentication and
2217 * encryption type in case the AP configuration includes more than one
2220 if (wps
->cred
.auth_type
& WPS_AUTH_WPA2PSK
)
2221 wps
->cred
.auth_type
= WPS_AUTH_WPA2PSK
;
2222 else if (wps
->cred
.auth_type
& WPS_AUTH_WPAPSK
)
2223 wps
->cred
.auth_type
= WPS_AUTH_WPAPSK
;
2224 if (wps
->cred
.encr_type
& WPS_ENCR_AES
)
2225 wps
->cred
.encr_type
= WPS_ENCR_AES
;
2226 else if (wps
->cred
.encr_type
& WPS_ENCR_TKIP
)
2227 wps
->cred
.encr_type
= WPS_ENCR_TKIP
;
2228 wpa_printf(MSG_DEBUG
, "WPS: Update local configuration based on the "
2229 "AP configuration");
2230 if (wps
->wps
->cred_cb
)
2231 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &wps
->cred
);
2235 static void wps_cred_update(struct wps_credential
*dst
,
2236 struct wps_credential
*src
)
2238 os_memcpy(dst
->ssid
, src
->ssid
, sizeof(dst
->ssid
));
2239 dst
->ssid_len
= src
->ssid_len
;
2240 dst
->auth_type
= src
->auth_type
;
2241 dst
->encr_type
= src
->encr_type
;
2242 dst
->key_idx
= src
->key_idx
;
2243 os_memcpy(dst
->key
, src
->key
, sizeof(dst
->key
));
2244 dst
->key_len
= src
->key_len
;
2248 static int wps_process_ap_settings_r(struct wps_data
*wps
,
2249 struct wps_parse_attr
*attr
)
2251 if (wps
->wps
->ap
|| wps
->er
)
2254 /* AP Settings Attributes in M7 when Enrollee is an AP */
2255 if (wps_process_ap_settings(attr
, &wps
->cred
) < 0)
2258 wpa_printf(MSG_INFO
, "WPS: Received old AP configuration from AP");
2260 if (wps
->new_ap_settings
) {
2261 wpa_printf(MSG_INFO
, "WPS: Update AP configuration based on "
2263 wps_cred_update(&wps
->cred
, wps
->new_ap_settings
);
2267 * Use the AP PIN only to receive the current AP settings, not
2268 * to reconfigure the AP.
2270 if (wps
->ap_settings_cb
) {
2271 wps
->ap_settings_cb(wps
->ap_settings_cb_ctx
,
2275 wps_sta_cred_cb(wps
);
2281 static enum wps_process_res
wps_process_m7(struct wps_data
*wps
,
2282 const struct wpabuf
*msg
,
2283 struct wps_parse_attr
*attr
)
2285 struct wpabuf
*decrypted
;
2286 struct wps_parse_attr eattr
;
2288 wpa_printf(MSG_DEBUG
, "WPS: Received M7");
2290 if (wps
->state
!= RECV_M7
) {
2291 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2292 "receiving M7", wps
->state
);
2293 wps
->state
= SEND_WSC_NACK
;
2294 return WPS_CONTINUE
;
2297 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2298 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2300 wps
->state
= SEND_WSC_NACK
;
2301 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2302 return WPS_CONTINUE
;
2305 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2306 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2307 wps
->state
= SEND_WSC_NACK
;
2308 return WPS_CONTINUE
;
2311 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2312 attr
->encr_settings_len
);
2313 if (decrypted
== NULL
) {
2314 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypt Encrypted "
2315 "Settings attribute");
2316 wps
->state
= SEND_WSC_NACK
;
2317 return WPS_CONTINUE
;
2320 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2322 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2323 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2324 wps_process_e_snonce2(wps
, eattr
.e_snonce2
) ||
2325 wps_process_ap_settings_r(wps
, &eattr
)) {
2326 wpabuf_free(decrypted
);
2327 wps
->state
= SEND_WSC_NACK
;
2328 return WPS_CONTINUE
;
2331 wpabuf_free(decrypted
);
2333 wps
->state
= SEND_M8
;
2334 return WPS_CONTINUE
;
2338 static enum wps_process_res
wps_process_wsc_msg(struct wps_data
*wps
,
2339 const struct wpabuf
*msg
)
2341 struct wps_parse_attr attr
;
2342 enum wps_process_res ret
= WPS_CONTINUE
;
2344 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_MSG");
2346 if (wps_parse_msg(msg
, &attr
) < 0)
2349 if (!wps_version_supported(attr
.version
)) {
2350 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2351 attr
.version
? *attr
.version
: 0);
2355 if (attr
.msg_type
== NULL
) {
2356 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2360 if (*attr
.msg_type
!= WPS_M1
&&
2361 (attr
.registrar_nonce
== NULL
||
2362 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
,
2363 WPS_NONCE_LEN
!= 0))) {
2364 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2368 switch (*attr
.msg_type
) {
2370 #ifdef CONFIG_WPS_UPNP
2371 if (wps
->wps
->wps_upnp
&& attr
.mac_addr
) {
2372 /* Remove old pending messages when starting new run */
2373 wps_free_pending_msgs(wps
->wps
->upnp_msgs
);
2374 wps
->wps
->upnp_msgs
= NULL
;
2376 upnp_wps_device_send_wlan_event(
2377 wps
->wps
->wps_upnp
, attr
.mac_addr
,
2378 UPNP_WPS_WLANEVENT_TYPE_EAP
, msg
);
2380 #endif /* CONFIG_WPS_UPNP */
2381 ret
= wps_process_m1(wps
, &attr
);
2384 ret
= wps_process_m3(wps
, msg
, &attr
);
2385 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2386 wps_fail_event(wps
->wps
, WPS_M3
);
2389 ret
= wps_process_m5(wps
, msg
, &attr
);
2390 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2391 wps_fail_event(wps
->wps
, WPS_M5
);
2394 ret
= wps_process_m7(wps
, msg
, &attr
);
2395 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2396 wps_fail_event(wps
->wps
, WPS_M7
);
2399 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Message Type %d",
2404 if (ret
== WPS_CONTINUE
) {
2405 /* Save a copy of the last message for Authenticator derivation
2407 wpabuf_free(wps
->last_msg
);
2408 wps
->last_msg
= wpabuf_dup(msg
);
2415 static enum wps_process_res
wps_process_wsc_ack(struct wps_data
*wps
,
2416 const struct wpabuf
*msg
)
2418 struct wps_parse_attr attr
;
2420 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_ACK");
2422 if (wps_parse_msg(msg
, &attr
) < 0)
2425 if (!wps_version_supported(attr
.version
)) {
2426 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2427 attr
.version
? *attr
.version
: 0);
2431 if (attr
.msg_type
== NULL
) {
2432 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2436 if (*attr
.msg_type
!= WPS_WSC_ACK
) {
2437 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2442 #ifdef CONFIG_WPS_UPNP
2443 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& wps
->state
== RECV_M2D_ACK
&&
2444 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2445 if (wps
->wps
->upnp_msgs
)
2446 return WPS_CONTINUE
;
2447 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2448 "external Registrar");
2451 #endif /* CONFIG_WPS_UPNP */
2453 if (attr
.registrar_nonce
== NULL
||
2454 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2456 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2460 if (attr
.enrollee_nonce
== NULL
||
2461 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2462 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2466 if (wps
->state
== RECV_M2D_ACK
) {
2467 #ifdef CONFIG_WPS_UPNP
2468 if (wps
->wps
->wps_upnp
&&
2469 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2470 if (wps
->wps
->upnp_msgs
)
2471 return WPS_CONTINUE
;
2472 if (wps
->ext_reg
== 0)
2474 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2475 "external Registrar");
2478 #endif /* CONFIG_WPS_UPNP */
2480 wpa_printf(MSG_DEBUG
, "WPS: No more registrars available - "
2481 "terminate negotiation");
2488 static enum wps_process_res
wps_process_wsc_nack(struct wps_data
*wps
,
2489 const struct wpabuf
*msg
)
2491 struct wps_parse_attr attr
;
2494 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_NACK");
2496 old_state
= wps
->state
;
2497 wps
->state
= SEND_WSC_NACK
;
2499 if (wps_parse_msg(msg
, &attr
) < 0)
2502 if (!wps_version_supported(attr
.version
)) {
2503 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2504 attr
.version
? *attr
.version
: 0);
2508 if (attr
.msg_type
== NULL
) {
2509 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2513 if (*attr
.msg_type
!= WPS_WSC_NACK
) {
2514 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2519 #ifdef CONFIG_WPS_UPNP
2520 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2521 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2522 "Registrar terminated by the Enrollee");
2525 #endif /* CONFIG_WPS_UPNP */
2527 if (attr
.registrar_nonce
== NULL
||
2528 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2530 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2534 if (attr
.enrollee_nonce
== NULL
||
2535 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2536 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2540 if (attr
.config_error
== NULL
) {
2541 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error attribute "
2546 wpa_printf(MSG_DEBUG
, "WPS: Enrollee terminated negotiation with "
2547 "Configuration Error %d", WPA_GET_BE16(attr
.config_error
));
2549 switch (old_state
) {
2551 wps_fail_event(wps
->wps
, WPS_M2
);
2554 wps_fail_event(wps
->wps
, WPS_M4
);
2557 wps_fail_event(wps
->wps
, WPS_M6
);
2560 wps_fail_event(wps
->wps
, WPS_M8
);
2570 static enum wps_process_res
wps_process_wsc_done(struct wps_data
*wps
,
2571 const struct wpabuf
*msg
)
2573 struct wps_parse_attr attr
;
2575 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_Done");
2577 if (wps
->state
!= RECV_DONE
&&
2578 (!wps
->wps
->wps_upnp
|| !wps
->ext_reg
)) {
2579 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2580 "receiving WSC_Done", wps
->state
);
2584 if (wps_parse_msg(msg
, &attr
) < 0)
2587 if (!wps_version_supported(attr
.version
)) {
2588 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2589 attr
.version
? *attr
.version
: 0);
2593 if (attr
.msg_type
== NULL
) {
2594 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2598 if (*attr
.msg_type
!= WPS_WSC_DONE
) {
2599 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2604 #ifdef CONFIG_WPS_UPNP
2605 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2606 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2607 "Registrar completed successfully");
2608 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2612 #endif /* CONFIG_WPS_UPNP */
2614 if (attr
.registrar_nonce
== NULL
||
2615 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2617 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2621 if (attr
.enrollee_nonce
== NULL
||
2622 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2623 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2627 wpa_printf(MSG_DEBUG
, "WPS: Negotiation completed successfully");
2628 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2631 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->new_psk
&&
2632 wps
->wps
->ap
&& !wps
->wps
->registrar
->disable_auto_conf
) {
2633 struct wps_credential cred
;
2635 wpa_printf(MSG_DEBUG
, "WPS: Moving to Configured state based "
2636 "on first Enrollee connection");
2638 os_memset(&cred
, 0, sizeof(cred
));
2639 os_memcpy(cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
2640 cred
.ssid_len
= wps
->wps
->ssid_len
;
2641 cred
.auth_type
= WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
;
2642 cred
.encr_type
= WPS_ENCR_TKIP
| WPS_ENCR_AES
;
2643 os_memcpy(cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
2644 cred
.key_len
= wps
->new_psk_len
;
2646 wps
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
2647 wpa_hexdump_ascii_key(MSG_DEBUG
,
2648 "WPS: Generated random passphrase",
2649 wps
->new_psk
, wps
->new_psk_len
);
2650 if (wps
->wps
->cred_cb
)
2651 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &cred
);
2653 os_free(wps
->new_psk
);
2654 wps
->new_psk
= NULL
;
2657 if (!wps
->wps
->ap
&& !wps
->er
)
2658 wps_sta_cred_cb(wps
);
2661 if (wps_cb_new_psk(wps
->wps
->registrar
, wps
->mac_addr_e
,
2662 wps
->new_psk
, wps
->new_psk_len
)) {
2663 wpa_printf(MSG_DEBUG
, "WPS: Failed to configure the "
2666 os_free(wps
->new_psk
);
2667 wps
->new_psk
= NULL
;
2670 wps_cb_reg_success(wps
->wps
->registrar
, wps
->mac_addr_e
, wps
->uuid_e
);
2673 wps_registrar_remove_pbc_session(wps
->wps
->registrar
,
2674 wps
->mac_addr_e
, wps
->uuid_e
);
2675 wps_registrar_pbc_completed(wps
->wps
->registrar
);
2677 wps_registrar_pin_completed(wps
->wps
->registrar
);
2680 wps_success_event(wps
->wps
);
2686 enum wps_process_res
wps_registrar_process_msg(struct wps_data
*wps
,
2687 enum wsc_op_code op_code
,
2688 const struct wpabuf
*msg
)
2690 enum wps_process_res ret
;
2692 wpa_printf(MSG_DEBUG
, "WPS: Processing received message (len=%lu "
2694 (unsigned long) wpabuf_len(msg
), op_code
);
2696 #ifdef CONFIG_WPS_UPNP
2697 if (wps
->wps
->wps_upnp
&& op_code
== WSC_MSG
&& wps
->ext_reg
== 1) {
2698 struct wps_parse_attr attr
;
2699 if (wps_parse_msg(msg
, &attr
) == 0 && attr
.msg_type
&&
2700 *attr
.msg_type
== WPS_M3
)
2701 wps
->ext_reg
= 2; /* past M2/M2D phase */
2703 if (wps
->ext_reg
> 1)
2704 wps_registrar_free_pending_m2(wps
->wps
);
2705 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&&
2706 wps
->wps
->upnp_msgs
== NULL
&&
2707 (op_code
== WSC_MSG
|| op_code
== WSC_Done
|| op_code
== WSC_NACK
))
2709 struct wps_parse_attr attr
;
2711 if (wps_parse_msg(msg
, &attr
) < 0 || attr
.msg_type
== NULL
)
2714 type
= *attr
.msg_type
;
2715 wpa_printf(MSG_DEBUG
, "WPS: Sending received message (type %d)"
2716 " to external Registrar for processing", type
);
2717 upnp_wps_device_send_wlan_event(wps
->wps
->wps_upnp
,
2719 UPNP_WPS_WLANEVENT_TYPE_EAP
,
2721 if (op_code
== WSC_MSG
)
2723 } else if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& op_code
== WSC_MSG
) {
2724 wpa_printf(MSG_DEBUG
, "WPS: Skip internal processing - using "
2725 "external Registrar");
2726 return WPS_CONTINUE
;
2728 #endif /* CONFIG_WPS_UPNP */
2732 return wps_process_wsc_msg(wps
, msg
);
2734 return wps_process_wsc_ack(wps
, msg
);
2736 return wps_process_wsc_nack(wps
, msg
);
2738 ret
= wps_process_wsc_done(wps
, msg
);
2739 if (ret
== WPS_FAILURE
) {
2740 wps
->state
= SEND_WSC_NACK
;
2741 wps_fail_event(wps
->wps
, WPS_WSC_DONE
);
2745 wpa_printf(MSG_DEBUG
, "WPS: Unsupported op_code %d", op_code
);
2751 int wps_registrar_update_ie(struct wps_registrar
*reg
)
2753 return wps_set_ie(reg
);
2757 static void wps_registrar_set_selected_timeout(void *eloop_ctx
,
2760 struct wps_registrar
*reg
= eloop_ctx
;
2762 wpa_printf(MSG_DEBUG
, "WPS: Selected Registrar timeout - "
2763 "unselect internal Registrar");
2764 reg
->selected_registrar
= 0;
2766 wps_registrar_selected_registrar_changed(reg
);
2770 #ifdef CONFIG_WPS_UPNP
2771 static void wps_registrar_sel_reg_add(struct wps_registrar
*reg
,
2772 struct subscription
*s
)
2774 wpa_printf(MSG_DEBUG
, "WPS: External Registrar selected (dev_pw_id=%d "
2775 "config_methods=0x%x)",
2776 s
->dev_password_id
, s
->config_methods
);
2777 reg
->sel_reg_union
= 1;
2778 if (reg
->sel_reg_dev_password_id_override
!= DEV_PW_PUSHBUTTON
)
2779 reg
->sel_reg_dev_password_id_override
= s
->dev_password_id
;
2780 if (reg
->sel_reg_config_methods_override
== -1)
2781 reg
->sel_reg_config_methods_override
= 0;
2782 reg
->sel_reg_config_methods_override
|= s
->config_methods
;
2784 #endif /* CONFIG_WPS_UPNP */
2787 static void wps_registrar_sel_reg_union(struct wps_registrar
*reg
)
2789 #ifdef CONFIG_WPS_UPNP
2790 struct subscription
*s
;
2792 if (reg
->wps
->wps_upnp
== NULL
)
2795 dl_list_for_each(s
, ®
->wps
->wps_upnp
->subscriptions
,
2796 struct subscription
, list
) {
2797 struct subscr_addr
*sa
;
2798 sa
= dl_list_first(&s
->addr_list
, struct subscr_addr
, list
);
2800 wpa_printf(MSG_DEBUG
, "WPS: External Registrar %s:%d",
2801 inet_ntoa(sa
->saddr
.sin_addr
),
2802 ntohs(sa
->saddr
.sin_port
));
2804 if (s
->selected_registrar
)
2805 wps_registrar_sel_reg_add(reg
, s
);
2807 wpa_printf(MSG_DEBUG
, "WPS: External Registrar not "
2810 #endif /* CONFIG_WPS_UPNP */
2815 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
2816 * @reg: Registrar data from wps_registrar_init()
2818 * This function is called when selected registrar state changes, e.g., when an
2819 * AP receives a SetSelectedRegistrar UPnP message.
2821 void wps_registrar_selected_registrar_changed(struct wps_registrar
*reg
)
2823 wpa_printf(MSG_DEBUG
, "WPS: Selected registrar information changed");
2825 reg
->sel_reg_union
= reg
->selected_registrar
;
2826 reg
->sel_reg_dev_password_id_override
= -1;
2827 reg
->sel_reg_config_methods_override
= -1;
2828 if (reg
->selected_registrar
) {
2829 reg
->sel_reg_config_methods_override
=
2830 reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
2832 reg
->sel_reg_dev_password_id_override
=
2834 reg
->sel_reg_config_methods_override
|=
2835 WPS_CONFIG_PUSHBUTTON
;
2837 wpa_printf(MSG_DEBUG
, "WPS: Internal Registrar selected "
2838 "(pbc=%d)", reg
->pbc
);
2840 wpa_printf(MSG_DEBUG
, "WPS: Internal Registrar not selected");
2842 wps_registrar_sel_reg_union(reg
);
2845 wps_cb_set_sel_reg(reg
);
2849 int wps_registrar_get_info(struct wps_registrar
*reg
, const u8
*addr
,
2850 char *buf
, size_t buflen
)
2852 struct wps_registrar_device
*d
;
2855 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
2857 d
= wps_device_get(reg
, addr
);
2860 if (uuid_bin2str(d
->uuid
, uuid
, sizeof(uuid
)))
2863 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2865 "wpsPrimaryDeviceType=%s\n"
2866 "wpsDeviceName=%s\n"
2867 "wpsManufacturer=%s\n"
2869 "wpsModelNumber=%s\n"
2870 "wpsSerialNumber=%s\n",
2872 wps_dev_type_bin2str(d
->dev
.pri_dev_type
, devtype
,
2874 d
->dev
.device_name
? d
->dev
.device_name
: "",
2875 d
->dev
.manufacturer
? d
->dev
.manufacturer
: "",
2876 d
->dev
.model_name
? d
->dev
.model_name
: "",
2877 d
->dev
.model_number
? d
->dev
.model_number
: "",
2878 d
->dev
.serial_number
? d
->dev
.serial_number
: "");
2879 if (ret
< 0 || (size_t) ret
>= buflen
- len
)