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