]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/ap/wps_hostapd.c
e0033cedf3cda4028ba8221f8929495dc499c624
[thirdparty/hostap.git] / src / ap / wps_hostapd.c
1 /*
2 * hostapd / WPS integration
3 * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "utils/uuid.h"
14 #include "common/wpa_ctrl.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/ieee802_11_common.h"
17 #include "eapol_auth/eapol_auth_sm.h"
18 #include "eapol_auth/eapol_auth_sm_i.h"
19 #include "wps/wps.h"
20 #include "wps/wps_defs.h"
21 #include "wps/wps_dev_attr.h"
22 #include "wps/wps_attr_parse.h"
23 #include "hostapd.h"
24 #include "ap_config.h"
25 #include "ap_drv_ops.h"
26 #include "beacon.h"
27 #include "sta_info.h"
28 #include "wps_hostapd.h"
29
30
31 #ifdef CONFIG_WPS_UPNP
32 #include "wps/wps_upnp.h"
33 static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
34 struct wps_context *wps);
35 static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);
36 #endif /* CONFIG_WPS_UPNP */
37
38 static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da,
39 const u8 *bssid,
40 const u8 *ie, size_t ie_len,
41 int ssi_signal);
42 static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
43 static void hostapd_wps_nfc_clear(struct wps_context *wps);
44
45
46 struct wps_for_each_data {
47 int (*func)(struct hostapd_data *h, void *ctx);
48 void *ctx;
49 struct hostapd_data *calling_hapd;
50 };
51
52
53 static int wps_for_each(struct hostapd_iface *iface, void *ctx)
54 {
55 struct wps_for_each_data *data = ctx;
56 size_t j;
57
58 if (iface == NULL)
59 return 0;
60 for (j = 0; j < iface->num_bss; j++) {
61 struct hostapd_data *hapd = iface->bss[j];
62 int ret;
63
64 if (hapd != data->calling_hapd &&
65 (hapd->conf->wps_independent ||
66 data->calling_hapd->conf->wps_independent))
67 continue;
68
69 ret = data->func(hapd, data->ctx);
70 if (ret)
71 return ret;
72 }
73
74 return 0;
75 }
76
77
78 static int hostapd_wps_for_each(struct hostapd_data *hapd,
79 int (*func)(struct hostapd_data *h, void *ctx),
80 void *ctx)
81 {
82 struct hostapd_iface *iface = hapd->iface;
83 struct wps_for_each_data data;
84 data.func = func;
85 data.ctx = ctx;
86 data.calling_hapd = hapd;
87 if (iface->interfaces == NULL ||
88 iface->interfaces->for_each_interface == NULL)
89 return wps_for_each(iface, &data);
90 return iface->interfaces->for_each_interface(iface->interfaces,
91 wps_for_each, &data);
92 }
93
94
95 static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr,
96 const u8 *p2p_dev_addr, const u8 *psk,
97 size_t psk_len)
98 {
99 struct hostapd_data *hapd = ctx;
100 struct hostapd_wpa_psk *p;
101 struct hostapd_ssid *ssid = &hapd->conf->ssid;
102
103 if (is_zero_ether_addr(p2p_dev_addr)) {
104 wpa_printf(MSG_DEBUG,
105 "Received new WPA/WPA2-PSK from WPS for STA " MACSTR,
106 MAC2STR(mac_addr));
107 } else {
108 wpa_printf(MSG_DEBUG,
109 "Received new WPA/WPA2-PSK from WPS for STA " MACSTR
110 " P2P Device Addr " MACSTR,
111 MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
112 }
113 wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
114
115 if (psk_len != PMK_LEN) {
116 wpa_printf(MSG_DEBUG, "Unexpected PSK length %lu",
117 (unsigned long) psk_len);
118 return -1;
119 }
120
121 /* Add the new PSK to runtime PSK list */
122 p = os_zalloc(sizeof(*p));
123 if (p == NULL)
124 return -1;
125 os_memcpy(p->addr, mac_addr, ETH_ALEN);
126 os_memcpy(p->p2p_dev_addr, p2p_dev_addr, ETH_ALEN);
127 os_memcpy(p->psk, psk, PMK_LEN);
128
129 if (hapd->new_psk_cb) {
130 hapd->new_psk_cb(hapd->new_psk_cb_ctx, mac_addr, p2p_dev_addr,
131 psk, psk_len);
132 }
133
134 p->next = ssid->wpa_psk;
135 ssid->wpa_psk = p;
136
137 if (ssid->wpa_psk_file) {
138 FILE *f;
139 char hex[PMK_LEN * 2 + 1];
140 /* Add the new PSK to PSK list file */
141 f = fopen(ssid->wpa_psk_file, "a");
142 if (f == NULL) {
143 wpa_printf(MSG_DEBUG, "Failed to add the PSK to "
144 "'%s'", ssid->wpa_psk_file);
145 return -1;
146 }
147
148 wpa_snprintf_hex(hex, sizeof(hex), psk, psk_len);
149 fprintf(f, MACSTR " %s\n", MAC2STR(mac_addr), hex);
150 fclose(f);
151 }
152
153 return 0;
154 }
155
156
157 static int hostapd_wps_set_ie_cb(void *ctx, struct wpabuf *beacon_ie,
158 struct wpabuf *probe_resp_ie)
159 {
160 struct hostapd_data *hapd = ctx;
161 wpabuf_free(hapd->wps_beacon_ie);
162 hapd->wps_beacon_ie = beacon_ie;
163 wpabuf_free(hapd->wps_probe_resp_ie);
164 hapd->wps_probe_resp_ie = probe_resp_ie;
165 if (hapd->beacon_set_done)
166 ieee802_11_set_beacon(hapd);
167 return hostapd_set_ap_wps_ie(hapd);
168 }
169
170
171 static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
172 const struct wps_device_data *dev)
173 {
174 struct hostapd_data *hapd = ctx;
175 char uuid[40], txt[400];
176 int len;
177 char devtype[WPS_DEV_TYPE_BUFSIZE];
178 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
179 return;
180 wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid);
181 len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED
182 "%s " MACSTR " [%s|%s|%s|%s|%s|%s]",
183 uuid, MAC2STR(dev->mac_addr), dev->device_name,
184 dev->manufacturer, dev->model_name,
185 dev->model_number, dev->serial_number,
186 wps_dev_type_bin2str(dev->pri_dev_type, devtype,
187 sizeof(devtype)));
188 if (len > 0 && len < (int) sizeof(txt))
189 wpa_msg(hapd->msg_ctx, MSG_INFO, "%s", txt);
190
191 if (hapd->conf->wps_pin_requests) {
192 FILE *f;
193 struct os_time t;
194 f = fopen(hapd->conf->wps_pin_requests, "a");
195 if (f == NULL)
196 return;
197 os_get_time(&t);
198 fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s"
199 "\t%s\n",
200 t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name,
201 dev->manufacturer, dev->model_name, dev->model_number,
202 dev->serial_number,
203 wps_dev_type_bin2str(dev->pri_dev_type, devtype,
204 sizeof(devtype)));
205 fclose(f);
206 }
207 }
208
209
210 struct wps_stop_reg_data {
211 struct hostapd_data *current_hapd;
212 const u8 *uuid_e;
213 const u8 *dev_pw;
214 size_t dev_pw_len;
215 };
216
217 static int wps_stop_registrar(struct hostapd_data *hapd, void *ctx)
218 {
219 struct wps_stop_reg_data *data = ctx;
220 if (hapd != data->current_hapd && hapd->wps != NULL)
221 wps_registrar_complete(hapd->wps->registrar, data->uuid_e,
222 data->dev_pw, data->dev_pw_len);
223 return 0;
224 }
225
226
227 static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
228 const u8 *uuid_e, const u8 *dev_pw,
229 size_t dev_pw_len)
230 {
231 struct hostapd_data *hapd = ctx;
232 char uuid[40];
233 struct wps_stop_reg_data data;
234 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
235 return;
236 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",
237 MAC2STR(mac_addr), uuid);
238 if (hapd->wps_reg_success_cb)
239 hapd->wps_reg_success_cb(hapd->wps_reg_success_cb_ctx,
240 mac_addr, uuid_e);
241 data.current_hapd = hapd;
242 data.uuid_e = uuid_e;
243 data.dev_pw = dev_pw;
244 data.dev_pw_len = dev_pw_len;
245 hostapd_wps_for_each(hapd, wps_stop_registrar, &data);
246 }
247
248
249 static void hostapd_wps_enrollee_seen_cb(void *ctx, const u8 *addr,
250 const u8 *uuid_e,
251 const u8 *pri_dev_type,
252 u16 config_methods,
253 u16 dev_password_id, u8 request_type,
254 const char *dev_name)
255 {
256 struct hostapd_data *hapd = ctx;
257 char uuid[40];
258 char devtype[WPS_DEV_TYPE_BUFSIZE];
259 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
260 return;
261 if (dev_name == NULL)
262 dev_name = "";
263 wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ENROLLEE_SEEN MACSTR
264 " %s %s 0x%x %u %u [%s]",
265 MAC2STR(addr), uuid,
266 wps_dev_type_bin2str(pri_dev_type, devtype,
267 sizeof(devtype)),
268 config_methods, dev_password_id, request_type, dev_name);
269 }
270
271
272 static int str_starts(const char *str, const char *start)
273 {
274 return os_strncmp(str, start, os_strlen(start)) == 0;
275 }
276
277
278 static void wps_reload_config(void *eloop_data, void *user_ctx)
279 {
280 struct hostapd_iface *iface = eloop_data;
281
282 wpa_printf(MSG_DEBUG, "WPS: Reload configuration data");
283 if (iface->interfaces == NULL ||
284 iface->interfaces->reload_config(iface) < 0) {
285 wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated "
286 "configuration");
287 }
288 }
289
290
291 void hostapd_wps_eap_completed(struct hostapd_data *hapd)
292 {
293 /*
294 * Reduce race condition of the station trying to reconnect immediately
295 * after AP reconfiguration through WPS by rescheduling the reload
296 * timeout to happen after EAP completion rather than the originally
297 * scheduled 100 ms after new configuration became known.
298 */
299 if (eloop_deplete_timeout(0, 0, wps_reload_config, hapd->iface, NULL) ==
300 1)
301 wpa_printf(MSG_DEBUG, "WPS: Reschedule immediate configuration reload");
302 }
303
304
305 static void hapd_new_ap_event(struct hostapd_data *hapd, const u8 *attr,
306 size_t attr_len)
307 {
308 size_t blen = attr_len * 2 + 1;
309 char *buf = os_malloc(blen);
310 if (buf) {
311 wpa_snprintf_hex(buf, blen, attr, attr_len);
312 wpa_msg(hapd->msg_ctx, MSG_INFO,
313 WPS_EVENT_NEW_AP_SETTINGS "%s", buf);
314 os_free(buf);
315 }
316 }
317
318
319 static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd,
320 const struct wps_credential *cred)
321 {
322 struct hostapd_bss_config *bss = hapd->conf;
323
324 wpa_printf(MSG_DEBUG, "WPS: Updating in-memory configuration");
325
326 bss->wps_state = 2;
327 if (cred->ssid_len <= HOSTAPD_MAX_SSID_LEN) {
328 os_memcpy(bss->ssid.ssid, cred->ssid, cred->ssid_len);
329 bss->ssid.ssid_len = cred->ssid_len;
330 bss->ssid.ssid_set = 1;
331 }
332
333 if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) &&
334 (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)))
335 bss->wpa = 3;
336 else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK))
337 bss->wpa = 2;
338 else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))
339 bss->wpa = 1;
340 else
341 bss->wpa = 0;
342
343 if (bss->wpa) {
344 if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA))
345 bss->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
346 if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK))
347 bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
348
349 bss->wpa_pairwise = 0;
350 if (cred->encr_type & WPS_ENCR_AES)
351 bss->wpa_pairwise |= WPA_CIPHER_CCMP;
352 if (cred->encr_type & WPS_ENCR_TKIP)
353 bss->wpa_pairwise |= WPA_CIPHER_TKIP;
354 bss->rsn_pairwise = bss->wpa_pairwise;
355 bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa,
356 bss->wpa_pairwise,
357 bss->rsn_pairwise);
358
359 if (cred->key_len >= 8 && cred->key_len < 64) {
360 os_free(bss->ssid.wpa_passphrase);
361 bss->ssid.wpa_passphrase = os_zalloc(cred->key_len + 1);
362 if (bss->ssid.wpa_passphrase)
363 os_memcpy(bss->ssid.wpa_passphrase, cred->key,
364 cred->key_len);
365 os_free(bss->ssid.wpa_psk);
366 bss->ssid.wpa_psk = NULL;
367 } else if (cred->key_len == 64) {
368 os_free(bss->ssid.wpa_psk);
369 bss->ssid.wpa_psk =
370 os_zalloc(sizeof(struct hostapd_wpa_psk));
371 if (bss->ssid.wpa_psk &&
372 hexstr2bin((const char *) cred->key,
373 bss->ssid.wpa_psk->psk, PMK_LEN) == 0) {
374 bss->ssid.wpa_psk->group = 1;
375 os_free(bss->ssid.wpa_passphrase);
376 bss->ssid.wpa_passphrase = NULL;
377 }
378 }
379 bss->auth_algs = 1;
380 } else {
381 #ifdef CONFIG_WPS2
382 /*
383 * WPS 2.0 does not allow WEP to be configured, so no need to
384 * process that option here either.
385 */
386 bss->auth_algs = 1;
387 #else /* CONFIG_WPS2 */
388 if ((cred->auth_type & WPS_AUTH_OPEN) &&
389 (cred->auth_type & WPS_AUTH_SHARED))
390 bss->auth_algs = 3;
391 else if (cred->auth_type & WPS_AUTH_SHARED)
392 bss->auth_algs = 2;
393 else
394 bss->auth_algs = 1;
395 if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx > 0 &&
396 cred->key_idx <= 4) {
397 struct hostapd_wep_keys *wep = &bss->ssid.wep;
398 int idx = cred->key_idx;
399 if (idx)
400 idx--;
401 wep->idx = idx;
402 if (cred->key_len == 10 || cred->key_len == 26) {
403 os_free(wep->key[idx]);
404 wep->key[idx] = os_malloc(cred->key_len / 2);
405 if (wep->key[idx] == NULL ||
406 hexstr2bin((const char *) cred->key,
407 wep->key[idx],
408 cred->key_len / 2))
409 return -1;
410 wep->len[idx] = cred->key_len / 2;
411 } else {
412 os_free(wep->key[idx]);
413 wep->key[idx] = os_malloc(cred->key_len);
414 if (wep->key[idx] == NULL)
415 return -1;
416 os_memcpy(wep->key[idx], cred->key,
417 cred->key_len);
418 wep->len[idx] = cred->key_len;
419 }
420 wep->keys_set = 1;
421 }
422 #endif /* CONFIG_WPS2 */
423 }
424
425 /* Schedule configuration reload after short period of time to allow
426 * EAP-WSC to be finished.
427 */
428 eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface,
429 NULL);
430
431 return 0;
432 }
433
434
435 static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx)
436 {
437 const struct wps_credential *cred = ctx;
438 FILE *oconf, *nconf;
439 size_t len, i;
440 char *tmp_fname;
441 char buf[1024];
442 int multi_bss;
443 int wpa;
444
445 if (hapd->wps == NULL)
446 return 0;
447
448 wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
449 cred->cred_attr, cred->cred_attr_len);
450
451 wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings");
452 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
453 wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
454 cred->auth_type);
455 wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
456 wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
457 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
458 cred->key, cred->key_len);
459 wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
460 MAC2STR(cred->mac_addr));
461
462 if ((hapd->conf->wps_cred_processing == 1 ||
463 hapd->conf->wps_cred_processing == 2) && cred->cred_attr) {
464 hapd_new_ap_event(hapd, cred->cred_attr, cred->cred_attr_len);
465 } else if (hapd->conf->wps_cred_processing == 1 ||
466 hapd->conf->wps_cred_processing == 2) {
467 struct wpabuf *attr;
468 attr = wpabuf_alloc(200);
469 if (attr && wps_build_credential_wrap(attr, cred) == 0)
470 hapd_new_ap_event(hapd, wpabuf_head_u8(attr),
471 wpabuf_len(attr));
472 wpabuf_free(attr);
473 } else
474 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS);
475
476 if (hapd->conf->wps_cred_processing == 1)
477 return 0;
478
479 os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
480 hapd->wps->ssid_len = cred->ssid_len;
481 hapd->wps->encr_types = cred->encr_type;
482 hapd->wps->auth_types = cred->auth_type;
483 hapd->wps->ap_encr_type = cred->encr_type;
484 hapd->wps->ap_auth_type = cred->auth_type;
485 if (cred->key_len == 0) {
486 os_free(hapd->wps->network_key);
487 hapd->wps->network_key = NULL;
488 hapd->wps->network_key_len = 0;
489 } else {
490 if (hapd->wps->network_key == NULL ||
491 hapd->wps->network_key_len < cred->key_len) {
492 hapd->wps->network_key_len = 0;
493 os_free(hapd->wps->network_key);
494 hapd->wps->network_key = os_malloc(cred->key_len);
495 if (hapd->wps->network_key == NULL)
496 return -1;
497 }
498 hapd->wps->network_key_len = cred->key_len;
499 os_memcpy(hapd->wps->network_key, cred->key, cred->key_len);
500 }
501 hapd->wps->wps_state = WPS_STATE_CONFIGURED;
502
503 if (hapd->iface->config_fname == NULL)
504 return hapd_wps_reconfig_in_memory(hapd, cred);
505 len = os_strlen(hapd->iface->config_fname) + 5;
506 tmp_fname = os_malloc(len);
507 if (tmp_fname == NULL)
508 return -1;
509 os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname);
510
511 oconf = fopen(hapd->iface->config_fname, "r");
512 if (oconf == NULL) {
513 wpa_printf(MSG_WARNING, "WPS: Could not open current "
514 "configuration file");
515 os_free(tmp_fname);
516 return -1;
517 }
518
519 nconf = fopen(tmp_fname, "w");
520 if (nconf == NULL) {
521 wpa_printf(MSG_WARNING, "WPS: Could not write updated "
522 "configuration file");
523 os_free(tmp_fname);
524 fclose(oconf);
525 return -1;
526 }
527
528 fprintf(nconf, "# WPS configuration - START\n");
529
530 fprintf(nconf, "wps_state=2\n");
531
532 if (is_hex(cred->ssid, cred->ssid_len)) {
533 fprintf(nconf, "ssid2=");
534 for (i = 0; i < cred->ssid_len; i++)
535 fprintf(nconf, "%02x", cred->ssid[i]);
536 fprintf(nconf, "\n");
537 } else {
538 fprintf(nconf, "ssid=");
539 for (i = 0; i < cred->ssid_len; i++)
540 fputc(cred->ssid[i], nconf);
541 fprintf(nconf, "\n");
542 }
543
544 if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) &&
545 (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)))
546 wpa = 3;
547 else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK))
548 wpa = 2;
549 else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))
550 wpa = 1;
551 else
552 wpa = 0;
553
554 if (wpa) {
555 char *prefix;
556 fprintf(nconf, "wpa=%d\n", wpa);
557
558 fprintf(nconf, "wpa_key_mgmt=");
559 prefix = "";
560 if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) {
561 fprintf(nconf, "WPA-EAP");
562 prefix = " ";
563 }
564 if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK))
565 fprintf(nconf, "%sWPA-PSK", prefix);
566 fprintf(nconf, "\n");
567
568 fprintf(nconf, "wpa_pairwise=");
569 prefix = "";
570 if (cred->encr_type & WPS_ENCR_AES) {
571 fprintf(nconf, "CCMP");
572 prefix = " ";
573 }
574 if (cred->encr_type & WPS_ENCR_TKIP) {
575 fprintf(nconf, "%sTKIP", prefix);
576 }
577 fprintf(nconf, "\n");
578
579 if (cred->key_len >= 8 && cred->key_len < 64) {
580 fprintf(nconf, "wpa_passphrase=");
581 for (i = 0; i < cred->key_len; i++)
582 fputc(cred->key[i], nconf);
583 fprintf(nconf, "\n");
584 } else if (cred->key_len == 64) {
585 fprintf(nconf, "wpa_psk=");
586 for (i = 0; i < cred->key_len; i++)
587 fputc(cred->key[i], nconf);
588 fprintf(nconf, "\n");
589 } else {
590 wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu "
591 "for WPA/WPA2",
592 (unsigned long) cred->key_len);
593 }
594
595 fprintf(nconf, "auth_algs=1\n");
596 } else {
597 #ifdef CONFIG_WPS2
598 /*
599 * WPS 2.0 does not allow WEP to be configured, so no need to
600 * process that option here either.
601 */
602 fprintf(nconf, "auth_algs=1\n");
603 #else /* CONFIG_WPS2 */
604 if ((cred->auth_type & WPS_AUTH_OPEN) &&
605 (cred->auth_type & WPS_AUTH_SHARED))
606 fprintf(nconf, "auth_algs=3\n");
607 else if (cred->auth_type & WPS_AUTH_SHARED)
608 fprintf(nconf, "auth_algs=2\n");
609 else
610 fprintf(nconf, "auth_algs=1\n");
611
612 if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) {
613 int key_idx = cred->key_idx;
614 if (key_idx)
615 key_idx--;
616 fprintf(nconf, "wep_default_key=%d\n", key_idx);
617 fprintf(nconf, "wep_key%d=", key_idx);
618 if (cred->key_len == 10 || cred->key_len == 26) {
619 /* WEP key as a hex string */
620 for (i = 0; i < cred->key_len; i++)
621 fputc(cred->key[i], nconf);
622 } else {
623 /* Raw WEP key; convert to hex */
624 for (i = 0; i < cred->key_len; i++)
625 fprintf(nconf, "%02x", cred->key[i]);
626 }
627 fprintf(nconf, "\n");
628 }
629 #endif /* CONFIG_WPS2 */
630 }
631
632 fprintf(nconf, "# WPS configuration - END\n");
633
634 multi_bss = 0;
635 while (fgets(buf, sizeof(buf), oconf)) {
636 if (os_strncmp(buf, "bss=", 4) == 0)
637 multi_bss = 1;
638 if (!multi_bss &&
639 (str_starts(buf, "ssid=") ||
640 str_starts(buf, "ssid2=") ||
641 str_starts(buf, "auth_algs=") ||
642 str_starts(buf, "wep_default_key=") ||
643 str_starts(buf, "wep_key") ||
644 str_starts(buf, "wps_state=") ||
645 str_starts(buf, "wpa=") ||
646 str_starts(buf, "wpa_psk=") ||
647 str_starts(buf, "wpa_pairwise=") ||
648 str_starts(buf, "rsn_pairwise=") ||
649 str_starts(buf, "wpa_key_mgmt=") ||
650 str_starts(buf, "wpa_passphrase="))) {
651 fprintf(nconf, "#WPS# %s", buf);
652 } else
653 fprintf(nconf, "%s", buf);
654 }
655
656 fclose(nconf);
657 fclose(oconf);
658
659 if (rename(tmp_fname, hapd->iface->config_fname) < 0) {
660 wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated "
661 "configuration file: %s", strerror(errno));
662 os_free(tmp_fname);
663 return -1;
664 }
665
666 os_free(tmp_fname);
667
668 /* Schedule configuration reload after short period of time to allow
669 * EAP-WSC to be finished.
670 */
671 eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface,
672 NULL);
673
674 wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");
675
676 return 0;
677 }
678
679
680 static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred)
681 {
682 struct hostapd_data *hapd = ctx;
683 return hostapd_wps_for_each(hapd, hapd_wps_cred_cb, (void *) cred);
684 }
685
686
687 static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
688 {
689 struct hostapd_data *hapd = eloop_data;
690
691 if (hapd->conf->ap_setup_locked)
692 return;
693 if (hapd->ap_pin_failures_consecutive >= 10)
694 return;
695
696 wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
697 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
698 hapd->wps->ap_setup_locked = 0;
699 wps_registrar_update_ie(hapd->wps->registrar);
700 }
701
702
703 static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
704 {
705 struct wps_event_pwd_auth_fail *data = ctx;
706
707 if (!data->enrollee || hapd->conf->ap_pin == NULL || hapd->wps == NULL)
708 return 0;
709
710 /*
711 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
712 * for some time if this happens multiple times to slow down brute
713 * force attacks.
714 */
715 hapd->ap_pin_failures++;
716 hapd->ap_pin_failures_consecutive++;
717 wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u "
718 "(%u consecutive)",
719 hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
720 if (hapd->ap_pin_failures < 3)
721 return 0;
722
723 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
724 hapd->wps->ap_setup_locked = 1;
725
726 wps_registrar_update_ie(hapd->wps->registrar);
727
728 if (!hapd->conf->ap_setup_locked &&
729 hapd->ap_pin_failures_consecutive >= 10) {
730 /*
731 * In indefinite lockdown - disable automatic AP PIN
732 * reenablement.
733 */
734 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
735 wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
736 } else if (!hapd->conf->ap_setup_locked) {
737 if (hapd->ap_pin_lockout_time == 0)
738 hapd->ap_pin_lockout_time = 60;
739 else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
740 (hapd->ap_pin_failures % 3) == 0)
741 hapd->ap_pin_lockout_time *= 2;
742
743 wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN for %u seconds",
744 hapd->ap_pin_lockout_time);
745 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
746 eloop_register_timeout(hapd->ap_pin_lockout_time, 0,
747 hostapd_wps_reenable_ap_pin, hapd,
748 NULL);
749 }
750
751 return 0;
752 }
753
754
755 static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
756 struct wps_event_pwd_auth_fail *data)
757 {
758 /* Update WPS Status - Authentication Failure */
759 wpa_printf(MSG_DEBUG, "WPS: Authentication failure update");
760 hapd->wps_stats.status = WPS_STATUS_FAILURE;
761 hapd->wps_stats.failure_reason = WPS_EI_AUTH_FAILURE;
762 os_memcpy(hapd->wps_stats.peer_addr, data->peer_macaddr, ETH_ALEN);
763
764 hostapd_wps_for_each(hapd, wps_pwd_auth_fail, data);
765 }
766
767
768 static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
769 {
770 if (hapd->conf->ap_pin == NULL || hapd->wps == NULL)
771 return 0;
772
773 if (hapd->ap_pin_failures_consecutive == 0)
774 return 0;
775
776 wpa_printf(MSG_DEBUG, "WPS: Clear consecutive AP PIN failure counter "
777 "- total validation failures %u (%u consecutive)",
778 hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
779 hapd->ap_pin_failures_consecutive = 0;
780
781 return 0;
782 }
783
784
785 static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd)
786 {
787 hostapd_wps_for_each(hapd, wps_ap_pin_success, NULL);
788 }
789
790
791 static void hostapd_wps_event_pbc_overlap(struct hostapd_data *hapd)
792 {
793 /* Update WPS Status - PBC Overlap */
794 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_OVERLAP;
795 }
796
797
798 static void hostapd_wps_event_pbc_timeout(struct hostapd_data *hapd)
799 {
800 /* Update WPS PBC Status:PBC Timeout */
801 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_TIMEOUT;
802 }
803
804
805 static void hostapd_wps_event_pbc_active(struct hostapd_data *hapd)
806 {
807 /* Update WPS PBC status - Active */
808 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_ACTIVE;
809 }
810
811
812 static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
813 {
814 /* Update WPS PBC status - Active */
815 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE;
816 }
817
818
819 static void hostapd_wps_event_success(struct hostapd_data *hapd,
820 struct wps_event_success *success)
821 {
822 /* Update WPS status - Success */
823 hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE;
824 hapd->wps_stats.status = WPS_STATUS_SUCCESS;
825 os_memcpy(hapd->wps_stats.peer_addr, success->peer_macaddr, ETH_ALEN);
826 }
827
828
829 static void hostapd_wps_event_fail(struct hostapd_data *hapd,
830 struct wps_event_fail *fail)
831 {
832 /* Update WPS status - Failure */
833 hapd->wps_stats.status = WPS_STATUS_FAILURE;
834 os_memcpy(hapd->wps_stats.peer_addr, fail->peer_macaddr, ETH_ALEN);
835
836 hapd->wps_stats.failure_reason = fail->error_indication;
837
838 if (fail->error_indication > 0 &&
839 fail->error_indication < NUM_WPS_EI_VALUES) {
840 wpa_msg(hapd->msg_ctx, MSG_INFO,
841 WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
842 fail->msg, fail->config_error, fail->error_indication,
843 wps_ei_str(fail->error_indication));
844 } else {
845 wpa_msg(hapd->msg_ctx, MSG_INFO,
846 WPS_EVENT_FAIL "msg=%d config_error=%d",
847 fail->msg, fail->config_error);
848 }
849 }
850
851
852 static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
853 union wps_event_data *data)
854 {
855 struct hostapd_data *hapd = ctx;
856
857 switch (event) {
858 case WPS_EV_M2D:
859 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_M2D);
860 break;
861 case WPS_EV_FAIL:
862 hostapd_wps_event_fail(hapd, &data->fail);
863 break;
864 case WPS_EV_SUCCESS:
865 hostapd_wps_event_success(hapd, &data->success);
866 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_SUCCESS);
867 break;
868 case WPS_EV_PWD_AUTH_FAIL:
869 hostapd_pwd_auth_fail(hapd, &data->pwd_auth_fail);
870 break;
871 case WPS_EV_PBC_OVERLAP:
872 hostapd_wps_event_pbc_overlap(hapd);
873 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_OVERLAP);
874 break;
875 case WPS_EV_PBC_TIMEOUT:
876 hostapd_wps_event_pbc_timeout(hapd);
877 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_TIMEOUT);
878 break;
879 case WPS_EV_PBC_ACTIVE:
880 hostapd_wps_event_pbc_active(hapd);
881 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ACTIVE);
882 break;
883 case WPS_EV_PBC_DISABLE:
884 hostapd_wps_event_pbc_disable(hapd);
885 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_DISABLE);
886 break;
887 case WPS_EV_ER_AP_ADD:
888 break;
889 case WPS_EV_ER_AP_REMOVE:
890 break;
891 case WPS_EV_ER_ENROLLEE_ADD:
892 break;
893 case WPS_EV_ER_ENROLLEE_REMOVE:
894 break;
895 case WPS_EV_ER_AP_SETTINGS:
896 break;
897 case WPS_EV_ER_SET_SELECTED_REGISTRAR:
898 break;
899 case WPS_EV_AP_PIN_SUCCESS:
900 hostapd_wps_ap_pin_success(hapd);
901 break;
902 }
903 if (hapd->wps_event_cb)
904 hapd->wps_event_cb(hapd->wps_event_cb_ctx, event, data);
905 }
906
907
908 static int hostapd_wps_rf_band_cb(void *ctx)
909 {
910 struct hostapd_data *hapd = ctx;
911
912 return hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
913 WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */
914 }
915
916
917 static void hostapd_wps_clear_ies(struct hostapd_data *hapd, int deinit_only)
918 {
919 wpabuf_free(hapd->wps_beacon_ie);
920 hapd->wps_beacon_ie = NULL;
921
922 wpabuf_free(hapd->wps_probe_resp_ie);
923 hapd->wps_probe_resp_ie = NULL;
924
925 if (deinit_only)
926 return;
927
928 hostapd_set_ap_wps_ie(hapd);
929 }
930
931
932 static int get_uuid_cb(struct hostapd_iface *iface, void *ctx)
933 {
934 const u8 **uuid = ctx;
935 size_t j;
936
937 if (iface == NULL)
938 return 0;
939 for (j = 0; j < iface->num_bss; j++) {
940 struct hostapd_data *hapd = iface->bss[j];
941 if (hapd->wps && !hapd->conf->wps_independent &&
942 !is_nil_uuid(hapd->wps->uuid)) {
943 *uuid = hapd->wps->uuid;
944 return 1;
945 }
946 }
947
948 return 0;
949 }
950
951
952 static const u8 * get_own_uuid(struct hostapd_iface *iface)
953 {
954 const u8 *uuid;
955 if (iface->interfaces == NULL ||
956 iface->interfaces->for_each_interface == NULL)
957 return NULL;
958 uuid = NULL;
959 iface->interfaces->for_each_interface(iface->interfaces, get_uuid_cb,
960 &uuid);
961 return uuid;
962 }
963
964
965 static int count_interface_cb(struct hostapd_iface *iface, void *ctx)
966 {
967 int *count= ctx;
968 (*count)++;
969 return 0;
970 }
971
972
973 static int interface_count(struct hostapd_iface *iface)
974 {
975 int count = 0;
976 if (iface->interfaces == NULL ||
977 iface->interfaces->for_each_interface == NULL)
978 return 0;
979 iface->interfaces->for_each_interface(iface->interfaces,
980 count_interface_cb, &count);
981 return count;
982 }
983
984
985 static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
986 struct wps_context *wps)
987 {
988 int i;
989
990 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
991 wpabuf_free(wps->dev.vendor_ext[i]);
992 wps->dev.vendor_ext[i] = NULL;
993
994 if (hapd->conf->wps_vendor_ext[i] == NULL)
995 continue;
996
997 wps->dev.vendor_ext[i] =
998 wpabuf_dup(hapd->conf->wps_vendor_ext[i]);
999 if (wps->dev.vendor_ext[i] == NULL) {
1000 while (--i >= 0)
1001 wpabuf_free(wps->dev.vendor_ext[i]);
1002 return -1;
1003 }
1004 }
1005
1006 return 0;
1007 }
1008
1009
1010 static void hostapd_free_wps(struct wps_context *wps)
1011 {
1012 int i;
1013
1014 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
1015 wpabuf_free(wps->dev.vendor_ext[i]);
1016 wps_device_data_free(&wps->dev);
1017 os_free(wps->network_key);
1018 hostapd_wps_nfc_clear(wps);
1019 wpabuf_free(wps->dh_pubkey);
1020 wpabuf_free(wps->dh_privkey);
1021 os_free(wps);
1022 }
1023
1024
1025 int hostapd_init_wps(struct hostapd_data *hapd,
1026 struct hostapd_bss_config *conf)
1027 {
1028 struct wps_context *wps;
1029 struct wps_registrar_config cfg;
1030
1031 if (conf->wps_state == 0) {
1032 hostapd_wps_clear_ies(hapd, 0);
1033 return 0;
1034 }
1035
1036 wps = os_zalloc(sizeof(*wps));
1037 if (wps == NULL)
1038 return -1;
1039
1040 wps->cred_cb = hostapd_wps_cred_cb;
1041 wps->event_cb = hostapd_wps_event_cb;
1042 wps->rf_band_cb = hostapd_wps_rf_band_cb;
1043 wps->cb_ctx = hapd;
1044
1045 os_memset(&cfg, 0, sizeof(cfg));
1046 wps->wps_state = hapd->conf->wps_state;
1047 wps->ap_setup_locked = hapd->conf->ap_setup_locked;
1048 if (is_nil_uuid(hapd->conf->uuid)) {
1049 const u8 *uuid;
1050 uuid = get_own_uuid(hapd->iface);
1051 if (uuid && !conf->wps_independent) {
1052 os_memcpy(wps->uuid, uuid, UUID_LEN);
1053 wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another "
1054 "interface", wps->uuid, UUID_LEN);
1055 } else {
1056 uuid_gen_mac_addr(hapd->own_addr, wps->uuid);
1057 wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC "
1058 "address", wps->uuid, UUID_LEN);
1059 }
1060 } else {
1061 os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN);
1062 wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID",
1063 wps->uuid, UUID_LEN);
1064 }
1065 wps->ssid_len = hapd->conf->ssid.ssid_len;
1066 os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len);
1067 wps->ap = 1;
1068 os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN);
1069 wps->dev.device_name = hapd->conf->device_name ?
1070 os_strdup(hapd->conf->device_name) : NULL;
1071 wps->dev.manufacturer = hapd->conf->manufacturer ?
1072 os_strdup(hapd->conf->manufacturer) : NULL;
1073 wps->dev.model_name = hapd->conf->model_name ?
1074 os_strdup(hapd->conf->model_name) : NULL;
1075 wps->dev.model_number = hapd->conf->model_number ?
1076 os_strdup(hapd->conf->model_number) : NULL;
1077 wps->dev.serial_number = hapd->conf->serial_number ?
1078 os_strdup(hapd->conf->serial_number) : NULL;
1079 wps->config_methods =
1080 wps_config_methods_str2bin(hapd->conf->config_methods);
1081 #ifdef CONFIG_WPS2
1082 if ((wps->config_methods &
1083 (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
1084 WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
1085 wpa_printf(MSG_INFO, "WPS: Converting display to "
1086 "virtual_display for WPS 2.0 compliance");
1087 wps->config_methods |= WPS_CONFIG_VIRT_DISPLAY;
1088 }
1089 if ((wps->config_methods &
1090 (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
1091 WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
1092 wpa_printf(MSG_INFO, "WPS: Converting push_button to "
1093 "virtual_push_button for WPS 2.0 compliance");
1094 wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
1095 }
1096 #endif /* CONFIG_WPS2 */
1097 os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
1098 WPS_DEV_TYPE_LEN);
1099
1100 if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
1101 goto fail;
1102
1103 wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
1104
1105 if (conf->wps_rf_bands) {
1106 wps->dev.rf_bands = conf->wps_rf_bands;
1107 } else {
1108 wps->dev.rf_bands =
1109 hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
1110 WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */
1111 }
1112
1113 if (conf->wpa & WPA_PROTO_RSN) {
1114 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
1115 wps->auth_types |= WPS_AUTH_WPA2PSK;
1116 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
1117 wps->auth_types |= WPS_AUTH_WPA2;
1118
1119 if (conf->rsn_pairwise & WPA_CIPHER_CCMP)
1120 wps->encr_types |= WPS_ENCR_AES;
1121 if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
1122 wps->encr_types |= WPS_ENCR_TKIP;
1123 }
1124
1125 if (conf->wpa & WPA_PROTO_WPA) {
1126 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
1127 wps->auth_types |= WPS_AUTH_WPAPSK;
1128 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
1129 wps->auth_types |= WPS_AUTH_WPA;
1130
1131 if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
1132 wps->encr_types |= WPS_ENCR_AES;
1133 if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
1134 wps->encr_types |= WPS_ENCR_TKIP;
1135 }
1136
1137 if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
1138 wps->encr_types |= WPS_ENCR_NONE;
1139 wps->auth_types |= WPS_AUTH_OPEN;
1140 } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) {
1141 wps->encr_types |= WPS_ENCR_WEP;
1142 if (conf->auth_algs & WPA_AUTH_ALG_OPEN)
1143 wps->auth_types |= WPS_AUTH_OPEN;
1144 if (conf->auth_algs & WPA_AUTH_ALG_SHARED)
1145 wps->auth_types |= WPS_AUTH_SHARED;
1146 } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) {
1147 wps->auth_types |= WPS_AUTH_OPEN;
1148 if (conf->default_wep_key_len)
1149 wps->encr_types |= WPS_ENCR_WEP;
1150 else
1151 wps->encr_types |= WPS_ENCR_NONE;
1152 }
1153
1154 if (conf->ssid.wpa_psk_file) {
1155 /* Use per-device PSKs */
1156 } else if (conf->ssid.wpa_passphrase) {
1157 wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase);
1158 wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
1159 } else if (conf->ssid.wpa_psk) {
1160 wps->network_key = os_malloc(2 * PMK_LEN + 1);
1161 if (wps->network_key == NULL)
1162 goto fail;
1163 wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
1164 conf->ssid.wpa_psk->psk, PMK_LEN);
1165 wps->network_key_len = 2 * PMK_LEN;
1166 } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
1167 wps->network_key = os_malloc(conf->ssid.wep.len[0]);
1168 if (wps->network_key == NULL)
1169 goto fail;
1170 os_memcpy(wps->network_key, conf->ssid.wep.key[0],
1171 conf->ssid.wep.len[0]);
1172 wps->network_key_len = conf->ssid.wep.len[0];
1173 }
1174
1175 if (conf->ssid.wpa_psk) {
1176 os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN);
1177 wps->psk_set = 1;
1178 }
1179
1180 wps->ap_auth_type = wps->auth_types;
1181 wps->ap_encr_type = wps->encr_types;
1182 if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) {
1183 /* Override parameters to enable security by default */
1184 wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
1185 wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
1186 }
1187
1188 wps->ap_settings = conf->ap_settings;
1189 wps->ap_settings_len = conf->ap_settings_len;
1190
1191 cfg.new_psk_cb = hostapd_wps_new_psk_cb;
1192 cfg.set_ie_cb = hostapd_wps_set_ie_cb;
1193 cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
1194 cfg.reg_success_cb = hostapd_wps_reg_success_cb;
1195 cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb;
1196 cfg.cb_ctx = hapd;
1197 cfg.skip_cred_build = conf->skip_cred_build;
1198 cfg.extra_cred = conf->extra_cred;
1199 cfg.extra_cred_len = conf->extra_cred_len;
1200 cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
1201 conf->skip_cred_build;
1202 if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
1203 cfg.static_wep_only = 1;
1204 cfg.dualband = interface_count(hapd->iface) > 1;
1205 if ((wps->dev.rf_bands & (WPS_RF_50GHZ | WPS_RF_24GHZ)) ==
1206 (WPS_RF_50GHZ | WPS_RF_24GHZ))
1207 cfg.dualband = 1;
1208 if (cfg.dualband)
1209 wpa_printf(MSG_DEBUG, "WPS: Dualband AP");
1210 cfg.force_per_enrollee_psk = conf->force_per_enrollee_psk;
1211
1212 wps->registrar = wps_registrar_init(wps, &cfg);
1213 if (wps->registrar == NULL) {
1214 wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
1215 goto fail;
1216 }
1217
1218 #ifdef CONFIG_WPS_UPNP
1219 wps->friendly_name = hapd->conf->friendly_name;
1220 wps->manufacturer_url = hapd->conf->manufacturer_url;
1221 wps->model_description = hapd->conf->model_description;
1222 wps->model_url = hapd->conf->model_url;
1223 wps->upc = hapd->conf->upc;
1224 #endif /* CONFIG_WPS_UPNP */
1225
1226 hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
1227
1228 hapd->wps = wps;
1229
1230 return 0;
1231
1232 fail:
1233 hostapd_free_wps(wps);
1234 return -1;
1235 }
1236
1237
1238 int hostapd_init_wps_complete(struct hostapd_data *hapd)
1239 {
1240 struct wps_context *wps = hapd->wps;
1241
1242 if (wps == NULL)
1243 return 0;
1244
1245 #ifdef CONFIG_WPS_UPNP
1246 if (hostapd_wps_upnp_init(hapd, wps) < 0) {
1247 wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP");
1248 wps_registrar_deinit(wps->registrar);
1249 hostapd_free_wps(wps);
1250 hapd->wps = NULL;
1251 return -1;
1252 }
1253 #endif /* CONFIG_WPS_UPNP */
1254
1255 return 0;
1256 }
1257
1258
1259 static void hostapd_wps_nfc_clear(struct wps_context *wps)
1260 {
1261 #ifdef CONFIG_WPS_NFC
1262 wpa_printf(MSG_DEBUG, "WPS: Clear NFC Tag context %p", wps);
1263 wps->ap_nfc_dev_pw_id = 0;
1264 wpabuf_free(wps->ap_nfc_dh_pubkey);
1265 wps->ap_nfc_dh_pubkey = NULL;
1266 wpabuf_free(wps->ap_nfc_dh_privkey);
1267 wps->ap_nfc_dh_privkey = NULL;
1268 wpabuf_free(wps->ap_nfc_dev_pw);
1269 wps->ap_nfc_dev_pw = NULL;
1270 #endif /* CONFIG_WPS_NFC */
1271 }
1272
1273
1274 void hostapd_deinit_wps(struct hostapd_data *hapd)
1275 {
1276 eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
1277 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
1278 eloop_cancel_timeout(wps_reload_config, hapd->iface, NULL);
1279 if (hapd->wps == NULL) {
1280 hostapd_wps_clear_ies(hapd, 1);
1281 return;
1282 }
1283 #ifdef CONFIG_WPS_UPNP
1284 hostapd_wps_upnp_deinit(hapd);
1285 #endif /* CONFIG_WPS_UPNP */
1286 wps_registrar_deinit(hapd->wps->registrar);
1287 wps_free_pending_msgs(hapd->wps->upnp_msgs);
1288 hostapd_free_wps(hapd->wps);
1289 hapd->wps = NULL;
1290 hostapd_wps_clear_ies(hapd, 1);
1291 }
1292
1293
1294 void hostapd_update_wps(struct hostapd_data *hapd)
1295 {
1296 if (hapd->wps == NULL)
1297 return;
1298
1299 #ifdef CONFIG_WPS_UPNP
1300 hapd->wps->friendly_name = hapd->conf->friendly_name;
1301 hapd->wps->manufacturer_url = hapd->conf->manufacturer_url;
1302 hapd->wps->model_description = hapd->conf->model_description;
1303 hapd->wps->model_url = hapd->conf->model_url;
1304 hapd->wps->upc = hapd->conf->upc;
1305 #endif /* CONFIG_WPS_UPNP */
1306
1307 hostapd_wps_set_vendor_ext(hapd, hapd->wps);
1308
1309 if (hapd->conf->wps_state)
1310 wps_registrar_update_ie(hapd->wps->registrar);
1311 else
1312 hostapd_deinit_wps(hapd);
1313 }
1314
1315
1316 struct wps_add_pin_data {
1317 const u8 *addr;
1318 const u8 *uuid;
1319 const u8 *pin;
1320 size_t pin_len;
1321 int timeout;
1322 int added;
1323 };
1324
1325
1326 static int wps_add_pin(struct hostapd_data *hapd, void *ctx)
1327 {
1328 struct wps_add_pin_data *data = ctx;
1329 int ret;
1330
1331 if (hapd->wps == NULL)
1332 return 0;
1333 ret = wps_registrar_add_pin(hapd->wps->registrar, data->addr,
1334 data->uuid, data->pin, data->pin_len,
1335 data->timeout);
1336 if (ret == 0)
1337 data->added++;
1338 return ret;
1339 }
1340
1341
1342 int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *addr,
1343 const char *uuid, const char *pin, int timeout)
1344 {
1345 u8 u[UUID_LEN];
1346 struct wps_add_pin_data data;
1347
1348 data.addr = addr;
1349 data.uuid = u;
1350 data.pin = (const u8 *) pin;
1351 data.pin_len = os_strlen(pin);
1352 data.timeout = timeout;
1353 data.added = 0;
1354
1355 if (os_strcmp(uuid, "any") == 0)
1356 data.uuid = NULL;
1357 else {
1358 if (uuid_str2bin(uuid, u))
1359 return -1;
1360 data.uuid = u;
1361 }
1362 if (hostapd_wps_for_each(hapd, wps_add_pin, &data) < 0)
1363 return -1;
1364 return data.added ? 0 : -1;
1365 }
1366
1367
1368 static int wps_button_pushed(struct hostapd_data *hapd, void *ctx)
1369 {
1370 const u8 *p2p_dev_addr = ctx;
1371 if (hapd->wps == NULL)
1372 return 0;
1373 return wps_registrar_button_pushed(hapd->wps->registrar, p2p_dev_addr);
1374 }
1375
1376
1377 int hostapd_wps_button_pushed(struct hostapd_data *hapd,
1378 const u8 *p2p_dev_addr)
1379 {
1380 return hostapd_wps_for_each(hapd, wps_button_pushed,
1381 (void *) p2p_dev_addr);
1382 }
1383
1384
1385 static int wps_cancel(struct hostapd_data *hapd, void *ctx)
1386 {
1387 if (hapd->wps == NULL)
1388 return 0;
1389
1390 wps_registrar_wps_cancel(hapd->wps->registrar);
1391 ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL);
1392
1393 return 0;
1394 }
1395
1396
1397 int hostapd_wps_cancel(struct hostapd_data *hapd)
1398 {
1399 return hostapd_wps_for_each(hapd, wps_cancel, NULL);
1400 }
1401
1402
1403 static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da,
1404 const u8 *bssid,
1405 const u8 *ie, size_t ie_len,
1406 int ssi_signal)
1407 {
1408 struct hostapd_data *hapd = ctx;
1409 struct wpabuf *wps_ie;
1410 struct ieee802_11_elems elems;
1411
1412 if (hapd->wps == NULL)
1413 return 0;
1414
1415 if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
1416 wpa_printf(MSG_DEBUG, "WPS: Could not parse ProbeReq from "
1417 MACSTR, MAC2STR(addr));
1418 return 0;
1419 }
1420
1421 if (elems.ssid && elems.ssid_len > 0 &&
1422 (elems.ssid_len != hapd->conf->ssid.ssid_len ||
1423 os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) !=
1424 0))
1425 return 0; /* Not for us */
1426
1427 wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
1428 if (wps_ie == NULL)
1429 return 0;
1430 if (wps_validate_probe_req(wps_ie, addr) < 0) {
1431 wpabuf_free(wps_ie);
1432 return 0;
1433 }
1434
1435 if (wpabuf_len(wps_ie) > 0) {
1436 int p2p_wildcard = 0;
1437 #ifdef CONFIG_P2P
1438 if (elems.ssid && elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
1439 os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
1440 P2P_WILDCARD_SSID_LEN) == 0)
1441 p2p_wildcard = 1;
1442 #endif /* CONFIG_P2P */
1443 wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie,
1444 p2p_wildcard);
1445 #ifdef CONFIG_WPS_UPNP
1446 /* FIX: what exactly should be included in the WLANEvent?
1447 * WPS attributes? Full ProbeReq frame? */
1448 if (!p2p_wildcard)
1449 upnp_wps_device_send_wlan_event(
1450 hapd->wps_upnp, addr,
1451 UPNP_WPS_WLANEVENT_TYPE_PROBE, wps_ie);
1452 #endif /* CONFIG_WPS_UPNP */
1453 }
1454
1455 wpabuf_free(wps_ie);
1456
1457 return 0;
1458 }
1459
1460
1461 #ifdef CONFIG_WPS_UPNP
1462
1463 static int hostapd_rx_req_put_wlan_response(
1464 void *priv, enum upnp_wps_wlanevent_type ev_type,
1465 const u8 *mac_addr, const struct wpabuf *msg,
1466 enum wps_msg_type msg_type)
1467 {
1468 struct hostapd_data *hapd = priv;
1469 struct sta_info *sta;
1470 struct upnp_pending_message *p;
1471
1472 wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
1473 MACSTR, ev_type, MAC2STR(mac_addr));
1474 wpa_hexdump(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage",
1475 wpabuf_head(msg), wpabuf_len(msg));
1476 if (ev_type != UPNP_WPS_WLANEVENT_TYPE_EAP) {
1477 wpa_printf(MSG_DEBUG, "WPS UPnP: Ignored unexpected "
1478 "PutWLANResponse WLANEventType %d", ev_type);
1479 return -1;
1480 }
1481
1482 /*
1483 * EAP response to ongoing to WPS Registration. Send it to EAP-WSC
1484 * server implementation for delivery to the peer.
1485 */
1486
1487 sta = ap_get_sta(hapd, mac_addr);
1488 #ifndef CONFIG_WPS_STRICT
1489 if (!sta) {
1490 /*
1491 * Workaround - Intel wsccmd uses bogus NewWLANEventMAC:
1492 * Pick STA that is in an ongoing WPS registration without
1493 * checking the MAC address.
1494 */
1495 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found based "
1496 "on NewWLANEventMAC; try wildcard match");
1497 for (sta = hapd->sta_list; sta; sta = sta->next) {
1498 if (sta->eapol_sm && (sta->flags & WLAN_STA_WPS))
1499 break;
1500 }
1501 }
1502 #endif /* CONFIG_WPS_STRICT */
1503
1504 if (!sta || !(sta->flags & WLAN_STA_WPS)) {
1505 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found");
1506 return 0;
1507 }
1508
1509 if (!sta->eapol_sm) {
1510 /*
1511 * This can happen, e.g., if an ER sends an extra message after
1512 * the station has disassociated (but not fully
1513 * deauthenticated).
1514 */
1515 wpa_printf(MSG_DEBUG, "WPS UPnP: Matching STA did not have EAPOL state machine initialized");
1516 return 0;
1517 }
1518
1519 p = os_zalloc(sizeof(*p));
1520 if (p == NULL)
1521 return -1;
1522 os_memcpy(p->addr, sta->addr, ETH_ALEN);
1523 p->msg = wpabuf_dup(msg);
1524 p->type = msg_type;
1525 p->next = hapd->wps->upnp_msgs;
1526 hapd->wps->upnp_msgs = p;
1527
1528 return eapol_auth_eap_pending_cb(sta->eapol_sm, sta->eapol_sm->eap);
1529 }
1530
1531
1532 static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
1533 struct wps_context *wps)
1534 {
1535 struct upnp_wps_device_ctx *ctx;
1536
1537 if (!hapd->conf->upnp_iface)
1538 return 0;
1539 ctx = os_zalloc(sizeof(*ctx));
1540 if (ctx == NULL)
1541 return -1;
1542
1543 ctx->rx_req_put_wlan_response = hostapd_rx_req_put_wlan_response;
1544 if (hapd->conf->ap_pin)
1545 ctx->ap_pin = os_strdup(hapd->conf->ap_pin);
1546
1547 hapd->wps_upnp = upnp_wps_device_init(ctx, wps, hapd,
1548 hapd->conf->upnp_iface);
1549 if (hapd->wps_upnp == NULL)
1550 return -1;
1551 wps->wps_upnp = hapd->wps_upnp;
1552
1553 return 0;
1554 }
1555
1556
1557 static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd)
1558 {
1559 upnp_wps_device_deinit(hapd->wps_upnp, hapd);
1560 }
1561
1562 #endif /* CONFIG_WPS_UPNP */
1563
1564
1565 int hostapd_wps_get_mib_sta(struct hostapd_data *hapd, const u8 *addr,
1566 char *buf, size_t buflen)
1567 {
1568 if (hapd->wps == NULL)
1569 return 0;
1570 return wps_registrar_get_info(hapd->wps->registrar, addr, buf, buflen);
1571 }
1572
1573
1574 static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
1575 {
1576 struct hostapd_data *hapd = eloop_data;
1577 wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
1578 hostapd_wps_ap_pin_disable(hapd);
1579 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_PIN_DISABLED);
1580 }
1581
1582
1583 static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout)
1584 {
1585 wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
1586 hapd->ap_pin_failures = 0;
1587 hapd->ap_pin_failures_consecutive = 0;
1588 hapd->conf->ap_setup_locked = 0;
1589 if (hapd->wps->ap_setup_locked) {
1590 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
1591 hapd->wps->ap_setup_locked = 0;
1592 wps_registrar_update_ie(hapd->wps->registrar);
1593 }
1594 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
1595 if (timeout > 0)
1596 eloop_register_timeout(timeout, 0,
1597 hostapd_wps_ap_pin_timeout, hapd, NULL);
1598 }
1599
1600
1601 static int wps_ap_pin_disable(struct hostapd_data *hapd, void *ctx)
1602 {
1603 os_free(hapd->conf->ap_pin);
1604 hapd->conf->ap_pin = NULL;
1605 #ifdef CONFIG_WPS_UPNP
1606 upnp_wps_set_ap_pin(hapd->wps_upnp, NULL);
1607 #endif /* CONFIG_WPS_UPNP */
1608 eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
1609 return 0;
1610 }
1611
1612
1613 void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd)
1614 {
1615 wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
1616 hostapd_wps_for_each(hapd, wps_ap_pin_disable, NULL);
1617 }
1618
1619
1620 struct wps_ap_pin_data {
1621 char pin_txt[9];
1622 int timeout;
1623 };
1624
1625
1626 static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx)
1627 {
1628 struct wps_ap_pin_data *data = ctx;
1629 os_free(hapd->conf->ap_pin);
1630 hapd->conf->ap_pin = os_strdup(data->pin_txt);
1631 #ifdef CONFIG_WPS_UPNP
1632 upnp_wps_set_ap_pin(hapd->wps_upnp, data->pin_txt);
1633 #endif /* CONFIG_WPS_UPNP */
1634 hostapd_wps_ap_pin_enable(hapd, data->timeout);
1635 return 0;
1636 }
1637
1638
1639 const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout)
1640 {
1641 unsigned int pin;
1642 struct wps_ap_pin_data data;
1643
1644 pin = wps_generate_pin();
1645 os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%08u", pin);
1646 data.timeout = timeout;
1647 hostapd_wps_for_each(hapd, wps_ap_pin_set, &data);
1648 return hapd->conf->ap_pin;
1649 }
1650
1651
1652 const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd)
1653 {
1654 return hapd->conf->ap_pin;
1655 }
1656
1657
1658 int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
1659 int timeout)
1660 {
1661 struct wps_ap_pin_data data;
1662 int ret;
1663
1664 ret = os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%s", pin);
1665 if (ret < 0 || ret >= (int) sizeof(data.pin_txt))
1666 return -1;
1667 data.timeout = timeout;
1668 return hostapd_wps_for_each(hapd, wps_ap_pin_set, &data);
1669 }
1670
1671
1672 static int wps_update_ie(struct hostapd_data *hapd, void *ctx)
1673 {
1674 if (hapd->wps)
1675 wps_registrar_update_ie(hapd->wps->registrar);
1676 return 0;
1677 }
1678
1679
1680 void hostapd_wps_update_ie(struct hostapd_data *hapd)
1681 {
1682 hostapd_wps_for_each(hapd, wps_update_ie, NULL);
1683 }
1684
1685
1686 int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
1687 const char *auth, const char *encr, const char *key)
1688 {
1689 struct wps_credential cred;
1690 size_t len;
1691
1692 os_memset(&cred, 0, sizeof(cred));
1693
1694 len = os_strlen(ssid);
1695 if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
1696 hexstr2bin(ssid, cred.ssid, len / 2))
1697 return -1;
1698 cred.ssid_len = len / 2;
1699
1700 if (os_strncmp(auth, "OPEN", 4) == 0)
1701 cred.auth_type = WPS_AUTH_OPEN;
1702 else if (os_strncmp(auth, "WPAPSK", 6) == 0)
1703 cred.auth_type = WPS_AUTH_WPAPSK;
1704 else if (os_strncmp(auth, "WPA2PSK", 7) == 0)
1705 cred.auth_type = WPS_AUTH_WPA2PSK;
1706 else
1707 return -1;
1708
1709 if (encr) {
1710 if (os_strncmp(encr, "NONE", 4) == 0)
1711 cred.encr_type = WPS_ENCR_NONE;
1712 else if (os_strncmp(encr, "WEP", 3) == 0)
1713 cred.encr_type = WPS_ENCR_WEP;
1714 else if (os_strncmp(encr, "TKIP", 4) == 0)
1715 cred.encr_type = WPS_ENCR_TKIP;
1716 else if (os_strncmp(encr, "CCMP", 4) == 0)
1717 cred.encr_type = WPS_ENCR_AES;
1718 else
1719 return -1;
1720 } else
1721 cred.encr_type = WPS_ENCR_NONE;
1722
1723 if (key) {
1724 len = os_strlen(key);
1725 if ((len & 1) || len > 2 * sizeof(cred.key) ||
1726 hexstr2bin(key, cred.key, len / 2))
1727 return -1;
1728 cred.key_len = len / 2;
1729 }
1730
1731 return wps_registrar_config_ap(hapd->wps->registrar, &cred);
1732 }
1733
1734
1735 #ifdef CONFIG_WPS_NFC
1736
1737 struct wps_nfc_password_token_data {
1738 const u8 *oob_dev_pw;
1739 size_t oob_dev_pw_len;
1740 int added;
1741 };
1742
1743
1744 static int wps_add_nfc_password_token(struct hostapd_data *hapd, void *ctx)
1745 {
1746 struct wps_nfc_password_token_data *data = ctx;
1747 int ret;
1748
1749 if (hapd->wps == NULL)
1750 return 0;
1751 ret = wps_registrar_add_nfc_password_token(hapd->wps->registrar,
1752 data->oob_dev_pw,
1753 data->oob_dev_pw_len);
1754 if (ret == 0)
1755 data->added++;
1756 return ret;
1757 }
1758
1759
1760 static int hostapd_wps_add_nfc_password_token(struct hostapd_data *hapd,
1761 struct wps_parse_attr *attr)
1762 {
1763 struct wps_nfc_password_token_data data;
1764
1765 data.oob_dev_pw = attr->oob_dev_password;
1766 data.oob_dev_pw_len = attr->oob_dev_password_len;
1767 data.added = 0;
1768 if (hostapd_wps_for_each(hapd, wps_add_nfc_password_token, &data) < 0)
1769 return -1;
1770 return data.added ? 0 : -1;
1771 }
1772
1773
1774 static int hostapd_wps_nfc_tag_process(struct hostapd_data *hapd,
1775 const struct wpabuf *wps)
1776 {
1777 struct wps_parse_attr attr;
1778
1779 wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
1780
1781 if (wps_parse_msg(wps, &attr)) {
1782 wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
1783 return -1;
1784 }
1785
1786 if (attr.oob_dev_password)
1787 return hostapd_wps_add_nfc_password_token(hapd, &attr);
1788
1789 wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
1790 return -1;
1791 }
1792
1793
1794 int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd,
1795 const struct wpabuf *data)
1796 {
1797 const struct wpabuf *wps = data;
1798 struct wpabuf *tmp = NULL;
1799 int ret;
1800
1801 if (wpabuf_len(data) < 4)
1802 return -1;
1803
1804 if (*wpabuf_head_u8(data) != 0x10) {
1805 /* Assume this contains full NDEF record */
1806 tmp = ndef_parse_wifi(data);
1807 if (tmp == NULL) {
1808 wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
1809 return -1;
1810 }
1811 wps = tmp;
1812 }
1813
1814 ret = hostapd_wps_nfc_tag_process(hapd, wps);
1815 wpabuf_free(tmp);
1816 return ret;
1817 }
1818
1819
1820 struct wpabuf * hostapd_wps_nfc_config_token(struct hostapd_data *hapd,
1821 int ndef)
1822 {
1823 struct wpabuf *ret;
1824
1825 if (hapd->wps == NULL)
1826 return NULL;
1827
1828 ret = wps_get_oob_cred(hapd->wps, hostapd_wps_rf_band_cb(hapd),
1829 hapd->iconf->channel);
1830 if (ndef && ret) {
1831 struct wpabuf *tmp;
1832 tmp = ndef_build_wifi(ret);
1833 wpabuf_free(ret);
1834 if (tmp == NULL)
1835 return NULL;
1836 ret = tmp;
1837 }
1838
1839 return ret;
1840 }
1841
1842
1843 struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef)
1844 {
1845 struct wpabuf *ret;
1846
1847 if (hapd->wps == NULL)
1848 return NULL;
1849
1850 if (hapd->conf->wps_nfc_dh_pubkey == NULL) {
1851 struct wps_context *wps = hapd->wps;
1852 if (wps_nfc_gen_dh(&hapd->conf->wps_nfc_dh_pubkey,
1853 &hapd->conf->wps_nfc_dh_privkey) < 0)
1854 return NULL;
1855 hostapd_wps_nfc_clear(wps);
1856 wps->ap_nfc_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
1857 wps->ap_nfc_dh_pubkey =
1858 wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey);
1859 wps->ap_nfc_dh_privkey =
1860 wpabuf_dup(hapd->conf->wps_nfc_dh_privkey);
1861 if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey) {
1862 hostapd_wps_nfc_clear(wps);
1863 return NULL;
1864 }
1865 }
1866
1867 ret = wps_build_nfc_handover_sel(hapd->wps,
1868 hapd->conf->wps_nfc_dh_pubkey,
1869 hapd->own_addr, hapd->iface->freq);
1870
1871 if (ndef && ret) {
1872 struct wpabuf *tmp;
1873 tmp = ndef_build_wifi(ret);
1874 wpabuf_free(ret);
1875 if (tmp == NULL)
1876 return NULL;
1877 ret = tmp;
1878 }
1879
1880 return ret;
1881 }
1882
1883
1884 int hostapd_wps_nfc_report_handover(struct hostapd_data *hapd,
1885 const struct wpabuf *req,
1886 const struct wpabuf *sel)
1887 {
1888 struct wpabuf *wps;
1889 int ret = -1;
1890 u16 wsc_len;
1891 const u8 *pos;
1892 struct wpabuf msg;
1893 struct wps_parse_attr attr;
1894 u16 dev_pw_id;
1895
1896 /*
1897 * Enrollee/station is always initiator of the NFC connection handover,
1898 * so use the request message here to find Enrollee public key hash.
1899 */
1900 wps = ndef_parse_wifi(req);
1901 if (wps == NULL)
1902 return -1;
1903 wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
1904 "payload from NFC connection handover");
1905 wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
1906 if (wpabuf_len(wps) < 2) {
1907 wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Request "
1908 "Message");
1909 goto out;
1910 }
1911 pos = wpabuf_head(wps);
1912 wsc_len = WPA_GET_BE16(pos);
1913 if (wsc_len > wpabuf_len(wps) - 2) {
1914 wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
1915 "in rt Wi-Fi Handover Request Message", wsc_len);
1916 goto out;
1917 }
1918 pos += 2;
1919
1920 wpa_hexdump(MSG_DEBUG,
1921 "WPS: WSC attributes in Wi-Fi Handover Request Message",
1922 pos, wsc_len);
1923 if (wsc_len < wpabuf_len(wps) - 2) {
1924 wpa_hexdump(MSG_DEBUG,
1925 "WPS: Ignore extra data after WSC attributes",
1926 pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
1927 }
1928
1929 wpabuf_set(&msg, pos, wsc_len);
1930 ret = wps_parse_msg(&msg, &attr);
1931 if (ret < 0) {
1932 wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
1933 "Wi-Fi Handover Request Message");
1934 goto out;
1935 }
1936
1937 if (attr.oob_dev_password == NULL ||
1938 attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
1939 wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
1940 "included in Wi-Fi Handover Request Message");
1941 ret = -1;
1942 goto out;
1943 }
1944
1945 if (attr.uuid_e == NULL) {
1946 wpa_printf(MSG_DEBUG, "WPS: No UUID-E included in Wi-Fi "
1947 "Handover Request Message");
1948 ret = -1;
1949 goto out;
1950 }
1951
1952 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", attr.uuid_e, WPS_UUID_LEN);
1953
1954 wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
1955 attr.oob_dev_password, attr.oob_dev_password_len);
1956 dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
1957 WPS_OOB_PUBKEY_HASH_LEN);
1958 if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
1959 wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
1960 "%u in Wi-Fi Handover Request Message", dev_pw_id);
1961 ret = -1;
1962 goto out;
1963 }
1964 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Public Key hash",
1965 attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
1966
1967 ret = wps_registrar_add_nfc_pw_token(hapd->wps->registrar,
1968 attr.oob_dev_password,
1969 DEV_PW_NFC_CONNECTION_HANDOVER,
1970 NULL, 0, 1);
1971
1972 out:
1973 wpabuf_free(wps);
1974 return ret;
1975 }
1976
1977
1978 struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef)
1979 {
1980 if (hapd->conf->wps_nfc_pw_from_config) {
1981 return wps_nfc_token_build(ndef,
1982 hapd->conf->wps_nfc_dev_pw_id,
1983 hapd->conf->wps_nfc_dh_pubkey,
1984 hapd->conf->wps_nfc_dev_pw);
1985 }
1986
1987 return wps_nfc_token_gen(ndef, &hapd->conf->wps_nfc_dev_pw_id,
1988 &hapd->conf->wps_nfc_dh_pubkey,
1989 &hapd->conf->wps_nfc_dh_privkey,
1990 &hapd->conf->wps_nfc_dev_pw);
1991 }
1992
1993
1994 int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd)
1995 {
1996 struct wps_context *wps = hapd->wps;
1997 struct wpabuf *pw;
1998
1999 if (wps == NULL)
2000 return -1;
2001
2002 if (!hapd->conf->wps_nfc_dh_pubkey ||
2003 !hapd->conf->wps_nfc_dh_privkey ||
2004 !hapd->conf->wps_nfc_dev_pw ||
2005 !hapd->conf->wps_nfc_dev_pw_id)
2006 return -1;
2007
2008 hostapd_wps_nfc_clear(wps);
2009 wpa_printf(MSG_DEBUG,
2010 "WPS: Enable NFC Tag (Dev Pw Id %u) for AP interface %s (context %p)",
2011 hapd->conf->wps_nfc_dev_pw_id, hapd->conf->iface, wps);
2012 wps->ap_nfc_dev_pw_id = hapd->conf->wps_nfc_dev_pw_id;
2013 wps->ap_nfc_dh_pubkey = wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey);
2014 wps->ap_nfc_dh_privkey = wpabuf_dup(hapd->conf->wps_nfc_dh_privkey);
2015 pw = hapd->conf->wps_nfc_dev_pw;
2016 wps->ap_nfc_dev_pw = wpabuf_alloc(
2017 wpabuf_len(pw) * 2 + 1);
2018 if (wps->ap_nfc_dev_pw) {
2019 wpa_snprintf_hex_uppercase(
2020 (char *) wpabuf_put(wps->ap_nfc_dev_pw,
2021 wpabuf_len(pw) * 2),
2022 wpabuf_len(pw) * 2 + 1,
2023 wpabuf_head(pw), wpabuf_len(pw));
2024 }
2025
2026 if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey ||
2027 !wps->ap_nfc_dev_pw) {
2028 hostapd_wps_nfc_clear(wps);
2029 return -1;
2030 }
2031
2032 return 0;
2033 }
2034
2035
2036 void hostapd_wps_nfc_token_disable(struct hostapd_data *hapd)
2037 {
2038 wpa_printf(MSG_DEBUG, "WPS: Disable NFC token for AP interface %s",
2039 hapd->conf->iface);
2040 hostapd_wps_nfc_clear(hapd->wps);
2041 }
2042
2043 #endif /* CONFIG_WPS_NFC */