wps_hostapd.c revision d11f019d62a42a8fc4c4d1f2ec17cf35b0763153
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"
33static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
34				 struct wps_context *wps);
35static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);
36#endif /* CONFIG_WPS_UPNP */
37
38static 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);
42static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
43static void hostapd_wps_nfc_clear(struct wps_context *wps);
44
45
46struct 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
53static 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
78static 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
95static 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
157static 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
171static 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
210struct 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
217static 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
227static 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
249static 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
272static int str_starts(const char *str, const char *start)
273{
274	return os_strncmp(str, start, os_strlen(start)) == 0;
275}
276
277
278static 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
291void 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
305static 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
319static 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
435static 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
680static 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
687static 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
703static 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
755static 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
768static 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
785static 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
791static 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
798static 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
805static 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
812static 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
819static 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
829static 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
852static 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
908static 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
917static 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
932static 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
952static 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
965static int count_interface_cb(struct hostapd_iface *iface, void *ctx)
966{
967	int *count= ctx;
968	(*count)++;
969	return 0;
970}
971
972
973static 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
985static 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
1010static 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
1025int 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
1232fail:
1233	hostapd_free_wps(wps);
1234	return -1;
1235}
1236
1237
1238int 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
1259static 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
1274void 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
1294void 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
1316struct 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
1326static 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
1342int 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
1368static 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
1377int 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
1385static 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
1397int hostapd_wps_cancel(struct hostapd_data *hapd)
1398{
1399	return hostapd_wps_for_each(hapd, wps_cancel, NULL);
1400}
1401
1402
1403static 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
1463static 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
1532static 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
1557static 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
1565int 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
1574static 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
1583static 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
1601static 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
1613void 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
1620struct wps_ap_pin_data {
1621	char pin_txt[9];
1622	int timeout;
1623};
1624
1625
1626static 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
1639const 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
1652const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd)
1653{
1654	return hapd->conf->ap_pin;
1655}
1656
1657
1658int 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
1672static 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
1680void hostapd_wps_update_ie(struct hostapd_data *hapd)
1681{
1682	hostapd_wps_for_each(hapd, wps_update_ie, NULL);
1683}
1684
1685
1686int 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
1737struct wps_nfc_password_token_data {
1738	const u8 *oob_dev_pw;
1739	size_t oob_dev_pw_len;
1740	int added;
1741};
1742
1743
1744static 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
1760static 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
1774static 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
1794int 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
1820struct 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
1843struct 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
1884int 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
1972out:
1973	wpabuf_free(wps);
1974	return ret;
1975}
1976
1977
1978struct 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
1994int 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
2036void 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 */
2044