2 * hostapd / WPS integration
3 * Copyright (c) 2008, 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.
21 #include "common/wpa_ctrl.h"
22 #include "common/ieee802_11_defs.h"
23 #include "common/ieee802_11_common.h"
27 #include "wps/wps_defs.h"
28 #include "wps/wps_dev_attr.h"
29 #include "wps_hostapd.h"
30 #include "dh_groups.h"
33 #ifdef CONFIG_WPS_UPNP
34 #include "wps/wps_upnp.h"
35 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
36 struct wps_context
*wps
);
37 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
);
38 #endif /* CONFIG_WPS_UPNP */
40 static void hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
41 const u8
*ie
, size_t ie_len
);
44 static int hostapd_wps_new_psk_cb(void *ctx
, const u8
*mac_addr
, const u8
*psk
,
47 struct hostapd_data
*hapd
= ctx
;
48 struct hostapd_wpa_psk
*p
;
49 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
51 wpa_printf(MSG_DEBUG
, "Received new WPA/WPA2-PSK from WPS for STA "
52 MACSTR
, MAC2STR(mac_addr
));
53 wpa_hexdump_key(MSG_DEBUG
, "Per-device PSK", psk
, psk_len
);
55 if (psk_len
!= PMK_LEN
) {
56 wpa_printf(MSG_DEBUG
, "Unexpected PSK length %lu",
57 (unsigned long) psk_len
);
61 /* Add the new PSK to runtime PSK list */
62 p
= os_zalloc(sizeof(*p
));
65 os_memcpy(p
->addr
, mac_addr
, ETH_ALEN
);
66 os_memcpy(p
->psk
, psk
, PMK_LEN
);
68 p
->next
= ssid
->wpa_psk
;
71 if (ssid
->wpa_psk_file
) {
73 char hex
[PMK_LEN
* 2 + 1];
74 /* Add the new PSK to PSK list file */
75 f
= fopen(ssid
->wpa_psk_file
, "a");
77 wpa_printf(MSG_DEBUG
, "Failed to add the PSK to "
78 "'%s'", ssid
->wpa_psk_file
);
82 wpa_snprintf_hex(hex
, sizeof(hex
), psk
, psk_len
);
83 fprintf(f
, MACSTR
" %s\n", MAC2STR(mac_addr
), hex
);
91 static int hostapd_wps_set_ie_cb(void *ctx
, const u8
*beacon_ie
,
92 size_t beacon_ie_len
, const u8
*probe_resp_ie
,
93 size_t probe_resp_ie_len
)
95 struct hostapd_data
*hapd
= ctx
;
97 os_free(hapd
->wps_beacon_ie
);
98 if (beacon_ie_len
== 0) {
99 hapd
->wps_beacon_ie
= NULL
;
100 hapd
->wps_beacon_ie_len
= 0;
102 hapd
->wps_beacon_ie
= os_malloc(beacon_ie_len
);
103 if (hapd
->wps_beacon_ie
== NULL
) {
104 hapd
->wps_beacon_ie_len
= 0;
107 os_memcpy(hapd
->wps_beacon_ie
, beacon_ie
, beacon_ie_len
);
108 hapd
->wps_beacon_ie_len
= beacon_ie_len
;
110 hostapd_set_wps_beacon_ie(hapd
, hapd
->wps_beacon_ie
,
111 hapd
->wps_beacon_ie_len
);
113 os_free(hapd
->wps_probe_resp_ie
);
114 if (probe_resp_ie_len
== 0) {
115 hapd
->wps_probe_resp_ie
= NULL
;
116 hapd
->wps_probe_resp_ie_len
= 0;
118 hapd
->wps_probe_resp_ie
= os_malloc(probe_resp_ie_len
);
119 if (hapd
->wps_probe_resp_ie
== NULL
) {
120 hapd
->wps_probe_resp_ie_len
= 0;
123 os_memcpy(hapd
->wps_probe_resp_ie
, probe_resp_ie
,
125 hapd
->wps_probe_resp_ie_len
= probe_resp_ie_len
;
127 hostapd_set_wps_probe_resp_ie(hapd
, hapd
->wps_probe_resp_ie
,
128 hapd
->wps_probe_resp_ie_len
);
134 static void hostapd_wps_pin_needed_cb(void *ctx
, const u8
*uuid_e
,
135 const struct wps_device_data
*dev
)
137 struct hostapd_data
*hapd
= ctx
;
138 char uuid
[40], txt
[400];
140 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
141 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
143 wpa_printf(MSG_DEBUG
, "WPS: PIN needed for E-UUID %s", uuid
);
144 len
= os_snprintf(txt
, sizeof(txt
), WPS_EVENT_PIN_NEEDED
145 "%s " MACSTR
" [%s|%s|%s|%s|%s|%s]",
146 uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
147 dev
->manufacturer
, dev
->model_name
,
148 dev
->model_number
, dev
->serial_number
,
149 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
151 if (len
> 0 && len
< (int) sizeof(txt
))
152 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s", txt
);
154 if (hapd
->conf
->wps_pin_requests
) {
157 f
= fopen(hapd
->conf
->wps_pin_requests
, "a");
161 fprintf(f
, "%ld\t%s\t" MACSTR
"\t%s\t%s\t%s\t%s\t%s"
163 t
.sec
, uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
164 dev
->manufacturer
, dev
->model_name
, dev
->model_number
,
166 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
173 static void hostapd_wps_reg_success_cb(void *ctx
, const u8
*mac_addr
,
176 struct hostapd_data
*hapd
= ctx
;
178 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
180 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_REG_SUCCESS MACSTR
" %s",
181 MAC2STR(mac_addr
), uuid
);
185 static int str_starts(const char *str
, const char *start
)
187 return os_strncmp(str
, start
, os_strlen(start
)) == 0;
191 static void wps_reload_config(void *eloop_data
, void *user_ctx
)
193 struct hostapd_iface
*iface
= eloop_data
;
195 wpa_printf(MSG_DEBUG
, "WPS: Reload configuration data");
196 if (hostapd_reload_config(iface
) < 0) {
197 wpa_printf(MSG_WARNING
, "WPS: Failed to reload the updated "
203 static int hostapd_wps_cred_cb(void *ctx
, const struct wps_credential
*cred
)
205 struct hostapd_data
*hapd
= ctx
;
213 wpa_hexdump_key(MSG_DEBUG
, "WPS: Received Credential attribute",
214 cred
->cred_attr
, cred
->cred_attr_len
);
216 wpa_printf(MSG_DEBUG
, "WPS: Received new AP Settings");
217 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: SSID", cred
->ssid
, cred
->ssid_len
);
218 wpa_printf(MSG_DEBUG
, "WPS: Authentication Type 0x%x",
220 wpa_printf(MSG_DEBUG
, "WPS: Encryption Type 0x%x", cred
->encr_type
);
221 wpa_printf(MSG_DEBUG
, "WPS: Network Key Index %d", cred
->key_idx
);
222 wpa_hexdump_key(MSG_DEBUG
, "WPS: Network Key",
223 cred
->key
, cred
->key_len
);
224 wpa_printf(MSG_DEBUG
, "WPS: MAC Address " MACSTR
,
225 MAC2STR(cred
->mac_addr
));
227 if ((hapd
->conf
->wps_cred_processing
== 1 ||
228 hapd
->conf
->wps_cred_processing
== 2) && cred
->cred_attr
) {
229 size_t blen
= cred
->cred_attr_len
* 2 + 1;
230 char *_buf
= os_malloc(blen
);
232 wpa_snprintf_hex(_buf
, blen
,
233 cred
->cred_attr
, cred
->cred_attr_len
);
234 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s%s",
235 WPS_EVENT_NEW_AP_SETTINGS
, _buf
);
239 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_NEW_AP_SETTINGS
);
241 if (hapd
->conf
->wps_cred_processing
== 1)
244 os_memcpy(hapd
->wps
->ssid
, cred
->ssid
, cred
->ssid_len
);
245 hapd
->wps
->ssid_len
= cred
->ssid_len
;
246 hapd
->wps
->encr_types
= cred
->encr_type
;
247 hapd
->wps
->auth_types
= cred
->auth_type
;
248 if (cred
->key_len
== 0) {
249 os_free(hapd
->wps
->network_key
);
250 hapd
->wps
->network_key
= NULL
;
251 hapd
->wps
->network_key_len
= 0;
253 if (hapd
->wps
->network_key
== NULL
||
254 hapd
->wps
->network_key_len
< cred
->key_len
) {
255 hapd
->wps
->network_key_len
= 0;
256 os_free(hapd
->wps
->network_key
);
257 hapd
->wps
->network_key
= os_malloc(cred
->key_len
);
258 if (hapd
->wps
->network_key
== NULL
)
261 hapd
->wps
->network_key_len
= cred
->key_len
;
262 os_memcpy(hapd
->wps
->network_key
, cred
->key
, cred
->key_len
);
264 hapd
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
266 len
= os_strlen(hapd
->iface
->config_fname
) + 5;
267 tmp_fname
= os_malloc(len
);
268 if (tmp_fname
== NULL
)
270 os_snprintf(tmp_fname
, len
, "%s-new", hapd
->iface
->config_fname
);
272 oconf
= fopen(hapd
->iface
->config_fname
, "r");
274 wpa_printf(MSG_WARNING
, "WPS: Could not open current "
275 "configuration file");
280 nconf
= fopen(tmp_fname
, "w");
282 wpa_printf(MSG_WARNING
, "WPS: Could not write updated "
283 "configuration file");
289 fprintf(nconf
, "# WPS configuration - START\n");
291 fprintf(nconf
, "wps_state=2\n");
293 fprintf(nconf
, "ssid=");
294 for (i
= 0; i
< cred
->ssid_len
; i
++)
295 fputc(cred
->ssid
[i
], nconf
);
296 fprintf(nconf
, "\n");
298 if ((cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
)) &&
299 (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
)))
301 else if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
))
303 else if (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
))
310 fprintf(nconf
, "wpa=%d\n", wpa
);
312 fprintf(nconf
, "wpa_key_mgmt=");
314 if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA
)) {
315 fprintf(nconf
, "WPA-EAP");
318 if (cred
->auth_type
& (WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
))
319 fprintf(nconf
, "%sWPA-PSK", prefix
);
320 fprintf(nconf
, "\n");
322 fprintf(nconf
, "wpa_pairwise=");
324 if (cred
->encr_type
& WPS_ENCR_AES
) {
325 fprintf(nconf
, "CCMP");
328 if (cred
->encr_type
& WPS_ENCR_TKIP
) {
329 fprintf(nconf
, "%sTKIP", prefix
);
331 fprintf(nconf
, "\n");
333 if (cred
->key_len
>= 8 && cred
->key_len
< 64) {
334 fprintf(nconf
, "wpa_passphrase=");
335 for (i
= 0; i
< cred
->key_len
; i
++)
336 fputc(cred
->key
[i
], nconf
);
337 fprintf(nconf
, "\n");
338 } else if (cred
->key_len
== 64) {
339 fprintf(nconf
, "wpa_psk=");
340 for (i
= 0; i
< cred
->key_len
; i
++)
341 fputc(cred
->key
[i
], nconf
);
342 fprintf(nconf
, "\n");
344 wpa_printf(MSG_WARNING
, "WPS: Invalid key length %lu "
346 (unsigned long) cred
->key_len
);
349 fprintf(nconf
, "auth_algs=1\n");
351 if ((cred
->auth_type
& WPS_AUTH_OPEN
) &&
352 (cred
->auth_type
& WPS_AUTH_SHARED
))
353 fprintf(nconf
, "auth_algs=3\n");
354 else if (cred
->auth_type
& WPS_AUTH_SHARED
)
355 fprintf(nconf
, "auth_algs=2\n");
357 fprintf(nconf
, "auth_algs=1\n");
359 if (cred
->encr_type
& WPS_ENCR_WEP
&& cred
->key_idx
<= 4) {
360 int key_idx
= cred
->key_idx
;
363 fprintf(nconf
, "wep_default_key=%d\n", key_idx
);
364 fprintf(nconf
, "wep_key%d=", key_idx
);
365 if (cred
->key_len
== 10 || cred
->key_len
== 26) {
366 /* WEP key as a hex string */
367 for (i
= 0; i
< cred
->key_len
; i
++)
368 fputc(cred
->key
[i
], nconf
);
370 /* Raw WEP key; convert to hex */
371 for (i
= 0; i
< cred
->key_len
; i
++)
372 fprintf(nconf
, "%02x", cred
->key
[i
]);
374 fprintf(nconf
, "\n");
378 fprintf(nconf
, "# WPS configuration - END\n");
381 while (fgets(buf
, sizeof(buf
), oconf
)) {
382 if (os_strncmp(buf
, "bss=", 4) == 0)
385 (str_starts(buf
, "ssid=") ||
386 str_starts(buf
, "auth_algs=") ||
387 str_starts(buf
, "wps_state=") ||
388 str_starts(buf
, "wpa=") ||
389 str_starts(buf
, "wpa_psk=") ||
390 str_starts(buf
, "wpa_pairwise=") ||
391 str_starts(buf
, "rsn_pairwise=") ||
392 str_starts(buf
, "wpa_key_mgmt=") ||
393 str_starts(buf
, "wpa_passphrase="))) {
394 fprintf(nconf
, "#WPS# %s", buf
);
396 fprintf(nconf
, "%s", buf
);
402 if (rename(tmp_fname
, hapd
->iface
->config_fname
) < 0) {
403 wpa_printf(MSG_WARNING
, "WPS: Failed to rename the updated "
404 "configuration file: %s", strerror(errno
));
411 /* Schedule configuration reload after short period of time to allow
412 * EAP-WSC to be finished.
414 eloop_register_timeout(0, 100000, wps_reload_config
, hapd
->iface
,
417 /* TODO: dualband AP may need to update multiple configuration files */
419 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
425 static void hostapd_pwd_auth_fail(struct hostapd_data
*hapd
,
426 struct wps_event_pwd_auth_fail
*data
)
434 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
435 * if this happens multiple times.
437 hapd
->ap_pin_failures
++;
438 if (hapd
->ap_pin_failures
< 4)
441 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_LOCKED
);
442 hapd
->wps
->ap_setup_locked
= 1;
444 wps_registrar_update_ie(hapd
->wps
->registrar
);
446 if (hapd
->conf
->wps_cred_processing
== 1)
449 f
= fopen(hapd
->iface
->config_fname
, "a");
451 wpa_printf(MSG_WARNING
, "WPS: Could not append to the current "
452 "configuration file");
456 fprintf(f
, "# WPS AP Setup Locked based on possible attack\n");
457 fprintf(f
, "ap_setup_locked=1\n");
460 /* TODO: dualband AP may need to update multiple configuration files */
462 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
466 static void hostapd_wps_event_cb(void *ctx
, enum wps_event event
,
467 union wps_event_data
*data
)
469 struct hostapd_data
*hapd
= ctx
;
471 if (event
== WPS_EV_PWD_AUTH_FAIL
)
472 hostapd_pwd_auth_fail(hapd
, &data
->pwd_auth_fail
);
476 static void hostapd_wps_clear_ies(struct hostapd_data
*hapd
)
478 os_free(hapd
->wps_beacon_ie
);
479 hapd
->wps_beacon_ie
= NULL
;
480 hapd
->wps_beacon_ie_len
= 0;
481 hostapd_set_wps_beacon_ie(hapd
, NULL
, 0);
483 os_free(hapd
->wps_probe_resp_ie
);
484 hapd
->wps_probe_resp_ie
= NULL
;
485 hapd
->wps_probe_resp_ie_len
= 0;
486 hostapd_set_wps_probe_resp_ie(hapd
, NULL
, 0);
490 int hostapd_init_wps(struct hostapd_data
*hapd
,
491 struct hostapd_bss_config
*conf
)
493 struct wps_context
*wps
;
494 struct wps_registrar_config cfg
;
496 if (conf
->wps_state
== 0) {
497 hostapd_wps_clear_ies(hapd
);
501 wps
= os_zalloc(sizeof(*wps
));
505 wps
->cred_cb
= hostapd_wps_cred_cb
;
506 wps
->event_cb
= hostapd_wps_event_cb
;
509 os_memset(&cfg
, 0, sizeof(cfg
));
510 wps
->wps_state
= hapd
->conf
->wps_state
;
511 wps
->ap_setup_locked
= hapd
->conf
->ap_setup_locked
;
512 if (is_nil_uuid(hapd
->conf
->uuid
)) {
513 uuid_gen_mac_addr(hapd
->own_addr
, wps
->uuid
);
514 wpa_hexdump(MSG_DEBUG
, "WPS: UUID based on MAC address",
515 wps
->uuid
, UUID_LEN
);
517 os_memcpy(wps
->uuid
, hapd
->conf
->uuid
, UUID_LEN
);
518 wps
->ssid_len
= hapd
->conf
->ssid
.ssid_len
;
519 os_memcpy(wps
->ssid
, hapd
->conf
->ssid
.ssid
, wps
->ssid_len
);
521 os_memcpy(wps
->dev
.mac_addr
, hapd
->own_addr
, ETH_ALEN
);
522 wps
->dev
.device_name
= hapd
->conf
->device_name
?
523 os_strdup(hapd
->conf
->device_name
) : NULL
;
524 wps
->dev
.manufacturer
= hapd
->conf
->manufacturer
?
525 os_strdup(hapd
->conf
->manufacturer
) : NULL
;
526 wps
->dev
.model_name
= hapd
->conf
->model_name
?
527 os_strdup(hapd
->conf
->model_name
) : NULL
;
528 wps
->dev
.model_number
= hapd
->conf
->model_number
?
529 os_strdup(hapd
->conf
->model_number
) : NULL
;
530 wps
->dev
.serial_number
= hapd
->conf
->serial_number
?
531 os_strdup(hapd
->conf
->serial_number
) : NULL
;
532 if (hapd
->conf
->config_methods
) {
533 char *m
= hapd
->conf
->config_methods
;
534 if (os_strstr(m
, "label"))
535 wps
->config_methods
|= WPS_CONFIG_LABEL
;
536 if (os_strstr(m
, "display"))
537 wps
->config_methods
|= WPS_CONFIG_DISPLAY
;
538 if (os_strstr(m
, "push_button"))
539 wps
->config_methods
|= WPS_CONFIG_PUSHBUTTON
;
540 if (os_strstr(m
, "keypad"))
541 wps
->config_methods
|= WPS_CONFIG_KEYPAD
;
543 if (hapd
->conf
->device_type
&&
544 wps_dev_type_str2bin(hapd
->conf
->device_type
,
545 wps
->dev
.pri_dev_type
) < 0) {
546 wpa_printf(MSG_ERROR
, "WPS: Invalid device_type");
550 wps
->dev
.os_version
= WPA_GET_BE32(hapd
->conf
->os_version
);
551 wps
->dev
.rf_bands
= hapd
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211A
?
552 WPS_RF_50GHZ
: WPS_RF_24GHZ
; /* FIX: dualband AP */
554 if (conf
->wpa
& WPA_PROTO_RSN
) {
555 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
556 wps
->auth_types
|= WPS_AUTH_WPA2PSK
;
557 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
558 wps
->auth_types
|= WPS_AUTH_WPA2
;
560 if (conf
->rsn_pairwise
& WPA_CIPHER_CCMP
)
561 wps
->encr_types
|= WPS_ENCR_AES
;
562 if (conf
->rsn_pairwise
& WPA_CIPHER_TKIP
)
563 wps
->encr_types
|= WPS_ENCR_TKIP
;
566 if (conf
->wpa
& WPA_PROTO_WPA
) {
567 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
568 wps
->auth_types
|= WPS_AUTH_WPAPSK
;
569 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
570 wps
->auth_types
|= WPS_AUTH_WPA
;
572 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
573 wps
->encr_types
|= WPS_ENCR_AES
;
574 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
575 wps
->encr_types
|= WPS_ENCR_TKIP
;
578 if (conf
->ssid
.security_policy
== SECURITY_PLAINTEXT
) {
579 wps
->encr_types
|= WPS_ENCR_NONE
;
580 wps
->auth_types
|= WPS_AUTH_OPEN
;
581 } else if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
582 wps
->encr_types
|= WPS_ENCR_WEP
;
583 if (conf
->auth_algs
& WPA_AUTH_ALG_OPEN
)
584 wps
->auth_types
|= WPS_AUTH_OPEN
;
585 if (conf
->auth_algs
& WPA_AUTH_ALG_SHARED
)
586 wps
->auth_types
|= WPS_AUTH_SHARED
;
587 } else if (conf
->ssid
.security_policy
== SECURITY_IEEE_802_1X
) {
588 wps
->auth_types
|= WPS_AUTH_OPEN
;
589 if (conf
->default_wep_key_len
)
590 wps
->encr_types
|= WPS_ENCR_WEP
;
592 wps
->encr_types
|= WPS_ENCR_NONE
;
595 if (conf
->ssid
.wpa_psk_file
) {
596 /* Use per-device PSKs */
597 } else if (conf
->ssid
.wpa_passphrase
) {
598 wps
->network_key
= (u8
*) os_strdup(conf
->ssid
.wpa_passphrase
);
599 wps
->network_key_len
= os_strlen(conf
->ssid
.wpa_passphrase
);
600 } else if (conf
->ssid
.wpa_psk
) {
601 wps
->network_key
= os_malloc(2 * PMK_LEN
+ 1);
602 if (wps
->network_key
== NULL
) {
606 wpa_snprintf_hex((char *) wps
->network_key
, 2 * PMK_LEN
+ 1,
607 conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
608 wps
->network_key_len
= 2 * PMK_LEN
;
609 } else if (conf
->ssid
.wep
.keys_set
&& conf
->ssid
.wep
.key
[0]) {
610 wps
->network_key
= os_malloc(conf
->ssid
.wep
.len
[0]);
611 if (wps
->network_key
== NULL
) {
615 os_memcpy(wps
->network_key
, conf
->ssid
.wep
.key
[0],
616 conf
->ssid
.wep
.len
[0]);
617 wps
->network_key_len
= conf
->ssid
.wep
.len
[0];
620 if (conf
->wps_state
== WPS_STATE_NOT_CONFIGURED
) {
621 /* Override parameters to enable security by default */
622 wps
->auth_types
= WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
;
623 wps
->encr_types
= WPS_ENCR_AES
| WPS_ENCR_TKIP
;
626 wps
->ap_settings
= conf
->ap_settings
;
627 wps
->ap_settings_len
= conf
->ap_settings_len
;
629 cfg
.new_psk_cb
= hostapd_wps_new_psk_cb
;
630 cfg
.set_ie_cb
= hostapd_wps_set_ie_cb
;
631 cfg
.pin_needed_cb
= hostapd_wps_pin_needed_cb
;
632 cfg
.reg_success_cb
= hostapd_wps_reg_success_cb
;
634 cfg
.skip_cred_build
= conf
->skip_cred_build
;
635 cfg
.extra_cred
= conf
->extra_cred
;
636 cfg
.extra_cred_len
= conf
->extra_cred_len
;
637 cfg
.disable_auto_conf
= (hapd
->conf
->wps_cred_processing
== 1) &&
638 conf
->skip_cred_build
;
639 if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
)
640 cfg
.static_wep_only
= 1;
642 wps
->registrar
= wps_registrar_init(wps
, &cfg
);
643 if (wps
->registrar
== NULL
) {
644 printf("Failed to initialize WPS Registrar\n");
645 os_free(wps
->network_key
);
650 #ifdef CONFIG_WPS_UPNP
651 wps
->friendly_name
= hapd
->conf
->friendly_name
;
652 wps
->manufacturer_url
= hapd
->conf
->manufacturer_url
;
653 wps
->model_description
= hapd
->conf
->model_description
;
654 wps
->model_url
= hapd
->conf
->model_url
;
655 wps
->upc
= hapd
->conf
->upc
;
657 if (hostapd_wps_upnp_init(hapd
, wps
) < 0) {
658 wpa_printf(MSG_ERROR
, "Failed to initialize WPS UPnP");
659 wps_registrar_deinit(wps
->registrar
);
660 os_free(wps
->network_key
);
664 #endif /* CONFIG_WPS_UPNP */
666 hostapd_register_probereq_cb(hapd
, hostapd_wps_probe_req_rx
, hapd
);
674 void hostapd_deinit_wps(struct hostapd_data
*hapd
)
676 if (hapd
->wps
== NULL
)
678 #ifdef CONFIG_WPS_UPNP
679 hostapd_wps_upnp_deinit(hapd
);
680 #endif /* CONFIG_WPS_UPNP */
681 wps_registrar_deinit(hapd
->wps
->registrar
);
682 os_free(hapd
->wps
->network_key
);
683 wps_device_data_free(&hapd
->wps
->dev
);
684 wpabuf_free(hapd
->wps
->dh_pubkey
);
685 wpabuf_free(hapd
->wps
->dh_privkey
);
686 wpabuf_free(hapd
->wps
->oob_conf
.pubkey_hash
);
687 wpabuf_free(hapd
->wps
->oob_conf
.dev_password
);
688 wps_free_pending_msgs(hapd
->wps
->upnp_msgs
);
691 hostapd_wps_clear_ies(hapd
);
695 int hostapd_wps_add_pin(struct hostapd_data
*hapd
, const char *uuid
,
696 const char *pin
, int timeout
)
701 if (hapd
->wps
== NULL
)
703 if (os_strcmp(uuid
, "any") == 0)
705 else if (uuid_str2bin(uuid
, u
))
707 return wps_registrar_add_pin(hapd
->wps
->registrar
, any
? NULL
: u
,
708 (const u8
*) pin
, os_strlen(pin
),
713 int hostapd_wps_button_pushed(struct hostapd_data
*hapd
)
715 if (hapd
->wps
== NULL
)
717 return wps_registrar_button_pushed(hapd
->wps
->registrar
);
721 #ifdef CONFIG_WPS_OOB
722 int hostapd_wps_start_oob(struct hostapd_data
*hapd
, char *device_type
,
723 char *path
, char *method
, char *name
)
725 struct wps_context
*wps
= hapd
->wps
;
726 struct oob_device_data
*oob_dev
;
728 oob_dev
= wps_get_oob_device(device_type
);
731 oob_dev
->device_path
= path
;
732 oob_dev
->device_name
= name
;
733 wps
->oob_conf
.oob_method
= wps_get_oob_method(method
);
735 if (wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) {
737 * Use pre-configured DH keys in order to be able to write the
738 * key hash into the OOB file.
740 wpabuf_free(wps
->dh_pubkey
);
741 wpabuf_free(wps
->dh_privkey
);
742 wps
->dh_privkey
= NULL
;
743 wps
->dh_pubkey
= dh_init(dh_groups_get(WPS_DH_GROUP
),
745 wps
->dh_pubkey
= wpabuf_zeropad(wps
->dh_pubkey
, 192);
746 if (wps
->dh_pubkey
== NULL
) {
747 wpa_printf(MSG_ERROR
, "WPS: Failed to initialize "
748 "Diffie-Hellman handshake");
753 if (wps_process_oob(wps
, oob_dev
, 1) < 0)
756 if ((wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_E
||
757 wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) &&
758 hostapd_wps_add_pin(hapd
, "any",
759 wpabuf_head(wps
->oob_conf
.dev_password
), 0) <
766 wpabuf_free(wps
->dh_pubkey
);
767 wps
->dh_pubkey
= NULL
;
768 wpabuf_free(wps
->dh_privkey
);
769 wps
->dh_privkey
= NULL
;
772 #endif /* CONFIG_WPS_OOB */
775 static void hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
776 const u8
*ie
, size_t ie_len
)
778 struct hostapd_data
*hapd
= ctx
;
779 struct wpabuf
*wps_ie
;
781 if (hapd
->wps
== NULL
)
784 wps_ie
= ieee802_11_vendor_ie_concat(ie
, ie_len
, WPS_DEV_OUI_WFA
);
788 if (wpabuf_len(wps_ie
) > 0) {
789 wps_registrar_probe_req_rx(hapd
->wps
->registrar
, addr
, wps_ie
);
790 #ifdef CONFIG_WPS_UPNP
791 /* FIX: what exactly should be included in the WLANEvent?
792 * WPS attributes? Full ProbeReq frame? */
793 upnp_wps_device_send_wlan_event(hapd
->wps_upnp
, addr
,
794 UPNP_WPS_WLANEVENT_TYPE_PROBE
,
796 #endif /* CONFIG_WPS_UPNP */
803 #ifdef CONFIG_WPS_UPNP
805 static struct wpabuf
*
806 hostapd_rx_req_get_device_info(void *priv
, struct upnp_wps_peer
*peer
)
808 struct hostapd_data
*hapd
= priv
;
809 struct wps_config cfg
;
810 struct wps_data
*wps
;
811 enum wsc_op_code op_code
;
815 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
816 * registration over UPnP with the AP acting as an Enrollee. It should
817 * be noted that this is frequently used just to get the device data,
818 * i.e., there may not be any intent to actually complete the
823 wps_deinit(peer
->wps
);
825 os_memset(&cfg
, 0, sizeof(cfg
));
827 cfg
.pin
= (u8
*) hapd
->conf
->ap_pin
;
828 cfg
.pin_len
= os_strlen(hapd
->conf
->ap_pin
);
829 wps
= wps_init(&cfg
);
833 m1
= wps_get_msg(wps
, &op_code
);
845 static struct wpabuf
*
846 hostapd_rx_req_put_message(void *priv
, struct upnp_wps_peer
*peer
,
847 const struct wpabuf
*msg
)
849 enum wps_process_res res
;
850 enum wsc_op_code op_code
;
852 /* PutMessage: msg = InMessage, return OutMessage */
853 res
= wps_process_msg(peer
->wps
, WSC_UPnP
, msg
);
854 if (res
== WPS_FAILURE
)
856 return wps_get_msg(peer
->wps
, &op_code
);
860 static int hostapd_rx_req_put_wlan_response(
861 void *priv
, enum upnp_wps_wlanevent_type ev_type
,
862 const u8
*mac_addr
, const struct wpabuf
*msg
,
863 enum wps_msg_type msg_type
)
865 struct hostapd_data
*hapd
= priv
;
866 struct sta_info
*sta
;
867 struct upnp_pending_message
*p
;
869 wpa_printf(MSG_DEBUG
, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
870 MACSTR
, ev_type
, MAC2STR(mac_addr
));
871 wpa_hexdump(MSG_MSGDUMP
, "WPS UPnP: PutWLANResponse NewMessage",
872 wpabuf_head(msg
), wpabuf_len(msg
));
873 if (ev_type
!= UPNP_WPS_WLANEVENT_TYPE_EAP
) {
874 wpa_printf(MSG_DEBUG
, "WPS UPnP: Ignored unexpected "
875 "PutWLANResponse WLANEventType %d", ev_type
);
880 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC
881 * server implementation for delivery to the peer.
884 sta
= ap_get_sta(hapd
, mac_addr
);
887 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
888 * Pick STA that is in an ongoing WPS registration without
889 * checking the MAC address.
891 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found based "
892 "on NewWLANEventMAC; try wildcard match");
893 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
894 if (sta
->eapol_sm
&& (sta
->flags
& WLAN_STA_WPS
))
900 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found");
904 p
= os_zalloc(sizeof(*p
));
907 os_memcpy(p
->addr
, sta
->addr
, ETH_ALEN
);
908 p
->msg
= wpabuf_dup(msg
);
910 p
->next
= hapd
->wps
->upnp_msgs
;
911 hapd
->wps
->upnp_msgs
= p
;
913 return eapol_auth_eap_pending_cb(sta
->eapol_sm
, sta
->eapol_sm
->eap
);
917 static int hostapd_rx_req_set_selected_registrar(void *priv
,
918 const struct wpabuf
*msg
)
920 struct hostapd_data
*hapd
= priv
;
921 return wps_registrar_set_selected_registrar(hapd
->wps
->registrar
, msg
);
925 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
926 struct wps_context
*wps
)
928 struct upnp_wps_device_ctx
*ctx
;
930 if (!hapd
->conf
->upnp_iface
)
932 ctx
= os_zalloc(sizeof(*ctx
));
936 ctx
->rx_req_get_device_info
= hostapd_rx_req_get_device_info
;
937 ctx
->rx_req_put_message
= hostapd_rx_req_put_message
;
938 ctx
->rx_req_put_wlan_response
= hostapd_rx_req_put_wlan_response
;
939 ctx
->rx_req_set_selected_registrar
=
940 hostapd_rx_req_set_selected_registrar
;
942 hapd
->wps_upnp
= upnp_wps_device_init(ctx
, wps
, hapd
);
943 if (hapd
->wps_upnp
== NULL
) {
947 wps
->wps_upnp
= hapd
->wps_upnp
;
949 if (upnp_wps_device_start(hapd
->wps_upnp
, hapd
->conf
->upnp_iface
)) {
950 upnp_wps_device_deinit(hapd
->wps_upnp
);
951 hapd
->wps_upnp
= NULL
;
959 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
)
961 upnp_wps_device_deinit(hapd
->wps_upnp
);
964 #endif /* CONFIG_WPS_UPNP */
967 int hostapd_wps_get_mib_sta(struct hostapd_data
*hapd
, const u8
*addr
,
968 char *buf
, size_t buflen
)
970 return wps_registrar_get_info(hapd
->wps
->registrar
, addr
, buf
, buflen
);