Line data Source code
1 : /*
2 : * wpa_supplicant / WPS integration
3 : * Copyright (c) 2008-2014, 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 "includes.h"
10 :
11 : #include "common.h"
12 : #include "eloop.h"
13 : #include "uuid.h"
14 : #include "crypto/random.h"
15 : #include "crypto/dh_group5.h"
16 : #include "common/ieee802_11_defs.h"
17 : #include "common/ieee802_11_common.h"
18 : #include "common/wpa_common.h"
19 : #include "common/wpa_ctrl.h"
20 : #include "eap_common/eap_wsc_common.h"
21 : #include "eap_peer/eap.h"
22 : #include "eapol_supp/eapol_supp_sm.h"
23 : #include "rsn_supp/wpa.h"
24 : #include "wps/wps_attr_parse.h"
25 : #include "config.h"
26 : #include "wpa_supplicant_i.h"
27 : #include "driver_i.h"
28 : #include "notify.h"
29 : #include "blacklist.h"
30 : #include "bss.h"
31 : #include "scan.h"
32 : #include "ap.h"
33 : #include "p2p/p2p.h"
34 : #include "p2p_supplicant.h"
35 : #include "wps_supplicant.h"
36 :
37 :
38 : #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
39 : #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
40 : #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
41 :
42 : static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
43 : static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
44 :
45 :
46 5715 : static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
47 : {
48 5715 : os_free(wpa_s->wps_ap);
49 5715 : wpa_s->wps_ap = NULL;
50 5715 : wpa_s->num_wps_ap = 0;
51 5715 : wpa_s->wps_ap_iter = 0;
52 5715 : }
53 :
54 :
55 237 : static void wpas_wps_assoc_with_cred(void *eloop_ctx, void *timeout_ctx)
56 : {
57 237 : struct wpa_supplicant *wpa_s = eloop_ctx;
58 237 : int use_fast_assoc = timeout_ctx != NULL;
59 :
60 237 : wpa_printf(MSG_DEBUG, "WPS: Continuing association after eapol_cb");
61 462 : if (!use_fast_assoc ||
62 225 : wpa_supplicant_fast_associate(wpa_s) != 1)
63 12 : wpa_supplicant_req_scan(wpa_s, 0, 0);
64 237 : }
65 :
66 :
67 449 : static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
68 : {
69 449 : eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 0);
70 449 : eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 1);
71 449 : }
72 :
73 :
74 2003 : int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
75 : {
76 2003 : if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
77 3 : return 1;
78 :
79 2596 : if (!wpa_s->wps_success &&
80 1192 : wpa_s->current_ssid &&
81 596 : eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
82 9 : const u8 *bssid = wpa_s->bssid;
83 9 : if (is_zero_ether_addr(bssid))
84 0 : bssid = wpa_s->pending_bssid;
85 :
86 54 : wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
87 : " did not succeed - continue trying to find "
88 54 : "suitable AP", MAC2STR(bssid));
89 9 : wpa_blacklist_add(wpa_s, bssid);
90 :
91 9 : wpa_supplicant_deauthenticate(wpa_s,
92 : WLAN_REASON_DEAUTH_LEAVING);
93 9 : wpa_s->reassociate = 1;
94 9 : wpa_supplicant_req_scan(wpa_s,
95 9 : wpa_s->blacklist_cleared ? 5 : 0, 0);
96 9 : wpa_s->blacklist_cleared = 0;
97 9 : return 1;
98 : }
99 :
100 1991 : wpas_wps_clear_ap_info(wpa_s);
101 1991 : eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
102 1991 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success)
103 44 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL);
104 :
105 2253 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
106 262 : !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
107 237 : int disabled = wpa_s->current_ssid->disabled;
108 237 : unsigned int freq = wpa_s->assoc_freq;
109 : struct wpa_bss *bss;
110 237 : struct wpa_ssid *ssid = NULL;
111 237 : int use_fast_assoc = 0;
112 :
113 237 : wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
114 : "try to associate with the received credential "
115 : "(freq=%u)", freq);
116 237 : wpa_supplicant_deauthenticate(wpa_s,
117 : WLAN_REASON_DEAUTH_LEAVING);
118 237 : if (disabled) {
119 0 : wpa_printf(MSG_DEBUG, "WPS: Current network is "
120 : "disabled - wait for user to enable");
121 0 : return 1;
122 : }
123 237 : wpa_s->after_wps = 5;
124 237 : wpa_s->wps_freq = freq;
125 237 : wpa_s->normal_scans = 0;
126 237 : wpa_s->reassociate = 1;
127 :
128 237 : wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
129 : "without a new scan can be used");
130 237 : bss = wpa_supplicant_pick_network(wpa_s, &ssid);
131 237 : if (bss) {
132 : struct wpabuf *wps;
133 : struct wps_parse_attr attr;
134 :
135 225 : wps = wpa_bss_get_vendor_ie_multi(bss,
136 : WPS_IE_VENDOR_TYPE);
137 450 : if (wps && wps_parse_msg(wps, &attr) == 0 &&
138 450 : attr.wps_state &&
139 225 : *attr.wps_state == WPS_STATE_CONFIGURED)
140 225 : use_fast_assoc = 1;
141 225 : wpabuf_free(wps);
142 : }
143 :
144 : /*
145 : * Complete the next step from an eloop timeout to allow pending
146 : * driver events related to the disconnection to be processed
147 : * first. This makes it less likely for disconnection event to
148 : * cause problems with the following connection.
149 : */
150 237 : wpa_printf(MSG_DEBUG, "WPS: Continue association from timeout");
151 237 : wpas_wps_assoc_with_cred_cancel(wpa_s);
152 237 : eloop_register_timeout(0, 10000,
153 : wpas_wps_assoc_with_cred, wpa_s,
154 : use_fast_assoc ? (void *) 1 :
155 : (void *) 0);
156 237 : return 1;
157 : }
158 :
159 1754 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
160 25 : wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
161 : "for external credential processing");
162 25 : wpas_clear_wps(wpa_s);
163 25 : wpa_supplicant_deauthenticate(wpa_s,
164 : WLAN_REASON_DEAUTH_LEAVING);
165 25 : return 1;
166 : }
167 :
168 1729 : return 0;
169 : }
170 :
171 :
172 245 : static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
173 : struct wpa_ssid *ssid,
174 : const struct wps_credential *cred)
175 : {
176 : struct wpa_driver_capa capa;
177 : struct wpa_bss *bss;
178 : const u8 *ie;
179 : struct wpa_ie_data adv;
180 245 : int wpa2 = 0, ccmp = 0;
181 :
182 : /*
183 : * Many existing WPS APs do not know how to negotiate WPA2 or CCMP in
184 : * case they are configured for mixed mode operation (WPA+WPA2 and
185 : * TKIP+CCMP). Try to use scan results to figure out whether the AP
186 : * actually supports stronger security and select that if the client
187 : * has support for it, too.
188 : */
189 :
190 245 : if (wpa_drv_get_capa(wpa_s, &capa))
191 224 : return; /* Unknown what driver supports */
192 :
193 245 : if (ssid->ssid == NULL)
194 0 : return;
195 245 : bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
196 245 : if (bss == NULL) {
197 224 : wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
198 : "table - use credential as-is");
199 224 : return;
200 : }
201 :
202 21 : wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
203 :
204 21 : ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
205 21 : if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
206 20 : wpa2 = 1;
207 40 : if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
208 20 : ccmp = 1;
209 : } else {
210 1 : ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
211 1 : if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 &&
212 0 : adv.pairwise_cipher & WPA_CIPHER_CCMP)
213 0 : ccmp = 1;
214 : }
215 :
216 21 : if (ie == NULL && (ssid->proto & WPA_PROTO_WPA) &&
217 0 : (ssid->pairwise_cipher & WPA_CIPHER_TKIP)) {
218 : /*
219 : * TODO: This could be the initial AP configuration and the
220 : * Beacon contents could change shortly. Should request a new
221 : * scan and delay addition of the network until the updated
222 : * scan results are available.
223 : */
224 0 : wpa_printf(MSG_DEBUG, "WPS: The AP did not yet advertise WPA "
225 : "support - use credential as-is");
226 0 : return;
227 : }
228 :
229 21 : if (ccmp && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
230 0 : (ssid->pairwise_cipher & WPA_CIPHER_TKIP) &&
231 0 : (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
232 0 : wpa_printf(MSG_DEBUG, "WPS: Add CCMP into the credential "
233 : "based on scan results");
234 0 : if (wpa_s->conf->ap_scan == 1)
235 0 : ssid->pairwise_cipher |= WPA_CIPHER_CCMP;
236 : else
237 0 : ssid->pairwise_cipher = WPA_CIPHER_CCMP;
238 : }
239 :
240 21 : if (wpa2 && !(ssid->proto & WPA_PROTO_RSN) &&
241 0 : (ssid->proto & WPA_PROTO_WPA) &&
242 0 : (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
243 0 : wpa_printf(MSG_DEBUG, "WPS: Add WPA2 into the credential "
244 : "based on scan results");
245 0 : if (wpa_s->conf->ap_scan == 1)
246 0 : ssid->proto |= WPA_PROTO_RSN;
247 : else
248 0 : ssid->proto = WPA_PROTO_RSN;
249 : }
250 : }
251 :
252 :
253 245 : static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s,
254 : struct wpa_ssid *new_ssid)
255 : {
256 : struct wpa_ssid *ssid, *next;
257 :
258 744 : for (ssid = wpa_s->conf->ssid, next = ssid ? ssid->next : NULL; ssid;
259 254 : ssid = next, next = ssid ? ssid->next : NULL) {
260 : /*
261 : * new_ssid has already been added to the list in
262 : * wpas_wps_add_network(), so skip it.
263 : */
264 254 : if (ssid == new_ssid)
265 245 : continue;
266 :
267 9 : if (ssid->bssid_set || new_ssid->bssid_set) {
268 3 : if (ssid->bssid_set != new_ssid->bssid_set)
269 2 : continue;
270 1 : if (os_memcmp(ssid->bssid, new_ssid->bssid, ETH_ALEN) !=
271 : 0)
272 0 : continue;
273 : }
274 :
275 : /* compare SSID */
276 7 : if (ssid->ssid_len == 0 || ssid->ssid_len != new_ssid->ssid_len)
277 3 : continue;
278 :
279 4 : if (ssid->ssid && new_ssid->ssid) {
280 8 : if (os_memcmp(ssid->ssid, new_ssid->ssid,
281 : ssid->ssid_len) != 0)
282 0 : continue;
283 0 : } else if (ssid->ssid || new_ssid->ssid)
284 0 : continue;
285 :
286 : /* compare security parameters */
287 7 : if (ssid->auth_alg != new_ssid->auth_alg ||
288 6 : ssid->key_mgmt != new_ssid->key_mgmt ||
289 5 : (ssid->group_cipher != new_ssid->group_cipher &&
290 2 : !(ssid->group_cipher & new_ssid->group_cipher &
291 : WPA_CIPHER_CCMP)))
292 1 : continue;
293 :
294 : /*
295 : * Some existing WPS APs will send two creds in case they are
296 : * configured for mixed mode operation (WPA+WPA2 and TKIP+CCMP).
297 : * Try to merge these two creds if they are received in the same
298 : * M8 message.
299 : */
300 4 : if (ssid->wps_run && ssid->wps_run == new_ssid->wps_run &&
301 1 : wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
302 2 : if (new_ssid->passphrase && ssid->passphrase &&
303 1 : os_strcmp(new_ssid->passphrase, ssid->passphrase) !=
304 : 0) {
305 0 : wpa_printf(MSG_DEBUG,
306 : "WPS: M8 Creds with different passphrase - do not merge");
307 0 : continue;
308 : }
309 :
310 2 : if (new_ssid->psk_set &&
311 2 : (!ssid->psk_set ||
312 1 : os_memcmp(new_ssid->psk, ssid->psk, 32) != 0)) {
313 0 : wpa_printf(MSG_DEBUG,
314 : "WPS: M8 Creds with different PSK - do not merge");
315 0 : continue;
316 : }
317 :
318 2 : if ((new_ssid->passphrase && !ssid->passphrase) ||
319 1 : (!new_ssid->passphrase && ssid->passphrase)) {
320 0 : wpa_printf(MSG_DEBUG,
321 : "WPS: M8 Creds with different passphrase/PSK type - do not merge");
322 0 : continue;
323 : }
324 :
325 1 : wpa_printf(MSG_DEBUG,
326 : "WPS: Workaround - merge likely WPA/WPA2-mixed mode creds in same M8 message");
327 1 : new_ssid->proto |= ssid->proto;
328 1 : new_ssid->pairwise_cipher |= ssid->pairwise_cipher;
329 : } else {
330 : /*
331 : * proto and pairwise_cipher difference matter for
332 : * non-mixed-mode creds.
333 : */
334 4 : if (ssid->proto != new_ssid->proto ||
335 2 : ssid->pairwise_cipher != new_ssid->pairwise_cipher)
336 1 : continue;
337 : }
338 :
339 : /* Remove the duplicated older network entry. */
340 2 : wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id);
341 2 : wpas_notify_network_removed(wpa_s, ssid);
342 2 : if (wpa_s->current_ssid == ssid)
343 1 : wpa_s->current_ssid = NULL;
344 2 : wpa_config_remove_network(wpa_s->conf, ssid->id);
345 : }
346 245 : }
347 :
348 :
349 245 : static int wpa_supplicant_wps_cred(void *ctx,
350 : const struct wps_credential *cred)
351 : {
352 245 : struct wpa_supplicant *wpa_s = ctx;
353 245 : struct wpa_ssid *ssid = wpa_s->current_ssid;
354 : u16 auth_type;
355 : #ifdef CONFIG_WPS_REG_DISABLE_OPEN
356 : int registrar = 0;
357 : #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
358 :
359 490 : if ((wpa_s->conf->wps_cred_processing == 1 ||
360 267 : wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
361 11 : size_t blen = cred->cred_attr_len * 2 + 1;
362 11 : char *buf = os_malloc(blen);
363 11 : if (buf) {
364 11 : wpa_snprintf_hex(buf, blen,
365 : cred->cred_attr, cred->cred_attr_len);
366 11 : wpa_msg(wpa_s, MSG_INFO, "%s%s",
367 : WPS_EVENT_CRED_RECEIVED, buf);
368 11 : os_free(buf);
369 : }
370 :
371 11 : wpas_notify_wps_credential(wpa_s, cred);
372 : } else
373 234 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
374 :
375 490 : wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
376 245 : cred->cred_attr, cred->cred_attr_len);
377 :
378 245 : if (wpa_s->conf->wps_cred_processing == 1)
379 0 : return 0;
380 :
381 245 : wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
382 245 : wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
383 245 : cred->auth_type);
384 245 : wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
385 245 : wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
386 490 : wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
387 245 : cred->key, cred->key_len);
388 1470 : wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
389 1470 : MAC2STR(cred->mac_addr));
390 :
391 245 : auth_type = cred->auth_type;
392 245 : if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
393 0 : wpa_printf(MSG_DEBUG, "WPS: Workaround - convert mixed-mode "
394 : "auth_type into WPA2PSK");
395 0 : auth_type = WPS_AUTH_WPA2PSK;
396 : }
397 :
398 245 : if (auth_type != WPS_AUTH_OPEN &&
399 242 : auth_type != WPS_AUTH_WPAPSK &&
400 : auth_type != WPS_AUTH_WPA2PSK) {
401 0 : wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for "
402 : "unsupported authentication type 0x%x",
403 : auth_type);
404 0 : return 0;
405 : }
406 :
407 245 : if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) {
408 244 : if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) {
409 0 : wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with "
410 : "invalid Network Key length %lu",
411 : (unsigned long) cred->key_len);
412 0 : return -1;
413 : }
414 : }
415 :
416 245 : if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
417 238 : wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
418 : "on the received credential");
419 : #ifdef CONFIG_WPS_REG_DISABLE_OPEN
420 : if (ssid->eap.identity &&
421 : ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
422 : os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
423 : WSC_ID_REGISTRAR_LEN) == 0)
424 : registrar = 1;
425 : #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
426 238 : os_free(ssid->eap.identity);
427 238 : ssid->eap.identity = NULL;
428 238 : ssid->eap.identity_len = 0;
429 238 : os_free(ssid->eap.phase1);
430 238 : ssid->eap.phase1 = NULL;
431 238 : os_free(ssid->eap.eap_methods);
432 238 : ssid->eap.eap_methods = NULL;
433 238 : if (!ssid->p2p_group) {
434 84 : ssid->temporary = 0;
435 84 : ssid->bssid_set = 0;
436 : }
437 238 : ssid->disabled_until.sec = 0;
438 238 : ssid->disabled_until.usec = 0;
439 238 : ssid->auth_failures = 0;
440 : } else {
441 7 : wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
442 : "received credential");
443 7 : ssid = wpa_config_add_network(wpa_s->conf);
444 7 : if (ssid == NULL)
445 0 : return -1;
446 7 : if (wpa_s->current_ssid) {
447 : /*
448 : * Should the GO issue multiple credentials for some
449 : * reason, each credential should be marked as a
450 : * temporary P2P group similarly to the one that gets
451 : * marked as such based on the pre-configured values
452 : * used for the WPS network block.
453 : */
454 3 : ssid->p2p_group = wpa_s->current_ssid->p2p_group;
455 3 : ssid->temporary = wpa_s->current_ssid->temporary;
456 : }
457 7 : wpas_notify_network_added(wpa_s, ssid);
458 : }
459 :
460 245 : wpa_config_set_network_defaults(ssid);
461 245 : ssid->wps_run = wpa_s->wps_run;
462 :
463 245 : os_free(ssid->ssid);
464 245 : ssid->ssid = os_malloc(cred->ssid_len);
465 245 : if (ssid->ssid) {
466 245 : os_memcpy(ssid->ssid, cred->ssid, cred->ssid_len);
467 245 : ssid->ssid_len = cred->ssid_len;
468 : }
469 :
470 245 : switch (cred->encr_type) {
471 : case WPS_ENCR_NONE:
472 1 : break;
473 : case WPS_ENCR_TKIP:
474 2 : ssid->pairwise_cipher = WPA_CIPHER_TKIP;
475 2 : break;
476 : case WPS_ENCR_AES:
477 242 : ssid->pairwise_cipher = WPA_CIPHER_CCMP;
478 484 : if (wpa_s->drv_capa_known &&
479 242 : (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP)) {
480 242 : ssid->pairwise_cipher |= WPA_CIPHER_GCMP;
481 242 : ssid->group_cipher |= WPA_CIPHER_GCMP;
482 : }
483 242 : break;
484 : }
485 :
486 245 : switch (auth_type) {
487 : case WPS_AUTH_OPEN:
488 1 : ssid->auth_alg = WPA_AUTH_ALG_OPEN;
489 1 : ssid->key_mgmt = WPA_KEY_MGMT_NONE;
490 1 : ssid->proto = 0;
491 : #ifdef CONFIG_WPS_REG_DISABLE_OPEN
492 : if (registrar) {
493 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OPEN_NETWORK
494 : "id=%d - Credentials for an open "
495 : "network disabled by default - use "
496 : "'select_network %d' to enable",
497 : ssid->id, ssid->id);
498 : ssid->disabled = 1;
499 : }
500 : #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
501 1 : break;
502 : case WPS_AUTH_WPAPSK:
503 2 : ssid->auth_alg = WPA_AUTH_ALG_OPEN;
504 2 : ssid->key_mgmt = WPA_KEY_MGMT_PSK;
505 2 : ssid->proto = WPA_PROTO_WPA;
506 2 : break;
507 : case WPS_AUTH_WPA2PSK:
508 242 : ssid->auth_alg = WPA_AUTH_ALG_OPEN;
509 242 : ssid->key_mgmt = WPA_KEY_MGMT_PSK;
510 242 : ssid->proto = WPA_PROTO_RSN;
511 242 : break;
512 : }
513 :
514 245 : if (ssid->key_mgmt == WPA_KEY_MGMT_PSK) {
515 244 : if (cred->key_len == 2 * PMK_LEN) {
516 171 : if (hexstr2bin((const char *) cred->key, ssid->psk,
517 : PMK_LEN)) {
518 0 : wpa_printf(MSG_ERROR, "WPS: Invalid Network "
519 : "Key");
520 0 : return -1;
521 : }
522 171 : ssid->psk_set = 1;
523 171 : ssid->export_keys = 1;
524 73 : } else if (cred->key_len >= 8 && cred->key_len < 2 * PMK_LEN) {
525 73 : os_free(ssid->passphrase);
526 73 : ssid->passphrase = os_malloc(cred->key_len + 1);
527 73 : if (ssid->passphrase == NULL)
528 0 : return -1;
529 73 : os_memcpy(ssid->passphrase, cred->key, cred->key_len);
530 73 : ssid->passphrase[cred->key_len] = '\0';
531 73 : wpa_config_update_psk(ssid);
532 73 : ssid->export_keys = 1;
533 : } else {
534 0 : wpa_printf(MSG_ERROR, "WPS: Invalid Network Key "
535 : "length %lu",
536 : (unsigned long) cred->key_len);
537 0 : return -1;
538 : }
539 : }
540 :
541 245 : wpas_wps_security_workaround(wpa_s, ssid, cred);
542 :
543 245 : wpas_wps_remove_dup_network(wpa_s, ssid);
544 :
545 : #ifndef CONFIG_NO_CONFIG_WRITE
546 245 : if (wpa_s->conf->update_config &&
547 0 : wpa_config_write(wpa_s->confname, wpa_s->conf)) {
548 0 : wpa_printf(MSG_DEBUG, "WPS: Failed to update configuration");
549 0 : return -1;
550 : }
551 : #endif /* CONFIG_NO_CONFIG_WRITE */
552 :
553 : /*
554 : * Optimize the post-WPS scan based on the channel used during
555 : * the provisioning in case EAP-Failure is not received.
556 : */
557 245 : wpa_s->after_wps = 5;
558 245 : wpa_s->wps_freq = wpa_s->assoc_freq;
559 :
560 245 : return 0;
561 : }
562 :
563 :
564 23 : static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
565 : struct wps_event_m2d *m2d)
566 : {
567 46 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
568 : "dev_password_id=%d config_error=%d",
569 46 : m2d->dev_password_id, m2d->config_error);
570 23 : wpas_notify_wps_event_m2d(wpa_s, m2d);
571 : #ifdef CONFIG_P2P
572 23 : if (wpa_s->parent && wpa_s->parent != wpa_s) {
573 4 : wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_M2D
574 : "dev_password_id=%d config_error=%d",
575 4 : m2d->dev_password_id, m2d->config_error);
576 : }
577 23 : if (m2d->config_error == WPS_CFG_MULTIPLE_PBC_DETECTED) {
578 : /*
579 : * Notify P2P from eloop timeout to avoid issues with the
580 : * interface getting removed while processing a message.
581 : */
582 5 : eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, wpa_s,
583 : NULL);
584 : }
585 : #endif /* CONFIG_P2P */
586 23 : }
587 :
588 :
589 23 : static void wpas_wps_clear_timeout(void *eloop_ctx, void *timeout_ctx)
590 : {
591 23 : struct wpa_supplicant *wpa_s = eloop_ctx;
592 23 : wpa_printf(MSG_DEBUG, "WPS: Clear WPS network from timeout");
593 23 : wpas_clear_wps(wpa_s);
594 23 : }
595 :
596 :
597 43 : static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
598 : struct wps_event_fail *fail)
599 : {
600 44 : if (fail->error_indication > 0 &&
601 1 : fail->error_indication < NUM_WPS_EI_VALUES) {
602 3 : wpa_msg(wpa_s, MSG_INFO,
603 : WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
604 2 : fail->msg, fail->config_error, fail->error_indication,
605 1 : wps_ei_str(fail->error_indication));
606 2 : if (wpa_s->parent && wpa_s->parent != wpa_s)
607 0 : wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
608 : "msg=%d config_error=%d reason=%d (%s)",
609 0 : fail->msg, fail->config_error,
610 0 : fail->error_indication,
611 0 : wps_ei_str(fail->error_indication));
612 : } else {
613 42 : wpa_msg(wpa_s, MSG_INFO,
614 : WPS_EVENT_FAIL "msg=%d config_error=%d",
615 42 : fail->msg, fail->config_error);
616 42 : if (wpa_s->parent && wpa_s->parent != wpa_s)
617 1 : wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
618 : "msg=%d config_error=%d",
619 1 : fail->msg, fail->config_error);
620 : }
621 :
622 : /*
623 : * Need to allow WPS processing to complete, e.g., by sending WSC_NACK.
624 : */
625 43 : wpa_printf(MSG_DEBUG, "WPS: Register timeout to clear WPS network");
626 43 : eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
627 43 : eloop_register_timeout(0, 100000, wpas_wps_clear_timeout, wpa_s, NULL);
628 :
629 43 : wpas_notify_wps_event_fail(wpa_s, fail);
630 43 : wpas_p2p_wps_failed(wpa_s, fail);
631 43 : }
632 :
633 :
634 : static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx);
635 :
636 3516 : static void wpas_wps_reenable_networks(struct wpa_supplicant *wpa_s)
637 : {
638 : struct wpa_ssid *ssid;
639 3516 : int changed = 0;
640 :
641 3516 : eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
642 :
643 5474 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
644 1958 : if (ssid->disabled_for_connect && ssid->disabled) {
645 4 : ssid->disabled_for_connect = 0;
646 4 : ssid->disabled = 0;
647 4 : wpas_notify_network_enabled_changed(wpa_s, ssid);
648 4 : changed++;
649 : }
650 : }
651 :
652 3516 : if (changed) {
653 : #ifndef CONFIG_NO_CONFIG_WRITE
654 3 : if (wpa_s->conf->update_config &&
655 0 : wpa_config_write(wpa_s->confname, wpa_s->conf)) {
656 0 : wpa_printf(MSG_DEBUG, "WPS: Failed to update "
657 : "configuration");
658 : }
659 : #endif /* CONFIG_NO_CONFIG_WRITE */
660 : }
661 3516 : }
662 :
663 :
664 4 : static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx)
665 : {
666 4 : struct wpa_supplicant *wpa_s = eloop_ctx;
667 : /* Enable the networks disabled during wpas_wps_reassoc */
668 4 : wpas_wps_reenable_networks(wpa_s);
669 4 : }
670 :
671 :
672 226 : static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
673 : {
674 226 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
675 226 : wpa_s->wps_success = 1;
676 226 : wpas_notify_wps_event_success(wpa_s);
677 226 : if (wpa_s->current_ssid)
678 225 : wpas_clear_temp_disabled(wpa_s, wpa_s->current_ssid, 1);
679 226 : wpa_s->extra_blacklist_count = 0;
680 :
681 : /*
682 : * Enable the networks disabled during wpas_wps_reassoc after 10
683 : * seconds. The 10 seconds timer is to allow the data connection to be
684 : * formed before allowing other networks to be selected.
685 : */
686 226 : eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
687 : NULL);
688 :
689 226 : wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
690 226 : }
691 :
692 :
693 11 : static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
694 : struct wps_event_er_ap *ap)
695 : {
696 : char uuid_str[100];
697 : char dev_type[WPS_DEV_TYPE_BUFSIZE];
698 :
699 11 : uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
700 11 : if (ap->pri_dev_type)
701 11 : wps_dev_type_bin2str(ap->pri_dev_type, dev_type,
702 : sizeof(dev_type));
703 : else
704 0 : dev_type[0] = '\0';
705 :
706 143 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR
707 : " pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|",
708 77 : uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state,
709 11 : ap->friendly_name ? ap->friendly_name : "",
710 11 : ap->manufacturer ? ap->manufacturer : "",
711 11 : ap->model_description ? ap->model_description : "",
712 11 : ap->model_name ? ap->model_name : "",
713 11 : ap->manufacturer_url ? ap->manufacturer_url : "",
714 11 : ap->model_url ? ap->model_url : "");
715 11 : }
716 :
717 :
718 10 : static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
719 : struct wps_event_er_ap *ap)
720 : {
721 : char uuid_str[100];
722 10 : uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
723 10 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
724 10 : }
725 :
726 :
727 30 : static void wpa_supplicant_wps_event_er_enrollee_add(
728 : struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
729 : {
730 : char uuid_str[100];
731 : char dev_type[WPS_DEV_TYPE_BUFSIZE];
732 :
733 30 : uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
734 30 : if (enrollee->pri_dev_type)
735 30 : wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type,
736 : sizeof(dev_type));
737 : else
738 0 : dev_type[0] = '\0';
739 :
740 390 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
741 : " M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
742 : "|%s|%s|%s|%s|%s|",
743 180 : uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
744 60 : enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
745 30 : enrollee->dev_name ? enrollee->dev_name : "",
746 30 : enrollee->manufacturer ? enrollee->manufacturer : "",
747 30 : enrollee->model_name ? enrollee->model_name : "",
748 30 : enrollee->model_number ? enrollee->model_number : "",
749 30 : enrollee->serial_number ? enrollee->serial_number : "");
750 30 : }
751 :
752 :
753 21 : static void wpa_supplicant_wps_event_er_enrollee_remove(
754 : struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
755 : {
756 : char uuid_str[100];
757 21 : uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
758 126 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
759 126 : uuid_str, MAC2STR(enrollee->mac_addr));
760 21 : }
761 :
762 :
763 1 : static void wpa_supplicant_wps_event_er_ap_settings(
764 : struct wpa_supplicant *wpa_s,
765 : struct wps_event_er_ap_settings *ap_settings)
766 : {
767 : char uuid_str[100];
768 : char key_str[65];
769 1 : const struct wps_credential *cred = ap_settings->cred;
770 :
771 1 : key_str[0] = '\0';
772 1 : if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
773 1 : if (cred->key_len >= 8 && cred->key_len <= 64) {
774 1 : os_memcpy(key_str, cred->key, cred->key_len);
775 1 : key_str[cred->key_len] = '\0';
776 : }
777 : }
778 :
779 1 : uuid_bin2str(ap_settings->uuid, uuid_str, sizeof(uuid_str));
780 : /* Use wpa_msg_ctrl to avoid showing the key in debug log */
781 3 : wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_SETTINGS
782 : "uuid=%s ssid=%s auth_type=0x%04x encr_type=0x%04x "
783 : "key=%s",
784 1 : uuid_str, wpa_ssid_txt(cred->ssid, cred->ssid_len),
785 2 : cred->auth_type, cred->encr_type, key_str);
786 1 : }
787 :
788 :
789 44 : static void wpa_supplicant_wps_event_er_set_sel_reg(
790 : struct wpa_supplicant *wpa_s,
791 : struct wps_event_er_set_selected_registrar *ev)
792 : {
793 : char uuid_str[100];
794 :
795 44 : uuid_bin2str(ev->uuid, uuid_str, sizeof(uuid_str));
796 44 : switch (ev->state) {
797 : case WPS_ER_SET_SEL_REG_START:
798 52 : wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
799 : "uuid=%s state=START sel_reg=%d dev_passwd_id=%u "
800 : "sel_reg_config_methods=0x%x",
801 26 : uuid_str, ev->sel_reg, ev->dev_passwd_id,
802 26 : ev->sel_reg_config_methods);
803 26 : break;
804 : case WPS_ER_SET_SEL_REG_DONE:
805 18 : wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
806 : "uuid=%s state=DONE", uuid_str);
807 18 : break;
808 : case WPS_ER_SET_SEL_REG_FAILED:
809 0 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_SET_SEL_REG
810 : "uuid=%s state=FAILED", uuid_str);
811 0 : break;
812 : }
813 44 : }
814 :
815 :
816 417 : static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
817 : union wps_event_data *data)
818 : {
819 417 : struct wpa_supplicant *wpa_s = ctx;
820 417 : switch (event) {
821 : case WPS_EV_M2D:
822 23 : wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
823 23 : break;
824 : case WPS_EV_FAIL:
825 43 : wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
826 43 : break;
827 : case WPS_EV_SUCCESS:
828 226 : wpa_supplicant_wps_event_success(wpa_s);
829 226 : break;
830 : case WPS_EV_PWD_AUTH_FAIL:
831 : #ifdef CONFIG_AP
832 5 : if (wpa_s->ap_iface && data->pwd_auth_fail.enrollee)
833 0 : wpa_supplicant_ap_pwd_auth_fail(wpa_s);
834 : #endif /* CONFIG_AP */
835 5 : break;
836 : case WPS_EV_PBC_OVERLAP:
837 1 : break;
838 : case WPS_EV_PBC_TIMEOUT:
839 0 : break;
840 : case WPS_EV_PBC_ACTIVE:
841 1 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ACTIVE);
842 1 : break;
843 : case WPS_EV_PBC_DISABLE:
844 1 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_DISABLE);
845 1 : break;
846 : case WPS_EV_ER_AP_ADD:
847 11 : wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
848 11 : break;
849 : case WPS_EV_ER_AP_REMOVE:
850 10 : wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
851 10 : break;
852 : case WPS_EV_ER_ENROLLEE_ADD:
853 30 : wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
854 : &data->enrollee);
855 30 : break;
856 : case WPS_EV_ER_ENROLLEE_REMOVE:
857 21 : wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
858 : &data->enrollee);
859 21 : break;
860 : case WPS_EV_ER_AP_SETTINGS:
861 1 : wpa_supplicant_wps_event_er_ap_settings(wpa_s,
862 : &data->ap_settings);
863 1 : break;
864 : case WPS_EV_ER_SET_SELECTED_REGISTRAR:
865 44 : wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
866 : &data->set_sel_reg);
867 44 : break;
868 : case WPS_EV_AP_PIN_SUCCESS:
869 0 : break;
870 : }
871 417 : }
872 :
873 :
874 289 : static int wpa_supplicant_wps_rf_band(void *ctx)
875 : {
876 289 : struct wpa_supplicant *wpa_s = ctx;
877 :
878 289 : if (!wpa_s->current_ssid || !wpa_s->assoc_freq)
879 0 : return 0;
880 :
881 289 : return (wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ;
882 : }
883 :
884 :
885 660 : enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
886 : {
887 1170 : if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
888 510 : eap_is_wps_pin_enrollee(&ssid->eap))
889 541 : return WPS_REQ_ENROLLEE;
890 : else
891 119 : return WPS_REQ_REGISTRAR;
892 : }
893 :
894 :
895 2540 : static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
896 : {
897 : int id;
898 2540 : struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
899 :
900 2540 : wpa_s->after_wps = 0;
901 2540 : wpa_s->known_wps_freq = 0;
902 :
903 2540 : prev_current = wpa_s->current_ssid;
904 :
905 : /* Enable the networks disabled during wpas_wps_reassoc */
906 2540 : wpas_wps_reenable_networks(wpa_s);
907 :
908 2540 : eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
909 2540 : eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
910 :
911 : /* Remove any existing WPS network from configuration */
912 2540 : ssid = wpa_s->conf->ssid;
913 6016 : while (ssid) {
914 936 : if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
915 35 : if (ssid == wpa_s->current_ssid) {
916 26 : wpa_supplicant_deauthenticate(
917 : wpa_s, WLAN_REASON_DEAUTH_LEAVING);
918 : }
919 35 : id = ssid->id;
920 35 : remove_ssid = ssid;
921 : } else
922 901 : id = -1;
923 936 : ssid = ssid->next;
924 936 : if (id >= 0) {
925 35 : if (prev_current == remove_ssid) {
926 26 : wpa_sm_set_config(wpa_s->wpa, NULL);
927 26 : eapol_sm_notify_config(wpa_s->eapol, NULL,
928 : NULL);
929 : }
930 35 : wpas_notify_network_removed(wpa_s, remove_ssid);
931 35 : wpa_config_remove_network(wpa_s->conf, id);
932 : }
933 : }
934 :
935 2540 : wpas_wps_clear_ap_info(wpa_s);
936 2540 : }
937 :
938 :
939 1 : static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
940 : {
941 1 : struct wpa_supplicant *wpa_s = eloop_ctx;
942 1 : wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
943 : "out");
944 1 : wpas_clear_wps(wpa_s);
945 1 : }
946 :
947 :
948 285 : static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
949 : int registrar, const u8 *dev_addr,
950 : const u8 *bssid)
951 : {
952 : struct wpa_ssid *ssid;
953 :
954 285 : ssid = wpa_config_add_network(wpa_s->conf);
955 285 : if (ssid == NULL)
956 4 : return NULL;
957 281 : wpas_notify_network_added(wpa_s, ssid);
958 281 : wpa_config_set_network_defaults(ssid);
959 281 : ssid->temporary = 1;
960 562 : if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
961 562 : wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
962 281 : wpa_config_set(ssid, "identity", registrar ?
963 : "\"" WSC_ID_REGISTRAR "\"" :
964 : "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
965 0 : wpas_notify_network_removed(wpa_s, ssid);
966 0 : wpa_config_remove_network(wpa_s->conf, ssid->id);
967 0 : return NULL;
968 : }
969 :
970 : #ifdef CONFIG_P2P
971 281 : if (dev_addr)
972 15 : os_memcpy(ssid->go_p2p_dev_addr, dev_addr, ETH_ALEN);
973 : #endif /* CONFIG_P2P */
974 :
975 281 : if (bssid) {
976 : #ifndef CONFIG_P2P
977 : struct wpa_bss *bss;
978 : int count = 0;
979 : #endif /* CONFIG_P2P */
980 :
981 257 : os_memcpy(ssid->bssid, bssid, ETH_ALEN);
982 257 : ssid->bssid_set = 1;
983 :
984 : /*
985 : * Note: With P2P, the SSID may change at the time the WPS
986 : * provisioning is started, so better not filter the AP based
987 : * on the current SSID in the scan results.
988 : */
989 : #ifndef CONFIG_P2P
990 : dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
991 : if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
992 : continue;
993 :
994 : os_free(ssid->ssid);
995 : ssid->ssid = os_malloc(bss->ssid_len);
996 : if (ssid->ssid == NULL)
997 : break;
998 : os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
999 : ssid->ssid_len = bss->ssid_len;
1000 : wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
1001 : "scan results",
1002 : ssid->ssid, ssid->ssid_len);
1003 : count++;
1004 : }
1005 :
1006 : if (count > 1) {
1007 : wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
1008 : "for the AP; use wildcard");
1009 : os_free(ssid->ssid);
1010 : ssid->ssid = NULL;
1011 : ssid->ssid_len = 0;
1012 : }
1013 : #endif /* CONFIG_P2P */
1014 : }
1015 :
1016 281 : return ssid;
1017 : }
1018 :
1019 :
1020 289 : static void wpas_wps_temp_disable(struct wpa_supplicant *wpa_s,
1021 : struct wpa_ssid *selected)
1022 : {
1023 : struct wpa_ssid *ssid;
1024 :
1025 289 : if (wpa_s->current_ssid)
1026 2 : wpa_supplicant_deauthenticate(
1027 : wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1028 :
1029 : /* Mark all other networks disabled and trigger reassociation */
1030 289 : ssid = wpa_s->conf->ssid;
1031 865 : while (ssid) {
1032 287 : int was_disabled = ssid->disabled;
1033 287 : ssid->disabled_for_connect = 0;
1034 : /*
1035 : * In case the network object corresponds to a persistent group
1036 : * then do not send out network disabled signal. In addition,
1037 : * do not change disabled status of persistent network objects
1038 : * from 2 to 1 should we connect to another network.
1039 : */
1040 287 : if (was_disabled != 2) {
1041 286 : ssid->disabled = ssid != selected;
1042 286 : if (was_disabled != ssid->disabled) {
1043 5 : if (ssid->disabled)
1044 5 : ssid->disabled_for_connect = 1;
1045 5 : wpas_notify_network_enabled_changed(wpa_s,
1046 : ssid);
1047 : }
1048 : }
1049 287 : ssid = ssid->next;
1050 : }
1051 289 : }
1052 :
1053 :
1054 281 : static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
1055 : struct wpa_ssid *selected, const u8 *bssid,
1056 : int freq)
1057 : {
1058 : struct wpa_bss *bss;
1059 :
1060 281 : wpa_s->wps_run++;
1061 281 : if (wpa_s->wps_run == 0)
1062 0 : wpa_s->wps_run++;
1063 281 : wpa_s->after_wps = 0;
1064 281 : wpa_s->known_wps_freq = 0;
1065 281 : if (freq) {
1066 8 : wpa_s->after_wps = 5;
1067 8 : wpa_s->wps_freq = freq;
1068 273 : } else if (bssid) {
1069 249 : bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
1070 249 : if (bss && bss->freq > 0) {
1071 159 : wpa_s->known_wps_freq = 1;
1072 159 : wpa_s->wps_freq = bss->freq;
1073 : }
1074 : }
1075 :
1076 281 : wpas_wps_temp_disable(wpa_s, selected);
1077 :
1078 281 : wpa_s->disconnected = 0;
1079 281 : wpa_s->reassociate = 1;
1080 281 : wpa_s->scan_runs = 0;
1081 281 : wpa_s->normal_scans = 0;
1082 281 : wpa_s->wps_success = 0;
1083 281 : wpa_s->blacklist_cleared = 0;
1084 :
1085 281 : wpa_supplicant_cancel_sched_scan(wpa_s);
1086 281 : wpa_supplicant_req_scan(wpa_s, 0, 0);
1087 281 : }
1088 :
1089 :
1090 61 : int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
1091 : int p2p_group)
1092 : {
1093 : struct wpa_ssid *ssid;
1094 :
1095 : #ifdef CONFIG_AP
1096 61 : if (wpa_s->ap_iface) {
1097 0 : wpa_printf(MSG_DEBUG,
1098 : "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1099 0 : return -1;
1100 : }
1101 : #endif /* CONFIG_AP */
1102 61 : wpas_clear_wps(wpa_s);
1103 61 : ssid = wpas_wps_add_network(wpa_s, 0, NULL, bssid);
1104 61 : if (ssid == NULL)
1105 1 : return -1;
1106 60 : ssid->temporary = 1;
1107 60 : ssid->p2p_group = p2p_group;
1108 : #ifdef CONFIG_P2P
1109 60 : if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
1110 23 : ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
1111 23 : if (ssid->ssid) {
1112 23 : ssid->ssid_len = wpa_s->go_params->ssid_len;
1113 23 : os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
1114 : ssid->ssid_len);
1115 46 : wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
1116 23 : "SSID", ssid->ssid, ssid->ssid_len);
1117 : }
1118 : }
1119 : #endif /* CONFIG_P2P */
1120 60 : if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
1121 0 : return -1;
1122 60 : if (wpa_s->wps_fragment_size)
1123 1 : ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1124 60 : eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1125 : wpa_s, NULL);
1126 60 : wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
1127 60 : return 0;
1128 : }
1129 :
1130 :
1131 181 : static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
1132 : const u8 *dev_addr, const u8 *bssid,
1133 : const char *pin, int p2p_group, u16 dev_pw_id,
1134 : const u8 *peer_pubkey_hash,
1135 : const u8 *ssid_val, size_t ssid_len, int freq)
1136 : {
1137 : struct wpa_ssid *ssid;
1138 : char val[128 + 2 * WPS_OOB_PUBKEY_HASH_LEN];
1139 181 : unsigned int rpin = 0;
1140 : char hash[2 * WPS_OOB_PUBKEY_HASH_LEN + 10];
1141 :
1142 : #ifdef CONFIG_AP
1143 181 : if (wpa_s->ap_iface) {
1144 0 : wpa_printf(MSG_DEBUG,
1145 : "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1146 0 : return -1;
1147 : }
1148 : #endif /* CONFIG_AP */
1149 181 : wpas_clear_wps(wpa_s);
1150 181 : if (bssid && is_zero_ether_addr(bssid))
1151 4 : bssid = NULL;
1152 181 : ssid = wpas_wps_add_network(wpa_s, 0, dev_addr, bssid);
1153 181 : if (ssid == NULL) {
1154 2 : wpa_printf(MSG_DEBUG, "WPS: Could not add network");
1155 2 : return -1;
1156 : }
1157 179 : ssid->temporary = 1;
1158 179 : ssid->p2p_group = p2p_group;
1159 179 : if (ssid_val) {
1160 11 : ssid->ssid = os_malloc(ssid_len);
1161 11 : if (ssid->ssid) {
1162 11 : os_memcpy(ssid->ssid, ssid_val, ssid_len);
1163 11 : ssid->ssid_len = ssid_len;
1164 : }
1165 : }
1166 179 : if (peer_pubkey_hash) {
1167 17 : os_memcpy(hash, " pkhash=", 8);
1168 17 : wpa_snprintf_hex_uppercase(hash + 8, sizeof(hash) - 8,
1169 : peer_pubkey_hash,
1170 : WPS_OOB_PUBKEY_HASH_LEN);
1171 : } else {
1172 162 : hash[0] = '\0';
1173 : }
1174 : #ifdef CONFIG_P2P
1175 179 : if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
1176 139 : ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
1177 139 : if (ssid->ssid) {
1178 139 : ssid->ssid_len = wpa_s->go_params->ssid_len;
1179 139 : os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
1180 : ssid->ssid_len);
1181 278 : wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
1182 139 : "SSID", ssid->ssid, ssid->ssid_len);
1183 : }
1184 : }
1185 : #endif /* CONFIG_P2P */
1186 179 : if (pin)
1187 159 : os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u%s\"",
1188 : pin, dev_pw_id, hash);
1189 20 : else if (pin == NULL && dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
1190 17 : os_snprintf(val, sizeof(val), "\"dev_pw_id=%u%s\"",
1191 : dev_pw_id, hash);
1192 : } else {
1193 3 : rpin = wps_generate_pin();
1194 3 : os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u%s\"",
1195 : rpin, dev_pw_id, hash);
1196 : }
1197 179 : if (wpa_config_set(ssid, "phase1", val, 0) < 0) {
1198 0 : wpa_printf(MSG_DEBUG, "WPS: Failed to set phase1 '%s'", val);
1199 0 : return -1;
1200 : }
1201 179 : if (wpa_s->wps_fragment_size)
1202 1 : ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1203 179 : eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1204 : wpa_s, NULL);
1205 179 : wpa_s->wps_ap_iter = 1;
1206 179 : wpas_wps_reassoc(wpa_s, ssid, bssid, freq);
1207 179 : return rpin;
1208 : }
1209 :
1210 :
1211 152 : int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
1212 : const char *pin, int p2p_group, u16 dev_pw_id)
1213 : {
1214 152 : return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
1215 : dev_pw_id, NULL, NULL, 0, 0);
1216 : }
1217 :
1218 :
1219 : /* Cancel the wps pbc/pin requests */
1220 3186 : int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
1221 : {
1222 : #ifdef CONFIG_AP
1223 3186 : if (wpa_s->ap_iface) {
1224 8 : wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
1225 8 : return wpa_supplicant_ap_wps_cancel(wpa_s);
1226 : }
1227 : #endif /* CONFIG_AP */
1228 :
1229 6093 : if (wpa_s->wpa_state == WPA_SCANNING ||
1230 2915 : wpa_s->wpa_state == WPA_DISCONNECTED) {
1231 1664 : wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
1232 1664 : wpa_supplicant_cancel_scan(wpa_s);
1233 1664 : wpas_clear_wps(wpa_s);
1234 1514 : } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
1235 542 : wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
1236 : "deauthenticate");
1237 542 : wpa_supplicant_deauthenticate(wpa_s,
1238 : WLAN_REASON_DEAUTH_LEAVING);
1239 542 : wpas_clear_wps(wpa_s);
1240 : } else {
1241 972 : wpas_wps_reenable_networks(wpa_s);
1242 972 : wpas_wps_clear_ap_info(wpa_s);
1243 972 : if (eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL) >
1244 : 0)
1245 0 : wpas_clear_wps(wpa_s);
1246 : }
1247 :
1248 3178 : wpa_s->after_wps = 0;
1249 :
1250 3178 : return 0;
1251 : }
1252 :
1253 :
1254 43 : int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
1255 : const char *pin, struct wps_new_ap_settings *settings)
1256 : {
1257 : struct wpa_ssid *ssid;
1258 : char val[200];
1259 : char *pos, *end;
1260 : int res;
1261 :
1262 : #ifdef CONFIG_AP
1263 43 : if (wpa_s->ap_iface) {
1264 0 : wpa_printf(MSG_DEBUG,
1265 : "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1266 0 : return -1;
1267 : }
1268 : #endif /* CONFIG_AP */
1269 43 : if (!pin)
1270 0 : return -1;
1271 43 : wpas_clear_wps(wpa_s);
1272 43 : ssid = wpas_wps_add_network(wpa_s, 1, NULL, bssid);
1273 43 : if (ssid == NULL)
1274 1 : return -1;
1275 42 : ssid->temporary = 1;
1276 42 : pos = val;
1277 42 : end = pos + sizeof(val);
1278 42 : res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
1279 42 : if (os_snprintf_error(end - pos, res))
1280 0 : return -1;
1281 42 : pos += res;
1282 42 : if (settings) {
1283 16 : res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s "
1284 : "new_encr=%s new_key=%s",
1285 : settings->ssid_hex, settings->auth,
1286 : settings->encr, settings->key_hex);
1287 16 : if (os_snprintf_error(end - pos, res))
1288 0 : return -1;
1289 16 : pos += res;
1290 : }
1291 42 : res = os_snprintf(pos, end - pos, "\"");
1292 42 : if (os_snprintf_error(end - pos, res))
1293 0 : return -1;
1294 42 : if (wpa_config_set(ssid, "phase1", val, 0) < 0)
1295 0 : return -1;
1296 42 : if (wpa_s->wps_fragment_size)
1297 1 : ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1298 42 : eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1299 : wpa_s, NULL);
1300 42 : wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
1301 42 : return 0;
1302 : }
1303 :
1304 :
1305 0 : static int wpas_wps_new_psk_cb(void *ctx, const u8 *mac_addr,
1306 : const u8 *p2p_dev_addr, const u8 *psk,
1307 : size_t psk_len)
1308 : {
1309 0 : if (is_zero_ether_addr(p2p_dev_addr)) {
1310 0 : wpa_printf(MSG_DEBUG,
1311 : "Received new WPA/WPA2-PSK from WPS for STA " MACSTR,
1312 0 : MAC2STR(mac_addr));
1313 : } else {
1314 0 : wpa_printf(MSG_DEBUG,
1315 : "Received new WPA/WPA2-PSK from WPS for STA " MACSTR
1316 : " P2P Device Addr " MACSTR,
1317 0 : MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
1318 : }
1319 0 : wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
1320 :
1321 : /* TODO */
1322 :
1323 0 : return 0;
1324 : }
1325 :
1326 :
1327 0 : static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
1328 : const struct wps_device_data *dev)
1329 : {
1330 : char uuid[40], txt[400];
1331 : int len;
1332 : char devtype[WPS_DEV_TYPE_BUFSIZE];
1333 0 : if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
1334 0 : return;
1335 0 : wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
1336 0 : len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
1337 : " [%s|%s|%s|%s|%s|%s]",
1338 0 : uuid, MAC2STR(dev->mac_addr), dev->device_name,
1339 : dev->manufacturer, dev->model_name,
1340 : dev->model_number, dev->serial_number,
1341 0 : wps_dev_type_bin2str(dev->pri_dev_type, devtype,
1342 : sizeof(devtype)));
1343 0 : if (!os_snprintf_error(sizeof(txt), len))
1344 0 : wpa_printf(MSG_INFO, "%s", txt);
1345 : }
1346 :
1347 :
1348 130 : static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
1349 : u16 sel_reg_config_methods)
1350 : {
1351 : #ifdef CONFIG_WPS_ER
1352 130 : struct wpa_supplicant *wpa_s = ctx;
1353 :
1354 130 : if (wpa_s->wps_er == NULL)
1355 232 : return;
1356 28 : wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
1357 : "dev_password_id=%u sel_reg_config_methods=0x%x",
1358 : sel_reg, dev_passwd_id, sel_reg_config_methods);
1359 28 : wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
1360 : sel_reg_config_methods);
1361 : #endif /* CONFIG_WPS_ER */
1362 : }
1363 :
1364 :
1365 19701 : static u16 wps_fix_config_methods(u16 config_methods)
1366 : {
1367 19701 : if ((config_methods &
1368 : (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
1369 : WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
1370 1 : wpa_printf(MSG_INFO, "WPS: Converting display to "
1371 : "virtual_display for WPS 2.0 compliance");
1372 1 : config_methods |= WPS_CONFIG_VIRT_DISPLAY;
1373 : }
1374 19701 : if ((config_methods &
1375 : (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
1376 : WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
1377 1 : wpa_printf(MSG_INFO, "WPS: Converting push_button to "
1378 : "virtual_push_button for WPS 2.0 compliance");
1379 1 : config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
1380 : }
1381 :
1382 19701 : return config_methods;
1383 : }
1384 :
1385 :
1386 193 : static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
1387 : struct wps_context *wps)
1388 : {
1389 : char buf[50];
1390 : const char *src;
1391 :
1392 193 : if (is_nil_uuid(wpa_s->conf->uuid)) {
1393 : struct wpa_supplicant *first;
1394 192 : first = wpa_s->global->ifaces;
1395 389 : while (first && first->next)
1396 5 : first = first->next;
1397 192 : if (first && first != wpa_s) {
1398 101 : if (wps != wpa_s->global->ifaces->wps)
1399 101 : os_memcpy(wps->uuid,
1400 : wpa_s->global->ifaces->wps->uuid,
1401 : WPS_UUID_LEN);
1402 101 : src = "from the first interface";
1403 : } else {
1404 91 : uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
1405 91 : src = "based on MAC address";
1406 : }
1407 : } else {
1408 1 : os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
1409 1 : src = "based on configuration";
1410 : }
1411 :
1412 193 : uuid_bin2str(wps->uuid, buf, sizeof(buf));
1413 193 : wpa_dbg(wpa_s, MSG_DEBUG, "WPS: UUID %s: %s", src, buf);
1414 193 : }
1415 :
1416 :
1417 195 : static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
1418 : struct wps_context *wps)
1419 : {
1420 195 : wpabuf_free(wps->dev.vendor_ext_m1);
1421 195 : wps->dev.vendor_ext_m1 = NULL;
1422 :
1423 195 : if (wpa_s->conf->wps_vendor_ext_m1) {
1424 1 : wps->dev.vendor_ext_m1 =
1425 1 : wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
1426 1 : if (!wps->dev.vendor_ext_m1) {
1427 0 : wpa_printf(MSG_ERROR, "WPS: Cannot "
1428 : "allocate memory for vendor_ext_m1");
1429 : }
1430 : }
1431 195 : }
1432 :
1433 :
1434 192 : int wpas_wps_init(struct wpa_supplicant *wpa_s)
1435 : {
1436 : struct wps_context *wps;
1437 : struct wps_registrar_config rcfg;
1438 : struct hostapd_hw_modes *modes;
1439 : u16 m;
1440 :
1441 192 : wps = os_zalloc(sizeof(*wps));
1442 192 : if (wps == NULL)
1443 1 : return -1;
1444 :
1445 191 : wps->cred_cb = wpa_supplicant_wps_cred;
1446 191 : wps->event_cb = wpa_supplicant_wps_event;
1447 191 : wps->rf_band_cb = wpa_supplicant_wps_rf_band;
1448 191 : wps->cb_ctx = wpa_s;
1449 :
1450 191 : wps->dev.device_name = wpa_s->conf->device_name;
1451 191 : wps->dev.manufacturer = wpa_s->conf->manufacturer;
1452 191 : wps->dev.model_name = wpa_s->conf->model_name;
1453 191 : wps->dev.model_number = wpa_s->conf->model_number;
1454 191 : wps->dev.serial_number = wpa_s->conf->serial_number;
1455 191 : wps->config_methods =
1456 191 : wps_config_methods_str2bin(wpa_s->conf->config_methods);
1457 191 : if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
1458 : (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
1459 0 : wpa_printf(MSG_ERROR, "WPS: Both Label and Display config "
1460 : "methods are not allowed at the same time");
1461 0 : os_free(wps);
1462 0 : return -1;
1463 : }
1464 191 : wps->config_methods = wps_fix_config_methods(wps->config_methods);
1465 191 : wps->dev.config_methods = wps->config_methods;
1466 191 : os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
1467 : WPS_DEV_TYPE_LEN);
1468 :
1469 191 : wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
1470 191 : os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
1471 : WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
1472 :
1473 191 : wpas_wps_set_vendor_ext_m1(wpa_s, wps);
1474 :
1475 191 : wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
1476 191 : modes = wpa_s->hw.modes;
1477 191 : if (modes) {
1478 604 : for (m = 0; m < wpa_s->hw.num_modes; m++) {
1479 755 : if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
1480 302 : modes[m].mode == HOSTAPD_MODE_IEEE80211G)
1481 302 : wps->dev.rf_bands |= WPS_RF_24GHZ;
1482 151 : else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
1483 151 : wps->dev.rf_bands |= WPS_RF_50GHZ;
1484 : }
1485 : }
1486 191 : if (wps->dev.rf_bands == 0) {
1487 : /*
1488 : * Default to claiming support for both bands if the driver
1489 : * does not provide support for fetching supported bands.
1490 : */
1491 40 : wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
1492 : }
1493 191 : os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
1494 191 : wpas_wps_set_uuid(wpa_s, wps);
1495 :
1496 191 : wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
1497 191 : wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
1498 :
1499 191 : os_memset(&rcfg, 0, sizeof(rcfg));
1500 191 : rcfg.new_psk_cb = wpas_wps_new_psk_cb;
1501 191 : rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
1502 191 : rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
1503 191 : rcfg.cb_ctx = wpa_s;
1504 :
1505 191 : wps->registrar = wps_registrar_init(wps, &rcfg);
1506 191 : if (wps->registrar == NULL) {
1507 1 : wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
1508 1 : os_free(wps);
1509 1 : return -1;
1510 : }
1511 :
1512 190 : wpa_s->wps = wps;
1513 :
1514 190 : return 0;
1515 : }
1516 :
1517 :
1518 : #ifdef CONFIG_WPS_ER
1519 193 : static void wpas_wps_nfc_clear(struct wps_context *wps)
1520 : {
1521 193 : wps->ap_nfc_dev_pw_id = 0;
1522 193 : wpabuf_free(wps->ap_nfc_dh_pubkey);
1523 193 : wps->ap_nfc_dh_pubkey = NULL;
1524 193 : wpabuf_free(wps->ap_nfc_dh_privkey);
1525 193 : wps->ap_nfc_dh_privkey = NULL;
1526 193 : wpabuf_free(wps->ap_nfc_dev_pw);
1527 193 : wps->ap_nfc_dev_pw = NULL;
1528 193 : }
1529 : #endif /* CONFIG_WPS_ER */
1530 :
1531 :
1532 212 : void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
1533 : {
1534 212 : wpas_wps_assoc_with_cred_cancel(wpa_s);
1535 212 : eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
1536 212 : eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
1537 212 : eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
1538 212 : wpas_wps_clear_ap_info(wpa_s);
1539 :
1540 : #ifdef CONFIG_P2P
1541 212 : eloop_cancel_timeout(wpas_p2p_pbc_overlap_cb, wpa_s, NULL);
1542 : #endif /* CONFIG_P2P */
1543 :
1544 212 : if (wpa_s->wps == NULL)
1545 234 : return;
1546 :
1547 : #ifdef CONFIG_WPS_ER
1548 190 : wps_er_deinit(wpa_s->wps_er, NULL, NULL);
1549 190 : wpa_s->wps_er = NULL;
1550 190 : wpas_wps_nfc_clear(wpa_s->wps);
1551 : #endif /* CONFIG_WPS_ER */
1552 :
1553 190 : wps_registrar_deinit(wpa_s->wps->registrar);
1554 190 : wpabuf_free(wpa_s->wps->dh_pubkey);
1555 190 : wpabuf_free(wpa_s->wps->dh_privkey);
1556 190 : wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
1557 190 : os_free(wpa_s->wps->network_key);
1558 190 : os_free(wpa_s->wps);
1559 190 : wpa_s->wps = NULL;
1560 : }
1561 :
1562 :
1563 2637 : int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
1564 : struct wpa_ssid *ssid, struct wpa_bss *bss)
1565 : {
1566 : struct wpabuf *wps_ie;
1567 :
1568 2637 : if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
1569 2332 : return -1;
1570 :
1571 305 : wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1572 305 : if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
1573 60 : if (!wps_ie) {
1574 0 : wpa_printf(MSG_DEBUG, " skip - non-WPS AP");
1575 0 : return 0;
1576 : }
1577 :
1578 60 : if (!wps_is_selected_pbc_registrar(wps_ie)) {
1579 3 : wpa_printf(MSG_DEBUG, " skip - WPS AP "
1580 : "without active PBC Registrar");
1581 3 : wpabuf_free(wps_ie);
1582 3 : return 0;
1583 : }
1584 :
1585 : /* TODO: overlap detection */
1586 57 : wpa_printf(MSG_DEBUG, " selected based on WPS IE "
1587 : "(Active PBC)");
1588 57 : wpabuf_free(wps_ie);
1589 57 : return 1;
1590 : }
1591 :
1592 245 : if (eap_is_wps_pin_enrollee(&ssid->eap)) {
1593 186 : if (!wps_ie) {
1594 0 : wpa_printf(MSG_DEBUG, " skip - non-WPS AP");
1595 0 : return 0;
1596 : }
1597 :
1598 : /*
1599 : * Start with WPS APs that advertise our address as an
1600 : * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
1601 : * allow any WPS AP after couple of scans since some APs do not
1602 : * set Selected Registrar attribute properly when using
1603 : * external Registrar.
1604 : */
1605 186 : if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
1606 31 : if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) {
1607 19 : wpa_printf(MSG_DEBUG, " skip - WPS AP "
1608 : "without active PIN Registrar");
1609 19 : wpabuf_free(wps_ie);
1610 19 : return 0;
1611 : }
1612 12 : wpa_printf(MSG_DEBUG, " selected based on WPS IE");
1613 : } else {
1614 155 : wpa_printf(MSG_DEBUG, " selected based on WPS IE "
1615 : "(Authorized MAC or Active PIN)");
1616 : }
1617 167 : wpabuf_free(wps_ie);
1618 167 : return 1;
1619 : }
1620 :
1621 59 : if (wps_ie) {
1622 59 : wpa_printf(MSG_DEBUG, " selected based on WPS IE");
1623 59 : wpabuf_free(wps_ie);
1624 59 : return 1;
1625 : }
1626 :
1627 0 : return -1;
1628 : }
1629 :
1630 :
1631 147 : int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
1632 : struct wpa_ssid *ssid,
1633 : struct wpa_bss *bss)
1634 : {
1635 147 : struct wpabuf *wps_ie = NULL;
1636 147 : int ret = 0;
1637 :
1638 147 : if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
1639 66 : wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1640 66 : if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
1641 : /* allow wildcard SSID for WPS PBC */
1642 34 : ret = 1;
1643 : }
1644 81 : } else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
1645 37 : wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1646 74 : if (wps_ie &&
1647 46 : (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
1648 9 : wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
1649 : /* allow wildcard SSID for WPS PIN */
1650 31 : ret = 1;
1651 : }
1652 : }
1653 :
1654 200 : if (!ret && ssid->bssid_set &&
1655 53 : os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
1656 : /* allow wildcard SSID due to hardcoded BSSID match */
1657 53 : ret = 1;
1658 : }
1659 :
1660 : #ifdef CONFIG_WPS_STRICT
1661 : if (wps_ie) {
1662 : if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
1663 : 0, bss->bssid) < 0)
1664 : ret = 0;
1665 : if (bss->beacon_ie_len) {
1666 : struct wpabuf *bcn_wps;
1667 : bcn_wps = wpa_bss_get_vendor_ie_multi_beacon(
1668 : bss, WPS_IE_VENDOR_TYPE);
1669 : if (bcn_wps == NULL) {
1670 : wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
1671 : "missing from AP Beacon");
1672 : ret = 0;
1673 : } else {
1674 : if (wps_validate_beacon(wps_ie) < 0)
1675 : ret = 0;
1676 : wpabuf_free(bcn_wps);
1677 : }
1678 : }
1679 : }
1680 : #endif /* CONFIG_WPS_STRICT */
1681 :
1682 147 : wpabuf_free(wps_ie);
1683 :
1684 147 : return ret;
1685 : }
1686 :
1687 :
1688 2416 : int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
1689 : struct wpa_bss *selected, struct wpa_ssid *ssid)
1690 : {
1691 : const u8 *sel_uuid, *uuid;
1692 : struct wpabuf *wps_ie;
1693 2416 : int ret = 0;
1694 : struct wpa_bss *bss;
1695 :
1696 2416 : if (!eap_is_wps_pbc_enrollee(&ssid->eap))
1697 2359 : return 0;
1698 :
1699 342 : wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
1700 : "present in scan results; selected BSSID " MACSTR,
1701 342 : MAC2STR(selected->bssid));
1702 :
1703 : /* Make sure that only one AP is in active PBC mode */
1704 57 : wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
1705 57 : if (wps_ie) {
1706 57 : sel_uuid = wps_get_uuid_e(wps_ie);
1707 57 : wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
1708 : sel_uuid, UUID_LEN);
1709 : } else {
1710 0 : wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
1711 : "WPS IE?!");
1712 0 : sel_uuid = NULL;
1713 : }
1714 :
1715 138 : dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1716 : struct wpabuf *ie;
1717 84 : if (bss == selected)
1718 55 : continue;
1719 29 : ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1720 29 : if (!ie)
1721 7 : continue;
1722 22 : if (!wps_is_selected_pbc_registrar(ie)) {
1723 7 : wpabuf_free(ie);
1724 7 : continue;
1725 : }
1726 90 : wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
1727 90 : MACSTR, MAC2STR(bss->bssid));
1728 15 : uuid = wps_get_uuid_e(ie);
1729 15 : wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
1730 : uuid, UUID_LEN);
1731 15 : if (os_memcmp(selected->bssid, bss->bssid, ETH_ALEN) == 0) {
1732 11 : wpabuf_free(ie);
1733 11 : continue;
1734 : }
1735 8 : if (sel_uuid == NULL || uuid == NULL ||
1736 4 : os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) {
1737 3 : ret = 1; /* PBC overlap */
1738 36 : wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
1739 : MACSTR " and " MACSTR,
1740 18 : MAC2STR(selected->bssid),
1741 18 : MAC2STR(bss->bssid));
1742 3 : wpabuf_free(ie);
1743 3 : break;
1744 : }
1745 :
1746 : /* TODO: verify that this is reasonable dual-band situation */
1747 :
1748 1 : wpabuf_free(ie);
1749 : }
1750 :
1751 57 : wpabuf_free(wps_ie);
1752 :
1753 57 : return ret;
1754 : }
1755 :
1756 :
1757 1839 : void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
1758 : {
1759 : struct wpa_bss *bss;
1760 1839 : unsigned int pbc = 0, auth = 0, pin = 0, wps = 0;
1761 :
1762 1839 : if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
1763 2005 : return;
1764 :
1765 3641 : dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1766 : struct wpabuf *ie;
1767 1968 : ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1768 1968 : if (!ie)
1769 1341 : continue;
1770 627 : if (wps_is_selected_pbc_registrar(ie))
1771 119 : pbc++;
1772 508 : else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
1773 262 : auth++;
1774 246 : else if (wps_is_selected_pin_registrar(ie))
1775 19 : pin++;
1776 : else
1777 227 : wps++;
1778 627 : wpabuf_free(ie);
1779 : }
1780 :
1781 1673 : if (pbc)
1782 99 : wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
1783 1574 : else if (auth)
1784 210 : wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH);
1785 1364 : else if (pin)
1786 13 : wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
1787 1351 : else if (wps)
1788 195 : wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
1789 : }
1790 :
1791 :
1792 4738 : int wpas_wps_searching(struct wpa_supplicant *wpa_s)
1793 : {
1794 : struct wpa_ssid *ssid;
1795 :
1796 7845 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1797 3564 : if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
1798 457 : return 1;
1799 : }
1800 :
1801 4281 : return 0;
1802 : }
1803 :
1804 :
1805 398 : int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
1806 : char *end)
1807 : {
1808 : struct wpabuf *wps_ie;
1809 : int ret;
1810 :
1811 398 : wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA);
1812 398 : if (wps_ie == NULL)
1813 297 : return 0;
1814 :
1815 101 : ret = wps_attr_text(wps_ie, buf, end);
1816 101 : wpabuf_free(wps_ie);
1817 101 : return ret;
1818 : }
1819 :
1820 :
1821 11 : int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
1822 : {
1823 : #ifdef CONFIG_WPS_ER
1824 11 : if (wpa_s->wps_er) {
1825 1 : wps_er_refresh(wpa_s->wps_er);
1826 1 : return 0;
1827 : }
1828 10 : wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
1829 10 : if (wpa_s->wps_er == NULL)
1830 0 : return -1;
1831 10 : return 0;
1832 : #else /* CONFIG_WPS_ER */
1833 : return 0;
1834 : #endif /* CONFIG_WPS_ER */
1835 : }
1836 :
1837 :
1838 18 : void wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
1839 : {
1840 : #ifdef CONFIG_WPS_ER
1841 18 : wps_er_deinit(wpa_s->wps_er, NULL, NULL);
1842 18 : wpa_s->wps_er = NULL;
1843 : #endif /* CONFIG_WPS_ER */
1844 18 : }
1845 :
1846 :
1847 : #ifdef CONFIG_WPS_ER
1848 4 : int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
1849 : const char *uuid, const char *pin)
1850 : {
1851 : u8 u[UUID_LEN];
1852 4 : const u8 *use_uuid = NULL;
1853 : u8 addr_buf[ETH_ALEN];
1854 :
1855 4 : if (os_strcmp(uuid, "any") == 0) {
1856 1 : } else if (uuid_str2bin(uuid, u) == 0) {
1857 0 : use_uuid = u;
1858 1 : } else if (hwaddr_aton(uuid, addr_buf) == 0) {
1859 1 : use_uuid = wps_er_get_sta_uuid(wpa_s->wps_er, addr_buf);
1860 1 : if (use_uuid == NULL)
1861 0 : return -1;
1862 : } else
1863 0 : return -1;
1864 4 : return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
1865 : use_uuid,
1866 : (const u8 *) pin, os_strlen(pin), 300);
1867 : }
1868 :
1869 :
1870 5 : int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
1871 : {
1872 5 : u8 u[UUID_LEN], *use_uuid = NULL;
1873 5 : u8 addr[ETH_ALEN], *use_addr = NULL;
1874 :
1875 5 : if (uuid_str2bin(uuid, u) == 0)
1876 1 : use_uuid = u;
1877 4 : else if (hwaddr_aton(uuid, addr) == 0)
1878 3 : use_addr = addr;
1879 : else
1880 1 : return -1;
1881 4 : return wps_er_pbc(wpa_s->wps_er, use_uuid, use_addr);
1882 : }
1883 :
1884 :
1885 1 : int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
1886 : const char *pin)
1887 : {
1888 1 : u8 u[UUID_LEN], *use_uuid = NULL;
1889 1 : u8 addr[ETH_ALEN], *use_addr = NULL;
1890 :
1891 1 : if (uuid_str2bin(uuid, u) == 0)
1892 1 : use_uuid = u;
1893 0 : else if (hwaddr_aton(uuid, addr) == 0)
1894 0 : use_addr = addr;
1895 : else
1896 0 : return -1;
1897 :
1898 1 : return wps_er_learn(wpa_s->wps_er, use_uuid, use_addr, (const u8 *) pin,
1899 : os_strlen(pin));
1900 : }
1901 :
1902 :
1903 8 : static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
1904 : struct wps_credential *cred)
1905 : {
1906 8 : os_memset(cred, 0, sizeof(*cred));
1907 8 : if (ssid->ssid_len > 32)
1908 0 : return -1;
1909 8 : os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
1910 8 : cred->ssid_len = ssid->ssid_len;
1911 8 : if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
1912 8 : cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
1913 : WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
1914 8 : if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
1915 8 : cred->encr_type = WPS_ENCR_AES;
1916 : else
1917 0 : cred->encr_type = WPS_ENCR_TKIP;
1918 8 : if (ssid->passphrase) {
1919 8 : cred->key_len = os_strlen(ssid->passphrase);
1920 8 : if (cred->key_len >= 64)
1921 0 : return -1;
1922 8 : os_memcpy(cred->key, ssid->passphrase, cred->key_len);
1923 0 : } else if (ssid->psk_set) {
1924 0 : cred->key_len = 32;
1925 0 : os_memcpy(cred->key, ssid->psk, 32);
1926 : } else
1927 0 : return -1;
1928 : } else {
1929 0 : cred->auth_type = WPS_AUTH_OPEN;
1930 0 : cred->encr_type = WPS_ENCR_NONE;
1931 : }
1932 :
1933 8 : return 0;
1934 : }
1935 :
1936 :
1937 8 : int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
1938 : int id)
1939 : {
1940 8 : u8 u[UUID_LEN], *use_uuid = NULL;
1941 8 : u8 addr[ETH_ALEN], *use_addr = NULL;
1942 : struct wpa_ssid *ssid;
1943 : struct wps_credential cred;
1944 : int ret;
1945 :
1946 8 : if (uuid_str2bin(uuid, u) == 0)
1947 7 : use_uuid = u;
1948 1 : else if (hwaddr_aton(uuid, addr) == 0)
1949 1 : use_addr = addr;
1950 : else
1951 0 : return -1;
1952 8 : ssid = wpa_config_get_network(wpa_s->conf, id);
1953 8 : if (ssid == NULL || ssid->ssid == NULL)
1954 0 : return -1;
1955 :
1956 8 : if (wpas_wps_network_to_cred(ssid, &cred) < 0)
1957 0 : return -1;
1958 8 : ret = wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
1959 8 : os_memset(&cred, 0, sizeof(cred));
1960 8 : return ret;
1961 : }
1962 :
1963 :
1964 1 : int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
1965 : const char *pin, struct wps_new_ap_settings *settings)
1966 : {
1967 1 : u8 u[UUID_LEN], *use_uuid = NULL;
1968 1 : u8 addr[ETH_ALEN], *use_addr = NULL;
1969 : struct wps_credential cred;
1970 : size_t len;
1971 :
1972 1 : if (uuid_str2bin(uuid, u) == 0)
1973 0 : use_uuid = u;
1974 1 : else if (hwaddr_aton(uuid, addr) == 0)
1975 1 : use_addr = addr;
1976 : else
1977 0 : return -1;
1978 2 : if (settings->ssid_hex == NULL || settings->auth == NULL ||
1979 2 : settings->encr == NULL || settings->key_hex == NULL)
1980 0 : return -1;
1981 :
1982 1 : os_memset(&cred, 0, sizeof(cred));
1983 1 : len = os_strlen(settings->ssid_hex);
1984 2 : if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
1985 1 : hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
1986 0 : return -1;
1987 1 : cred.ssid_len = len / 2;
1988 :
1989 1 : len = os_strlen(settings->key_hex);
1990 2 : if ((len & 1) || len > 2 * sizeof(cred.key) ||
1991 1 : hexstr2bin(settings->key_hex, cred.key, len / 2))
1992 0 : return -1;
1993 1 : cred.key_len = len / 2;
1994 :
1995 1 : if (os_strcmp(settings->auth, "OPEN") == 0)
1996 0 : cred.auth_type = WPS_AUTH_OPEN;
1997 1 : else if (os_strcmp(settings->auth, "WPAPSK") == 0)
1998 0 : cred.auth_type = WPS_AUTH_WPAPSK;
1999 1 : else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
2000 1 : cred.auth_type = WPS_AUTH_WPA2PSK;
2001 : else
2002 0 : return -1;
2003 :
2004 1 : if (os_strcmp(settings->encr, "NONE") == 0)
2005 0 : cred.encr_type = WPS_ENCR_NONE;
2006 : #ifdef CONFIG_TESTING_OPTIONS
2007 1 : else if (os_strcmp(settings->encr, "WEP") == 0)
2008 0 : cred.encr_type = WPS_ENCR_WEP;
2009 : #endif /* CONFIG_TESTING_OPTIONS */
2010 1 : else if (os_strcmp(settings->encr, "TKIP") == 0)
2011 0 : cred.encr_type = WPS_ENCR_TKIP;
2012 1 : else if (os_strcmp(settings->encr, "CCMP") == 0)
2013 1 : cred.encr_type = WPS_ENCR_AES;
2014 : else
2015 0 : return -1;
2016 :
2017 1 : return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
2018 : (const u8 *) pin, os_strlen(pin), &cred);
2019 : }
2020 :
2021 :
2022 : #ifdef CONFIG_WPS_NFC
2023 3 : struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
2024 : int ndef, const char *uuid)
2025 : {
2026 : struct wpabuf *ret;
2027 3 : u8 u[UUID_LEN], *use_uuid = NULL;
2028 3 : u8 addr[ETH_ALEN], *use_addr = NULL;
2029 :
2030 3 : if (!wpa_s->wps_er)
2031 1 : return NULL;
2032 :
2033 2 : if (uuid_str2bin(uuid, u) == 0)
2034 0 : use_uuid = u;
2035 2 : else if (hwaddr_aton(uuid, addr) == 0)
2036 2 : use_addr = addr;
2037 : else
2038 0 : return NULL;
2039 :
2040 2 : ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
2041 2 : if (ndef && ret) {
2042 : struct wpabuf *tmp;
2043 1 : tmp = ndef_build_wifi(ret);
2044 1 : wpabuf_free(ret);
2045 1 : if (tmp == NULL)
2046 0 : return NULL;
2047 1 : ret = tmp;
2048 : }
2049 :
2050 2 : return ret;
2051 : }
2052 : #endif /* CONFIG_WPS_NFC */
2053 :
2054 :
2055 : static int callbacks_pending = 0;
2056 :
2057 0 : static void wpas_wps_terminate_cb(void *ctx)
2058 : {
2059 0 : wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
2060 0 : if (--callbacks_pending <= 0)
2061 0 : eloop_terminate();
2062 0 : }
2063 : #endif /* CONFIG_WPS_ER */
2064 :
2065 :
2066 15 : int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
2067 : {
2068 : #ifdef CONFIG_WPS_ER
2069 15 : if (wpa_s->wps_er) {
2070 0 : callbacks_pending++;
2071 0 : wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
2072 0 : wpa_s->wps_er = NULL;
2073 0 : return 1;
2074 : }
2075 : #endif /* CONFIG_WPS_ER */
2076 15 : return 0;
2077 : }
2078 :
2079 :
2080 19510 : void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
2081 : {
2082 19510 : struct wps_context *wps = wpa_s->wps;
2083 :
2084 19510 : if (wps == NULL)
2085 19510 : return;
2086 :
2087 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
2088 6 : wps->config_methods = wps_config_methods_str2bin(
2089 6 : wpa_s->conf->config_methods);
2090 6 : if ((wps->config_methods &
2091 : (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
2092 : (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
2093 1 : wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
2094 : "config methods are not allowed at the "
2095 : "same time");
2096 1 : wps->config_methods &= ~WPS_CONFIG_LABEL;
2097 : }
2098 : }
2099 19510 : wps->config_methods = wps_fix_config_methods(wps->config_methods);
2100 19510 : wps->dev.config_methods = wps->config_methods;
2101 :
2102 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
2103 3 : os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
2104 : WPS_DEV_TYPE_LEN);
2105 :
2106 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
2107 6 : wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
2108 6 : os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
2109 : wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
2110 : }
2111 :
2112 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
2113 4 : wpas_wps_set_vendor_ext_m1(wpa_s, wps);
2114 :
2115 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
2116 2 : wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
2117 :
2118 19510 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
2119 2 : wpas_wps_set_uuid(wpa_s, wps);
2120 :
2121 19510 : if (wpa_s->conf->changed_parameters &
2122 : (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
2123 : /* Update pointers to make sure they refer current values */
2124 19 : wps->dev.device_name = wpa_s->conf->device_name;
2125 19 : wps->dev.manufacturer = wpa_s->conf->manufacturer;
2126 19 : wps->dev.model_name = wpa_s->conf->model_name;
2127 19 : wps->dev.model_number = wpa_s->conf->model_number;
2128 19 : wps->dev.serial_number = wpa_s->conf->serial_number;
2129 : }
2130 : }
2131 :
2132 :
2133 : #ifdef CONFIG_WPS_NFC
2134 :
2135 : #ifdef CONFIG_WPS_ER
2136 : static struct wpabuf *
2137 0 : wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
2138 : struct wpa_ssid *ssid)
2139 : {
2140 : struct wpabuf *ret;
2141 : struct wps_credential cred;
2142 :
2143 0 : if (wpas_wps_network_to_cred(ssid, &cred) < 0)
2144 0 : return NULL;
2145 :
2146 0 : ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
2147 :
2148 0 : if (ndef && ret) {
2149 : struct wpabuf *tmp;
2150 0 : tmp = ndef_build_wifi(ret);
2151 0 : wpabuf_free(ret);
2152 0 : if (tmp == NULL)
2153 0 : return NULL;
2154 0 : ret = tmp;
2155 : }
2156 :
2157 0 : return ret;
2158 : }
2159 : #endif /* CONFIG_WPS_ER */
2160 :
2161 :
2162 2 : struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
2163 : int ndef, const char *id_str)
2164 : {
2165 : #ifdef CONFIG_WPS_ER
2166 2 : if (id_str) {
2167 : int id;
2168 1 : char *end = NULL;
2169 : struct wpa_ssid *ssid;
2170 :
2171 1 : id = strtol(id_str, &end, 10);
2172 1 : if (end && *end)
2173 1 : return NULL;
2174 :
2175 0 : ssid = wpa_config_get_network(wpa_s->conf, id);
2176 0 : if (ssid == NULL)
2177 0 : return NULL;
2178 0 : return wpas_wps_network_config_token(wpa_s, ndef, ssid);
2179 : }
2180 : #endif /* CONFIG_WPS_ER */
2181 : #ifdef CONFIG_AP
2182 1 : if (wpa_s->ap_iface)
2183 1 : return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
2184 : #endif /* CONFIG_AP */
2185 0 : return NULL;
2186 : }
2187 :
2188 :
2189 13 : struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
2190 : {
2191 13 : if (wpa_s->conf->wps_nfc_pw_from_config) {
2192 0 : return wps_nfc_token_build(ndef,
2193 0 : wpa_s->conf->wps_nfc_dev_pw_id,
2194 0 : wpa_s->conf->wps_nfc_dh_pubkey,
2195 0 : wpa_s->conf->wps_nfc_dev_pw);
2196 : }
2197 :
2198 39 : return wps_nfc_token_gen(ndef, &wpa_s->conf->wps_nfc_dev_pw_id,
2199 13 : &wpa_s->conf->wps_nfc_dh_pubkey,
2200 13 : &wpa_s->conf->wps_nfc_dh_privkey,
2201 13 : &wpa_s->conf->wps_nfc_dev_pw);
2202 : }
2203 :
2204 :
2205 29 : int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *go_dev_addr,
2206 : const u8 *bssid,
2207 : const struct wpabuf *dev_pw, u16 dev_pw_id,
2208 : int p2p_group, const u8 *peer_pubkey_hash,
2209 : const u8 *ssid, size_t ssid_len, int freq)
2210 : {
2211 29 : struct wps_context *wps = wpa_s->wps;
2212 : char pw[32 * 2 + 1];
2213 :
2214 29 : if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
2215 3 : dev_pw = wpa_s->conf->wps_nfc_dev_pw;
2216 3 : dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
2217 : }
2218 :
2219 58 : if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
2220 29 : wpa_s->conf->wps_nfc_dh_privkey == NULL) {
2221 0 : wpa_printf(MSG_DEBUG, "WPS: Missing DH params - "
2222 : "cannot start NFC-triggered connection");
2223 0 : return -1;
2224 : }
2225 :
2226 29 : if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
2227 0 : wpa_printf(MSG_DEBUG, "WPS: Missing Device Password (id=%u) - "
2228 : "cannot start NFC-triggered connection", dev_pw_id);
2229 0 : return -1;
2230 : }
2231 :
2232 29 : dh5_free(wps->dh_ctx);
2233 29 : wpabuf_free(wps->dh_pubkey);
2234 29 : wpabuf_free(wps->dh_privkey);
2235 29 : wps->dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
2236 29 : wps->dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
2237 29 : if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
2238 0 : wps->dh_ctx = NULL;
2239 0 : wpabuf_free(wps->dh_pubkey);
2240 0 : wps->dh_pubkey = NULL;
2241 0 : wpabuf_free(wps->dh_privkey);
2242 0 : wps->dh_privkey = NULL;
2243 0 : wpa_printf(MSG_DEBUG, "WPS: Failed to get DH priv/pub key");
2244 0 : return -1;
2245 : }
2246 29 : wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
2247 29 : if (wps->dh_ctx == NULL) {
2248 0 : wpabuf_free(wps->dh_pubkey);
2249 0 : wps->dh_pubkey = NULL;
2250 0 : wpabuf_free(wps->dh_privkey);
2251 0 : wps->dh_privkey = NULL;
2252 0 : wpa_printf(MSG_DEBUG, "WPS: Failed to initialize DH context");
2253 0 : return -1;
2254 : }
2255 :
2256 29 : if (dev_pw) {
2257 24 : wpa_snprintf_hex_uppercase(pw, sizeof(pw),
2258 12 : wpabuf_head(dev_pw),
2259 : wpabuf_len(dev_pw));
2260 : }
2261 29 : return wpas_wps_start_dev_pw(wpa_s, go_dev_addr, bssid,
2262 : dev_pw ? pw : NULL,
2263 : p2p_group, dev_pw_id, peer_pubkey_hash,
2264 : ssid, ssid_len, freq);
2265 : }
2266 :
2267 :
2268 8 : static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
2269 : struct wps_parse_attr *attr)
2270 : {
2271 : /*
2272 : * Disable existing networks temporarily to allow the newly learned
2273 : * credential to be preferred. Enable the temporarily disabled networks
2274 : * after 10 seconds.
2275 : */
2276 8 : wpas_wps_temp_disable(wpa_s, NULL);
2277 8 : eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
2278 : NULL);
2279 :
2280 8 : if (wps_oob_use_cred(wpa_s->wps, attr) < 0)
2281 4 : return -1;
2282 :
2283 4 : if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2284 0 : return 0;
2285 :
2286 4 : if (attr->ap_channel) {
2287 3 : u16 chan = WPA_GET_BE16(attr->ap_channel);
2288 3 : int freq = 0;
2289 :
2290 3 : if (chan >= 1 && chan <= 13)
2291 3 : freq = 2407 + 5 * chan;
2292 0 : else if (chan == 14)
2293 0 : freq = 2484;
2294 0 : else if (chan >= 30)
2295 0 : freq = 5000 + 5 * chan;
2296 :
2297 3 : if (freq) {
2298 3 : wpa_printf(MSG_DEBUG, "WPS: Credential container indicated AP channel %u -> %u MHz",
2299 : chan, freq);
2300 3 : wpa_s->after_wps = 5;
2301 3 : wpa_s->wps_freq = freq;
2302 : }
2303 : }
2304 :
2305 4 : wpa_printf(MSG_DEBUG, "WPS: Request reconnection with new network "
2306 : "based on the received credential added");
2307 4 : wpa_s->normal_scans = 0;
2308 4 : wpa_supplicant_reinit_autoscan(wpa_s);
2309 4 : wpa_s->disconnected = 0;
2310 4 : wpa_s->reassociate = 1;
2311 :
2312 4 : wpa_supplicant_cancel_sched_scan(wpa_s);
2313 4 : wpa_supplicant_req_scan(wpa_s, 0, 0);
2314 :
2315 4 : return 0;
2316 : }
2317 :
2318 :
2319 : #ifdef CONFIG_WPS_ER
2320 2 : static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s,
2321 : struct wps_parse_attr *attr)
2322 : {
2323 4 : return wps_registrar_add_nfc_password_token(
2324 2 : wpa_s->wps->registrar, attr->oob_dev_password,
2325 : attr->oob_dev_password_len);
2326 : }
2327 : #endif /* CONFIG_WPS_ER */
2328 :
2329 :
2330 12 : static int wpas_wps_nfc_tag_process(struct wpa_supplicant *wpa_s,
2331 : const struct wpabuf *wps)
2332 : {
2333 : struct wps_parse_attr attr;
2334 :
2335 12 : wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
2336 :
2337 12 : if (wps_parse_msg(wps, &attr)) {
2338 1 : wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
2339 1 : return -1;
2340 : }
2341 :
2342 11 : if (attr.num_cred)
2343 8 : return wpas_wps_use_cred(wpa_s, &attr);
2344 :
2345 : #ifdef CONFIG_WPS_ER
2346 3 : if (attr.oob_dev_password)
2347 2 : return wpas_wps_add_nfc_password_token(wpa_s, &attr);
2348 : #endif /* CONFIG_WPS_ER */
2349 :
2350 1 : wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
2351 1 : return -1;
2352 : }
2353 :
2354 :
2355 35 : int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
2356 : const struct wpabuf *data, int forced_freq)
2357 : {
2358 35 : const struct wpabuf *wps = data;
2359 35 : struct wpabuf *tmp = NULL;
2360 : int ret;
2361 :
2362 35 : if (wpabuf_len(data) < 4)
2363 2 : return -1;
2364 :
2365 33 : if (*wpabuf_head_u8(data) != 0x10) {
2366 : /* Assume this contains full NDEF record */
2367 27 : tmp = ndef_parse_wifi(data);
2368 27 : if (tmp == NULL) {
2369 : #ifdef CONFIG_P2P
2370 21 : tmp = ndef_parse_p2p(data);
2371 21 : if (tmp) {
2372 9 : ret = wpas_p2p_nfc_tag_process(wpa_s, tmp,
2373 : forced_freq);
2374 9 : wpabuf_free(tmp);
2375 9 : return ret;
2376 : }
2377 : #endif /* CONFIG_P2P */
2378 12 : wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
2379 12 : return -1;
2380 : }
2381 6 : wps = tmp;
2382 : }
2383 :
2384 12 : ret = wpas_wps_nfc_tag_process(wpa_s, wps);
2385 12 : wpabuf_free(tmp);
2386 12 : return ret;
2387 : }
2388 :
2389 :
2390 12 : struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
2391 : int ndef)
2392 : {
2393 : struct wpabuf *ret;
2394 :
2395 13 : if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
2396 1 : wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
2397 1 : &wpa_s->conf->wps_nfc_dh_privkey) < 0)
2398 0 : return NULL;
2399 :
2400 12 : ret = wps_build_nfc_handover_req(wpa_s->wps,
2401 12 : wpa_s->conf->wps_nfc_dh_pubkey);
2402 :
2403 12 : if (ndef && ret) {
2404 : struct wpabuf *tmp;
2405 12 : tmp = ndef_build_wifi(ret);
2406 12 : wpabuf_free(ret);
2407 12 : if (tmp == NULL)
2408 0 : return NULL;
2409 12 : ret = tmp;
2410 : }
2411 :
2412 12 : return ret;
2413 : }
2414 :
2415 :
2416 : #ifdef CONFIG_WPS_NFC
2417 :
2418 : static struct wpabuf *
2419 3 : wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s, int ndef,
2420 : const char *uuid)
2421 : {
2422 : #ifdef CONFIG_WPS_ER
2423 : struct wpabuf *ret;
2424 3 : u8 u[UUID_LEN], *use_uuid = NULL;
2425 3 : u8 addr[ETH_ALEN], *use_addr = NULL;
2426 3 : struct wps_context *wps = wpa_s->wps;
2427 :
2428 3 : if (wps == NULL)
2429 0 : return NULL;
2430 :
2431 3 : if (uuid == NULL)
2432 0 : return NULL;
2433 3 : if (uuid_str2bin(uuid, u) == 0)
2434 0 : use_uuid = u;
2435 3 : else if (hwaddr_aton(uuid, addr) == 0)
2436 3 : use_addr = addr;
2437 : else
2438 0 : return NULL;
2439 :
2440 3 : if (wpa_s->conf->wps_nfc_dh_pubkey == NULL) {
2441 1 : if (wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
2442 1 : &wpa_s->conf->wps_nfc_dh_privkey) < 0)
2443 0 : return NULL;
2444 : }
2445 :
2446 3 : wpas_wps_nfc_clear(wps);
2447 3 : wps->ap_nfc_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
2448 3 : wps->ap_nfc_dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
2449 3 : wps->ap_nfc_dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
2450 3 : if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey) {
2451 0 : wpas_wps_nfc_clear(wps);
2452 0 : return NULL;
2453 : }
2454 :
2455 3 : ret = wps_er_nfc_handover_sel(wpa_s->wps_er, wpa_s->wps, use_uuid,
2456 3 : use_addr, wpa_s->conf->wps_nfc_dh_pubkey);
2457 3 : if (ndef && ret) {
2458 : struct wpabuf *tmp;
2459 3 : tmp = ndef_build_wifi(ret);
2460 3 : wpabuf_free(ret);
2461 3 : if (tmp == NULL)
2462 0 : return NULL;
2463 3 : ret = tmp;
2464 : }
2465 :
2466 3 : return ret;
2467 : #else /* CONFIG_WPS_ER */
2468 : return NULL;
2469 : #endif /* CONFIG_WPS_ER */
2470 : }
2471 : #endif /* CONFIG_WPS_NFC */
2472 :
2473 :
2474 6 : struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
2475 : int ndef, int cr, const char *uuid)
2476 : {
2477 : struct wpabuf *ret;
2478 6 : if (!cr)
2479 2 : return NULL;
2480 4 : ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
2481 4 : if (ret)
2482 1 : return ret;
2483 3 : return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
2484 : }
2485 :
2486 :
2487 11 : static int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
2488 : const struct wpabuf *data)
2489 : {
2490 : struct wpabuf *wps;
2491 11 : int ret = -1;
2492 : u16 wsc_len;
2493 : const u8 *pos;
2494 : struct wpabuf msg;
2495 : struct wps_parse_attr attr;
2496 : u16 dev_pw_id;
2497 11 : const u8 *bssid = NULL;
2498 11 : int freq = 0;
2499 :
2500 11 : wps = ndef_parse_wifi(data);
2501 11 : if (wps == NULL)
2502 0 : return -1;
2503 11 : wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
2504 : "payload from NFC connection handover");
2505 11 : wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
2506 11 : if (wpabuf_len(wps) < 2) {
2507 0 : wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Select "
2508 : "Message");
2509 0 : goto out;
2510 : }
2511 11 : pos = wpabuf_head(wps);
2512 11 : wsc_len = WPA_GET_BE16(pos);
2513 11 : if (wsc_len > wpabuf_len(wps) - 2) {
2514 0 : wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
2515 : "in Wi-Fi Handover Select Message", wsc_len);
2516 0 : goto out;
2517 : }
2518 11 : pos += 2;
2519 :
2520 11 : wpa_hexdump(MSG_DEBUG,
2521 : "WPS: WSC attributes in Wi-Fi Handover Select Message",
2522 : pos, wsc_len);
2523 11 : if (wsc_len < wpabuf_len(wps) - 2) {
2524 0 : wpa_hexdump(MSG_DEBUG,
2525 : "WPS: Ignore extra data after WSC attributes",
2526 0 : pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
2527 : }
2528 :
2529 11 : wpabuf_set(&msg, pos, wsc_len);
2530 11 : ret = wps_parse_msg(&msg, &attr);
2531 11 : if (ret < 0) {
2532 0 : wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
2533 : "Wi-Fi Handover Select Message");
2534 0 : goto out;
2535 : }
2536 :
2537 22 : if (attr.oob_dev_password == NULL ||
2538 11 : attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
2539 0 : wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
2540 : "included in Wi-Fi Handover Select Message");
2541 0 : ret = -1;
2542 0 : goto out;
2543 : }
2544 :
2545 11 : if (attr.ssid == NULL) {
2546 0 : wpa_printf(MSG_DEBUG, "WPS: No SSID included in Wi-Fi Handover "
2547 : "Select Message");
2548 0 : ret = -1;
2549 0 : goto out;
2550 : }
2551 :
2552 11 : wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", attr.ssid, attr.ssid_len);
2553 :
2554 11 : if (attr.mac_addr) {
2555 11 : bssid = attr.mac_addr;
2556 66 : wpa_printf(MSG_DEBUG, "WPS: MAC Address (BSSID): " MACSTR,
2557 66 : MAC2STR(bssid));
2558 : }
2559 :
2560 11 : if (attr.rf_bands)
2561 8 : wpa_printf(MSG_DEBUG, "WPS: RF Bands: %d", *attr.rf_bands);
2562 :
2563 11 : if (attr.ap_channel) {
2564 8 : u16 chan = WPA_GET_BE16(attr.ap_channel);
2565 :
2566 8 : wpa_printf(MSG_DEBUG, "WPS: AP Channel: %d", chan);
2567 :
2568 14 : if (chan >= 1 && chan <= 13 &&
2569 12 : (attr.rf_bands == NULL || *attr.rf_bands & WPS_RF_24GHZ))
2570 6 : freq = 2407 + 5 * chan;
2571 3 : else if (chan == 14 &&
2572 2 : (attr.rf_bands == NULL ||
2573 1 : *attr.rf_bands & WPS_RF_24GHZ))
2574 1 : freq = 2484;
2575 2 : else if (chan >= 30 &&
2576 2 : (attr.rf_bands == NULL ||
2577 1 : *attr.rf_bands & WPS_RF_50GHZ))
2578 1 : freq = 5000 + 5 * chan;
2579 :
2580 8 : if (freq) {
2581 8 : wpa_printf(MSG_DEBUG,
2582 : "WPS: AP indicated channel %u -> %u MHz",
2583 : chan, freq);
2584 : }
2585 : }
2586 :
2587 22 : wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
2588 11 : attr.oob_dev_password, attr.oob_dev_password_len);
2589 11 : dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
2590 : WPS_OOB_PUBKEY_HASH_LEN);
2591 11 : if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
2592 0 : wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
2593 : "%u in Wi-Fi Handover Select Message", dev_pw_id);
2594 0 : ret = -1;
2595 0 : goto out;
2596 : }
2597 11 : wpa_hexdump(MSG_DEBUG, "WPS: AP Public Key hash",
2598 11 : attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
2599 :
2600 11 : ret = wpas_wps_start_nfc(wpa_s, NULL, bssid, NULL, dev_pw_id, 0,
2601 : attr.oob_dev_password,
2602 : attr.ssid, attr.ssid_len, freq);
2603 :
2604 : out:
2605 11 : wpabuf_free(wps);
2606 11 : return ret;
2607 : }
2608 :
2609 :
2610 11 : int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
2611 : const struct wpabuf *req,
2612 : const struct wpabuf *sel)
2613 : {
2614 11 : wpa_printf(MSG_DEBUG, "NFC: WPS connection handover reported");
2615 11 : wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in request", req);
2616 11 : wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in select", sel);
2617 11 : return wpas_wps_nfc_rx_handover_sel(wpa_s, sel);
2618 : }
2619 :
2620 :
2621 3 : int wpas_er_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
2622 : const struct wpabuf *req,
2623 : const struct wpabuf *sel)
2624 : {
2625 : struct wpabuf *wps;
2626 3 : int ret = -1;
2627 : u16 wsc_len;
2628 : const u8 *pos;
2629 : struct wpabuf msg;
2630 : struct wps_parse_attr attr;
2631 : u16 dev_pw_id;
2632 :
2633 : /*
2634 : * Enrollee/station is always initiator of the NFC connection handover,
2635 : * so use the request message here to find Enrollee public key hash.
2636 : */
2637 3 : wps = ndef_parse_wifi(req);
2638 3 : if (wps == NULL)
2639 0 : return -1;
2640 3 : wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
2641 : "payload from NFC connection handover");
2642 3 : wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
2643 3 : if (wpabuf_len(wps) < 2) {
2644 0 : wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Request "
2645 : "Message");
2646 0 : goto out;
2647 : }
2648 3 : pos = wpabuf_head(wps);
2649 3 : wsc_len = WPA_GET_BE16(pos);
2650 3 : if (wsc_len > wpabuf_len(wps) - 2) {
2651 0 : wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
2652 : "in rt Wi-Fi Handover Request Message", wsc_len);
2653 0 : goto out;
2654 : }
2655 3 : pos += 2;
2656 :
2657 3 : wpa_hexdump(MSG_DEBUG,
2658 : "WPS: WSC attributes in Wi-Fi Handover Request Message",
2659 : pos, wsc_len);
2660 3 : if (wsc_len < wpabuf_len(wps) - 2) {
2661 0 : wpa_hexdump(MSG_DEBUG,
2662 : "WPS: Ignore extra data after WSC attributes",
2663 0 : pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
2664 : }
2665 :
2666 3 : wpabuf_set(&msg, pos, wsc_len);
2667 3 : ret = wps_parse_msg(&msg, &attr);
2668 3 : if (ret < 0) {
2669 0 : wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
2670 : "Wi-Fi Handover Request Message");
2671 0 : goto out;
2672 : }
2673 :
2674 6 : if (attr.oob_dev_password == NULL ||
2675 3 : attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
2676 0 : wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
2677 : "included in Wi-Fi Handover Request Message");
2678 0 : ret = -1;
2679 0 : goto out;
2680 : }
2681 :
2682 3 : if (attr.uuid_e == NULL) {
2683 0 : wpa_printf(MSG_DEBUG, "WPS: No UUID-E included in Wi-Fi "
2684 : "Handover Request Message");
2685 0 : ret = -1;
2686 0 : goto out;
2687 : }
2688 :
2689 3 : wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", attr.uuid_e, WPS_UUID_LEN);
2690 :
2691 6 : wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
2692 3 : attr.oob_dev_password, attr.oob_dev_password_len);
2693 3 : dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
2694 : WPS_OOB_PUBKEY_HASH_LEN);
2695 3 : if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
2696 0 : wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
2697 : "%u in Wi-Fi Handover Request Message", dev_pw_id);
2698 0 : ret = -1;
2699 0 : goto out;
2700 : }
2701 3 : wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Public Key hash",
2702 3 : attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
2703 :
2704 3 : ret = wps_registrar_add_nfc_pw_token(wpa_s->wps->registrar,
2705 : attr.oob_dev_password,
2706 : DEV_PW_NFC_CONNECTION_HANDOVER,
2707 : NULL, 0, 1);
2708 :
2709 : out:
2710 3 : wpabuf_free(wps);
2711 3 : return ret;
2712 : }
2713 :
2714 : #endif /* CONFIG_WPS_NFC */
2715 :
2716 :
2717 1475 : static void wpas_wps_dump_ap_info(struct wpa_supplicant *wpa_s)
2718 : {
2719 : size_t i;
2720 : struct os_reltime now;
2721 :
2722 1475 : if (wpa_debug_level > MSG_DEBUG)
2723 1042 : return;
2724 :
2725 1475 : if (wpa_s->wps_ap == NULL)
2726 1042 : return;
2727 :
2728 433 : os_get_reltime(&now);
2729 :
2730 884 : for (i = 0; i < wpa_s->num_wps_ap; i++) {
2731 451 : struct wps_ap_info *ap = &wpa_s->wps_ap[i];
2732 451 : struct wpa_blacklist *e = wpa_blacklist_get(wpa_s, ap->bssid);
2733 :
2734 3613 : wpa_printf(MSG_DEBUG, "WPS: AP[%d] " MACSTR " type=%d "
2735 : "tries=%d last_attempt=%d sec ago blacklist=%d",
2736 2706 : (int) i, MAC2STR(ap->bssid), ap->type, ap->tries,
2737 451 : ap->last_attempt.sec > 0 ?
2738 5 : (int) now.sec - (int) ap->last_attempt.sec : -1,
2739 : e ? e->count : 0);
2740 : }
2741 : }
2742 :
2743 :
2744 683 : static struct wps_ap_info * wpas_wps_get_ap_info(struct wpa_supplicant *wpa_s,
2745 : const u8 *bssid)
2746 : {
2747 : size_t i;
2748 :
2749 683 : if (wpa_s->wps_ap == NULL)
2750 347 : return NULL;
2751 :
2752 358 : for (i = 0; i < wpa_s->num_wps_ap; i++) {
2753 342 : struct wps_ap_info *ap = &wpa_s->wps_ap[i];
2754 342 : if (os_memcmp(ap->bssid, bssid, ETH_ALEN) == 0)
2755 320 : return ap;
2756 : }
2757 :
2758 16 : return NULL;
2759 : }
2760 :
2761 :
2762 1609 : static void wpas_wps_update_ap_info_bss(struct wpa_supplicant *wpa_s,
2763 : struct wpa_scan_res *res)
2764 : {
2765 : struct wpabuf *wps;
2766 : enum wps_ap_info_type type;
2767 : struct wps_ap_info *ap;
2768 : int r;
2769 :
2770 1609 : if (wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE) == NULL)
2771 1110 : return;
2772 :
2773 499 : wps = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
2774 499 : if (wps == NULL)
2775 0 : return;
2776 :
2777 499 : r = wps_is_addr_authorized(wps, wpa_s->own_addr, 1);
2778 499 : if (r == 2)
2779 93 : type = WPS_AP_SEL_REG_OUR;
2780 406 : else if (r == 1)
2781 196 : type = WPS_AP_SEL_REG;
2782 : else
2783 210 : type = WPS_AP_NOT_SEL_REG;
2784 :
2785 499 : wpabuf_free(wps);
2786 :
2787 499 : ap = wpas_wps_get_ap_info(wpa_s, res->bssid);
2788 499 : if (ap) {
2789 136 : if (ap->type != type) {
2790 240 : wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR
2791 : " changed type %d -> %d",
2792 240 : MAC2STR(res->bssid), ap->type, type);
2793 40 : ap->type = type;
2794 40 : if (type != WPS_AP_NOT_SEL_REG)
2795 12 : wpa_blacklist_del(wpa_s, ap->bssid);
2796 : }
2797 136 : return;
2798 : }
2799 :
2800 363 : ap = os_realloc_array(wpa_s->wps_ap, wpa_s->num_wps_ap + 1,
2801 : sizeof(struct wps_ap_info));
2802 363 : if (ap == NULL)
2803 0 : return;
2804 :
2805 363 : wpa_s->wps_ap = ap;
2806 363 : ap = &wpa_s->wps_ap[wpa_s->num_wps_ap];
2807 363 : wpa_s->num_wps_ap++;
2808 :
2809 363 : os_memset(ap, 0, sizeof(*ap));
2810 363 : os_memcpy(ap->bssid, res->bssid, ETH_ALEN);
2811 363 : ap->type = type;
2812 2178 : wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR " type %d added",
2813 2178 : MAC2STR(ap->bssid), ap->type);
2814 : }
2815 :
2816 :
2817 1475 : void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
2818 : struct wpa_scan_results *scan_res)
2819 : {
2820 : size_t i;
2821 :
2822 3084 : for (i = 0; i < scan_res->num; i++)
2823 1609 : wpas_wps_update_ap_info_bss(wpa_s, scan_res->res[i]);
2824 :
2825 1475 : wpas_wps_dump_ap_info(wpa_s);
2826 1475 : }
2827 :
2828 :
2829 2472 : void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid)
2830 : {
2831 : struct wps_ap_info *ap;
2832 :
2833 2472 : wpa_s->after_wps = 0;
2834 :
2835 2472 : if (!wpa_s->wps_ap_iter)
2836 2288 : return;
2837 184 : ap = wpas_wps_get_ap_info(wpa_s, bssid);
2838 184 : if (ap == NULL)
2839 0 : return;
2840 184 : ap->tries++;
2841 184 : os_get_reltime(&ap->last_attempt);
2842 : }
|