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 int 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 void hostapd_wps_enrollee_seen_cb(void *ctx
, const u8
*addr
,
159 const u8
*pri_dev_type
,
161 u16 dev_password_id
, u8 request_type
,
162 const char *dev_name
)
164 struct hostapd_data
*hapd
= ctx
;
166 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
167 if (uuid_bin2str(uuid_e
, uuid
, sizeof(uuid
)))
169 if (dev_name
== NULL
)
171 wpa_msg_ctrl(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_ENROLLEE_SEEN MACSTR
172 " %s %s 0x%x %u %u [%s]",
174 wps_dev_type_bin2str(pri_dev_type
, devtype
,
176 config_methods
, dev_password_id
, request_type
, dev_name
);
180 static int str_starts(const char *str
, const char *start
)
182 return os_strncmp(str
, start
, os_strlen(start
)) == 0;
186 static void wps_reload_config(void *eloop_data
, void *user_ctx
)
188 struct hostapd_iface
*iface
= eloop_data
;
190 wpa_printf(MSG_DEBUG
, "WPS: Reload configuration data");
191 if (iface
->reload_config(iface
) < 0) {
192 wpa_printf(MSG_WARNING
, "WPS: Failed to reload the updated "
198 static int hostapd_wps_cred_cb(void *ctx
, const struct wps_credential
*cred
)
200 struct hostapd_data
*hapd
= ctx
;
208 wpa_hexdump_key(MSG_DEBUG
, "WPS: Received Credential attribute",
209 cred
->cred_attr
, cred
->cred_attr_len
);
211 wpa_printf(MSG_DEBUG
, "WPS: Received new AP Settings");
212 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: SSID", cred
->ssid
, cred
->ssid_len
);
213 wpa_printf(MSG_DEBUG
, "WPS: Authentication Type 0x%x",
215 wpa_printf(MSG_DEBUG
, "WPS: Encryption Type 0x%x", cred
->encr_type
);
216 wpa_printf(MSG_DEBUG
, "WPS: Network Key Index %d", cred
->key_idx
);
217 wpa_hexdump_key(MSG_DEBUG
, "WPS: Network Key",
218 cred
->key
, cred
->key_len
);
219 wpa_printf(MSG_DEBUG
, "WPS: MAC Address " MACSTR
,
220 MAC2STR(cred
->mac_addr
));
222 if ((hapd
->conf
->wps_cred_processing
== 1 ||
223 hapd
->conf
->wps_cred_processing
== 2) && cred
->cred_attr
) {
224 size_t blen
= cred
->cred_attr_len
* 2 + 1;
225 char *_buf
= os_malloc(blen
);
227 wpa_snprintf_hex(_buf
, blen
,
228 cred
->cred_attr
, cred
->cred_attr_len
);
229 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "%s%s",
230 WPS_EVENT_NEW_AP_SETTINGS
, _buf
);
234 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_NEW_AP_SETTINGS
);
236 if (hapd
->conf
->wps_cred_processing
== 1)
239 os_memcpy(hapd
->wps
->ssid
, cred
->ssid
, cred
->ssid_len
);
240 hapd
->wps
->ssid_len
= cred
->ssid_len
;
241 hapd
->wps
->encr_types
= cred
->encr_type
;
242 hapd
->wps
->auth_types
= cred
->auth_type
;
243 if (cred
->key_len
== 0) {
244 os_free(hapd
->wps
->network_key
);
245 hapd
->wps
->network_key
= NULL
;
246 hapd
->wps
->network_key_len
= 0;
248 if (hapd
->wps
->network_key
== NULL
||
249 hapd
->wps
->network_key_len
< cred
->key_len
) {
250 hapd
->wps
->network_key_len
= 0;
251 os_free(hapd
->wps
->network_key
);
252 hapd
->wps
->network_key
= os_malloc(cred
->key_len
);
253 if (hapd
->wps
->network_key
== NULL
)
256 hapd
->wps
->network_key_len
= cred
->key_len
;
257 os_memcpy(hapd
->wps
->network_key
, cred
->key
, cred
->key_len
);
259 hapd
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
261 len
= os_strlen(hapd
->iface
->config_fname
) + 5;
262 tmp_fname
= os_malloc(len
);
263 if (tmp_fname
== NULL
)
265 os_snprintf(tmp_fname
, len
, "%s-new", hapd
->iface
->config_fname
);
267 oconf
= fopen(hapd
->iface
->config_fname
, "r");
269 wpa_printf(MSG_WARNING
, "WPS: Could not open current "
270 "configuration file");
275 nconf
= fopen(tmp_fname
, "w");
277 wpa_printf(MSG_WARNING
, "WPS: Could not write updated "
278 "configuration file");
284 fprintf(nconf
, "# WPS configuration - START\n");
286 fprintf(nconf
, "wps_state=2\n");
288 fprintf(nconf
, "ssid=");
289 for (i
= 0; i
< cred
->ssid_len
; i
++)
290 fputc(cred
->ssid
[i
], nconf
);
291 fprintf(nconf
, "\n");
293 if ((cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
)) &&
294 (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
)))
296 else if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA2PSK
))
298 else if (cred
->auth_type
& (WPS_AUTH_WPA
| WPS_AUTH_WPAPSK
))
305 fprintf(nconf
, "wpa=%d\n", wpa
);
307 fprintf(nconf
, "wpa_key_mgmt=");
309 if (cred
->auth_type
& (WPS_AUTH_WPA2
| WPS_AUTH_WPA
)) {
310 fprintf(nconf
, "WPA-EAP");
313 if (cred
->auth_type
& (WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
))
314 fprintf(nconf
, "%sWPA-PSK", prefix
);
315 fprintf(nconf
, "\n");
317 fprintf(nconf
, "wpa_pairwise=");
319 if (cred
->encr_type
& WPS_ENCR_AES
) {
320 fprintf(nconf
, "CCMP");
323 if (cred
->encr_type
& WPS_ENCR_TKIP
) {
324 fprintf(nconf
, "%sTKIP", prefix
);
326 fprintf(nconf
, "\n");
328 if (cred
->key_len
>= 8 && cred
->key_len
< 64) {
329 fprintf(nconf
, "wpa_passphrase=");
330 for (i
= 0; i
< cred
->key_len
; i
++)
331 fputc(cred
->key
[i
], nconf
);
332 fprintf(nconf
, "\n");
333 } else if (cred
->key_len
== 64) {
334 fprintf(nconf
, "wpa_psk=");
335 for (i
= 0; i
< cred
->key_len
; i
++)
336 fputc(cred
->key
[i
], nconf
);
337 fprintf(nconf
, "\n");
339 wpa_printf(MSG_WARNING
, "WPS: Invalid key length %lu "
341 (unsigned long) cred
->key_len
);
344 fprintf(nconf
, "auth_algs=1\n");
346 if ((cred
->auth_type
& WPS_AUTH_OPEN
) &&
347 (cred
->auth_type
& WPS_AUTH_SHARED
))
348 fprintf(nconf
, "auth_algs=3\n");
349 else if (cred
->auth_type
& WPS_AUTH_SHARED
)
350 fprintf(nconf
, "auth_algs=2\n");
352 fprintf(nconf
, "auth_algs=1\n");
354 if (cred
->encr_type
& WPS_ENCR_WEP
&& cred
->key_idx
<= 4) {
355 int key_idx
= cred
->key_idx
;
358 fprintf(nconf
, "wep_default_key=%d\n", key_idx
);
359 fprintf(nconf
, "wep_key%d=", key_idx
);
360 if (cred
->key_len
== 10 || cred
->key_len
== 26) {
361 /* WEP key as a hex string */
362 for (i
= 0; i
< cred
->key_len
; i
++)
363 fputc(cred
->key
[i
], nconf
);
365 /* Raw WEP key; convert to hex */
366 for (i
= 0; i
< cred
->key_len
; i
++)
367 fprintf(nconf
, "%02x", cred
->key
[i
]);
369 fprintf(nconf
, "\n");
373 fprintf(nconf
, "# WPS configuration - END\n");
376 while (fgets(buf
, sizeof(buf
), oconf
)) {
377 if (os_strncmp(buf
, "bss=", 4) == 0)
380 (str_starts(buf
, "ssid=") ||
381 str_starts(buf
, "auth_algs=") ||
382 str_starts(buf
, "wps_state=") ||
383 str_starts(buf
, "wpa=") ||
384 str_starts(buf
, "wpa_psk=") ||
385 str_starts(buf
, "wpa_pairwise=") ||
386 str_starts(buf
, "rsn_pairwise=") ||
387 str_starts(buf
, "wpa_key_mgmt=") ||
388 str_starts(buf
, "wpa_passphrase="))) {
389 fprintf(nconf
, "#WPS# %s", buf
);
391 fprintf(nconf
, "%s", buf
);
397 if (rename(tmp_fname
, hapd
->iface
->config_fname
) < 0) {
398 wpa_printf(MSG_WARNING
, "WPS: Failed to rename the updated "
399 "configuration file: %s", strerror(errno
));
406 /* Schedule configuration reload after short period of time to allow
407 * EAP-WSC to be finished.
409 eloop_register_timeout(0, 100000, wps_reload_config
, hapd
->iface
,
412 /* TODO: dualband AP may need to update multiple configuration files */
414 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
420 static void hostapd_pwd_auth_fail(struct hostapd_data
*hapd
,
421 struct wps_event_pwd_auth_fail
*data
)
429 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
430 * if this happens multiple times.
432 hapd
->ap_pin_failures
++;
433 if (hapd
->ap_pin_failures
< 4)
436 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, WPS_EVENT_AP_SETUP_LOCKED
);
437 hapd
->wps
->ap_setup_locked
= 1;
439 wps_registrar_update_ie(hapd
->wps
->registrar
);
441 if (hapd
->conf
->wps_cred_processing
== 1)
444 f
= fopen(hapd
->iface
->config_fname
, "a");
446 wpa_printf(MSG_WARNING
, "WPS: Could not append to the current "
447 "configuration file");
451 fprintf(f
, "# WPS AP Setup Locked based on possible attack\n");
452 fprintf(f
, "ap_setup_locked=1\n");
455 /* TODO: dualband AP may need to update multiple configuration files */
457 wpa_printf(MSG_DEBUG
, "WPS: AP configuration updated");
461 static void hostapd_wps_event_cb(void *ctx
, enum wps_event event
,
462 union wps_event_data
*data
)
464 struct hostapd_data
*hapd
= ctx
;
466 if (event
== WPS_EV_PWD_AUTH_FAIL
)
467 hostapd_pwd_auth_fail(hapd
, &data
->pwd_auth_fail
);
471 static void hostapd_wps_clear_ies(struct hostapd_data
*hapd
)
473 wpabuf_free(hapd
->wps_beacon_ie
);
474 hapd
->wps_beacon_ie
= NULL
;
476 wpabuf_free(hapd
->wps_probe_resp_ie
);
477 hapd
->wps_probe_resp_ie
= NULL
;
479 hapd
->drv
.set_ap_wps_ie(hapd
, NULL
, NULL
);
483 int hostapd_init_wps(struct hostapd_data
*hapd
,
484 struct hostapd_bss_config
*conf
)
486 struct wps_context
*wps
;
487 struct wps_registrar_config cfg
;
489 if (conf
->wps_state
== 0) {
490 hostapd_wps_clear_ies(hapd
);
494 wps
= os_zalloc(sizeof(*wps
));
498 wps
->cred_cb
= hostapd_wps_cred_cb
;
499 wps
->event_cb
= hostapd_wps_event_cb
;
502 os_memset(&cfg
, 0, sizeof(cfg
));
503 wps
->wps_state
= hapd
->conf
->wps_state
;
504 wps
->ap_setup_locked
= hapd
->conf
->ap_setup_locked
;
505 if (is_nil_uuid(hapd
->conf
->uuid
)) {
506 uuid_gen_mac_addr(hapd
->own_addr
, wps
->uuid
);
507 wpa_hexdump(MSG_DEBUG
, "WPS: UUID based on MAC address",
508 wps
->uuid
, UUID_LEN
);
510 os_memcpy(wps
->uuid
, hapd
->conf
->uuid
, UUID_LEN
);
511 wps
->ssid_len
= hapd
->conf
->ssid
.ssid_len
;
512 os_memcpy(wps
->ssid
, hapd
->conf
->ssid
.ssid
, wps
->ssid_len
);
514 os_memcpy(wps
->dev
.mac_addr
, hapd
->own_addr
, ETH_ALEN
);
515 wps
->dev
.device_name
= hapd
->conf
->device_name
?
516 os_strdup(hapd
->conf
->device_name
) : NULL
;
517 wps
->dev
.manufacturer
= hapd
->conf
->manufacturer
?
518 os_strdup(hapd
->conf
->manufacturer
) : NULL
;
519 wps
->dev
.model_name
= hapd
->conf
->model_name
?
520 os_strdup(hapd
->conf
->model_name
) : NULL
;
521 wps
->dev
.model_number
= hapd
->conf
->model_number
?
522 os_strdup(hapd
->conf
->model_number
) : NULL
;
523 wps
->dev
.serial_number
= hapd
->conf
->serial_number
?
524 os_strdup(hapd
->conf
->serial_number
) : NULL
;
525 wps
->config_methods
=
526 wps_config_methods_str2bin(hapd
->conf
->config_methods
);
527 if (hapd
->conf
->device_type
&&
528 wps_dev_type_str2bin(hapd
->conf
->device_type
,
529 wps
->dev
.pri_dev_type
) < 0) {
530 wpa_printf(MSG_ERROR
, "WPS: Invalid device_type");
534 wps
->dev
.os_version
= WPA_GET_BE32(hapd
->conf
->os_version
);
535 wps
->dev
.rf_bands
= hapd
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211A
?
536 WPS_RF_50GHZ
: WPS_RF_24GHZ
; /* FIX: dualband AP */
538 if (conf
->wpa
& WPA_PROTO_RSN
) {
539 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
540 wps
->auth_types
|= WPS_AUTH_WPA2PSK
;
541 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
542 wps
->auth_types
|= WPS_AUTH_WPA2
;
544 if (conf
->rsn_pairwise
& WPA_CIPHER_CCMP
)
545 wps
->encr_types
|= WPS_ENCR_AES
;
546 if (conf
->rsn_pairwise
& WPA_CIPHER_TKIP
)
547 wps
->encr_types
|= WPS_ENCR_TKIP
;
550 if (conf
->wpa
& WPA_PROTO_WPA
) {
551 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_PSK
)
552 wps
->auth_types
|= WPS_AUTH_WPAPSK
;
553 if (conf
->wpa_key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
554 wps
->auth_types
|= WPS_AUTH_WPA
;
556 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
557 wps
->encr_types
|= WPS_ENCR_AES
;
558 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
559 wps
->encr_types
|= WPS_ENCR_TKIP
;
562 if (conf
->ssid
.security_policy
== SECURITY_PLAINTEXT
) {
563 wps
->encr_types
|= WPS_ENCR_NONE
;
564 wps
->auth_types
|= WPS_AUTH_OPEN
;
565 } else if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
) {
566 wps
->encr_types
|= WPS_ENCR_WEP
;
567 if (conf
->auth_algs
& WPA_AUTH_ALG_OPEN
)
568 wps
->auth_types
|= WPS_AUTH_OPEN
;
569 if (conf
->auth_algs
& WPA_AUTH_ALG_SHARED
)
570 wps
->auth_types
|= WPS_AUTH_SHARED
;
571 } else if (conf
->ssid
.security_policy
== SECURITY_IEEE_802_1X
) {
572 wps
->auth_types
|= WPS_AUTH_OPEN
;
573 if (conf
->default_wep_key_len
)
574 wps
->encr_types
|= WPS_ENCR_WEP
;
576 wps
->encr_types
|= WPS_ENCR_NONE
;
579 if (conf
->ssid
.wpa_psk_file
) {
580 /* Use per-device PSKs */
581 } else if (conf
->ssid
.wpa_passphrase
) {
582 wps
->network_key
= (u8
*) os_strdup(conf
->ssid
.wpa_passphrase
);
583 wps
->network_key_len
= os_strlen(conf
->ssid
.wpa_passphrase
);
584 } else if (conf
->ssid
.wpa_psk
) {
585 wps
->network_key
= os_malloc(2 * PMK_LEN
+ 1);
586 if (wps
->network_key
== NULL
) {
590 wpa_snprintf_hex((char *) wps
->network_key
, 2 * PMK_LEN
+ 1,
591 conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
592 wps
->network_key_len
= 2 * PMK_LEN
;
593 } else if (conf
->ssid
.wep
.keys_set
&& conf
->ssid
.wep
.key
[0]) {
594 wps
->network_key
= os_malloc(conf
->ssid
.wep
.len
[0]);
595 if (wps
->network_key
== NULL
) {
599 os_memcpy(wps
->network_key
, conf
->ssid
.wep
.key
[0],
600 conf
->ssid
.wep
.len
[0]);
601 wps
->network_key_len
= conf
->ssid
.wep
.len
[0];
604 if (conf
->ssid
.wpa_psk
) {
605 os_memcpy(wps
->psk
, conf
->ssid
.wpa_psk
->psk
, PMK_LEN
);
609 if (conf
->wps_state
== WPS_STATE_NOT_CONFIGURED
) {
610 /* Override parameters to enable security by default */
611 wps
->auth_types
= WPS_AUTH_WPA2PSK
| WPS_AUTH_WPAPSK
;
612 wps
->encr_types
= WPS_ENCR_AES
| WPS_ENCR_TKIP
;
615 wps
->ap_settings
= conf
->ap_settings
;
616 wps
->ap_settings_len
= conf
->ap_settings_len
;
618 cfg
.new_psk_cb
= hostapd_wps_new_psk_cb
;
619 cfg
.set_ie_cb
= hostapd_wps_set_ie_cb
;
620 cfg
.pin_needed_cb
= hostapd_wps_pin_needed_cb
;
621 cfg
.reg_success_cb
= hostapd_wps_reg_success_cb
;
622 cfg
.enrollee_seen_cb
= hostapd_wps_enrollee_seen_cb
;
624 cfg
.skip_cred_build
= conf
->skip_cred_build
;
625 cfg
.extra_cred
= conf
->extra_cred
;
626 cfg
.extra_cred_len
= conf
->extra_cred_len
;
627 cfg
.disable_auto_conf
= (hapd
->conf
->wps_cred_processing
== 1) &&
628 conf
->skip_cred_build
;
629 if (conf
->ssid
.security_policy
== SECURITY_STATIC_WEP
)
630 cfg
.static_wep_only
= 1;
632 wps
->registrar
= wps_registrar_init(wps
, &cfg
);
633 if (wps
->registrar
== NULL
) {
634 printf("Failed to initialize WPS Registrar\n");
635 os_free(wps
->network_key
);
640 #ifdef CONFIG_WPS_UPNP
641 wps
->friendly_name
= hapd
->conf
->friendly_name
;
642 wps
->manufacturer_url
= hapd
->conf
->manufacturer_url
;
643 wps
->model_description
= hapd
->conf
->model_description
;
644 wps
->model_url
= hapd
->conf
->model_url
;
645 wps
->upc
= hapd
->conf
->upc
;
647 if (hostapd_wps_upnp_init(hapd
, wps
) < 0) {
648 wpa_printf(MSG_ERROR
, "Failed to initialize WPS UPnP");
649 wps_registrar_deinit(wps
->registrar
);
650 os_free(wps
->network_key
);
654 #endif /* CONFIG_WPS_UPNP */
656 hostapd_register_probereq_cb(hapd
, hostapd_wps_probe_req_rx
, hapd
);
664 void hostapd_deinit_wps(struct hostapd_data
*hapd
)
666 if (hapd
->wps
== NULL
)
668 #ifdef CONFIG_WPS_UPNP
669 hostapd_wps_upnp_deinit(hapd
);
670 #endif /* CONFIG_WPS_UPNP */
671 wps_registrar_deinit(hapd
->wps
->registrar
);
672 os_free(hapd
->wps
->network_key
);
673 wps_device_data_free(&hapd
->wps
->dev
);
674 wpabuf_free(hapd
->wps
->dh_pubkey
);
675 wpabuf_free(hapd
->wps
->dh_privkey
);
676 wpabuf_free(hapd
->wps
->oob_conf
.pubkey_hash
);
677 wpabuf_free(hapd
->wps
->oob_conf
.dev_password
);
678 wps_free_pending_msgs(hapd
->wps
->upnp_msgs
);
681 hostapd_wps_clear_ies(hapd
);
685 int hostapd_wps_add_pin(struct hostapd_data
*hapd
, const char *uuid
,
686 const char *pin
, int timeout
)
691 if (hapd
->wps
== NULL
)
693 if (os_strcmp(uuid
, "any") == 0)
695 else if (uuid_str2bin(uuid
, u
))
697 return wps_registrar_add_pin(hapd
->wps
->registrar
, any
? NULL
: u
,
698 (const u8
*) pin
, os_strlen(pin
),
703 int hostapd_wps_button_pushed(struct hostapd_data
*hapd
)
705 if (hapd
->wps
== NULL
)
707 return wps_registrar_button_pushed(hapd
->wps
->registrar
);
711 #ifdef CONFIG_WPS_OOB
712 int hostapd_wps_start_oob(struct hostapd_data
*hapd
, char *device_type
,
713 char *path
, char *method
, char *name
)
715 struct wps_context
*wps
= hapd
->wps
;
716 struct oob_device_data
*oob_dev
;
718 oob_dev
= wps_get_oob_device(device_type
);
721 oob_dev
->device_path
= path
;
722 oob_dev
->device_name
= name
;
723 wps
->oob_conf
.oob_method
= wps_get_oob_method(method
);
725 if (wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) {
727 * Use pre-configured DH keys in order to be able to write the
728 * key hash into the OOB file.
730 wpabuf_free(wps
->dh_pubkey
);
731 wpabuf_free(wps
->dh_privkey
);
732 wps
->dh_privkey
= NULL
;
733 wps
->dh_pubkey
= dh_init(dh_groups_get(WPS_DH_GROUP
),
735 wps
->dh_pubkey
= wpabuf_zeropad(wps
->dh_pubkey
, 192);
736 if (wps
->dh_pubkey
== NULL
) {
737 wpa_printf(MSG_ERROR
, "WPS: Failed to initialize "
738 "Diffie-Hellman handshake");
743 if (wps_process_oob(wps
, oob_dev
, 1) < 0)
746 if ((wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_E
||
747 wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_R
) &&
748 hostapd_wps_add_pin(hapd
, "any",
749 wpabuf_head(wps
->oob_conf
.dev_password
), 0) <
756 wpabuf_free(wps
->dh_pubkey
);
757 wps
->dh_pubkey
= NULL
;
758 wpabuf_free(wps
->dh_privkey
);
759 wps
->dh_privkey
= NULL
;
762 #endif /* CONFIG_WPS_OOB */
765 static int hostapd_wps_probe_req_rx(void *ctx
, const u8
*addr
,
766 const u8
*ie
, size_t ie_len
)
768 struct hostapd_data
*hapd
= ctx
;
769 struct wpabuf
*wps_ie
;
771 if (hapd
->wps
== NULL
)
774 wps_ie
= ieee802_11_vendor_ie_concat(ie
, ie_len
, WPS_DEV_OUI_WFA
);
778 if (wpabuf_len(wps_ie
) > 0) {
779 wps_registrar_probe_req_rx(hapd
->wps
->registrar
, addr
, wps_ie
);
780 #ifdef CONFIG_WPS_UPNP
781 /* FIX: what exactly should be included in the WLANEvent?
782 * WPS attributes? Full ProbeReq frame? */
783 upnp_wps_device_send_wlan_event(hapd
->wps_upnp
, addr
,
784 UPNP_WPS_WLANEVENT_TYPE_PROBE
,
786 #endif /* CONFIG_WPS_UPNP */
795 #ifdef CONFIG_WPS_UPNP
797 static int hostapd_rx_req_put_wlan_response(
798 void *priv
, enum upnp_wps_wlanevent_type ev_type
,
799 const u8
*mac_addr
, const struct wpabuf
*msg
,
800 enum wps_msg_type msg_type
)
802 struct hostapd_data
*hapd
= priv
;
803 struct sta_info
*sta
;
804 struct upnp_pending_message
*p
;
806 wpa_printf(MSG_DEBUG
, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
807 MACSTR
, ev_type
, MAC2STR(mac_addr
));
808 wpa_hexdump(MSG_MSGDUMP
, "WPS UPnP: PutWLANResponse NewMessage",
809 wpabuf_head(msg
), wpabuf_len(msg
));
810 if (ev_type
!= UPNP_WPS_WLANEVENT_TYPE_EAP
) {
811 wpa_printf(MSG_DEBUG
, "WPS UPnP: Ignored unexpected "
812 "PutWLANResponse WLANEventType %d", ev_type
);
817 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC
818 * server implementation for delivery to the peer.
821 sta
= ap_get_sta(hapd
, mac_addr
);
824 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
825 * Pick STA that is in an ongoing WPS registration without
826 * checking the MAC address.
828 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found based "
829 "on NewWLANEventMAC; try wildcard match");
830 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
831 if (sta
->eapol_sm
&& (sta
->flags
& WLAN_STA_WPS
))
837 wpa_printf(MSG_DEBUG
, "WPS UPnP: No matching STA found");
841 p
= os_zalloc(sizeof(*p
));
844 os_memcpy(p
->addr
, sta
->addr
, ETH_ALEN
);
845 p
->msg
= wpabuf_dup(msg
);
847 p
->next
= hapd
->wps
->upnp_msgs
;
848 hapd
->wps
->upnp_msgs
= p
;
850 return eapol_auth_eap_pending_cb(sta
->eapol_sm
, sta
->eapol_sm
->eap
);
854 static int hostapd_wps_upnp_init(struct hostapd_data
*hapd
,
855 struct wps_context
*wps
)
857 struct upnp_wps_device_ctx
*ctx
;
859 if (!hapd
->conf
->upnp_iface
)
861 ctx
= os_zalloc(sizeof(*ctx
));
865 ctx
->rx_req_put_wlan_response
= hostapd_rx_req_put_wlan_response
;
866 if (hapd
->conf
->ap_pin
)
867 ctx
->ap_pin
= os_strdup(hapd
->conf
->ap_pin
);
869 hapd
->wps_upnp
= upnp_wps_device_init(ctx
, wps
, hapd
);
870 if (hapd
->wps_upnp
== NULL
) {
874 wps
->wps_upnp
= hapd
->wps_upnp
;
876 if (upnp_wps_device_start(hapd
->wps_upnp
, hapd
->conf
->upnp_iface
)) {
877 upnp_wps_device_deinit(hapd
->wps_upnp
);
878 hapd
->wps_upnp
= NULL
;
886 static void hostapd_wps_upnp_deinit(struct hostapd_data
*hapd
)
888 upnp_wps_device_deinit(hapd
->wps_upnp
);
891 #endif /* CONFIG_WPS_UPNP */
894 int hostapd_wps_get_mib_sta(struct hostapd_data
*hapd
, const u8
*addr
,
895 char *buf
, size_t buflen
)
897 return wps_registrar_get_info(hapd
->wps
->registrar
, addr
, buf
, buflen
);