2 * hostapd / WPS integration
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/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"
32 #include "wps_hostapd.h"
35 #ifdef CONFIG_WPS_UPNP
36 #include "wps/wps_upnp.h"
37 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
38 struct wps_context
*wps
);
39 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
);
40 #endif /* CONFIG_WPS_UPNP */
42 static void hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
43 const u8
*ie
, size_t ie_len
);
46 static int hostapd_wps_new_psk_cb(void *ctx
, const u8
*mac_addr
, const u8
*psk
,
49 struct hostapd_data
*hapd
= ctx
;
50 struct hostapd_wpa_psk
*p
;
51 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
53 wpa_printf(MSG_DEBUG
, "Received new WPA/WPA2-PSK from WPS for STA "
54 MACSTR
, MAC2STR(mac_addr
));
55 wpa_hexdump_key(MSG_DEBUG
, "Per-device PSK", psk
, psk_len
);
57 if (psk_len
!= PMK_LEN
) {
58 wpa_printf(MSG_DEBUG
, "Unexpected PSK length %lu",
59 (unsigned long) psk_len
);
63 /* Add the new PSK to runtime PSK list */
64 p
= os_zalloc(sizeof(*p
));
67 os_memcpy(p
->addr
, mac_addr
, ETH_ALEN
);
68 os_memcpy(p
->psk
, psk
, PMK_LEN
);
70 p
->next
= ssid
->wpa_psk
;
73 if (ssid
->wpa_psk_file
) {
75 char hex
[PMK_LEN
* 2 + 1];
76 /* Add the new PSK to PSK list file */
77 f
= fopen(ssid
->wpa_psk_file
, "a");
79 wpa_printf(MSG_DEBUG
, "Failed to add the PSK to "
80 "'%s'", ssid
->wpa_psk_file
);
84 wpa_snprintf_hex(hex
, sizeof(hex
), psk
, psk_len
);
85 fprintf(f
, MACSTR
" %s\n", MAC2STR(mac_addr
), hex
);
93 static int hostapd_wps_set_ie_cb(void *ctx
, struct wpabuf
*beacon_ie
,
94 struct wpabuf
*probe_resp_ie
)
96 struct hostapd_data
*hapd
= ctx
;
97 wpabuf_free(hapd
->wps_beacon_ie
);
98 hapd
->wps_beacon_ie
= beacon_ie
;
99 wpabuf_free(hapd
->wps_probe_resp_ie
);
100 hapd
->wps_probe_resp_ie
= probe_resp_ie
;
101 return hapd
->drv
.set_ap_wps_ie(hapd
, hapd
->wps_beacon_ie
,
102 hapd
->wps_probe_resp_ie
);
106 static void hostapd_wps_pin_needed_cb(void *ctx
, const u8
*uuid_e
,
107 const struct wps_device_data
*dev
)
109 struct hostapd_data
*hapd
= ctx
;
110 char uuid
[40], txt
[400];
112 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
113 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
115 wpa_printf(MSG_DEBUG
, "WPS: PIN needed for E-UUID %s", uuid
);
116 len
= os_snprintf(txt
, sizeof(txt
), WPS_EVENT_PIN_NEEDED
117 "%s " MACSTR
" [%s|%s|%s|%s|%s|%s]",
118 uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
119 dev
->manufacturer
, dev
->model_name
,
120 dev
->model_number
, dev
->serial_number
,
121 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
123 if (len
> 0 && len
< (int) sizeof(txt
))
124 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s", txt
);
126 if (hapd
->conf
->wps_pin_requests
) {
129 f
= fopen(hapd
->conf
->wps_pin_requests
, "a");
133 fprintf(f
, "%ld\t%s\t" MACSTR
"\t%s\t%s\t%s\t%s\t%s"
135 t
.sec
, uuid
, MAC2STR(dev
->mac_addr
), dev
->device_name
,
136 dev
->manufacturer
, dev
->model_name
, dev
->model_number
,
138 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
145 static void hostapd_wps_reg_success_cb(void *ctx
, const u8
*mac_addr
,
148 struct hostapd_data
*hapd
= ctx
;
150 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
152 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_REG_SUCCESS MACSTR
" %s",
153 MAC2STR(mac_addr
), uuid
);
157 static int str_starts(const char *str
, const char *start
)
159 return os_strncmp(str
, start
, os_strlen(start
)) == 0;
163 static void wps_reload_config(void *eloop_data
, void *user_ctx
)
165 struct hostapd_iface
*iface
= eloop_data
;
167 wpa_printf(MSG_DEBUG
, "WPS: Reload configuration data");
168 if (iface
->reload_config(iface
) < 0) {
169 wpa_printf(MSG_WARNING
, "WPS: Failed to reload the updated "
175 static int hostapd_wps_cred_cb(void *ctx
, const struct wps_credential
*cred
)
177 struct hostapd_data
*hapd
= ctx
;
185 wpa_hexdump_key(MSG_DEBUG
, "WPS: Received Credential attribute",
186 cred
->cred_attr
, cred
->cred_attr_len
);
188 wpa_printf(MSG_DEBUG
, "WPS: Received new AP Settings");
189 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: SSID", cred
->ssid
, cred
->ssid_len
);
190 wpa_printf(MSG_DEBUG
, "WPS: Authentication Type 0x%x",
192 wpa_printf(MSG_DEBUG
, "WPS: Encryption Type 0x%x", cred
->encr_type
);
193 wpa_printf(MSG_DEBUG
, "WPS: Network Key Index %d", cred
->key_idx
);
194 wpa_hexdump_key(MSG_DEBUG
, "WPS: Network Key",
195 cred
->key
, cred
->key_len
);
196 wpa_printf(MSG_DEBUG
, "WPS: MAC Address " MACSTR
,
197 MAC2STR(cred
->mac_addr
));
199 if ((hapd
->conf
->wps_cred_processing
== 1 ||
200 hapd
->conf
->wps_cred_processing
== 2) && cred
->cred_attr
) {
201 size_t blen
= cred
->cred_attr_len
* 2 + 1;
202 char *_buf
= os_malloc(blen
);
204 wpa_snprintf_hex(_buf
, blen
,
205 cred
->cred_attr
, cred
->cred_attr_len
);
206 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s%s",
207 WPS_EVENT_NEW_AP_SETTINGS
, _buf
);
211 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_NEW_AP_SETTINGS
);
213 if (hapd
->conf
->wps_cred_processing
== 1)
216 os_memcpy(hapd
->wps
->ssid
, cred
->ssid
, cred
->ssid_len
);
217 hapd
->wps
->ssid_len
= cred
->ssid_len
;
218 hapd
->wps
->encr_types
= cred
->encr_type
;
219 hapd
->wps
->auth_types
= cred
->auth_type
;
220 if (cred
->key_len
== 0) {
221 os_free(hapd
->wps
->network_key
);
222 hapd
->wps
->network_key
= NULL
;
223 hapd
->wps
->network_key_len
= 0;
225 if (hapd
->wps
->network_key
== NULL
||
226 hapd
->wps
->network_key_len
< cred
->key_len
) {
227 hapd
->wps
->network_key_len
= 0;
228 os_free(hapd
->wps
->network_key
);
229 hapd
->wps
->network_key
= os_malloc(cred
->key_len
);
230 if (hapd
->wps
->network_key
== NULL
)
233 hapd
->wps
->network_key_len
= cred
->key_len
;
234 os_memcpy(hapd
->wps
->network_key
, cred
->key
, cred
->key_len
);
236 hapd
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
238 len
= os_strlen(hapd
->iface
->config_fname
) + 5;
239 tmp_fname
= os_malloc(len
);
240 if (tmp_fname
== NULL
)
242 os_snprintf(tmp_fname
, len
, "%s-new", hapd
->iface
->config_fname
);
244 oconf
= fopen(hapd
->iface
->config_fname
, "r");
246 wpa_printf(MSG_WARNING
, "WPS: Could not open current "
247 "configuration file");
252 nconf
= fopen(tmp_fname
, "w");
254 wpa_printf(MSG_WARNING
, "WPS: Could not write updated "
255 "configuration file");
261 fprintf(nconf
, "# WPS configuration - START\n");
263 fprintf(nconf
, "wps_state=2\n");
265 fprintf(nconf
, "ssid=");
266 for (i
= 0; i
< cred
->ssid_len
; i
++)
267 fputc(cred
->ssid
[i
], nconf
);
268 fprintf(nconf
, "\n");
270 if ((cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
)) &&
271 (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
)))
273 else if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
))
275 else if (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
))
282 fprintf(nconf
, "wpa=%d\n", wpa
);
284 fprintf(nconf
, "wpa_key_mgmt=");
286 if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA
)) {
287 fprintf(nconf
, "WPA-EAP");
290 if (cred
->auth_type
& (WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
))
291 fprintf(nconf
, "%sWPA-PSK", prefix
);
292 fprintf(nconf
, "\n");
294 fprintf(nconf
, "wpa_pairwise=");
296 if (cred
->encr_type
& WPS_ENCR_AES
) {
297 fprintf(nconf
, "CCMP");
300 if (cred
->encr_type
& WPS_ENCR_TKIP
) {
301 fprintf(nconf
, "%sTKIP", prefix
);
303 fprintf(nconf
, "\n");
305 if (cred
->key_len
>= 8 && cred
->key_len
< 64) {
306 fprintf(nconf
, "wpa_passphrase=");
307 for (i
= 0; i
< cred
->key_len
; i
++)
308 fputc(cred
->key
[i
], nconf
);
309 fprintf(nconf
, "\n");
310 } else if (cred
->key_len
== 64) {
311 fprintf(nconf
, "wpa_psk=");
312 for (i
= 0; i
< cred
->key_len
; i
++)
313 fputc(cred
->key
[i
], nconf
);
314 fprintf(nconf
, "\n");
316 wpa_printf(MSG_WARNING
, "WPS: Invalid key length %lu "
318 (unsigned long) cred
->key_len
);
321 fprintf(nconf
, "auth_algs=1\n");
323 if ((cred
->auth_type
& WPS_AUTH_OPEN
) &&
324 (cred
->auth_type
& WPS_AUTH_SHARED
))
325 fprintf(nconf
, "auth_algs=3\n");
326 else if (cred
->auth_type
& WPS_AUTH_SHARED
)
327 fprintf(nconf
, "auth_algs=2\n");
329 fprintf(nconf
, "auth_algs=1\n");
331 if (cred
->encr_type
& WPS_ENCR_WEP
&& cred
->key_idx
<= 4) {
332 int key_idx
= cred
->key_idx
;
335 fprintf(nconf
, "wep_default_key=%d\n", key_idx
);
336 fprintf(nconf
, "wep_key%d=", key_idx
);
337 if (cred
->key_len
== 10 || cred
->key_len
== 26) {
338 /* WEP key as a hex string */
339 for (i
= 0; i
< cred
->key_len
; i
++)
340 fputc(cred
->key
[i
], nconf
);
342 /* Raw WEP key; convert to hex */
343 for (i
= 0; i
< cred
->key_len
; i
++)
344 fprintf(nconf
, "%02x", cred
->key
[i
]);
346 fprintf(nconf
, "\n");
350 fprintf(nconf
, "# WPS configuration - END\n");
353 while (fgets(buf
, sizeof(buf
), oconf
)) {
354 if (os_strncmp(buf
, "bss=", 4) == 0)
357 (str_starts(buf
, "ssid=") ||
358 str_starts(buf
, "auth_algs=") ||
359 str_starts(buf
, "wps_state=") ||
360 str_starts(buf
, "wpa=") ||
361 str_starts(buf
, "wpa_psk=") ||
362 str_starts(buf
, "wpa_pairwise=") ||
363 str_starts(buf
, "rsn_pairwise=") ||
364 str_starts(buf
, "wpa_key_mgmt=") ||
365 str_starts(buf
, "wpa_passphrase="))) {
366 fprintf(nconf
, "#WPS# %s", buf
);
368 fprintf(nconf
, "%s", buf
);
374 if (rename(tmp_fname
, hapd
->iface
->config_fname
) < 0) {
375 wpa_printf(MSG_WARNING
, "WPS: Failed to rename the updated "
376 "configuration file: %s", strerror(errno
));
383 /* Schedule configuration reload after short period of time to allow
384 * EAP-WSC to be finished.
386 eloop_register_timeout(0, 100000, wps_reload_config
, hapd
->iface
,
389 /* TODO: dualband AP may need to update multiple configuration files */
391 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
397 static void hostapd_pwd_auth_fail(struct hostapd_data
*hapd
,
398 struct wps_event_pwd_auth_fail
*data
)
406 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
407 * if this happens multiple times.
409 hapd
->ap_pin_failures
++;
410 if (hapd
->ap_pin_failures
< 4)
413 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_LOCKED
);
414 hapd
->wps
->ap_setup_locked
= 1;
416 wps_registrar_update_ie(hapd
->wps
->registrar
);
418 if (hapd
->conf
->wps_cred_processing
== 1)
421 f
= fopen(hapd
->iface
->config_fname
, "a");
423 wpa_printf(MSG_WARNING
, "WPS: Could not append to the current "
424 "configuration file");
428 fprintf(f
, "# WPS AP Setup Locked based on possible attack\n");
429 fprintf(f
, "ap_setup_locked=1\n");
432 /* TODO: dualband AP may need to update multiple configuration files */
434 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
438 static void hostapd_wps_event_cb(void *ctx
, enum wps_event event
,
439 union wps_event_data
*data
)
441 struct hostapd_data
*hapd
= ctx
;
443 if (event
== WPS_EV_PWD_AUTH_FAIL
)
444 hostapd_pwd_auth_fail(hapd
, &data
->pwd_auth_fail
);
448 static void hostapd_wps_clear_ies(struct hostapd_data
*hapd
)
450 wpabuf_free(hapd
->wps_beacon_ie
);
451 hapd
->wps_beacon_ie
= NULL
;
453 wpabuf_free(hapd
->wps_probe_resp_ie
);
454 hapd
->wps_probe_resp_ie
= NULL
;
456 hapd
->drv
.set_ap_wps_ie(hapd
, NULL
, NULL
);
460 int hostapd_init_wps(struct hostapd_data
*hapd
,
461 struct hostapd_bss_config
*conf
)
463 struct wps_context
*wps
;
464 struct wps_registrar_config cfg
;
466 if (conf
->wps_state
== 0) {
467 hostapd_wps_clear_ies(hapd
);
471 wps
= os_zalloc(sizeof(*wps
));
475 wps
->cred_cb
= hostapd_wps_cred_cb
;
476 wps
->event_cb
= hostapd_wps_event_cb
;
479 os_memset(&cfg
, 0, sizeof(cfg
));
480 wps
->wps_state
= hapd
->conf
->wps_state
;
481 wps
->ap_setup_locked
= hapd
->conf
->ap_setup_locked
;
482 if (is_nil_uuid(hapd
->conf
->uuid
)) {
483 uuid_gen_mac_addr(hapd
->own_addr
, wps
->uuid
);
484 wpa_hexdump(MSG_DEBUG
, "WPS: UUID based on MAC address",
485 wps
->uuid
, UUID_LEN
);
487 os_memcpy(wps
->uuid
, hapd
->conf
->uuid
, UUID_LEN
);
488 wps
->ssid_len
= hapd
->conf
->ssid
.ssid_len
;
489 os_memcpy(wps
->ssid
, hapd
->conf
->ssid
.ssid
, wps
->ssid_len
);
491 os_memcpy(wps
->dev
.mac_addr
, hapd
->own_addr
, ETH_ALEN
);
492 wps
->dev
.device_name
= hapd
->conf
->device_name
?
493 os_strdup(hapd
->conf
->device_name
) : NULL
;
494 wps
->dev
.manufacturer
= hapd
->conf
->manufacturer
?
495 os_strdup(hapd
->conf
->manufacturer
) : NULL
;
496 wps
->dev
.model_name
= hapd
->conf
->model_name
?
497 os_strdup(hapd
->conf
->model_name
) : NULL
;
498 wps
->dev
.model_number
= hapd
->conf
->model_number
?
499 os_strdup(hapd
->conf
->model_number
) : NULL
;
500 wps
->dev
.serial_number
= hapd
->conf
->serial_number
?
501 os_strdup(hapd
->conf
->serial_number
) : NULL
;
502 wps
->config_methods
=
503 wps_config_methods_str2bin(hapd
->conf
->config_methods
);
504 if (hapd
->conf
->device_type
&&
505 wps_dev_type_str2bin(hapd
->conf
->device_type
,
506 wps
->dev
.pri_dev_type
) < 0) {
507 wpa_printf(MSG_ERROR
, "WPS: Invalid device_type");
511 wps
->dev
.os_version
= WPA_GET_BE32(hapd
->conf
->os_version
);
512 wps
->dev
.rf_bands
= hapd
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211A
?
513 WPS_RF_50GHZ
: WPS_RF_24GHZ
; /* FIX: dualband AP */
515 if (conf
->wpa
& WPA_PROTO_RSN
) {
516 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
517 wps
->auth_types
|= WPS_AUTH_WPA2PSK
;
518 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
519 wps
->auth_types
|= WPS_AUTH_WPA2
;
521 if (conf
->rsn_pairwise
& WPA_CIPHER_CCMP
)
522 wps
->encr_types
|= WPS_ENCR_AES
;
523 if (conf
->rsn_pairwise
& WPA_CIPHER_TKIP
)
524 wps
->encr_types
|= WPS_ENCR_TKIP
;
527 if (conf
->wpa
& WPA_PROTO_WPA
) {
528 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
529 wps
->auth_types
|= WPS_AUTH_WPAPSK
;
530 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
531 wps
->auth_types
|= WPS_AUTH_WPA
;
533 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
534 wps
->encr_types
|= WPS_ENCR_AES
;
535 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
536 wps
->encr_types
|= WPS_ENCR_TKIP
;
539 if (conf
->ssid
.security_policy
== SECURITY_PLAINTEXT
) {
540 wps
->encr_types
|= WPS_ENCR_NONE
;
541 wps
->auth_types
|= WPS_AUTH_OPEN
;
542 } else if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
543 wps
->encr_types
|= WPS_ENCR_WEP
;
544 if (conf
->auth_algs
& WPA_AUTH_ALG_OPEN
)
545 wps
->auth_types
|= WPS_AUTH_OPEN
;
546 if (conf
->auth_algs
& WPA_AUTH_ALG_SHARED
)
547 wps
->auth_types
|= WPS_AUTH_SHARED
;
548 } else if (conf
->ssid
.security_policy
== SECURITY_IEEE_802_1X
) {
549 wps
->auth_types
|= WPS_AUTH_OPEN
;
550 if (conf
->default_wep_key_len
)
551 wps
->encr_types
|= WPS_ENCR_WEP
;
553 wps
->encr_types
|= WPS_ENCR_NONE
;
556 if (conf
->ssid
.wpa_psk_file
) {
557 /* Use per-device PSKs */
558 } else if (conf
->ssid
.wpa_passphrase
) {
559 wps
->network_key
= (u8
*) os_strdup(conf
->ssid
.wpa_passphrase
);
560 wps
->network_key_len
= os_strlen(conf
->ssid
.wpa_passphrase
);
561 } else if (conf
->ssid
.wpa_psk
) {
562 wps
->network_key
= os_malloc(2 * PMK_LEN
+ 1);
563 if (wps
->network_key
== NULL
) {
567 wpa_snprintf_hex((char *) wps
->network_key
, 2 * PMK_LEN
+ 1,
568 conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
569 wps
->network_key_len
= 2 * PMK_LEN
;
570 } else if (conf
->ssid
.wep
.keys_set
&& conf
->ssid
.wep
.key
[0]) {
571 wps
->network_key
= os_malloc(conf
->ssid
.wep
.len
[0]);
572 if (wps
->network_key
== NULL
) {
576 os_memcpy(wps
->network_key
, conf
->ssid
.wep
.key
[0],
577 conf
->ssid
.wep
.len
[0]);
578 wps
->network_key_len
= conf
->ssid
.wep
.len
[0];
581 if (conf
->ssid
.wpa_psk
) {
582 os_memcpy(wps
->psk
, conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
586 if (conf
->wps_state
== WPS_STATE_NOT_CONFIGURED
) {
587 /* Override parameters to enable security by default */
588 wps
->auth_types
= WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
;
589 wps
->encr_types
= WPS_ENCR_AES
| WPS_ENCR_TKIP
;
592 wps
->ap_settings
= conf
->ap_settings
;
593 wps
->ap_settings_len
= conf
->ap_settings_len
;
595 cfg
.new_psk_cb
= hostapd_wps_new_psk_cb
;
596 cfg
.set_ie_cb
= hostapd_wps_set_ie_cb
;
597 cfg
.pin_needed_cb
= hostapd_wps_pin_needed_cb
;
598 cfg
.reg_success_cb
= hostapd_wps_reg_success_cb
;
600 cfg
.skip_cred_build
= conf
->skip_cred_build
;
601 cfg
.extra_cred
= conf
->extra_cred
;
602 cfg
.extra_cred_len
= conf
->extra_cred_len
;
603 cfg
.disable_auto_conf
= (hapd
->conf
->wps_cred_processing
== 1) &&
604 conf
->skip_cred_build
;
605 if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
)
606 cfg
.static_wep_only
= 1;
608 wps
->registrar
= wps_registrar_init(wps
, &cfg
);
609 if (wps
->registrar
== NULL
) {
610 printf("Failed to initialize WPS Registrar\n");
611 os_free(wps
->network_key
);
616 #ifdef CONFIG_WPS_UPNP
617 wps
->friendly_name
= hapd
->conf
->friendly_name
;
618 wps
->manufacturer_url
= hapd
->conf
->manufacturer_url
;
619 wps
->model_description
= hapd
->conf
->model_description
;
620 wps
->model_url
= hapd
->conf
->model_url
;
621 wps
->upc
= hapd
->conf
->upc
;
623 if (hostapd_wps_upnp_init(hapd
, wps
) < 0) {
624 wpa_printf(MSG_ERROR
, "Failed to initialize WPS UPnP");
625 wps_registrar_deinit(wps
->registrar
);
626 os_free(wps
->network_key
);
630 #endif /* CONFIG_WPS_UPNP */
632 hostapd_register_probereq_cb(hapd
, hostapd_wps_probe_req_rx
, hapd
);
640 void hostapd_deinit_wps(struct hostapd_data
*hapd
)
642 if (hapd
->wps
== NULL
)
644 #ifdef CONFIG_WPS_UPNP
645 hostapd_wps_upnp_deinit(hapd
);
646 #endif /* CONFIG_WPS_UPNP */
647 wps_registrar_deinit(hapd
->wps
->registrar
);
648 os_free(hapd
->wps
->network_key
);
649 wps_device_data_free(&hapd
->wps
->dev
);
650 wpabuf_free(hapd
->wps
->dh_pubkey
);
651 wpabuf_free(hapd
->wps
->dh_privkey
);
652 wpabuf_free(hapd
->wps
->oob_conf
.pubkey_hash
);
653 wpabuf_free(hapd
->wps
->oob_conf
.dev_password
);
654 wps_free_pending_msgs(hapd
->wps
->upnp_msgs
);
657 hostapd_wps_clear_ies(hapd
);
661 int hostapd_wps_add_pin(struct hostapd_data
*hapd
, const char *uuid
,
662 const char *pin
, int timeout
)
667 if (hapd
->wps
== NULL
)
669 if (os_strcmp(uuid
, "any") == 0)
671 else if (uuid_str2bin(uuid
, u
))
673 return wps_registrar_add_pin(hapd
->wps
->registrar
, any
? NULL
: u
,
674 (const u8
*) pin
, os_strlen(pin
),
679 int hostapd_wps_button_pushed(struct hostapd_data
*hapd
)
681 if (hapd
->wps
== NULL
)
683 return wps_registrar_button_pushed(hapd
->wps
->registrar
);
687 #ifdef CONFIG_WPS_OOB
688 int hostapd_wps_start_oob(struct hostapd_data
*hapd
, char *device_type
,
689 char *path
, char *method
, char *name
)
691 struct wps_context
*wps
= hapd
->wps
;
692 struct oob_device_data
*oob_dev
;
694 oob_dev
= wps_get_oob_device(device_type
);
697 oob_dev
->device_path
= path
;
698 oob_dev
->device_name
= name
;
699 wps
->oob_conf
.oob_method
= wps_get_oob_method(method
);
701 if (wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) {
703 * Use pre-configured DH keys in order to be able to write the
704 * key hash into the OOB file.
706 wpabuf_free(wps
->dh_pubkey
);
707 wpabuf_free(wps
->dh_privkey
);
708 wps
->dh_privkey
= NULL
;
709 wps
->dh_pubkey
= dh_init(dh_groups_get(WPS_DH_GROUP
),
711 wps
->dh_pubkey
= wpabuf_zeropad(wps
->dh_pubkey
, 192);
712 if (wps
->dh_pubkey
== NULL
) {
713 wpa_printf(MSG_ERROR
, "WPS: Failed to initialize "
714 "Diffie-Hellman handshake");
719 if (wps_process_oob(wps
, oob_dev
, 1) < 0)
722 if ((wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_E
||
723 wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) &&
724 hostapd_wps_add_pin(hapd
, "any",
725 wpabuf_head(wps
->oob_conf
.dev_password
), 0) <
732 wpabuf_free(wps
->dh_pubkey
);
733 wps
->dh_pubkey
= NULL
;
734 wpabuf_free(wps
->dh_privkey
);
735 wps
->dh_privkey
= NULL
;
738 #endif /* CONFIG_WPS_OOB */
741 static void hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
742 const u8
*ie
, size_t ie_len
)
744 struct hostapd_data
*hapd
= ctx
;
745 struct wpabuf
*wps_ie
;
747 if (hapd
->wps
== NULL
)
750 wps_ie
= ieee802_11_vendor_ie_concat(ie
, ie_len
, WPS_DEV_OUI_WFA
);
754 if (wpabuf_len(wps_ie
) > 0) {
755 wps_registrar_probe_req_rx(hapd
->wps
->registrar
, addr
, wps_ie
);
756 #ifdef CONFIG_WPS_UPNP
757 /* FIX: what exactly should be included in the WLANEvent?
758 * WPS attributes? Full ProbeReq frame? */
759 upnp_wps_device_send_wlan_event(hapd
->wps_upnp
, addr
,
760 UPNP_WPS_WLANEVENT_TYPE_PROBE
,
762 #endif /* CONFIG_WPS_UPNP */
769 #ifdef CONFIG_WPS_UPNP
771 static int hostapd_rx_req_put_wlan_response(
772 void *priv
, enum upnp_wps_wlanevent_type ev_type
,
773 const u8
*mac_addr
, const struct wpabuf
*msg
,
774 enum wps_msg_type msg_type
)
776 struct hostapd_data
*hapd
= priv
;
777 struct sta_info
*sta
;
778 struct upnp_pending_message
*p
;
780 wpa_printf(MSG_DEBUG
, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
781 MACSTR
, ev_type
, MAC2STR(mac_addr
));
782 wpa_hexdump(MSG_MSGDUMP
, "WPS UPnP: PutWLANResponse NewMessage",
783 wpabuf_head(msg
), wpabuf_len(msg
));
784 if (ev_type
!= UPNP_WPS_WLANEVENT_TYPE_EAP
) {
785 wpa_printf(MSG_DEBUG
, "WPS UPnP: Ignored unexpected "
786 "PutWLANResponse WLANEventType %d", ev_type
);
791 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC
792 * server implementation for delivery to the peer.
795 sta
= ap_get_sta(hapd
, mac_addr
);
798 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
799 * Pick STA that is in an ongoing WPS registration without
800 * checking the MAC address.
802 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found based "
803 "on NewWLANEventMAC; try wildcard match");
804 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
805 if (sta
->eapol_sm
&& (sta
->flags
& WLAN_STA_WPS
))
811 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found");
815 p
= os_zalloc(sizeof(*p
));
818 os_memcpy(p
->addr
, sta
->addr
, ETH_ALEN
);
819 p
->msg
= wpabuf_dup(msg
);
821 p
->next
= hapd
->wps
->upnp_msgs
;
822 hapd
->wps
->upnp_msgs
= p
;
824 return eapol_auth_eap_pending_cb(sta
->eapol_sm
, sta
->eapol_sm
->eap
);
828 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
829 struct wps_context
*wps
)
831 struct upnp_wps_device_ctx
*ctx
;
833 if (!hapd
->conf
->upnp_iface
)
835 ctx
= os_zalloc(sizeof(*ctx
));
839 ctx
->rx_req_put_wlan_response
= hostapd_rx_req_put_wlan_response
;
840 if (hapd
->conf
->ap_pin
)
841 ctx
->ap_pin
= os_strdup(hapd
->conf
->ap_pin
);
843 hapd
->wps_upnp
= upnp_wps_device_init(ctx
, wps
, hapd
);
844 if (hapd
->wps_upnp
== NULL
) {
848 wps
->wps_upnp
= hapd
->wps_upnp
;
850 if (upnp_wps_device_start(hapd
->wps_upnp
, hapd
->conf
->upnp_iface
)) {
851 upnp_wps_device_deinit(hapd
->wps_upnp
);
852 hapd
->wps_upnp
= NULL
;
860 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
)
862 upnp_wps_device_deinit(hapd
->wps_upnp
);
865 #endif /* CONFIG_WPS_UPNP */
868 int hostapd_wps_get_mib_sta(struct hostapd_data
*hapd
, const u8
*addr
,
869 char *buf
, size_t buflen
)
871 return wps_registrar_get_info(hapd
->wps
->registrar
, addr
, buf
, buflen
);