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