Line data Source code
1 : /*
2 : * WPA Supplicant
3 : * Copyright (c) 2003-2016, 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 : * This file implements functions for registering and unregistering
9 : * %wpa_supplicant interfaces. In addition, this file contains number of
10 : * functions for managing network connections.
11 : */
12 :
13 : #include "includes.h"
14 : #ifdef CONFIG_MATCH_IFACE
15 : #include <net/if.h>
16 : #include <fnmatch.h>
17 : #endif /* CONFIG_MATCH_IFACE */
18 :
19 : #include "common.h"
20 : #include "crypto/random.h"
21 : #include "crypto/sha1.h"
22 : #include "eapol_supp/eapol_supp_sm.h"
23 : #include "eap_peer/eap.h"
24 : #include "eap_peer/eap_proxy.h"
25 : #include "eap_server/eap_methods.h"
26 : #include "rsn_supp/wpa.h"
27 : #include "eloop.h"
28 : #include "config.h"
29 : #include "utils/ext_password.h"
30 : #include "l2_packet/l2_packet.h"
31 : #include "wpa_supplicant_i.h"
32 : #include "driver_i.h"
33 : #include "ctrl_iface.h"
34 : #include "pcsc_funcs.h"
35 : #include "common/version.h"
36 : #include "rsn_supp/preauth.h"
37 : #include "rsn_supp/pmksa_cache.h"
38 : #include "common/wpa_ctrl.h"
39 : #include "common/ieee802_11_defs.h"
40 : #include "common/hw_features_common.h"
41 : #include "p2p/p2p.h"
42 : #include "fst/fst.h"
43 : #include "blacklist.h"
44 : #include "wpas_glue.h"
45 : #include "wps_supplicant.h"
46 : #include "ibss_rsn.h"
47 : #include "sme.h"
48 : #include "gas_query.h"
49 : #include "ap.h"
50 : #include "p2p_supplicant.h"
51 : #include "wifi_display.h"
52 : #include "notify.h"
53 : #include "bgscan.h"
54 : #include "autoscan.h"
55 : #include "bss.h"
56 : #include "scan.h"
57 : #include "offchannel.h"
58 : #include "hs20_supplicant.h"
59 : #include "wnm_sta.h"
60 : #include "wpas_kay.h"
61 : #include "mesh.h"
62 :
63 : const char *const wpa_supplicant_version =
64 : "wpa_supplicant v" VERSION_STR "\n"
65 : "Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> and contributors";
66 :
67 : const char *const wpa_supplicant_license =
68 : "This software may be distributed under the terms of the BSD license.\n"
69 : "See README for more details.\n"
70 : #ifdef EAP_TLS_OPENSSL
71 : "\nThis product includes software developed by the OpenSSL Project\n"
72 : "for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
73 : #endif /* EAP_TLS_OPENSSL */
74 : ;
75 :
76 : #ifndef CONFIG_NO_STDOUT_DEBUG
77 : /* Long text divided into parts in order to fit in C89 strings size limits. */
78 : const char *const wpa_supplicant_full_license1 =
79 : "";
80 : const char *const wpa_supplicant_full_license2 =
81 : "This software may be distributed under the terms of the BSD license.\n"
82 : "\n"
83 : "Redistribution and use in source and binary forms, with or without\n"
84 : "modification, are permitted provided that the following conditions are\n"
85 : "met:\n"
86 : "\n";
87 : const char *const wpa_supplicant_full_license3 =
88 : "1. Redistributions of source code must retain the above copyright\n"
89 : " notice, this list of conditions and the following disclaimer.\n"
90 : "\n"
91 : "2. Redistributions in binary form must reproduce the above copyright\n"
92 : " notice, this list of conditions and the following disclaimer in the\n"
93 : " documentation and/or other materials provided with the distribution.\n"
94 : "\n";
95 : const char *const wpa_supplicant_full_license4 =
96 : "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
97 : " names of its contributors may be used to endorse or promote products\n"
98 : " derived from this software without specific prior written permission.\n"
99 : "\n"
100 : "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
101 : "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
102 : "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
103 : "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
104 : const char *const wpa_supplicant_full_license5 =
105 : "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
106 : "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
107 : "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
108 : "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
109 : "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
110 : "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
111 : "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
112 : "\n";
113 : #endif /* CONFIG_NO_STDOUT_DEBUG */
114 :
115 : /* Configure default/group WEP keys for static WEP */
116 1036 : int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
117 : {
118 1036 : int i, set = 0;
119 :
120 5180 : for (i = 0; i < NUM_WEP_KEYS; i++) {
121 4144 : if (ssid->wep_key_len[i] == 0)
122 4111 : continue;
123 :
124 33 : set = 1;
125 66 : wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
126 33 : i, i == ssid->wep_tx_keyidx, NULL, 0,
127 33 : ssid->wep_key[i], ssid->wep_key_len[i]);
128 : }
129 :
130 1036 : return set;
131 : }
132 :
133 :
134 15 : int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
135 : struct wpa_ssid *ssid)
136 : {
137 : u8 key[32];
138 : size_t keylen;
139 : enum wpa_alg alg;
140 15 : u8 seq[6] = { 0 };
141 : int ret;
142 :
143 : /* IBSS/WPA-None uses only one key (Group) for both receiving and
144 : * sending unicast and multicast packets. */
145 :
146 15 : if (ssid->mode != WPAS_MODE_IBSS) {
147 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
148 0 : "IBSS/ad-hoc) for WPA-None", ssid->mode);
149 0 : return -1;
150 : }
151 :
152 15 : if (!ssid->psk_set) {
153 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
154 : "WPA-None");
155 0 : return -1;
156 : }
157 :
158 15 : switch (wpa_s->group_cipher) {
159 : case WPA_CIPHER_CCMP:
160 0 : os_memcpy(key, ssid->psk, 16);
161 0 : keylen = 16;
162 0 : alg = WPA_ALG_CCMP;
163 0 : break;
164 : case WPA_CIPHER_GCMP:
165 0 : os_memcpy(key, ssid->psk, 16);
166 0 : keylen = 16;
167 0 : alg = WPA_ALG_GCMP;
168 0 : break;
169 : case WPA_CIPHER_TKIP:
170 : /* WPA-None uses the same Michael MIC key for both TX and RX */
171 15 : os_memcpy(key, ssid->psk, 16 + 8);
172 15 : os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
173 15 : keylen = 32;
174 15 : alg = WPA_ALG_TKIP;
175 15 : break;
176 : default:
177 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
178 : "WPA-None", wpa_s->group_cipher);
179 0 : return -1;
180 : }
181 :
182 : /* TODO: should actually remember the previously used seq#, both for TX
183 : * and RX from each STA.. */
184 :
185 15 : ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
186 15 : os_memset(key, 0, sizeof(key));
187 15 : return ret;
188 : }
189 :
190 :
191 7 : static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
192 : {
193 7 : struct wpa_supplicant *wpa_s = eloop_ctx;
194 7 : const u8 *bssid = wpa_s->bssid;
195 9 : if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
196 4 : (wpa_s->wpa_state == WPA_AUTHENTICATING ||
197 2 : wpa_s->wpa_state == WPA_ASSOCIATING))
198 2 : bssid = wpa_s->pending_bssid;
199 42 : wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
200 42 : MAC2STR(bssid));
201 7 : wpa_blacklist_add(wpa_s, bssid);
202 7 : wpa_sm_notify_disassoc(wpa_s->wpa);
203 7 : wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
204 7 : wpa_s->reassociate = 1;
205 :
206 : /*
207 : * If we timed out, the AP or the local radio may be busy.
208 : * So, wait a second until scanning again.
209 : */
210 7 : wpa_supplicant_req_scan(wpa_s, 1, 0);
211 7 : }
212 :
213 :
214 : /**
215 : * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
216 : * @wpa_s: Pointer to wpa_supplicant data
217 : * @sec: Number of seconds after which to time out authentication
218 : * @usec: Number of microseconds after which to time out authentication
219 : *
220 : * This function is used to schedule a timeout for the current authentication
221 : * attempt.
222 : */
223 8441 : void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
224 : int sec, int usec)
225 : {
226 8441 : if (wpa_s->conf->ap_scan == 0 &&
227 0 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
228 8441 : return;
229 :
230 8441 : wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
231 : "%d usec", sec, usec);
232 8441 : eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
233 8441 : eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
234 : }
235 :
236 :
237 : /**
238 : * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
239 : * @wpa_s: Pointer to wpa_supplicant data
240 : *
241 : * This function is used to cancel authentication timeout scheduled with
242 : * wpa_supplicant_req_auth_timeout() and it is called when authentication has
243 : * been completed.
244 : */
245 4139 : void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
246 : {
247 4139 : wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
248 4139 : eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
249 4139 : wpa_blacklist_del(wpa_s, wpa_s->bssid);
250 4139 : }
251 :
252 :
253 : /**
254 : * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
255 : * @wpa_s: Pointer to wpa_supplicant data
256 : *
257 : * This function is used to configure EAPOL state machine based on the selected
258 : * authentication mode.
259 : */
260 4924 : void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
261 : {
262 : #ifdef IEEE8021X_EAPOL
263 : struct eapol_config eapol_conf;
264 4924 : struct wpa_ssid *ssid = wpa_s->current_ssid;
265 :
266 : #ifdef CONFIG_IBSS_RSN
267 4954 : if (ssid->mode == WPAS_MODE_IBSS &&
268 46 : wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
269 16 : wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
270 : /*
271 : * RSN IBSS authentication is per-STA and we can disable the
272 : * per-BSSID EAPOL authentication.
273 : */
274 11 : eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
275 11 : eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
276 11 : eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
277 4935 : return;
278 : }
279 : #endif /* CONFIG_IBSS_RSN */
280 :
281 4913 : eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
282 4913 : eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
283 :
284 9029 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
285 4116 : wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
286 802 : eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
287 : else
288 4111 : eapol_sm_notify_portControl(wpa_s->eapol, Auto);
289 :
290 4913 : os_memset(&eapol_conf, 0, sizeof(eapol_conf));
291 4913 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
292 21 : eapol_conf.accept_802_1x_keys = 1;
293 21 : eapol_conf.required_keys = 0;
294 21 : if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
295 6 : eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
296 : }
297 21 : if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
298 6 : eapol_conf.required_keys |=
299 : EAPOL_REQUIRE_KEY_BROADCAST;
300 : }
301 :
302 21 : if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
303 0 : eapol_conf.required_keys = 0;
304 : }
305 4913 : eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
306 4913 : eapol_conf.workaround = ssid->eap_workaround;
307 4913 : eapol_conf.eap_disabled =
308 7519 : !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
309 7498 : wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
310 2585 : wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
311 4913 : eapol_conf.external_sim = wpa_s->conf->external_sim;
312 :
313 : #ifdef CONFIG_WPS
314 4913 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
315 539 : eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
316 539 : if (wpa_s->current_bss) {
317 : struct wpabuf *ie;
318 539 : ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
319 : WPS_IE_VENDOR_TYPE);
320 539 : if (ie) {
321 539 : if (wps_is_20(ie))
322 538 : eapol_conf.wps |=
323 : EAPOL_PEER_IS_WPS20_AP;
324 539 : wpabuf_free(ie);
325 : }
326 : }
327 : }
328 : #endif /* CONFIG_WPS */
329 :
330 4913 : eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
331 :
332 4913 : ieee802_1x_alloc_kay_sm(wpa_s, ssid);
333 : #endif /* IEEE8021X_EAPOL */
334 : }
335 :
336 :
337 : /**
338 : * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
339 : * @wpa_s: Pointer to wpa_supplicant data
340 : * @ssid: Configuration data for the network
341 : *
342 : * This function is used to configure WPA state machine and related parameters
343 : * to a mode where WPA is not enabled. This is called as part of the
344 : * authentication configuration when the selected network does not use WPA.
345 : */
346 1356 : void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
347 : struct wpa_ssid *ssid)
348 : {
349 : int i;
350 :
351 1356 : if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
352 539 : wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
353 817 : else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
354 21 : wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
355 : else
356 796 : wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
357 1356 : wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
358 1356 : wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
359 1356 : wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
360 1356 : wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
361 1356 : wpa_s->group_cipher = WPA_CIPHER_NONE;
362 1356 : wpa_s->mgmt_group_cipher = 0;
363 :
364 6656 : for (i = 0; i < NUM_WEP_KEYS; i++) {
365 5331 : if (ssid->wep_key_len[i] > 5) {
366 15 : wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
367 15 : wpa_s->group_cipher = WPA_CIPHER_WEP104;
368 15 : break;
369 5316 : } else if (ssid->wep_key_len[i] > 0) {
370 16 : wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
371 16 : wpa_s->group_cipher = WPA_CIPHER_WEP40;
372 16 : break;
373 : }
374 : }
375 :
376 1356 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
377 1356 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
378 1356 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
379 1356 : wpa_s->pairwise_cipher);
380 1356 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
381 : #ifdef CONFIG_IEEE80211W
382 1356 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
383 1356 : wpa_s->mgmt_group_cipher);
384 : #endif /* CONFIG_IEEE80211W */
385 :
386 1356 : pmksa_cache_clear_current(wpa_s->wpa);
387 1356 : }
388 :
389 :
390 15436 : void free_hw_features(struct wpa_supplicant *wpa_s)
391 : {
392 : int i;
393 15436 : if (wpa_s->hw.modes == NULL)
394 15531 : return;
395 :
396 61364 : for (i = 0; i < wpa_s->hw.num_modes; i++) {
397 46023 : os_free(wpa_s->hw.modes[i].channels);
398 46023 : os_free(wpa_s->hw.modes[i].rates);
399 : }
400 :
401 15341 : os_free(wpa_s->hw.modes);
402 15341 : wpa_s->hw.modes = NULL;
403 : }
404 :
405 :
406 733 : static void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s)
407 : {
408 : struct wpa_bss_tmp_disallowed *bss, *prev;
409 :
410 733 : dl_list_for_each_safe(bss, prev, &wpa_s->bss_tmp_disallowed,
411 : struct wpa_bss_tmp_disallowed, list) {
412 0 : dl_list_del(&bss->list);
413 0 : os_free(bss);
414 : }
415 733 : }
416 :
417 :
418 733 : static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
419 : {
420 : int i;
421 :
422 733 : bgscan_deinit(wpa_s);
423 733 : autoscan_deinit(wpa_s);
424 : scard_deinit(wpa_s->scard);
425 733 : wpa_s->scard = NULL;
426 733 : wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
427 733 : eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
428 733 : l2_packet_deinit(wpa_s->l2);
429 733 : wpa_s->l2 = NULL;
430 733 : if (wpa_s->l2_br) {
431 3 : l2_packet_deinit(wpa_s->l2_br);
432 3 : wpa_s->l2_br = NULL;
433 : }
434 : #ifdef CONFIG_TESTING_OPTIONS
435 733 : l2_packet_deinit(wpa_s->l2_test);
436 733 : wpa_s->l2_test = NULL;
437 : #endif /* CONFIG_TESTING_OPTIONS */
438 :
439 733 : if (wpa_s->conf != NULL) {
440 : struct wpa_ssid *ssid;
441 1254 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
442 539 : wpas_notify_network_removed(wpa_s, ssid);
443 : }
444 :
445 733 : os_free(wpa_s->confname);
446 733 : wpa_s->confname = NULL;
447 :
448 733 : os_free(wpa_s->confanother);
449 733 : wpa_s->confanother = NULL;
450 :
451 733 : wpa_sm_set_eapol(wpa_s->wpa, NULL);
452 733 : eapol_sm_deinit(wpa_s->eapol);
453 733 : wpa_s->eapol = NULL;
454 :
455 733 : rsn_preauth_deinit(wpa_s->wpa);
456 :
457 : #ifdef CONFIG_TDLS
458 733 : wpa_tdls_deinit(wpa_s->wpa);
459 : #endif /* CONFIG_TDLS */
460 :
461 733 : wmm_ac_clear_saved_tspecs(wpa_s);
462 733 : pmksa_candidate_free(wpa_s->wpa);
463 733 : wpa_sm_deinit(wpa_s->wpa);
464 733 : wpa_s->wpa = NULL;
465 733 : wpa_blacklist_clear(wpa_s);
466 :
467 733 : wpa_bss_deinit(wpa_s);
468 :
469 733 : wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
470 733 : wpa_supplicant_cancel_scan(wpa_s);
471 733 : wpa_supplicant_cancel_auth_timeout(wpa_s);
472 733 : eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
473 : #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
474 : eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
475 : wpa_s, NULL);
476 : #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
477 :
478 733 : eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
479 :
480 733 : wpas_wps_deinit(wpa_s);
481 :
482 733 : wpabuf_free(wpa_s->pending_eapol_rx);
483 733 : wpa_s->pending_eapol_rx = NULL;
484 :
485 : #ifdef CONFIG_IBSS_RSN
486 733 : ibss_rsn_deinit(wpa_s->ibss_rsn);
487 733 : wpa_s->ibss_rsn = NULL;
488 : #endif /* CONFIG_IBSS_RSN */
489 :
490 733 : sme_deinit(wpa_s);
491 :
492 : #ifdef CONFIG_AP
493 733 : wpa_supplicant_ap_deinit(wpa_s);
494 : #endif /* CONFIG_AP */
495 :
496 733 : wpas_p2p_deinit(wpa_s);
497 :
498 : #ifdef CONFIG_OFFCHANNEL
499 733 : offchannel_deinit(wpa_s);
500 : #endif /* CONFIG_OFFCHANNEL */
501 :
502 733 : wpa_supplicant_cancel_sched_scan(wpa_s);
503 :
504 733 : os_free(wpa_s->next_scan_freqs);
505 733 : wpa_s->next_scan_freqs = NULL;
506 :
507 733 : os_free(wpa_s->manual_scan_freqs);
508 733 : wpa_s->manual_scan_freqs = NULL;
509 :
510 733 : os_free(wpa_s->manual_sched_scan_freqs);
511 733 : wpa_s->manual_sched_scan_freqs = NULL;
512 :
513 733 : wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
514 :
515 : /*
516 : * Need to remove any pending gas-query radio work before the
517 : * gas_query_deinit() call because gas_query::work has not yet been set
518 : * for works that have not been started. gas_query_free() will be unable
519 : * to cancel such pending radio works and once the pending gas-query
520 : * radio work eventually gets removed, the deinit notification call to
521 : * gas_query_start_cb() would result in dereferencing freed memory.
522 : */
523 733 : if (wpa_s->radio)
524 710 : radio_remove_works(wpa_s, "gas-query", 0);
525 733 : gas_query_deinit(wpa_s->gas);
526 733 : wpa_s->gas = NULL;
527 :
528 733 : free_hw_features(wpa_s);
529 :
530 733 : ieee802_1x_dealloc_kay_sm(wpa_s);
531 :
532 733 : os_free(wpa_s->bssid_filter);
533 733 : wpa_s->bssid_filter = NULL;
534 :
535 733 : os_free(wpa_s->disallow_aps_bssid);
536 733 : wpa_s->disallow_aps_bssid = NULL;
537 733 : os_free(wpa_s->disallow_aps_ssid);
538 733 : wpa_s->disallow_aps_ssid = NULL;
539 :
540 733 : wnm_bss_keep_alive_deinit(wpa_s);
541 : #ifdef CONFIG_WNM
542 733 : wnm_deallocate_memory(wpa_s);
543 : #endif /* CONFIG_WNM */
544 :
545 733 : ext_password_deinit(wpa_s->ext_pw);
546 733 : wpa_s->ext_pw = NULL;
547 :
548 733 : wpabuf_free(wpa_s->last_gas_resp);
549 733 : wpa_s->last_gas_resp = NULL;
550 733 : wpabuf_free(wpa_s->prev_gas_resp);
551 733 : wpa_s->prev_gas_resp = NULL;
552 :
553 733 : os_free(wpa_s->last_scan_res);
554 733 : wpa_s->last_scan_res = NULL;
555 :
556 : #ifdef CONFIG_HS20
557 733 : if (wpa_s->drv_priv)
558 711 : wpa_drv_configure_frame_filters(wpa_s, 0);
559 733 : hs20_deinit(wpa_s);
560 : #endif /* CONFIG_HS20 */
561 :
562 11728 : for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
563 10995 : wpabuf_free(wpa_s->vendor_elem[i]);
564 10995 : wpa_s->vendor_elem[i] = NULL;
565 : }
566 :
567 733 : wmm_ac_notify_disassoc(wpa_s);
568 :
569 733 : wpa_s->sched_scan_plans_num = 0;
570 733 : os_free(wpa_s->sched_scan_plans);
571 733 : wpa_s->sched_scan_plans = NULL;
572 :
573 : #ifdef CONFIG_MBO
574 733 : wpa_s->non_pref_chan_num = 0;
575 733 : os_free(wpa_s->non_pref_chan);
576 733 : wpa_s->non_pref_chan = NULL;
577 : #endif /* CONFIG_MBO */
578 :
579 733 : free_bss_tmp_disallowed(wpa_s);
580 :
581 733 : wpabuf_free(wpa_s->lci);
582 733 : wpa_s->lci = NULL;
583 733 : }
584 :
585 :
586 : /**
587 : * wpa_clear_keys - Clear keys configured for the driver
588 : * @wpa_s: Pointer to wpa_supplicant data
589 : * @addr: Previously used BSSID or %NULL if not available
590 : *
591 : * This function clears the encryption keys that has been previously configured
592 : * for the driver.
593 : */
594 19642 : void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
595 : {
596 : int i, max;
597 :
598 : #ifdef CONFIG_IEEE80211W
599 19642 : max = 6;
600 : #else /* CONFIG_IEEE80211W */
601 : max = 4;
602 : #endif /* CONFIG_IEEE80211W */
603 :
604 : /* MLME-DELETEKEYS.request */
605 137494 : for (i = 0; i < max; i++) {
606 117852 : if (wpa_s->keys_cleared & BIT(i))
607 108884 : continue;
608 8968 : wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
609 : NULL, 0);
610 : }
611 21849 : if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
612 2207 : !is_zero_ether_addr(addr)) {
613 2186 : wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
614 : 0);
615 : /* MLME-SETPROTECTION.request(None) */
616 2186 : wpa_drv_mlme_setprotection(
617 : wpa_s, addr,
618 : MLME_SETPROTECTION_PROTECT_TYPE_NONE,
619 : MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
620 : }
621 19642 : wpa_s->keys_cleared = (u32) -1;
622 19642 : }
623 :
624 :
625 : /**
626 : * wpa_supplicant_state_txt - Get the connection state name as a text string
627 : * @state: State (wpa_state; WPA_*)
628 : * Returns: The state name as a printable text string
629 : */
630 193212 : const char * wpa_supplicant_state_txt(enum wpa_states state)
631 : {
632 193212 : switch (state) {
633 : case WPA_DISCONNECTED:
634 49707 : return "DISCONNECTED";
635 : case WPA_INACTIVE:
636 6766 : return "INACTIVE";
637 : case WPA_INTERFACE_DISABLED:
638 273 : return "INTERFACE_DISABLED";
639 : case WPA_SCANNING:
640 19453 : return "SCANNING";
641 : case WPA_AUTHENTICATING:
642 23177 : return "AUTHENTICATING";
643 : case WPA_ASSOCIATING:
644 23804 : return "ASSOCIATING";
645 : case WPA_ASSOCIATED:
646 23839 : return "ASSOCIATED";
647 : case WPA_4WAY_HANDSHAKE:
648 14992 : return "4WAY_HANDSHAKE";
649 : case WPA_GROUP_HANDSHAKE:
650 7493 : return "GROUP_HANDSHAKE";
651 : case WPA_COMPLETED:
652 23708 : return "COMPLETED";
653 : default:
654 0 : return "UNKNOWN";
655 : }
656 : }
657 :
658 :
659 : #ifdef CONFIG_BGSCAN
660 :
661 4000 : static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
662 : {
663 : const char *name;
664 :
665 4000 : if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
666 14 : name = wpa_s->current_ssid->bgscan;
667 : else
668 3986 : name = wpa_s->conf->bgscan;
669 4000 : if (name == NULL || name[0] == '\0')
670 3986 : return;
671 14 : if (wpas_driver_bss_selection(wpa_s))
672 0 : return;
673 14 : if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
674 0 : return;
675 : #ifdef CONFIG_P2P
676 14 : if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
677 0 : return;
678 : #endif /* CONFIG_P2P */
679 :
680 14 : bgscan_deinit(wpa_s);
681 14 : if (wpa_s->current_ssid) {
682 14 : if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
683 4 : wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
684 : "bgscan");
685 : /*
686 : * Live without bgscan; it is only used as a roaming
687 : * optimization, so the initial connection is not
688 : * affected.
689 : */
690 : } else {
691 : struct wpa_scan_results *scan_res;
692 10 : wpa_s->bgscan_ssid = wpa_s->current_ssid;
693 10 : scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
694 : 0);
695 10 : if (scan_res) {
696 10 : bgscan_notify_scan(wpa_s, scan_res);
697 10 : wpa_scan_results_free(scan_res);
698 : }
699 : }
700 : } else
701 0 : wpa_s->bgscan_ssid = NULL;
702 : }
703 :
704 :
705 29236 : static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
706 : {
707 29236 : if (wpa_s->bgscan_ssid != NULL) {
708 10 : bgscan_deinit(wpa_s);
709 10 : wpa_s->bgscan_ssid = NULL;
710 : }
711 29236 : }
712 :
713 : #endif /* CONFIG_BGSCAN */
714 :
715 :
716 15719 : static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
717 : {
718 15719 : if (autoscan_init(wpa_s, 0))
719 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
720 15719 : }
721 :
722 :
723 4597 : static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
724 : {
725 4597 : autoscan_deinit(wpa_s);
726 4597 : }
727 :
728 :
729 150 : void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
730 : {
731 201 : if (wpa_s->wpa_state == WPA_DISCONNECTED ||
732 51 : wpa_s->wpa_state == WPA_SCANNING) {
733 100 : autoscan_deinit(wpa_s);
734 100 : wpa_supplicant_start_autoscan(wpa_s);
735 : }
736 150 : }
737 :
738 :
739 : /**
740 : * wpa_supplicant_set_state - Set current connection state
741 : * @wpa_s: Pointer to wpa_supplicant data
742 : * @state: The new connection state
743 : *
744 : * This function is called whenever the connection state changes, e.g.,
745 : * association is completed for WPA/WPA2 4-Way Handshake is started.
746 : */
747 44582 : void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
748 : enum wpa_states state)
749 : {
750 44582 : enum wpa_states old_state = wpa_s->wpa_state;
751 :
752 44582 : wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
753 : wpa_supplicant_state_txt(wpa_s->wpa_state),
754 : wpa_supplicant_state_txt(state));
755 :
756 44582 : if (state == WPA_INTERFACE_DISABLED) {
757 : /* Assure normal scan when interface is restored */
758 115 : wpa_s->normal_scans = 0;
759 : }
760 :
761 44582 : if (state == WPA_COMPLETED) {
762 4000 : wpas_connect_work_done(wpa_s);
763 : /* Reinitialize normal_scan counter */
764 4000 : wpa_s->normal_scans = 0;
765 : }
766 :
767 : #ifdef CONFIG_P2P
768 : /*
769 : * P2PS client has to reply to Probe Request frames received on the
770 : * group operating channel. Enable Probe Request frame reporting for
771 : * P2P connected client in case p2p_cli_probe configuration property is
772 : * set to 1.
773 : */
774 45591 : if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid &&
775 2012 : wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
776 1003 : wpa_s->current_ssid->p2p_group) {
777 20 : if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) {
778 2 : wpa_dbg(wpa_s, MSG_DEBUG,
779 : "P2P: Enable CLI Probe Request RX reporting");
780 2 : wpa_s->p2p_cli_probe =
781 2 : wpa_drv_probe_req_report(wpa_s, 1) >= 0;
782 18 : } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) {
783 2 : wpa_dbg(wpa_s, MSG_DEBUG,
784 : "P2P: Disable CLI Probe Request RX reporting");
785 2 : wpa_s->p2p_cli_probe = 0;
786 2 : wpa_drv_probe_req_report(wpa_s, 0);
787 : }
788 : }
789 : #endif /* CONFIG_P2P */
790 :
791 44582 : if (state != WPA_SCANNING)
792 40507 : wpa_supplicant_notify_scanning(wpa_s, 0);
793 :
794 48236 : if (state == WPA_COMPLETED && wpa_s->new_connection) {
795 3654 : struct wpa_ssid *ssid = wpa_s->current_ssid;
796 : #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
797 25579 : wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
798 : MACSTR " completed [id=%d id_str=%s]",
799 21924 : MAC2STR(wpa_s->bssid),
800 : ssid ? ssid->id : -1,
801 3654 : ssid && ssid->id_str ? ssid->id_str : "");
802 : #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
803 3654 : wpas_clear_temp_disabled(wpa_s, ssid, 1);
804 3654 : wpa_blacklist_clear(wpa_s);
805 3654 : wpa_s->extra_blacklist_count = 0;
806 3654 : wpa_s->new_connection = 0;
807 3654 : wpa_drv_set_operstate(wpa_s, 1);
808 : #ifndef IEEE8021X_EAPOL
809 : wpa_drv_set_supp_port(wpa_s, 1);
810 : #endif /* IEEE8021X_EAPOL */
811 3654 : wpa_s->after_wps = 0;
812 3654 : wpa_s->known_wps_freq = 0;
813 3654 : wpas_p2p_completed(wpa_s);
814 :
815 3654 : sme_sched_obss_scan(wpa_s, 1);
816 40928 : } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
817 : state == WPA_ASSOCIATED) {
818 23476 : wpa_s->new_connection = 1;
819 23476 : wpa_drv_set_operstate(wpa_s, 0);
820 : #ifndef IEEE8021X_EAPOL
821 : wpa_drv_set_supp_port(wpa_s, 0);
822 : #endif /* IEEE8021X_EAPOL */
823 23476 : sme_sched_obss_scan(wpa_s, 0);
824 : }
825 44582 : wpa_s->wpa_state = state;
826 :
827 : #ifdef CONFIG_BGSCAN
828 44582 : if (state == WPA_COMPLETED)
829 4000 : wpa_supplicant_start_bgscan(wpa_s);
830 40582 : else if (state < WPA_ASSOCIATED)
831 29236 : wpa_supplicant_stop_bgscan(wpa_s);
832 : #endif /* CONFIG_BGSCAN */
833 :
834 44582 : if (state == WPA_AUTHENTICATING)
835 4597 : wpa_supplicant_stop_autoscan(wpa_s);
836 :
837 44582 : if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
838 15619 : wpa_supplicant_start_autoscan(wpa_s);
839 :
840 44582 : if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
841 5381 : wmm_ac_notify_disassoc(wpa_s);
842 :
843 44582 : if (wpa_s->wpa_state != old_state) {
844 35380 : wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
845 :
846 : /*
847 : * Notify the P2P Device interface about a state change in one
848 : * of the interfaces.
849 : */
850 35380 : wpas_p2p_indicate_state_change(wpa_s);
851 :
852 35380 : if (wpa_s->wpa_state == WPA_COMPLETED ||
853 : old_state == WPA_COMPLETED)
854 7532 : wpas_notify_auth_changed(wpa_s);
855 : }
856 44582 : }
857 :
858 :
859 27 : void wpa_supplicant_terminate_proc(struct wpa_global *global)
860 : {
861 27 : int pending = 0;
862 : #ifdef CONFIG_WPS
863 27 : struct wpa_supplicant *wpa_s = global->ifaces;
864 77 : while (wpa_s) {
865 23 : struct wpa_supplicant *next = wpa_s->next;
866 23 : if (wpas_wps_terminate_pending(wpa_s) == 1)
867 0 : pending = 1;
868 : #ifdef CONFIG_P2P
869 46 : if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
870 23 : (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
871 0 : wpas_p2p_disconnect(wpa_s);
872 : #endif /* CONFIG_P2P */
873 23 : wpa_s = next;
874 : }
875 : #endif /* CONFIG_WPS */
876 27 : if (pending)
877 27 : return;
878 27 : eloop_terminate();
879 : }
880 :
881 :
882 26 : static void wpa_supplicant_terminate(int sig, void *signal_ctx)
883 : {
884 26 : struct wpa_global *global = signal_ctx;
885 26 : wpa_supplicant_terminate_proc(global);
886 26 : }
887 :
888 :
889 508 : void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
890 : {
891 508 : enum wpa_states old_state = wpa_s->wpa_state;
892 :
893 508 : wpa_s->pairwise_cipher = 0;
894 508 : wpa_s->group_cipher = 0;
895 508 : wpa_s->mgmt_group_cipher = 0;
896 508 : wpa_s->key_mgmt = 0;
897 508 : if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
898 508 : wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
899 :
900 508 : if (wpa_s->wpa_state != old_state)
901 219 : wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
902 508 : }
903 :
904 :
905 : /**
906 : * wpa_supplicant_reload_configuration - Reload configuration data
907 : * @wpa_s: Pointer to wpa_supplicant data
908 : * Returns: 0 on success or -1 if configuration parsing failed
909 : *
910 : * This function can be used to request that the configuration data is reloaded
911 : * (e.g., after configuration file change). This function is reloading
912 : * configuration only for one interface, so this may need to be called multiple
913 : * times if %wpa_supplicant is controlling multiple interfaces and all
914 : * interfaces need reconfiguration.
915 : */
916 1 : int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
917 : {
918 : struct wpa_config *conf;
919 : int reconf_ctrl;
920 : int old_ap_scan;
921 :
922 1 : if (wpa_s->confname == NULL)
923 0 : return -1;
924 1 : conf = wpa_config_read(wpa_s->confname, NULL);
925 1 : if (conf == NULL) {
926 0 : wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
927 : "file '%s' - exiting", wpa_s->confname);
928 0 : return -1;
929 : }
930 1 : wpa_config_read(wpa_s->confanother, conf);
931 :
932 1 : conf->changed_parameters = (unsigned int) -1;
933 :
934 2 : reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
935 2 : || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
936 1 : os_strcmp(conf->ctrl_interface,
937 : wpa_s->conf->ctrl_interface) != 0);
938 :
939 1 : if (reconf_ctrl && wpa_s->ctrl_iface) {
940 0 : wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
941 0 : wpa_s->ctrl_iface = NULL;
942 : }
943 :
944 1 : eapol_sm_invalidate_cached_session(wpa_s->eapol);
945 1 : if (wpa_s->current_ssid) {
946 0 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
947 0 : wpa_s->own_disconnect_req = 1;
948 0 : wpa_supplicant_deauthenticate(wpa_s,
949 : WLAN_REASON_DEAUTH_LEAVING);
950 : }
951 :
952 : /*
953 : * TODO: should notify EAPOL SM about changes in opensc_engine_path,
954 : * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
955 : */
956 1 : if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
957 : /*
958 : * Clear forced success to clear EAP state for next
959 : * authentication.
960 : */
961 0 : eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
962 : }
963 1 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
964 1 : wpa_sm_set_config(wpa_s->wpa, NULL);
965 1 : wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
966 1 : wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
967 1 : rsn_preauth_deinit(wpa_s->wpa);
968 :
969 1 : old_ap_scan = wpa_s->conf->ap_scan;
970 1 : wpa_config_free(wpa_s->conf);
971 1 : wpa_s->conf = conf;
972 1 : if (old_ap_scan != wpa_s->conf->ap_scan)
973 0 : wpas_notify_ap_scan_changed(wpa_s);
974 :
975 1 : if (reconf_ctrl)
976 0 : wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
977 :
978 1 : wpa_supplicant_update_config(wpa_s);
979 :
980 1 : wpa_supplicant_clear_status(wpa_s);
981 1 : if (wpa_supplicant_enabled_networks(wpa_s)) {
982 0 : wpa_s->reassociate = 1;
983 0 : wpa_supplicant_req_scan(wpa_s, 0, 0);
984 : }
985 1 : wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
986 1 : return 0;
987 : }
988 :
989 :
990 0 : static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
991 : {
992 0 : struct wpa_global *global = signal_ctx;
993 : struct wpa_supplicant *wpa_s;
994 0 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
995 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
996 : sig);
997 0 : if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
998 0 : wpa_supplicant_terminate_proc(global);
999 : }
1000 : }
1001 :
1002 0 : if (wpa_debug_reopen_file() < 0) {
1003 : /* Ignore errors since we cannot really do much to fix this */
1004 0 : wpa_printf(MSG_DEBUG, "Could not reopen debug log file");
1005 : }
1006 0 : }
1007 :
1008 :
1009 25 : static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
1010 : struct wpa_ssid *ssid,
1011 : struct wpa_ie_data *ie)
1012 : {
1013 25 : int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
1014 25 : if (ret) {
1015 18 : if (ret == -2) {
1016 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
1017 : "from association info");
1018 : }
1019 18 : return -1;
1020 : }
1021 :
1022 7 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
1023 : "cipher suites");
1024 7 : if (!(ie->group_cipher & ssid->group_cipher)) {
1025 1 : wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
1026 : "cipher 0x%x (mask 0x%x) - reject",
1027 : ie->group_cipher, ssid->group_cipher);
1028 1 : return -1;
1029 : }
1030 6 : if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
1031 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
1032 : "cipher 0x%x (mask 0x%x) - reject",
1033 : ie->pairwise_cipher, ssid->pairwise_cipher);
1034 0 : return -1;
1035 : }
1036 6 : if (!(ie->key_mgmt & ssid->key_mgmt)) {
1037 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
1038 : "management 0x%x (mask 0x%x) - reject",
1039 : ie->key_mgmt, ssid->key_mgmt);
1040 0 : return -1;
1041 : }
1042 :
1043 : #ifdef CONFIG_IEEE80211W
1044 11 : if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
1045 5 : wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
1046 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
1047 : "that does not support management frame protection - "
1048 : "reject");
1049 0 : return -1;
1050 : }
1051 : #endif /* CONFIG_IEEE80211W */
1052 :
1053 6 : return 0;
1054 : }
1055 :
1056 :
1057 : /**
1058 : * wpa_supplicant_set_suites - Set authentication and encryption parameters
1059 : * @wpa_s: Pointer to wpa_supplicant data
1060 : * @bss: Scan results for the selected BSS, or %NULL if not available
1061 : * @ssid: Configuration data for the selected network
1062 : * @wpa_ie: Buffer for the WPA/RSN IE
1063 : * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
1064 : * used buffer length in case the functions returns success.
1065 : * Returns: 0 on success or -1 on failure
1066 : *
1067 : * This function is used to configure authentication and encryption parameters
1068 : * based on the network configuration and scan result for the selected BSS (if
1069 : * available).
1070 : */
1071 3616 : int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
1072 : struct wpa_bss *bss, struct wpa_ssid *ssid,
1073 : u8 *wpa_ie, size_t *wpa_ie_len)
1074 : {
1075 : struct wpa_ie_data ie;
1076 : int sel, proto;
1077 : const u8 *bss_wpa, *bss_rsn, *bss_osen;
1078 :
1079 3616 : if (bss) {
1080 3591 : bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1081 3591 : bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1082 3591 : bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
1083 : } else
1084 25 : bss_wpa = bss_rsn = bss_osen = NULL;
1085 :
1086 7159 : if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
1087 7086 : wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
1088 7086 : (ie.group_cipher & ssid->group_cipher) &&
1089 7085 : (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1090 3542 : (ie.key_mgmt & ssid->key_mgmt)) {
1091 3542 : wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
1092 3542 : proto = WPA_PROTO_RSN;
1093 123 : } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
1094 98 : wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
1095 98 : (ie.group_cipher & ssid->group_cipher) &&
1096 98 : (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1097 49 : (ie.key_mgmt & ssid->key_mgmt)) {
1098 49 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
1099 49 : proto = WPA_PROTO_WPA;
1100 : #ifdef CONFIG_HS20
1101 25 : } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
1102 0 : wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
1103 : /* TODO: parse OSEN element */
1104 0 : os_memset(&ie, 0, sizeof(ie));
1105 0 : ie.group_cipher = WPA_CIPHER_CCMP;
1106 0 : ie.pairwise_cipher = WPA_CIPHER_CCMP;
1107 0 : ie.key_mgmt = WPA_KEY_MGMT_OSEN;
1108 0 : proto = WPA_PROTO_OSEN;
1109 : #endif /* CONFIG_HS20 */
1110 25 : } else if (bss) {
1111 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
1112 0 : wpa_dbg(wpa_s, MSG_DEBUG,
1113 : "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1114 : ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
1115 : ssid->key_mgmt);
1116 0 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
1117 : MAC2STR(bss->bssid),
1118 : wpa_ssid_txt(bss->ssid, bss->ssid_len),
1119 : bss_wpa ? " WPA" : "",
1120 : bss_rsn ? " RSN" : "",
1121 : bss_osen ? " OSEN" : "");
1122 0 : if (bss_rsn) {
1123 0 : wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
1124 0 : if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
1125 0 : wpa_dbg(wpa_s, MSG_DEBUG,
1126 : "Could not parse RSN element");
1127 : } else {
1128 0 : wpa_dbg(wpa_s, MSG_DEBUG,
1129 : "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1130 : ie.pairwise_cipher, ie.group_cipher,
1131 : ie.key_mgmt);
1132 : }
1133 : }
1134 0 : if (bss_wpa) {
1135 0 : wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
1136 0 : if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
1137 0 : wpa_dbg(wpa_s, MSG_DEBUG,
1138 : "Could not parse WPA element");
1139 : } else {
1140 0 : wpa_dbg(wpa_s, MSG_DEBUG,
1141 : "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1142 : ie.pairwise_cipher, ie.group_cipher,
1143 : ie.key_mgmt);
1144 : }
1145 : }
1146 0 : return -1;
1147 : } else {
1148 25 : if (ssid->proto & WPA_PROTO_OSEN)
1149 2 : proto = WPA_PROTO_OSEN;
1150 23 : else if (ssid->proto & WPA_PROTO_RSN)
1151 18 : proto = WPA_PROTO_RSN;
1152 : else
1153 5 : proto = WPA_PROTO_WPA;
1154 25 : if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1155 19 : os_memset(&ie, 0, sizeof(ie));
1156 19 : ie.group_cipher = ssid->group_cipher;
1157 19 : ie.pairwise_cipher = ssid->pairwise_cipher;
1158 19 : ie.key_mgmt = ssid->key_mgmt;
1159 : #ifdef CONFIG_IEEE80211W
1160 19 : ie.mgmt_group_cipher =
1161 19 : ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
1162 : WPA_CIPHER_AES_128_CMAC : 0;
1163 : #endif /* CONFIG_IEEE80211W */
1164 19 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1165 : "based on configuration");
1166 : } else
1167 6 : proto = ie.proto;
1168 : }
1169 :
1170 3616 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1171 : "pairwise %d key_mgmt %d proto %d",
1172 : ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
1173 : #ifdef CONFIG_IEEE80211W
1174 3616 : if (ssid->ieee80211w) {
1175 3610 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1176 : ie.mgmt_group_cipher);
1177 : }
1178 : #endif /* CONFIG_IEEE80211W */
1179 :
1180 3616 : wpa_s->wpa_proto = proto;
1181 3616 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1182 3616 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1183 3616 : !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
1184 :
1185 3616 : if (bss || !wpa_s->ap_ies_from_associnfo) {
1186 3704 : if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1187 3704 : bss_wpa ? 2 + bss_wpa[1] : 0) ||
1188 7165 : wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1189 3549 : bss_rsn ? 2 + bss_rsn[1] : 0))
1190 1 : return -1;
1191 : }
1192 :
1193 : #ifdef CONFIG_NO_WPA
1194 : wpa_s->group_cipher = WPA_CIPHER_NONE;
1195 : wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
1196 : #else /* CONFIG_NO_WPA */
1197 3615 : sel = ie.group_cipher & ssid->group_cipher;
1198 3615 : wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1199 3615 : if (wpa_s->group_cipher < 0) {
1200 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1201 : "cipher");
1202 0 : return -1;
1203 : }
1204 3615 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1205 : wpa_cipher_txt(wpa_s->group_cipher));
1206 :
1207 3615 : sel = ie.pairwise_cipher & ssid->pairwise_cipher;
1208 3615 : wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1209 3615 : if (wpa_s->pairwise_cipher < 0) {
1210 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1211 : "cipher");
1212 0 : return -1;
1213 : }
1214 3615 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1215 : wpa_cipher_txt(wpa_s->pairwise_cipher));
1216 : #endif /* CONFIG_NO_WPA */
1217 :
1218 3615 : sel = ie.key_mgmt & ssid->key_mgmt;
1219 : #ifdef CONFIG_SAE
1220 3615 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1221 9 : sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1222 : #endif /* CONFIG_SAE */
1223 : if (0) {
1224 : #ifdef CONFIG_SUITEB192
1225 3615 : } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1226 5 : wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1227 5 : wpa_dbg(wpa_s, MSG_DEBUG,
1228 : "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
1229 : #endif /* CONFIG_SUITEB192 */
1230 : #ifdef CONFIG_SUITEB
1231 3610 : } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1232 5 : wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1233 5 : wpa_dbg(wpa_s, MSG_DEBUG,
1234 : "WPA: using KEY_MGMT 802.1X with Suite B");
1235 : #endif /* CONFIG_SUITEB */
1236 : #ifdef CONFIG_IEEE80211R
1237 3605 : } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1238 9 : wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1239 9 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1240 3596 : } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1241 168 : wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1242 168 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1243 : #endif /* CONFIG_IEEE80211R */
1244 : #ifdef CONFIG_SAE
1245 3428 : } else if (sel & WPA_KEY_MGMT_SAE) {
1246 228 : wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1247 228 : wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1248 3200 : } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1249 8 : wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1250 8 : wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1251 : #endif /* CONFIG_SAE */
1252 : #ifdef CONFIG_IEEE80211W
1253 3192 : } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1254 5 : wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1255 5 : wpa_dbg(wpa_s, MSG_DEBUG,
1256 : "WPA: using KEY_MGMT 802.1X with SHA256");
1257 3187 : } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1258 27 : wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1259 27 : wpa_dbg(wpa_s, MSG_DEBUG,
1260 : "WPA: using KEY_MGMT PSK with SHA256");
1261 : #endif /* CONFIG_IEEE80211W */
1262 3160 : } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1263 2281 : wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1264 2281 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1265 879 : } else if (sel & WPA_KEY_MGMT_PSK) {
1266 872 : wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1267 872 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1268 7 : } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1269 5 : wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1270 5 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1271 : #ifdef CONFIG_HS20
1272 2 : } else if (sel & WPA_KEY_MGMT_OSEN) {
1273 2 : wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1274 2 : wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1275 : #endif /* CONFIG_HS20 */
1276 : } else {
1277 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1278 : "authenticated key management type");
1279 0 : return -1;
1280 : }
1281 :
1282 3615 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1283 3615 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1284 3615 : wpa_s->pairwise_cipher);
1285 3615 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1286 :
1287 : #ifdef CONFIG_IEEE80211W
1288 3615 : sel = ie.mgmt_group_cipher;
1289 4085 : if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
1290 470 : !(ie.capabilities & WPA_CAPABILITY_MFPC))
1291 3542 : sel = 0;
1292 3615 : if (sel & WPA_CIPHER_AES_128_CMAC) {
1293 60 : wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1294 60 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1295 : "AES-128-CMAC");
1296 3555 : } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1297 6 : wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1298 6 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1299 : "BIP-GMAC-128");
1300 3549 : } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1301 6 : wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1302 6 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1303 : "BIP-GMAC-256");
1304 3543 : } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1305 1 : wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1306 1 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1307 : "BIP-CMAC-256");
1308 : } else {
1309 3542 : wpa_s->mgmt_group_cipher = 0;
1310 3542 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1311 : }
1312 3615 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1313 3615 : wpa_s->mgmt_group_cipher);
1314 3615 : wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1315 3615 : wpas_get_ssid_pmf(wpa_s, ssid));
1316 : #endif /* CONFIG_IEEE80211W */
1317 :
1318 3615 : if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1319 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1320 0 : return -1;
1321 : }
1322 :
1323 3615 : if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
1324 1303 : int psk_set = 0;
1325 :
1326 1303 : if (ssid->psk_set) {
1327 1297 : wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL,
1328 : NULL);
1329 1297 : psk_set = 1;
1330 : }
1331 : #ifndef CONFIG_NO_PBKDF2
1332 1305 : if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1333 2 : ssid->passphrase) {
1334 : u8 psk[PMK_LEN];
1335 1 : pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1336 : 4096, psk, PMK_LEN);
1337 1 : wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1338 : psk, PMK_LEN);
1339 1 : wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL);
1340 1 : psk_set = 1;
1341 1 : os_memset(psk, 0, sizeof(psk));
1342 : }
1343 : #endif /* CONFIG_NO_PBKDF2 */
1344 : #ifdef CONFIG_EXT_PASSWORD
1345 1303 : if (ssid->ext_psk) {
1346 5 : struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1347 5 : ssid->ext_psk);
1348 : char pw_str[64 + 1];
1349 : u8 psk[PMK_LEN];
1350 :
1351 5 : if (pw == NULL) {
1352 1 : wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1353 : "found from external storage");
1354 5 : return -1;
1355 : }
1356 :
1357 4 : if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1358 2 : wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1359 : "PSK length %d in external storage",
1360 2 : (int) wpabuf_len(pw));
1361 2 : ext_password_free(pw);
1362 2 : return -1;
1363 : }
1364 :
1365 2 : os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1366 2 : pw_str[wpabuf_len(pw)] = '\0';
1367 :
1368 : #ifndef CONFIG_NO_PBKDF2
1369 2 : if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1370 : {
1371 1 : pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1372 : 4096, psk, PMK_LEN);
1373 1 : os_memset(pw_str, 0, sizeof(pw_str));
1374 1 : wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1375 : "external passphrase)",
1376 : psk, PMK_LEN);
1377 1 : wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1378 : NULL);
1379 1 : psk_set = 1;
1380 1 : os_memset(psk, 0, sizeof(psk));
1381 : } else
1382 : #endif /* CONFIG_NO_PBKDF2 */
1383 1 : if (wpabuf_len(pw) == 2 * PMK_LEN) {
1384 1 : if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1385 1 : wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1386 : "Invalid PSK hex string");
1387 1 : os_memset(pw_str, 0, sizeof(pw_str));
1388 1 : ext_password_free(pw);
1389 1 : return -1;
1390 : }
1391 0 : wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1392 : NULL);
1393 0 : psk_set = 1;
1394 0 : os_memset(psk, 0, sizeof(psk));
1395 : } else {
1396 0 : wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1397 : "PSK available");
1398 0 : os_memset(pw_str, 0, sizeof(pw_str));
1399 0 : ext_password_free(pw);
1400 0 : return -1;
1401 : }
1402 :
1403 1 : os_memset(pw_str, 0, sizeof(pw_str));
1404 1 : ext_password_free(pw);
1405 : }
1406 : #endif /* CONFIG_EXT_PASSWORD */
1407 :
1408 1299 : if (!psk_set) {
1409 0 : wpa_msg(wpa_s, MSG_INFO,
1410 : "No PSK available for association");
1411 0 : return -1;
1412 : }
1413 : } else
1414 2312 : wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1415 :
1416 3611 : return 0;
1417 : }
1418 :
1419 :
1420 83649 : static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1421 : {
1422 83649 : *pos = 0x00;
1423 :
1424 83649 : switch (idx) {
1425 : case 0: /* Bits 0-7 */
1426 10475 : break;
1427 : case 1: /* Bits 8-15 */
1428 10475 : break;
1429 : case 2: /* Bits 16-23 */
1430 : #ifdef CONFIG_WNM
1431 10475 : *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1432 10475 : *pos |= 0x08; /* Bit 19 - BSS Transition */
1433 : #endif /* CONFIG_WNM */
1434 10475 : break;
1435 : case 3: /* Bits 24-31 */
1436 : #ifdef CONFIG_WNM
1437 10475 : *pos |= 0x02; /* Bit 25 - SSID List */
1438 : #endif /* CONFIG_WNM */
1439 : #ifdef CONFIG_INTERWORKING
1440 10475 : if (wpa_s->conf->interworking)
1441 4067 : *pos |= 0x80; /* Bit 31 - Interworking */
1442 : #endif /* CONFIG_INTERWORKING */
1443 10475 : break;
1444 : case 4: /* Bits 32-39 */
1445 : #ifdef CONFIG_INTERWORKING
1446 10475 : if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1447 10399 : *pos |= 0x01; /* Bit 32 - QoS Map */
1448 : #endif /* CONFIG_INTERWORKING */
1449 10475 : break;
1450 : case 5: /* Bits 40-47 */
1451 : #ifdef CONFIG_HS20
1452 10475 : if (wpa_s->conf->hs20)
1453 4067 : *pos |= 0x40; /* Bit 46 - WNM-Notification */
1454 : #endif /* CONFIG_HS20 */
1455 : #ifdef CONFIG_MBO
1456 10475 : *pos |= 0x40; /* Bit 46 - WNM-Notification */
1457 : #endif /* CONFIG_MBO */
1458 10475 : break;
1459 : case 6: /* Bits 48-55 */
1460 10399 : break;
1461 : case 7: /* Bits 56-63 */
1462 10399 : break;
1463 : case 8: /* Bits 64-71 */
1464 1 : if (wpa_s->conf->ftm_responder)
1465 1 : *pos |= 0x40; /* Bit 70 - FTM responder */
1466 1 : if (wpa_s->conf->ftm_initiator)
1467 1 : *pos |= 0x80; /* Bit 71 - FTM initiator */
1468 1 : break;
1469 : }
1470 83649 : }
1471 :
1472 :
1473 10475 : int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
1474 : {
1475 10475 : u8 *pos = buf;
1476 10475 : u8 len = 6, i;
1477 :
1478 20950 : if (len < 9 &&
1479 20949 : (wpa_s->conf->ftm_initiator || wpa_s->conf->ftm_responder))
1480 1 : len = 9;
1481 10475 : if (len < wpa_s->extended_capa_len)
1482 10398 : len = wpa_s->extended_capa_len;
1483 10475 : if (buflen < (size_t) len + 2) {
1484 0 : wpa_printf(MSG_INFO,
1485 : "Not enough room for building extended capabilities element");
1486 0 : return -1;
1487 : }
1488 :
1489 10475 : *pos++ = WLAN_EID_EXT_CAPAB;
1490 10475 : *pos++ = len;
1491 94124 : for (i = 0; i < len; i++, pos++) {
1492 83649 : wpas_ext_capab_byte(wpa_s, pos, i);
1493 :
1494 83649 : if (i < wpa_s->extended_capa_len) {
1495 83192 : *pos &= ~wpa_s->extended_capa_mask[i];
1496 83192 : *pos |= wpa_s->extended_capa[i];
1497 : }
1498 : }
1499 :
1500 20950 : while (len > 0 && buf[1 + len] == 0) {
1501 0 : len--;
1502 0 : buf[1] = len;
1503 : }
1504 10475 : if (len == 0)
1505 0 : return 0;
1506 :
1507 10475 : return 2 + len;
1508 : }
1509 :
1510 :
1511 4848 : static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1512 : struct wpa_bss *test_bss)
1513 : {
1514 : struct wpa_bss *bss;
1515 :
1516 5632 : dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1517 5632 : if (bss == test_bss)
1518 4848 : return 1;
1519 : }
1520 :
1521 0 : return 0;
1522 : }
1523 :
1524 :
1525 4882 : static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1526 : struct wpa_ssid *test_ssid)
1527 : {
1528 : struct wpa_ssid *ssid;
1529 :
1530 5301 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1531 5301 : if (ssid == test_ssid)
1532 4882 : return 1;
1533 : }
1534 :
1535 0 : return 0;
1536 : }
1537 :
1538 :
1539 4882 : int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1540 : struct wpa_ssid *test_ssid)
1541 : {
1542 4882 : if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1543 0 : return 0;
1544 :
1545 4882 : return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1546 : }
1547 :
1548 :
1549 4889 : void wpas_connect_work_free(struct wpa_connect_work *cwork)
1550 : {
1551 4889 : if (cwork == NULL)
1552 4889 : return;
1553 4889 : os_free(cwork);
1554 : }
1555 :
1556 :
1557 13137 : void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1558 : {
1559 : struct wpa_connect_work *cwork;
1560 13137 : struct wpa_radio_work *work = wpa_s->connect_work;
1561 :
1562 13137 : if (!work)
1563 21391 : return;
1564 :
1565 4883 : wpa_s->connect_work = NULL;
1566 4883 : cwork = work->ctx;
1567 4883 : work->ctx = NULL;
1568 4883 : wpas_connect_work_free(cwork);
1569 4883 : radio_work_done(work);
1570 : }
1571 :
1572 :
1573 15 : int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
1574 : {
1575 : struct os_reltime now;
1576 : u8 addr[ETH_ALEN];
1577 :
1578 15 : os_get_reltime(&now);
1579 23 : if (wpa_s->last_mac_addr_style == style &&
1580 16 : wpa_s->last_mac_addr_change.sec != 0 &&
1581 8 : !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
1582 8 : wpa_s->conf->rand_addr_lifetime)) {
1583 4 : wpa_msg(wpa_s, MSG_DEBUG,
1584 : "Previously selected random MAC address has not yet expired");
1585 4 : return 0;
1586 : }
1587 :
1588 11 : switch (style) {
1589 : case 1:
1590 6 : if (random_mac_addr(addr) < 0)
1591 0 : return -1;
1592 6 : break;
1593 : case 2:
1594 4 : os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
1595 4 : if (random_mac_addr_keep_oui(addr) < 0)
1596 0 : return -1;
1597 4 : break;
1598 : default:
1599 1 : return -1;
1600 : }
1601 :
1602 10 : if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
1603 1 : wpa_msg(wpa_s, MSG_INFO,
1604 : "Failed to set random MAC address");
1605 1 : return -1;
1606 : }
1607 :
1608 9 : os_get_reltime(&wpa_s->last_mac_addr_change);
1609 9 : wpa_s->mac_addr_changed = 1;
1610 9 : wpa_s->last_mac_addr_style = style;
1611 :
1612 9 : if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1613 0 : wpa_msg(wpa_s, MSG_INFO,
1614 : "Could not update MAC address information");
1615 0 : return -1;
1616 : }
1617 :
1618 54 : wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
1619 54 : MAC2STR(addr));
1620 :
1621 9 : return 0;
1622 : }
1623 :
1624 :
1625 4993 : int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
1626 : {
1627 9788 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
1628 4795 : !wpa_s->conf->preassoc_mac_addr)
1629 4983 : return 0;
1630 :
1631 10 : return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
1632 : }
1633 :
1634 :
1635 : static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1636 :
1637 : /**
1638 : * wpa_supplicant_associate - Request association
1639 : * @wpa_s: Pointer to wpa_supplicant data
1640 : * @bss: Scan results for the selected BSS, or %NULL if not available
1641 : * @ssid: Configuration data for the selected network
1642 : *
1643 : * This function is used to request %wpa_supplicant to associate with a BSS.
1644 : */
1645 5528 : void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1646 : struct wpa_bss *bss, struct wpa_ssid *ssid)
1647 : {
1648 : struct wpa_connect_work *cwork;
1649 : int rand_style;
1650 :
1651 5528 : wpa_s->own_disconnect_req = 0;
1652 :
1653 : /*
1654 : * If we are starting a new connection, any previously pending EAPOL
1655 : * RX cannot be valid anymore.
1656 : */
1657 5528 : wpabuf_free(wpa_s->pending_eapol_rx);
1658 5528 : wpa_s->pending_eapol_rx = NULL;
1659 :
1660 5528 : if (ssid->mac_addr == -1)
1661 5522 : rand_style = wpa_s->conf->mac_addr;
1662 : else
1663 6 : rand_style = ssid->mac_addr;
1664 :
1665 5528 : wmm_ac_clear_saved_tspecs(wpa_s);
1666 5528 : wpa_s->reassoc_same_bss = 0;
1667 5528 : wpa_s->reassoc_same_ess = 0;
1668 :
1669 5528 : if (wpa_s->last_ssid == ssid) {
1670 1302 : wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
1671 1302 : wpa_s->reassoc_same_ess = 1;
1672 1302 : if (wpa_s->current_bss && wpa_s->current_bss == bss) {
1673 91 : wmm_ac_save_tspecs(wpa_s);
1674 91 : wpa_s->reassoc_same_bss = 1;
1675 : }
1676 4226 : } else if (rand_style > 0) {
1677 5 : if (wpas_update_random_addr(wpa_s, rand_style) < 0)
1678 0 : return;
1679 5 : wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
1680 4221 : } else if (wpa_s->mac_addr_changed) {
1681 2 : if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1682 0 : wpa_msg(wpa_s, MSG_INFO,
1683 : "Could not restore permanent MAC address");
1684 0 : return;
1685 : }
1686 2 : wpa_s->mac_addr_changed = 0;
1687 2 : if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1688 0 : wpa_msg(wpa_s, MSG_INFO,
1689 : "Could not update MAC address information");
1690 0 : return;
1691 : }
1692 2 : wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1693 : }
1694 5528 : wpa_s->last_ssid = ssid;
1695 :
1696 : #ifdef CONFIG_IBSS_RSN
1697 5528 : ibss_rsn_deinit(wpa_s->ibss_rsn);
1698 5528 : wpa_s->ibss_rsn = NULL;
1699 : #endif /* CONFIG_IBSS_RSN */
1700 :
1701 10756 : if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1702 5228 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1703 : #ifdef CONFIG_AP
1704 445 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1705 0 : wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1706 : "mode");
1707 0 : return;
1708 : }
1709 445 : if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1710 7 : wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1711 7 : if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1712 0 : wpas_p2p_ap_setup_failed(wpa_s);
1713 7 : return;
1714 : }
1715 438 : wpa_s->current_bss = bss;
1716 : #else /* CONFIG_AP */
1717 : wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1718 : "the build");
1719 : #endif /* CONFIG_AP */
1720 438 : return;
1721 : }
1722 :
1723 5083 : if (ssid->mode == WPAS_MODE_MESH) {
1724 : #ifdef CONFIG_MESH
1725 191 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1726 0 : wpa_msg(wpa_s, MSG_INFO,
1727 : "Driver does not support mesh mode");
1728 0 : return;
1729 : }
1730 191 : if (bss)
1731 0 : ssid->frequency = bss->freq;
1732 191 : if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1733 24 : wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1734 24 : return;
1735 : }
1736 167 : wpa_s->current_bss = bss;
1737 334 : wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
1738 167 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1739 : ssid->id);
1740 : #else /* CONFIG_MESH */
1741 : wpa_msg(wpa_s, MSG_ERROR,
1742 : "mesh mode support not included in the build");
1743 : #endif /* CONFIG_MESH */
1744 167 : return;
1745 : }
1746 :
1747 : #ifdef CONFIG_TDLS
1748 4892 : if (bss)
1749 4856 : wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1750 : bss->ie_len);
1751 : #endif /* CONFIG_TDLS */
1752 :
1753 9490 : if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1754 4598 : ssid->mode == IEEE80211_MODE_INFRA) {
1755 4571 : sme_authenticate(wpa_s, bss, ssid);
1756 4571 : return;
1757 : }
1758 :
1759 321 : if (wpa_s->connect_work) {
1760 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1761 0 : return;
1762 : }
1763 :
1764 321 : if (radio_work_pending(wpa_s, "connect")) {
1765 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1766 0 : return;
1767 : }
1768 :
1769 321 : wpas_abort_ongoing_scan(wpa_s);
1770 :
1771 321 : cwork = os_zalloc(sizeof(*cwork));
1772 321 : if (cwork == NULL)
1773 0 : return;
1774 :
1775 321 : cwork->bss = bss;
1776 321 : cwork->ssid = ssid;
1777 :
1778 321 : if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1779 : wpas_start_assoc_cb, cwork) < 0) {
1780 0 : os_free(cwork);
1781 : }
1782 : }
1783 :
1784 :
1785 10 : static int bss_is_ibss(struct wpa_bss *bss)
1786 : {
1787 10 : return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1788 : IEEE80211_CAP_IBSS;
1789 : }
1790 :
1791 :
1792 10 : static int drv_supports_vht(struct wpa_supplicant *wpa_s,
1793 : const struct wpa_ssid *ssid)
1794 : {
1795 : enum hostapd_hw_mode hw_mode;
1796 10 : struct hostapd_hw_modes *mode = NULL;
1797 : u8 channel;
1798 : int i;
1799 :
1800 : #ifdef CONFIG_HT_OVERRIDES
1801 10 : if (ssid->disable_ht)
1802 0 : return 0;
1803 : #endif /* CONFIG_HT_OVERRIDES */
1804 :
1805 10 : hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
1806 10 : if (hw_mode == NUM_HOSTAPD_MODES)
1807 0 : return 0;
1808 20 : for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1809 20 : if (wpa_s->hw.modes[i].mode == hw_mode) {
1810 10 : mode = &wpa_s->hw.modes[i];
1811 10 : break;
1812 : }
1813 : }
1814 :
1815 10 : if (!mode)
1816 0 : return 0;
1817 :
1818 10 : return mode->vht_capab != 0;
1819 : }
1820 :
1821 :
1822 217 : void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1823 : const struct wpa_ssid *ssid,
1824 : struct hostapd_freq_params *freq)
1825 : {
1826 : enum hostapd_hw_mode hw_mode;
1827 217 : struct hostapd_hw_modes *mode = NULL;
1828 217 : int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1829 : 184, 192 };
1830 217 : int vht80[] = { 36, 52, 100, 116, 132, 149 };
1831 217 : struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1832 : u8 channel;
1833 217 : int i, chan_idx, ht40 = -1, res, obss_scan = 1;
1834 : unsigned int j, k;
1835 : struct hostapd_freq_params vht_freq;
1836 : int chwidth, seg0, seg1;
1837 217 : u32 vht_caps = 0;
1838 :
1839 217 : freq->freq = ssid->frequency;
1840 :
1841 217 : for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1842 10 : struct wpa_bss *bss = wpa_s->last_scan_res[j];
1843 :
1844 10 : if (ssid->mode != WPAS_MODE_IBSS)
1845 0 : break;
1846 :
1847 : /* Don't adjust control freq in case of fixed_freq */
1848 10 : if (ssid->fixed_freq)
1849 0 : break;
1850 :
1851 10 : if (!bss_is_ibss(bss))
1852 0 : continue;
1853 :
1854 20 : if (ssid->ssid_len == bss->ssid_len &&
1855 10 : os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1856 10 : wpa_printf(MSG_DEBUG,
1857 : "IBSS already found in scan results, adjust control freq: %d",
1858 : bss->freq);
1859 10 : freq->freq = bss->freq;
1860 10 : obss_scan = 0;
1861 10 : break;
1862 : }
1863 : }
1864 :
1865 : /* For IBSS check HT_IBSS flag */
1866 244 : if (ssid->mode == WPAS_MODE_IBSS &&
1867 27 : !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1868 207 : return;
1869 :
1870 432 : if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1871 430 : wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1872 215 : wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1873 9 : wpa_printf(MSG_DEBUG,
1874 : "IBSS: WEP/TKIP detected, do not try to enable HT");
1875 9 : return;
1876 : }
1877 :
1878 208 : hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
1879 221 : for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1880 220 : if (wpa_s->hw.modes[i].mode == hw_mode) {
1881 207 : mode = &wpa_s->hw.modes[i];
1882 207 : break;
1883 : }
1884 : }
1885 :
1886 208 : if (!mode)
1887 1 : return;
1888 :
1889 : #ifdef CONFIG_HT_OVERRIDES
1890 207 : if (ssid->disable_ht) {
1891 0 : freq->ht_enabled = 0;
1892 0 : return;
1893 : }
1894 : #endif /* CONFIG_HT_OVERRIDES */
1895 :
1896 207 : freq->ht_enabled = ht_supported(mode);
1897 207 : if (!freq->ht_enabled)
1898 0 : return;
1899 :
1900 : /* Setup higher BW only for 5 GHz */
1901 207 : if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1902 197 : return;
1903 :
1904 28 : for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1905 28 : pri_chan = &mode->channels[chan_idx];
1906 28 : if (pri_chan->chan == channel)
1907 10 : break;
1908 18 : pri_chan = NULL;
1909 : }
1910 10 : if (!pri_chan)
1911 0 : return;
1912 :
1913 : /* Check primary channel flags */
1914 10 : if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1915 0 : return;
1916 :
1917 : #ifdef CONFIG_HT_OVERRIDES
1918 10 : if (ssid->disable_ht40)
1919 0 : return;
1920 : #endif /* CONFIG_HT_OVERRIDES */
1921 :
1922 : /* Check/setup HT40+/HT40- */
1923 36 : for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1924 34 : if (ht40plus[j] == channel) {
1925 8 : ht40 = 1;
1926 8 : break;
1927 : }
1928 : }
1929 :
1930 : /* Find secondary channel */
1931 34 : for (i = 0; i < mode->num_channels; i++) {
1932 34 : sec_chan = &mode->channels[i];
1933 34 : if (sec_chan->chan == channel + ht40 * 4)
1934 10 : break;
1935 24 : sec_chan = NULL;
1936 : }
1937 10 : if (!sec_chan)
1938 0 : return;
1939 :
1940 : /* Check secondary channel flags */
1941 10 : if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1942 0 : return;
1943 :
1944 10 : freq->channel = pri_chan->chan;
1945 :
1946 10 : if (ht40 == -1) {
1947 2 : if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1948 0 : return;
1949 : } else {
1950 8 : if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1951 0 : return;
1952 : }
1953 10 : freq->sec_channel_offset = ht40;
1954 :
1955 10 : if (obss_scan) {
1956 : struct wpa_scan_results *scan_res;
1957 :
1958 8 : scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1959 8 : if (scan_res == NULL) {
1960 : /* Back to HT20 */
1961 0 : freq->sec_channel_offset = 0;
1962 0 : return;
1963 : }
1964 :
1965 8 : res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
1966 8 : sec_chan->chan);
1967 8 : switch (res) {
1968 : case 0:
1969 : /* Back to HT20 */
1970 0 : freq->sec_channel_offset = 0;
1971 0 : break;
1972 : case 1:
1973 : /* Configuration allowed */
1974 8 : break;
1975 : case 2:
1976 : /* Switch pri/sec channels */
1977 0 : freq->freq = hw_get_freq(mode, sec_chan->chan);
1978 0 : freq->sec_channel_offset = -freq->sec_channel_offset;
1979 0 : freq->channel = sec_chan->chan;
1980 0 : break;
1981 : default:
1982 0 : freq->sec_channel_offset = 0;
1983 0 : break;
1984 : }
1985 :
1986 8 : wpa_scan_results_free(scan_res);
1987 : }
1988 :
1989 10 : wpa_printf(MSG_DEBUG,
1990 : "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
1991 : freq->channel, freq->sec_channel_offset);
1992 :
1993 10 : if (!drv_supports_vht(wpa_s, ssid))
1994 0 : return;
1995 :
1996 : /* For IBSS check VHT_IBSS flag */
1997 14 : if (ssid->mode == WPAS_MODE_IBSS &&
1998 4 : !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
1999 0 : return;
2000 :
2001 10 : vht_freq = *freq;
2002 :
2003 10 : vht_freq.vht_enabled = vht_supported(mode);
2004 10 : if (!vht_freq.vht_enabled)
2005 0 : return;
2006 :
2007 : /* setup center_freq1, bandwidth */
2008 14 : for (j = 0; j < ARRAY_SIZE(vht80); j++) {
2009 28 : if (freq->channel >= vht80[j] &&
2010 14 : freq->channel < vht80[j] + 16)
2011 10 : break;
2012 : }
2013 :
2014 10 : if (j == ARRAY_SIZE(vht80))
2015 0 : return;
2016 :
2017 50 : for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
2018 : struct hostapd_channel_data *chan;
2019 :
2020 40 : chan = hw_get_channel_chan(mode, i, NULL);
2021 40 : if (!chan)
2022 0 : return;
2023 :
2024 : /* Back to HT configuration if channel not usable */
2025 40 : if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2026 0 : return;
2027 : }
2028 :
2029 10 : chwidth = VHT_CHANWIDTH_80MHZ;
2030 10 : seg0 = vht80[j] + 6;
2031 10 : seg1 = 0;
2032 :
2033 10 : if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) {
2034 : /* setup center_freq2, bandwidth */
2035 24 : for (k = 0; k < ARRAY_SIZE(vht80); k++) {
2036 : /* Only accept 80 MHz segments separated by a gap */
2037 24 : if (j == k || abs(vht80[j] - vht80[k]) == 16)
2038 8 : continue;
2039 80 : for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
2040 : struct hostapd_channel_data *chan;
2041 :
2042 64 : chan = hw_get_channel_chan(mode, i, NULL);
2043 64 : if (!chan)
2044 4 : continue;
2045 :
2046 60 : if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2047 : HOSTAPD_CHAN_NO_IR |
2048 : HOSTAPD_CHAN_RADAR))
2049 44 : continue;
2050 :
2051 : /* Found a suitable second segment for 80+80 */
2052 16 : chwidth = VHT_CHANWIDTH_80P80MHZ;
2053 16 : vht_caps |=
2054 : VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2055 16 : seg1 = vht80[k] + 6;
2056 : }
2057 :
2058 16 : if (chwidth == VHT_CHANWIDTH_80P80MHZ)
2059 4 : break;
2060 : }
2061 6 : } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) {
2062 2 : if (freq->freq == 5180) {
2063 0 : chwidth = VHT_CHANWIDTH_160MHZ;
2064 0 : vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2065 0 : seg0 = 50;
2066 2 : } else if (freq->freq == 5520) {
2067 2 : chwidth = VHT_CHANWIDTH_160MHZ;
2068 2 : vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2069 2 : seg0 = 114;
2070 : }
2071 : }
2072 :
2073 10 : if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
2074 : freq->channel, freq->ht_enabled,
2075 : vht_freq.vht_enabled,
2076 : freq->sec_channel_offset,
2077 : chwidth, seg0, seg1, vht_caps) != 0)
2078 0 : return;
2079 :
2080 10 : *freq = vht_freq;
2081 :
2082 10 : wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2083 : freq->center_freq1, freq->center_freq2, freq->bandwidth);
2084 : }
2085 :
2086 :
2087 321 : static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
2088 : {
2089 321 : struct wpa_connect_work *cwork = work->ctx;
2090 321 : struct wpa_bss *bss = cwork->bss;
2091 321 : struct wpa_ssid *ssid = cwork->ssid;
2092 321 : struct wpa_supplicant *wpa_s = work->wpa_s;
2093 : u8 wpa_ie[200];
2094 : size_t wpa_ie_len;
2095 : int use_crypt, ret, i, bssid_changed;
2096 321 : int algs = WPA_AUTH_ALG_OPEN;
2097 : unsigned int cipher_pairwise, cipher_group;
2098 : struct wpa_driver_associate_params params;
2099 321 : int wep_keys_set = 0;
2100 321 : int assoc_failed = 0;
2101 : struct wpa_ssid *old_ssid;
2102 : u8 prev_bssid[ETH_ALEN];
2103 : #ifdef CONFIG_HT_OVERRIDES
2104 : struct ieee80211_ht_capabilities htcaps;
2105 : struct ieee80211_ht_capabilities htcaps_mask;
2106 : #endif /* CONFIG_HT_OVERRIDES */
2107 : #ifdef CONFIG_VHT_OVERRIDES
2108 : struct ieee80211_vht_capabilities vhtcaps;
2109 : struct ieee80211_vht_capabilities vhtcaps_mask;
2110 : #endif /* CONFIG_VHT_OVERRIDES */
2111 : #ifdef CONFIG_MBO
2112 321 : const u8 *mbo = NULL;
2113 : #endif /* CONFIG_MBO */
2114 :
2115 321 : if (deinit) {
2116 0 : if (work->started) {
2117 0 : wpa_s->connect_work = NULL;
2118 :
2119 : /* cancel possible auth. timeout */
2120 0 : eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
2121 : NULL);
2122 : }
2123 0 : wpas_connect_work_free(cwork);
2124 0 : return;
2125 : }
2126 :
2127 321 : wpa_s->connect_work = work;
2128 :
2129 641 : if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
2130 320 : wpas_network_disabled(wpa_s, ssid)) {
2131 2 : wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
2132 2 : wpas_connect_work_done(wpa_s);
2133 2 : return;
2134 : }
2135 :
2136 319 : os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
2137 319 : os_memset(¶ms, 0, sizeof(params));
2138 319 : wpa_s->reassociate = 0;
2139 319 : wpa_s->eap_expected_failure = 0;
2140 604 : if (bss &&
2141 571 : (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
2142 : #ifdef CONFIG_IEEE80211R
2143 280 : const u8 *ie, *md = NULL;
2144 : #endif /* CONFIG_IEEE80211R */
2145 2240 : wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2146 1680 : " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
2147 280 : wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
2148 280 : bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2149 280 : os_memset(wpa_s->bssid, 0, ETH_ALEN);
2150 280 : os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2151 280 : if (bssid_changed)
2152 7 : wpas_notify_bssid_changed(wpa_s);
2153 : #ifdef CONFIG_IEEE80211R
2154 280 : ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
2155 280 : if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
2156 0 : md = ie + 2;
2157 280 : wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
2158 280 : if (md) {
2159 : /* Prepare for the next transition */
2160 0 : wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
2161 : }
2162 : #endif /* CONFIG_IEEE80211R */
2163 : #ifdef CONFIG_WPS
2164 40 : } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
2165 2 : wpa_s->conf->ap_scan == 2 &&
2166 1 : (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
2167 : /* Use ap_scan==1 style network selection to find the network
2168 : */
2169 1 : wpas_connect_work_done(wpa_s);
2170 1 : wpa_s->scan_req = MANUAL_SCAN_REQ;
2171 1 : wpa_s->reassociate = 1;
2172 1 : wpa_supplicant_req_scan(wpa_s, 0, 0);
2173 1 : return;
2174 : #endif /* CONFIG_WPS */
2175 : } else {
2176 76 : wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
2177 38 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
2178 38 : if (bss)
2179 5 : os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2180 : else
2181 33 : os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2182 : }
2183 318 : if (!wpa_s->pno)
2184 318 : wpa_supplicant_cancel_sched_scan(wpa_s);
2185 :
2186 318 : wpa_supplicant_cancel_scan(wpa_s);
2187 :
2188 : /* Starting new association, so clear the possibly used WPA IE from the
2189 : * previous association. */
2190 318 : wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2191 :
2192 : #ifdef IEEE8021X_EAPOL
2193 318 : if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2194 0 : if (ssid->leap) {
2195 0 : if (ssid->non_leap == 0)
2196 0 : algs = WPA_AUTH_ALG_LEAP;
2197 : else
2198 0 : algs |= WPA_AUTH_ALG_LEAP;
2199 : }
2200 : }
2201 : #endif /* IEEE8021X_EAPOL */
2202 318 : wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
2203 318 : if (ssid->auth_alg) {
2204 7 : algs = ssid->auth_alg;
2205 7 : wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
2206 : "0x%x", algs);
2207 : }
2208 :
2209 602 : if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2210 306 : wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
2211 42 : wpa_key_mgmt_wpa(ssid->key_mgmt)) {
2212 : int try_opportunistic;
2213 40 : try_opportunistic = (ssid->proactive_key_caching < 0 ?
2214 17 : wpa_s->conf->okc :
2215 40 : ssid->proactive_key_caching) &&
2216 3 : (ssid->proto & WPA_PROTO_RSN);
2217 20 : if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
2218 : ssid, try_opportunistic) == 0)
2219 3 : eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
2220 20 : wpa_ie_len = sizeof(wpa_ie);
2221 20 : if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2222 : wpa_ie, &wpa_ie_len)) {
2223 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2224 : "key management and encryption suites");
2225 0 : wpas_connect_work_done(wpa_s);
2226 0 : return;
2227 : }
2228 298 : } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2229 0 : wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2230 : /*
2231 : * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2232 : * use non-WPA since the scan results did not indicate that the
2233 : * AP is using WPA or WPA2.
2234 : */
2235 0 : wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2236 0 : wpa_ie_len = 0;
2237 0 : wpa_s->wpa_proto = 0;
2238 298 : } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
2239 18 : wpa_ie_len = sizeof(wpa_ie);
2240 18 : if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2241 : wpa_ie, &wpa_ie_len)) {
2242 0 : wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2243 : "key management and encryption suites (no "
2244 : "scan results)");
2245 0 : wpas_connect_work_done(wpa_s);
2246 0 : return;
2247 : }
2248 : #ifdef CONFIG_WPS
2249 280 : } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
2250 : struct wpabuf *wps_ie;
2251 2 : wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
2252 2 : if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2253 2 : wpa_ie_len = wpabuf_len(wps_ie);
2254 2 : os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
2255 : } else
2256 0 : wpa_ie_len = 0;
2257 2 : wpabuf_free(wps_ie);
2258 2 : wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2259 2 : if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2260 2 : params.wps = WPS_MODE_PRIVACY;
2261 : else
2262 0 : params.wps = WPS_MODE_OPEN;
2263 2 : wpa_s->wpa_proto = 0;
2264 : #endif /* CONFIG_WPS */
2265 : } else {
2266 278 : wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2267 278 : wpa_ie_len = 0;
2268 278 : wpa_s->wpa_proto = 0;
2269 : }
2270 :
2271 : #ifdef CONFIG_P2P
2272 318 : if (wpa_s->global->p2p) {
2273 : u8 *pos;
2274 : size_t len;
2275 : int res;
2276 304 : pos = wpa_ie + wpa_ie_len;
2277 304 : len = sizeof(wpa_ie) - wpa_ie_len;
2278 304 : res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2279 : ssid->p2p_group);
2280 304 : if (res >= 0)
2281 271 : wpa_ie_len += res;
2282 : }
2283 :
2284 318 : wpa_s->cross_connect_disallowed = 0;
2285 318 : if (bss) {
2286 : struct wpabuf *p2p;
2287 285 : p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2288 285 : if (p2p) {
2289 4 : wpa_s->cross_connect_disallowed =
2290 4 : p2p_get_cross_connect_disallowed(p2p);
2291 4 : wpabuf_free(p2p);
2292 4 : wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2293 : "connection",
2294 : wpa_s->cross_connect_disallowed ?
2295 : "disallows" : "allows");
2296 : }
2297 : }
2298 :
2299 318 : os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
2300 : #endif /* CONFIG_P2P */
2301 :
2302 : #ifdef CONFIG_MBO
2303 318 : if (bss) {
2304 285 : mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
2305 285 : if (mbo) {
2306 : int len;
2307 :
2308 0 : len = wpas_mbo_supp_op_class_ie(wpa_s, bss->freq,
2309 : wpa_ie + wpa_ie_len,
2310 : sizeof(wpa_ie) -
2311 : wpa_ie_len);
2312 0 : if (len > 0)
2313 0 : wpa_ie_len += len;
2314 : }
2315 : }
2316 : #endif /* CONFIG_MBO */
2317 :
2318 : /*
2319 : * Workaround: Add Extended Capabilities element only if the AP
2320 : * included this element in Beacon/Probe Response frames. Some older
2321 : * APs seem to have interoperability issues if this element is
2322 : * included, so while the standard may require us to include the
2323 : * element in all cases, it is justifiable to skip it to avoid
2324 : * interoperability issues.
2325 : */
2326 318 : if (ssid->p2p_group)
2327 2 : wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
2328 : else
2329 316 : wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
2330 :
2331 318 : if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
2332 : u8 ext_capab[18];
2333 : int ext_capab_len;
2334 318 : ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2335 : sizeof(ext_capab));
2336 318 : if (ext_capab_len > 0) {
2337 318 : u8 *pos = wpa_ie;
2338 318 : if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2339 31 : pos += 2 + pos[1];
2340 318 : os_memmove(pos + ext_capab_len, pos,
2341 : wpa_ie_len - (pos - wpa_ie));
2342 318 : wpa_ie_len += ext_capab_len;
2343 318 : os_memcpy(pos, ext_capab, ext_capab_len);
2344 : }
2345 : }
2346 :
2347 : #ifdef CONFIG_HS20
2348 318 : if (is_hs20_network(wpa_s, ssid, bss)) {
2349 : struct wpabuf *hs20;
2350 :
2351 1 : hs20 = wpabuf_alloc(20);
2352 1 : if (hs20) {
2353 1 : int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
2354 : size_t len;
2355 :
2356 1 : wpas_hs20_add_indication(hs20, pps_mo_id);
2357 1 : len = sizeof(wpa_ie) - wpa_ie_len;
2358 1 : if (wpabuf_len(hs20) <= len) {
2359 1 : os_memcpy(wpa_ie + wpa_ie_len,
2360 : wpabuf_head(hs20), wpabuf_len(hs20));
2361 1 : wpa_ie_len += wpabuf_len(hs20);
2362 : }
2363 1 : wpabuf_free(hs20);
2364 :
2365 1 : hs20_configure_frame_filters(wpa_s);
2366 : }
2367 : }
2368 : #endif /* CONFIG_HS20 */
2369 :
2370 318 : if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2371 0 : struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2372 : size_t len;
2373 :
2374 0 : len = sizeof(wpa_ie) - wpa_ie_len;
2375 0 : if (wpabuf_len(buf) <= len) {
2376 0 : os_memcpy(wpa_ie + wpa_ie_len,
2377 : wpabuf_head(buf), wpabuf_len(buf));
2378 0 : wpa_ie_len += wpabuf_len(buf);
2379 : }
2380 : }
2381 :
2382 : #ifdef CONFIG_FST
2383 318 : if (wpa_s->fst_ies) {
2384 243 : int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2385 :
2386 243 : if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
2387 243 : os_memcpy(wpa_ie + wpa_ie_len,
2388 : wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2389 243 : wpa_ie_len += fst_ies_len;
2390 : }
2391 : }
2392 : #endif /* CONFIG_FST */
2393 :
2394 : #ifdef CONFIG_MBO
2395 318 : if (mbo) {
2396 : int len;
2397 :
2398 0 : len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
2399 : sizeof(wpa_ie) - wpa_ie_len);
2400 0 : if (len >= 0)
2401 0 : wpa_ie_len += len;
2402 : }
2403 : #endif /* CONFIG_MBO */
2404 :
2405 318 : wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2406 318 : use_crypt = 1;
2407 318 : cipher_pairwise = wpa_s->pairwise_cipher;
2408 318 : cipher_group = wpa_s->group_cipher;
2409 358 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2410 40 : wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2411 278 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2412 278 : use_crypt = 0;
2413 278 : if (wpa_set_wep_keys(wpa_s, ssid)) {
2414 8 : use_crypt = 1;
2415 8 : wep_keys_set = 1;
2416 : }
2417 : }
2418 318 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2419 2 : use_crypt = 0;
2420 :
2421 : #ifdef IEEE8021X_EAPOL
2422 318 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2423 0 : if ((ssid->eapol_flags &
2424 : (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2425 0 : EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2426 : !wep_keys_set) {
2427 0 : use_crypt = 0;
2428 : } else {
2429 : /* Assume that dynamic WEP-104 keys will be used and
2430 : * set cipher suites in order for drivers to expect
2431 : * encryption. */
2432 0 : cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
2433 : }
2434 : }
2435 : #endif /* IEEE8021X_EAPOL */
2436 :
2437 318 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2438 : /* Set the key before (and later after) association */
2439 5 : wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2440 : }
2441 :
2442 318 : wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
2443 318 : if (bss) {
2444 285 : params.ssid = bss->ssid;
2445 285 : params.ssid_len = bss->ssid_len;
2446 285 : if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
2447 1967 : wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2448 : MACSTR " freq=%u MHz based on scan results "
2449 : "(bssid_set=%d)",
2450 1686 : MAC2STR(bss->bssid), bss->freq,
2451 : ssid->bssid_set);
2452 281 : params.bssid = bss->bssid;
2453 281 : params.freq.freq = bss->freq;
2454 : }
2455 285 : params.bssid_hint = bss->bssid;
2456 285 : params.freq_hint = bss->freq;
2457 285 : params.pbss = bss_is_pbss(bss);
2458 : } else {
2459 33 : params.ssid = ssid->ssid;
2460 33 : params.ssid_len = ssid->ssid_len;
2461 33 : params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
2462 : }
2463 :
2464 321 : if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2465 3 : wpa_s->conf->ap_scan == 2) {
2466 3 : params.bssid = ssid->bssid;
2467 3 : params.fixed_bssid = 1;
2468 : }
2469 :
2470 : /* Initial frequency for IBSS/mesh */
2471 345 : if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
2472 54 : ssid->frequency > 0 && params.freq.freq == 0)
2473 27 : ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq);
2474 :
2475 318 : if (ssid->mode == WPAS_MODE_IBSS) {
2476 27 : params.fixed_freq = ssid->fixed_freq;
2477 27 : if (ssid->beacon_int)
2478 7 : params.beacon_int = ssid->beacon_int;
2479 : else
2480 20 : params.beacon_int = wpa_s->conf->beacon_int;
2481 : }
2482 :
2483 318 : params.wpa_ie = wpa_ie;
2484 318 : params.wpa_ie_len = wpa_ie_len;
2485 318 : params.pairwise_suite = cipher_pairwise;
2486 318 : params.group_suite = cipher_group;
2487 318 : params.key_mgmt_suite = wpa_s->key_mgmt;
2488 318 : params.wpa_proto = wpa_s->wpa_proto;
2489 318 : params.auth_alg = algs;
2490 318 : params.mode = ssid->mode;
2491 318 : params.bg_scan_period = ssid->bg_scan_period;
2492 1590 : for (i = 0; i < NUM_WEP_KEYS; i++) {
2493 1272 : if (ssid->wep_key_len[i])
2494 8 : params.wep_key[i] = ssid->wep_key[i];
2495 1272 : params.wep_key_len[i] = ssid->wep_key_len[i];
2496 : }
2497 318 : params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2498 :
2499 318 : if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
2500 0 : (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2501 0 : params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
2502 0 : params.passphrase = ssid->passphrase;
2503 0 : if (ssid->psk_set)
2504 0 : params.psk = ssid->psk;
2505 : }
2506 :
2507 318 : if (wpa_s->conf->key_mgmt_offload) {
2508 628 : if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
2509 620 : params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
2510 620 : params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2511 310 : params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
2512 8 : params.req_key_mgmt_offload =
2513 8 : ssid->proactive_key_caching < 0 ?
2514 8 : wpa_s->conf->okc : ssid->proactive_key_caching;
2515 : else
2516 310 : params.req_key_mgmt_offload = 1;
2517 :
2518 613 : if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2519 589 : params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2520 318 : params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2521 24 : ssid->psk_set)
2522 24 : params.psk = ssid->psk;
2523 : }
2524 :
2525 318 : params.drop_unencrypted = use_crypt;
2526 :
2527 : #ifdef CONFIG_IEEE80211W
2528 318 : params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
2529 318 : if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
2530 1 : const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
2531 : struct wpa_ie_data ie;
2532 2 : if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2533 1 : ie.capabilities &
2534 : (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
2535 1 : wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2536 : "MFP: require MFP");
2537 1 : params.mgmt_frame_protection =
2538 : MGMT_FRAME_PROTECTION_REQUIRED;
2539 : }
2540 : }
2541 : #endif /* CONFIG_IEEE80211W */
2542 :
2543 318 : params.p2p = ssid->p2p_group;
2544 :
2545 318 : if (wpa_s->p2pdev->set_sta_uapsd)
2546 0 : params.uapsd = wpa_s->p2pdev->sta_uapsd;
2547 : else
2548 318 : params.uapsd = -1;
2549 :
2550 : #ifdef CONFIG_HT_OVERRIDES
2551 318 : os_memset(&htcaps, 0, sizeof(htcaps));
2552 318 : os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2553 318 : params.htcaps = (u8 *) &htcaps;
2554 318 : params.htcaps_mask = (u8 *) &htcaps_mask;
2555 318 : wpa_supplicant_apply_ht_overrides(wpa_s, ssid, ¶ms);
2556 : #endif /* CONFIG_HT_OVERRIDES */
2557 : #ifdef CONFIG_VHT_OVERRIDES
2558 318 : os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2559 318 : os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2560 318 : params.vhtcaps = &vhtcaps;
2561 318 : params.vhtcaps_mask = &vhtcaps_mask;
2562 318 : wpa_supplicant_apply_vht_overrides(wpa_s, ssid, ¶ms);
2563 : #endif /* CONFIG_VHT_OVERRIDES */
2564 :
2565 : #ifdef CONFIG_P2P
2566 : /*
2567 : * If multi-channel concurrency is not supported, check for any
2568 : * frequency conflict. In case of any frequency conflict, remove the
2569 : * least prioritized connection.
2570 : */
2571 318 : if (wpa_s->num_multichan_concurrent < 2) {
2572 : int freq, num;
2573 318 : num = get_shared_radio_freqs(wpa_s, &freq, 1);
2574 318 : if (num > 0 && freq > 0 && freq != params.freq.freq) {
2575 1 : wpa_printf(MSG_DEBUG,
2576 : "Assoc conflicting freq found (%d != %d)",
2577 : freq, params.freq.freq);
2578 1 : if (wpas_p2p_handle_frequency_conflicts(
2579 : wpa_s, params.freq.freq, ssid) < 0) {
2580 0 : wpas_connect_work_done(wpa_s);
2581 0 : return;
2582 : }
2583 : }
2584 : }
2585 : #endif /* CONFIG_P2P */
2586 :
2587 328 : if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
2588 10 : wpa_s->current_ssid)
2589 10 : params.prev_bssid = prev_bssid;
2590 :
2591 318 : ret = wpa_drv_associate(wpa_s, ¶ms);
2592 318 : if (ret < 0) {
2593 14 : wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2594 : "failed");
2595 14 : if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2596 : /*
2597 : * The driver is known to mean what is saying, so we
2598 : * can stop right here; the association will not
2599 : * succeed.
2600 : */
2601 0 : wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2602 0 : wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2603 0 : os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2604 0 : return;
2605 : }
2606 : /* try to continue anyway; new association will be tried again
2607 : * after timeout */
2608 14 : assoc_failed = 1;
2609 : }
2610 :
2611 318 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2612 : /* Set the key after the association just in case association
2613 : * cleared the previously configured key. */
2614 5 : wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2615 : /* No need to timeout authentication since there is no key
2616 : * management. */
2617 5 : wpa_supplicant_cancel_auth_timeout(wpa_s);
2618 5 : wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
2619 : #ifdef CONFIG_IBSS_RSN
2620 335 : } else if (ssid->mode == WPAS_MODE_IBSS &&
2621 33 : wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2622 11 : wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2623 : /*
2624 : * RSN IBSS authentication is per-STA and we can disable the
2625 : * per-BSSID authentication.
2626 : */
2627 11 : wpa_supplicant_cancel_auth_timeout(wpa_s);
2628 : #endif /* CONFIG_IBSS_RSN */
2629 : } else {
2630 : /* Timeout for IEEE 802.11 authentication and association */
2631 302 : int timeout = 60;
2632 :
2633 302 : if (assoc_failed) {
2634 : /* give IBSS a bit more time */
2635 14 : timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
2636 288 : } else if (wpa_s->conf->ap_scan == 1) {
2637 : /* give IBSS a bit more time */
2638 277 : timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
2639 : }
2640 302 : wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2641 : }
2642 :
2643 326 : if (wep_keys_set &&
2644 8 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
2645 : /* Set static WEP keys again */
2646 0 : wpa_set_wep_keys(wpa_s, ssid);
2647 : }
2648 :
2649 318 : if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2650 : /*
2651 : * Do not allow EAP session resumption between different
2652 : * network configurations.
2653 : */
2654 0 : eapol_sm_invalidate_cached_session(wpa_s->eapol);
2655 : }
2656 318 : old_ssid = wpa_s->current_ssid;
2657 318 : wpa_s->current_ssid = ssid;
2658 :
2659 318 : if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
2660 312 : wpa_s->current_bss = bss;
2661 : #ifdef CONFIG_HS20
2662 312 : hs20_configure_frame_filters(wpa_s);
2663 : #endif /* CONFIG_HS20 */
2664 : }
2665 :
2666 318 : wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2667 318 : wpa_supplicant_initiate_eapol(wpa_s);
2668 318 : if (old_ssid != wpa_s->current_ssid)
2669 17 : wpas_notify_network_changed(wpa_s);
2670 : }
2671 :
2672 :
2673 5313 : static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2674 : const u8 *addr)
2675 : {
2676 : struct wpa_ssid *old_ssid;
2677 :
2678 5313 : wpas_connect_work_done(wpa_s);
2679 5313 : wpa_clear_keys(wpa_s, addr);
2680 5313 : old_ssid = wpa_s->current_ssid;
2681 5313 : wpa_supplicant_mark_disassoc(wpa_s);
2682 5313 : wpa_sm_set_config(wpa_s->wpa, NULL);
2683 5313 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2684 5313 : if (old_ssid != wpa_s->current_ssid)
2685 359 : wpas_notify_network_changed(wpa_s);
2686 5313 : eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2687 5313 : }
2688 :
2689 :
2690 : /**
2691 : * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2692 : * @wpa_s: Pointer to wpa_supplicant data
2693 : * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2694 : *
2695 : * This function is used to request %wpa_supplicant to deauthenticate from the
2696 : * current AP.
2697 : */
2698 5313 : void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2699 : int reason_code)
2700 : {
2701 5313 : u8 *addr = NULL;
2702 : union wpa_event_data event;
2703 5313 : int zero_addr = 0;
2704 :
2705 5313 : wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2706 : " pending_bssid=" MACSTR " reason=%d state=%s",
2707 : MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2708 : reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2709 :
2710 5408 : if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2711 183 : (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2712 88 : wpa_s->wpa_state == WPA_ASSOCIATING))
2713 9 : addr = wpa_s->pending_bssid;
2714 5304 : else if (!is_zero_ether_addr(wpa_s->bssid))
2715 4317 : addr = wpa_s->bssid;
2716 987 : else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2717 : /*
2718 : * When using driver-based BSS selection, we may not know the
2719 : * BSSID with which we are currently trying to associate. We
2720 : * need to notify the driver of this disconnection even in such
2721 : * a case, so use the all zeros address here.
2722 : */
2723 0 : addr = wpa_s->bssid;
2724 0 : zero_addr = 1;
2725 : }
2726 :
2727 : #ifdef CONFIG_TDLS
2728 5313 : wpa_tdls_teardown_peers(wpa_s->wpa);
2729 : #endif /* CONFIG_TDLS */
2730 :
2731 : #ifdef CONFIG_MESH
2732 5313 : if (wpa_s->ifmsh) {
2733 171 : wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2734 171 : wpa_s->ifname);
2735 171 : wpa_supplicant_leave_mesh(wpa_s);
2736 : }
2737 : #endif /* CONFIG_MESH */
2738 :
2739 5313 : if (addr) {
2740 4326 : wpa_drv_deauthenticate(wpa_s, addr, reason_code);
2741 4326 : os_memset(&event, 0, sizeof(event));
2742 4326 : event.deauth_info.reason_code = (u16) reason_code;
2743 4326 : event.deauth_info.locally_generated = 1;
2744 4326 : wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
2745 4326 : if (zero_addr)
2746 0 : addr = NULL;
2747 : }
2748 :
2749 5313 : wpa_supplicant_clear_connection(wpa_s, addr);
2750 5313 : }
2751 :
2752 12 : static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2753 : struct wpa_ssid *ssid)
2754 : {
2755 12 : if (!ssid || !ssid->disabled || ssid->disabled == 2)
2756 13 : return;
2757 :
2758 11 : ssid->disabled = 0;
2759 11 : wpas_clear_temp_disabled(wpa_s, ssid, 1);
2760 11 : wpas_notify_network_enabled_changed(wpa_s, ssid);
2761 :
2762 : /*
2763 : * Try to reassociate since there is no current configuration and a new
2764 : * network was made available.
2765 : */
2766 11 : if (!wpa_s->current_ssid && !wpa_s->disconnected)
2767 10 : wpa_s->reassociate = 1;
2768 : }
2769 :
2770 :
2771 : /**
2772 : * wpa_supplicant_add_network - Add a new network
2773 : * @wpa_s: wpa_supplicant structure for a network interface
2774 : * Returns: The new network configuration or %NULL if operation failed
2775 : *
2776 : * This function performs the following operations:
2777 : * 1. Adds a new network.
2778 : * 2. Send network addition notification.
2779 : * 3. Marks the network disabled.
2780 : * 4. Set network default parameters.
2781 : */
2782 4533 : struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
2783 : {
2784 : struct wpa_ssid *ssid;
2785 :
2786 4533 : ssid = wpa_config_add_network(wpa_s->conf);
2787 4533 : if (!ssid)
2788 2 : return NULL;
2789 4531 : wpas_notify_network_added(wpa_s, ssid);
2790 4531 : ssid->disabled = 1;
2791 4531 : wpa_config_set_network_defaults(ssid);
2792 :
2793 4531 : return ssid;
2794 : }
2795 :
2796 :
2797 : /**
2798 : * wpa_supplicant_remove_network - Remove a configured network based on id
2799 : * @wpa_s: wpa_supplicant structure for a network interface
2800 : * @id: Unique network id to search for
2801 : * Returns: 0 on success, or -1 if the network was not found, -2 if the network
2802 : * could not be removed
2803 : *
2804 : * This function performs the following operations:
2805 : * 1. Removes the network.
2806 : * 2. Send network removal notification.
2807 : * 3. Update internal state machines.
2808 : * 4. Stop any running sched scans.
2809 : */
2810 180 : int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
2811 : {
2812 : struct wpa_ssid *ssid;
2813 : int was_disabled;
2814 :
2815 180 : ssid = wpa_config_get_network(wpa_s->conf, id);
2816 180 : if (!ssid)
2817 5 : return -1;
2818 175 : wpas_notify_network_removed(wpa_s, ssid);
2819 :
2820 175 : if (wpa_s->last_ssid == ssid)
2821 133 : wpa_s->last_ssid = NULL;
2822 :
2823 175 : if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
2824 : #ifdef CONFIG_SME
2825 174 : wpa_s->sme.prev_bssid_set = 0;
2826 : #endif /* CONFIG_SME */
2827 : /*
2828 : * Invalidate the EAP session cache if the current or
2829 : * previously used network is removed.
2830 : */
2831 174 : eapol_sm_invalidate_cached_session(wpa_s->eapol);
2832 : }
2833 :
2834 175 : if (ssid == wpa_s->current_ssid) {
2835 139 : wpa_sm_set_config(wpa_s->wpa, NULL);
2836 139 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2837 :
2838 139 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2839 104 : wpa_s->own_disconnect_req = 1;
2840 139 : wpa_supplicant_deauthenticate(wpa_s,
2841 : WLAN_REASON_DEAUTH_LEAVING);
2842 : }
2843 :
2844 175 : was_disabled = ssid->disabled;
2845 :
2846 175 : if (wpa_config_remove_network(wpa_s->conf, id) < 0)
2847 0 : return -2;
2848 :
2849 175 : if (!was_disabled && wpa_s->sched_scanning) {
2850 0 : wpa_printf(MSG_DEBUG,
2851 : "Stop ongoing sched_scan to remove network from filters");
2852 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
2853 0 : wpa_supplicant_req_scan(wpa_s, 0, 0);
2854 : }
2855 :
2856 175 : return 0;
2857 : }
2858 :
2859 :
2860 : /**
2861 : * wpa_supplicant_enable_network - Mark a configured network as enabled
2862 : * @wpa_s: wpa_supplicant structure for a network interface
2863 : * @ssid: wpa_ssid structure for a configured network or %NULL
2864 : *
2865 : * Enables the specified network or all networks if no network specified.
2866 : */
2867 12 : void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2868 : struct wpa_ssid *ssid)
2869 : {
2870 12 : if (ssid == NULL) {
2871 2 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2872 1 : wpa_supplicant_enable_one_network(wpa_s, ssid);
2873 : } else
2874 11 : wpa_supplicant_enable_one_network(wpa_s, ssid);
2875 :
2876 23 : if (wpa_s->reassociate && !wpa_s->disconnected &&
2877 12 : (!wpa_s->current_ssid ||
2878 2 : wpa_s->wpa_state == WPA_DISCONNECTED ||
2879 1 : wpa_s->wpa_state == WPA_SCANNING)) {
2880 10 : if (wpa_s->sched_scanning) {
2881 0 : wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2882 : "new network to scan filters");
2883 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
2884 : }
2885 :
2886 10 : if (wpa_supplicant_fast_associate(wpa_s) != 1) {
2887 6 : wpa_s->scan_req = NORMAL_SCAN_REQ;
2888 6 : wpa_supplicant_req_scan(wpa_s, 0, 0);
2889 : }
2890 : }
2891 12 : }
2892 :
2893 :
2894 : /**
2895 : * wpa_supplicant_disable_network - Mark a configured network as disabled
2896 : * @wpa_s: wpa_supplicant structure for a network interface
2897 : * @ssid: wpa_ssid structure for a configured network or %NULL
2898 : *
2899 : * Disables the specified network or all networks if no network specified.
2900 : */
2901 12 : void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2902 : struct wpa_ssid *ssid)
2903 : {
2904 : struct wpa_ssid *other_ssid;
2905 : int was_disabled;
2906 :
2907 12 : if (ssid == NULL) {
2908 2 : if (wpa_s->sched_scanning)
2909 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
2910 :
2911 6 : for (other_ssid = wpa_s->conf->ssid; other_ssid;
2912 2 : other_ssid = other_ssid->next) {
2913 2 : was_disabled = other_ssid->disabled;
2914 2 : if (was_disabled == 2)
2915 0 : continue; /* do not change persistent P2P group
2916 : * data */
2917 :
2918 2 : other_ssid->disabled = 1;
2919 :
2920 2 : if (was_disabled != other_ssid->disabled)
2921 2 : wpas_notify_network_enabled_changed(
2922 : wpa_s, other_ssid);
2923 : }
2924 2 : if (wpa_s->current_ssid)
2925 1 : wpa_supplicant_deauthenticate(
2926 : wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2927 10 : } else if (ssid->disabled != 2) {
2928 10 : if (ssid == wpa_s->current_ssid)
2929 3 : wpa_supplicant_deauthenticate(
2930 : wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2931 :
2932 10 : was_disabled = ssid->disabled;
2933 :
2934 10 : ssid->disabled = 1;
2935 :
2936 10 : if (was_disabled != ssid->disabled) {
2937 6 : wpas_notify_network_enabled_changed(wpa_s, ssid);
2938 6 : if (wpa_s->sched_scanning) {
2939 0 : wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2940 : "to remove network from filters");
2941 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
2942 0 : wpa_supplicant_req_scan(wpa_s, 0, 0);
2943 : }
2944 : }
2945 : }
2946 12 : }
2947 :
2948 :
2949 : /**
2950 : * wpa_supplicant_select_network - Attempt association with a network
2951 : * @wpa_s: wpa_supplicant structure for a network interface
2952 : * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2953 : */
2954 3657 : void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2955 : struct wpa_ssid *ssid)
2956 : {
2957 :
2958 : struct wpa_ssid *other_ssid;
2959 3657 : int disconnected = 0;
2960 :
2961 3657 : if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
2962 67 : if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2963 60 : wpa_s->own_disconnect_req = 1;
2964 67 : wpa_supplicant_deauthenticate(
2965 : wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2966 67 : disconnected = 1;
2967 : }
2968 :
2969 3657 : if (ssid)
2970 3655 : wpas_clear_temp_disabled(wpa_s, ssid, 1);
2971 :
2972 : /*
2973 : * Mark all other networks disabled or mark all networks enabled if no
2974 : * network specified.
2975 : */
2976 13639 : for (other_ssid = wpa_s->conf->ssid; other_ssid;
2977 6325 : other_ssid = other_ssid->next) {
2978 6325 : int was_disabled = other_ssid->disabled;
2979 6325 : if (was_disabled == 2)
2980 43 : continue; /* do not change persistent P2P group data */
2981 :
2982 6282 : other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
2983 6282 : if (was_disabled && !other_ssid->disabled)
2984 3424 : wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
2985 :
2986 6282 : if (was_disabled != other_ssid->disabled)
2987 3572 : wpas_notify_network_enabled_changed(wpa_s, other_ssid);
2988 : }
2989 :
2990 3658 : if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
2991 1 : wpa_s->wpa_state >= WPA_AUTHENTICATING) {
2992 : /* We are already associated with the selected network */
2993 0 : wpa_printf(MSG_DEBUG, "Already associated with the "
2994 : "selected network - do nothing");
2995 3657 : return;
2996 : }
2997 :
2998 3657 : if (ssid) {
2999 3655 : wpa_s->current_ssid = ssid;
3000 3655 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
3001 3655 : wpa_s->connect_without_scan =
3002 3655 : (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
3003 :
3004 : /*
3005 : * Don't optimize next scan freqs since a new ESS has been
3006 : * selected.
3007 : */
3008 3655 : os_free(wpa_s->next_scan_freqs);
3009 3655 : wpa_s->next_scan_freqs = NULL;
3010 : } else {
3011 2 : wpa_s->connect_without_scan = NULL;
3012 : }
3013 :
3014 3657 : wpa_s->disconnected = 0;
3015 3657 : wpa_s->reassociate = 1;
3016 :
3017 7123 : if (wpa_s->connect_without_scan ||
3018 3466 : wpa_supplicant_fast_associate(wpa_s) != 1) {
3019 1434 : wpa_s->scan_req = NORMAL_SCAN_REQ;
3020 1434 : wpas_scan_reset_sched_scan(wpa_s);
3021 1434 : wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
3022 : }
3023 :
3024 3657 : if (ssid)
3025 3655 : wpas_notify_network_selected(wpa_s, ssid);
3026 : }
3027 :
3028 :
3029 : /**
3030 : * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
3031 : * @wpa_s: wpa_supplicant structure for a network interface
3032 : * @pkcs11_engine_path: PKCS #11 engine path or NULL
3033 : * @pkcs11_module_path: PKCS #11 module path or NULL
3034 : * Returns: 0 on success; -1 on failure
3035 : *
3036 : * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
3037 : * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
3038 : * module path fails the paths will be reset to the default value (NULL).
3039 : */
3040 4 : int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
3041 : const char *pkcs11_engine_path,
3042 : const char *pkcs11_module_path)
3043 : {
3044 4 : char *pkcs11_engine_path_copy = NULL;
3045 4 : char *pkcs11_module_path_copy = NULL;
3046 :
3047 4 : if (pkcs11_engine_path != NULL) {
3048 2 : pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
3049 2 : if (pkcs11_engine_path_copy == NULL)
3050 0 : return -1;
3051 : }
3052 4 : if (pkcs11_module_path != NULL) {
3053 2 : pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
3054 2 : if (pkcs11_module_path_copy == NULL) {
3055 0 : os_free(pkcs11_engine_path_copy);
3056 0 : return -1;
3057 : }
3058 : }
3059 :
3060 4 : os_free(wpa_s->conf->pkcs11_engine_path);
3061 4 : os_free(wpa_s->conf->pkcs11_module_path);
3062 4 : wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
3063 4 : wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
3064 :
3065 4 : wpa_sm_set_eapol(wpa_s->wpa, NULL);
3066 4 : eapol_sm_deinit(wpa_s->eapol);
3067 4 : wpa_s->eapol = NULL;
3068 4 : if (wpa_supplicant_init_eapol(wpa_s)) {
3069 : /* Error -> Reset paths to the default value (NULL) once. */
3070 0 : if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
3071 0 : wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
3072 : NULL);
3073 :
3074 0 : return -1;
3075 : }
3076 4 : wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3077 :
3078 4 : return 0;
3079 : }
3080 :
3081 :
3082 : /**
3083 : * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
3084 : * @wpa_s: wpa_supplicant structure for a network interface
3085 : * @ap_scan: AP scan mode
3086 : * Returns: 0 if succeed or -1 if ap_scan has an invalid value
3087 : *
3088 : */
3089 24 : int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
3090 : {
3091 :
3092 : int old_ap_scan;
3093 :
3094 24 : if (ap_scan < 0 || ap_scan > 2)
3095 4 : return -1;
3096 :
3097 20 : if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3098 9 : wpa_printf(MSG_INFO,
3099 : "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3100 : }
3101 :
3102 : #ifdef ANDROID
3103 : if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
3104 : wpa_s->wpa_state >= WPA_ASSOCIATING &&
3105 : wpa_s->wpa_state < WPA_COMPLETED) {
3106 : wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
3107 : "associating", wpa_s->conf->ap_scan, ap_scan);
3108 : return 0;
3109 : }
3110 : #endif /* ANDROID */
3111 :
3112 20 : old_ap_scan = wpa_s->conf->ap_scan;
3113 20 : wpa_s->conf->ap_scan = ap_scan;
3114 :
3115 20 : if (old_ap_scan != wpa_s->conf->ap_scan)
3116 18 : wpas_notify_ap_scan_changed(wpa_s);
3117 :
3118 20 : return 0;
3119 : }
3120 :
3121 :
3122 : /**
3123 : * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
3124 : * @wpa_s: wpa_supplicant structure for a network interface
3125 : * @expire_age: Expiration age in seconds
3126 : * Returns: 0 if succeed or -1 if expire_age has an invalid value
3127 : *
3128 : */
3129 6 : int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
3130 : unsigned int bss_expire_age)
3131 : {
3132 6 : if (bss_expire_age < 10) {
3133 2 : wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
3134 : bss_expire_age);
3135 2 : return -1;
3136 : }
3137 4 : wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
3138 : bss_expire_age);
3139 4 : wpa_s->conf->bss_expiration_age = bss_expire_age;
3140 :
3141 4 : return 0;
3142 : }
3143 :
3144 :
3145 : /**
3146 : * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
3147 : * @wpa_s: wpa_supplicant structure for a network interface
3148 : * @expire_count: number of scans after which an unseen BSS is reclaimed
3149 : * Returns: 0 if succeed or -1 if expire_count has an invalid value
3150 : *
3151 : */
3152 7 : int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
3153 : unsigned int bss_expire_count)
3154 : {
3155 7 : if (bss_expire_count < 1) {
3156 2 : wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
3157 : bss_expire_count);
3158 2 : return -1;
3159 : }
3160 5 : wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
3161 : bss_expire_count);
3162 5 : wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
3163 :
3164 5 : return 0;
3165 : }
3166 :
3167 :
3168 : /**
3169 : * wpa_supplicant_set_scan_interval - Set scan interval
3170 : * @wpa_s: wpa_supplicant structure for a network interface
3171 : * @scan_interval: scan interval in seconds
3172 : * Returns: 0 if succeed or -1 if scan_interval has an invalid value
3173 : *
3174 : */
3175 28 : int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
3176 : int scan_interval)
3177 : {
3178 28 : if (scan_interval < 0) {
3179 2 : wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
3180 : scan_interval);
3181 2 : return -1;
3182 : }
3183 26 : wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
3184 : scan_interval);
3185 26 : wpa_supplicant_update_scan_int(wpa_s, scan_interval);
3186 :
3187 26 : return 0;
3188 : }
3189 :
3190 :
3191 : /**
3192 : * wpa_supplicant_set_debug_params - Set global debug params
3193 : * @global: wpa_global structure
3194 : * @debug_level: debug level
3195 : * @debug_timestamp: determines if show timestamp in debug data
3196 : * @debug_show_keys: determines if show keys in debug data
3197 : * Returns: 0 if succeed or -1 if debug_level has wrong value
3198 : */
3199 8 : int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
3200 : int debug_timestamp, int debug_show_keys)
3201 : {
3202 :
3203 : int old_level, old_timestamp, old_show_keys;
3204 :
3205 : /* check for allowed debuglevels */
3206 8 : if (debug_level != MSG_EXCESSIVE &&
3207 2 : debug_level != MSG_MSGDUMP &&
3208 1 : debug_level != MSG_DEBUG &&
3209 1 : debug_level != MSG_INFO &&
3210 1 : debug_level != MSG_WARNING &&
3211 : debug_level != MSG_ERROR)
3212 1 : return -1;
3213 :
3214 7 : old_level = wpa_debug_level;
3215 7 : old_timestamp = wpa_debug_timestamp;
3216 7 : old_show_keys = wpa_debug_show_keys;
3217 :
3218 7 : wpa_debug_level = debug_level;
3219 7 : wpa_debug_timestamp = debug_timestamp ? 1 : 0;
3220 7 : wpa_debug_show_keys = debug_show_keys ? 1 : 0;
3221 :
3222 7 : if (wpa_debug_level != old_level)
3223 2 : wpas_notify_debug_level_changed(global);
3224 7 : if (wpa_debug_timestamp != old_timestamp)
3225 2 : wpas_notify_debug_timestamp_changed(global);
3226 7 : if (wpa_debug_show_keys != old_show_keys)
3227 2 : wpas_notify_debug_show_keys_changed(global);
3228 :
3229 7 : return 0;
3230 : }
3231 :
3232 :
3233 : /**
3234 : * wpa_supplicant_get_ssid - Get a pointer to the current network structure
3235 : * @wpa_s: Pointer to wpa_supplicant data
3236 : * Returns: A pointer to the current network structure or %NULL on failure
3237 : */
3238 2263 : struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
3239 : {
3240 : struct wpa_ssid *entry;
3241 : u8 ssid[SSID_MAX_LEN];
3242 : int res;
3243 : size_t ssid_len;
3244 : u8 bssid[ETH_ALEN];
3245 : int wired;
3246 :
3247 2263 : res = wpa_drv_get_ssid(wpa_s, ssid);
3248 2263 : if (res < 0) {
3249 1 : wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
3250 : "driver");
3251 1 : return NULL;
3252 : }
3253 2262 : ssid_len = res;
3254 :
3255 2262 : if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
3256 0 : wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
3257 : "driver");
3258 0 : return NULL;
3259 : }
3260 :
3261 2264 : wired = wpa_s->conf->ap_scan == 0 &&
3262 2 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
3263 :
3264 2262 : entry = wpa_s->conf->ssid;
3265 4768 : while (entry) {
3266 4767 : if (!wpas_network_disabled(wpa_s, entry) &&
3267 4519 : ((ssid_len == entry->ssid_len &&
3268 4519 : os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
3269 2500 : (!entry->bssid_set ||
3270 246 : os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3271 2254 : return entry;
3272 : #ifdef CONFIG_WPS
3273 259 : if (!wpas_network_disabled(wpa_s, entry) &&
3274 12 : (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
3275 2 : (entry->ssid == NULL || entry->ssid_len == 0) &&
3276 2 : (!entry->bssid_set ||
3277 1 : os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3278 1 : return entry;
3279 : #endif /* CONFIG_WPS */
3280 :
3281 251 : if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
3282 7 : entry->ssid_len == 0 &&
3283 3 : os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
3284 3 : return entry;
3285 :
3286 244 : entry = entry->next;
3287 : }
3288 :
3289 4 : return NULL;
3290 : }
3291 :
3292 :
3293 715 : static int select_driver(struct wpa_supplicant *wpa_s, int i)
3294 : {
3295 715 : struct wpa_global *global = wpa_s->global;
3296 :
3297 715 : if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
3298 36 : global->drv_priv[i] = wpa_drivers[i]->global_init(global);
3299 36 : if (global->drv_priv[i] == NULL) {
3300 0 : wpa_printf(MSG_ERROR, "Failed to initialize driver "
3301 0 : "'%s'", wpa_drivers[i]->name);
3302 0 : return -1;
3303 : }
3304 : }
3305 :
3306 715 : wpa_s->driver = wpa_drivers[i];
3307 715 : wpa_s->global_drv_priv = global->drv_priv[i];
3308 :
3309 715 : return 0;
3310 : }
3311 :
3312 :
3313 715 : static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
3314 : const char *name)
3315 : {
3316 : int i;
3317 : size_t len;
3318 715 : const char *pos, *driver = name;
3319 :
3320 715 : if (wpa_s == NULL)
3321 0 : return -1;
3322 :
3323 715 : if (wpa_drivers[0] == NULL) {
3324 0 : wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
3325 : "wpa_supplicant");
3326 0 : return -1;
3327 : }
3328 :
3329 715 : if (name == NULL) {
3330 : /* default to first driver in the list */
3331 3 : return select_driver(wpa_s, 0);
3332 : }
3333 :
3334 : do {
3335 712 : pos = os_strchr(driver, ',');
3336 712 : if (pos)
3337 0 : len = pos - driver;
3338 : else
3339 712 : len = os_strlen(driver);
3340 :
3341 829 : for (i = 0; wpa_drivers[i]; i++) {
3342 1595 : if (os_strlen(wpa_drivers[i]->name) == len &&
3343 766 : os_strncmp(driver, wpa_drivers[i]->name, len) ==
3344 : 0) {
3345 : /* First driver that succeeds wins */
3346 712 : if (select_driver(wpa_s, i) == 0)
3347 712 : return 0;
3348 : }
3349 : }
3350 :
3351 0 : driver = pos + 1;
3352 0 : } while (pos);
3353 :
3354 0 : wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
3355 0 : return -1;
3356 : }
3357 :
3358 :
3359 : /**
3360 : * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
3361 : * @ctx: Context pointer (wpa_s); this is the ctx variable registered
3362 : * with struct wpa_driver_ops::init()
3363 : * @src_addr: Source address of the EAPOL frame
3364 : * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
3365 : * @len: Length of the EAPOL data
3366 : *
3367 : * This function is called for each received EAPOL frame. Most driver
3368 : * interfaces rely on more generic OS mechanism for receiving frames through
3369 : * l2_packet, but if such a mechanism is not available, the driver wrapper may
3370 : * take care of received EAPOL frames and deliver them to the core supplicant
3371 : * code by calling this function.
3372 : */
3373 21326 : void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
3374 : const u8 *buf, size_t len)
3375 : {
3376 21326 : struct wpa_supplicant *wpa_s = ctx;
3377 :
3378 21326 : wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
3379 21326 : wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
3380 :
3381 : #ifdef CONFIG_TESTING_OPTIONS
3382 21326 : if (wpa_s->ignore_auth_resp) {
3383 8 : wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
3384 8 : return;
3385 : }
3386 : #endif /* CONFIG_TESTING_OPTIONS */
3387 :
3388 : #ifdef CONFIG_PEERKEY
3389 26425 : if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
3390 5124 : wpa_s->current_ssid->peerkey &&
3391 34 : !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
3392 17 : wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
3393 3 : wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
3394 3 : return;
3395 : }
3396 : #endif /* CONFIG_PEERKEY */
3397 :
3398 42586 : if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3399 36620 : (wpa_s->last_eapol_matches_bssid &&
3400 : #ifdef CONFIG_AP
3401 30623 : !wpa_s->ap_iface &&
3402 : #endif /* CONFIG_AP */
3403 15274 : os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
3404 : /*
3405 : * There is possible race condition between receiving the
3406 : * association event and the EAPOL frame since they are coming
3407 : * through different paths from the driver. In order to avoid
3408 : * issues in trying to process the EAPOL frame before receiving
3409 : * association information, lets queue it for processing until
3410 : * the association event is received. This may also be needed in
3411 : * driver-based roaming case, so also use src_addr != BSSID as a
3412 : * trigger if we have previously confirmed that the
3413 : * Authenticator uses BSSID as the src_addr (which is not the
3414 : * case with wired IEEE 802.1X).
3415 : */
3416 44 : wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3417 : "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3418 : wpa_supplicant_state_txt(wpa_s->wpa_state),
3419 : MAC2STR(wpa_s->bssid));
3420 44 : wpabuf_free(wpa_s->pending_eapol_rx);
3421 44 : wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3422 44 : if (wpa_s->pending_eapol_rx) {
3423 44 : os_get_reltime(&wpa_s->pending_eapol_rx_time);
3424 44 : os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3425 : ETH_ALEN);
3426 : }
3427 44 : return;
3428 : }
3429 :
3430 21271 : wpa_s->last_eapol_matches_bssid =
3431 21271 : os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3432 :
3433 : #ifdef CONFIG_AP
3434 21271 : if (wpa_s->ap_iface) {
3435 2100 : wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3436 2100 : return;
3437 : }
3438 : #endif /* CONFIG_AP */
3439 :
3440 19171 : if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
3441 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3442 : "no key management is configured");
3443 0 : return;
3444 : }
3445 :
3446 22963 : if (wpa_s->eapol_received == 0 &&
3447 3792 : (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
3448 0 : !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
3449 3792 : wpa_s->wpa_state != WPA_COMPLETED) &&
3450 7584 : (wpa_s->current_ssid == NULL ||
3451 3792 : wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
3452 : /* Timeout for completing IEEE 802.1X and WPA authentication */
3453 3783 : int timeout = 10;
3454 :
3455 5269 : if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
3456 2953 : wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3457 1467 : wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
3458 : /* Use longer timeout for IEEE 802.1X/EAP */
3459 2851 : timeout = 70;
3460 : }
3461 :
3462 : #ifdef CONFIG_WPS
3463 7566 : if (wpa_s->current_ssid && wpa_s->current_bss &&
3464 4318 : (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
3465 535 : eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
3466 : /*
3467 : * Use shorter timeout if going through WPS AP iteration
3468 : * for PIN config method with an AP that does not
3469 : * advertise Selected Registrar.
3470 : */
3471 : struct wpabuf *wps_ie;
3472 :
3473 345 : wps_ie = wpa_bss_get_vendor_ie_multi(
3474 345 : wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
3475 689 : if (wps_ie &&
3476 344 : !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
3477 12 : timeout = 10;
3478 345 : wpabuf_free(wps_ie);
3479 : }
3480 : #endif /* CONFIG_WPS */
3481 :
3482 3783 : wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
3483 : }
3484 19171 : wpa_s->eapol_received++;
3485 :
3486 19171 : if (wpa_s->countermeasures) {
3487 0 : wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3488 : "EAPOL packet");
3489 0 : return;
3490 : }
3491 :
3492 : #ifdef CONFIG_IBSS_RSN
3493 38342 : if (wpa_s->current_ssid &&
3494 19171 : wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
3495 77 : ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3496 77 : return;
3497 : }
3498 : #endif /* CONFIG_IBSS_RSN */
3499 :
3500 : /* Source address of the incoming EAPOL frame could be compared to the
3501 : * current BSSID. However, it is possible that a centralized
3502 : * Authenticator could be using another MAC address than the BSSID of
3503 : * an AP, so just allow any address to be used for now. The replies are
3504 : * still sent to the current BSSID (if available), though. */
3505 :
3506 19094 : os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
3507 36241 : if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
3508 17147 : eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3509 14648 : return;
3510 4446 : wpa_drv_poll(wpa_s);
3511 4446 : if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
3512 4446 : wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
3513 0 : else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
3514 : /*
3515 : * Set portValid = TRUE here since we are going to skip 4-way
3516 : * handshake processing which would normally set portValid. We
3517 : * need this to allow the EAPOL state machines to be completed
3518 : * without going through EAPOL-Key handshake.
3519 : */
3520 0 : eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3521 : }
3522 : }
3523 :
3524 :
3525 744 : int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
3526 : {
3527 773 : if ((!wpa_s->p2p_mgmt ||
3528 744 : !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3529 715 : !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
3530 715 : l2_packet_deinit(wpa_s->l2);
3531 715 : wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3532 : wpa_drv_get_mac_addr(wpa_s),
3533 : ETH_P_EAPOL,
3534 : wpa_supplicant_rx_eapol, wpa_s, 0);
3535 1429 : if (wpa_s->l2 == NULL)
3536 1 : return -1;
3537 : } else {
3538 29 : const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3539 29 : if (addr)
3540 29 : os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
3541 : }
3542 :
3543 743 : if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
3544 0 : wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
3545 0 : return -1;
3546 : }
3547 :
3548 743 : wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3549 :
3550 743 : return 0;
3551 : }
3552 :
3553 :
3554 22 : static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3555 : const u8 *buf, size_t len)
3556 : {
3557 22 : struct wpa_supplicant *wpa_s = ctx;
3558 : const struct l2_ethhdr *eth;
3559 :
3560 22 : if (len < sizeof(*eth))
3561 0 : return;
3562 22 : eth = (const struct l2_ethhdr *) buf;
3563 :
3564 22 : if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3565 0 : !(eth->h_dest[0] & 0x01)) {
3566 0 : wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3567 : " (bridge - not for this interface - ignore)",
3568 : MAC2STR(src_addr), MAC2STR(eth->h_dest));
3569 0 : return;
3570 : }
3571 :
3572 22 : wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3573 : " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3574 22 : wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3575 : len - sizeof(*eth));
3576 : }
3577 :
3578 :
3579 : /**
3580 : * wpa_supplicant_driver_init - Initialize driver interface parameters
3581 : * @wpa_s: Pointer to wpa_supplicant data
3582 : * Returns: 0 on success, -1 on failure
3583 : *
3584 : * This function is called to initialize driver interface parameters.
3585 : * wpa_drv_init() must have been called before this function to initialize the
3586 : * driver interface.
3587 : */
3588 707 : int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3589 : {
3590 : static int interface_count = 0;
3591 :
3592 707 : if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3593 1 : return -1;
3594 :
3595 706 : wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3596 : MAC2STR(wpa_s->own_addr));
3597 706 : os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
3598 706 : wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3599 :
3600 706 : if (wpa_s->bridge_ifname[0]) {
3601 4 : wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3602 : "interface '%s'", wpa_s->bridge_ifname);
3603 4 : wpa_s->l2_br = l2_packet_init_bridge(
3604 4 : wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3605 : ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
3606 4 : if (wpa_s->l2_br == NULL) {
3607 1 : wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3608 : "connection for the bridge interface '%s'",
3609 1 : wpa_s->bridge_ifname);
3610 1 : return -1;
3611 : }
3612 : }
3613 :
3614 705 : if (wpa_s->conf->ap_scan == 2 &&
3615 0 : os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3616 0 : wpa_printf(MSG_INFO,
3617 : "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3618 : }
3619 :
3620 705 : wpa_clear_keys(wpa_s, NULL);
3621 :
3622 : /* Make sure that TKIP countermeasures are not left enabled (could
3623 : * happen if wpa_supplicant is killed during countermeasures. */
3624 705 : wpa_drv_set_countermeasures(wpa_s, 0);
3625 :
3626 705 : wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
3627 705 : wpa_drv_flush_pmkid(wpa_s);
3628 :
3629 705 : wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
3630 705 : wpa_s->prev_scan_wildcard = 0;
3631 :
3632 705 : if (wpa_supplicant_enabled_networks(wpa_s)) {
3633 0 : if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3634 0 : wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3635 0 : interface_count = 0;
3636 : }
3637 : #ifndef ANDROID
3638 0 : if (!wpa_s->p2p_mgmt &&
3639 0 : wpa_supplicant_delayed_sched_scan(wpa_s,
3640 : interface_count % 3,
3641 : 100000))
3642 0 : wpa_supplicant_req_scan(wpa_s, interface_count % 3,
3643 : 100000);
3644 : #endif /* ANDROID */
3645 0 : interface_count++;
3646 : } else
3647 705 : wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
3648 :
3649 705 : return 0;
3650 : }
3651 :
3652 :
3653 3 : static int wpa_supplicant_daemon(const char *pid_file)
3654 : {
3655 3 : wpa_printf(MSG_DEBUG, "Daemonize..");
3656 3 : return os_daemonize(pid_file);
3657 : }
3658 :
3659 :
3660 : static struct wpa_supplicant *
3661 735 : wpa_supplicant_alloc(struct wpa_supplicant *parent)
3662 : {
3663 : struct wpa_supplicant *wpa_s;
3664 :
3665 735 : wpa_s = os_zalloc(sizeof(*wpa_s));
3666 735 : if (wpa_s == NULL)
3667 2 : return NULL;
3668 733 : wpa_s->scan_req = INITIAL_SCAN_REQ;
3669 733 : wpa_s->scan_interval = 5;
3670 733 : wpa_s->new_connection = 1;
3671 733 : wpa_s->parent = parent ? parent : wpa_s;
3672 733 : wpa_s->p2pdev = wpa_s->parent;
3673 733 : wpa_s->sched_scanning = 0;
3674 :
3675 733 : dl_list_init(&wpa_s->bss_tmp_disallowed);
3676 :
3677 733 : return wpa_s;
3678 : }
3679 :
3680 :
3681 : #ifdef CONFIG_HT_OVERRIDES
3682 :
3683 4830 : static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3684 : struct ieee80211_ht_capabilities *htcaps,
3685 : struct ieee80211_ht_capabilities *htcaps_mask,
3686 : const char *ht_mcs)
3687 : {
3688 : /* parse ht_mcs into hex array */
3689 : int i;
3690 4830 : const char *tmp = ht_mcs;
3691 4830 : char *end = NULL;
3692 :
3693 : /* If ht_mcs is null, do not set anything */
3694 4830 : if (!ht_mcs)
3695 4829 : return 0;
3696 :
3697 : /* This is what we are setting in the kernel */
3698 1 : os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3699 :
3700 1 : wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3701 :
3702 11 : for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3703 10 : errno = 0;
3704 10 : long v = strtol(tmp, &end, 16);
3705 10 : if (errno == 0) {
3706 10 : wpa_msg(wpa_s, MSG_DEBUG,
3707 : "htcap value[%i]: %ld end: %p tmp: %p",
3708 : i, v, end, tmp);
3709 10 : if (end == tmp)
3710 0 : break;
3711 :
3712 10 : htcaps->supported_mcs_set[i] = v;
3713 10 : tmp = end;
3714 : } else {
3715 0 : wpa_msg(wpa_s, MSG_ERROR,
3716 : "Failed to parse ht-mcs: %s, error: %s\n",
3717 0 : ht_mcs, strerror(errno));
3718 0 : return -1;
3719 : }
3720 : }
3721 :
3722 : /*
3723 : * If we were able to parse any values, then set mask for the MCS set.
3724 : */
3725 1 : if (i) {
3726 1 : os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3727 : IEEE80211_HT_MCS_MASK_LEN - 1);
3728 : /* skip the 3 reserved bits */
3729 1 : htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3730 : 0x1f;
3731 : }
3732 :
3733 1 : return 0;
3734 : }
3735 :
3736 :
3737 4830 : static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3738 : struct ieee80211_ht_capabilities *htcaps,
3739 : struct ieee80211_ht_capabilities *htcaps_mask,
3740 : int disabled)
3741 : {
3742 : le16 msk;
3743 :
3744 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3745 :
3746 4830 : if (disabled == -1)
3747 4829 : return 0;
3748 :
3749 1 : msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3750 1 : htcaps_mask->ht_capabilities_info |= msk;
3751 1 : if (disabled)
3752 1 : htcaps->ht_capabilities_info &= msk;
3753 : else
3754 0 : htcaps->ht_capabilities_info |= msk;
3755 :
3756 1 : return 0;
3757 : }
3758 :
3759 :
3760 4830 : static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3761 : struct ieee80211_ht_capabilities *htcaps,
3762 : struct ieee80211_ht_capabilities *htcaps_mask,
3763 : int factor)
3764 : {
3765 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3766 :
3767 4830 : if (factor == -1)
3768 4829 : return 0;
3769 :
3770 1 : if (factor < 0 || factor > 3) {
3771 0 : wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3772 : "Must be 0-3 or -1", factor);
3773 0 : return -EINVAL;
3774 : }
3775 :
3776 1 : htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3777 1 : htcaps->a_mpdu_params &= ~0x3;
3778 1 : htcaps->a_mpdu_params |= factor & 0x3;
3779 :
3780 1 : return 0;
3781 : }
3782 :
3783 :
3784 4830 : static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3785 : struct ieee80211_ht_capabilities *htcaps,
3786 : struct ieee80211_ht_capabilities *htcaps_mask,
3787 : int density)
3788 : {
3789 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3790 :
3791 4830 : if (density == -1)
3792 4829 : return 0;
3793 :
3794 1 : if (density < 0 || density > 7) {
3795 0 : wpa_msg(wpa_s, MSG_ERROR,
3796 : "ampdu_density: %d out of range. Must be 0-7 or -1.",
3797 : density);
3798 0 : return -EINVAL;
3799 : }
3800 :
3801 1 : htcaps_mask->a_mpdu_params |= 0x1C;
3802 1 : htcaps->a_mpdu_params &= ~(0x1C);
3803 1 : htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3804 :
3805 1 : return 0;
3806 : }
3807 :
3808 :
3809 4830 : static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3810 : struct ieee80211_ht_capabilities *htcaps,
3811 : struct ieee80211_ht_capabilities *htcaps_mask,
3812 : int disabled)
3813 : {
3814 : /* Masking these out disables HT40 */
3815 4830 : le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3816 : HT_CAP_INFO_SHORT_GI40MHZ);
3817 :
3818 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3819 :
3820 4830 : if (disabled)
3821 1 : htcaps->ht_capabilities_info &= ~msk;
3822 : else
3823 4829 : htcaps->ht_capabilities_info |= msk;
3824 :
3825 4830 : htcaps_mask->ht_capabilities_info |= msk;
3826 :
3827 4830 : return 0;
3828 : }
3829 :
3830 :
3831 4830 : static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3832 : struct ieee80211_ht_capabilities *htcaps,
3833 : struct ieee80211_ht_capabilities *htcaps_mask,
3834 : int disabled)
3835 : {
3836 : /* Masking these out disables SGI */
3837 4830 : le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3838 : HT_CAP_INFO_SHORT_GI40MHZ);
3839 :
3840 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3841 :
3842 4830 : if (disabled)
3843 1 : htcaps->ht_capabilities_info &= ~msk;
3844 : else
3845 4829 : htcaps->ht_capabilities_info |= msk;
3846 :
3847 4830 : htcaps_mask->ht_capabilities_info |= msk;
3848 :
3849 4830 : return 0;
3850 : }
3851 :
3852 :
3853 4830 : static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3854 : struct ieee80211_ht_capabilities *htcaps,
3855 : struct ieee80211_ht_capabilities *htcaps_mask,
3856 : int disabled)
3857 : {
3858 : /* Masking these out disables LDPC */
3859 4830 : le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
3860 :
3861 4830 : wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3862 :
3863 4830 : if (disabled)
3864 1 : htcaps->ht_capabilities_info &= ~msk;
3865 : else
3866 4829 : htcaps->ht_capabilities_info |= msk;
3867 :
3868 4830 : htcaps_mask->ht_capabilities_info |= msk;
3869 :
3870 4830 : return 0;
3871 : }
3872 :
3873 :
3874 4830 : void wpa_supplicant_apply_ht_overrides(
3875 : struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3876 : struct wpa_driver_associate_params *params)
3877 : {
3878 : struct ieee80211_ht_capabilities *htcaps;
3879 : struct ieee80211_ht_capabilities *htcaps_mask;
3880 :
3881 4830 : if (!ssid)
3882 0 : return;
3883 :
3884 4830 : params->disable_ht = ssid->disable_ht;
3885 4830 : if (!params->htcaps || !params->htcaps_mask)
3886 0 : return;
3887 :
3888 4830 : htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3889 4830 : htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3890 4830 : wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3891 4830 : wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3892 : ssid->disable_max_amsdu);
3893 4830 : wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3894 4830 : wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3895 4830 : wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
3896 4830 : wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
3897 4830 : wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
3898 :
3899 4830 : if (ssid->ht40_intolerant) {
3900 1 : le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
3901 1 : htcaps->ht_capabilities_info |= bit;
3902 1 : htcaps_mask->ht_capabilities_info |= bit;
3903 : }
3904 : }
3905 :
3906 : #endif /* CONFIG_HT_OVERRIDES */
3907 :
3908 :
3909 : #ifdef CONFIG_VHT_OVERRIDES
3910 4830 : void wpa_supplicant_apply_vht_overrides(
3911 : struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3912 : struct wpa_driver_associate_params *params)
3913 : {
3914 : struct ieee80211_vht_capabilities *vhtcaps;
3915 : struct ieee80211_vht_capabilities *vhtcaps_mask;
3916 :
3917 4830 : if (!ssid)
3918 0 : return;
3919 :
3920 4830 : params->disable_vht = ssid->disable_vht;
3921 :
3922 4830 : vhtcaps = (void *) params->vhtcaps;
3923 4830 : vhtcaps_mask = (void *) params->vhtcaps_mask;
3924 :
3925 4830 : if (!vhtcaps || !vhtcaps_mask)
3926 0 : return;
3927 :
3928 4830 : vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
3929 4830 : vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
3930 :
3931 : #ifdef CONFIG_HT_OVERRIDES
3932 : /* if max ampdu is <= 3, we have to make the HT cap the same */
3933 4830 : if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3934 : int max_ampdu;
3935 :
3936 0 : max_ampdu = (ssid->vht_capa &
3937 0 : VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3938 : VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
3939 :
3940 0 : max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3941 0 : wpa_set_ampdu_factor(wpa_s,
3942 0 : (void *) params->htcaps,
3943 0 : (void *) params->htcaps_mask,
3944 : max_ampdu);
3945 : }
3946 : #endif /* CONFIG_HT_OVERRIDES */
3947 :
3948 : #define OVERRIDE_MCS(i) \
3949 : if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3950 : vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
3951 : host_to_le16(3 << 2 * (i - 1)); \
3952 : vhtcaps->vht_supported_mcs_set.tx_map |= \
3953 : host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
3954 : 2 * (i - 1)); \
3955 : } \
3956 : if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3957 : vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
3958 : host_to_le16(3 << 2 * (i - 1)); \
3959 : vhtcaps->vht_supported_mcs_set.rx_map |= \
3960 : host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
3961 : 2 * (i - 1)); \
3962 : }
3963 :
3964 4830 : OVERRIDE_MCS(1);
3965 4830 : OVERRIDE_MCS(2);
3966 4830 : OVERRIDE_MCS(3);
3967 4830 : OVERRIDE_MCS(4);
3968 4830 : OVERRIDE_MCS(5);
3969 4830 : OVERRIDE_MCS(6);
3970 4830 : OVERRIDE_MCS(7);
3971 4830 : OVERRIDE_MCS(8);
3972 : }
3973 : #endif /* CONFIG_VHT_OVERRIDES */
3974 :
3975 :
3976 695 : static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3977 : {
3978 : #ifdef PCSC_FUNCS
3979 : size_t len;
3980 :
3981 : if (!wpa_s->conf->pcsc_reader)
3982 : return 0;
3983 :
3984 : wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
3985 : if (!wpa_s->scard)
3986 : return 1;
3987 :
3988 : if (wpa_s->conf->pcsc_pin &&
3989 : scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
3990 : scard_deinit(wpa_s->scard);
3991 : wpa_s->scard = NULL;
3992 : wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
3993 : return -1;
3994 : }
3995 :
3996 : len = sizeof(wpa_s->imsi) - 1;
3997 : if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
3998 : scard_deinit(wpa_s->scard);
3999 : wpa_s->scard = NULL;
4000 : wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
4001 : return -1;
4002 : }
4003 : wpa_s->imsi[len] = '\0';
4004 :
4005 : wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
4006 :
4007 : wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
4008 : wpa_s->imsi, wpa_s->mnc_len);
4009 :
4010 : wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
4011 : eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
4012 : #endif /* PCSC_FUNCS */
4013 :
4014 695 : return 0;
4015 : }
4016 :
4017 :
4018 703 : int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
4019 : {
4020 : char *val, *pos;
4021 :
4022 703 : ext_password_deinit(wpa_s->ext_pw);
4023 703 : wpa_s->ext_pw = NULL;
4024 703 : eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
4025 :
4026 703 : if (!wpa_s->conf->ext_password_backend)
4027 696 : return 0;
4028 :
4029 7 : val = os_strdup(wpa_s->conf->ext_password_backend);
4030 7 : if (val == NULL)
4031 0 : return -1;
4032 7 : pos = os_strchr(val, ':');
4033 7 : if (pos)
4034 7 : *pos++ = '\0';
4035 :
4036 7 : wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
4037 :
4038 7 : wpa_s->ext_pw = ext_password_init(val, pos);
4039 7 : os_free(val);
4040 7 : if (wpa_s->ext_pw == NULL) {
4041 0 : wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
4042 0 : return -1;
4043 : }
4044 7 : eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
4045 :
4046 7 : return 0;
4047 : }
4048 :
4049 :
4050 : #ifdef CONFIG_FST
4051 :
4052 2528 : static const u8 * wpas_fst_get_bssid_cb(void *ctx)
4053 : {
4054 2528 : struct wpa_supplicant *wpa_s = ctx;
4055 :
4056 6550 : return (is_zero_ether_addr(wpa_s->bssid) ||
4057 3526 : wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
4058 : }
4059 :
4060 :
4061 1418 : static void wpas_fst_get_channel_info_cb(void *ctx,
4062 : enum hostapd_hw_mode *hw_mode,
4063 : u8 *channel)
4064 : {
4065 1418 : struct wpa_supplicant *wpa_s = ctx;
4066 :
4067 1418 : if (wpa_s->current_bss) {
4068 1418 : *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
4069 : channel);
4070 0 : } else if (wpa_s->hw.num_modes) {
4071 0 : *hw_mode = wpa_s->hw.modes[0].mode;
4072 : } else {
4073 : WPA_ASSERT(0);
4074 0 : *hw_mode = 0;
4075 : }
4076 1418 : }
4077 :
4078 :
4079 1530 : static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
4080 : {
4081 1530 : struct wpa_supplicant *wpa_s = ctx;
4082 :
4083 1530 : *modes = wpa_s->hw.modes;
4084 1530 : return wpa_s->hw.num_modes;
4085 : }
4086 :
4087 :
4088 1817 : static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
4089 : {
4090 1817 : struct wpa_supplicant *wpa_s = ctx;
4091 :
4092 1817 : wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
4093 1817 : wpa_s->fst_ies = fst_ies;
4094 1817 : }
4095 :
4096 :
4097 613 : static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
4098 : {
4099 613 : struct wpa_supplicant *wpa_s = ctx;
4100 :
4101 : WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
4102 1226 : return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
4103 613 : wpa_s->own_addr, wpa_s->bssid,
4104 613 : wpabuf_head(data), wpabuf_len(data),
4105 : 0);
4106 : }
4107 :
4108 :
4109 36 : static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
4110 : {
4111 36 : struct wpa_supplicant *wpa_s = ctx;
4112 :
4113 : WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4114 36 : return wpa_s->received_mb_ies;
4115 : }
4116 :
4117 :
4118 27 : static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
4119 : const u8 *buf, size_t size)
4120 : {
4121 27 : struct wpa_supplicant *wpa_s = ctx;
4122 : struct mb_ies_info info;
4123 :
4124 : WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4125 :
4126 27 : if (!mb_ies_info_by_ies(&info, buf, size)) {
4127 27 : wpabuf_free(wpa_s->received_mb_ies);
4128 27 : wpa_s->received_mb_ies = mb_ies_by_info(&info);
4129 : }
4130 27 : }
4131 :
4132 :
4133 1488 : static const u8 * wpas_fst_get_peer_first(void *ctx,
4134 : struct fst_get_peer_ctx **get_ctx,
4135 : Boolean mb_only)
4136 : {
4137 1488 : struct wpa_supplicant *wpa_s = ctx;
4138 :
4139 1488 : *get_ctx = NULL;
4140 1488 : if (!is_zero_ether_addr(wpa_s->bssid))
4141 2026 : return (wpa_s->received_mb_ies || !mb_only) ?
4142 2023 : wpa_s->bssid : NULL;
4143 476 : return NULL;
4144 : }
4145 :
4146 :
4147 3 : static const u8 * wpas_fst_get_peer_next(void *ctx,
4148 : struct fst_get_peer_ctx **get_ctx,
4149 : Boolean mb_only)
4150 : {
4151 3 : return NULL;
4152 : }
4153 :
4154 275 : void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
4155 : struct fst_wpa_obj *iface_obj)
4156 : {
4157 275 : iface_obj->ctx = wpa_s;
4158 275 : iface_obj->get_bssid = wpas_fst_get_bssid_cb;
4159 275 : iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
4160 275 : iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
4161 275 : iface_obj->set_ies = wpas_fst_set_ies_cb;
4162 275 : iface_obj->send_action = wpas_fst_send_action_cb;
4163 275 : iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
4164 275 : iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
4165 275 : iface_obj->get_peer_first = wpas_fst_get_peer_first;
4166 275 : iface_obj->get_peer_next = wpas_fst_get_peer_next;
4167 275 : }
4168 : #endif /* CONFIG_FST */
4169 :
4170 657 : static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
4171 : const struct wpa_driver_capa *capa)
4172 : {
4173 : struct wowlan_triggers *triggers;
4174 657 : int ret = 0;
4175 :
4176 657 : if (!wpa_s->conf->wowlan_triggers)
4177 657 : return 0;
4178 :
4179 0 : triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
4180 0 : if (triggers) {
4181 0 : ret = wpa_drv_wowlan(wpa_s, triggers);
4182 0 : os_free(triggers);
4183 : }
4184 0 : return ret;
4185 : }
4186 :
4187 :
4188 18401 : enum wpa_radio_work_band wpas_freq_to_band(int freq)
4189 : {
4190 18401 : if (freq < 3000)
4191 17911 : return BAND_2_4_GHZ;
4192 490 : if (freq > 50000)
4193 0 : return BAND_60_GHZ;
4194 490 : return BAND_5_GHZ;
4195 : }
4196 :
4197 :
4198 11140 : unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
4199 : {
4200 : int i;
4201 11140 : unsigned int band = 0;
4202 :
4203 11140 : if (freqs) {
4204 : /* freqs are specified for the radio work */
4205 16398 : for (i = 0; freqs[i]; i++)
4206 10102 : band |= wpas_freq_to_band(freqs[i]);
4207 : } else {
4208 : /*
4209 : * freqs are not specified, implies all
4210 : * the supported freqs by HW
4211 : */
4212 19355 : for (i = 0; i < wpa_s->hw.num_modes; i++) {
4213 14511 : if (wpa_s->hw.modes[i].num_channels != 0) {
4214 14511 : if (wpa_s->hw.modes[i].mode ==
4215 9674 : HOSTAPD_MODE_IEEE80211B ||
4216 9674 : wpa_s->hw.modes[i].mode ==
4217 : HOSTAPD_MODE_IEEE80211G)
4218 9674 : band |= BAND_2_4_GHZ;
4219 4837 : else if (wpa_s->hw.modes[i].mode ==
4220 : HOSTAPD_MODE_IEEE80211A)
4221 4837 : band |= BAND_5_GHZ;
4222 0 : else if (wpa_s->hw.modes[i].mode ==
4223 : HOSTAPD_MODE_IEEE80211AD)
4224 0 : band |= BAND_60_GHZ;
4225 0 : else if (wpa_s->hw.modes[i].mode ==
4226 : HOSTAPD_MODE_IEEE80211ANY)
4227 0 : band = BAND_2_4_GHZ | BAND_5_GHZ |
4228 : BAND_60_GHZ;
4229 : }
4230 : }
4231 : }
4232 :
4233 11140 : return band;
4234 : }
4235 :
4236 :
4237 711 : static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
4238 : const char *rn)
4239 : {
4240 711 : struct wpa_supplicant *iface = wpa_s->global->ifaces;
4241 : struct wpa_radio *radio;
4242 :
4243 1554 : while (rn && iface) {
4244 359 : radio = iface->radio;
4245 359 : if (radio && os_strcmp(rn, radio->name) == 0) {
4246 227 : wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
4247 227 : wpa_s->ifname, rn);
4248 227 : dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4249 227 : return radio;
4250 : }
4251 :
4252 132 : iface = iface->next;
4253 : }
4254 :
4255 968 : wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
4256 484 : wpa_s->ifname, rn ? rn : "N/A");
4257 484 : radio = os_zalloc(sizeof(*radio));
4258 484 : if (radio == NULL)
4259 1 : return NULL;
4260 :
4261 483 : if (rn)
4262 431 : os_strlcpy(radio->name, rn, sizeof(radio->name));
4263 483 : dl_list_init(&radio->ifaces);
4264 483 : dl_list_init(&radio->work);
4265 483 : dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4266 :
4267 483 : return radio;
4268 : }
4269 :
4270 :
4271 13863 : static void radio_work_free(struct wpa_radio_work *work)
4272 : {
4273 13863 : if (work->wpa_s->scan_work == work) {
4274 : /* This should not really happen. */
4275 0 : wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
4276 : work->type, work, work->started);
4277 0 : work->wpa_s->scan_work = NULL;
4278 : }
4279 :
4280 : #ifdef CONFIG_P2P
4281 13863 : if (work->wpa_s->p2p_scan_work == work) {
4282 : /* This should not really happen. */
4283 0 : wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
4284 : work->type, work, work->started);
4285 0 : work->wpa_s->p2p_scan_work = NULL;
4286 : }
4287 : #endif /* CONFIG_P2P */
4288 :
4289 13863 : if (work->started) {
4290 13846 : work->wpa_s->radio->num_active_works--;
4291 13846 : wpa_dbg(work->wpa_s, MSG_DEBUG,
4292 : "radio_work_free('%s'@%p: num_active_works --> %u",
4293 : work->type, work,
4294 : work->wpa_s->radio->num_active_works);
4295 : }
4296 :
4297 13863 : dl_list_del(&work->list);
4298 13863 : os_free(work);
4299 13863 : }
4300 :
4301 :
4302 0 : static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
4303 : {
4304 0 : struct wpa_radio_work *active_work = NULL;
4305 : struct wpa_radio_work *tmp;
4306 :
4307 : /* Get the active work to know the type and band. */
4308 0 : dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4309 0 : if (tmp->started) {
4310 0 : active_work = tmp;
4311 0 : break;
4312 : }
4313 : }
4314 :
4315 0 : if (!active_work) {
4316 : /* No active work, start one */
4317 0 : radio->num_active_works = 0;
4318 0 : dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
4319 : list) {
4320 0 : if (os_strcmp(tmp->type, "scan") == 0 &&
4321 0 : radio->external_scan_running &&
4322 0 : (((struct wpa_driver_scan_params *)
4323 0 : tmp->ctx)->only_new_results ||
4324 0 : tmp->wpa_s->clear_driver_scan_cache))
4325 0 : continue;
4326 0 : return tmp;
4327 : }
4328 0 : return NULL;
4329 : }
4330 :
4331 0 : if (os_strcmp(active_work->type, "sme-connect") == 0 ||
4332 0 : os_strcmp(active_work->type, "connect") == 0) {
4333 : /*
4334 : * If the active work is either connect or sme-connect,
4335 : * do not parallelize them with other radio works.
4336 : */
4337 0 : wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4338 : "Do not parallelize radio work with %s",
4339 : active_work->type);
4340 0 : return NULL;
4341 : }
4342 :
4343 0 : dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4344 0 : if (tmp->started)
4345 0 : continue;
4346 :
4347 : /*
4348 : * If connect or sme-connect are enqueued, parallelize only
4349 : * those operations ahead of them in the queue.
4350 : */
4351 0 : if (os_strcmp(tmp->type, "connect") == 0 ||
4352 0 : os_strcmp(tmp->type, "sme-connect") == 0)
4353 : break;
4354 :
4355 : /*
4356 : * Check that the radio works are distinct and
4357 : * on different bands.
4358 : */
4359 0 : if (os_strcmp(active_work->type, tmp->type) != 0 &&
4360 0 : (active_work->bands != tmp->bands)) {
4361 : /*
4362 : * If a scan has to be scheduled through nl80211 scan
4363 : * interface and if an external scan is already running,
4364 : * do not schedule the scan since it is likely to get
4365 : * rejected by kernel.
4366 : */
4367 0 : if (os_strcmp(tmp->type, "scan") == 0 &&
4368 0 : radio->external_scan_running &&
4369 0 : (((struct wpa_driver_scan_params *)
4370 0 : tmp->ctx)->only_new_results ||
4371 0 : tmp->wpa_s->clear_driver_scan_cache))
4372 0 : continue;
4373 :
4374 0 : wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4375 : "active_work:%s new_work:%s",
4376 : active_work->type, tmp->type);
4377 0 : return tmp;
4378 : }
4379 : }
4380 :
4381 : /* Did not find a radio work to schedule in parallel. */
4382 0 : return NULL;
4383 : }
4384 :
4385 :
4386 13864 : static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
4387 : {
4388 13864 : struct wpa_radio *radio = eloop_ctx;
4389 : struct wpa_radio_work *work;
4390 : struct os_reltime now, diff;
4391 : struct wpa_supplicant *wpa_s;
4392 :
4393 13864 : work = dl_list_first(&radio->work, struct wpa_radio_work, list);
4394 13864 : if (work == NULL) {
4395 4 : radio->num_active_works = 0;
4396 22 : return;
4397 : }
4398 :
4399 13860 : wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
4400 : radio_list);
4401 :
4402 27720 : if (!(wpa_s &&
4403 13860 : wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
4404 13860 : if (work->started)
4405 13 : return; /* already started and still in progress */
4406 :
4407 27693 : if (wpa_s && wpa_s->radio->external_scan_running) {
4408 1 : wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
4409 1 : return;
4410 : }
4411 : } else {
4412 0 : work = NULL;
4413 0 : if (radio->num_active_works < MAX_ACTIVE_WORKS) {
4414 : /* get the work to schedule next */
4415 0 : work = radio_work_get_next_work(radio);
4416 : }
4417 0 : if (!work)
4418 0 : return;
4419 : }
4420 :
4421 13846 : wpa_s = work->wpa_s;
4422 13846 : os_get_reltime(&now);
4423 13846 : os_reltime_sub(&now, &work->time, &diff);
4424 13846 : wpa_dbg(wpa_s, MSG_DEBUG,
4425 : "Starting radio work '%s'@%p after %ld.%06ld second wait",
4426 : work->type, work, diff.sec, diff.usec);
4427 13846 : work->started = 1;
4428 13846 : work->time = now;
4429 13846 : radio->num_active_works++;
4430 :
4431 13846 : work->cb(work, 0);
4432 :
4433 13846 : if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
4434 0 : radio->num_active_works < MAX_ACTIVE_WORKS)
4435 0 : radio_work_check_next(wpa_s);
4436 : }
4437 :
4438 :
4439 : /*
4440 : * This function removes both started and pending radio works running on
4441 : * the provided interface's radio.
4442 : * Prior to the removal of the radio work, its callback (cb) is called with
4443 : * deinit set to be 1. Each work's callback is responsible for clearing its
4444 : * internal data and restoring to a correct state.
4445 : * @wpa_s: wpa_supplicant data
4446 : * @type: type of works to be removed
4447 : * @remove_all: 1 to remove all the works on this radio, 0 to remove only
4448 : * this interface's works.
4449 : */
4450 8489 : void radio_remove_works(struct wpa_supplicant *wpa_s,
4451 : const char *type, int remove_all)
4452 : {
4453 : struct wpa_radio_work *work, *tmp;
4454 8489 : struct wpa_radio *radio = wpa_s->radio;
4455 :
4456 8564 : dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
4457 : list) {
4458 75 : if (type && os_strcmp(type, work->type) != 0)
4459 21 : continue;
4460 :
4461 : /* skip other ifaces' works */
4462 54 : if (!remove_all && work->wpa_s != wpa_s)
4463 3 : continue;
4464 :
4465 51 : wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
4466 : work->type, work, work->started ? " (started)" : "");
4467 51 : work->cb(work, 1);
4468 51 : radio_work_free(work);
4469 : }
4470 :
4471 : /* in case we removed the started work */
4472 8489 : radio_work_check_next(wpa_s);
4473 8489 : }
4474 :
4475 :
4476 733 : static void radio_remove_interface(struct wpa_supplicant *wpa_s)
4477 : {
4478 733 : struct wpa_radio *radio = wpa_s->radio;
4479 :
4480 733 : if (!radio)
4481 23 : return;
4482 :
4483 710 : wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
4484 710 : wpa_s->ifname, radio->name);
4485 710 : dl_list_del(&wpa_s->radio_list);
4486 710 : radio_remove_works(wpa_s, NULL, 0);
4487 710 : wpa_s->radio = NULL;
4488 710 : if (!dl_list_empty(&radio->ifaces))
4489 227 : return; /* Interfaces remain for this radio */
4490 :
4491 483 : wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
4492 483 : eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4493 483 : os_free(radio);
4494 : }
4495 :
4496 :
4497 41449 : void radio_work_check_next(struct wpa_supplicant *wpa_s)
4498 : {
4499 41449 : struct wpa_radio *radio = wpa_s->radio;
4500 :
4501 41449 : if (dl_list_empty(&radio->work))
4502 24688 : return;
4503 16761 : if (wpa_s->ext_work_in_progress) {
4504 9 : wpa_printf(MSG_DEBUG,
4505 : "External radio work in progress - delay start of pending item");
4506 9 : return;
4507 : }
4508 16752 : eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4509 16752 : eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
4510 : }
4511 :
4512 :
4513 : /**
4514 : * radio_add_work - Add a radio work item
4515 : * @wpa_s: Pointer to wpa_supplicant data
4516 : * @freq: Frequency of the offchannel operation in MHz or 0
4517 : * @type: Unique identifier for each type of work
4518 : * @next: Force as the next work to be executed
4519 : * @cb: Callback function for indicating when radio is available
4520 : * @ctx: Context pointer for the work (work->ctx in cb())
4521 : * Returns: 0 on success, -1 on failure
4522 : *
4523 : * This function is used to request time for an operation that requires
4524 : * exclusive radio control. Once the radio is available, the registered callback
4525 : * function will be called. radio_work_done() must be called once the exclusive
4526 : * radio operation has been completed, so that the radio is freed for other
4527 : * operations. The special case of deinit=1 is used to free the context data
4528 : * during interface removal. That does not allow the callback function to start
4529 : * the radio operation, i.e., it must free any resources allocated for the radio
4530 : * work and return.
4531 : *
4532 : * The @freq parameter can be used to indicate a single channel on which the
4533 : * offchannel operation will occur. This may allow multiple radio work
4534 : * operations to be performed in parallel if they apply for the same channel.
4535 : * Setting this to 0 indicates that the work item may use multiple channels or
4536 : * requires exclusive control of the radio.
4537 : */
4538 13867 : int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
4539 : const char *type, int next,
4540 : void (*cb)(struct wpa_radio_work *work, int deinit),
4541 : void *ctx)
4542 : {
4543 13867 : struct wpa_radio *radio = wpa_s->radio;
4544 : struct wpa_radio_work *work;
4545 : int was_empty;
4546 :
4547 13867 : work = os_zalloc(sizeof(*work));
4548 13867 : if (work == NULL)
4549 4 : return -1;
4550 13863 : wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
4551 13863 : os_get_reltime(&work->time);
4552 13863 : work->freq = freq;
4553 13863 : work->type = type;
4554 13863 : work->wpa_s = wpa_s;
4555 13863 : work->cb = cb;
4556 13863 : work->ctx = ctx;
4557 :
4558 13863 : if (freq)
4559 8299 : work->bands = wpas_freq_to_band(freq);
4560 6554 : else if (os_strcmp(type, "scan") == 0 ||
4561 990 : os_strcmp(type, "p2p-scan") == 0)
4562 5509 : work->bands = wpas_get_bands(wpa_s,
4563 : ((struct wpa_driver_scan_params *)
4564 5509 : ctx)->freqs);
4565 : else
4566 55 : work->bands = wpas_get_bands(wpa_s, NULL);
4567 :
4568 13863 : was_empty = dl_list_empty(&wpa_s->radio->work);
4569 13863 : if (next)
4570 4888 : dl_list_add(&wpa_s->radio->work, &work->list);
4571 : else
4572 8975 : dl_list_add_tail(&wpa_s->radio->work, &work->list);
4573 13863 : if (was_empty) {
4574 13548 : wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
4575 13548 : radio_work_check_next(wpa_s);
4576 315 : } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
4577 0 : && radio->num_active_works < MAX_ACTIVE_WORKS) {
4578 0 : wpa_dbg(wpa_s, MSG_DEBUG,
4579 : "Try to schedule a radio work (num_active_works=%u)",
4580 : radio->num_active_works);
4581 0 : radio_work_check_next(wpa_s);
4582 : }
4583 :
4584 13863 : return 0;
4585 : }
4586 :
4587 :
4588 : /**
4589 : * radio_work_done - Indicate that a radio work item has been completed
4590 : * @work: Completed work
4591 : *
4592 : * This function is called once the callback function registered with
4593 : * radio_add_work() has completed its work.
4594 : */
4595 13812 : void radio_work_done(struct wpa_radio_work *work)
4596 : {
4597 13812 : struct wpa_supplicant *wpa_s = work->wpa_s;
4598 : struct os_reltime now, diff;
4599 13812 : unsigned int started = work->started;
4600 :
4601 13812 : os_get_reltime(&now);
4602 13812 : os_reltime_sub(&now, &work->time, &diff);
4603 13812 : wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
4604 : work->type, work, started ? "done" : "canceled",
4605 : diff.sec, diff.usec);
4606 13812 : radio_work_free(work);
4607 13812 : if (started)
4608 13811 : radio_work_check_next(wpa_s);
4609 13812 : }
4610 :
4611 :
4612 : struct wpa_radio_work *
4613 14960 : radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
4614 : {
4615 : struct wpa_radio_work *work;
4616 14960 : struct wpa_radio *radio = wpa_s->radio;
4617 :
4618 15675 : dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
4619 740 : if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
4620 25 : return work;
4621 : }
4622 :
4623 14935 : return NULL;
4624 : }
4625 :
4626 :
4627 715 : static int wpas_init_driver(struct wpa_supplicant *wpa_s,
4628 : struct wpa_interface *iface)
4629 : {
4630 : const char *ifname, *driver, *rn;
4631 :
4632 715 : driver = iface->driver;
4633 : next_driver:
4634 715 : if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
4635 0 : return -1;
4636 :
4637 715 : wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
4638 715 : if (wpa_s->drv_priv == NULL) {
4639 : const char *pos;
4640 4 : pos = driver ? os_strchr(driver, ',') : NULL;
4641 4 : if (pos) {
4642 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
4643 : "driver interface - try next driver wrapper");
4644 0 : driver = pos + 1;
4645 0 : goto next_driver;
4646 : }
4647 4 : wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
4648 : "interface");
4649 4 : return -1;
4650 : }
4651 711 : if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
4652 0 : wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
4653 0 : "driver_param '%s'", wpa_s->conf->driver_param);
4654 0 : return -1;
4655 : }
4656 :
4657 711 : ifname = wpa_drv_get_ifname(wpa_s);
4658 711 : if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
4659 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
4660 : "interface name with '%s'", ifname);
4661 0 : os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
4662 : }
4663 :
4664 711 : rn = wpa_driver_get_radio_name(wpa_s);
4665 711 : if (rn && rn[0] == '\0')
4666 0 : rn = NULL;
4667 :
4668 711 : wpa_s->radio = radio_add_interface(wpa_s, rn);
4669 711 : if (wpa_s->radio == NULL)
4670 1 : return -1;
4671 :
4672 710 : return 0;
4673 : }
4674 :
4675 :
4676 733 : static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
4677 : struct wpa_interface *iface)
4678 : {
4679 : struct wpa_driver_capa capa;
4680 : int capa_res;
4681 :
4682 2932 : wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
4683 : "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
4684 733 : iface->confname ? iface->confname : "N/A",
4685 733 : iface->driver ? iface->driver : "default",
4686 733 : iface->ctrl_interface ? iface->ctrl_interface : "N/A",
4687 733 : iface->bridge_ifname ? iface->bridge_ifname : "N/A");
4688 :
4689 733 : if (iface->confname) {
4690 : #ifdef CONFIG_BACKEND_FILE
4691 58 : wpa_s->confname = os_rel2abs_path(iface->confname);
4692 58 : if (wpa_s->confname == NULL) {
4693 0 : wpa_printf(MSG_ERROR, "Failed to get absolute path "
4694 : "for configuration file '%s'.",
4695 : iface->confname);
4696 0 : return -1;
4697 : }
4698 58 : wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
4699 : iface->confname, wpa_s->confname);
4700 : #else /* CONFIG_BACKEND_FILE */
4701 : wpa_s->confname = os_strdup(iface->confname);
4702 : #endif /* CONFIG_BACKEND_FILE */
4703 58 : wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
4704 58 : if (wpa_s->conf == NULL) {
4705 16 : wpa_printf(MSG_ERROR, "Failed to read or parse "
4706 : "configuration '%s'.", wpa_s->confname);
4707 16 : return -1;
4708 : }
4709 42 : wpa_s->confanother = os_rel2abs_path(iface->confanother);
4710 42 : wpa_config_read(wpa_s->confanother, wpa_s->conf);
4711 :
4712 : /*
4713 : * Override ctrl_interface and driver_param if set on command
4714 : * line.
4715 : */
4716 42 : if (iface->ctrl_interface) {
4717 10 : os_free(wpa_s->conf->ctrl_interface);
4718 20 : wpa_s->conf->ctrl_interface =
4719 10 : os_strdup(iface->ctrl_interface);
4720 : }
4721 :
4722 42 : if (iface->driver_param) {
4723 0 : os_free(wpa_s->conf->driver_param);
4724 0 : wpa_s->conf->driver_param =
4725 0 : os_strdup(iface->driver_param);
4726 : }
4727 :
4728 42 : if (iface->p2p_mgmt && !iface->ctrl_interface) {
4729 0 : os_free(wpa_s->conf->ctrl_interface);
4730 0 : wpa_s->conf->ctrl_interface = NULL;
4731 : }
4732 : } else
4733 675 : wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4734 : iface->driver_param);
4735 :
4736 717 : if (wpa_s->conf == NULL) {
4737 2 : wpa_printf(MSG_ERROR, "\nNo configuration found.");
4738 2 : return -1;
4739 : }
4740 :
4741 715 : if (iface->ifname == NULL) {
4742 0 : wpa_printf(MSG_ERROR, "\nInterface name is required.");
4743 0 : return -1;
4744 : }
4745 715 : if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4746 0 : wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4747 : iface->ifname);
4748 0 : return -1;
4749 : }
4750 715 : os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4751 :
4752 715 : if (iface->bridge_ifname) {
4753 4 : if (os_strlen(iface->bridge_ifname) >=
4754 : sizeof(wpa_s->bridge_ifname)) {
4755 0 : wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4756 : "name '%s'.", iface->bridge_ifname);
4757 0 : return -1;
4758 : }
4759 4 : os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4760 : sizeof(wpa_s->bridge_ifname));
4761 : }
4762 :
4763 : /* RSNA Supplicant Key Management - INITIALIZE */
4764 715 : eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4765 715 : eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4766 :
4767 : /* Initialize driver interface and register driver event handler before
4768 : * L2 receive handler so that association events are processed before
4769 : * EAPOL-Key packets if both become available for the same select()
4770 : * call. */
4771 715 : if (wpas_init_driver(wpa_s, iface) < 0)
4772 5 : return -1;
4773 :
4774 710 : if (wpa_supplicant_init_wpa(wpa_s) < 0)
4775 3 : return -1;
4776 :
4777 707 : wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4778 707 : wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4779 : NULL);
4780 707 : wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4781 :
4782 707 : if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4783 0 : wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4784 0 : wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
4785 0 : wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4786 : "dot11RSNAConfigPMKLifetime");
4787 0 : return -1;
4788 : }
4789 :
4790 707 : if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4791 0 : wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4792 0 : wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
4793 0 : wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4794 : "dot11RSNAConfigPMKReauthThreshold");
4795 0 : return -1;
4796 : }
4797 :
4798 707 : if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4799 0 : wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4800 0 : wpa_s->conf->dot11RSNAConfigSATimeout)) {
4801 0 : wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4802 : "dot11RSNAConfigSATimeout");
4803 0 : return -1;
4804 : }
4805 :
4806 707 : wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4807 : &wpa_s->hw.num_modes,
4808 : &wpa_s->hw.flags);
4809 707 : if (wpa_s->hw.modes) {
4810 : u16 i;
4811 :
4812 1298 : for (i = 0; i < wpa_s->hw.num_modes; i++) {
4813 1298 : if (wpa_s->hw.modes[i].vht_capab) {
4814 649 : wpa_s->hw_capab = CAPAB_VHT;
4815 649 : break;
4816 : }
4817 :
4818 649 : if (wpa_s->hw.modes[i].ht_capab &
4819 : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4820 649 : wpa_s->hw_capab = CAPAB_HT40;
4821 0 : else if (wpa_s->hw.modes[i].ht_capab &&
4822 0 : wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4823 0 : wpa_s->hw_capab = CAPAB_HT;
4824 : }
4825 : }
4826 :
4827 707 : capa_res = wpa_drv_get_capa(wpa_s, &capa);
4828 707 : if (capa_res == 0) {
4829 658 : wpa_s->drv_capa_known = 1;
4830 658 : wpa_s->drv_flags = capa.flags;
4831 658 : wpa_s->drv_enc = capa.enc;
4832 658 : wpa_s->drv_smps_modes = capa.smps_modes;
4833 658 : wpa_s->drv_rrm_flags = capa.rrm_flags;
4834 658 : wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
4835 658 : wpa_s->max_scan_ssids = capa.max_scan_ssids;
4836 658 : wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
4837 658 : wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
4838 658 : wpa_s->max_sched_scan_plan_interval =
4839 658 : capa.max_sched_scan_plan_interval;
4840 658 : wpa_s->max_sched_scan_plan_iterations =
4841 658 : capa.max_sched_scan_plan_iterations;
4842 658 : wpa_s->sched_scan_supported = capa.sched_scan_supported;
4843 658 : wpa_s->max_match_sets = capa.max_match_sets;
4844 658 : wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
4845 658 : wpa_s->max_stations = capa.max_stations;
4846 658 : wpa_s->extended_capa = capa.extended_capa;
4847 658 : wpa_s->extended_capa_mask = capa.extended_capa_mask;
4848 658 : wpa_s->extended_capa_len = capa.extended_capa_len;
4849 658 : wpa_s->num_multichan_concurrent =
4850 658 : capa.num_multichan_concurrent;
4851 658 : wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
4852 :
4853 658 : if (capa.mac_addr_rand_scan_supported)
4854 649 : wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4855 658 : if (wpa_s->sched_scan_supported &&
4856 : capa.mac_addr_rand_sched_scan_supported)
4857 0 : wpa_s->mac_addr_rand_supported |=
4858 : (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
4859 : }
4860 707 : if (wpa_s->max_remain_on_chan == 0)
4861 58 : wpa_s->max_remain_on_chan = 1000;
4862 :
4863 : /*
4864 : * Only take p2p_mgmt parameters when P2P Device is supported.
4865 : * Doing it here as it determines whether l2_packet_init() will be done
4866 : * during wpa_supplicant_driver_init().
4867 : */
4868 707 : if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4869 74 : wpa_s->p2p_mgmt = iface->p2p_mgmt;
4870 : else
4871 633 : iface->p2p_mgmt = 1;
4872 :
4873 707 : if (wpa_s->num_multichan_concurrent == 0)
4874 677 : wpa_s->num_multichan_concurrent = 1;
4875 :
4876 707 : if (wpa_supplicant_driver_init(wpa_s) < 0)
4877 2 : return -1;
4878 :
4879 : #ifdef CONFIG_TDLS
4880 1363 : if ((!iface->p2p_mgmt ||
4881 658 : !(wpa_s->drv_flags &
4882 678 : WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4883 678 : wpa_tdls_init(wpa_s->wpa))
4884 1 : return -1;
4885 : #endif /* CONFIG_TDLS */
4886 :
4887 704 : if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4888 0 : wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
4889 0 : wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
4890 0 : return -1;
4891 : }
4892 :
4893 : #ifdef CONFIG_FST
4894 704 : if (wpa_s->conf->fst_group_id) {
4895 : struct fst_iface_cfg cfg;
4896 : struct fst_wpa_obj iface_obj;
4897 :
4898 13 : fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
4899 13 : os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
4900 : sizeof(cfg.group_id));
4901 13 : cfg.priority = wpa_s->conf->fst_priority;
4902 13 : cfg.llt = wpa_s->conf->fst_llt;
4903 :
4904 13 : wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
4905 : &iface_obj, &cfg);
4906 13 : if (!wpa_s->fst) {
4907 0 : wpa_msg(wpa_s, MSG_ERROR,
4908 : "FST: Cannot attach iface %s to group %s",
4909 0 : wpa_s->ifname, cfg.group_id);
4910 0 : return -1;
4911 : }
4912 : }
4913 : #endif /* CONFIG_FST */
4914 :
4915 704 : if (wpas_wps_init(wpa_s))
4916 2 : return -1;
4917 :
4918 702 : if (wpa_supplicant_init_eapol(wpa_s) < 0)
4919 5 : return -1;
4920 697 : wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4921 :
4922 697 : wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4923 697 : if (wpa_s->ctrl_iface == NULL) {
4924 1 : wpa_printf(MSG_ERROR,
4925 : "Failed to initialize control interface '%s'.\n"
4926 : "You may have another wpa_supplicant process "
4927 : "already running or the file was\n"
4928 : "left by an unclean termination of wpa_supplicant "
4929 : "in which case you will need\n"
4930 : "to manually remove this file before starting "
4931 : "wpa_supplicant again.\n",
4932 1 : wpa_s->conf->ctrl_interface);
4933 1 : return -1;
4934 : }
4935 :
4936 696 : wpa_s->gas = gas_query_init(wpa_s);
4937 696 : if (wpa_s->gas == NULL) {
4938 1 : wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4939 1 : return -1;
4940 : }
4941 :
4942 695 : if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
4943 0 : wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
4944 0 : return -1;
4945 : }
4946 :
4947 695 : if (wpa_bss_init(wpa_s) < 0)
4948 0 : return -1;
4949 :
4950 : /*
4951 : * Set Wake-on-WLAN triggers, if configured.
4952 : * Note: We don't restore/remove the triggers on shutdown (it doesn't
4953 : * have effect anyway when the interface is down).
4954 : */
4955 695 : if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
4956 0 : return -1;
4957 :
4958 : #ifdef CONFIG_EAP_PROXY
4959 : {
4960 : size_t len;
4961 : wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4962 : &len);
4963 : if (wpa_s->mnc_len > 0) {
4964 : wpa_s->imsi[len] = '\0';
4965 : wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4966 : wpa_s->imsi, wpa_s->mnc_len);
4967 : } else {
4968 : wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4969 : }
4970 : }
4971 : #endif /* CONFIG_EAP_PROXY */
4972 :
4973 695 : if (pcsc_reader_init(wpa_s) < 0)
4974 0 : return -1;
4975 :
4976 695 : if (wpas_init_ext_pw(wpa_s) < 0)
4977 0 : return -1;
4978 :
4979 695 : wpas_rrm_reset(wpa_s);
4980 :
4981 695 : wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
4982 :
4983 : #ifdef CONFIG_HS20
4984 695 : hs20_init(wpa_s);
4985 : #endif /* CONFIG_HS20 */
4986 : #ifdef CONFIG_MBO
4987 695 : wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
4988 : #endif /* CONFIG_MBO */
4989 :
4990 695 : wpa_supplicant_set_default_scan_ies(wpa_s);
4991 :
4992 695 : return 0;
4993 : }
4994 :
4995 :
4996 733 : static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
4997 : int notify, int terminate)
4998 : {
4999 733 : struct wpa_global *global = wpa_s->global;
5000 : struct wpa_supplicant *iface, *prev;
5001 :
5002 733 : if (wpa_s == wpa_s->parent)
5003 519 : wpas_p2p_group_remove(wpa_s, "*");
5004 :
5005 733 : iface = global->ifaces;
5006 3916 : while (iface) {
5007 2450 : if (iface->p2pdev == wpa_s)
5008 3 : iface->p2pdev = iface->parent;
5009 2450 : if (iface == wpa_s || iface->parent != wpa_s) {
5010 2448 : iface = iface->next;
5011 2448 : continue;
5012 : }
5013 2 : wpa_printf(MSG_DEBUG,
5014 : "Remove remaining child interface %s from parent %s",
5015 2 : iface->ifname, wpa_s->ifname);
5016 2 : prev = iface;
5017 2 : iface = iface->next;
5018 2 : wpa_supplicant_remove_iface(global, prev, terminate);
5019 : }
5020 :
5021 733 : wpa_s->disconnected = 1;
5022 733 : if (wpa_s->drv_priv) {
5023 711 : wpa_supplicant_deauthenticate(wpa_s,
5024 : WLAN_REASON_DEAUTH_LEAVING);
5025 :
5026 711 : wpa_drv_set_countermeasures(wpa_s, 0);
5027 711 : wpa_clear_keys(wpa_s, NULL);
5028 : }
5029 :
5030 733 : wpa_supplicant_cleanup(wpa_s);
5031 733 : wpas_p2p_deinit_iface(wpa_s);
5032 :
5033 733 : wpas_ctrl_radio_work_flush(wpa_s);
5034 733 : radio_remove_interface(wpa_s);
5035 :
5036 : #ifdef CONFIG_FST
5037 733 : if (wpa_s->fst) {
5038 21 : fst_detach(wpa_s->fst);
5039 21 : wpa_s->fst = NULL;
5040 : }
5041 733 : if (wpa_s->received_mb_ies) {
5042 243 : wpabuf_free(wpa_s->received_mb_ies);
5043 243 : wpa_s->received_mb_ies = NULL;
5044 : }
5045 : #endif /* CONFIG_FST */
5046 :
5047 733 : if (wpa_s->drv_priv)
5048 711 : wpa_drv_deinit(wpa_s);
5049 :
5050 733 : if (notify)
5051 695 : wpas_notify_iface_removed(wpa_s);
5052 :
5053 733 : if (terminate)
5054 32 : wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
5055 :
5056 733 : if (wpa_s->ctrl_iface) {
5057 696 : wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
5058 696 : wpa_s->ctrl_iface = NULL;
5059 : }
5060 :
5061 : #ifdef CONFIG_MESH
5062 733 : if (wpa_s->ifmsh) {
5063 0 : wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
5064 0 : wpa_s->ifmsh = NULL;
5065 : }
5066 : #endif /* CONFIG_MESH */
5067 :
5068 733 : if (wpa_s->conf != NULL) {
5069 715 : wpa_config_free(wpa_s->conf);
5070 715 : wpa_s->conf = NULL;
5071 : }
5072 :
5073 733 : os_free(wpa_s->ssids_from_scan_req);
5074 :
5075 733 : os_free(wpa_s);
5076 733 : }
5077 :
5078 :
5079 : #ifdef CONFIG_MATCH_IFACE
5080 :
5081 : /**
5082 : * wpa_supplicant_match_iface - Match an interface description to a name
5083 : * @global: Pointer to global data from wpa_supplicant_init()
5084 : * @ifname: Name of the interface to match
5085 : * Returns: Pointer to the created interface description or %NULL on failure
5086 : */
5087 : struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
5088 : const char *ifname)
5089 : {
5090 : int i;
5091 : struct wpa_interface *iface, *miface;
5092 :
5093 : for (i = 0; i < global->params.match_iface_count; i++) {
5094 : miface = &global->params.match_ifaces[i];
5095 : if (!miface->ifname ||
5096 : fnmatch(miface->ifname, ifname, 0) == 0) {
5097 : iface = os_zalloc(sizeof(*iface));
5098 : if (!iface)
5099 : return NULL;
5100 : *iface = *miface;
5101 : iface->ifname = ifname;
5102 : return iface;
5103 : }
5104 : }
5105 :
5106 : return NULL;
5107 : }
5108 :
5109 :
5110 : /**
5111 : * wpa_supplicant_match_existing - Match existing interfaces
5112 : * @global: Pointer to global data from wpa_supplicant_init()
5113 : * Returns: 0 on success, -1 on failure
5114 : */
5115 : static int wpa_supplicant_match_existing(struct wpa_global *global)
5116 : {
5117 : struct if_nameindex *ifi, *ifp;
5118 : struct wpa_supplicant *wpa_s;
5119 : struct wpa_interface *iface;
5120 :
5121 : ifp = if_nameindex();
5122 : if (!ifp) {
5123 : wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
5124 : return -1;
5125 : }
5126 :
5127 : for (ifi = ifp; ifi->if_name; ifi++) {
5128 : wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
5129 : if (wpa_s)
5130 : continue;
5131 : iface = wpa_supplicant_match_iface(global, ifi->if_name);
5132 : if (iface) {
5133 : wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
5134 : os_free(iface);
5135 : if (wpa_s)
5136 : wpa_s->matched = 1;
5137 : }
5138 : }
5139 :
5140 : if_freenameindex(ifp);
5141 : return 0;
5142 : }
5143 :
5144 : #endif /* CONFIG_MATCH_IFACE */
5145 :
5146 :
5147 : /**
5148 : * wpa_supplicant_add_iface - Add a new network interface
5149 : * @global: Pointer to global data from wpa_supplicant_init()
5150 : * @iface: Interface configuration options
5151 : * @parent: Parent interface or %NULL to assign new interface as parent
5152 : * Returns: Pointer to the created interface or %NULL on failure
5153 : *
5154 : * This function is used to add new network interfaces for %wpa_supplicant.
5155 : * This can be called before wpa_supplicant_run() to add interfaces before the
5156 : * main event loop has been started. In addition, new interfaces can be added
5157 : * dynamically while %wpa_supplicant is already running. This could happen,
5158 : * e.g., when a hotplug network adapter is inserted.
5159 : */
5160 735 : struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
5161 : struct wpa_interface *iface,
5162 : struct wpa_supplicant *parent)
5163 : {
5164 : struct wpa_supplicant *wpa_s;
5165 : struct wpa_interface t_iface;
5166 : struct wpa_ssid *ssid;
5167 :
5168 735 : if (global == NULL || iface == NULL)
5169 0 : return NULL;
5170 :
5171 735 : wpa_s = wpa_supplicant_alloc(parent);
5172 735 : if (wpa_s == NULL)
5173 2 : return NULL;
5174 :
5175 733 : wpa_s->global = global;
5176 :
5177 733 : t_iface = *iface;
5178 733 : if (global->params.override_driver) {
5179 0 : wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
5180 : "('%s' -> '%s')",
5181 : iface->driver, global->params.override_driver);
5182 0 : t_iface.driver = global->params.override_driver;
5183 : }
5184 733 : if (global->params.override_ctrl_interface) {
5185 0 : wpa_printf(MSG_DEBUG, "Override interface parameter: "
5186 : "ctrl_interface ('%s' -> '%s')",
5187 : iface->ctrl_interface,
5188 : global->params.override_ctrl_interface);
5189 0 : t_iface.ctrl_interface =
5190 0 : global->params.override_ctrl_interface;
5191 : }
5192 733 : if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
5193 38 : wpa_printf(MSG_DEBUG, "Failed to add interface %s",
5194 : iface->ifname);
5195 38 : wpa_supplicant_deinit_iface(wpa_s, 0, 0);
5196 38 : return NULL;
5197 : }
5198 :
5199 695 : if (iface->p2p_mgmt == 0) {
5200 : /* Notify the control interfaces about new iface */
5201 668 : if (wpas_notify_iface_added(wpa_s)) {
5202 3 : wpa_supplicant_deinit_iface(wpa_s, 1, 0);
5203 3 : return NULL;
5204 : }
5205 :
5206 666 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
5207 1 : wpas_notify_network_added(wpa_s, ssid);
5208 : }
5209 :
5210 692 : wpa_s->next = global->ifaces;
5211 692 : global->ifaces = wpa_s;
5212 :
5213 692 : wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
5214 692 : wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
5215 :
5216 : #ifdef CONFIG_P2P
5217 728 : if (wpa_s->global->p2p == NULL &&
5218 108 : !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
5219 63 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
5220 27 : wpas_p2p_add_p2pdev_interface(
5221 27 : wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
5222 0 : wpa_printf(MSG_INFO,
5223 : "P2P: Failed to enable P2P Device interface");
5224 : /* Try to continue without. P2P will be disabled. */
5225 : }
5226 : #endif /* CONFIG_P2P */
5227 :
5228 692 : return wpa_s;
5229 : }
5230 :
5231 :
5232 : /**
5233 : * wpa_supplicant_remove_iface - Remove a network interface
5234 : * @global: Pointer to global data from wpa_supplicant_init()
5235 : * @wpa_s: Pointer to the network interface to be removed
5236 : * Returns: 0 if interface was removed, -1 if interface was not found
5237 : *
5238 : * This function can be used to dynamically remove network interfaces from
5239 : * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
5240 : * addition, this function is used to remove all remaining interfaces when
5241 : * %wpa_supplicant is terminated.
5242 : */
5243 692 : int wpa_supplicant_remove_iface(struct wpa_global *global,
5244 : struct wpa_supplicant *wpa_s,
5245 : int terminate)
5246 : {
5247 : struct wpa_supplicant *prev;
5248 : #ifdef CONFIG_MESH
5249 692 : unsigned int mesh_if_created = wpa_s->mesh_if_created;
5250 692 : char *ifname = NULL;
5251 : #endif /* CONFIG_MESH */
5252 :
5253 : /* Remove interface from the global list of interfaces */
5254 692 : prev = global->ifaces;
5255 692 : if (prev == wpa_s) {
5256 554 : global->ifaces = wpa_s->next;
5257 : } else {
5258 312 : while (prev && prev->next != wpa_s)
5259 36 : prev = prev->next;
5260 138 : if (prev == NULL)
5261 0 : return -1;
5262 138 : prev->next = wpa_s->next;
5263 : }
5264 :
5265 692 : wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
5266 :
5267 : #ifdef CONFIG_MESH
5268 692 : if (mesh_if_created) {
5269 4 : ifname = os_strdup(wpa_s->ifname);
5270 4 : if (ifname == NULL) {
5271 0 : wpa_dbg(wpa_s, MSG_ERROR,
5272 : "mesh: Failed to malloc ifname");
5273 0 : return -1;
5274 : }
5275 : }
5276 : #endif /* CONFIG_MESH */
5277 :
5278 692 : if (global->p2p_group_formation == wpa_s)
5279 9 : global->p2p_group_formation = NULL;
5280 692 : if (global->p2p_invite_group == wpa_s)
5281 4 : global->p2p_invite_group = NULL;
5282 692 : wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
5283 :
5284 : #ifdef CONFIG_MESH
5285 692 : if (mesh_if_created) {
5286 4 : wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
5287 4 : os_free(ifname);
5288 : }
5289 : #endif /* CONFIG_MESH */
5290 :
5291 692 : return 0;
5292 : }
5293 :
5294 :
5295 : /**
5296 : * wpa_supplicant_get_eap_mode - Get the current EAP mode
5297 : * @wpa_s: Pointer to the network interface
5298 : * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
5299 : */
5300 1878 : const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
5301 : {
5302 : const char *eapol_method;
5303 :
5304 1912 : if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
5305 34 : wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
5306 0 : return "NO-EAP";
5307 : }
5308 :
5309 1878 : eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
5310 1878 : if (eapol_method == NULL)
5311 0 : return "UNKNOWN-EAP";
5312 :
5313 1878 : return eapol_method;
5314 : }
5315 :
5316 :
5317 : /**
5318 : * wpa_supplicant_get_iface - Get a new network interface
5319 : * @global: Pointer to global data from wpa_supplicant_init()
5320 : * @ifname: Interface name
5321 : * Returns: Pointer to the interface or %NULL if not found
5322 : */
5323 145677 : struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
5324 : const char *ifname)
5325 : {
5326 : struct wpa_supplicant *wpa_s;
5327 :
5328 266212 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5329 121723 : if (os_strcmp(wpa_s->ifname, ifname) == 0)
5330 1188 : return wpa_s;
5331 : }
5332 144489 : return NULL;
5333 : }
5334 :
5335 :
5336 : #ifndef CONFIG_NO_WPA_MSG
5337 1085518 : static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
5338 : {
5339 1085518 : struct wpa_supplicant *wpa_s = ctx;
5340 1085518 : if (wpa_s == NULL)
5341 1273 : return NULL;
5342 1084245 : return wpa_s->ifname;
5343 : }
5344 : #endif /* CONFIG_NO_WPA_MSG */
5345 :
5346 :
5347 : #ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
5348 : #define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
5349 : #endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
5350 :
5351 : /* Periodic cleanup tasks */
5352 2798 : static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
5353 : {
5354 2798 : struct wpa_global *global = eloop_ctx;
5355 : struct wpa_supplicant *wpa_s;
5356 :
5357 2798 : eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5358 : wpas_periodic, global, NULL);
5359 :
5360 : #ifdef CONFIG_P2P
5361 2798 : if (global->p2p)
5362 2130 : p2p_expire_peers(global->p2p);
5363 : #endif /* CONFIG_P2P */
5364 :
5365 5232 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5366 2434 : wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
5367 : #ifdef CONFIG_AP
5368 2434 : ap_periodic(wpa_s);
5369 : #endif /* CONFIG_AP */
5370 : }
5371 2798 : }
5372 :
5373 :
5374 : /**
5375 : * wpa_supplicant_init - Initialize %wpa_supplicant
5376 : * @params: Parameters for %wpa_supplicant
5377 : * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
5378 : *
5379 : * This function is used to initialize %wpa_supplicant. After successful
5380 : * initialization, the returned data pointer can be used to add and remove
5381 : * network interfaces, and eventually, to deinitialize %wpa_supplicant.
5382 : */
5383 49 : struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
5384 : {
5385 : struct wpa_global *global;
5386 : int ret, i;
5387 :
5388 49 : if (params == NULL)
5389 0 : return NULL;
5390 :
5391 : #ifdef CONFIG_DRIVER_NDIS
5392 : {
5393 : void driver_ndis_init_ops(void);
5394 : driver_ndis_init_ops();
5395 : }
5396 : #endif /* CONFIG_DRIVER_NDIS */
5397 :
5398 : #ifndef CONFIG_NO_WPA_MSG
5399 49 : wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
5400 : #endif /* CONFIG_NO_WPA_MSG */
5401 :
5402 49 : if (params->wpa_debug_file_path)
5403 36 : wpa_debug_open_file(params->wpa_debug_file_path);
5404 : else
5405 13 : wpa_debug_setup_stdout();
5406 49 : if (params->wpa_debug_syslog)
5407 0 : wpa_debug_open_syslog();
5408 49 : if (params->wpa_debug_tracing) {
5409 1 : ret = wpa_debug_open_linux_tracing();
5410 1 : if (ret) {
5411 0 : wpa_printf(MSG_ERROR,
5412 : "Failed to enable trace logging");
5413 0 : return NULL;
5414 : }
5415 : }
5416 :
5417 49 : ret = eap_register_methods();
5418 49 : if (ret) {
5419 0 : wpa_printf(MSG_ERROR, "Failed to register EAP methods");
5420 0 : if (ret == -2)
5421 0 : wpa_printf(MSG_ERROR, "Two or more EAP methods used "
5422 : "the same EAP type.");
5423 0 : return NULL;
5424 : }
5425 :
5426 49 : global = os_zalloc(sizeof(*global));
5427 49 : if (global == NULL)
5428 0 : return NULL;
5429 49 : dl_list_init(&global->p2p_srv_bonjour);
5430 49 : dl_list_init(&global->p2p_srv_upnp);
5431 49 : global->params.daemonize = params->daemonize;
5432 49 : global->params.wait_for_monitor = params->wait_for_monitor;
5433 49 : global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
5434 49 : if (params->pid_file)
5435 12 : global->params.pid_file = os_strdup(params->pid_file);
5436 49 : if (params->ctrl_interface)
5437 35 : global->params.ctrl_interface =
5438 35 : os_strdup(params->ctrl_interface);
5439 49 : if (params->ctrl_interface_group)
5440 24 : global->params.ctrl_interface_group =
5441 24 : os_strdup(params->ctrl_interface_group);
5442 49 : if (params->override_driver)
5443 0 : global->params.override_driver =
5444 0 : os_strdup(params->override_driver);
5445 49 : if (params->override_ctrl_interface)
5446 0 : global->params.override_ctrl_interface =
5447 0 : os_strdup(params->override_ctrl_interface);
5448 : #ifdef CONFIG_MATCH_IFACE
5449 : global->params.match_iface_count = params->match_iface_count;
5450 : if (params->match_iface_count) {
5451 : global->params.match_ifaces =
5452 : os_calloc(params->match_iface_count,
5453 : sizeof(struct wpa_interface));
5454 : os_memcpy(global->params.match_ifaces,
5455 : params->match_ifaces,
5456 : params->match_iface_count *
5457 : sizeof(struct wpa_interface));
5458 : }
5459 : #endif /* CONFIG_MATCH_IFACE */
5460 : #ifdef CONFIG_P2P
5461 49 : if (params->conf_p2p_dev)
5462 0 : global->params.conf_p2p_dev =
5463 0 : os_strdup(params->conf_p2p_dev);
5464 : #endif /* CONFIG_P2P */
5465 49 : wpa_debug_level = global->params.wpa_debug_level =
5466 49 : params->wpa_debug_level;
5467 49 : wpa_debug_show_keys = global->params.wpa_debug_show_keys =
5468 49 : params->wpa_debug_show_keys;
5469 49 : wpa_debug_timestamp = global->params.wpa_debug_timestamp =
5470 49 : params->wpa_debug_timestamp;
5471 :
5472 49 : wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
5473 :
5474 49 : if (eloop_init()) {
5475 0 : wpa_printf(MSG_ERROR, "Failed to initialize event loop");
5476 0 : wpa_supplicant_deinit(global);
5477 0 : return NULL;
5478 : }
5479 :
5480 : random_init(params->entropy_file);
5481 :
5482 49 : global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
5483 49 : if (global->ctrl_iface == NULL) {
5484 0 : wpa_supplicant_deinit(global);
5485 0 : return NULL;
5486 : }
5487 :
5488 49 : if (wpas_notify_supplicant_initialized(global)) {
5489 0 : wpa_supplicant_deinit(global);
5490 0 : return NULL;
5491 : }
5492 :
5493 196 : for (i = 0; wpa_drivers[i]; i++)
5494 147 : global->drv_count++;
5495 49 : if (global->drv_count == 0) {
5496 0 : wpa_printf(MSG_ERROR, "No drivers enabled");
5497 0 : wpa_supplicant_deinit(global);
5498 0 : return NULL;
5499 : }
5500 49 : global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
5501 49 : if (global->drv_priv == NULL) {
5502 0 : wpa_supplicant_deinit(global);
5503 0 : return NULL;
5504 : }
5505 :
5506 : #ifdef CONFIG_WIFI_DISPLAY
5507 49 : if (wifi_display_init(global) < 0) {
5508 0 : wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
5509 0 : wpa_supplicant_deinit(global);
5510 0 : return NULL;
5511 : }
5512 : #endif /* CONFIG_WIFI_DISPLAY */
5513 :
5514 49 : eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5515 : wpas_periodic, global, NULL);
5516 :
5517 49 : return global;
5518 : }
5519 :
5520 :
5521 : /**
5522 : * wpa_supplicant_run - Run the %wpa_supplicant main event loop
5523 : * @global: Pointer to global data from wpa_supplicant_init()
5524 : * Returns: 0 after successful event loop run, -1 on failure
5525 : *
5526 : * This function starts the main event loop and continues running as long as
5527 : * there are any remaining events. In most cases, this function is running as
5528 : * long as the %wpa_supplicant process in still in use.
5529 : */
5530 27 : int wpa_supplicant_run(struct wpa_global *global)
5531 : {
5532 : struct wpa_supplicant *wpa_s;
5533 :
5534 30 : if (global->params.daemonize &&
5535 6 : (wpa_supplicant_daemon(global->params.pid_file) ||
5536 3 : eloop_sock_requeue()))
5537 0 : return -1;
5538 :
5539 : #ifdef CONFIG_MATCH_IFACE
5540 : if (wpa_supplicant_match_existing(global))
5541 : return -1;
5542 : #endif
5543 :
5544 27 : if (global->params.wait_for_monitor) {
5545 2 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
5546 1 : if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
5547 1 : wpa_supplicant_ctrl_iface_wait(
5548 : wpa_s->ctrl_iface);
5549 : }
5550 :
5551 27 : eloop_register_signal_terminate(wpa_supplicant_terminate, global);
5552 27 : eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
5553 :
5554 27 : eloop_run();
5555 :
5556 27 : return 0;
5557 : }
5558 :
5559 :
5560 : /**
5561 : * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
5562 : * @global: Pointer to global data from wpa_supplicant_init()
5563 : *
5564 : * This function is called to deinitialize %wpa_supplicant and to free all
5565 : * allocated resources. Remaining network interfaces will also be removed.
5566 : */
5567 49 : void wpa_supplicant_deinit(struct wpa_global *global)
5568 : {
5569 : int i;
5570 :
5571 49 : if (global == NULL)
5572 49 : return;
5573 :
5574 49 : eloop_cancel_timeout(wpas_periodic, global, NULL);
5575 :
5576 : #ifdef CONFIG_WIFI_DISPLAY
5577 49 : wifi_display_deinit(global);
5578 : #endif /* CONFIG_WIFI_DISPLAY */
5579 :
5580 130 : while (global->ifaces)
5581 32 : wpa_supplicant_remove_iface(global, global->ifaces, 1);
5582 :
5583 49 : if (global->ctrl_iface)
5584 49 : wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
5585 :
5586 49 : wpas_notify_supplicant_deinitialized(global);
5587 :
5588 49 : eap_peer_unregister_methods();
5589 : #ifdef CONFIG_AP
5590 49 : eap_server_unregister_methods();
5591 : #endif /* CONFIG_AP */
5592 :
5593 196 : for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
5594 147 : if (!global->drv_priv[i])
5595 111 : continue;
5596 36 : wpa_drivers[i]->global_deinit(global->drv_priv[i]);
5597 : }
5598 49 : os_free(global->drv_priv);
5599 :
5600 : random_deinit();
5601 :
5602 49 : eloop_destroy();
5603 :
5604 49 : if (global->params.pid_file) {
5605 12 : os_daemonize_terminate(global->params.pid_file);
5606 12 : os_free(global->params.pid_file);
5607 : }
5608 49 : os_free(global->params.ctrl_interface);
5609 49 : os_free(global->params.ctrl_interface_group);
5610 49 : os_free(global->params.override_driver);
5611 49 : os_free(global->params.override_ctrl_interface);
5612 : #ifdef CONFIG_MATCH_IFACE
5613 : os_free(global->params.match_ifaces);
5614 : #endif /* CONFIG_MATCH_IFACE */
5615 : #ifdef CONFIG_P2P
5616 49 : os_free(global->params.conf_p2p_dev);
5617 : #endif /* CONFIG_P2P */
5618 :
5619 49 : os_free(global->p2p_disallow_freq.range);
5620 49 : os_free(global->p2p_go_avoid_freq.range);
5621 49 : os_free(global->add_psk);
5622 :
5623 49 : os_free(global);
5624 49 : wpa_debug_close_syslog();
5625 49 : wpa_debug_close_file();
5626 49 : wpa_debug_close_linux_tracing();
5627 : }
5628 :
5629 :
5630 7124 : void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
5631 : {
5632 7132 : if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5633 15 : wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5634 : char country[3];
5635 7 : country[0] = wpa_s->conf->country[0];
5636 7 : country[1] = wpa_s->conf->country[1];
5637 7 : country[2] = '\0';
5638 7 : if (wpa_drv_set_country(wpa_s, country) < 0) {
5639 0 : wpa_printf(MSG_ERROR, "Failed to set country code "
5640 : "'%s'", country);
5641 : }
5642 : }
5643 :
5644 7124 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
5645 8 : wpas_init_ext_pw(wpa_s);
5646 :
5647 7124 : if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
5648 8 : wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5649 :
5650 : #ifdef CONFIG_WPS
5651 7124 : wpas_wps_update_config(wpa_s);
5652 : #endif /* CONFIG_WPS */
5653 7124 : wpas_p2p_update_config(wpa_s);
5654 7124 : wpa_s->conf->changed_parameters = 0;
5655 7124 : }
5656 :
5657 :
5658 59 : void add_freq(int *freqs, int *num_freqs, int freq)
5659 : {
5660 : int i;
5661 :
5662 106 : for (i = 0; i < *num_freqs; i++) {
5663 50 : if (freqs[i] == freq)
5664 62 : return;
5665 : }
5666 :
5667 56 : freqs[*num_freqs] = freq;
5668 56 : (*num_freqs)++;
5669 : }
5670 :
5671 :
5672 525 : static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
5673 : {
5674 : struct wpa_bss *bss, *cbss;
5675 525 : const int max_freqs = 10;
5676 : int *freqs;
5677 525 : int num_freqs = 0;
5678 :
5679 525 : freqs = os_calloc(max_freqs + 1, sizeof(int));
5680 525 : if (freqs == NULL)
5681 0 : return NULL;
5682 :
5683 525 : cbss = wpa_s->current_bss;
5684 :
5685 1109 : dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
5686 584 : if (bss == cbss)
5687 525 : continue;
5688 87 : if (bss->ssid_len == cbss->ssid_len &&
5689 54 : os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
5690 26 : wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
5691 24 : add_freq(freqs, &num_freqs, bss->freq);
5692 24 : if (num_freqs == max_freqs)
5693 0 : break;
5694 : }
5695 : }
5696 :
5697 525 : if (num_freqs == 0) {
5698 501 : os_free(freqs);
5699 501 : freqs = NULL;
5700 : }
5701 :
5702 525 : return freqs;
5703 : }
5704 :
5705 :
5706 3809 : void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
5707 : {
5708 : int timeout;
5709 : int count;
5710 3809 : int *freqs = NULL;
5711 :
5712 3809 : wpas_connect_work_done(wpa_s);
5713 :
5714 : /*
5715 : * Remove possible authentication timeout since the connection failed.
5716 : */
5717 3809 : eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
5718 :
5719 : /*
5720 : * There is no point in blacklisting the AP if this event is
5721 : * generated based on local request to disconnect.
5722 : */
5723 3809 : if (wpa_s->own_disconnect_req) {
5724 2278 : wpa_s->own_disconnect_req = 0;
5725 2278 : wpa_dbg(wpa_s, MSG_DEBUG,
5726 : "Ignore connection failure due to local request to disconnect");
5727 2278 : return;
5728 : }
5729 1531 : if (wpa_s->disconnected) {
5730 970 : wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
5731 : "indication since interface has been put into "
5732 : "disconnected state");
5733 970 : return;
5734 : }
5735 :
5736 : /*
5737 : * Add the failed BSSID into the blacklist and speed up next scan
5738 : * attempt if there could be other APs that could accept association.
5739 : * The current blacklist count indicates how many times we have tried
5740 : * connecting to this AP and multiple attempts mean that other APs are
5741 : * either not available or has already been tried, so that we can start
5742 : * increasing the delay here to avoid constant scanning.
5743 : */
5744 561 : count = wpa_blacklist_add(wpa_s, bssid);
5745 561 : if (count == 1 && wpa_s->current_bss) {
5746 : /*
5747 : * This BSS was not in the blacklist before. If there is
5748 : * another BSS available for the same ESS, we should try that
5749 : * next. Otherwise, we may as well try this one once more
5750 : * before allowing other, likely worse, ESSes to be considered.
5751 : */
5752 525 : freqs = get_bss_freqs_in_ess(wpa_s);
5753 525 : if (freqs) {
5754 24 : wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
5755 : "has been seen; try it next");
5756 24 : wpa_blacklist_add(wpa_s, bssid);
5757 : /*
5758 : * On the next scan, go through only the known channels
5759 : * used in this ESS based on previous scans to speed up
5760 : * common load balancing use case.
5761 : */
5762 24 : os_free(wpa_s->next_scan_freqs);
5763 24 : wpa_s->next_scan_freqs = freqs;
5764 : }
5765 : }
5766 :
5767 : /*
5768 : * Add previous failure count in case the temporary blacklist was
5769 : * cleared due to no other BSSes being available.
5770 : */
5771 561 : count += wpa_s->extra_blacklist_count;
5772 :
5773 561 : if (count > 3 && wpa_s->current_ssid) {
5774 132 : wpa_printf(MSG_DEBUG, "Continuous association failures - "
5775 : "consider temporary network disabling");
5776 132 : wpas_auth_failed(wpa_s, "CONN_FAILED");
5777 : }
5778 :
5779 561 : switch (count) {
5780 : case 1:
5781 328 : timeout = 100;
5782 328 : break;
5783 : case 2:
5784 70 : timeout = 500;
5785 70 : break;
5786 : case 3:
5787 31 : timeout = 1000;
5788 31 : break;
5789 : case 4:
5790 20 : timeout = 5000;
5791 20 : break;
5792 : default:
5793 112 : timeout = 10000;
5794 112 : break;
5795 : }
5796 :
5797 561 : wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
5798 : "ms", count, timeout);
5799 :
5800 : /*
5801 : * TODO: if more than one possible AP is available in scan results,
5802 : * could try the other ones before requesting a new scan.
5803 : */
5804 561 : wpa_supplicant_req_scan(wpa_s, timeout / 1000,
5805 561 : 1000 * (timeout % 1000));
5806 : }
5807 :
5808 :
5809 3939 : int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
5810 : {
5811 7862 : return wpa_s->conf->ap_scan == 2 ||
5812 3923 : (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
5813 : }
5814 :
5815 :
5816 : #if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
5817 85 : int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
5818 : struct wpa_ssid *ssid,
5819 : const char *field,
5820 : const char *value)
5821 : {
5822 : #ifdef IEEE8021X_EAPOL
5823 85 : struct eap_peer_config *eap = &ssid->eap;
5824 :
5825 85 : wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
5826 85 : wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
5827 : (const u8 *) value, os_strlen(value));
5828 :
5829 85 : switch (wpa_supplicant_ctrl_req_from_string(field)) {
5830 : case WPA_CTRL_REQ_EAP_IDENTITY:
5831 7 : os_free(eap->identity);
5832 7 : eap->identity = (u8 *) os_strdup(value);
5833 7 : eap->identity_len = os_strlen(value);
5834 7 : eap->pending_req_identity = 0;
5835 7 : if (ssid == wpa_s->current_ssid)
5836 5 : wpa_s->reassociate = 1;
5837 7 : break;
5838 : case WPA_CTRL_REQ_EAP_PASSWORD:
5839 9 : bin_clear_free(eap->password, eap->password_len);
5840 9 : eap->password = (u8 *) os_strdup(value);
5841 9 : eap->password_len = os_strlen(value);
5842 9 : eap->pending_req_password = 0;
5843 9 : if (ssid == wpa_s->current_ssid)
5844 7 : wpa_s->reassociate = 1;
5845 9 : break;
5846 : case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
5847 14 : bin_clear_free(eap->new_password, eap->new_password_len);
5848 14 : eap->new_password = (u8 *) os_strdup(value);
5849 14 : eap->new_password_len = os_strlen(value);
5850 14 : eap->pending_req_new_password = 0;
5851 14 : if (ssid == wpa_s->current_ssid)
5852 12 : wpa_s->reassociate = 1;
5853 14 : break;
5854 : case WPA_CTRL_REQ_EAP_PIN:
5855 2 : str_clear_free(eap->pin);
5856 2 : eap->pin = os_strdup(value);
5857 2 : eap->pending_req_pin = 0;
5858 2 : if (ssid == wpa_s->current_ssid)
5859 0 : wpa_s->reassociate = 1;
5860 2 : break;
5861 : case WPA_CTRL_REQ_EAP_OTP:
5862 4 : bin_clear_free(eap->otp, eap->otp_len);
5863 4 : eap->otp = (u8 *) os_strdup(value);
5864 4 : eap->otp_len = os_strlen(value);
5865 4 : os_free(eap->pending_req_otp);
5866 4 : eap->pending_req_otp = NULL;
5867 4 : eap->pending_req_otp_len = 0;
5868 4 : break;
5869 : case WPA_CTRL_REQ_EAP_PASSPHRASE:
5870 3 : str_clear_free(eap->private_key_passwd);
5871 3 : eap->private_key_passwd = os_strdup(value);
5872 3 : eap->pending_req_passphrase = 0;
5873 3 : if (ssid == wpa_s->current_ssid)
5874 1 : wpa_s->reassociate = 1;
5875 3 : break;
5876 : case WPA_CTRL_REQ_SIM:
5877 34 : str_clear_free(eap->external_sim_resp);
5878 34 : eap->external_sim_resp = os_strdup(value);
5879 34 : break;
5880 : case WPA_CTRL_REQ_PSK_PASSPHRASE:
5881 3 : if (wpa_config_set(ssid, "psk", value, 0) < 0)
5882 0 : return -1;
5883 3 : ssid->mem_only_psk = 1;
5884 3 : if (ssid->passphrase)
5885 2 : wpa_config_update_psk(ssid);
5886 3 : if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
5887 3 : wpa_supplicant_req_scan(wpa_s, 0, 0);
5888 3 : break;
5889 : case WPA_CTRL_REQ_EXT_CERT_CHECK:
5890 8 : if (eap->pending_ext_cert_check != PENDING_CHECK)
5891 0 : return -1;
5892 8 : if (os_strcmp(value, "good") == 0)
5893 4 : eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
5894 4 : else if (os_strcmp(value, "bad") == 0)
5895 4 : eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
5896 : else
5897 0 : return -1;
5898 8 : break;
5899 : default:
5900 1 : wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
5901 1 : return -1;
5902 : }
5903 :
5904 84 : return 0;
5905 : #else /* IEEE8021X_EAPOL */
5906 : wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
5907 : return -1;
5908 : #endif /* IEEE8021X_EAPOL */
5909 : }
5910 : #endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
5911 :
5912 :
5913 27604 : int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5914 : {
5915 : int i;
5916 : unsigned int drv_enc;
5917 :
5918 27604 : if (wpa_s->p2p_mgmt)
5919 0 : return 1; /* no normal network profiles on p2p_mgmt interface */
5920 :
5921 27604 : if (ssid == NULL)
5922 0 : return 1;
5923 :
5924 27604 : if (ssid->disabled)
5925 5787 : return 1;
5926 :
5927 21817 : if (wpa_s->drv_capa_known)
5928 21817 : drv_enc = wpa_s->drv_enc;
5929 : else
5930 0 : drv_enc = (unsigned int) -1;
5931 :
5932 109085 : for (i = 0; i < NUM_WEP_KEYS; i++) {
5933 87268 : size_t len = ssid->wep_key_len[i];
5934 87268 : if (len == 0)
5935 87087 : continue;
5936 181 : if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
5937 92 : continue;
5938 89 : if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5939 89 : continue;
5940 0 : if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5941 0 : continue;
5942 0 : return 1; /* invalid WEP key */
5943 : }
5944 :
5945 21869 : if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
5946 78 : (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
5947 18 : !ssid->mem_only_psk)
5948 0 : return 1;
5949 :
5950 21817 : return 0;
5951 : }
5952 :
5953 :
5954 16804 : int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5955 : {
5956 : #ifdef CONFIG_IEEE80211W
5957 16804 : if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5958 15027 : if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5959 12 : !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5960 : /*
5961 : * Driver does not support BIP -- ignore pmf=1 default
5962 : * since the connection with PMF would fail and the
5963 : * configuration does not require PMF to be enabled.
5964 : */
5965 0 : return NO_MGMT_FRAME_PROTECTION;
5966 : }
5967 :
5968 30030 : if (ssid &&
5969 15015 : (ssid->key_mgmt &
5970 : ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
5971 : WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
5972 : /*
5973 : * Do not use the default PMF value for non-RSN networks
5974 : * since PMF is available only with RSN and pmf=2
5975 : * configuration would otherwise prevent connections to
5976 : * all open networks.
5977 : */
5978 2210 : return NO_MGMT_FRAME_PROTECTION;
5979 : }
5980 :
5981 12805 : return wpa_s->conf->pmf;
5982 : }
5983 :
5984 1789 : return ssid->ieee80211w;
5985 : #else /* CONFIG_IEEE80211W */
5986 : return NO_MGMT_FRAME_PROTECTION;
5987 : #endif /* CONFIG_IEEE80211W */
5988 : }
5989 :
5990 :
5991 59 : int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
5992 : {
5993 59 : if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
5994 0 : return 1;
5995 59 : if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
5996 0 : return 0;
5997 59 : return -1;
5998 : }
5999 :
6000 :
6001 772 : void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
6002 : {
6003 772 : struct wpa_ssid *ssid = wpa_s->current_ssid;
6004 : int dur;
6005 : struct os_reltime now;
6006 :
6007 772 : if (ssid == NULL) {
6008 62 : wpa_printf(MSG_DEBUG, "Authentication failure but no known "
6009 : "SSID block");
6010 62 : return;
6011 : }
6012 :
6013 710 : if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
6014 42 : return;
6015 :
6016 668 : ssid->auth_failures++;
6017 :
6018 : #ifdef CONFIG_P2P
6019 672 : if (ssid->p2p_group &&
6020 8 : (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
6021 : /*
6022 : * Skip the wait time since there is a short timeout on the
6023 : * connection to a P2P group.
6024 : */
6025 4 : return;
6026 : }
6027 : #endif /* CONFIG_P2P */
6028 :
6029 664 : if (ssid->auth_failures > 50)
6030 0 : dur = 300;
6031 664 : else if (ssid->auth_failures > 10)
6032 0 : dur = 120;
6033 664 : else if (ssid->auth_failures > 5)
6034 0 : dur = 90;
6035 664 : else if (ssid->auth_failures > 3)
6036 0 : dur = 60;
6037 664 : else if (ssid->auth_failures > 2)
6038 0 : dur = 30;
6039 664 : else if (ssid->auth_failures > 1)
6040 47 : dur = 20;
6041 : else
6042 617 : dur = 10;
6043 :
6044 711 : if (ssid->auth_failures > 1 &&
6045 47 : wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
6046 47 : dur += os_random() % (ssid->auth_failures * 10);
6047 :
6048 664 : os_get_reltime(&now);
6049 664 : if (now.sec + dur <= ssid->disabled_until.sec)
6050 0 : return;
6051 :
6052 664 : ssid->disabled_until.sec = now.sec + dur;
6053 :
6054 1328 : wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
6055 : "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
6056 664 : ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
6057 : ssid->auth_failures, dur, reason);
6058 : }
6059 :
6060 :
6061 11073 : void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
6062 : struct wpa_ssid *ssid, int clear_failures)
6063 : {
6064 11073 : if (ssid == NULL)
6065 11073 : return;
6066 :
6067 11073 : if (ssid->disabled_until.sec) {
6068 94 : wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
6069 : "id=%d ssid=\"%s\"",
6070 47 : ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
6071 : }
6072 11073 : ssid->disabled_until.sec = 0;
6073 11073 : ssid->disabled_until.usec = 0;
6074 11073 : if (clear_failures)
6075 7648 : ssid->auth_failures = 0;
6076 : }
6077 :
6078 :
6079 7351 : int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
6080 : {
6081 : size_t i;
6082 :
6083 7351 : if (wpa_s->disallow_aps_bssid == NULL)
6084 7341 : return 0;
6085 :
6086 13 : for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
6087 11 : if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
6088 : bssid, ETH_ALEN) == 0)
6089 8 : return 1;
6090 : }
6091 :
6092 2 : return 0;
6093 : }
6094 :
6095 :
6096 7343 : int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
6097 : size_t ssid_len)
6098 : {
6099 : size_t i;
6100 :
6101 7343 : if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
6102 7337 : return 0;
6103 :
6104 6 : for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
6105 6 : struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
6106 12 : if (ssid_len == s->ssid_len &&
6107 6 : os_memcmp(ssid, s->ssid, ssid_len) == 0)
6108 6 : return 1;
6109 : }
6110 :
6111 0 : return 0;
6112 : }
6113 :
6114 :
6115 : /**
6116 : * wpas_request_connection - Request a new connection
6117 : * @wpa_s: Pointer to the network interface
6118 : *
6119 : * This function is used to request a new connection to be found. It will mark
6120 : * the interface to allow reassociation and request a new scan to find a
6121 : * suitable network to connect to.
6122 : */
6123 145 : void wpas_request_connection(struct wpa_supplicant *wpa_s)
6124 : {
6125 145 : wpa_s->normal_scans = 0;
6126 145 : wpa_s->scan_req = NORMAL_SCAN_REQ;
6127 145 : wpa_supplicant_reinit_autoscan(wpa_s);
6128 145 : wpa_s->extra_blacklist_count = 0;
6129 145 : wpa_s->disconnected = 0;
6130 145 : wpa_s->reassociate = 1;
6131 :
6132 145 : if (wpa_supplicant_fast_associate(wpa_s) != 1)
6133 13 : wpa_supplicant_req_scan(wpa_s, 0, 0);
6134 : else
6135 132 : wpa_s->reattach = 0;
6136 145 : }
6137 :
6138 :
6139 : /**
6140 : * wpas_request_disconnection - Request disconnection
6141 : * @wpa_s: Pointer to the network interface
6142 : *
6143 : * This function is used to request disconnection from the currently connected
6144 : * network. This will stop any ongoing scans and initiate deauthentication.
6145 : */
6146 747 : void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
6147 : {
6148 : #ifdef CONFIG_SME
6149 747 : wpa_s->sme.prev_bssid_set = 0;
6150 : #endif /* CONFIG_SME */
6151 747 : wpa_s->reassociate = 0;
6152 747 : wpa_s->disconnected = 1;
6153 747 : wpa_supplicant_cancel_sched_scan(wpa_s);
6154 747 : wpa_supplicant_cancel_scan(wpa_s);
6155 747 : wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6156 747 : eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
6157 747 : }
6158 :
6159 :
6160 56499 : void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
6161 : struct wpa_used_freq_data *freqs_data,
6162 : unsigned int len)
6163 : {
6164 : unsigned int i;
6165 :
6166 56499 : wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
6167 : len, title);
6168 72337 : for (i = 0; i < len; i++) {
6169 15838 : struct wpa_used_freq_data *cur = &freqs_data[i];
6170 15838 : wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
6171 : i, cur->freq, cur->flags);
6172 : }
6173 56499 : }
6174 :
6175 :
6176 : /*
6177 : * Find the operating frequencies of any of the virtual interfaces that
6178 : * are using the same radio as the current interface, and in addition, get
6179 : * information about the interface types that are using the frequency.
6180 : */
6181 55934 : int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
6182 : struct wpa_used_freq_data *freqs_data,
6183 : unsigned int len)
6184 : {
6185 : struct wpa_supplicant *ifs;
6186 : u8 bssid[ETH_ALEN];
6187 : int freq;
6188 55934 : unsigned int idx = 0, i;
6189 :
6190 55934 : wpa_dbg(wpa_s, MSG_DEBUG,
6191 : "Determining shared radio frequencies (max len %u)", len);
6192 55934 : os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
6193 :
6194 113483 : dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
6195 : radio_list) {
6196 58323 : if (idx == len)
6197 774 : break;
6198 :
6199 57549 : if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
6200 37552 : continue;
6201 :
6202 39930 : if (ifs->current_ssid->mode == WPAS_MODE_AP ||
6203 38909 : ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
6204 18976 : ifs->current_ssid->mode == WPAS_MODE_MESH)
6205 1273 : freq = ifs->current_ssid->frequency;
6206 18724 : else if (wpa_drv_get_bssid(ifs, bssid) == 0)
6207 14514 : freq = ifs->assoc_freq;
6208 : else
6209 4210 : continue;
6210 :
6211 : /* Hold only distinct freqs */
6212 15830 : for (i = 0; i < idx; i++)
6213 43 : if (freqs_data[i].freq == freq)
6214 0 : break;
6215 :
6216 15787 : if (i == idx)
6217 15787 : freqs_data[idx++].freq = freq;
6218 :
6219 15787 : if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
6220 28882 : freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
6221 14441 : WPA_FREQ_USED_BY_P2P_CLIENT :
6222 : WPA_FREQ_USED_BY_INFRA_STATION;
6223 : }
6224 : }
6225 :
6226 55934 : dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
6227 55934 : return idx;
6228 : }
6229 :
6230 :
6231 : /*
6232 : * Find the operating frequencies of any of the virtual interfaces that
6233 : * are using the same radio as the current interface.
6234 : */
6235 5803 : int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
6236 : int *freq_array, unsigned int len)
6237 : {
6238 : struct wpa_used_freq_data *freqs_data;
6239 : int num, i;
6240 :
6241 5803 : os_memset(freq_array, 0, sizeof(int) * len);
6242 :
6243 5803 : freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
6244 5803 : if (!freqs_data)
6245 0 : return -1;
6246 :
6247 5803 : num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
6248 6219 : for (i = 0; i < num; i++)
6249 416 : freq_array[i] = freqs_data[i].freq;
6250 :
6251 5803 : os_free(freqs_data);
6252 :
6253 5803 : return num;
6254 : }
6255 :
6256 :
6257 0 : static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
6258 : {
6259 0 : struct rrm_data *rrm = data;
6260 :
6261 0 : if (!rrm->notify_neighbor_rep) {
6262 0 : wpa_printf(MSG_ERROR,
6263 : "RRM: Unexpected neighbor report timeout");
6264 0 : return;
6265 : }
6266 :
6267 0 : wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
6268 0 : rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
6269 :
6270 0 : rrm->notify_neighbor_rep = NULL;
6271 0 : rrm->neighbor_rep_cb_ctx = NULL;
6272 : }
6273 :
6274 :
6275 : /*
6276 : * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
6277 : * @wpa_s: Pointer to wpa_supplicant
6278 : */
6279 11003 : void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
6280 : {
6281 11003 : wpa_s->rrm.rrm_used = 0;
6282 :
6283 11003 : eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6284 : NULL);
6285 11003 : if (wpa_s->rrm.notify_neighbor_rep)
6286 0 : wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
6287 11003 : wpa_s->rrm.next_neighbor_rep_token = 1;
6288 11003 : }
6289 :
6290 :
6291 : /*
6292 : * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
6293 : * @wpa_s: Pointer to wpa_supplicant
6294 : * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
6295 : * @report_len: Length of neighbor report buffer
6296 : */
6297 17 : void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
6298 : const u8 *report, size_t report_len)
6299 : {
6300 : struct wpabuf *neighbor_rep;
6301 :
6302 17 : wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
6303 17 : if (report_len < 1)
6304 0 : return;
6305 :
6306 17 : if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
6307 0 : wpa_printf(MSG_DEBUG,
6308 : "RRM: Discarding neighbor report with token %d (expected %d)",
6309 0 : report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
6310 0 : return;
6311 : }
6312 :
6313 17 : eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6314 : NULL);
6315 :
6316 17 : if (!wpa_s->rrm.notify_neighbor_rep) {
6317 0 : wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
6318 0 : return;
6319 : }
6320 :
6321 : /* skipping the first byte, which is only an id (dialog token) */
6322 17 : neighbor_rep = wpabuf_alloc(report_len - 1);
6323 17 : if (neighbor_rep == NULL)
6324 0 : return;
6325 17 : wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
6326 17 : wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
6327 17 : report[0]);
6328 17 : wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
6329 : neighbor_rep);
6330 17 : wpa_s->rrm.notify_neighbor_rep = NULL;
6331 17 : wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
6332 : }
6333 :
6334 :
6335 : #if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
6336 : /* Workaround different, undefined for Windows, error codes used here */
6337 : #define ENOTCONN -1
6338 : #define EOPNOTSUPP -1
6339 : #define ECANCELED -1
6340 : #endif
6341 :
6342 : /* Measurement Request element + Location Subject + Maximum Age subelement */
6343 : #define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
6344 : /* Measurement Request element + Location Civic Request */
6345 : #define MEASURE_REQUEST_CIVIC_LEN (3 + 5)
6346 :
6347 :
6348 : /**
6349 : * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
6350 : * @wpa_s: Pointer to wpa_supplicant
6351 : * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
6352 : * is sent in the request.
6353 : * @lci: if set, neighbor request will include LCI request
6354 : * @civic: if set, neighbor request will include civic location request
6355 : * @cb: Callback function to be called once the requested report arrives, or
6356 : * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
6357 : * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
6358 : * the requester's responsibility to free it.
6359 : * In the latter case NULL will be sent in 'neighbor_rep'.
6360 : * @cb_ctx: Context value to send the callback function
6361 : * Returns: 0 in case of success, negative error code otherwise
6362 : *
6363 : * In case there is a previous request which has not been answered yet, the
6364 : * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
6365 : * Request must contain a callback function.
6366 : */
6367 19 : int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
6368 : const struct wpa_ssid_value *ssid,
6369 : int lci, int civic,
6370 : void (*cb)(void *ctx,
6371 : struct wpabuf *neighbor_rep),
6372 : void *cb_ctx)
6373 : {
6374 : struct wpabuf *buf;
6375 : const u8 *rrm_ie;
6376 :
6377 19 : if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
6378 0 : wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
6379 0 : return -ENOTCONN;
6380 : }
6381 :
6382 19 : if (!wpa_s->rrm.rrm_used) {
6383 2 : wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
6384 2 : return -EOPNOTSUPP;
6385 : }
6386 :
6387 17 : rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
6388 : WLAN_EID_RRM_ENABLED_CAPABILITIES);
6389 34 : if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
6390 17 : !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
6391 0 : wpa_printf(MSG_DEBUG,
6392 : "RRM: No network support for Neighbor Report.");
6393 0 : return -EOPNOTSUPP;
6394 : }
6395 :
6396 17 : if (!cb) {
6397 0 : wpa_printf(MSG_DEBUG,
6398 : "RRM: Neighbor Report request must provide a callback.");
6399 0 : return -EINVAL;
6400 : }
6401 :
6402 : /* Refuse if there's a live request */
6403 17 : if (wpa_s->rrm.notify_neighbor_rep) {
6404 0 : wpa_printf(MSG_DEBUG,
6405 : "RRM: Currently handling previous Neighbor Report.");
6406 0 : return -EBUSY;
6407 : }
6408 :
6409 : /* 3 = action category + action code + dialog token */
6410 17 : buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
6411 : (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
6412 : (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
6413 17 : if (buf == NULL) {
6414 0 : wpa_printf(MSG_DEBUG,
6415 : "RRM: Failed to allocate Neighbor Report Request");
6416 0 : return -ENOMEM;
6417 : }
6418 :
6419 31 : wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
6420 14 : (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
6421 17 : wpa_s->rrm.next_neighbor_rep_token);
6422 :
6423 17 : wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6424 17 : wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
6425 17 : wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
6426 17 : if (ssid) {
6427 14 : wpabuf_put_u8(buf, WLAN_EID_SSID);
6428 14 : wpabuf_put_u8(buf, ssid->ssid_len);
6429 14 : wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
6430 : }
6431 :
6432 17 : if (lci) {
6433 : /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6434 9 : wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6435 9 : wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);
6436 :
6437 : /*
6438 : * Measurement token; nonzero number that is unique among the
6439 : * Measurement Request elements in a particular frame.
6440 : */
6441 9 : wpabuf_put_u8(buf, 1); /* Measurement Token */
6442 :
6443 : /*
6444 : * Parallel, Enable, Request, and Report bits are 0, Duration is
6445 : * reserved.
6446 : */
6447 9 : wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6448 9 : wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */
6449 :
6450 : /* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */
6451 : /* Location Subject */
6452 9 : wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6453 :
6454 : /* Optional Subelements */
6455 : /*
6456 : * IEEE P802.11-REVmc/D5.0 Figure 9-170
6457 : * The Maximum Age subelement is required, otherwise the AP can
6458 : * send only data that was determined after receiving the
6459 : * request. Setting it here to unlimited age.
6460 : */
6461 9 : wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE);
6462 9 : wpabuf_put_u8(buf, 2);
6463 9 : wpabuf_put_le16(buf, 0xffff);
6464 : }
6465 :
6466 17 : if (civic) {
6467 : /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6468 8 : wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6469 8 : wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);
6470 :
6471 : /*
6472 : * Measurement token; nonzero number that is unique among the
6473 : * Measurement Request elements in a particular frame.
6474 : */
6475 8 : wpabuf_put_u8(buf, 2); /* Measurement Token */
6476 :
6477 : /*
6478 : * Parallel, Enable, Request, and Report bits are 0, Duration is
6479 : * reserved.
6480 : */
6481 8 : wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6482 : /* Measurement Type */
6483 8 : wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);
6484 :
6485 : /* IEEE P802.11-REVmc/D5.0 9.4.2.21.14:
6486 : * Location Civic request */
6487 : /* Location Subject */
6488 8 : wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6489 8 : wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */
6490 : /* Location Service Interval Units: Seconds */
6491 8 : wpabuf_put_u8(buf, 0);
6492 : /* Location Service Interval: 0 - Only one report is requested
6493 : */
6494 8 : wpabuf_put_le16(buf, 0);
6495 : /* No optional subelements */
6496 : }
6497 :
6498 17 : wpa_s->rrm.next_neighbor_rep_token++;
6499 :
6500 34 : if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
6501 17 : wpa_s->own_addr, wpa_s->bssid,
6502 17 : wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
6503 0 : wpa_printf(MSG_DEBUG,
6504 : "RRM: Failed to send Neighbor Report Request");
6505 0 : wpabuf_free(buf);
6506 0 : return -ECANCELED;
6507 : }
6508 :
6509 17 : wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
6510 17 : wpa_s->rrm.notify_neighbor_rep = cb;
6511 17 : eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
6512 : wpas_rrm_neighbor_rep_timeout_handler,
6513 17 : &wpa_s->rrm, NULL);
6514 :
6515 17 : wpabuf_free(buf);
6516 17 : return 0;
6517 : }
6518 :
6519 :
6520 1 : static struct wpabuf * wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s,
6521 : const u8 *request, size_t len,
6522 : struct wpabuf *report)
6523 : {
6524 : u8 token, type, subject;
6525 1 : u16 max_age = 0;
6526 : struct os_reltime t, diff;
6527 : unsigned long diff_l;
6528 : u8 *ptoken;
6529 : const u8 *subelem;
6530 :
6531 1 : if (!wpa_s->lci || len < 3 + 4)
6532 0 : return report;
6533 :
6534 1 : token = *request++;
6535 : /* Measurement request mode isn't used */
6536 1 : request++;
6537 1 : type = *request++;
6538 1 : subject = *request++;
6539 :
6540 1 : wpa_printf(MSG_DEBUG,
6541 : "Measurement request token %u type %u location subject %u",
6542 : token, type, subject);
6543 :
6544 1 : if (type != MEASURE_TYPE_LCI || subject != LOCATION_SUBJECT_REMOTE) {
6545 0 : wpa_printf(MSG_INFO,
6546 : "Not building LCI report - bad type or location subject");
6547 0 : return report;
6548 : }
6549 :
6550 : /* Subelements are formatted exactly like elements */
6551 1 : subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE);
6552 1 : if (subelem && subelem[1] == 2)
6553 1 : max_age = WPA_GET_LE16(subelem + 2);
6554 :
6555 1 : if (os_get_reltime(&t))
6556 0 : return report;
6557 :
6558 1 : os_reltime_sub(&t, &wpa_s->lci_time, &diff);
6559 : /* LCI age is calculated in 10th of a second units. */
6560 1 : diff_l = diff.sec * 10 + diff.usec / 100000;
6561 :
6562 1 : if (max_age != 0xffff && max_age < diff_l)
6563 0 : return report;
6564 :
6565 1 : if (wpabuf_resize(&report, 2 + wpabuf_len(wpa_s->lci)))
6566 0 : return report;
6567 :
6568 1 : wpabuf_put_u8(report, WLAN_EID_MEASURE_REPORT);
6569 1 : wpabuf_put_u8(report, wpabuf_len(wpa_s->lci));
6570 : /* We'll override user's measurement token */
6571 1 : ptoken = wpabuf_put(report, 0);
6572 1 : wpabuf_put_buf(report, wpa_s->lci);
6573 1 : *ptoken = token;
6574 :
6575 1 : return report;
6576 : }
6577 :
6578 :
6579 1 : void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
6580 : const u8 *src,
6581 : const u8 *frame, size_t len)
6582 : {
6583 : struct wpabuf *buf, *report;
6584 : u8 token;
6585 : const u8 *ie, *end;
6586 :
6587 1 : if (wpa_s->wpa_state != WPA_COMPLETED) {
6588 0 : wpa_printf(MSG_INFO,
6589 : "RRM: Ignoring radio measurement request: Not associated");
6590 0 : return;
6591 : }
6592 :
6593 1 : if (!wpa_s->rrm.rrm_used) {
6594 0 : wpa_printf(MSG_INFO,
6595 : "RRM: Ignoring radio measurement request: Not RRM network");
6596 0 : return;
6597 : }
6598 :
6599 1 : if (len < 3) {
6600 0 : wpa_printf(MSG_INFO,
6601 : "RRM: Ignoring too short radio measurement request");
6602 0 : return;
6603 : }
6604 :
6605 1 : end = frame + len;
6606 :
6607 1 : token = *frame++;
6608 :
6609 : /* Ignore number of repetitions because it's not used in LCI request */
6610 1 : frame += 2;
6611 :
6612 1 : report = NULL;
6613 4 : while ((ie = get_ie(frame, end - frame, WLAN_EID_MEASURE_REQUEST)) &&
6614 1 : ie[1] >= 3) {
6615 : u8 msmt_type;
6616 :
6617 1 : msmt_type = ie[4];
6618 1 : wpa_printf(MSG_DEBUG, "RRM request %d", msmt_type);
6619 :
6620 1 : switch (msmt_type) {
6621 : case MEASURE_TYPE_LCI:
6622 1 : report = wpas_rrm_build_lci_report(wpa_s, ie + 2, ie[1],
6623 : report);
6624 1 : break;
6625 : default:
6626 0 : wpa_printf(MSG_INFO,
6627 : "RRM: Unsupported radio measurement request %d",
6628 : msmt_type);
6629 0 : break;
6630 : }
6631 :
6632 1 : frame = ie + ie[1] + 2;
6633 : }
6634 :
6635 1 : if (!report)
6636 0 : return;
6637 :
6638 1 : buf = wpabuf_alloc(3 + wpabuf_len(report));
6639 1 : if (!buf) {
6640 0 : wpabuf_free(report);
6641 0 : return;
6642 : }
6643 :
6644 1 : wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6645 1 : wpabuf_put_u8(buf, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
6646 1 : wpabuf_put_u8(buf, token);
6647 :
6648 1 : wpabuf_put_buf(buf, report);
6649 1 : wpabuf_free(report);
6650 :
6651 2 : if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6652 1 : wpa_s->own_addr, wpa_s->bssid,
6653 1 : wpabuf_head(buf), wpabuf_len(buf), 0)) {
6654 0 : wpa_printf(MSG_ERROR,
6655 : "RRM: Radio measurement report failed: Sending Action frame failed");
6656 : }
6657 1 : wpabuf_free(buf);
6658 : }
6659 :
6660 :
6661 0 : void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
6662 : const u8 *src,
6663 : const u8 *frame, size_t len,
6664 : int rssi)
6665 : {
6666 : struct wpabuf *buf;
6667 : const struct rrm_link_measurement_request *req;
6668 : struct rrm_link_measurement_report report;
6669 :
6670 0 : if (wpa_s->wpa_state != WPA_COMPLETED) {
6671 0 : wpa_printf(MSG_INFO,
6672 : "RRM: Ignoring link measurement request. Not associated");
6673 0 : return;
6674 : }
6675 :
6676 0 : if (!wpa_s->rrm.rrm_used) {
6677 0 : wpa_printf(MSG_INFO,
6678 : "RRM: Ignoring link measurement request. Not RRM network");
6679 0 : return;
6680 : }
6681 :
6682 0 : if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
6683 0 : wpa_printf(MSG_INFO,
6684 : "RRM: Measurement report failed. TX power insertion not supported");
6685 0 : return;
6686 : }
6687 :
6688 0 : req = (const struct rrm_link_measurement_request *) frame;
6689 0 : if (len < sizeof(*req)) {
6690 0 : wpa_printf(MSG_INFO,
6691 : "RRM: Link measurement report failed. Request too short");
6692 0 : return;
6693 : }
6694 :
6695 0 : os_memset(&report, 0, sizeof(report));
6696 0 : report.tpc.eid = WLAN_EID_TPC_REPORT;
6697 0 : report.tpc.len = 2;
6698 0 : report.rsni = 255; /* 255 indicates that RSNI is not available */
6699 0 : report.dialog_token = req->dialog_token;
6700 :
6701 : /*
6702 : * It's possible to estimate RCPI based on RSSI in dBm. This
6703 : * calculation will not reflect the correct value for high rates,
6704 : * but it's good enough for Action frames which are transmitted
6705 : * with up to 24 Mbps rates.
6706 : */
6707 0 : if (!rssi)
6708 0 : report.rcpi = 255; /* not available */
6709 0 : else if (rssi < -110)
6710 0 : report.rcpi = 0;
6711 0 : else if (rssi > 0)
6712 0 : report.rcpi = 220;
6713 : else
6714 0 : report.rcpi = (rssi + 110) * 2;
6715 :
6716 : /* action_category + action_code */
6717 0 : buf = wpabuf_alloc(2 + sizeof(report));
6718 0 : if (buf == NULL) {
6719 0 : wpa_printf(MSG_ERROR,
6720 : "RRM: Link measurement report failed. Buffer allocation failed");
6721 0 : return;
6722 : }
6723 :
6724 0 : wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6725 0 : wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
6726 0 : wpabuf_put_data(buf, &report, sizeof(report));
6727 0 : wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
6728 : wpabuf_head(buf), wpabuf_len(buf));
6729 :
6730 0 : if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6731 0 : wpa_s->own_addr, wpa_s->bssid,
6732 0 : wpabuf_head(buf), wpabuf_len(buf), 0)) {
6733 0 : wpa_printf(MSG_ERROR,
6734 : "RRM: Link measurement report failed. Send action failed");
6735 : }
6736 0 : wpabuf_free(buf);
6737 : }
6738 :
6739 :
6740 : struct wpa_supplicant *
6741 162 : wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
6742 : {
6743 162 : switch (frame) {
6744 : #ifdef CONFIG_P2P
6745 : case VENDOR_ELEM_PROBE_REQ_P2P:
6746 : case VENDOR_ELEM_PROBE_RESP_P2P:
6747 : case VENDOR_ELEM_PROBE_RESP_P2P_GO:
6748 : case VENDOR_ELEM_BEACON_P2P_GO:
6749 : case VENDOR_ELEM_P2P_PD_REQ:
6750 : case VENDOR_ELEM_P2P_PD_RESP:
6751 : case VENDOR_ELEM_P2P_GO_NEG_REQ:
6752 : case VENDOR_ELEM_P2P_GO_NEG_RESP:
6753 : case VENDOR_ELEM_P2P_GO_NEG_CONF:
6754 : case VENDOR_ELEM_P2P_INV_REQ:
6755 : case VENDOR_ELEM_P2P_INV_RESP:
6756 : case VENDOR_ELEM_P2P_ASSOC_REQ:
6757 : case VENDOR_ELEM_P2P_ASSOC_RESP:
6758 100 : return wpa_s->p2pdev;
6759 : #endif /* CONFIG_P2P */
6760 : default:
6761 62 : return wpa_s;
6762 : }
6763 : }
6764 :
6765 :
6766 127 : void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
6767 : {
6768 : unsigned int i;
6769 : char buf[30];
6770 :
6771 127 : wpa_printf(MSG_DEBUG, "Update vendor elements");
6772 :
6773 2032 : for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
6774 1905 : if (wpa_s->vendor_elem[i]) {
6775 : int res;
6776 :
6777 74 : res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
6778 74 : if (!os_snprintf_error(sizeof(buf), res)) {
6779 74 : wpa_hexdump_buf(MSG_DEBUG, buf,
6780 74 : wpa_s->vendor_elem[i]);
6781 : }
6782 : }
6783 : }
6784 :
6785 : #ifdef CONFIG_P2P
6786 254 : if (wpa_s->parent == wpa_s &&
6787 254 : wpa_s->global->p2p &&
6788 127 : !wpa_s->global->p2p_disabled)
6789 127 : p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
6790 : #endif /* CONFIG_P2P */
6791 127 : }
6792 :
6793 :
6794 7 : int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
6795 : const u8 *elem, size_t len)
6796 : {
6797 : u8 *ie, *end;
6798 :
6799 7 : ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
6800 7 : end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
6801 :
6802 22 : for (; ie + 1 < end; ie += 2 + ie[1]) {
6803 9 : if (ie + len > end)
6804 0 : break;
6805 9 : if (os_memcmp(ie, elem, len) != 0)
6806 4 : continue;
6807 :
6808 5 : if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
6809 2 : wpabuf_free(wpa_s->vendor_elem[frame]);
6810 2 : wpa_s->vendor_elem[frame] = NULL;
6811 : } else {
6812 3 : os_memmove(ie, ie + len, end - (ie + len));
6813 3 : wpa_s->vendor_elem[frame]->used -= len;
6814 : }
6815 5 : wpas_vendor_elem_update(wpa_s);
6816 5 : return 0;
6817 : }
6818 :
6819 2 : return -1;
6820 : }
6821 :
6822 :
6823 594224 : struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
6824 : u16 num_modes, enum hostapd_hw_mode mode)
6825 : {
6826 : u16 i;
6827 :
6828 1237884 : for (i = 0; i < num_modes; i++) {
6829 1188381 : if (modes[i].mode == mode)
6830 544721 : return &modes[i];
6831 : }
6832 :
6833 49503 : return NULL;
6834 : }
6835 :
6836 :
6837 : static struct
6838 1 : wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
6839 : const u8 *bssid)
6840 : {
6841 : struct wpa_bss_tmp_disallowed *bss;
6842 :
6843 1 : dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
6844 : struct wpa_bss_tmp_disallowed, list) {
6845 0 : if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
6846 0 : return bss;
6847 : }
6848 :
6849 1 : return NULL;
6850 : }
6851 :
6852 :
6853 1 : void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
6854 : unsigned int sec)
6855 : {
6856 : struct wpa_bss_tmp_disallowed *bss;
6857 : struct os_reltime until;
6858 :
6859 1 : os_get_reltime(&until);
6860 1 : until.sec += sec;
6861 :
6862 1 : bss = wpas_get_disallowed_bss(wpa_s, bssid);
6863 1 : if (bss) {
6864 0 : bss->disallowed_until = until;
6865 0 : return;
6866 : }
6867 :
6868 1 : bss = os_malloc(sizeof(*bss));
6869 1 : if (!bss) {
6870 0 : wpa_printf(MSG_DEBUG,
6871 : "Failed to allocate memory for temp disallow BSS");
6872 0 : return;
6873 : }
6874 :
6875 1 : bss->disallowed_until = until;
6876 1 : os_memcpy(bss->bssid, bssid, ETH_ALEN);
6877 1 : dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
6878 : }
6879 :
6880 :
6881 5144 : int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid)
6882 : {
6883 5144 : struct wpa_bss_tmp_disallowed *bss = NULL, *tmp, *prev;
6884 : struct os_reltime now, age;
6885 :
6886 5144 : os_get_reltime(&now);
6887 :
6888 5145 : dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
6889 : struct wpa_bss_tmp_disallowed, list) {
6890 7 : if (!os_reltime_before(&now, &tmp->disallowed_until)) {
6891 : /* This BSS is not disallowed anymore */
6892 1 : dl_list_del(&tmp->list);
6893 1 : os_free(tmp);
6894 1 : continue;
6895 : }
6896 6 : if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
6897 6 : bss = tmp;
6898 6 : break;
6899 : }
6900 : }
6901 5144 : if (!bss)
6902 5138 : return 0;
6903 :
6904 6 : os_reltime_sub(&bss->disallowed_until, &now, &age);
6905 42 : wpa_printf(MSG_DEBUG,
6906 : "BSS " MACSTR " disabled for %ld.%0ld seconds",
6907 36 : MAC2STR(bss->bssid), age.sec, age.usec);
6908 6 : return 1;
6909 : }
|