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