2 * hostapd / WPS integration
3 * Copyright (c) 2008-2010, 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/eloop.h"
19 #include "utils/uuid.h"
20 #include "crypto/dh_groups.h"
21 #include "common/wpa_ctrl.h"
22 #include "common/ieee802_11_defs.h"
23 #include "common/ieee802_11_common.h"
24 #include "eapol_auth/eapol_auth_sm.h"
25 #include "eapol_auth/eapol_auth_sm_i.h"
27 #include "wps/wps_defs.h"
28 #include "wps/wps_dev_attr.h"
30 #include "ap_config.h"
33 #include "wps_hostapd.h"
36 #ifdef CONFIG_WPS_UPNP
37 #include "wps/wps_upnp.h"
38 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
39 struct wps_context
*wps
);
40 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
);
41 #endif /* CONFIG_WPS_UPNP */
43 static int hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
44 const u8
*ie
, size_t ie_len
);
45 static void hostapd_wps_ap_pin_timeout(void *eloop_data
, void *user_ctx
);
48 static int hostapd_wps_new_psk_cb(void *ctx
, const u8
*mac_addr
, const u8
*psk
,
51 struct hostapd_data
*hapd
= ctx
;
52 struct hostapd_wpa_psk
*p
;
53 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
55 wpa_printf(MSG_DEBUG
, "Received new WPA/WPA2-PSK from WPS for STA "
56 MACSTR
, MAC2STR(mac_addr
));
57 wpa_hexdump_key(MSG_DEBUG
, "Per-device PSK", psk
, psk_len
);
59 if (psk_len
!= PMK_LEN
) {
60 wpa_printf(MSG_DEBUG
, "Unexpected PSK length %lu",
61 (unsigned long) psk_len
);
65 /* Add the new PSK to runtime PSK list */
66 p
= os_zalloc(sizeof(*p
));
69 os_memcpy(p
->addr
, mac_addr
, ETH_ALEN
);
70 os_memcpy(p
->psk
, psk
, PMK_LEN
);
72 p
->next
= ssid
->wpa_psk
;
75 if (ssid
->wpa_psk_file
) {
77 char hex
[PMK_LEN
* 2 + 1];
78 /* Add the new PSK to PSK list file */
79 f
= fopen(ssid
->wpa_psk_file
, "a");
81 wpa_printf(MSG_DEBUG
, "Failed to add the PSK to "
82 "'%s'", ssid
->wpa_psk_file
);
86 wpa_snprintf_hex(hex
, sizeof(hex
), psk
, psk_len
);
87 fprintf(f
, MACSTR
" %s\n", MAC2STR(mac_addr
), hex
);
95 static int hostapd_wps_set_ie_cb(void *ctx
, struct wpabuf
*beacon_ie
,
96 struct wpabuf
*probe_resp_ie
)
98 struct hostapd_data
*hapd
= ctx
;
99 wpabuf_free(hapd
->wps_beacon_ie
);
100 hapd
->wps_beacon_ie
= beacon_ie
;
101 wpabuf_free(hapd
->wps_probe_resp_ie
);
102 hapd
->wps_probe_resp_ie
= probe_resp_ie
;
103 ieee802_11_set_beacon(hapd
);
104 return hapd
->drv
.set_ap_wps_ie(hapd
);
108 static void hostapd_wps_pin_needed_cb(void *ctx
, const u8
*uuid_e
,
109 const struct wps_device_data
*dev
)
111 struct hostapd_data
*hapd
= ctx
;
112 char uuid
[40], txt
[400];
114 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
115 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
117 wpa_printf(MSG_DEBUG
, "WPS: PIN needed for E-UUID %s", uuid
);
118 len
= os_snprintf(txt
, sizeof(txt
), WPS_EVENT_PIN_NEEDED
119 "%s " MACSTR
" [%s|%s|%s|%s|%s|%s]",
120 uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
121 dev
->manufacturer
, dev
->model_name
,
122 dev
->model_number
, dev
->serial_number
,
123 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
125 if (len
> 0 && len
< (int) sizeof(txt
))
126 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s", txt
);
128 if (hapd
->conf
->wps_pin_requests
) {
131 f
= fopen(hapd
->conf
->wps_pin_requests
, "a");
135 fprintf(f
, "%ld\t%s\t" MACSTR
"\t%s\t%s\t%s\t%s\t%s"
137 t
.sec
, uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
138 dev
->manufacturer
, dev
->model_name
, dev
->model_number
,
140 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
147 static void hostapd_wps_reg_success_cb(void *ctx
, const u8
*mac_addr
,
150 struct hostapd_data
*hapd
= ctx
;
152 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
154 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_REG_SUCCESS MACSTR
" %s",
155 MAC2STR(mac_addr
), uuid
);
156 if (hapd
->wps_reg_success_cb
)
157 hapd
->wps_reg_success_cb(hapd
->wps_reg_success_cb_ctx
,
162 static void hostapd_wps_enrollee_seen_cb(void *ctx
, const u8
*addr
,
164 const u8
*pri_dev_type
,
166 u16 dev_password_id
, u8 request_type
,
167 const char *dev_name
)
169 struct hostapd_data
*hapd
= ctx
;
171 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
172 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
174 if (dev_name
== NULL
)
176 wpa_msg_ctrl(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_ENROLLEE_SEEN MACSTR
177 " %s %s 0x%x %u %u [%s]",
179 wps_dev_type_bin2str(pri_dev_type
, devtype
,
181 config_methods
, dev_password_id
, request_type
, dev_name
);
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 (iface
->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_wps_reenable_ap_pin(void *eloop_data
, void *user_ctx
)
427 struct hostapd_data
*hapd
= eloop_data
;
429 if (hapd
->conf
->ap_setup_locked
)
432 wpa_printf(MSG_DEBUG
, "WPS: Re-enable AP PIN");
433 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_UNLOCKED
);
434 hapd
->wps
->ap_setup_locked
= 0;
435 wps_registrar_update_ie(hapd
->wps
->registrar
);
439 static void hostapd_pwd_auth_fail(struct hostapd_data
*hapd
,
440 struct wps_event_pwd_auth_fail
*data
)
442 if (!data
->enrollee
|| hapd
->conf
->ap_pin
== NULL
)
446 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
447 * for some time if this happens multiple times to slow down brute
450 hapd
->ap_pin_failures
++;
451 wpa_printf(MSG_DEBUG
, "WPS: AP PIN authentication failure number %u",
452 hapd
->ap_pin_failures
);
453 if (hapd
->ap_pin_failures
< 3)
456 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_LOCKED
);
457 hapd
->wps
->ap_setup_locked
= 1;
459 wps_registrar_update_ie(hapd
->wps
->registrar
);
461 if (!hapd
->conf
->ap_setup_locked
) {
462 if (hapd
->ap_pin_lockout_time
== 0)
463 hapd
->ap_pin_lockout_time
= 60;
464 else if (hapd
->ap_pin_lockout_time
< 365 * 24 * 60 * 60 &&
465 (hapd
->ap_pin_failures
% 3) == 0)
466 hapd
->ap_pin_lockout_time
*= 2;
468 wpa_printf(MSG_DEBUG
, "WPS: Disable AP PIN for %u seconds",
469 hapd
->ap_pin_lockout_time
);
470 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin
, hapd
, NULL
);
471 eloop_register_timeout(hapd
->ap_pin_lockout_time
, 0,
472 hostapd_wps_reenable_ap_pin
, hapd
,
476 /* TODO: dualband AP may need to update other interfaces */
480 static void hostapd_wps_event_cb(void *ctx
, enum wps_event event
,
481 union wps_event_data
*data
)
483 struct hostapd_data
*hapd
= ctx
;
485 if (event
== WPS_EV_PWD_AUTH_FAIL
)
486 hostapd_pwd_auth_fail(hapd
, &data
->pwd_auth_fail
);
490 static void hostapd_wps_clear_ies(struct hostapd_data
*hapd
)
492 wpabuf_free(hapd
->wps_beacon_ie
);
493 hapd
->wps_beacon_ie
= NULL
;
495 wpabuf_free(hapd
->wps_probe_resp_ie
);
496 hapd
->wps_probe_resp_ie
= NULL
;
498 hapd
->drv
.set_ap_wps_ie(hapd
);
502 int hostapd_init_wps(struct hostapd_data
*hapd
,
503 struct hostapd_bss_config
*conf
)
505 struct wps_context
*wps
;
506 struct wps_registrar_config cfg
;
508 if (conf
->wps_state
== 0) {
509 hostapd_wps_clear_ies(hapd
);
513 wps
= os_zalloc(sizeof(*wps
));
517 wps
->cred_cb
= hostapd_wps_cred_cb
;
518 wps
->event_cb
= hostapd_wps_event_cb
;
521 os_memset(&cfg
, 0, sizeof(cfg
));
522 wps
->wps_state
= hapd
->conf
->wps_state
;
523 wps
->ap_setup_locked
= hapd
->conf
->ap_setup_locked
;
524 if (is_nil_uuid(hapd
->conf
->uuid
)) {
525 uuid_gen_mac_addr(hapd
->own_addr
, wps
->uuid
);
526 wpa_hexdump(MSG_DEBUG
, "WPS: UUID based on MAC address",
527 wps
->uuid
, UUID_LEN
);
529 os_memcpy(wps
->uuid
, hapd
->conf
->uuid
, UUID_LEN
);
530 wps
->ssid_len
= hapd
->conf
->ssid
.ssid_len
;
531 os_memcpy(wps
->ssid
, hapd
->conf
->ssid
.ssid
, wps
->ssid_len
);
533 os_memcpy(wps
->dev
.mac_addr
, hapd
->own_addr
, ETH_ALEN
);
534 wps
->dev
.device_name
= hapd
->conf
->device_name
?
535 os_strdup(hapd
->conf
->device_name
) : NULL
;
536 wps
->dev
.manufacturer
= hapd
->conf
->manufacturer
?
537 os_strdup(hapd
->conf
->manufacturer
) : NULL
;
538 wps
->dev
.model_name
= hapd
->conf
->model_name
?
539 os_strdup(hapd
->conf
->model_name
) : NULL
;
540 wps
->dev
.model_number
= hapd
->conf
->model_number
?
541 os_strdup(hapd
->conf
->model_number
) : NULL
;
542 wps
->dev
.serial_number
= hapd
->conf
->serial_number
?
543 os_strdup(hapd
->conf
->serial_number
) : NULL
;
544 wps
->config_methods
=
545 wps_config_methods_str2bin(hapd
->conf
->config_methods
);
546 if (hapd
->conf
->device_type
&&
547 wps_dev_type_str2bin(hapd
->conf
->device_type
,
548 wps
->dev
.pri_dev_type
) < 0) {
549 wpa_printf(MSG_ERROR
, "WPS: Invalid device_type");
553 wps
->dev
.os_version
= WPA_GET_BE32(hapd
->conf
->os_version
);
554 wps
->dev
.rf_bands
= hapd
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211A
?
555 WPS_RF_50GHZ
: WPS_RF_24GHZ
; /* FIX: dualband AP */
557 if (conf
->wpa
& WPA_PROTO_RSN
) {
558 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
559 wps
->auth_types
|= WPS_AUTH_WPA2PSK
;
560 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
561 wps
->auth_types
|= WPS_AUTH_WPA2
;
563 if (conf
->rsn_pairwise
& WPA_CIPHER_CCMP
)
564 wps
->encr_types
|= WPS_ENCR_AES
;
565 if (conf
->rsn_pairwise
& WPA_CIPHER_TKIP
)
566 wps
->encr_types
|= WPS_ENCR_TKIP
;
569 if (conf
->wpa
& WPA_PROTO_WPA
) {
570 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
571 wps
->auth_types
|= WPS_AUTH_WPAPSK
;
572 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
573 wps
->auth_types
|= WPS_AUTH_WPA
;
575 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
576 wps
->encr_types
|= WPS_ENCR_AES
;
577 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
578 wps
->encr_types
|= WPS_ENCR_TKIP
;
581 if (conf
->ssid
.security_policy
== SECURITY_PLAINTEXT
) {
582 wps
->encr_types
|= WPS_ENCR_NONE
;
583 wps
->auth_types
|= WPS_AUTH_OPEN
;
584 } else if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
585 wps
->encr_types
|= WPS_ENCR_WEP
;
586 if (conf
->auth_algs
& WPA_AUTH_ALG_OPEN
)
587 wps
->auth_types
|= WPS_AUTH_OPEN
;
588 if (conf
->auth_algs
& WPA_AUTH_ALG_SHARED
)
589 wps
->auth_types
|= WPS_AUTH_SHARED
;
590 } else if (conf
->ssid
.security_policy
== SECURITY_IEEE_802_1X
) {
591 wps
->auth_types
|= WPS_AUTH_OPEN
;
592 if (conf
->default_wep_key_len
)
593 wps
->encr_types
|= WPS_ENCR_WEP
;
595 wps
->encr_types
|= WPS_ENCR_NONE
;
598 if (conf
->ssid
.wpa_psk_file
) {
599 /* Use per-device PSKs */
600 } else if (conf
->ssid
.wpa_passphrase
) {
601 wps
->network_key
= (u8
*) os_strdup(conf
->ssid
.wpa_passphrase
);
602 wps
->network_key_len
= os_strlen(conf
->ssid
.wpa_passphrase
);
603 } else if (conf
->ssid
.wpa_psk
) {
604 wps
->network_key
= os_malloc(2 * PMK_LEN
+ 1);
605 if (wps
->network_key
== NULL
) {
609 wpa_snprintf_hex((char *) wps
->network_key
, 2 * PMK_LEN
+ 1,
610 conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
611 wps
->network_key_len
= 2 * PMK_LEN
;
612 } else if (conf
->ssid
.wep
.keys_set
&& conf
->ssid
.wep
.key
[0]) {
613 wps
->network_key
= os_malloc(conf
->ssid
.wep
.len
[0]);
614 if (wps
->network_key
== NULL
) {
618 os_memcpy(wps
->network_key
, conf
->ssid
.wep
.key
[0],
619 conf
->ssid
.wep
.len
[0]);
620 wps
->network_key_len
= conf
->ssid
.wep
.len
[0];
623 if (conf
->ssid
.wpa_psk
) {
624 os_memcpy(wps
->psk
, conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
628 if (conf
->wps_state
== WPS_STATE_NOT_CONFIGURED
) {
629 /* Override parameters to enable security by default */
630 wps
->auth_types
= WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
;
631 wps
->encr_types
= WPS_ENCR_AES
| WPS_ENCR_TKIP
;
634 wps
->ap_settings
= conf
->ap_settings
;
635 wps
->ap_settings_len
= conf
->ap_settings_len
;
637 cfg
.new_psk_cb
= hostapd_wps_new_psk_cb
;
638 cfg
.set_ie_cb
= hostapd_wps_set_ie_cb
;
639 cfg
.pin_needed_cb
= hostapd_wps_pin_needed_cb
;
640 cfg
.reg_success_cb
= hostapd_wps_reg_success_cb
;
641 cfg
.enrollee_seen_cb
= hostapd_wps_enrollee_seen_cb
;
643 cfg
.skip_cred_build
= conf
->skip_cred_build
;
644 cfg
.extra_cred
= conf
->extra_cred
;
645 cfg
.extra_cred_len
= conf
->extra_cred_len
;
646 cfg
.disable_auto_conf
= (hapd
->conf
->wps_cred_processing
== 1) &&
647 conf
->skip_cred_build
;
648 if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
)
649 cfg
.static_wep_only
= 1;
651 wps
->registrar
= wps_registrar_init(wps
, &cfg
);
652 if (wps
->registrar
== NULL
) {
653 printf("Failed to initialize WPS Registrar\n");
654 os_free(wps
->network_key
);
659 #ifdef CONFIG_WPS_UPNP
660 wps
->friendly_name
= hapd
->conf
->friendly_name
;
661 wps
->manufacturer_url
= hapd
->conf
->manufacturer_url
;
662 wps
->model_description
= hapd
->conf
->model_description
;
663 wps
->model_url
= hapd
->conf
->model_url
;
664 wps
->upc
= hapd
->conf
->upc
;
666 if (hostapd_wps_upnp_init(hapd
, wps
) < 0) {
667 wpa_printf(MSG_ERROR
, "Failed to initialize WPS UPnP");
668 wps_registrar_deinit(wps
->registrar
);
669 os_free(wps
->network_key
);
673 #endif /* CONFIG_WPS_UPNP */
675 hostapd_register_probereq_cb(hapd
, hostapd_wps_probe_req_rx
, hapd
);
683 void hostapd_deinit_wps(struct hostapd_data
*hapd
)
685 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin
, hapd
, NULL
);
686 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout
, hapd
, NULL
);
687 if (hapd
->wps
== NULL
)
689 #ifdef CONFIG_WPS_UPNP
690 hostapd_wps_upnp_deinit(hapd
);
691 #endif /* CONFIG_WPS_UPNP */
692 wps_registrar_deinit(hapd
->wps
->registrar
);
693 os_free(hapd
->wps
->network_key
);
694 wps_device_data_free(&hapd
->wps
->dev
);
695 wpabuf_free(hapd
->wps
->dh_pubkey
);
696 wpabuf_free(hapd
->wps
->dh_privkey
);
697 wpabuf_free(hapd
->wps
->oob_conf
.pubkey_hash
);
698 wpabuf_free(hapd
->wps
->oob_conf
.dev_password
);
699 wps_free_pending_msgs(hapd
->wps
->upnp_msgs
);
702 hostapd_wps_clear_ies(hapd
);
706 void hostapd_update_wps(struct hostapd_data
*hapd
)
708 if (hapd
->wps
== NULL
)
710 if (hapd
->conf
->wps_state
)
711 wps_registrar_update_ie(hapd
->wps
->registrar
);
713 hostapd_deinit_wps(hapd
);
717 int hostapd_wps_add_pin(struct hostapd_data
*hapd
, const char *uuid
,
718 const char *pin
, int timeout
)
723 if (hapd
->wps
== NULL
)
725 if (os_strcmp(uuid
, "any") == 0)
727 else if (uuid_str2bin(uuid
, u
))
729 return wps_registrar_add_pin(hapd
->wps
->registrar
, any
? NULL
: u
,
730 (const u8
*) pin
, os_strlen(pin
),
735 int hostapd_wps_button_pushed(struct hostapd_data
*hapd
)
737 if (hapd
->wps
== NULL
)
739 return wps_registrar_button_pushed(hapd
->wps
->registrar
);
743 #ifdef CONFIG_WPS_OOB
744 int hostapd_wps_start_oob(struct hostapd_data
*hapd
, char *device_type
,
745 char *path
, char *method
, char *name
)
747 struct wps_context
*wps
= hapd
->wps
;
748 struct oob_device_data
*oob_dev
;
750 oob_dev
= wps_get_oob_device(device_type
);
753 oob_dev
->device_path
= path
;
754 oob_dev
->device_name
= name
;
755 wps
->oob_conf
.oob_method
= wps_get_oob_method(method
);
757 if (wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) {
759 * Use pre-configured DH keys in order to be able to write the
760 * key hash into the OOB file.
762 wpabuf_free(wps
->dh_pubkey
);
763 wpabuf_free(wps
->dh_privkey
);
764 wps
->dh_privkey
= NULL
;
765 wps
->dh_pubkey
= dh_init(dh_groups_get(WPS_DH_GROUP
),
767 wps
->dh_pubkey
= wpabuf_zeropad(wps
->dh_pubkey
, 192);
768 if (wps
->dh_pubkey
== NULL
) {
769 wpa_printf(MSG_ERROR
, "WPS: Failed to initialize "
770 "Diffie-Hellman handshake");
775 if (wps_process_oob(wps
, oob_dev
, 1) < 0)
778 if ((wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_E
||
779 wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) &&
780 hostapd_wps_add_pin(hapd
, "any",
781 wpabuf_head(wps
->oob_conf
.dev_password
), 0) <
788 wpabuf_free(wps
->dh_pubkey
);
789 wps
->dh_pubkey
= NULL
;
790 wpabuf_free(wps
->dh_privkey
);
791 wps
->dh_privkey
= NULL
;
794 #endif /* CONFIG_WPS_OOB */
797 static int hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
798 const u8
*ie
, size_t ie_len
)
800 struct hostapd_data
*hapd
= ctx
;
801 struct wpabuf
*wps_ie
;
802 struct ieee802_11_elems elems
;
804 if (hapd
->wps
== NULL
)
807 if (ieee802_11_parse_elems(ie
, ie_len
, &elems
, 0) == ParseFailed
) {
808 wpa_printf(MSG_DEBUG
, "WPS: Could not parse ProbeReq from "
809 MACSTR
, MAC2STR(addr
));
813 if (elems
.ssid
&& elems
.ssid_len
> 0 &&
814 (elems
.ssid_len
!= hapd
->conf
->ssid
.ssid_len
||
815 os_memcmp(elems
.ssid
, hapd
->conf
->ssid
.ssid
, elems
.ssid_len
) !=
817 return 0; /* Not for us */
819 wps_ie
= ieee802_11_vendor_ie_concat(ie
, ie_len
, WPS_DEV_OUI_WFA
);
823 if (wpabuf_len(wps_ie
) > 0) {
824 wps_registrar_probe_req_rx(hapd
->wps
->registrar
, addr
, wps_ie
);
825 #ifdef CONFIG_WPS_UPNP
826 /* FIX: what exactly should be included in the WLANEvent?
827 * WPS attributes? Full ProbeReq frame? */
828 upnp_wps_device_send_wlan_event(hapd
->wps_upnp
, addr
,
829 UPNP_WPS_WLANEVENT_TYPE_PROBE
,
831 #endif /* CONFIG_WPS_UPNP */
840 #ifdef CONFIG_WPS_UPNP
842 static int hostapd_rx_req_put_wlan_response(
843 void *priv
, enum upnp_wps_wlanevent_type ev_type
,
844 const u8
*mac_addr
, const struct wpabuf
*msg
,
845 enum wps_msg_type msg_type
)
847 struct hostapd_data
*hapd
= priv
;
848 struct sta_info
*sta
;
849 struct upnp_pending_message
*p
;
851 wpa_printf(MSG_DEBUG
, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
852 MACSTR
, ev_type
, MAC2STR(mac_addr
));
853 wpa_hexdump(MSG_MSGDUMP
, "WPS UPnP: PutWLANResponse NewMessage",
854 wpabuf_head(msg
), wpabuf_len(msg
));
855 if (ev_type
!= UPNP_WPS_WLANEVENT_TYPE_EAP
) {
856 wpa_printf(MSG_DEBUG
, "WPS UPnP: Ignored unexpected "
857 "PutWLANResponse WLANEventType %d", ev_type
);
862 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC
863 * server implementation for delivery to the peer.
866 sta
= ap_get_sta(hapd
, mac_addr
);
869 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
870 * Pick STA that is in an ongoing WPS registration without
871 * checking the MAC address.
873 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found based "
874 "on NewWLANEventMAC; try wildcard match");
875 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
876 if (sta
->eapol_sm
&& (sta
->flags
& WLAN_STA_WPS
))
882 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found");
886 p
= os_zalloc(sizeof(*p
));
889 os_memcpy(p
->addr
, sta
->addr
, ETH_ALEN
);
890 p
->msg
= wpabuf_dup(msg
);
892 p
->next
= hapd
->wps
->upnp_msgs
;
893 hapd
->wps
->upnp_msgs
= p
;
895 return eapol_auth_eap_pending_cb(sta
->eapol_sm
, sta
->eapol_sm
->eap
);
899 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
900 struct wps_context
*wps
)
902 struct upnp_wps_device_ctx
*ctx
;
904 if (!hapd
->conf
->upnp_iface
)
906 ctx
= os_zalloc(sizeof(*ctx
));
910 ctx
->rx_req_put_wlan_response
= hostapd_rx_req_put_wlan_response
;
911 if (hapd
->conf
->ap_pin
)
912 ctx
->ap_pin
= os_strdup(hapd
->conf
->ap_pin
);
914 hapd
->wps_upnp
= upnp_wps_device_init(ctx
, wps
, hapd
);
915 if (hapd
->wps_upnp
== NULL
) {
919 wps
->wps_upnp
= hapd
->wps_upnp
;
921 if (upnp_wps_device_start(hapd
->wps_upnp
, hapd
->conf
->upnp_iface
)) {
922 upnp_wps_device_deinit(hapd
->wps_upnp
);
923 hapd
->wps_upnp
= NULL
;
931 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
)
933 upnp_wps_device_deinit(hapd
->wps_upnp
);
936 #endif /* CONFIG_WPS_UPNP */
939 int hostapd_wps_get_mib_sta(struct hostapd_data
*hapd
, const u8
*addr
,
940 char *buf
, size_t buflen
)
942 if (hapd
->wps
== NULL
)
944 return wps_registrar_get_info(hapd
->wps
->registrar
, addr
, buf
, buflen
);
948 static void hostapd_wps_ap_pin_timeout(void *eloop_data
, void *user_ctx
)
950 struct hostapd_data
*hapd
= eloop_data
;
951 wpa_printf(MSG_DEBUG
, "WPS: AP PIN timed out");
952 hostapd_wps_ap_pin_disable(hapd
);
956 static void hostapd_wps_ap_pin_enable(struct hostapd_data
*hapd
, int timeout
)
958 wpa_printf(MSG_DEBUG
, "WPS: Enabling AP PIN (timeout=%d)", timeout
);
959 hapd
->ap_pin_failures
= 0;
960 hapd
->conf
->ap_setup_locked
= 0;
961 if (hapd
->wps
->ap_setup_locked
) {
962 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_UNLOCKED
);
963 hapd
->wps
->ap_setup_locked
= 0;
964 wps_registrar_update_ie(hapd
->wps
->registrar
);
966 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout
, hapd
, NULL
);
968 eloop_register_timeout(timeout
, 0,
969 hostapd_wps_ap_pin_timeout
, hapd
, NULL
);
973 void hostapd_wps_ap_pin_disable(struct hostapd_data
*hapd
)
975 wpa_printf(MSG_DEBUG
, "WPS: Disabling AP PIN");
976 os_free(hapd
->conf
->ap_pin
);
977 hapd
->conf
->ap_pin
= NULL
;
978 #ifdef CONFIG_WPS_UPNP
979 upnp_wps_set_ap_pin(hapd
->wps_upnp
, NULL
);
980 #endif /* CONFIG_WPS_UPNP */
981 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout
, hapd
, NULL
);
985 const char * hostapd_wps_ap_pin_random(struct hostapd_data
*hapd
, int timeout
)
990 pin
= wps_generate_pin();
991 os_snprintf(pin_txt
, sizeof(pin_txt
), "%u", pin
);
992 os_free(hapd
->conf
->ap_pin
);
993 hapd
->conf
->ap_pin
= os_strdup(pin_txt
);
994 #ifdef CONFIG_WPS_UPNP
995 upnp_wps_set_ap_pin(hapd
->wps_upnp
, pin_txt
);
996 #endif /* CONFIG_WPS_UPNP */
997 hostapd_wps_ap_pin_enable(hapd
, timeout
);
998 return hapd
->conf
->ap_pin
;
1002 const char * hostapd_wps_ap_pin_get(struct hostapd_data
*hapd
)
1004 return hapd
->conf
->ap_pin
;
1008 int hostapd_wps_ap_pin_set(struct hostapd_data
*hapd
, const char *pin
,
1011 os_free(hapd
->conf
->ap_pin
);
1012 hapd
->conf
->ap_pin
= os_strdup(pin
);
1013 if (hapd
->conf
->ap_pin
== NULL
)
1015 #ifdef CONFIG_WPS_UPNP
1016 upnp_wps_set_ap_pin(hapd
->wps_upnp
, hapd
->conf
->ap_pin
);
1017 #endif /* CONFIG_WPS_UPNP */
1018 hostapd_wps_ap_pin_enable(hapd
, timeout
);