]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
SAE: Collect list of rejected groups for H2E in STA
[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
05a2fb0d
JM
1935static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
1936{
1937#ifdef CONFIG_SAE
1938 int *groups = conf->sae_groups;
1939 int default_groups[] = { 19, 20, 21, 0 };
1940 const char *password;
1941
1942 if (!groups || groups[0] <= 0)
1943 groups = default_groups;
1944
1945 password = ssid->sae_password;
1946 if (!password)
1947 password = ssid->passphrase;
1948
1949 if (conf->sae_pwe == 0 || !password) {
1950 /* PT derivation not needed */
1951 sae_deinit_pt(ssid->pt);
1952 ssid->pt = NULL;
1953 return;
1954 }
1955
1956 if (ssid->pt)
1957 return; /* PT already derived */
1958 ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
1959 (const u8 *) password, os_strlen(password),
1960 ssid->sae_password_id);
1961#endif /* CONFIG_SAE */
1962}
1963
1964
6ac4b15e
JM
1965static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1966
6fc6879b
JM
1967/**
1968 * wpa_supplicant_associate - Request association
1969 * @wpa_s: Pointer to wpa_supplicant data
1970 * @bss: Scan results for the selected BSS, or %NULL if not available
1971 * @ssid: Configuration data for the selected network
1972 *
1973 * This function is used to request %wpa_supplicant to associate with a BSS.
1974 */
1975void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
6fa81a3b 1976 struct wpa_bss *bss, struct wpa_ssid *ssid)
6fc6879b 1977{
6ac4b15e 1978 struct wpa_connect_work *cwork;
a313d17d
JM
1979 int rand_style;
1980
a8412ec9
JM
1981 wpa_s->own_disconnect_req = 0;
1982
e7160bd8
JM
1983 /*
1984 * If we are starting a new connection, any previously pending EAPOL
1985 * RX cannot be valid anymore.
1986 */
1987 wpabuf_free(wpa_s->pending_eapol_rx);
1988 wpa_s->pending_eapol_rx = NULL;
1989
a313d17d
JM
1990 if (ssid->mac_addr == -1)
1991 rand_style = wpa_s->conf->mac_addr;
1992 else
1993 rand_style = ssid->mac_addr;
6fc6879b 1994
8c42b369
EP
1995 wmm_ac_clear_saved_tspecs(wpa_s);
1996 wpa_s->reassoc_same_bss = 0;
6a5ee810 1997 wpa_s->reassoc_same_ess = 0;
daa40960
JM
1998#ifdef CONFIG_TESTING_OPTIONS
1999 wpa_s->testing_resend_assoc = 0;
2000#endif /* CONFIG_TESTING_OPTIONS */
8c42b369 2001
c267753b
JM
2002 if (wpa_s->last_ssid == ssid) {
2003 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
6a5ee810 2004 wpa_s->reassoc_same_ess = 1;
8c42b369
EP
2005 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
2006 wmm_ac_save_tspecs(wpa_s);
2007 wpa_s->reassoc_same_bss = 1;
2bbad1c7
MW
2008 } else if (wpa_s->current_bss && wpa_s->current_bss != bss) {
2009 os_get_reltime(&wpa_s->roam_start);
8c42b369 2010 }
05a2fb0d
JM
2011 } else {
2012#ifdef CONFIG_SAE
447cd5f2
JM
2013#ifdef CONFIG_SME
2014 os_free(wpa_s->sme.sae_rejected_groups);
2015 wpa_s->sme.sae_rejected_groups = NULL;
2016#endif /* CONFIG_SME */
05a2fb0d
JM
2017 wpa_s_setup_sae_pt(wpa_s->conf, ssid);
2018#endif /* CONFIG_SAE */
5d30f927
BR
2019 }
2020
2021 if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
a313d17d 2022 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
c267753b
JM
2023 return;
2024 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
5d30f927 2025 } else if (rand_style == 0 && wpa_s->mac_addr_changed) {
c267753b
JM
2026 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
2027 wpa_msg(wpa_s, MSG_INFO,
2028 "Could not restore permanent MAC address");
2029 return;
2030 }
2031 wpa_s->mac_addr_changed = 0;
2032 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
2033 wpa_msg(wpa_s, MSG_INFO,
2034 "Could not update MAC address information");
2035 return;
2036 }
2037 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
2038 }
2039 wpa_s->last_ssid = ssid;
2040
78177a00
JM
2041#ifdef CONFIG_IBSS_RSN
2042 ibss_rsn_deinit(wpa_s->ibss_rsn);
2043 wpa_s->ibss_rsn = NULL;
81a10a94
JM
2044#else /* CONFIG_IBSS_RSN */
2045 if (ssid->mode == WPAS_MODE_IBSS &&
2046 !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPA_NONE))) {
2047 wpa_msg(wpa_s, MSG_INFO,
2048 "IBSS RSN not supported in the build");
2049 return;
2050 }
78177a00
JM
2051#endif /* CONFIG_IBSS_RSN */
2052
2c5d725c
JM
2053 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
2054 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
2055#ifdef CONFIG_AP
2056 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
2057 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
2058 "mode");
1581b38b
JM
2059 return;
2060 }
8c981d17
DW
2061 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
2062 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
2063 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
2064 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
2065 return;
2066 }
8f770587 2067 wpa_s->current_bss = bss;
1581b38b 2068#else /* CONFIG_AP */
f049052b
BG
2069 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
2070 "the build");
1581b38b
JM
2071#endif /* CONFIG_AP */
2072 return;
2073 }
2074
603a3f34
JL
2075 if (ssid->mode == WPAS_MODE_MESH) {
2076#ifdef CONFIG_MESH
2077 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
2078 wpa_msg(wpa_s, MSG_INFO,
2079 "Driver does not support mesh mode");
2080 return;
2081 }
2082 if (bss)
2083 ssid->frequency = bss->freq;
2084 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
2085 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
2086 return;
2087 }
2088 wpa_s->current_bss = bss;
6174de66
JM
2089 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
2090 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
2091 ssid->id);
89e9cd25 2092 wpas_notify_mesh_group_started(wpa_s, ssid);
603a3f34
JL
2093#else /* CONFIG_MESH */
2094 wpa_msg(wpa_s, MSG_ERROR,
2095 "mesh mode support not included in the build");
2096#endif /* CONFIG_MESH */
2097 return;
2098 }
2099
2efc6720
JM
2100 /*
2101 * Set WPA state machine configuration to match the selected network now
2102 * so that the information is available before wpas_start_assoc_cb()
2103 * gets called. This is needed at least for RSN pre-authentication where
2104 * candidate APs are added to a list based on scan result processing
2105 * before completion of the first association.
2106 */
2107 wpa_supplicant_rsn_supp_set_config(wpa_s, ssid);
2108
a0d5c56f
JM
2109#ifdef CONFIG_DPP
2110 if (wpas_dpp_check_connect(wpa_s, ssid, bss) != 0)
2111 return;
2112#endif /* CONFIG_DPP */
2113
52c9e6f3 2114#ifdef CONFIG_TDLS
95cb2d88
JM
2115 if (bss)
2116 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
2117 bss->ie_len);
52c9e6f3
JM
2118#endif /* CONFIG_TDLS */
2119
2e06cef8
VK
2120#ifdef CONFIG_MBO
2121 wpas_mbo_check_pmf(wpa_s, bss, ssid);
2122#endif /* CONFIG_MBO */
2123
5cc4d64b 2124 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
f74618cb 2125 ssid->mode == WPAS_MODE_INFRA) {
c2a04078
JM
2126 sme_authenticate(wpa_s, bss, ssid);
2127 return;
2128 }
2129
6ac4b15e
JM
2130 if (wpa_s->connect_work) {
2131 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
2132 return;
2133 }
2134
f0e30c84
JM
2135 if (radio_work_pending(wpa_s, "connect")) {
2136 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
2137 return;
2138 }
2139
a1836de6
JM
2140#ifdef CONFIG_SME
2141 if (ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) {
2142 /* Clear possibly set auth_alg, if any, from last attempt. */
2143 wpa_s->sme.auth_alg = WPA_AUTH_ALG_OPEN;
2144 }
2145#endif /* CONFIG_SME */
2146
4ead7cfd
KV
2147 wpas_abort_ongoing_scan(wpa_s);
2148
6ac4b15e
JM
2149 cwork = os_zalloc(sizeof(*cwork));
2150 if (cwork == NULL)
2151 return;
2152
2153 cwork->bss = bss;
2154 cwork->ssid = ssid;
2155
2156 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
2157 wpas_start_assoc_cb, cwork) < 0) {
2158 os_free(cwork);
2159 }
2160}
2161
2162
98479dc9
JD
2163static int bss_is_ibss(struct wpa_bss *bss)
2164{
2165 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
2166 IEEE80211_CAP_IBSS;
2167}
2168
2169
a65efbfb
PO
2170static int drv_supports_vht(struct wpa_supplicant *wpa_s,
2171 const struct wpa_ssid *ssid)
2172{
2173 enum hostapd_hw_mode hw_mode;
2174 struct hostapd_hw_modes *mode = NULL;
2175 u8 channel;
2176 int i;
2177
a65efbfb
PO
2178 hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
2179 if (hw_mode == NUM_HOSTAPD_MODES)
2180 return 0;
2181 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
2182 if (wpa_s->hw.modes[i].mode == hw_mode) {
2183 mode = &wpa_s->hw.modes[i];
2184 break;
2185 }
2186 }
2187
2188 if (!mode)
2189 return 0;
2190
2191 return mode->vht_capab != 0;
2192}
2193
2194
54fe48b9
JM
2195void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
2196 const struct wpa_ssid *ssid,
2197 struct hostapd_freq_params *freq)
1830817e 2198{
3459c54a 2199 int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
1830817e
JD
2200 enum hostapd_hw_mode hw_mode;
2201 struct hostapd_hw_modes *mode = NULL;
6b8b0774
JD
2202 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
2203 184, 192 };
563ee183 2204 int vht80[] = { 36, 52, 100, 116, 132, 149 };
6b8b0774 2205 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1830817e 2206 u8 channel;
98479dc9 2207 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
0f29bc68 2208 unsigned int j, k;
563ee183 2209 struct hostapd_freq_params vht_freq;
0f29bc68
AK
2210 int chwidth, seg0, seg1;
2211 u32 vht_caps = 0;
6e711e7a 2212 int is_24ghz;
1830817e
JD
2213
2214 freq->freq = ssid->frequency;
2215
98479dc9
JD
2216 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
2217 struct wpa_bss *bss = wpa_s->last_scan_res[j];
2218
2219 if (ssid->mode != WPAS_MODE_IBSS)
2220 break;
2221
2222 /* Don't adjust control freq in case of fixed_freq */
2223 if (ssid->fixed_freq)
2224 break;
2225
2226 if (!bss_is_ibss(bss))
2227 continue;
2228
2229 if (ssid->ssid_len == bss->ssid_len &&
2230 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
2231 wpa_printf(MSG_DEBUG,
2232 "IBSS already found in scan results, adjust control freq: %d",
2233 bss->freq);
2234 freq->freq = bss->freq;
2235 obss_scan = 0;
2236 break;
2237 }
2238 }
2239
1830817e
JD
2240 /* For IBSS check HT_IBSS flag */
2241 if (ssid->mode == WPAS_MODE_IBSS &&
2242 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
2243 return;
2244
d9a9bc04
JD
2245 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
2246 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
2247 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
2248 wpa_printf(MSG_DEBUG,
2249 "IBSS: WEP/TKIP detected, do not try to enable HT");
2250 return;
2251 }
2252
98479dc9 2253 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
1830817e
JD
2254 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
2255 if (wpa_s->hw.modes[i].mode == hw_mode) {
2256 mode = &wpa_s->hw.modes[i];
2257 break;
2258 }
2259 }
2260
2261 if (!mode)
2262 return;
2263
6e711e7a
SE
2264 is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
2265 hw_mode == HOSTAPD_MODE_IEEE80211B;
3459c54a 2266
3388e7b9
MH
2267#ifdef CONFIG_HT_OVERRIDES
2268 if (ssid->disable_ht) {
2269 freq->ht_enabled = 0;
2270 return;
2271 }
2272#endif /* CONFIG_HT_OVERRIDES */
2273
1830817e 2274 freq->ht_enabled = ht_supported(mode);
6b8b0774
JD
2275 if (!freq->ht_enabled)
2276 return;
2277
6e711e7a
SE
2278 /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */
2279 if (is_24ghz)
2280 freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
2281
6b8b0774
JD
2282 /* Setup higher BW only for 5 GHz */
2283 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
2284 return;
2285
2286 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
2287 pri_chan = &mode->channels[chan_idx];
2288 if (pri_chan->chan == channel)
2289 break;
2290 pri_chan = NULL;
2291 }
2292 if (!pri_chan)
2293 return;
2294
2295 /* Check primary channel flags */
2296 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2297 return;
2298
e5a9b1e8
PO
2299 freq->channel = pri_chan->chan;
2300
05aed438 2301#ifdef CONFIG_HT_OVERRIDES
e5a9b1e8
PO
2302 if (ssid->disable_ht40) {
2303 if (ssid->disable_vht)
2304 return;
2305 goto skip_ht40;
2306 }
05aed438
MH
2307#endif /* CONFIG_HT_OVERRIDES */
2308
6b8b0774
JD
2309 /* Check/setup HT40+/HT40- */
2310 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
2311 if (ht40plus[j] == channel) {
2312 ht40 = 1;
2313 break;
2314 }
2315 }
2316
2317 /* Find secondary channel */
2318 for (i = 0; i < mode->num_channels; i++) {
2319 sec_chan = &mode->channels[i];
2320 if (sec_chan->chan == channel + ht40 * 4)
2321 break;
2322 sec_chan = NULL;
2323 }
2324 if (!sec_chan)
2325 return;
2326
2327 /* Check secondary channel flags */
2328 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2329 return;
2330
ecba4509 2331 if (ht40 == -1) {
6b8b0774
JD
2332 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
2333 return;
ecba4509 2334 } else {
6b8b0774
JD
2335 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
2336 return;
6b8b0774 2337 }
ecba4509 2338 freq->sec_channel_offset = ht40;
6b8b0774 2339
ecba4509 2340 if (obss_scan) {
6b8b0774
JD
2341 struct wpa_scan_results *scan_res;
2342
2343 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
2344 if (scan_res == NULL) {
2345 /* Back to HT20 */
2346 freq->sec_channel_offset = 0;
2347 return;
2348 }
2349
2350 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
2351 sec_chan->chan);
2352 switch (res) {
2353 case 0:
2354 /* Back to HT20 */
2355 freq->sec_channel_offset = 0;
2356 break;
2357 case 1:
2358 /* Configuration allowed */
2359 break;
2360 case 2:
2361 /* Switch pri/sec channels */
2362 freq->freq = hw_get_freq(mode, sec_chan->chan);
2363 freq->sec_channel_offset = -freq->sec_channel_offset;
2364 freq->channel = sec_chan->chan;
2365 break;
2366 default:
2367 freq->sec_channel_offset = 0;
2368 break;
2369 }
2370
2371 wpa_scan_results_free(scan_res);
2372 }
2373
e5a9b1e8
PO
2374#ifdef CONFIG_HT_OVERRIDES
2375skip_ht40:
2376#endif /* CONFIG_HT_OVERRIDES */
6b8b0774
JD
2377 wpa_printf(MSG_DEBUG,
2378 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
2379 freq->channel, freq->sec_channel_offset);
563ee183 2380
a65efbfb 2381 if (!drv_supports_vht(wpa_s, ssid))
563ee183
JD
2382 return;
2383
2384 /* For IBSS check VHT_IBSS flag */
a65efbfb
PO
2385 if (ssid->mode == WPAS_MODE_IBSS &&
2386 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
563ee183
JD
2387 return;
2388
2389 vht_freq = *freq;
2390
b301f54e
JM
2391#ifdef CONFIG_VHT_OVERRIDES
2392 if (ssid->disable_vht) {
2393 freq->vht_enabled = 0;
2394 return;
2395 }
2396#endif /* CONFIG_VHT_OVERRIDES */
2397
563ee183
JD
2398 vht_freq.vht_enabled = vht_supported(mode);
2399 if (!vht_freq.vht_enabled)
2400 return;
2401
6e711e7a
SE
2402 /* Enable HE for VHT */
2403 vht_freq.he_enabled = mode->he_capab[ieee80211_mode].he_supported;
2404
563ee183
JD
2405 /* setup center_freq1, bandwidth */
2406 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
2407 if (freq->channel >= vht80[j] &&
2408 freq->channel < vht80[j] + 16)
2409 break;
2410 }
2411
2412 if (j == ARRAY_SIZE(vht80))
2413 return;
2414
2415 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
2416 struct hostapd_channel_data *chan;
2417
2418 chan = hw_get_channel_chan(mode, i, NULL);
2419 if (!chan)
2420 return;
2421
2422 /* Back to HT configuration if channel not usable */
2423 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2424 return;
2425 }
2426
464dcfd0 2427 chwidth = CHANWIDTH_80MHZ;
0f29bc68
AK
2428 seg0 = vht80[j] + 6;
2429 seg1 = 0;
2430
464dcfd0 2431 if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) {
0f29bc68
AK
2432 /* setup center_freq2, bandwidth */
2433 for (k = 0; k < ARRAY_SIZE(vht80); k++) {
2434 /* Only accept 80 MHz segments separated by a gap */
2435 if (j == k || abs(vht80[j] - vht80[k]) == 16)
2436 continue;
2437 for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
2438 struct hostapd_channel_data *chan;
2439
2440 chan = hw_get_channel_chan(mode, i, NULL);
2441 if (!chan)
2442 continue;
2443
2444 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2445 HOSTAPD_CHAN_NO_IR |
2446 HOSTAPD_CHAN_RADAR))
2447 continue;
2448
2449 /* Found a suitable second segment for 80+80 */
464dcfd0 2450 chwidth = CHANWIDTH_80P80MHZ;
0f29bc68
AK
2451 vht_caps |=
2452 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2453 seg1 = vht80[k] + 6;
2454 }
2455
464dcfd0 2456 if (chwidth == CHANWIDTH_80P80MHZ)
0f29bc68
AK
2457 break;
2458 }
464dcfd0 2459 } else if (ssid->max_oper_chwidth == CHANWIDTH_160MHZ) {
331f0774 2460 if (freq->freq == 5180) {
464dcfd0 2461 chwidth = CHANWIDTH_160MHZ;
331f0774
JM
2462 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2463 seg0 = 50;
2464 } else if (freq->freq == 5520) {
464dcfd0 2465 chwidth = CHANWIDTH_160MHZ;
331f0774
JM
2466 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2467 seg0 = 114;
2468 }
464dcfd0
JC
2469 } else if (ssid->max_oper_chwidth == CHANWIDTH_USE_HT) {
2470 chwidth = CHANWIDTH_USE_HT;
806db174 2471 seg0 = vht80[j] + 2;
e5a9b1e8
PO
2472#ifdef CONFIG_HT_OVERRIDES
2473 if (ssid->disable_ht40)
2474 seg0 = 0;
2475#endif /* CONFIG_HT_OVERRIDES */
0f29bc68
AK
2476 }
2477
563ee183 2478 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
bebd91e9
AAL
2479 freq->channel, ssid->enable_edmg,
2480 ssid->edmg_channel, freq->ht_enabled,
3459c54a 2481 vht_freq.vht_enabled, freq->he_enabled,
563ee183 2482 freq->sec_channel_offset,
3459c54a
SE
2483 chwidth, seg0, seg1, vht_caps,
2484 &mode->he_capab[ieee80211_mode]) != 0)
563ee183
JD
2485 return;
2486
2487 *freq = vht_freq;
2488
2489 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2490 freq->center_freq1, freq->center_freq2, freq->bandwidth);
1830817e
JD
2491}
2492
2493
a38090b1
VK
2494#ifdef CONFIG_FILS
2495static size_t wpas_add_fils_hlp_req(struct wpa_supplicant *wpa_s, u8 *ie_buf,
2496 size_t ie_buf_len)
2497{
2498 struct fils_hlp_req *req;
2499 size_t rem_len, hdr_len, hlp_len, len, ie_len = 0;
2500 const u8 *pos;
2501 u8 *buf = ie_buf;
2502
2503 dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
2504 list) {
2505 rem_len = ie_buf_len - ie_len;
2506 pos = wpabuf_head(req->pkt);
2507 hdr_len = 1 + 2 * ETH_ALEN + 6;
2508 hlp_len = wpabuf_len(req->pkt);
2509
2510 if (rem_len < 2 + hdr_len + hlp_len) {
2511 wpa_printf(MSG_ERROR,
2512 "FILS: Cannot fit HLP - rem_len=%lu to_fill=%lu",
2513 (unsigned long) rem_len,
2514 (unsigned long) (2 + hdr_len + hlp_len));
2515 break;
2516 }
2517
2518 len = (hdr_len + hlp_len) > 255 ? 255 : hdr_len + hlp_len;
2519 /* Element ID */
2520 *buf++ = WLAN_EID_EXTENSION;
2521 /* Length */
2522 *buf++ = len;
2523 /* Element ID Extension */
2524 *buf++ = WLAN_EID_EXT_FILS_HLP_CONTAINER;
2525 /* Destination MAC address */
2526 os_memcpy(buf, req->dst, ETH_ALEN);
2527 buf += ETH_ALEN;
2528 /* Source MAC address */
2529 os_memcpy(buf, wpa_s->own_addr, ETH_ALEN);
2530 buf += ETH_ALEN;
2531 /* LLC/SNAP Header */
2532 os_memcpy(buf, "\xaa\xaa\x03\x00\x00\x00", 6);
2533 buf += 6;
2534 /* HLP Packet */
2535 os_memcpy(buf, pos, len - hdr_len);
2536 buf += len - hdr_len;
2537 pos += len - hdr_len;
2538
2539 hlp_len -= len - hdr_len;
2540 ie_len += 2 + len;
2541 rem_len -= 2 + len;
2542
2543 while (hlp_len) {
2544 len = (hlp_len > 255) ? 255 : hlp_len;
2545 if (rem_len < 2 + len)
2546 break;
2547 *buf++ = WLAN_EID_FRAGMENT;
2548 *buf++ = len;
2549 os_memcpy(buf, pos, len);
2550 buf += len;
2551 pos += len;
2552
2553 hlp_len -= len;
2554 ie_len += 2 + len;
2555 rem_len -= 2 + len;
2556 }
2557 }
2558
2559 return ie_len;
2560}
e4802127
MH
2561
2562
2563int wpa_is_fils_supported(struct wpa_supplicant *wpa_s)
2564{
2565 return (((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
2566 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS)) ||
2567 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
2568 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)));
2569}
2570
2571
2572int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s)
2573{
2574#ifdef CONFIG_FILS_SK_PFS
2575 return (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
2576 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS);
2577#else /* CONFIG_FILS_SK_PFS */
2578 return 0;
2579#endif /* CONFIG_FILS_SK_PFS */
2580}
2581
a38090b1
VK
2582#endif /* CONFIG_FILS */
2583
2584
d2ba0d71
VK
2585static u8 * wpas_populate_assoc_ies(
2586 struct wpa_supplicant *wpa_s,
2587 struct wpa_bss *bss, struct wpa_ssid *ssid,
6338c99e
VK
2588 struct wpa_driver_associate_params *params,
2589 enum wpa_drv_update_connect_params_mask *mask)
6ac4b15e 2590{
1e6780bd 2591 u8 *wpa_ie;
10970465 2592 size_t max_wpa_ie_len = 500;
6ac4b15e 2593 size_t wpa_ie_len;
6ac4b15e 2594 int algs = WPA_AUTH_ALG_OPEN;
077232f6
BL
2595#ifdef CONFIG_MBO
2596 const u8 *mbo_ie;
2597#endif
eb3234c0
SM
2598#ifdef CONFIG_SAE
2599 int sae_pmksa_cached = 0;
2600#endif /* CONFIG_SAE */
8b0a6dba
VK
2601#ifdef CONFIG_FILS
2602 const u8 *realm, *username, *rrk;
2603 size_t realm_len, username_len, rrk_len;
2604 u16 next_seq_num;
b377ec25 2605 struct fils_hlp_req *req;
6fc6879b 2606
b377ec25
VK
2607 dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
2608 list) {
2609 max_wpa_ie_len += 3 + 2 * ETH_ALEN + 6 + wpabuf_len(req->pkt) +
2610 2 + 2 * wpabuf_len(req->pkt) / 255;
8b0a6dba
VK
2611 }
2612#endif /* CONFIG_FILS */
8b0a6dba 2613
1e6780bd
VK
2614 wpa_ie = os_malloc(max_wpa_ie_len);
2615 if (!wpa_ie) {
2616 wpa_printf(MSG_ERROR,
2617 "Failed to allocate connect IE buffer for %lu bytes",
2618 (unsigned long) max_wpa_ie_len);
d2ba0d71 2619 return NULL;
1e6780bd
VK
2620 }
2621
6fa81a3b
JM
2622 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2623 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 2624 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 2625 int try_opportunistic;
79f3121b
VK
2626 const u8 *cache_id = NULL;
2627
6e202021
JM
2628 try_opportunistic = (ssid->proactive_key_caching < 0 ?
2629 wpa_s->conf->okc :
2630 ssid->proactive_key_caching) &&
6fc6879b 2631 (ssid->proto & WPA_PROTO_RSN);
79f3121b
VK
2632#ifdef CONFIG_FILS
2633 if (wpa_key_mgmt_fils(ssid->key_mgmt))
2634 cache_id = wpa_bss_get_fils_cache_id(bss);
2635#endif /* CONFIG_FILS */
6fc6879b 2636 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
79f3121b 2637 ssid, try_opportunistic,
eb3234c0 2638 cache_id, 0) == 0) {
ba422613 2639 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
eb3234c0
SM
2640#ifdef CONFIG_SAE
2641 sae_pmksa_cached = 1;
2642#endif /* CONFIG_SAE */
2643 }
1e6780bd 2644 wpa_ie_len = max_wpa_ie_len;
6fc6879b
JM
2645 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2646 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2647 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2648 "key management and encryption suites");
1e6780bd 2649 os_free(wpa_ie);
d2ba0d71 2650 return NULL;
6fc6879b 2651 }
dc673aec
JM
2652#ifdef CONFIG_HS20
2653 } else if (bss && wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE) &&
2654 (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)) {
2655 /* No PMKSA caching, but otherwise similar to RSN/WPA */
2656 wpa_ie_len = max_wpa_ie_len;
2657 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2658 wpa_ie, &wpa_ie_len)) {
2659 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2660 "key management and encryption suites");
2661 os_free(wpa_ie);
2662 return NULL;
2663 }
2664#endif /* CONFIG_HS20 */
a3f7e518
JM
2665 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2666 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2667 /*
2668 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2669 * use non-WPA since the scan results did not indicate that the
2670 * AP is using WPA or WPA2.
2671 */
2672 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2673 wpa_ie_len = 0;
2674 wpa_s->wpa_proto = 0;
0bf927a0 2675 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
1e6780bd 2676 wpa_ie_len = max_wpa_ie_len;
6fc6879b
JM
2677 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2678 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2679 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2680 "key management and encryption suites (no "
2681 "scan results)");
1e6780bd 2682 os_free(wpa_ie);
d2ba0d71 2683 return NULL;
6fc6879b 2684 }
ad08c363
JM
2685#ifdef CONFIG_WPS
2686 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
2687 struct wpabuf *wps_ie;
2688 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1e6780bd 2689 if (wps_ie && wpabuf_len(wps_ie) <= max_wpa_ie_len) {
ad08c363
JM
2690 wpa_ie_len = wpabuf_len(wps_ie);
2691 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
2692 } else
2693 wpa_ie_len = 0;
ad08c363
JM
2694 wpabuf_free(wps_ie);
2695 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d 2696 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
d2ba0d71 2697 params->wps = WPS_MODE_PRIVACY;
0c80427d 2698 else
d2ba0d71 2699 params->wps = WPS_MODE_OPEN;
cf546f1a 2700 wpa_s->wpa_proto = 0;
ad08c363 2701#endif /* CONFIG_WPS */
6fc6879b
JM
2702 } else {
2703 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2704 wpa_ie_len = 0;
cf546f1a 2705 wpa_s->wpa_proto = 0;
6fc6879b
JM
2706 }
2707
b377ec25
VK
2708#ifdef IEEE8021X_EAPOL
2709 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2710 if (ssid->leap) {
2711 if (ssid->non_leap == 0)
2712 algs = WPA_AUTH_ALG_LEAP;
2713 else
2714 algs |= WPA_AUTH_ALG_LEAP;
2715 }
2716 }
2717
2718#ifdef CONFIG_FILS
2719 /* Clear FILS association */
2720 wpa_sm_set_reset_fils_completed(wpa_s->wpa, 0);
2721
2722 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD) &&
2723 ssid->eap.erp && wpa_key_mgmt_fils(wpa_s->key_mgmt) &&
2724 eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap, &username,
2725 &username_len, &realm, &realm_len,
af835d75
AB
2726 &next_seq_num, &rrk, &rrk_len) == 0 &&
2727 (!wpa_s->last_con_fail_realm ||
2728 wpa_s->last_con_fail_realm_len != realm_len ||
2729 os_memcmp(wpa_s->last_con_fail_realm, realm, realm_len) != 0)) {
b377ec25 2730 algs = WPA_AUTH_ALG_FILS;
d2ba0d71
VK
2731 params->fils_erp_username = username;
2732 params->fils_erp_username_len = username_len;
2733 params->fils_erp_realm = realm;
2734 params->fils_erp_realm_len = realm_len;
2735 params->fils_erp_next_seq_num = next_seq_num;
2736 params->fils_erp_rrk = rrk;
2737 params->fils_erp_rrk_len = rrk_len;
6338c99e
VK
2738
2739 if (mask)
2740 *mask |= WPA_DRV_UPDATE_FILS_ERP_INFO;
b377ec25
VK
2741 }
2742#endif /* CONFIG_FILS */
2743#endif /* IEEE8021X_EAPOL */
5ff39c13
SD
2744#ifdef CONFIG_SAE
2745 if (wpa_s->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE))
2746 algs = WPA_AUTH_ALG_SAE;
2747#endif /* CONFIG_SAE */
b377ec25
VK
2748
2749 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
2750 if (ssid->auth_alg) {
2751 algs = ssid->auth_alg;
2752 wpa_dbg(wpa_s, MSG_DEBUG,
2753 "Overriding auth_alg selection: 0x%x", algs);
2754 }
2755
eb3234c0
SM
2756#ifdef CONFIG_SAE
2757 if (sae_pmksa_cached && algs == WPA_AUTH_ALG_SAE) {
2758 wpa_dbg(wpa_s, MSG_DEBUG,
2759 "SAE: Use WPA_AUTH_ALG_OPEN for PMKSA caching attempt");
2760 algs = WPA_AUTH_ALG_OPEN;
2761 }
2762#endif /* CONFIG_SAE */
2763
5f3a6aa0
JM
2764#ifdef CONFIG_P2P
2765 if (wpa_s->global->p2p) {
2766 u8 *pos;
2767 size_t len;
2768 int res;
5f3a6aa0 2769 pos = wpa_ie + wpa_ie_len;
1e6780bd 2770 len = max_wpa_ie_len - wpa_ie_len;
b8a8d677
JM
2771 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2772 ssid->p2p_group);
5f3a6aa0
JM
2773 if (res >= 0)
2774 wpa_ie_len += res;
2775 }
72044390
JM
2776
2777 wpa_s->cross_connect_disallowed = 0;
2778 if (bss) {
2779 struct wpabuf *p2p;
2780 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2781 if (p2p) {
2782 wpa_s->cross_connect_disallowed =
2783 p2p_get_cross_connect_disallowed(p2p);
2784 wpabuf_free(p2p);
f049052b
BG
2785 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2786 "connection",
2787 wpa_s->cross_connect_disallowed ?
2788 "disallows" : "allows");
72044390
JM
2789 }
2790 }
25ef8529
JM
2791
2792 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
5f3a6aa0
JM
2793#endif /* CONFIG_P2P */
2794
5e57ba25 2795 if (bss) {
cb828507 2796 wpa_ie_len += wpas_supp_op_class_ie(wpa_s, ssid, bss->freq,
065c029a 2797 wpa_ie + wpa_ie_len,
1e6780bd 2798 max_wpa_ie_len -
065c029a 2799 wpa_ie_len);
5e57ba25 2800 }
5e57ba25 2801
8b3b803a
AH
2802 /*
2803 * Workaround: Add Extended Capabilities element only if the AP
2804 * included this element in Beacon/Probe Response frames. Some older
2805 * APs seem to have interoperability issues if this element is
2806 * included, so while the standard may require us to include the
2807 * element in all cases, it is justifiable to skip it to avoid
2808 * interoperability issues.
2809 */
cc9a2575
KV
2810 if (ssid->p2p_group)
2811 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
2812 else
2813 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
2814
8b3b803a 2815 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
0bbaa9b9 2816 u8 ext_capab[18];
8b3b803a 2817 int ext_capab_len;
0bbaa9b9
JM
2818 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2819 sizeof(ext_capab));
2c66c7d1
AA
2820 if (ext_capab_len > 0 &&
2821 wpa_ie_len + ext_capab_len <= max_wpa_ie_len) {
8b3b803a
AH
2822 u8 *pos = wpa_ie;
2823 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2824 pos += 2 + pos[1];
2825 os_memmove(pos + ext_capab_len, pos,
2826 wpa_ie_len - (pos - wpa_ie));
2827 wpa_ie_len += ext_capab_len;
2828 os_memcpy(pos, ext_capab, ext_capab_len);
2829 }
92cbcf91 2830 }
92cbcf91 2831
c484b198
AS
2832#ifdef CONFIG_HS20
2833 if (is_hs20_network(wpa_s, ssid, bss)) {
2834 struct wpabuf *hs20;
2835
4204669c 2836 hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
c484b198
AS
2837 if (hs20) {
2838 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
2839 size_t len;
2840
ec2cf403
JM
2841 wpas_hs20_add_indication(hs20, pps_mo_id,
2842 get_hs20_version(bss));
4204669c 2843 wpas_hs20_add_roam_cons_sel(hs20, ssid);
1e6780bd 2844 len = max_wpa_ie_len - wpa_ie_len;
c484b198
AS
2845 if (wpabuf_len(hs20) <= len) {
2846 os_memcpy(wpa_ie + wpa_ie_len,
2847 wpabuf_head(hs20), wpabuf_len(hs20));
2848 wpa_ie_len += wpabuf_len(hs20);
2849 }
2850 wpabuf_free(hs20);
ece4ac5f
MG
2851
2852 hs20_configure_frame_filters(wpa_s);
c484b198
AS
2853 }
2854 }
2855#endif /* CONFIG_HS20 */
2856
d29fa3a7
JM
2857 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2858 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2859 size_t len;
2860
1e6780bd 2861 len = max_wpa_ie_len - wpa_ie_len;
d29fa3a7
JM
2862 if (wpabuf_len(buf) <= len) {
2863 os_memcpy(wpa_ie + wpa_ie_len,
2864 wpabuf_head(buf), wpabuf_len(buf));
2865 wpa_ie_len += wpabuf_len(buf);
2866 }
2867 }
2868
b36a3a65
AN
2869#ifdef CONFIG_FST
2870 if (wpa_s->fst_ies) {
2871 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2872
1e6780bd 2873 if (wpa_ie_len + fst_ies_len <= max_wpa_ie_len) {
b36a3a65
AN
2874 os_memcpy(wpa_ie + wpa_ie_len,
2875 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2876 wpa_ie_len += fst_ies_len;
2877 }
2878 }
2879#endif /* CONFIG_FST */
2880
92c6e2e3 2881#ifdef CONFIG_MBO
077232f6 2882 mbo_ie = bss ? wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE) : NULL;
2e06cef8 2883 if (!wpa_s->disable_mbo_oce && mbo_ie) {
5e57ba25 2884 int len;
92c6e2e3 2885
5e57ba25 2886 len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
077232f6
BL
2887 max_wpa_ie_len - wpa_ie_len,
2888 !!mbo_attr_from_mbo_ie(mbo_ie,
2889 OCE_ATTR_ID_CAPA_IND));
5e57ba25
AS
2890 if (len >= 0)
2891 wpa_ie_len += len;
92c6e2e3
DS
2892 }
2893#endif /* CONFIG_MBO */
2894
a38090b1
VK
2895#ifdef CONFIG_FILS
2896 if (algs == WPA_AUTH_ALG_FILS) {
2897 size_t len;
2898
2899 len = wpas_add_fils_hlp_req(wpa_s, wpa_ie + wpa_ie_len,
2900 max_wpa_ie_len - wpa_ie_len);
2901 wpa_ie_len += len;
2902 }
2903#endif /* CONFIG_FILS */
2904
10970465 2905#ifdef CONFIG_OWE
5f30b69c
JM
2906#ifdef CONFIG_TESTING_OPTIONS
2907 if (get_ie_ext(wpa_ie, wpa_ie_len, WLAN_EID_EXT_OWE_DH_PARAM)) {
2908 wpa_printf(MSG_INFO, "TESTING: Override OWE DH element");
2909 } else
2910#endif /* CONFIG_TESTING_OPTIONS */
10970465
JM
2911 if (algs == WPA_AUTH_ALG_OPEN &&
2912 ssid->key_mgmt == WPA_KEY_MGMT_OWE) {
2913 struct wpabuf *owe_ie;
2cb40e9f 2914 u16 group;
10970465 2915
2cb40e9f 2916 if (ssid->owe_group) {
10970465 2917 group = ssid->owe_group;
698c9e20
AK
2918 } else if (wpa_s->assoc_status_code ==
2919 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
2cb40e9f
JM
2920 if (wpa_s->last_owe_group == 19)
2921 group = 20;
2922 else if (wpa_s->last_owe_group == 20)
2923 group = 21;
2924 else
2925 group = OWE_DH_GROUP;
698c9e20
AK
2926 } else {
2927 group = OWE_DH_GROUP;
2cb40e9f 2928 }
698c9e20 2929
2cb40e9f
JM
2930 wpa_s->last_owe_group = group;
2931 wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group);
10970465
JM
2932 owe_ie = owe_build_assoc_req(wpa_s->wpa, group);
2933 if (owe_ie &&
2934 wpabuf_len(owe_ie) <= max_wpa_ie_len - wpa_ie_len) {
2935 os_memcpy(wpa_ie + wpa_ie_len,
2936 wpabuf_head(owe_ie), wpabuf_len(owe_ie));
2937 wpa_ie_len += wpabuf_len(owe_ie);
10970465 2938 }
04879671 2939 wpabuf_free(owe_ie);
10970465
JM
2940 }
2941#endif /* CONFIG_OWE */
2942
10ec6a5f
JM
2943#ifdef CONFIG_DPP2
2944 if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP &&
2945 ssid->dpp_netaccesskey) {
2946 dpp_pfs_free(wpa_s->dpp_pfs);
2947 wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
2948 ssid->dpp_netaccesskey_len);
2949 if (!wpa_s->dpp_pfs) {
2950 wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
2951 /* Try to continue without PFS */
2952 goto pfs_fail;
2953 }
2954 if (wpabuf_len(wpa_s->dpp_pfs->ie) <=
2955 max_wpa_ie_len - wpa_ie_len) {
2956 os_memcpy(wpa_ie + wpa_ie_len,
2957 wpabuf_head(wpa_s->dpp_pfs->ie),
2958 wpabuf_len(wpa_s->dpp_pfs->ie));
2959 wpa_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
2960 }
2961 }
2962pfs_fail:
2963#endif /* CONFIG_DPP2 */
2964
3dc3afe2
AM
2965#ifdef CONFIG_IEEE80211R
2966 /*
2967 * Add MDIE under these conditions: the network profile allows FT,
2968 * the AP supports FT, and the mobility domain ID matches.
2969 */
88bf44be 2970 if (bss && wpa_key_mgmt_ft(wpa_sm_get_key_mgmt(wpa_s->wpa))) {
3dc3afe2
AM
2971 const u8 *mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
2972
2973 if (mdie && mdie[1] >= MOBILITY_DOMAIN_ID_LEN) {
86c998d3 2974 size_t len = 0;
3dc3afe2
AM
2975 const u8 *md = mdie + 2;
2976 const u8 *wpa_md = wpa_sm_get_ft_md(wpa_s->wpa);
2977
2978 if (os_memcmp(md, wpa_md,
2979 MOBILITY_DOMAIN_ID_LEN) == 0) {
2980 /* Add mobility domain IE */
86c998d3 2981 len = wpa_ft_add_mdie(
3dc3afe2
AM
2982 wpa_s->wpa, wpa_ie + wpa_ie_len,
2983 max_wpa_ie_len - wpa_ie_len, mdie);
86c998d3 2984 wpa_ie_len += len;
3dc3afe2 2985 }
86c998d3
AM
2986#ifdef CONFIG_SME
2987 if (len > 0 && wpa_s->sme.ft_used &&
2988 wpa_sm_has_ptk(wpa_s->wpa)) {
2989 wpa_dbg(wpa_s, MSG_DEBUG,
2990 "SME: Trying to use FT over-the-air");
2991 algs |= WPA_AUTH_ALG_FT;
2992 }
2993#endif /* CONFIG_SME */
3dc3afe2
AM
2994 }
2995 }
2996#endif /* CONFIG_IEEE80211R */
2997
5abc7823
VN
2998 if (ssid->multi_ap_backhaul_sta) {
2999 size_t multi_ap_ie_len;
3000
3001 multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
3002 max_wpa_ie_len - wpa_ie_len,
3003 MULTI_AP_BACKHAUL_STA);
3004 if (multi_ap_ie_len == 0) {
3005 wpa_printf(MSG_ERROR,
3006 "Multi-AP: Failed to build Multi-AP IE");
3007 os_free(wpa_ie);
3008 return NULL;
3009 }
3010 wpa_ie_len += multi_ap_ie_len;
3011 }
3012
d2ba0d71
VK
3013 params->wpa_ie = wpa_ie;
3014 params->wpa_ie_len = wpa_ie_len;
3015 params->auth_alg = algs;
6338c99e
VK
3016 if (mask)
3017 *mask |= WPA_DRV_UPDATE_ASSOC_IES | WPA_DRV_UPDATE_AUTH_TYPE;
d2ba0d71
VK
3018
3019 return wpa_ie;
3020}
3021
3022
e0b331d8
SD
3023#ifdef CONFIG_OWE
3024static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s)
3025{
3026 struct wpa_driver_associate_params params;
3027 u8 *wpa_ie;
3028
3029 os_memset(&params, 0, sizeof(params));
3030 wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
3031 wpa_s->current_ssid, &params, NULL);
3032 if (!wpa_ie)
3033 return;
3034
3035 wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
3036 os_free(wpa_ie);
3037}
3038#endif /* CONFIG_OWE */
3039
3040
6338c99e
VK
3041#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
3042static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s)
3043{
3044 struct wpa_driver_associate_params params;
3045 enum wpa_drv_update_connect_params_mask mask = 0;
3046 u8 *wpa_ie;
3047
3048 if (wpa_s->auth_alg != WPA_AUTH_ALG_OPEN)
3049 return; /* nothing to do */
3050
3051 os_memset(&params, 0, sizeof(params));
3052 wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
3053 wpa_s->current_ssid, &params, &mask);
3054 if (!wpa_ie)
3055 return;
3056
3057 if (params.auth_alg != WPA_AUTH_ALG_FILS) {
3058 os_free(wpa_ie);
3059 return;
3060 }
3061
3062 wpa_s->auth_alg = params.auth_alg;
3063 wpa_drv_update_connect_params(wpa_s, &params, mask);
3064 os_free(wpa_ie);
3065}
3066#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
3067
3068
a82aee1f
AAL
3069static u8 wpa_ie_get_edmg_oper_chans(const u8 *edmg_ie)
3070{
3071 if (!edmg_ie || edmg_ie[1] < 6)
3072 return 0;
3073 return edmg_ie[EDMG_BSS_OPERATING_CHANNELS_OFFSET];
3074}
3075
3076
3077static u8 wpa_ie_get_edmg_oper_chan_width(const u8 *edmg_ie)
3078{
3079 if (!edmg_ie || edmg_ie[1] < 6)
3080 return 0;
3081 return edmg_ie[EDMG_OPERATING_CHANNEL_WIDTH_OFFSET];
3082}
3083
3084
3085/* Returns the intersection of two EDMG configurations.
3086 * Note: The current implementation is limited to CB2 only (CB1 included),
3087 * i.e., the implementation supports up to 2 contiguous channels.
3088 * For supporting non-contiguous (aggregated) channels and for supporting
3089 * CB3 and above, this function will need to be extended.
3090 */
3091static struct ieee80211_edmg_config
3092get_edmg_intersection(struct ieee80211_edmg_config a,
3093 struct ieee80211_edmg_config b,
3094 u8 primary_channel)
3095{
3096 struct ieee80211_edmg_config result;
3097 int i, contiguous = 0;
3098 int max_contiguous = 0;
3099
3100 result.channels = b.channels & a.channels;
3101 if (!result.channels) {
3102 wpa_printf(MSG_DEBUG,
3103 "EDMG not possible: cannot intersect channels 0x%x and 0x%x",
3104 a.channels, b.channels);
3105 goto fail;
3106 }
3107
3108 if (!(result.channels & BIT(primary_channel - 1))) {
3109 wpa_printf(MSG_DEBUG,
3110 "EDMG not possible: the primary channel %d is not one of the intersected channels 0x%x",
3111 primary_channel, result.channels);
3112 goto fail;
3113 }
3114
3115 /* Find max contiguous channels */
3116 for (i = 0; i < 6; i++) {
3117 if (result.channels & BIT(i))
3118 contiguous++;
3119 else
3120 contiguous = 0;
3121
3122 if (contiguous > max_contiguous)
3123 max_contiguous = contiguous;
3124 }
3125
3126 /* Assuming AP and STA supports ONLY contiguous channels,
3127 * bw configuration can have value between 4-7.
3128 */
3129 if ((b.bw_config < a.bw_config))
3130 result.bw_config = b.bw_config;
3131 else
3132 result.bw_config = a.bw_config;
3133
3134 if ((max_contiguous >= 2 && result.bw_config < EDMG_BW_CONFIG_5) ||
3135 (max_contiguous >= 1 && result.bw_config < EDMG_BW_CONFIG_4)) {
3136 wpa_printf(MSG_DEBUG,
3137 "EDMG not possible: not enough contiguous channels %d for supporting CB1 or CB2",
3138 max_contiguous);
3139 goto fail;
3140 }
3141
3142 return result;
3143
3144fail:
3145 result.channels = 0;
3146 result.bw_config = 0;
3147 return result;
3148}
3149
3150
3151static struct ieee80211_edmg_config
3152get_supported_edmg(struct wpa_supplicant *wpa_s,
3153 struct hostapd_freq_params *freq,
3154 struct ieee80211_edmg_config request_edmg)
3155{
3156 enum hostapd_hw_mode hw_mode;
3157 struct hostapd_hw_modes *mode = NULL;
3158 u8 primary_channel;
3159
3160 if (!wpa_s->hw.modes)
3161 goto fail;
3162
3163 hw_mode = ieee80211_freq_to_chan(freq->freq, &primary_channel);
3164 if (hw_mode == NUM_HOSTAPD_MODES)
3165 goto fail;
3166
3167 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode);
3168 if (!mode)
3169 goto fail;
3170
3171 return get_edmg_intersection(mode->edmg, request_edmg, primary_channel);
3172
3173fail:
3174 request_edmg.channels = 0;
3175 request_edmg.bw_config = 0;
3176 return request_edmg;
3177}
3178
3179
822c756e
AB
3180#ifdef CONFIG_MBO
3181void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s)
3182{
3183 struct wpa_driver_associate_params params;
3184 u8 *wpa_ie;
3185
3186 /*
3187 * Update MBO connect params only in case of change of MBO attributes
3188 * when connected, if the AP support MBO.
3189 */
3190
3191 if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid ||
3192 !wpa_s->current_bss ||
3193 !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE))
3194 return;
3195
3196 os_memset(&params, 0, sizeof(params));
3197 wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
3198 wpa_s->current_ssid, &params, NULL);
3199 if (!wpa_ie)
3200 return;
3201
3202 wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
3203 os_free(wpa_ie);
3204}
3205#endif /* CONFIG_MBO */
3206
3207
d2ba0d71
VK
3208static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
3209{
3210 struct wpa_connect_work *cwork = work->ctx;
3211 struct wpa_bss *bss = cwork->bss;
3212 struct wpa_ssid *ssid = cwork->ssid;
3213 struct wpa_supplicant *wpa_s = work->wpa_s;
3214 u8 *wpa_ie;
a82aee1f 3215 const u8 *edmg_ie_oper;
d2ba0d71
VK
3216 int use_crypt, ret, i, bssid_changed;
3217 unsigned int cipher_pairwise, cipher_group, cipher_group_mgmt;
3218 struct wpa_driver_associate_params params;
3219 int wep_keys_set = 0;
3220 int assoc_failed = 0;
3221 struct wpa_ssid *old_ssid;
3222 u8 prev_bssid[ETH_ALEN];
3223#ifdef CONFIG_HT_OVERRIDES
3224 struct ieee80211_ht_capabilities htcaps;
3225 struct ieee80211_ht_capabilities htcaps_mask;
3226#endif /* CONFIG_HT_OVERRIDES */
3227#ifdef CONFIG_VHT_OVERRIDES
3228 struct ieee80211_vht_capabilities vhtcaps;
3229 struct ieee80211_vht_capabilities vhtcaps_mask;
3230#endif /* CONFIG_VHT_OVERRIDES */
3231
3232 if (deinit) {
3233 if (work->started) {
3234 wpa_s->connect_work = NULL;
3235
3236 /* cancel possible auth. timeout */
3237 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
3238 NULL);
3239 }
3240 wpas_connect_work_free(cwork);
3241 return;
3242 }
3243
3244 wpa_s->connect_work = work;
3245
3246 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
3247 wpas_network_disabled(wpa_s, ssid)) {
3248 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
3249 wpas_connect_work_done(wpa_s);
3250 return;
3251 }
3252
3253 os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
3254 os_memset(&params, 0, sizeof(params));
3255 wpa_s->reassociate = 0;
3256 wpa_s->eap_expected_failure = 0;
3257 if (bss &&
3258 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
3259#ifdef CONFIG_IEEE80211R
3260 const u8 *ie, *md = NULL;
3261#endif /* CONFIG_IEEE80211R */
3262 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
3263 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
3264 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
3265 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
3266 os_memset(wpa_s->bssid, 0, ETH_ALEN);
3267 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
3268 if (bssid_changed)
3269 wpas_notify_bssid_changed(wpa_s);
3270#ifdef CONFIG_IEEE80211R
3271 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
3272 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
3273 md = ie + 2;
3274 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
3275 if (md) {
3276 /* Prepare for the next transition */
3277 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
3278 }
3279#endif /* CONFIG_IEEE80211R */
3280#ifdef CONFIG_WPS
3281 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
3282 wpa_s->conf->ap_scan == 2 &&
3283 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
3284 /* Use ap_scan==1 style network selection to find the network
3285 */
3286 wpas_connect_work_done(wpa_s);
3287 wpa_s->scan_req = MANUAL_SCAN_REQ;
3288 wpa_s->reassociate = 1;
3289 wpa_supplicant_req_scan(wpa_s, 0, 0);
3290 return;
3291#endif /* CONFIG_WPS */
3292 } else {
3293 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
3294 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3295 if (bss)
3296 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
3297 else
3298 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
3299 }
3300 if (!wpa_s->pno)
3301 wpa_supplicant_cancel_sched_scan(wpa_s);
3302
3303 wpa_supplicant_cancel_scan(wpa_s);
3304
3305 /* Starting new association, so clear the possibly used WPA IE from the
3306 * previous association. */
3307 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
3308
6338c99e 3309 wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, &params, NULL);
d2ba0d71
VK
3310 if (!wpa_ie) {
3311 wpas_connect_work_done(wpa_s);
3312 return;
3313 }
3314
6fc6879b
JM
3315 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
3316 use_crypt = 1;
4848a38d
JM
3317 cipher_pairwise = wpa_s->pairwise_cipher;
3318 cipher_group = wpa_s->group_cipher;
61a56c14 3319 cipher_group_mgmt = wpa_s->mgmt_group_cipher;
6fc6879b
JM
3320 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
3321 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3322 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
3323 use_crypt = 0;
3324 if (wpa_set_wep_keys(wpa_s, ssid)) {
3325 use_crypt = 1;
3326 wep_keys_set = 1;
3327 }
3328 }
ad08c363
JM
3329 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
3330 use_crypt = 0;
6fc6879b
JM
3331
3332#ifdef IEEE8021X_EAPOL
3333 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3334 if ((ssid->eapol_flags &
3335 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
3336 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
3337 !wep_keys_set) {
3338 use_crypt = 0;
3339 } else {
3340 /* Assume that dynamic WEP-104 keys will be used and
3341 * set cipher suites in order for drivers to expect
3342 * encryption. */
4848a38d 3343 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
3344 }
3345 }
3346#endif /* IEEE8021X_EAPOL */
3347
3348 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
3349 /* Set the key before (and later after) association */
3350 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
3351 }
3352
6fc6879b 3353 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 3354 if (bss) {
6fa81a3b
JM
3355 params.ssid = bss->ssid;
3356 params.ssid_len = bss->ssid_len;
4b5b8a53
JM
3357 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set ||
3358 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
f15854d1
JM
3359 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
3360 MACSTR " freq=%u MHz based on scan results "
4b5b8a53 3361 "(bssid_set=%d wps=%d)",
f15854d1 3362 MAC2STR(bss->bssid), bss->freq,
4b5b8a53
JM
3363 ssid->bssid_set,
3364 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
22628eca 3365 params.bssid = bss->bssid;
4ec68377 3366 params.freq.freq = bss->freq;
22628eca 3367 }
7ac7fd43
DS
3368 params.bssid_hint = bss->bssid;
3369 params.freq_hint = bss->freq;
b9074912 3370 params.pbss = bss_is_pbss(bss);
6fc6879b 3371 } else {
43a356b2
PK
3372 if (ssid->bssid_hint_set)
3373 params.bssid_hint = ssid->bssid_hint;
3374
6fc6879b
JM
3375 params.ssid = ssid->ssid;
3376 params.ssid_len = ssid->ssid_len;
90f14962 3377 params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
6fc6879b 3378 }
9e2af29f
NC
3379
3380 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
3381 wpa_s->conf->ap_scan == 2) {
3382 params.bssid = ssid->bssid;
3383 params.fixed_bssid = 1;
3384 }
3385
603a3f34
JL
3386 /* Initial frequency for IBSS/mesh */
3387 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
1830817e
JD
3388 ssid->frequency > 0 && params.freq.freq == 0)
3389 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
dc152f32 3390
8f05577d 3391 if (ssid->mode == WPAS_MODE_IBSS) {
4d9e6fba 3392 params.fixed_freq = ssid->fixed_freq;
8f05577d
JM
3393 if (ssid->beacon_int)
3394 params.beacon_int = ssid->beacon_int;
3395 else
3396 params.beacon_int = wpa_s->conf->beacon_int;
3397 }
3398
a82aee1f
AAL
3399 if (bss && ssid->enable_edmg)
3400 edmg_ie_oper = get_ie_ext((const u8 *) (bss + 1), bss->ie_len,
3401 WLAN_EID_EXT_EDMG_OPERATION);
3402 else
3403 edmg_ie_oper = NULL;
3404
3405 if (edmg_ie_oper) {
3406 params.freq.edmg.channels =
3407 wpa_ie_get_edmg_oper_chans(edmg_ie_oper);
3408 params.freq.edmg.bw_config =
3409 wpa_ie_get_edmg_oper_chan_width(edmg_ie_oper);
3410 wpa_printf(MSG_DEBUG,
3411 "AP supports EDMG channels 0x%x, bw_config %d",
3412 params.freq.edmg.channels,
3413 params.freq.edmg.bw_config);
3414
3415 /* User may ask for specific EDMG channel for EDMG connection
3416 * (must be supported by AP)
3417 */
3418 if (ssid->edmg_channel) {
3419 struct ieee80211_edmg_config configured_edmg;
3420 enum hostapd_hw_mode hw_mode;
3421 u8 primary_channel;
3422
3423 hw_mode = ieee80211_freq_to_chan(bss->freq,
3424 &primary_channel);
3425 if (hw_mode == NUM_HOSTAPD_MODES)
3426 goto edmg_fail;
3427
3428 hostapd_encode_edmg_chan(ssid->enable_edmg,
3429 ssid->edmg_channel,
3430 primary_channel,
3431 &configured_edmg);
3432
3433 if (ieee802_edmg_is_allowed(params.freq.edmg,
3434 configured_edmg)) {
3435 params.freq.edmg = configured_edmg;
3436 wpa_printf(MSG_DEBUG,
3437 "Use EDMG channel %d for connection",
3438 ssid->edmg_channel);
3439 } else {
3440 edmg_fail:
3441 params.freq.edmg.channels = 0;
3442 params.freq.edmg.bw_config = 0;
3443 wpa_printf(MSG_WARNING,
3444 "EDMG channel %d not supported by AP, fallback to DMG",
3445 ssid->edmg_channel);
3446 }
3447 }
3448
3449 if (params.freq.edmg.channels) {
3450 wpa_printf(MSG_DEBUG,
3451 "EDMG before: channels 0x%x, bw_config %d",
3452 params.freq.edmg.channels,
3453 params.freq.edmg.bw_config);
3454 params.freq.edmg = get_supported_edmg(wpa_s,
3455 &params.freq,
3456 params.freq.edmg);
3457 wpa_printf(MSG_DEBUG,
3458 "EDMG after: channels 0x%x, bw_config %d",
3459 params.freq.edmg.channels,
3460 params.freq.edmg.bw_config);
3461 }
3462 }
3463
6fc6879b
JM
3464 params.pairwise_suite = cipher_pairwise;
3465 params.group_suite = cipher_group;
61a56c14 3466 params.mgmt_group_suite = cipher_group_mgmt;
4848a38d 3467 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 3468 params.wpa_proto = wpa_s->wpa_proto;
5538fc93 3469 wpa_s->auth_alg = params.auth_alg;
6fc6879b 3470 params.mode = ssid->mode;
1f6c0ab8 3471 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
3472 for (i = 0; i < NUM_WEP_KEYS; i++) {
3473 if (ssid->wep_key_len[i])
3474 params.wep_key[i] = ssid->wep_key[i];
3475 params.wep_key_len[i] = ssid->wep_key_len[i];
3476 }
3477 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
3478
436ee2fd 3479 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
4848a38d
JM
3480 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
3481 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
3482 params.passphrase = ssid->passphrase;
3483 if (ssid->psk_set)
3484 params.psk = ssid->psk;
b41f2684
CL
3485 }
3486
d896874f
AS
3487 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
3488 (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
3489 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
3490 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
3491 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192))
cb28bd52 3492 params.req_handshake_offload = 1;
d896874f 3493
b41f2684
CL
3494 if (wpa_s->conf->key_mgmt_offload) {
3495 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
666497c8 3496 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
5e3b5197
JM
3497 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
3498 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
b41f2684
CL
3499 params.req_key_mgmt_offload =
3500 ssid->proactive_key_caching < 0 ?
3501 wpa_s->conf->okc : ssid->proactive_key_caching;
3502 else
3503 params.req_key_mgmt_offload = 1;
3504
3505 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
3506 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
3507 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
3508 ssid->psk_set)
3509 params.psk = ssid->psk;
6fc6879b
JM
3510 }
3511
36b15723
JM
3512 params.drop_unencrypted = use_crypt;
3513
3f56a2b7 3514 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
62d49803 3515 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 3516 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
3517 struct wpa_ie_data ie;
3518 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
3519 ie.capabilities &
3520 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
3521 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
3522 "MFP: require MFP");
97d3497e
JM
3523 params.mgmt_frame_protection =
3524 MGMT_FRAME_PROTECTION_REQUIRED;
cf94626c
PK
3525#ifdef CONFIG_OWE
3526 } else if (!rsn && (ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
3527 !ssid->owe_only) {
3528 params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION;
3529#endif /* CONFIG_OWE */
97d3497e
JM
3530 }
3531 }
6fc6879b 3532
ffad8858 3533 params.p2p = ssid->p2p_group;
6e3f4b89 3534
ba307f85
LD
3535 if (wpa_s->p2pdev->set_sta_uapsd)
3536 params.uapsd = wpa_s->p2pdev->sta_uapsd;
eea2fd9e
JM
3537 else
3538 params.uapsd = -1;
3539
80e8a5ee
BG
3540#ifdef CONFIG_HT_OVERRIDES
3541 os_memset(&htcaps, 0, sizeof(htcaps));
3542 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
3543 params.htcaps = (u8 *) &htcaps;
3544 params.htcaps_mask = (u8 *) &htcaps_mask;
3545 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
3546#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
3547#ifdef CONFIG_VHT_OVERRIDES
3548 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
3549 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
3550 params.vhtcaps = &vhtcaps;
3551 params.vhtcaps_mask = &vhtcaps_mask;
95ff3069 3552 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
6aa1cd4e 3553#endif /* CONFIG_VHT_OVERRIDES */
80e8a5ee 3554
8567866d
JJ
3555#ifdef CONFIG_P2P
3556 /*
3557 * If multi-channel concurrency is not supported, check for any
3558 * frequency conflict. In case of any frequency conflict, remove the
3559 * least prioritized connection.
3560 */
3561 if (wpa_s->num_multichan_concurrent < 2) {
d0df6437
IP
3562 int freq, num;
3563 num = get_shared_radio_freqs(wpa_s, &freq, 1);
4ec68377 3564 if (num > 0 && freq > 0 && freq != params.freq.freq) {
d0df6437
IP
3565 wpa_printf(MSG_DEBUG,
3566 "Assoc conflicting freq found (%d != %d)",
4ec68377
JD
3567 freq, params.freq.freq);
3568 if (wpas_p2p_handle_frequency_conflicts(
74656400
SD
3569 wpa_s, params.freq.freq, ssid) < 0) {
3570 wpas_connect_work_done(wpa_s);
1e6780bd 3571 os_free(wpa_ie);
8567866d 3572 return;
74656400 3573 }
8567866d
JJ
3574 }
3575 }
3576#endif /* CONFIG_P2P */
3577
6a5ee810
JM
3578 if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
3579 wpa_s->current_ssid)
3580 params.prev_bssid = prev_bssid;
3581
17fbb751 3582 ret = wpa_drv_associate(wpa_s, &params);
1e6780bd 3583 os_free(wpa_ie);
6fc6879b
JM
3584 if (ret < 0) {
3585 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
3586 "failed");
871f4dd0
JM
3587 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
3588 /*
3589 * The driver is known to mean what is saying, so we
3590 * can stop right here; the association will not
3591 * succeed.
3592 */
3593 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 3594 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
3595 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
3596 return;
3597 }
6fc6879b
JM
3598 /* try to continue anyway; new association will be tried again
3599 * after timeout */
3600 assoc_failed = 1;
3601 }
3602
3603 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
3604 /* Set the key after the association just in case association
3605 * cleared the previously configured key. */
3606 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
3607 /* No need to timeout authentication since there is no key
3608 * management. */
3609 wpa_supplicant_cancel_auth_timeout(wpa_s);
3610 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 3611#ifdef CONFIG_IBSS_RSN
d7dcba70 3612 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
3613 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
3614 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
3615 /*
3616 * RSN IBSS authentication is per-STA and we can disable the
3617 * per-BSSID authentication.
3618 */
3619 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 3620#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
3621 } else {
3622 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
3623 int timeout = 60;
3624
3625 if (assoc_failed) {
3626 /* give IBSS a bit more time */
d7dcba70 3627 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
3628 } else if (wpa_s->conf->ap_scan == 1) {
3629 /* give IBSS a bit more time */
d7dcba70 3630 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 3631 }
6fc6879b
JM
3632 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
3633 }
3634
66562e9c
JM
3635 if (wep_keys_set &&
3636 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
3637 /* Set static WEP keys again */
3638 wpa_set_wep_keys(wpa_s, ssid);
3639 }
3640
3641 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
3642 /*
3643 * Do not allow EAP session resumption between different
3644 * network configurations.
3645 */
3646 eapol_sm_invalidate_cached_session(wpa_s->eapol);
3647 }
8bac466b 3648 old_ssid = wpa_s->current_ssid;
6fc6879b 3649 wpa_s->current_ssid = ssid;
ece4ac5f
MG
3650
3651 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
4d3be9cd 3652 wpa_s->current_bss = bss;
ece4ac5f
MG
3653#ifdef CONFIG_HS20
3654 hs20_configure_frame_filters(wpa_s);
3655#endif /* CONFIG_HS20 */
3656 }
3657
6fc6879b
JM
3658 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
3659 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
3660 if (old_ssid != wpa_s->current_ssid)
3661 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
3662}
3663
3664
09f58c09
JM
3665static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
3666 const u8 *addr)
3667{
3668 struct wpa_ssid *old_ssid;
3669
c155305f 3670 wpas_connect_work_done(wpa_s);
09f58c09 3671 wpa_clear_keys(wpa_s, addr);
09f58c09 3672 old_ssid = wpa_s->current_ssid;
0d30cc24 3673 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
3674 wpa_sm_set_config(wpa_s->wpa, NULL);
3675 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
3676 if (old_ssid != wpa_s->current_ssid)
3677 wpas_notify_network_changed(wpa_s);
3678 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3679}
3680
3681
6fc6879b
JM
3682/**
3683 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
3684 * @wpa_s: Pointer to wpa_supplicant data
3685 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
3686 *
073ab58f 3687 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
3688 * current AP.
3689 */
3690void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
4be17ffb 3691 u16 reason_code)
6fc6879b
JM
3692{
3693 u8 *addr = NULL;
ef48ff94 3694 union wpa_event_data event;
42d23547 3695 int zero_addr = 0;
8bac466b 3696
42d23547 3697 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
cfde99a8 3698 " pending_bssid=" MACSTR " reason=%d (%s) state=%s",
42d23547 3699 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
cfde99a8
AK
3700 reason_code, reason2str(reason_code),
3701 wpa_supplicant_state_txt(wpa_s->wpa_state));
42d23547 3702
04e3d815
MK
3703 if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
3704 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
3705 wpa_s->wpa_state == WPA_ASSOCIATING))
42d23547 3706 addr = wpa_s->pending_bssid;
04e3d815
MK
3707 else if (!is_zero_ether_addr(wpa_s->bssid))
3708 addr = wpa_s->bssid;
42d23547
JM
3709 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
3710 /*
3711 * When using driver-based BSS selection, we may not know the
3712 * BSSID with which we are currently trying to associate. We
3713 * need to notify the driver of this disconnection even in such
3714 * a case, so use the all zeros address here.
3715 */
6fc6879b 3716 addr = wpa_s->bssid;
42d23547
JM
3717 zero_addr = 1;
3718 }
3719
5abc7823
VN
3720 if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
3721 wpa_s->enabled_4addr_mode = 0;
3722
7b44ff2c
SD
3723#ifdef CONFIG_TDLS
3724 wpa_tdls_teardown_peers(wpa_s->wpa);
3725#endif /* CONFIG_TDLS */
3726
603a3f34
JL
3727#ifdef CONFIG_MESH
3728 if (wpa_s->ifmsh) {
a39b040b
SB
3729 struct mesh_conf *mconf;
3730
3731 mconf = wpa_s->ifmsh->mconf;
6174de66
JM
3732 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
3733 wpa_s->ifname);
a39b040b
SB
3734 wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
3735 mconf->meshid_len, reason_code);
603a3f34
JL
3736 wpa_supplicant_leave_mesh(wpa_s);
3737 }
3738#endif /* CONFIG_MESH */
3739
42d23547
JM
3740 if (addr) {
3741 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94 3742 os_memset(&event, 0, sizeof(event));
4be17ffb 3743 event.deauth_info.reason_code = reason_code;
ef48ff94
JM
3744 event.deauth_info.locally_generated = 1;
3745 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
3746 if (zero_addr)
3747 addr = NULL;
6fc6879b 3748 }
09f58c09
JM
3749
3750 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
3751}
3752
dca1a511
DS
3753static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
3754 struct wpa_ssid *ssid)
3755{
3756 if (!ssid || !ssid->disabled || ssid->disabled == 2)
3757 return;
3758
3759 ssid->disabled = 0;
91073cca 3760 ssid->owe_transition_bss_select_count = 0;
dca1a511
DS
3761 wpas_clear_temp_disabled(wpa_s, ssid, 1);
3762 wpas_notify_network_enabled_changed(wpa_s, ssid);
3763
3764 /*
3765 * Try to reassociate since there is no current configuration and a new
3766 * network was made available.
3767 */
d2592497 3768 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
3769 wpa_s->reassociate = 1;
3770}
3771
6fc6879b 3772
d015bb05
RP
3773/**
3774 * wpa_supplicant_add_network - Add a new network
3775 * @wpa_s: wpa_supplicant structure for a network interface
3776 * Returns: The new network configuration or %NULL if operation failed
3777 *
3778 * This function performs the following operations:
3779 * 1. Adds a new network.
3780 * 2. Send network addition notification.
3781 * 3. Marks the network disabled.
3782 * 4. Set network default parameters.
3783 */
3784struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
3785{
3786 struct wpa_ssid *ssid;
3787
3788 ssid = wpa_config_add_network(wpa_s->conf);
3789 if (!ssid)
3790 return NULL;
3791 wpas_notify_network_added(wpa_s, ssid);
3792 ssid->disabled = 1;
3793 wpa_config_set_network_defaults(ssid);
3794
3795 return ssid;
3796}
3797
3798
3799/**
3800 * wpa_supplicant_remove_network - Remove a configured network based on id
3801 * @wpa_s: wpa_supplicant structure for a network interface
3802 * @id: Unique network id to search for
3803 * Returns: 0 on success, or -1 if the network was not found, -2 if the network
3804 * could not be removed
3805 *
3806 * This function performs the following operations:
3807 * 1. Removes the network.
3808 * 2. Send network removal notification.
3809 * 3. Update internal state machines.
3810 * 4. Stop any running sched scans.
3811 */
3812int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
3813{
3814 struct wpa_ssid *ssid;
3815 int was_disabled;
3816
3817 ssid = wpa_config_get_network(wpa_s->conf, id);
3818 if (!ssid)
3819 return -1;
3820 wpas_notify_network_removed(wpa_s, ssid);
3821
3822 if (wpa_s->last_ssid == ssid)
3823 wpa_s->last_ssid = NULL;
3824
3825 if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
3826#ifdef CONFIG_SME
3827 wpa_s->sme.prev_bssid_set = 0;
3828#endif /* CONFIG_SME */
3829 /*
3830 * Invalidate the EAP session cache if the current or
3831 * previously used network is removed.
3832 */
3833 eapol_sm_invalidate_cached_session(wpa_s->eapol);
3834 }
3835
3836 if (ssid == wpa_s->current_ssid) {
3837 wpa_sm_set_config(wpa_s->wpa, NULL);
3838 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
3839
3840 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
3841 wpa_s->own_disconnect_req = 1;
3842 wpa_supplicant_deauthenticate(wpa_s,
3843 WLAN_REASON_DEAUTH_LEAVING);
3844 }
3845
3846 was_disabled = ssid->disabled;
3847
3848 if (wpa_config_remove_network(wpa_s->conf, id) < 0)
3849 return -2;
3850
3851 if (!was_disabled && wpa_s->sched_scanning) {
3852 wpa_printf(MSG_DEBUG,
3853 "Stop ongoing sched_scan to remove network from filters");
3854 wpa_supplicant_cancel_sched_scan(wpa_s);
3855 wpa_supplicant_req_scan(wpa_s, 0, 0);
3856 }
3857
3858 return 0;
3859}
3860
3861
86b89452
WS
3862/**
3863 * wpa_supplicant_enable_network - Mark a configured network as enabled
3864 * @wpa_s: wpa_supplicant structure for a network interface
3865 * @ssid: wpa_ssid structure for a configured network or %NULL
3866 *
3867 * Enables the specified network or all networks if no network specified.
3868 */
3869void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
3870 struct wpa_ssid *ssid)
3871{
86b89452 3872 if (ssid == NULL) {
14f79078
JM
3873 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3874 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
3875 } else
3876 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 3877
5a1d9d1a
JM
3878 if (wpa_s->reassociate && !wpa_s->disconnected &&
3879 (!wpa_s->current_ssid ||
3880 wpa_s->wpa_state == WPA_DISCONNECTED ||
3881 wpa_s->wpa_state == WPA_SCANNING)) {
dca1a511
DS
3882 if (wpa_s->sched_scanning) {
3883 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
3884 "new network to scan filters");
3885 wpa_supplicant_cancel_sched_scan(wpa_s);
3886 }
86b89452 3887
35d40309
JM
3888 if (wpa_supplicant_fast_associate(wpa_s) != 1) {
3889 wpa_s->scan_req = NORMAL_SCAN_REQ;
dad153d1 3890 wpa_supplicant_req_scan(wpa_s, 0, 0);
35d40309 3891 }
86b89452
WS
3892 }
3893}
3894
3895
3896/**
3897 * wpa_supplicant_disable_network - Mark a configured network as disabled
3898 * @wpa_s: wpa_supplicant structure for a network interface
3899 * @ssid: wpa_ssid structure for a configured network or %NULL
3900 *
3901 * Disables the specified network or all networks if no network specified.
3902 */
3903void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
3904 struct wpa_ssid *ssid)
3905{
3906 struct wpa_ssid *other_ssid;
3907 int was_disabled;
3908
3909 if (ssid == NULL) {
725fc39e
DS
3910 if (wpa_s->sched_scanning)
3911 wpa_supplicant_cancel_sched_scan(wpa_s);
3912
4dac0245
JM
3913 for (other_ssid = wpa_s->conf->ssid; other_ssid;
3914 other_ssid = other_ssid->next) {
86b89452 3915 was_disabled = other_ssid->disabled;
4dac0245
JM
3916 if (was_disabled == 2)
3917 continue; /* do not change persistent P2P group
3918 * data */
86b89452
WS
3919
3920 other_ssid->disabled = 1;
3921
3922 if (was_disabled != other_ssid->disabled)
3923 wpas_notify_network_enabled_changed(
3924 wpa_s, other_ssid);
86b89452 3925 }
0661163e
SD
3926 if (wpa_s->current_ssid) {
3927 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
3928 wpa_s->own_disconnect_req = 1;
07783eaa 3929 wpa_supplicant_deauthenticate(
86b89452 3930 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
0661163e 3931 }
4dac0245 3932 } else if (ssid->disabled != 2) {
0661163e
SD
3933 if (ssid == wpa_s->current_ssid) {
3934 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
3935 wpa_s->own_disconnect_req = 1;
07783eaa 3936 wpa_supplicant_deauthenticate(
86b89452 3937 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
0661163e 3938 }
86b89452
WS
3939
3940 was_disabled = ssid->disabled;
3941
3942 ssid->disabled = 1;
3943
725fc39e 3944 if (was_disabled != ssid->disabled) {
86b89452 3945 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
3946 if (wpa_s->sched_scanning) {
3947 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
3948 "to remove network from filters");
3949 wpa_supplicant_cancel_sched_scan(wpa_s);
3950 wpa_supplicant_req_scan(wpa_s, 0, 0);
3951 }
3952 }
86b89452
WS
3953 }
3954}
3955
3956
3957/**
3958 * wpa_supplicant_select_network - Attempt association with a network
3959 * @wpa_s: wpa_supplicant structure for a network interface
3960 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
3961 */
3962void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
3963 struct wpa_ssid *ssid)
3964{
3965
3966 struct wpa_ssid *other_ssid;
d93dfbd5 3967 int disconnected = 0;
86b89452 3968
d93dfbd5 3969 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
e66bcedd
JM
3970 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
3971 wpa_s->own_disconnect_req = 1;
07783eaa 3972 wpa_supplicant_deauthenticate(
86b89452 3973 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
3974 disconnected = 1;
3975 }
86b89452 3976
00e5e3d5
JM
3977 if (ssid)
3978 wpas_clear_temp_disabled(wpa_s, ssid, 1);
3979
86b89452
WS
3980 /*
3981 * Mark all other networks disabled or mark all networks enabled if no
3982 * network specified.
3983 */
4dac0245
JM
3984 for (other_ssid = wpa_s->conf->ssid; other_ssid;
3985 other_ssid = other_ssid->next) {
86b89452 3986 int was_disabled = other_ssid->disabled;
4dac0245
JM
3987 if (was_disabled == 2)
3988 continue; /* do not change persistent P2P group data */
86b89452
WS
3989
3990 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
3991 if (was_disabled && !other_ssid->disabled)
3992 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
3993
3994 if (was_disabled != other_ssid->disabled)
3995 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 3996 }
2a6f78fb 3997
d38c7be0
JM
3998 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
3999 wpa_s->wpa_state >= WPA_AUTHENTICATING) {
2a6f78fb
JJ
4000 /* We are already associated with the selected network */
4001 wpa_printf(MSG_DEBUG, "Already associated with the "
4002 "selected network - do nothing");
4003 return;
4004 }
4005
25a8f9e3 4006 if (ssid) {
96efeeb6 4007 wpa_s->current_ssid = ssid;
25a8f9e3 4008 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
603a3f34
JL
4009 wpa_s->connect_without_scan =
4010 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
701f3961
AS
4011
4012 /*
4013 * Don't optimize next scan freqs since a new ESS has been
4014 * selected.
4015 */
4016 os_free(wpa_s->next_scan_freqs);
4017 wpa_s->next_scan_freqs = NULL;
603a3f34
JL
4018 } else {
4019 wpa_s->connect_without_scan = NULL;
25a8f9e3 4020 }
603a3f34 4021
86b89452
WS
4022 wpa_s->disconnected = 0;
4023 wpa_s->reassociate = 1;
447cd5f2
JM
4024#if defined(CONFIG_SAE) && defined(CONFIG_SME)
4025 os_free(wpa_s->sme.sae_rejected_groups);
4026 wpa_s->sme.sae_rejected_groups = NULL;
4027#endif /* CONFIG_SAE && CONFIG_SME */
2cb40e9f 4028 wpa_s->last_owe_group = 0;
05a2fb0d 4029 if (ssid) {
91073cca 4030 ssid->owe_transition_bss_select_count = 0;
05a2fb0d
JM
4031 wpa_s_setup_sae_pt(wpa_s->conf, ssid);
4032 }
cecdddc1 4033
e4a35f07 4034 if (wpa_s->connect_without_scan ||
35d40309
JM
4035 wpa_supplicant_fast_associate(wpa_s) != 1) {
4036 wpa_s->scan_req = NORMAL_SCAN_REQ;
be7ebd89 4037 wpas_scan_reset_sched_scan(wpa_s);
cecdddc1 4038 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
35d40309 4039 }
86b89452 4040
a1641d26
JM
4041 if (ssid)
4042 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
4043}
4044
4045
bdec7ee5
MS
4046/**
4047 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
4048 * @wpa_s: wpa_supplicant structure for a network interface
4049 * @pkcs11_engine_path: PKCS #11 engine path or NULL
4050 * @pkcs11_module_path: PKCS #11 module path or NULL
4051 * Returns: 0 on success; -1 on failure
4052 *
4053 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
4054 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
4055 * module path fails the paths will be reset to the default value (NULL).
4056 */
4057int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
4058 const char *pkcs11_engine_path,
4059 const char *pkcs11_module_path)
4060{
4061 char *pkcs11_engine_path_copy = NULL;
4062 char *pkcs11_module_path_copy = NULL;
4063
4064 if (pkcs11_engine_path != NULL) {
4065 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
4066 if (pkcs11_engine_path_copy == NULL)
4067 return -1;
4068 }
4069 if (pkcs11_module_path != NULL) {
4070 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
04c366cb 4071 if (pkcs11_module_path_copy == NULL) {
bdec7ee5
MS
4072 os_free(pkcs11_engine_path_copy);
4073 return -1;
4074 }
4075 }
4076
4077 os_free(wpa_s->conf->pkcs11_engine_path);
4078 os_free(wpa_s->conf->pkcs11_module_path);
4079 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
4080 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
4081
4082 wpa_sm_set_eapol(wpa_s->wpa, NULL);
4083 eapol_sm_deinit(wpa_s->eapol);
4084 wpa_s->eapol = NULL;
4085 if (wpa_supplicant_init_eapol(wpa_s)) {
4086 /* Error -> Reset paths to the default value (NULL) once. */
4087 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
4088 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
4089 NULL);
4090
4091 return -1;
4092 }
4093 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4094
4095 return 0;
4096}
4097
4098
86b89452
WS
4099/**
4100 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
4101 * @wpa_s: wpa_supplicant structure for a network interface
4102 * @ap_scan: AP scan mode
4103 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
4104 *
4105 */
4106int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
4107{
4108
4109 int old_ap_scan;
4110
4111 if (ap_scan < 0 || ap_scan > 2)
4112 return -1;
4113
8406cd35
JM
4114 if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
4115 wpa_printf(MSG_INFO,
4116 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
4117 }
4118
48f8e036
DS
4119#ifdef ANDROID
4120 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
4121 wpa_s->wpa_state >= WPA_ASSOCIATING &&
4122 wpa_s->wpa_state < WPA_COMPLETED) {
4123 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
4124 "associating", wpa_s->conf->ap_scan, ap_scan);
4125 return 0;
4126 }
4127#endif /* ANDROID */
4128
86b89452
WS
4129 old_ap_scan = wpa_s->conf->ap_scan;
4130 wpa_s->conf->ap_scan = ap_scan;
4131
4132 if (old_ap_scan != wpa_s->conf->ap_scan)
4133 wpas_notify_ap_scan_changed(wpa_s);
4134
4135 return 0;
4136}
4137
4138
78633c37
SL
4139/**
4140 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
4141 * @wpa_s: wpa_supplicant structure for a network interface
4142 * @expire_age: Expiration age in seconds
4143 * Returns: 0 if succeed or -1 if expire_age has an invalid value
4144 *
4145 */
4146int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
4147 unsigned int bss_expire_age)
4148{
4149 if (bss_expire_age < 10) {
4150 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
4151 bss_expire_age);
4152 return -1;
4153 }
4154 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
4155 bss_expire_age);
4156 wpa_s->conf->bss_expiration_age = bss_expire_age;
4157
4158 return 0;
4159}
4160
4161
4162/**
4163 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
4164 * @wpa_s: wpa_supplicant structure for a network interface
4165 * @expire_count: number of scans after which an unseen BSS is reclaimed
4166 * Returns: 0 if succeed or -1 if expire_count has an invalid value
4167 *
4168 */
4169int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
4170 unsigned int bss_expire_count)
4171{
4172 if (bss_expire_count < 1) {
4173 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
4174 bss_expire_count);
4175 return -1;
4176 }
4177 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
4178 bss_expire_count);
4179 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
4180
4181 return 0;
4182}
4183
4184
c6e86b63
MA
4185/**
4186 * wpa_supplicant_set_scan_interval - Set scan interval
4187 * @wpa_s: wpa_supplicant structure for a network interface
4188 * @scan_interval: scan interval in seconds
4189 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
4190 *
4191 */
4192int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
4193 int scan_interval)
4194{
4195 if (scan_interval < 0) {
4196 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
4197 scan_interval);
4198 return -1;
4199 }
4200 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
4201 scan_interval);
9e737f08 4202 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
4203
4204 return 0;
4205}
4206
4207
86b89452
WS
4208/**
4209 * wpa_supplicant_set_debug_params - Set global debug params
4210 * @global: wpa_global structure
4211 * @debug_level: debug level
4212 * @debug_timestamp: determines if show timestamp in debug data
4213 * @debug_show_keys: determines if show keys in debug data
4214 * Returns: 0 if succeed or -1 if debug_level has wrong value
4215 */
4216int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
4217 int debug_timestamp, int debug_show_keys)
4218{
4219
4220 int old_level, old_timestamp, old_show_keys;
4221
4222 /* check for allowed debuglevels */
14dc0011
PS
4223 if (debug_level != MSG_EXCESSIVE &&
4224 debug_level != MSG_MSGDUMP &&
86b89452
WS
4225 debug_level != MSG_DEBUG &&
4226 debug_level != MSG_INFO &&
4227 debug_level != MSG_WARNING &&
4228 debug_level != MSG_ERROR)
4229 return -1;
4230
4231 old_level = wpa_debug_level;
4232 old_timestamp = wpa_debug_timestamp;
4233 old_show_keys = wpa_debug_show_keys;
4234
4235 wpa_debug_level = debug_level;
4236 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
4237 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
4238
db9133ac
WS
4239 if (wpa_debug_level != old_level)
4240 wpas_notify_debug_level_changed(global);
4241 if (wpa_debug_timestamp != old_timestamp)
4242 wpas_notify_debug_timestamp_changed(global);
4243 if (wpa_debug_show_keys != old_show_keys)
4244 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
4245
4246 return 0;
4247}
4248
4249
e8b96490
JM
4250#ifdef CONFIG_OWE
4251static int owe_trans_ssid_match(struct wpa_supplicant *wpa_s, const u8 *bssid,
4252 const u8 *entry_ssid, size_t entry_ssid_len)
4253{
4254 const u8 *owe, *pos, *end;
4255 u8 ssid_len;
4256 struct wpa_bss *bss;
4257
4258 /* Check network profile SSID aganst the SSID in the
4259 * OWE Transition Mode element. */
4260
4261 bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
4262 if (!bss)
4263 return 0;
4264
4265 owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
4266 if (!owe)
4267 return 0;
4268
4269 pos = owe + 6;
4270 end = owe + 2 + owe[1];
4271
4272 if (end - pos < ETH_ALEN + 1)
4273 return 0;
4274 pos += ETH_ALEN;
4275 ssid_len = *pos++;
4276 if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
4277 return 0;
4278
4279 return entry_ssid_len == ssid_len &&
4280 os_memcmp(pos, entry_ssid, ssid_len) == 0;
4281}
4282#endif /* CONFIG_OWE */
4283
4284
6fc6879b
JM
4285/**
4286 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
4287 * @wpa_s: Pointer to wpa_supplicant data
4288 * Returns: A pointer to the current network structure or %NULL on failure
4289 */
4290struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
4291{
4292 struct wpa_ssid *entry;
eaa8eefe 4293 u8 ssid[SSID_MAX_LEN];
6fc6879b
JM
4294 int res;
4295 size_t ssid_len;
4296 u8 bssid[ETH_ALEN];
4297 int wired;
4298
17fbb751
JM
4299 res = wpa_drv_get_ssid(wpa_s, ssid);
4300 if (res < 0) {
4301 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
4302 "driver");
4303 return NULL;
6fc6879b 4304 }
17fbb751 4305 ssid_len = res;
6fc6879b 4306
17fbb751 4307 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
4308 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
4309 "driver");
6fc6879b
JM
4310 return NULL;
4311 }
4312
c2a04078
JM
4313 wired = wpa_s->conf->ap_scan == 0 &&
4314 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
4315
4316 entry = wpa_s->conf->ssid;
4317 while (entry) {
349493bd 4318 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b 4319 ((ssid_len == entry->ssid_len &&
c4fccfc7
JM
4320 (!entry->ssid ||
4321 os_memcmp(ssid, entry->ssid, ssid_len) == 0)) ||
4322 wired) &&
6fc6879b
JM
4323 (!entry->bssid_set ||
4324 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
4325 return entry;
24c23d1b 4326#ifdef CONFIG_WPS
349493bd 4327 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
4328 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
4329 (entry->ssid == NULL || entry->ssid_len == 0) &&
4330 (!entry->bssid_set ||
4331 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
4332 return entry;
4333#endif /* CONFIG_WPS */
7d232e23 4334
e8b96490
JM
4335#ifdef CONFIG_OWE
4336 if (!wpas_network_disabled(wpa_s, entry) &&
4337 owe_trans_ssid_match(wpa_s, bssid, entry->ssid,
4338 entry->ssid_len) &&
4339 (!entry->bssid_set ||
4340 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
4341 return entry;
4342#endif /* CONFIG_OWE */
4343
349493bd 4344 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
4345 entry->ssid_len == 0 &&
4346 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
4347 return entry;
4348
6fc6879b
JM
4349 entry = entry->next;
4350 }
4351
4352 return NULL;
4353}
4354
4355
7756114f
JM
4356static int select_driver(struct wpa_supplicant *wpa_s, int i)
4357{
4358 struct wpa_global *global = wpa_s->global;
4359
4360 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
45e3fc72 4361 global->drv_priv[i] = wpa_drivers[i]->global_init(global);
7756114f
JM
4362 if (global->drv_priv[i] == NULL) {
4363 wpa_printf(MSG_ERROR, "Failed to initialize driver "
4364 "'%s'", wpa_drivers[i]->name);
4365 return -1;
4366 }
4367 }
4368
4369 wpa_s->driver = wpa_drivers[i];
4370 wpa_s->global_drv_priv = global->drv_priv[i];
4371
4372 return 0;
4373}
4374
4375
6fc6879b
JM
4376static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
4377 const char *name)
4378{
4379 int i;
362f781e 4380 size_t len;
74b1c84a 4381 const char *pos, *driver = name;
6fc6879b
JM
4382
4383 if (wpa_s == NULL)
4384 return -1;
4385
c5121837 4386 if (wpa_drivers[0] == NULL) {
f049052b
BG
4387 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
4388 "wpa_supplicant");
6fc6879b
JM
4389 return -1;
4390 }
4391
4392 if (name == NULL) {
4393 /* default to first driver in the list */
7756114f 4394 return select_driver(wpa_s, 0);
6fc6879b
JM
4395 }
4396
74b1c84a
SO
4397 do {
4398 pos = os_strchr(driver, ',');
4399 if (pos)
4400 len = pos - driver;
4401 else
4402 len = os_strlen(driver);
4403
4404 for (i = 0; wpa_drivers[i]; i++) {
4405 if (os_strlen(wpa_drivers[i]->name) == len &&
4406 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
4407 0) {
4408 /* First driver that succeeds wins */
4409 if (select_driver(wpa_s, i) == 0)
4410 return 0;
4411 }
6fc6879b 4412 }
74b1c84a
SO
4413
4414 driver = pos + 1;
4415 } while (pos);
6fc6879b 4416
f049052b 4417 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
4418 return -1;
4419}
4420
4421
a8e0505b
JM
4422/**
4423 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
4424 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
4425 * with struct wpa_driver_ops::init()
4426 * @src_addr: Source address of the EAPOL frame
4427 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
4428 * @len: Length of the EAPOL data
4429 *
4430 * This function is called for each received EAPOL frame. Most driver
4431 * interfaces rely on more generic OS mechanism for receiving frames through
4432 * l2_packet, but if such a mechanism is not available, the driver wrapper may
4433 * take care of received EAPOL frames and deliver them to the core supplicant
4434 * code by calling this function.
4435 */
6fc6879b
JM
4436void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
4437 const u8 *buf, size_t len)
4438{
4439 struct wpa_supplicant *wpa_s = ctx;
4440
f049052b 4441 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
4442 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
4443
02adead5
MK
4444#ifdef CONFIG_TESTING_OPTIONS
4445 if (wpa_s->ignore_auth_resp) {
4446 wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
4447 return;
4448 }
4449#endif /* CONFIG_TESTING_OPTIONS */
4450
3ab35a66
JM
4451 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
4452 (wpa_s->last_eapol_matches_bssid &&
4453#ifdef CONFIG_AP
4454 !wpa_s->ap_iface &&
4455#endif /* CONFIG_AP */
4456 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
4457 /*
4458 * There is possible race condition between receiving the
4459 * association event and the EAPOL frame since they are coming
4460 * through different paths from the driver. In order to avoid
4461 * issues in trying to process the EAPOL frame before receiving
4462 * association information, lets queue it for processing until
3ab35a66
JM
4463 * the association event is received. This may also be needed in
4464 * driver-based roaming case, so also use src_addr != BSSID as a
4465 * trigger if we have previously confirmed that the
4466 * Authenticator uses BSSID as the src_addr (which is not the
4467 * case with wired IEEE 802.1X).
1ff73338 4468 */
f049052b 4469 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
4470 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
4471 wpa_supplicant_state_txt(wpa_s->wpa_state),
4472 MAC2STR(wpa_s->bssid));
1ff73338
JM
4473 wpabuf_free(wpa_s->pending_eapol_rx);
4474 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
4475 if (wpa_s->pending_eapol_rx) {
c2be937c 4476 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
4477 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
4478 ETH_ALEN);
4479 }
4480 return;
4481 }
4482
3ab35a66
JM
4483 wpa_s->last_eapol_matches_bssid =
4484 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
4485
db149ac9
JM
4486#ifdef CONFIG_AP
4487 if (wpa_s->ap_iface) {
4488 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
4489 return;
4490 }
4491#endif /* CONFIG_AP */
4492
6fc6879b 4493 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
4494 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
4495 "no key management is configured");
6fc6879b
JM
4496 return;
4497 }
4498
4499 if (wpa_s->eapol_received == 0 &&
436ee2fd 4500 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) ||
56586197 4501 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
4502 wpa_s->wpa_state != WPA_COMPLETED) &&
4503 (wpa_s->current_ssid == NULL ||
f74618cb 4504 wpa_s->current_ssid->mode != WPAS_MODE_IBSS)) {
6fc6879b 4505 /* Timeout for completing IEEE 802.1X and WPA authentication */
5add4101
JM
4506 int timeout = 10;
4507
4508 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
4509 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
4510 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
4511 /* Use longer timeout for IEEE 802.1X/EAP */
4512 timeout = 70;
4513 }
4514
c7dafdf9 4515#ifdef CONFIG_WPS
5add4101
JM
4516 if (wpa_s->current_ssid && wpa_s->current_bss &&
4517 (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
4518 eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
4519 /*
4520 * Use shorter timeout if going through WPS AP iteration
4521 * for PIN config method with an AP that does not
4522 * advertise Selected Registrar.
4523 */
4524 struct wpabuf *wps_ie;
4525
4526 wps_ie = wpa_bss_get_vendor_ie_multi(
4527 wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
0ef1e290
JM
4528 if (wps_ie &&
4529 !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
5add4101
JM
4530 timeout = 10;
4531 wpabuf_free(wps_ie);
4532 }
c7dafdf9 4533#endif /* CONFIG_WPS */
5add4101
JM
4534
4535 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
6fc6879b
JM
4536 }
4537 wpa_s->eapol_received++;
4538
4539 if (wpa_s->countermeasures) {
f049052b
BG
4540 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
4541 "EAPOL packet");
6fc6879b
JM
4542 return;
4543 }
4544
8be18440
JM
4545#ifdef CONFIG_IBSS_RSN
4546 if (wpa_s->current_ssid &&
d7dcba70 4547 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
4548 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
4549 return;
4550 }
4551#endif /* CONFIG_IBSS_RSN */
4552
6fc6879b
JM
4553 /* Source address of the incoming EAPOL frame could be compared to the
4554 * current BSSID. However, it is possible that a centralized
4555 * Authenticator could be using another MAC address than the BSSID of
4556 * an AP, so just allow any address to be used for now. The replies are
4557 * still sent to the current BSSID (if available), though. */
4558
4559 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 4560 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
a1ea1b45 4561 wpa_s->key_mgmt != WPA_KEY_MGMT_OWE &&
567da5bb 4562 wpa_s->key_mgmt != WPA_KEY_MGMT_DPP &&
6fc6879b
JM
4563 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
4564 return;
4565 wpa_drv_poll(wpa_s);
436ee2fd 4566 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK))
6fc6879b 4567 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 4568 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
4569 /*
4570 * Set portValid = TRUE here since we are going to skip 4-way
4571 * handshake processing which would normally set portValid. We
4572 * need this to allow the EAPOL state machines to be completed
4573 * without going through EAPOL-Key handshake.
4574 */
4575 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
4576 }
4577}
4578
4579
bfba8deb 4580int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 4581{
2961bfa8
JM
4582 if ((!wpa_s->p2p_mgmt ||
4583 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4584 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 4585 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
4586 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
4587 wpa_drv_get_mac_addr(wpa_s),
4588 ETH_P_EAPOL,
4589 wpa_supplicant_rx_eapol, wpa_s, 0);
4590 if (wpa_s->l2 == NULL)
4591 return -1;
d89edb61
DC
4592
4593 if (l2_packet_set_packet_filter(wpa_s->l2,
4594 L2_PACKET_FILTER_PKTTYPE))
4595 wpa_dbg(wpa_s, MSG_DEBUG,
4596 "Failed to attach pkt_type filter");
fdadd5fe
JM
4597 } else {
4598 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
4599 if (addr)
4600 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
4601 }
4602
4603 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 4604 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
4605 return -1;
4606 }
4607
c267753b 4608 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
8788a314 4609 wpas_wps_update_mac_addr(wpa_s);
c267753b 4610
bfba8deb
JM
4611 return 0;
4612}
4613
4614
25f839c6
JM
4615static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
4616 const u8 *buf, size_t len)
4617{
4618 struct wpa_supplicant *wpa_s = ctx;
4619 const struct l2_ethhdr *eth;
4620
4621 if (len < sizeof(*eth))
4622 return;
4623 eth = (const struct l2_ethhdr *) buf;
4624
4625 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
4626 !(eth->h_dest[0] & 0x01)) {
4627 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
4628 " (bridge - not for this interface - ignore)",
4629 MAC2STR(src_addr), MAC2STR(eth->h_dest));
4630 return;
4631 }
4632
4633 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
4634 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
4635 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
4636 len - sizeof(*eth));
4637}
4638
4639
bfba8deb
JM
4640/**
4641 * wpa_supplicant_driver_init - Initialize driver interface parameters
4642 * @wpa_s: Pointer to wpa_supplicant data
4643 * Returns: 0 on success, -1 on failure
4644 *
4645 * This function is called to initialize driver interface parameters.
4646 * wpa_drv_init() must have been called before this function to initialize the
4647 * driver interface.
4648 */
4649int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
4650{
4651 static int interface_count = 0;
4652
4653 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
4654 return -1;
4655
c68f6200
AS
4656 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
4657 MAC2STR(wpa_s->own_addr));
a313d17d 4658 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
c68f6200
AS
4659 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
4660
6fc6879b 4661 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
4662 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
4663 "interface '%s'", wpa_s->bridge_ifname);
e6dd8196
JM
4664 wpa_s->l2_br = l2_packet_init_bridge(
4665 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
4666 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
6fc6879b 4667 if (wpa_s->l2_br == NULL) {
f049052b
BG
4668 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
4669 "connection for the bridge interface '%s'",
4670 wpa_s->bridge_ifname);
6fc6879b
JM
4671 return -1;
4672 }
4673 }
4674
8406cd35
JM
4675 if (wpa_s->conf->ap_scan == 2 &&
4676 os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
4677 wpa_printf(MSG_INFO,
4678 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
4679 }
4680
6fc6879b
JM
4681 wpa_clear_keys(wpa_s, NULL);
4682
4683 /* Make sure that TKIP countermeasures are not left enabled (could
4684 * happen if wpa_supplicant is killed during countermeasures. */
4685 wpa_drv_set_countermeasures(wpa_s, 0);
4686
f049052b 4687 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
4688 wpa_drv_flush_pmkid(wpa_s);
4689
ba2a573c 4690 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
4691 wpa_s->prev_scan_wildcard = 0;
4692
349493bd 4693 if (wpa_supplicant_enabled_networks(wpa_s)) {
a0e9d892
AS
4694 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
4695 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
4696 interface_count = 0;
4697 }
ee82e33d 4698#ifndef ANDROID
3a94adbf 4699 if (!wpa_s->p2p_mgmt &&
5d0d72a3
BG
4700 wpa_supplicant_delayed_sched_scan(wpa_s,
4701 interface_count % 3,
6a90053c 4702 100000))
5d0d72a3 4703 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
a4cba8f1 4704 100000);
ee82e33d 4705#endif /* ANDROID */
74e259ec
JM
4706 interface_count++;
4707 } else
4708 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
4709
4710 return 0;
4711}
4712
4713
4714static int wpa_supplicant_daemon(const char *pid_file)
4715{
4716 wpa_printf(MSG_DEBUG, "Daemonize..");
4717 return os_daemonize(pid_file);
4718}
4719
4720
1772d348
JM
4721static struct wpa_supplicant *
4722wpa_supplicant_alloc(struct wpa_supplicant *parent)
6fc6879b
JM
4723{
4724 struct wpa_supplicant *wpa_s;
4725
4726 wpa_s = os_zalloc(sizeof(*wpa_s));
4727 if (wpa_s == NULL)
4728 return NULL;
4115303b 4729 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 4730 wpa_s->scan_interval = 5;
c302f207 4731 wpa_s->new_connection = 1;
1772d348 4732 wpa_s->parent = parent ? parent : wpa_s;
ba307f85 4733 wpa_s->p2pdev = wpa_s->parent;
cbdf3507 4734 wpa_s->sched_scanning = 0;
6fc6879b 4735
dd599908 4736 dl_list_init(&wpa_s->bss_tmp_disallowed);
5732b770 4737 dl_list_init(&wpa_s->fils_hlp_req);
dd599908 4738
6fc6879b
JM
4739 return wpa_s;
4740}
4741
4742
80e8a5ee
BG
4743#ifdef CONFIG_HT_OVERRIDES
4744
4745static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
4746 struct ieee80211_ht_capabilities *htcaps,
4747 struct ieee80211_ht_capabilities *htcaps_mask,
4748 const char *ht_mcs)
4749{
4750 /* parse ht_mcs into hex array */
4751 int i;
4752 const char *tmp = ht_mcs;
4753 char *end = NULL;
4754
4755 /* If ht_mcs is null, do not set anything */
4756 if (!ht_mcs)
4757 return 0;
4758
4759 /* This is what we are setting in the kernel */
4760 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
4761
4762 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
4763
4764 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
30eddf35
JB
4765 long v;
4766
80e8a5ee 4767 errno = 0;
30eddf35
JB
4768 v = strtol(tmp, &end, 16);
4769
80e8a5ee
BG
4770 if (errno == 0) {
4771 wpa_msg(wpa_s, MSG_DEBUG,
4772 "htcap value[%i]: %ld end: %p tmp: %p",
4773 i, v, end, tmp);
4774 if (end == tmp)
4775 break;
4776
4777 htcaps->supported_mcs_set[i] = v;
4778 tmp = end;
4779 } else {
4780 wpa_msg(wpa_s, MSG_ERROR,
4781 "Failed to parse ht-mcs: %s, error: %s\n",
4782 ht_mcs, strerror(errno));
4783 return -1;
4784 }
4785 }
4786
4787 /*
4788 * If we were able to parse any values, then set mask for the MCS set.
4789 */
4790 if (i) {
4791 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
4792 IEEE80211_HT_MCS_MASK_LEN - 1);
4793 /* skip the 3 reserved bits */
4794 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
4795 0x1f;
4796 }
4797
4798 return 0;
4799}
4800
4801
4802static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
4803 struct ieee80211_ht_capabilities *htcaps,
4804 struct ieee80211_ht_capabilities *htcaps_mask,
4805 int disabled)
4806{
5bc28571 4807 le16 msk;
80e8a5ee 4808
80e8a5ee
BG
4809 if (disabled == -1)
4810 return 0;
4811
bbdb5014
JM
4812 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
4813
80e8a5ee
BG
4814 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
4815 htcaps_mask->ht_capabilities_info |= msk;
4816 if (disabled)
4817 htcaps->ht_capabilities_info &= msk;
4818 else
4819 htcaps->ht_capabilities_info |= msk;
4820
4821 return 0;
4822}
4823
4824
4825static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
4826 struct ieee80211_ht_capabilities *htcaps,
4827 struct ieee80211_ht_capabilities *htcaps_mask,
4828 int factor)
4829{
80e8a5ee
BG
4830 if (factor == -1)
4831 return 0;
4832
bbdb5014
JM
4833 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
4834
80e8a5ee
BG
4835 if (factor < 0 || factor > 3) {
4836 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
4837 "Must be 0-3 or -1", factor);
4838 return -EINVAL;
4839 }
4840
4841 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
4842 htcaps->a_mpdu_params &= ~0x3;
4843 htcaps->a_mpdu_params |= factor & 0x3;
4844
4845 return 0;
4846}
4847
4848
4849static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
4850 struct ieee80211_ht_capabilities *htcaps,
4851 struct ieee80211_ht_capabilities *htcaps_mask,
4852 int density)
4853{
80e8a5ee
BG
4854 if (density == -1)
4855 return 0;
4856
bbdb5014
JM
4857 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
4858
80e8a5ee
BG
4859 if (density < 0 || density > 7) {
4860 wpa_msg(wpa_s, MSG_ERROR,
4861 "ampdu_density: %d out of range. Must be 0-7 or -1.",
4862 density);
4863 return -EINVAL;
4864 }
4865
4866 htcaps_mask->a_mpdu_params |= 0x1C;
4867 htcaps->a_mpdu_params &= ~(0x1C);
4868 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
4869
4870 return 0;
4871}
4872
4873
4874static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
4875 struct ieee80211_ht_capabilities *htcaps,
4876 struct ieee80211_ht_capabilities *htcaps_mask,
4877 int disabled)
4878{
bbdb5014
JM
4879 if (disabled)
4880 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
80e8a5ee 4881
9eb5757a
MH
4882 set_disable_ht40(htcaps, disabled);
4883 set_disable_ht40(htcaps_mask, 0);
80e8a5ee
BG
4884
4885 return 0;
4886}
4887
4888
a90497f8
BG
4889static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
4890 struct ieee80211_ht_capabilities *htcaps,
4891 struct ieee80211_ht_capabilities *htcaps_mask,
4892 int disabled)
4893{
4894 /* Masking these out disables SGI */
5bc28571
JM
4895 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
4896 HT_CAP_INFO_SHORT_GI40MHZ);
a90497f8 4897
bbdb5014
JM
4898 if (disabled)
4899 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
a90497f8
BG
4900
4901 if (disabled)
4902 htcaps->ht_capabilities_info &= ~msk;
4903 else
4904 htcaps->ht_capabilities_info |= msk;
4905
4906 htcaps_mask->ht_capabilities_info |= msk;
4907
4908 return 0;
4909}
4910
4911
39a5800f
PK
4912static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
4913 struct ieee80211_ht_capabilities *htcaps,
4914 struct ieee80211_ht_capabilities *htcaps_mask,
4915 int disabled)
4916{
4917 /* Masking these out disables LDPC */
5bc28571 4918 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
39a5800f 4919
bbdb5014
JM
4920 if (disabled)
4921 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
39a5800f
PK
4922
4923 if (disabled)
4924 htcaps->ht_capabilities_info &= ~msk;
4925 else
4926 htcaps->ht_capabilities_info |= msk;
4927
4928 htcaps_mask->ht_capabilities_info |= msk;
4929
4930 return 0;
4931}
4932
4933
cdeea70f
SM
4934static int wpa_set_tx_stbc(struct wpa_supplicant *wpa_s,
4935 struct ieee80211_ht_capabilities *htcaps,
4936 struct ieee80211_ht_capabilities *htcaps_mask,
4937 int tx_stbc)
4938{
4939 le16 msk = host_to_le16(HT_CAP_INFO_TX_STBC);
4940
cdeea70f
SM
4941 if (tx_stbc == -1)
4942 return 0;
4943
bbdb5014
JM
4944 wpa_msg(wpa_s, MSG_DEBUG, "set_tx_stbc: %d", tx_stbc);
4945
cdeea70f
SM
4946 if (tx_stbc < 0 || tx_stbc > 1) {
4947 wpa_msg(wpa_s, MSG_ERROR,
4948 "tx_stbc: %d out of range. Must be 0-1 or -1", tx_stbc);
4949 return -EINVAL;
4950 }
4951
4952 htcaps_mask->ht_capabilities_info |= msk;
4953 htcaps->ht_capabilities_info &= ~msk;
4954 htcaps->ht_capabilities_info |= (tx_stbc << 7) & msk;
4955
4956 return 0;
4957}
4958
4959
4960static int wpa_set_rx_stbc(struct wpa_supplicant *wpa_s,
4961 struct ieee80211_ht_capabilities *htcaps,
4962 struct ieee80211_ht_capabilities *htcaps_mask,
4963 int rx_stbc)
4964{
4965 le16 msk = host_to_le16(HT_CAP_INFO_RX_STBC_MASK);
4966
cdeea70f
SM
4967 if (rx_stbc == -1)
4968 return 0;
4969
bbdb5014
JM
4970 wpa_msg(wpa_s, MSG_DEBUG, "set_rx_stbc: %d", rx_stbc);
4971
cdeea70f
SM
4972 if (rx_stbc < 0 || rx_stbc > 3) {
4973 wpa_msg(wpa_s, MSG_ERROR,
4974 "rx_stbc: %d out of range. Must be 0-3 or -1", rx_stbc);
4975 return -EINVAL;
4976 }
4977
4978 htcaps_mask->ht_capabilities_info |= msk;
4979 htcaps->ht_capabilities_info &= ~msk;
4980 htcaps->ht_capabilities_info |= (rx_stbc << 8) & msk;
4981
4982 return 0;
4983}
4984
4985
80e8a5ee
BG
4986void wpa_supplicant_apply_ht_overrides(
4987 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
4988 struct wpa_driver_associate_params *params)
4989{
4990 struct ieee80211_ht_capabilities *htcaps;
4991 struct ieee80211_ht_capabilities *htcaps_mask;
4992
4993 if (!ssid)
4994 return;
4995
4996 params->disable_ht = ssid->disable_ht;
4997 if (!params->htcaps || !params->htcaps_mask)
4998 return;
4999
5000 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
5001 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
5002 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
5003 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
5004 ssid->disable_max_amsdu);
5005 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
5006 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
5007 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 5008 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
39a5800f 5009 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
cdeea70f
SM
5010 wpa_set_rx_stbc(wpa_s, htcaps, htcaps_mask, ssid->rx_stbc);
5011 wpa_set_tx_stbc(wpa_s, htcaps, htcaps_mask, ssid->tx_stbc);
d41cc8cc
JM
5012
5013 if (ssid->ht40_intolerant) {
5bc28571 5014 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
d41cc8cc
JM
5015 htcaps->ht_capabilities_info |= bit;
5016 htcaps_mask->ht_capabilities_info |= bit;
5017 }
80e8a5ee
BG
5018}
5019
5020#endif /* CONFIG_HT_OVERRIDES */
5021
5022
e9ee8dc3
JB
5023#ifdef CONFIG_VHT_OVERRIDES
5024void wpa_supplicant_apply_vht_overrides(
5025 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
5026 struct wpa_driver_associate_params *params)
5027{
5028 struct ieee80211_vht_capabilities *vhtcaps;
5029 struct ieee80211_vht_capabilities *vhtcaps_mask;
5030
5031 if (!ssid)
5032 return;
5033
5034 params->disable_vht = ssid->disable_vht;
5035
5036 vhtcaps = (void *) params->vhtcaps;
5037 vhtcaps_mask = (void *) params->vhtcaps_mask;
5038
5039 if (!vhtcaps || !vhtcaps_mask)
5040 return;
5041
4d8d710f
JM
5042 vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
5043 vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
e9ee8dc3 5044
4f560cde 5045#ifdef CONFIG_HT_OVERRIDES
fd83a808
BG
5046 if (ssid->disable_sgi) {
5047 vhtcaps_mask->vht_capabilities_info |= (VHT_CAP_SHORT_GI_80 |
5048 VHT_CAP_SHORT_GI_160);
5049 vhtcaps->vht_capabilities_info &= ~(VHT_CAP_SHORT_GI_80 |
5050 VHT_CAP_SHORT_GI_160);
5051 wpa_msg(wpa_s, MSG_DEBUG,
5052 "disable-sgi override specified, vht-caps: 0x%x",
5053 vhtcaps->vht_capabilities_info);
5054 }
5055
4f560cde 5056 /* if max ampdu is <= 3, we have to make the HT cap the same */
b0f33467
JM
5057 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
5058 int max_ampdu;
5059
5060 max_ampdu = (ssid->vht_capa &
5061 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
5062 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
4f560cde
EP
5063
5064 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
5065 wpa_set_ampdu_factor(wpa_s,
5066 (void *) params->htcaps,
5067 (void *) params->htcaps_mask,
5068 max_ampdu);
5069 }
5070#endif /* CONFIG_HT_OVERRIDES */
5071
e9ee8dc3
JB
5072#define OVERRIDE_MCS(i) \
5073 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
5074 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
4d8d710f 5075 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 5076 vhtcaps->vht_supported_mcs_set.tx_map |= \
4d8d710f
JM
5077 host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
5078 2 * (i - 1)); \
e9ee8dc3
JB
5079 } \
5080 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
5081 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
4d8d710f 5082 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 5083 vhtcaps->vht_supported_mcs_set.rx_map |= \
4d8d710f
JM
5084 host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
5085 2 * (i - 1)); \
e9ee8dc3
JB
5086 }
5087
5088 OVERRIDE_MCS(1);
5089 OVERRIDE_MCS(2);
5090 OVERRIDE_MCS(3);
5091 OVERRIDE_MCS(4);
5092 OVERRIDE_MCS(5);
5093 OVERRIDE_MCS(6);
5094 OVERRIDE_MCS(7);
5095 OVERRIDE_MCS(8);
5096}
5097#endif /* CONFIG_VHT_OVERRIDES */
5098
5099
f64adcd7
JM
5100static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
5101{
5102#ifdef PCSC_FUNCS
5103 size_t len;
5104
5105 if (!wpa_s->conf->pcsc_reader)
5106 return 0;
5107
22cf7d73 5108 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
5109 if (!wpa_s->scard)
5110 return 1;
5111
5112 if (wpa_s->conf->pcsc_pin &&
5113 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
5114 scard_deinit(wpa_s->scard);
5115 wpa_s->scard = NULL;
5116 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
5117 return -1;
5118 }
5119
5120 len = sizeof(wpa_s->imsi) - 1;
5121 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
5122 scard_deinit(wpa_s->scard);
5123 wpa_s->scard = NULL;
5124 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
5125 return -1;
5126 }
5127 wpa_s->imsi[len] = '\0';
5128
5129 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
5130
5131 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
5132 wpa_s->imsi, wpa_s->mnc_len);
5133
5134 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
5135 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
5136#endif /* PCSC_FUNCS */
5137
5138 return 0;
5139}
5140
5141
306ae225
JM
5142int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
5143{
5144 char *val, *pos;
5145
5146 ext_password_deinit(wpa_s->ext_pw);
5147 wpa_s->ext_pw = NULL;
5148 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
5149
5150 if (!wpa_s->conf->ext_password_backend)
5151 return 0;
5152
5153 val = os_strdup(wpa_s->conf->ext_password_backend);
5154 if (val == NULL)
5155 return -1;
5156 pos = os_strchr(val, ':');
5157 if (pos)
5158 *pos++ = '\0';
5159
5160 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
5161
5162 wpa_s->ext_pw = ext_password_init(val, pos);
5163 os_free(val);
5164 if (wpa_s->ext_pw == NULL) {
5165 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
5166 return -1;
5167 }
5168 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
5169
5170 return 0;
5171}
5172
5173
b36a3a65
AN
5174#ifdef CONFIG_FST
5175
5176static const u8 * wpas_fst_get_bssid_cb(void *ctx)
5177{
5178 struct wpa_supplicant *wpa_s = ctx;
5179
5180 return (is_zero_ether_addr(wpa_s->bssid) ||
5181 wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
5182}
5183
5184
5185static void wpas_fst_get_channel_info_cb(void *ctx,
5186 enum hostapd_hw_mode *hw_mode,
5187 u8 *channel)
5188{
5189 struct wpa_supplicant *wpa_s = ctx;
5190
5191 if (wpa_s->current_bss) {
5192 *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
5193 channel);
5194 } else if (wpa_s->hw.num_modes) {
5195 *hw_mode = wpa_s->hw.modes[0].mode;
5196 } else {
5197 WPA_ASSERT(0);
5198 *hw_mode = 0;
5199 }
5200}
5201
5202
5203static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
5204{
5205 struct wpa_supplicant *wpa_s = ctx;
5206
5207 *modes = wpa_s->hw.modes;
5208 return wpa_s->hw.num_modes;
5209}
5210
5211
84bcb4e7 5212static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
b36a3a65
AN
5213{
5214 struct wpa_supplicant *wpa_s = ctx;
5215
b7a07937 5216 wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
b36a3a65
AN
5217 wpa_s->fst_ies = fst_ies;
5218}
5219
5220
5221static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
5222{
5223 struct wpa_supplicant *wpa_s = ctx;
5224
0da35523
JM
5225 if (os_memcmp(wpa_s->bssid, da, ETH_ALEN) != 0) {
5226 wpa_printf(MSG_INFO, "FST:%s:bssid=" MACSTR " != da=" MACSTR,
5227 __func__, MAC2STR(wpa_s->bssid), MAC2STR(da));
5228 return -1;
5229 }
b36a3a65 5230 return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
0da35523
JM
5231 wpa_s->own_addr, wpa_s->bssid,
5232 wpabuf_head(data), wpabuf_len(data),
b36a3a65
AN
5233 0);
5234}
5235
5236
a0f04da5 5237static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
b36a3a65
AN
5238{
5239 struct wpa_supplicant *wpa_s = ctx;
5240
5241 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
5242 return wpa_s->received_mb_ies;
5243}
5244
5245
5246static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
5247 const u8 *buf, size_t size)
5248{
5249 struct wpa_supplicant *wpa_s = ctx;
5250 struct mb_ies_info info;
5251
5252 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
5253
5254 if (!mb_ies_info_by_ies(&info, buf, size)) {
5255 wpabuf_free(wpa_s->received_mb_ies);
5256 wpa_s->received_mb_ies = mb_ies_by_info(&info);
5257 }
5258}
5259
5260
39cdd3a0
JM
5261static const u8 * wpas_fst_get_peer_first(void *ctx,
5262 struct fst_get_peer_ctx **get_ctx,
5263 Boolean mb_only)
b36a3a65
AN
5264{
5265 struct wpa_supplicant *wpa_s = ctx;
5266
5267 *get_ctx = NULL;
5268 if (!is_zero_ether_addr(wpa_s->bssid))
5269 return (wpa_s->received_mb_ies || !mb_only) ?
5270 wpa_s->bssid : NULL;
5271 return NULL;
5272}
5273
5274
39cdd3a0
JM
5275static const u8 * wpas_fst_get_peer_next(void *ctx,
5276 struct fst_get_peer_ctx **get_ctx,
5277 Boolean mb_only)
b36a3a65
AN
5278{
5279 return NULL;
5280}
5281
5282void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
5283 struct fst_wpa_obj *iface_obj)
5284{
5285 iface_obj->ctx = wpa_s;
5286 iface_obj->get_bssid = wpas_fst_get_bssid_cb;
5287 iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
5288 iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
5289 iface_obj->set_ies = wpas_fst_set_ies_cb;
5290 iface_obj->send_action = wpas_fst_send_action_cb;
5291 iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
5292 iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
5293 iface_obj->get_peer_first = wpas_fst_get_peer_first;
5294 iface_obj->get_peer_next = wpas_fst_get_peer_next;
5295}
5296#endif /* CONFIG_FST */
5297
a520bf4a 5298static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
6cbdb0c5 5299 const struct wpa_driver_capa *capa)
e4fa8b12 5300{
88cb27c7
DS
5301 struct wowlan_triggers *triggers;
5302 int ret = 0;
e4fa8b12
EP
5303
5304 if (!wpa_s->conf->wowlan_triggers)
5305 return 0;
5306
88cb27c7
DS
5307 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
5308 if (triggers) {
5309 ret = wpa_drv_wowlan(wpa_s, triggers);
5310 os_free(triggers);
e4fa8b12 5311 }
e4fa8b12
EP
5312 return ret;
5313}
5314
5315
2b6e9f91 5316enum wpa_radio_work_band wpas_freq_to_band(int freq)
e903d32d
KV
5317{
5318 if (freq < 3000)
5319 return BAND_2_4_GHZ;
5320 if (freq > 50000)
5321 return BAND_60_GHZ;
5322 return BAND_5_GHZ;
5323}
5324
5325
2b6e9f91 5326unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
e903d32d
KV
5327{
5328 int i;
5329 unsigned int band = 0;
5330
5331 if (freqs) {
5332 /* freqs are specified for the radio work */
5333 for (i = 0; freqs[i]; i++)
5334 band |= wpas_freq_to_band(freqs[i]);
5335 } else {
5336 /*
5337 * freqs are not specified, implies all
5338 * the supported freqs by HW
5339 */
5340 for (i = 0; i < wpa_s->hw.num_modes; i++) {
5341 if (wpa_s->hw.modes[i].num_channels != 0) {
5342 if (wpa_s->hw.modes[i].mode ==
5343 HOSTAPD_MODE_IEEE80211B ||
5344 wpa_s->hw.modes[i].mode ==
5345 HOSTAPD_MODE_IEEE80211G)
5346 band |= BAND_2_4_GHZ;
5347 else if (wpa_s->hw.modes[i].mode ==
5348 HOSTAPD_MODE_IEEE80211A)
5349 band |= BAND_5_GHZ;
5350 else if (wpa_s->hw.modes[i].mode ==
5351 HOSTAPD_MODE_IEEE80211AD)
5352 band |= BAND_60_GHZ;
5353 else if (wpa_s->hw.modes[i].mode ==
5354 HOSTAPD_MODE_IEEE80211ANY)
5355 band = BAND_2_4_GHZ | BAND_5_GHZ |
5356 BAND_60_GHZ;
5357 }
5358 }
5359 }
5360
5361 return band;
5362}
5363
5364
202dec2a
JM
5365static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
5366 const char *rn)
5367{
5368 struct wpa_supplicant *iface = wpa_s->global->ifaces;
5369 struct wpa_radio *radio;
5370
5371 while (rn && iface) {
5372 radio = iface->radio;
5373 if (radio && os_strcmp(rn, radio->name) == 0) {
5374 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
5375 wpa_s->ifname, rn);
5376 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
5377 return radio;
5378 }
b154a24e
TB
5379
5380 iface = iface->next;
202dec2a
JM
5381 }
5382
5383 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
5384 wpa_s->ifname, rn ? rn : "N/A");
5385 radio = os_zalloc(sizeof(*radio));
5386 if (radio == NULL)
5387 return NULL;
5388
5389 if (rn)
5390 os_strlcpy(radio->name, rn, sizeof(radio->name));
5391 dl_list_init(&radio->ifaces);
b1ae396f 5392 dl_list_init(&radio->work);
202dec2a
JM
5393 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
5394
5395 return radio;
5396}
5397
5398
b1ae396f
JM
5399static void radio_work_free(struct wpa_radio_work *work)
5400{
d12a51b5
JM
5401 if (work->wpa_s->scan_work == work) {
5402 /* This should not really happen. */
5403 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
5404 work->type, work, work->started);
5405 work->wpa_s->scan_work = NULL;
5406 }
5407
1b5d4714
JM
5408#ifdef CONFIG_P2P
5409 if (work->wpa_s->p2p_scan_work == work) {
5410 /* This should not really happen. */
5411 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
5412 work->type, work, work->started);
5413 work->wpa_s->p2p_scan_work = NULL;
5414 }
5415#endif /* CONFIG_P2P */
5416
e903d32d
KV
5417 if (work->started) {
5418 work->wpa_s->radio->num_active_works--;
5419 wpa_dbg(work->wpa_s, MSG_DEBUG,
7ed5337d 5420 "radio_work_free('%s'@%p): num_active_works --> %u",
e903d32d
KV
5421 work->type, work,
5422 work->wpa_s->radio->num_active_works);
5423 }
5424
b1ae396f
JM
5425 dl_list_del(&work->list);
5426 os_free(work);
5427}
5428
5429
4c6f450c
JM
5430static int radio_work_is_connect(struct wpa_radio_work *work)
5431{
5432 return os_strcmp(work->type, "sme-connect") == 0 ||
5433 os_strcmp(work->type, "connect") == 0;
5434}
5435
5436
85b6b6b6
SD
5437static int radio_work_is_scan(struct wpa_radio_work *work)
5438{
5439 return os_strcmp(work->type, "scan") == 0 ||
5440 os_strcmp(work->type, "p2p-scan") == 0;
5441}
5442
5443
e903d32d
KV
5444static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
5445{
5446 struct wpa_radio_work *active_work = NULL;
5447 struct wpa_radio_work *tmp;
5448
5449 /* Get the active work to know the type and band. */
5450 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
5451 if (tmp->started) {
5452 active_work = tmp;
5453 break;
5454 }
5455 }
5456
5457 if (!active_work) {
5458 /* No active work, start one */
5459 radio->num_active_works = 0;
5460 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
5461 list) {
5462 if (os_strcmp(tmp->type, "scan") == 0 &&
5463 radio->external_scan_running &&
5464 (((struct wpa_driver_scan_params *)
5465 tmp->ctx)->only_new_results ||
5466 tmp->wpa_s->clear_driver_scan_cache))
5467 continue;
5468 return tmp;
5469 }
5470 return NULL;
5471 }
5472
4c6f450c 5473 if (radio_work_is_connect(active_work)) {
e903d32d
KV
5474 /*
5475 * If the active work is either connect or sme-connect,
5476 * do not parallelize them with other radio works.
5477 */
5478 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
5479 "Do not parallelize radio work with %s",
5480 active_work->type);
5481 return NULL;
5482 }
5483
5484 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
5485 if (tmp->started)
5486 continue;
5487
5488 /*
5489 * If connect or sme-connect are enqueued, parallelize only
5490 * those operations ahead of them in the queue.
5491 */
4c6f450c 5492 if (radio_work_is_connect(tmp))
e903d32d
KV
5493 break;
5494
85b6b6b6
SD
5495 /* Serialize parallel scan and p2p_scan operations on the same
5496 * interface since the driver_nl80211 mechanism for tracking
5497 * scan cookies does not yet have support for this. */
5498 if (active_work->wpa_s == tmp->wpa_s &&
5499 radio_work_is_scan(active_work) &&
5500 radio_work_is_scan(tmp)) {
5501 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
5502 "Do not start work '%s' when another work '%s' is already scheduled",
5503 tmp->type, active_work->type);
5504 continue;
5505 }
e903d32d
KV
5506 /*
5507 * Check that the radio works are distinct and
5508 * on different bands.
5509 */
5510 if (os_strcmp(active_work->type, tmp->type) != 0 &&
5511 (active_work->bands != tmp->bands)) {
5512 /*
5513 * If a scan has to be scheduled through nl80211 scan
5514 * interface and if an external scan is already running,
5515 * do not schedule the scan since it is likely to get
5516 * rejected by kernel.
5517 */
5518 if (os_strcmp(tmp->type, "scan") == 0 &&
5519 radio->external_scan_running &&
5520 (((struct wpa_driver_scan_params *)
5521 tmp->ctx)->only_new_results ||
5522 tmp->wpa_s->clear_driver_scan_cache))
5523 continue;
5524
5525 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
5526 "active_work:%s new_work:%s",
5527 active_work->type, tmp->type);
5528 return tmp;
5529 }
5530 }
5531
5532 /* Did not find a radio work to schedule in parallel. */
5533 return NULL;
5534}
5535
5536
b1ae396f
JM
5537static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
5538{
5539 struct wpa_radio *radio = eloop_ctx;
5540 struct wpa_radio_work *work;
5541 struct os_reltime now, diff;
6428d0a7 5542 struct wpa_supplicant *wpa_s;
b1ae396f
JM
5543
5544 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
e903d32d
KV
5545 if (work == NULL) {
5546 radio->num_active_works = 0;
b1ae396f 5547 return;
e903d32d 5548 }
b1ae396f 5549
6428d0a7
JM
5550 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
5551 radio_list);
e903d32d
KV
5552
5553 if (!(wpa_s &&
5554 wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
5555 if (work->started)
5556 return; /* already started and still in progress */
5557
5558 if (wpa_s && wpa_s->radio->external_scan_running) {
5559 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
5560 return;
5561 }
5562 } else {
5563 work = NULL;
5564 if (radio->num_active_works < MAX_ACTIVE_WORKS) {
5565 /* get the work to schedule next */
5566 work = radio_work_get_next_work(radio);
5567 }
5568 if (!work)
5569 return;
6428d0a7
JM
5570 }
5571
e903d32d 5572 wpa_s = work->wpa_s;
b1ae396f
JM
5573 os_get_reltime(&now);
5574 os_reltime_sub(&now, &work->time, &diff);
e903d32d
KV
5575 wpa_dbg(wpa_s, MSG_DEBUG,
5576 "Starting radio work '%s'@%p after %ld.%06ld second wait",
b1ae396f
JM
5577 work->type, work, diff.sec, diff.usec);
5578 work->started = 1;
5579 work->time = now;
e903d32d
KV
5580 radio->num_active_works++;
5581
b1ae396f 5582 work->cb(work, 0);
e903d32d
KV
5583
5584 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
5585 radio->num_active_works < MAX_ACTIVE_WORKS)
5586 radio_work_check_next(wpa_s);
b1ae396f
JM
5587}
5588
5589
b3253ebb
AO
5590/*
5591 * This function removes both started and pending radio works running on
5592 * the provided interface's radio.
5593 * Prior to the removal of the radio work, its callback (cb) is called with
5594 * deinit set to be 1. Each work's callback is responsible for clearing its
5595 * internal data and restoring to a correct state.
5596 * @wpa_s: wpa_supplicant data
5597 * @type: type of works to be removed
5598 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
5599 * this interface's works.
5600 */
5601void radio_remove_works(struct wpa_supplicant *wpa_s,
5602 const char *type, int remove_all)
b1ae396f
JM
5603{
5604 struct wpa_radio_work *work, *tmp;
5605 struct wpa_radio *radio = wpa_s->radio;
5606
5607 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
5608 list) {
b3253ebb 5609 if (type && os_strcmp(type, work->type) != 0)
b1ae396f 5610 continue;
b3253ebb
AO
5611
5612 /* skip other ifaces' works */
5613 if (!remove_all && work->wpa_s != wpa_s)
b1ae396f 5614 continue;
b3253ebb
AO
5615
5616 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
5617 work->type, work, work->started ? " (started)" : "");
b1ae396f
JM
5618 work->cb(work, 1);
5619 radio_work_free(work);
5620 }
b3253ebb
AO
5621
5622 /* in case we removed the started work */
5623 radio_work_check_next(wpa_s);
b1ae396f
JM
5624}
5625
5626
6a252ece
JM
5627void radio_remove_pending_work(struct wpa_supplicant *wpa_s, void *ctx)
5628{
5629 struct wpa_radio_work *work;
5630 struct wpa_radio *radio = wpa_s->radio;
5631
5632 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
5633 if (work->ctx != ctx)
5634 continue;
5635 wpa_dbg(wpa_s, MSG_DEBUG, "Free pending radio work '%s'@%p%s",
5636 work->type, work, work->started ? " (started)" : "");
5637 radio_work_free(work);
5638 break;
5639 }
5640}
5641
5642
202dec2a
JM
5643static void radio_remove_interface(struct wpa_supplicant *wpa_s)
5644{
5645 struct wpa_radio *radio = wpa_s->radio;
5646
5647 if (!radio)
5648 return;
5649
5650 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
5651 wpa_s->ifname, radio->name);
5652 dl_list_del(&wpa_s->radio_list);
c46235aa
AO
5653 radio_remove_works(wpa_s, NULL, 0);
5654 wpa_s->radio = NULL;
5655 if (!dl_list_empty(&radio->ifaces))
202dec2a
JM
5656 return; /* Interfaces remain for this radio */
5657
5658 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f 5659 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
202dec2a
JM
5660 os_free(radio);
5661}
5662
5663
6428d0a7 5664void radio_work_check_next(struct wpa_supplicant *wpa_s)
b1ae396f
JM
5665{
5666 struct wpa_radio *radio = wpa_s->radio;
5667
5668 if (dl_list_empty(&radio->work))
5669 return;
e3745228
JM
5670 if (wpa_s->ext_work_in_progress) {
5671 wpa_printf(MSG_DEBUG,
5672 "External radio work in progress - delay start of pending item");
5673 return;
5674 }
b1ae396f
JM
5675 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
5676 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
5677}
5678
5679
5680/**
5681 * radio_add_work - Add a radio work item
5682 * @wpa_s: Pointer to wpa_supplicant data
5683 * @freq: Frequency of the offchannel operation in MHz or 0
5684 * @type: Unique identifier for each type of work
5685 * @next: Force as the next work to be executed
5686 * @cb: Callback function for indicating when radio is available
5687 * @ctx: Context pointer for the work (work->ctx in cb())
5688 * Returns: 0 on success, -1 on failure
5689 *
5690 * This function is used to request time for an operation that requires
5691 * exclusive radio control. Once the radio is available, the registered callback
5692 * function will be called. radio_work_done() must be called once the exclusive
5693 * radio operation has been completed, so that the radio is freed for other
5694 * operations. The special case of deinit=1 is used to free the context data
5695 * during interface removal. That does not allow the callback function to start
5696 * the radio operation, i.e., it must free any resources allocated for the radio
5697 * work and return.
5698 *
5699 * The @freq parameter can be used to indicate a single channel on which the
5700 * offchannel operation will occur. This may allow multiple radio work
5701 * operations to be performed in parallel if they apply for the same channel.
5702 * Setting this to 0 indicates that the work item may use multiple channels or
5703 * requires exclusive control of the radio.
5704 */
5705int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
5706 const char *type, int next,
5707 void (*cb)(struct wpa_radio_work *work, int deinit),
5708 void *ctx)
5709{
e903d32d 5710 struct wpa_radio *radio = wpa_s->radio;
b1ae396f
JM
5711 struct wpa_radio_work *work;
5712 int was_empty;
5713
5714 work = os_zalloc(sizeof(*work));
5715 if (work == NULL)
5716 return -1;
5717 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
5718 os_get_reltime(&work->time);
5719 work->freq = freq;
5720 work->type = type;
5721 work->wpa_s = wpa_s;
5722 work->cb = cb;
5723 work->ctx = ctx;
5724
e903d32d
KV
5725 if (freq)
5726 work->bands = wpas_freq_to_band(freq);
5727 else if (os_strcmp(type, "scan") == 0 ||
5728 os_strcmp(type, "p2p-scan") == 0)
5729 work->bands = wpas_get_bands(wpa_s,
5730 ((struct wpa_driver_scan_params *)
5731 ctx)->freqs);
5732 else
5733 work->bands = wpas_get_bands(wpa_s, NULL);
5734
b1ae396f
JM
5735 was_empty = dl_list_empty(&wpa_s->radio->work);
5736 if (next)
5737 dl_list_add(&wpa_s->radio->work, &work->list);
5738 else
5739 dl_list_add_tail(&wpa_s->radio->work, &work->list);
5740 if (was_empty) {
5741 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
5742 radio_work_check_next(wpa_s);
e903d32d
KV
5743 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
5744 && radio->num_active_works < MAX_ACTIVE_WORKS) {
5745 wpa_dbg(wpa_s, MSG_DEBUG,
5746 "Try to schedule a radio work (num_active_works=%u)",
5747 radio->num_active_works);
5748 radio_work_check_next(wpa_s);
b1ae396f
JM
5749 }
5750
5751 return 0;
5752}
5753
5754
5755/**
5756 * radio_work_done - Indicate that a radio work item has been completed
5757 * @work: Completed work
5758 *
5759 * This function is called once the callback function registered with
5760 * radio_add_work() has completed its work.
5761 */
5762void radio_work_done(struct wpa_radio_work *work)
5763{
5764 struct wpa_supplicant *wpa_s = work->wpa_s;
5765 struct os_reltime now, diff;
1f965e62 5766 unsigned int started = work->started;
b1ae396f
JM
5767
5768 os_get_reltime(&now);
5769 os_reltime_sub(&now, &work->time, &diff);
1f965e62
JM
5770 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
5771 work->type, work, started ? "done" : "canceled",
5772 diff.sec, diff.usec);
b1ae396f 5773 radio_work_free(work);
1f965e62
JM
5774 if (started)
5775 radio_work_check_next(wpa_s);
b1ae396f
JM
5776}
5777
5778
a7f5271d
JM
5779struct wpa_radio_work *
5780radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
f0e30c84
JM
5781{
5782 struct wpa_radio_work *work;
5783 struct wpa_radio *radio = wpa_s->radio;
5784
5785 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
5786 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
a7f5271d 5787 return work;
f0e30c84
JM
5788 }
5789
a7f5271d 5790 return NULL;
f0e30c84
JM
5791}
5792
5793
73c00fd7 5794static int wpas_init_driver(struct wpa_supplicant *wpa_s,
8fb2b357 5795 const struct wpa_interface *iface)
73c00fd7 5796{
202dec2a 5797 const char *ifname, *driver, *rn;
73c00fd7
JM
5798
5799 driver = iface->driver;
5800next_driver:
5801 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
5802 return -1;
5803
5804 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
5805 if (wpa_s->drv_priv == NULL) {
5806 const char *pos;
5807 pos = driver ? os_strchr(driver, ',') : NULL;
5808 if (pos) {
5809 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
5810 "driver interface - try next driver wrapper");
5811 driver = pos + 1;
5812 goto next_driver;
5813 }
5814 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
5815 "interface");
5816 return -1;
5817 }
5818 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
5819 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
5820 "driver_param '%s'", wpa_s->conf->driver_param);
5821 return -1;
5822 }
5823
5824 ifname = wpa_drv_get_ifname(wpa_s);
5825 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
5826 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
5827 "interface name with '%s'", ifname);
5828 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
5829 }
5830
95bf699f 5831 rn = wpa_driver_get_radio_name(wpa_s);
202dec2a
JM
5832 if (rn && rn[0] == '\0')
5833 rn = NULL;
5834
5835 wpa_s->radio = radio_add_interface(wpa_s, rn);
5836 if (wpa_s->radio == NULL)
5837 return -1;
5838
73c00fd7
JM
5839 return 0;
5840}
5841
5842
461d39af
JM
5843#ifdef CONFIG_GAS_SERVER
5844
5845static void wpas_gas_server_tx_status(struct wpa_supplicant *wpa_s,
5846 unsigned int freq, const u8 *dst,
5847 const u8 *src, const u8 *bssid,
5848 const u8 *data, size_t data_len,
5849 enum offchannel_send_action_result result)
5850{
5851 wpa_printf(MSG_DEBUG, "GAS: TX status: freq=%u dst=" MACSTR
5852 " result=%s",
5853 freq, MAC2STR(dst),
5854 result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
5855 (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
5856 "FAILED"));
5857 gas_server_tx_status(wpa_s->gas_server, dst, data, data_len,
5858 result == OFFCHANNEL_SEND_ACTION_SUCCESS);
5859}
5860
5861
5862static void wpas_gas_server_tx(void *ctx, int freq, const u8 *da,
5863 struct wpabuf *buf, unsigned int wait_time)
5864{
5865 struct wpa_supplicant *wpa_s = ctx;
5866 const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
5867
5868 if (wait_time > wpa_s->max_remain_on_chan)
5869 wait_time = wpa_s->max_remain_on_chan;
5870
5871 offchannel_send_action(wpa_s, freq, da, wpa_s->own_addr, broadcast,
5872 wpabuf_head(buf), wpabuf_len(buf),
5873 wait_time, wpas_gas_server_tx_status, 0);
5874}
5875
5876#endif /* CONFIG_GAS_SERVER */
5877
6fc6879b 5878static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
8fb2b357 5879 const struct wpa_interface *iface)
6fc6879b 5880{
362f781e 5881 struct wpa_driver_capa capa;
6cbdb0c5 5882 int capa_res;
aa56e36d 5883 u8 dfs_domain;
362f781e 5884
6fc6879b
JM
5885 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
5886 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
5887 iface->confname ? iface->confname : "N/A",
5888 iface->driver ? iface->driver : "default",
5889 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
5890 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
5891
6fc6879b
JM
5892 if (iface->confname) {
5893#ifdef CONFIG_BACKEND_FILE
5894 wpa_s->confname = os_rel2abs_path(iface->confname);
5895 if (wpa_s->confname == NULL) {
5896 wpa_printf(MSG_ERROR, "Failed to get absolute path "
5897 "for configuration file '%s'.",
5898 iface->confname);
5899 return -1;
5900 }
5901 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
5902 iface->confname, wpa_s->confname);
5903#else /* CONFIG_BACKEND_FILE */
5904 wpa_s->confname = os_strdup(iface->confname);
5905#endif /* CONFIG_BACKEND_FILE */
e6304cad 5906 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
5907 if (wpa_s->conf == NULL) {
5908 wpa_printf(MSG_ERROR, "Failed to read or parse "
5909 "configuration '%s'.", wpa_s->confname);
5910 return -1;
5911 }
e6304cad 5912 wpa_s->confanother = os_rel2abs_path(iface->confanother);
3bd35b68
JM
5913 if (wpa_s->confanother &&
5914 !wpa_config_read(wpa_s->confanother, wpa_s->conf)) {
5915 wpa_printf(MSG_ERROR,
5916 "Failed to read or parse configuration '%s'.",
5917 wpa_s->confanother);
5918 return -1;
5919 }
6fc6879b
JM
5920
5921 /*
5922 * Override ctrl_interface and driver_param if set on command
5923 * line.
5924 */
5925 if (iface->ctrl_interface) {
5926 os_free(wpa_s->conf->ctrl_interface);
5927 wpa_s->conf->ctrl_interface =
5928 os_strdup(iface->ctrl_interface);
5929 }
5930
5931 if (iface->driver_param) {
5932 os_free(wpa_s->conf->driver_param);
5933 wpa_s->conf->driver_param =
5934 os_strdup(iface->driver_param);
5935 }
78f79fe5
JM
5936
5937 if (iface->p2p_mgmt && !iface->ctrl_interface) {
5938 os_free(wpa_s->conf->ctrl_interface);
5939 wpa_s->conf->ctrl_interface = NULL;
5940 }
6fc6879b
JM
5941 } else
5942 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
5943 iface->driver_param);
5944
5945 if (wpa_s->conf == NULL) {
5946 wpa_printf(MSG_ERROR, "\nNo configuration found.");
5947 return -1;
5948 }
5949
5950 if (iface->ifname == NULL) {
5951 wpa_printf(MSG_ERROR, "\nInterface name is required.");
5952 return -1;
5953 }
5954 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
5955 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
5956 iface->ifname);
5957 return -1;
5958 }
5959 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
5960
5961 if (iface->bridge_ifname) {
5962 if (os_strlen(iface->bridge_ifname) >=
5963 sizeof(wpa_s->bridge_ifname)) {
5964 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
5965 "name '%s'.", iface->bridge_ifname);
5966 return -1;
5967 }
5968 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
5969 sizeof(wpa_s->bridge_ifname));
5970 }
5971
6fc6879b
JM
5972 /* RSNA Supplicant Key Management - INITIALIZE */
5973 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
5974 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
5975
5976 /* Initialize driver interface and register driver event handler before
5977 * L2 receive handler so that association events are processed before
5978 * EAPOL-Key packets if both become available for the same select()
5979 * call. */
73c00fd7 5980 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
5981 return -1;
5982
6fc6879b
JM
5983 if (wpa_supplicant_init_wpa(wpa_s) < 0)
5984 return -1;
5985
5986 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
5987 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
5988 NULL);
5989 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
5990
5991 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
5992 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
5993 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
5994 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
5995 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
5996 return -1;
5997 }
5998
5999 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
6000 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
6001 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 6002 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
6003 "dot11RSNAConfigPMKReauthThreshold");
6004 return -1;
6005 }
6006
6007 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
6008 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
6009 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
6010 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6011 "dot11RSNAConfigSATimeout");
6fc6879b
JM
6012 return -1;
6013 }
6014
6bf731e8
CL
6015 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
6016 &wpa_s->hw.num_modes,
aa56e36d
VT
6017 &wpa_s->hw.flags,
6018 &dfs_domain);
a1b790eb
JM
6019 if (wpa_s->hw.modes) {
6020 u16 i;
6021
6022 for (i = 0; i < wpa_s->hw.num_modes; i++) {
6023 if (wpa_s->hw.modes[i].vht_capab) {
6024 wpa_s->hw_capab = CAPAB_VHT;
6025 break;
6026 }
6027
6028 if (wpa_s->hw.modes[i].ht_capab &
6029 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
6030 wpa_s->hw_capab = CAPAB_HT40;
6031 else if (wpa_s->hw.modes[i].ht_capab &&
6032 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
6033 wpa_s->hw_capab = CAPAB_HT;
6034 }
6035 }
6bf731e8 6036
6cbdb0c5
JM
6037 capa_res = wpa_drv_get_capa(wpa_s, &capa);
6038 if (capa_res == 0) {
c58ab8f2 6039 wpa_s->drv_capa_known = 1;
814782b9 6040 wpa_s->drv_flags = capa.flags;
349493bd 6041 wpa_s->drv_enc = capa.enc;
04ee647d 6042 wpa_s->drv_smps_modes = capa.smps_modes;
f936b73c 6043 wpa_s->drv_rrm_flags = capa.rrm_flags;
4f73d88a 6044 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 6045 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507 6046 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
32c02261
AS
6047 wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
6048 wpa_s->max_sched_scan_plan_interval =
6049 capa.max_sched_scan_plan_interval;
6050 wpa_s->max_sched_scan_plan_iterations =
6051 capa.max_sched_scan_plan_iterations;
cbdf3507 6052 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 6053 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 6054 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 6055 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
6056 wpa_s->extended_capa = capa.extended_capa;
6057 wpa_s->extended_capa_mask = capa.extended_capa_mask;
6058 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
6059 wpa_s->num_multichan_concurrent =
6060 capa.num_multichan_concurrent;
471cd6e1 6061 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
56c76fa5
IP
6062
6063 if (capa.mac_addr_rand_scan_supported)
6064 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
6065 if (wpa_s->sched_scan_supported &&
6066 capa.mac_addr_rand_sched_scan_supported)
6067 wpa_s->mac_addr_rand_supported |=
6068 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
2a93ecc8
JM
6069
6070 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
6071 if (wpa_s->extended_capa &&
6072 wpa_s->extended_capa_len >= 3 &&
6073 wpa_s->extended_capa[2] & 0x40)
6074 wpa_s->multi_bss_support = 1;
814782b9
JM
6075 }
6076 if (wpa_s->max_remain_on_chan == 0)
6077 wpa_s->max_remain_on_chan = 1000;
6078
c68f6200
AS
6079 /*
6080 * Only take p2p_mgmt parameters when P2P Device is supported.
6081 * Doing it here as it determines whether l2_packet_init() will be done
6082 * during wpa_supplicant_driver_init().
6083 */
6084 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
6085 wpa_s->p2p_mgmt = iface->p2p_mgmt;
c68f6200 6086
4752147d
IP
6087 if (wpa_s->num_multichan_concurrent == 0)
6088 wpa_s->num_multichan_concurrent = 1;
6089
6fc6879b
JM
6090 if (wpa_supplicant_driver_init(wpa_s) < 0)
6091 return -1;
6092
281ff0aa 6093#ifdef CONFIG_TDLS
8fb2b357 6094 if (!iface->p2p_mgmt && wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
6095 return -1;
6096#endif /* CONFIG_TDLS */
6097
315ce40a
JM
6098 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
6099 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 6100 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
6101 return -1;
6102 }
6103
b36a3a65
AN
6104#ifdef CONFIG_FST
6105 if (wpa_s->conf->fst_group_id) {
6106 struct fst_iface_cfg cfg;
6107 struct fst_wpa_obj iface_obj;
6108
6109 fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
6110 os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
6111 sizeof(cfg.group_id));
6112 cfg.priority = wpa_s->conf->fst_priority;
6113 cfg.llt = wpa_s->conf->fst_llt;
6114
6115 wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
6116 &iface_obj, &cfg);
6117 if (!wpa_s->fst) {
6118 wpa_msg(wpa_s, MSG_ERROR,
6119 "FST: Cannot attach iface %s to group %s",
6120 wpa_s->ifname, cfg.group_id);
6121 return -1;
6122 }
6123 }
6124#endif /* CONFIG_FST */
6125
116654ce
JM
6126 if (wpas_wps_init(wpa_s))
6127 return -1;
6128
461d39af
JM
6129#ifdef CONFIG_GAS_SERVER
6130 wpa_s->gas_server = gas_server_init(wpa_s, wpas_gas_server_tx);
6131 if (!wpa_s->gas_server) {
6132 wpa_printf(MSG_ERROR, "Failed to initialize GAS server");
6133 return -1;
6134 }
6135#endif /* CONFIG_GAS_SERVER */
6136
be27e185
JM
6137#ifdef CONFIG_DPP
6138 if (wpas_dpp_init(wpa_s) < 0)
6139 return -1;
6140#endif /* CONFIG_DPP */
6141
6fc6879b
JM
6142 if (wpa_supplicant_init_eapol(wpa_s) < 0)
6143 return -1;
6144 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
6145
6146 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
6147 if (wpa_s->ctrl_iface == NULL) {
6148 wpa_printf(MSG_ERROR,
6149 "Failed to initialize control interface '%s'.\n"
6150 "You may have another wpa_supplicant process "
6151 "already running or the file was\n"
6152 "left by an unclean termination of wpa_supplicant "
6153 "in which case you will need\n"
6154 "to manually remove this file before starting "
6155 "wpa_supplicant again.\n",
6156 wpa_s->conf->ctrl_interface);
6157 return -1;
6158 }
6159
04ea7b79
JM
6160 wpa_s->gas = gas_query_init(wpa_s);
6161 if (wpa_s->gas == NULL) {
6162 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
6163 return -1;
6164 }
6165
8fb2b357
VV
6166 if ((!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) ||
6167 wpa_s->p2p_mgmt) &&
6168 wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 6169 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
6170 return -1;
6171 }
b22128ef 6172
83922c2d
JM
6173 if (wpa_bss_init(wpa_s) < 0)
6174 return -1;
83922c2d 6175
4d77d80e
MH
6176#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
6177#ifdef CONFIG_MESH
6178 dl_list_init(&wpa_s->mesh_external_pmksa_cache);
6179#endif /* CONFIG_MESH */
6180#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
6181
e4fa8b12
EP
6182 /*
6183 * Set Wake-on-WLAN triggers, if configured.
6184 * Note: We don't restore/remove the triggers on shutdown (it doesn't
6185 * have effect anyway when the interface is down).
6186 */
6cbdb0c5 6187 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
e4fa8b12
EP
6188 return -1;
6189
ec7b97ab
JM
6190#ifdef CONFIG_EAP_PROXY
6191{
6192 size_t len;
b5db6e5d
VK
6193 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, -1,
6194 wpa_s->imsi, &len);
ec7b97ab
JM
6195 if (wpa_s->mnc_len > 0) {
6196 wpa_s->imsi[len] = '\0';
6197 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
6198 wpa_s->imsi, wpa_s->mnc_len);
6199 } else {
6200 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
6201 }
6202}
6203#endif /* CONFIG_EAP_PROXY */
6204
f64adcd7
JM
6205 if (pcsc_reader_init(wpa_s) < 0)
6206 return -1;
6207
306ae225
JM
6208 if (wpas_init_ext_pw(wpa_s) < 0)
6209 return -1;
6210
b361d580
AK
6211 wpas_rrm_reset(wpa_s);
6212
32c02261
AS
6213 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
6214
ca9968a0
JM
6215#ifdef CONFIG_HS20
6216 hs20_init(wpa_s);
6217#endif /* CONFIG_HS20 */
92c6e2e3 6218#ifdef CONFIG_MBO
2e06cef8 6219 if (!wpa_s->disable_mbo_oce && wpa_s->conf->oce) {
332aadb8
AP
6220 if ((wpa_s->conf->oce & OCE_STA) &&
6221 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
6222 wpa_s->enable_oce = OCE_STA;
6223 if ((wpa_s->conf->oce & OCE_STA_CFON) &&
6224 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA_CFON)) {
6225 /* TODO: Need to add STA-CFON support */
6226 wpa_printf(MSG_ERROR,
6227 "OCE STA-CFON feature is not yet supported");
6228 }
6229 }
92c6e2e3
DS
6230 wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
6231#endif /* CONFIG_MBO */
ca9968a0 6232
cc9985d1 6233 wpa_supplicant_set_default_scan_ies(wpa_s);
6234
6fc6879b
JM
6235 return 0;
6236}
6237
6238
2ee055b3 6239static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 6240 int notify, int terminate)
6fc6879b 6241{
26fc96e8
JM
6242 struct wpa_global *global = wpa_s->global;
6243 struct wpa_supplicant *iface, *prev;
6244
6245 if (wpa_s == wpa_s->parent)
6246 wpas_p2p_group_remove(wpa_s, "*");
6247
6248 iface = global->ifaces;
6249 while (iface) {
96a26ab7
LD
6250 if (iface->p2pdev == wpa_s)
6251 iface->p2pdev = iface->parent;
26fc96e8
JM
6252 if (iface == wpa_s || iface->parent != wpa_s) {
6253 iface = iface->next;
6254 continue;
6255 }
6256 wpa_printf(MSG_DEBUG,
6257 "Remove remaining child interface %s from parent %s",
6258 iface->ifname, wpa_s->ifname);
6259 prev = iface;
6260 iface = iface->next;
6261 wpa_supplicant_remove_iface(global, prev, terminate);
6262 }
6263
e679f140 6264 wpa_s->disconnected = 1;
6fc6879b
JM
6265 if (wpa_s->drv_priv) {
6266 wpa_supplicant_deauthenticate(wpa_s,
6267 WLAN_REASON_DEAUTH_LEAVING);
6268
6fc6879b
JM
6269 wpa_drv_set_countermeasures(wpa_s, 0);
6270 wpa_clear_keys(wpa_s, NULL);
6271 }
6272
8e56d189 6273 wpa_supplicant_cleanup(wpa_s);
bd10d938 6274 wpas_p2p_deinit_iface(wpa_s);
ab28911d 6275
1f965e62 6276 wpas_ctrl_radio_work_flush(wpa_s);
202dec2a
JM
6277 radio_remove_interface(wpa_s);
6278
b36a3a65
AN
6279#ifdef CONFIG_FST
6280 if (wpa_s->fst) {
6281 fst_detach(wpa_s->fst);
6282 wpa_s->fst = NULL;
6283 }
6284 if (wpa_s->received_mb_ies) {
6285 wpabuf_free(wpa_s->received_mb_ies);
6286 wpa_s->received_mb_ies = NULL;
6287 }
6288#endif /* CONFIG_FST */
6289
6fc6879b
JM
6290 if (wpa_s->drv_priv)
6291 wpa_drv_deinit(wpa_s);
2523ff6e
DS
6292
6293 if (notify)
6294 wpas_notify_iface_removed(wpa_s);
f0811516
DS
6295
6296 if (terminate)
6297 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
6298
6299 if (wpa_s->ctrl_iface) {
6300 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
6301 wpa_s->ctrl_iface = NULL;
6302 }
6303
603a3f34
JL
6304#ifdef CONFIG_MESH
6305 if (wpa_s->ifmsh) {
6306 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
6307 wpa_s->ifmsh = NULL;
6308 }
6309#endif /* CONFIG_MESH */
6310
f0811516
DS
6311 if (wpa_s->conf != NULL) {
6312 wpa_config_free(wpa_s->conf);
6313 wpa_s->conf = NULL;
6314 }
18e00b5e 6315
a80651d0 6316 os_free(wpa_s->ssids_from_scan_req);
16ef233b 6317 os_free(wpa_s->last_scan_freqs);
a80651d0 6318
18e00b5e 6319 os_free(wpa_s);
6fc6879b
JM
6320}
6321
6322
2e997eec
RM
6323#ifdef CONFIG_MATCH_IFACE
6324
6325/**
6326 * wpa_supplicant_match_iface - Match an interface description to a name
6327 * @global: Pointer to global data from wpa_supplicant_init()
6328 * @ifname: Name of the interface to match
6329 * Returns: Pointer to the created interface description or %NULL on failure
6330 */
6331struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
6332 const char *ifname)
6333{
6334 int i;
6335 struct wpa_interface *iface, *miface;
6336
6337 for (i = 0; i < global->params.match_iface_count; i++) {
6338 miface = &global->params.match_ifaces[i];
6339 if (!miface->ifname ||
6340 fnmatch(miface->ifname, ifname, 0) == 0) {
6341 iface = os_zalloc(sizeof(*iface));
6342 if (!iface)
6343 return NULL;
6344 *iface = *miface;
6345 iface->ifname = ifname;
6346 return iface;
6347 }
6348 }
6349
6350 return NULL;
6351}
6352
6353
6354/**
6355 * wpa_supplicant_match_existing - Match existing interfaces
6356 * @global: Pointer to global data from wpa_supplicant_init()
6357 * Returns: 0 on success, -1 on failure
6358 */
6359static int wpa_supplicant_match_existing(struct wpa_global *global)
6360{
6361 struct if_nameindex *ifi, *ifp;
6362 struct wpa_supplicant *wpa_s;
6363 struct wpa_interface *iface;
6364
6365 ifp = if_nameindex();
6366 if (!ifp) {
6367 wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
6368 return -1;
6369 }
6370
6371 for (ifi = ifp; ifi->if_name; ifi++) {
6372 wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
6373 if (wpa_s)
6374 continue;
6375 iface = wpa_supplicant_match_iface(global, ifi->if_name);
6376 if (iface) {
6377 wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
6378 os_free(iface);
6379 if (wpa_s)
6380 wpa_s->matched = 1;
6381 }
6382 }
6383
6384 if_freenameindex(ifp);
6385 return 0;
6386}
6387
6388#endif /* CONFIG_MATCH_IFACE */
6389
6390
6fc6879b
JM
6391/**
6392 * wpa_supplicant_add_iface - Add a new network interface
6393 * @global: Pointer to global data from wpa_supplicant_init()
6394 * @iface: Interface configuration options
1772d348 6395 * @parent: Parent interface or %NULL to assign new interface as parent
6fc6879b
JM
6396 * Returns: Pointer to the created interface or %NULL on failure
6397 *
6398 * This function is used to add new network interfaces for %wpa_supplicant.
6399 * This can be called before wpa_supplicant_run() to add interfaces before the
6400 * main event loop has been started. In addition, new interfaces can be added
6401 * dynamically while %wpa_supplicant is already running. This could happen,
6402 * e.g., when a hotplug network adapter is inserted.
6403 */
6404struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
1772d348
JM
6405 struct wpa_interface *iface,
6406 struct wpa_supplicant *parent)
6fc6879b
JM
6407{
6408 struct wpa_supplicant *wpa_s;
d27df100 6409 struct wpa_interface t_iface;
8e56d189 6410 struct wpa_ssid *ssid;
6fc6879b
JM
6411
6412 if (global == NULL || iface == NULL)
6413 return NULL;
6414
1772d348 6415 wpa_s = wpa_supplicant_alloc(parent);
6fc6879b
JM
6416 if (wpa_s == NULL)
6417 return NULL;
6418
d8222ae3
JM
6419 wpa_s->global = global;
6420
d27df100
JM
6421 t_iface = *iface;
6422 if (global->params.override_driver) {
6423 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
6424 "('%s' -> '%s')",
6425 iface->driver, global->params.override_driver);
6426 t_iface.driver = global->params.override_driver;
6427 }
6428 if (global->params.override_ctrl_interface) {
6429 wpa_printf(MSG_DEBUG, "Override interface parameter: "
6430 "ctrl_interface ('%s' -> '%s')",
6431 iface->ctrl_interface,
6432 global->params.override_ctrl_interface);
6433 t_iface.ctrl_interface =
6434 global->params.override_ctrl_interface;
6435 }
6436 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
6437 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
6438 iface->ifname);
df509539 6439 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
6440 return NULL;
6441 }
6442
21efc940
TB
6443 if (iface->p2p_mgmt == 0) {
6444 /* Notify the control interfaces about new iface */
6445 if (wpas_notify_iface_added(wpa_s)) {
6446 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
6447 return NULL;
6448 }
1bd3f426 6449
21efc940
TB
6450 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
6451 wpas_notify_network_added(wpa_s, ssid);
6452 }
8e56d189 6453
6fc6879b
JM
6454 wpa_s->next = global->ifaces;
6455 global->ifaces = wpa_s;
6456
f049052b 6457 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 6458 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b 6459
c3c4b3ed
JM
6460#ifdef CONFIG_P2P
6461 if (wpa_s->global->p2p == NULL &&
74802c09 6462 !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
c3c4b3ed 6463 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
f43c1ae7
IP
6464 wpas_p2p_add_p2pdev_interface(
6465 wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
c3c4b3ed
JM
6466 wpa_printf(MSG_INFO,
6467 "P2P: Failed to enable P2P Device interface");
6468 /* Try to continue without. P2P will be disabled. */
6469 }
6470#endif /* CONFIG_P2P */
6471
6fc6879b
JM
6472 return wpa_s;
6473}
6474
6475
6476/**
6477 * wpa_supplicant_remove_iface - Remove a network interface
6478 * @global: Pointer to global data from wpa_supplicant_init()
6479 * @wpa_s: Pointer to the network interface to be removed
6480 * Returns: 0 if interface was removed, -1 if interface was not found
6481 *
6482 * This function can be used to dynamically remove network interfaces from
6483 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
6484 * addition, this function is used to remove all remaining interfaces when
6485 * %wpa_supplicant is terminated.
6486 */
6487int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
6488 struct wpa_supplicant *wpa_s,
6489 int terminate)
6fc6879b
JM
6490{
6491 struct wpa_supplicant *prev;
5b78493f
MH
6492#ifdef CONFIG_MESH
6493 unsigned int mesh_if_created = wpa_s->mesh_if_created;
6494 char *ifname = NULL;
9b170991 6495 struct wpa_supplicant *parent = wpa_s->parent;
5b78493f 6496#endif /* CONFIG_MESH */
6fc6879b
JM
6497
6498 /* Remove interface from the global list of interfaces */
6499 prev = global->ifaces;
6500 if (prev == wpa_s) {
6501 global->ifaces = wpa_s->next;
6502 } else {
6503 while (prev && prev->next != wpa_s)
6504 prev = prev->next;
6505 if (prev == NULL)
6506 return -1;
6507 prev->next = wpa_s->next;
6508 }
6509
f049052b 6510 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 6511
5b78493f
MH
6512#ifdef CONFIG_MESH
6513 if (mesh_if_created) {
6514 ifname = os_strdup(wpa_s->ifname);
6515 if (ifname == NULL) {
6516 wpa_dbg(wpa_s, MSG_ERROR,
6517 "mesh: Failed to malloc ifname");
6518 return -1;
6519 }
6520 }
6521#endif /* CONFIG_MESH */
6522
b22128ef
JM
6523 if (global->p2p_group_formation == wpa_s)
6524 global->p2p_group_formation = NULL;
dbca75f8
JM
6525 if (global->p2p_invite_group == wpa_s)
6526 global->p2p_invite_group = NULL;
df509539 6527 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b 6528
5b78493f
MH
6529#ifdef CONFIG_MESH
6530 if (mesh_if_created) {
9b170991 6531 wpa_drv_if_remove(parent, WPA_IF_MESH, ifname);
5b78493f
MH
6532 os_free(ifname);
6533 }
6534#endif /* CONFIG_MESH */
6535
6fc6879b
JM
6536 return 0;
6537}
6538
6539
cf83fb0b
PS
6540/**
6541 * wpa_supplicant_get_eap_mode - Get the current EAP mode
6542 * @wpa_s: Pointer to the network interface
6543 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
6544 */
6545const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
6546{
6547 const char *eapol_method;
6548
6549 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
6550 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
6551 return "NO-EAP";
6552 }
6553
6554 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
6555 if (eapol_method == NULL)
6556 return "UNKNOWN-EAP";
6557
6558 return eapol_method;
6559}
6560
6561
6fc6879b
JM
6562/**
6563 * wpa_supplicant_get_iface - Get a new network interface
6564 * @global: Pointer to global data from wpa_supplicant_init()
6565 * @ifname: Interface name
6566 * Returns: Pointer to the interface or %NULL if not found
6567 */
6568struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
6569 const char *ifname)
6570{
6571 struct wpa_supplicant *wpa_s;
6572
6573 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
6574 if (os_strcmp(wpa_s->ifname, ifname) == 0)
6575 return wpa_s;
6576 }
6577 return NULL;
6578}
6579
6580
50b16da1 6581#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
6582static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
6583{
6584 struct wpa_supplicant *wpa_s = ctx;
6585 if (wpa_s == NULL)
6586 return NULL;
6587 return wpa_s->ifname;
6588}
50b16da1 6589#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
6590
6591
8c0d0ff2
JM
6592#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
6593#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
6594#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
6595
6596/* Periodic cleanup tasks */
6597static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
6598{
6599 struct wpa_global *global = eloop_ctx;
6600 struct wpa_supplicant *wpa_s;
6601
6602 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
6603 wpas_periodic, global, NULL);
6604
6605#ifdef CONFIG_P2P
6606 if (global->p2p)
6607 p2p_expire_peers(global->p2p);
6608#endif /* CONFIG_P2P */
6609
3188aaba 6610 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
8c0d0ff2 6611 wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
3188aaba
JM
6612#ifdef CONFIG_AP
6613 ap_periodic(wpa_s);
6614#endif /* CONFIG_AP */
6615 }
8c0d0ff2
JM
6616}
6617
6618
6fc6879b
JM
6619/**
6620 * wpa_supplicant_init - Initialize %wpa_supplicant
6621 * @params: Parameters for %wpa_supplicant
6622 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
6623 *
6624 * This function is used to initialize %wpa_supplicant. After successful
6625 * initialization, the returned data pointer can be used to add and remove
6626 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
6627 */
6628struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
6629{
6630 struct wpa_global *global;
ac305589 6631 int ret, i;
6fc6879b
JM
6632
6633 if (params == NULL)
6634 return NULL;
6635
39e7d718
JM
6636#ifdef CONFIG_DRIVER_NDIS
6637 {
6638 void driver_ndis_init_ops(void);
6639 driver_ndis_init_ops();
6640 }
6641#endif /* CONFIG_DRIVER_NDIS */
6642
50b16da1 6643#ifndef CONFIG_NO_WPA_MSG
4f1495ae 6644 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 6645#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 6646
f4637fe0
JM
6647 if (params->wpa_debug_file_path)
6648 wpa_debug_open_file(params->wpa_debug_file_path);
6649 else
6650 wpa_debug_setup_stdout();
daa70d49
SL
6651 if (params->wpa_debug_syslog)
6652 wpa_debug_open_syslog();
4f68895e
JB
6653 if (params->wpa_debug_tracing) {
6654 ret = wpa_debug_open_linux_tracing();
6655 if (ret) {
6656 wpa_printf(MSG_ERROR,
6657 "Failed to enable trace logging");
6658 return NULL;
6659 }
6660 }
6fc6879b 6661
12760815 6662 ret = eap_register_methods();
6fc6879b
JM
6663 if (ret) {
6664 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
6665 if (ret == -2)
6666 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
6667 "the same EAP type.");
6668 return NULL;
6669 }
6670
6671 global = os_zalloc(sizeof(*global));
6672 if (global == NULL)
6673 return NULL;
b22128ef
JM
6674 dl_list_init(&global->p2p_srv_bonjour);
6675 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
6676 global->params.daemonize = params->daemonize;
6677 global->params.wait_for_monitor = params->wait_for_monitor;
6678 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
6679 if (params->pid_file)
6680 global->params.pid_file = os_strdup(params->pid_file);
6681 if (params->ctrl_interface)
6682 global->params.ctrl_interface =
6683 os_strdup(params->ctrl_interface);
29257565
JM
6684 if (params->ctrl_interface_group)
6685 global->params.ctrl_interface_group =
6686 os_strdup(params->ctrl_interface_group);
d27df100
JM
6687 if (params->override_driver)
6688 global->params.override_driver =
6689 os_strdup(params->override_driver);
6690 if (params->override_ctrl_interface)
6691 global->params.override_ctrl_interface =
6692 os_strdup(params->override_ctrl_interface);
2e997eec
RM
6693#ifdef CONFIG_MATCH_IFACE
6694 global->params.match_iface_count = params->match_iface_count;
6695 if (params->match_iface_count) {
6696 global->params.match_ifaces =
6697 os_calloc(params->match_iface_count,
6698 sizeof(struct wpa_interface));
6699 os_memcpy(global->params.match_ifaces,
6700 params->match_ifaces,
6701 params->match_iface_count *
6702 sizeof(struct wpa_interface));
6703 }
6704#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
6705#ifdef CONFIG_P2P
6706 if (params->conf_p2p_dev)
6707 global->params.conf_p2p_dev =
6708 os_strdup(params->conf_p2p_dev);
6709#endif /* CONFIG_P2P */
6fc6879b
JM
6710 wpa_debug_level = global->params.wpa_debug_level =
6711 params->wpa_debug_level;
6712 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
6713 params->wpa_debug_show_keys;
6714 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
6715 params->wpa_debug_timestamp;
6716
f19858f5
JM
6717 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
6718
0456ea16 6719 if (eloop_init()) {
6fc6879b
JM
6720 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
6721 wpa_supplicant_deinit(global);
6722 return NULL;
6723 }
6724
38e24575 6725 random_init(params->entropy_file);
d47fa330 6726
6fc6879b
JM
6727 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
6728 if (global->ctrl_iface == NULL) {
6729 wpa_supplicant_deinit(global);
6730 return NULL;
6731 }
6732
dc461de4
WS
6733 if (wpas_notify_supplicant_initialized(global)) {
6734 wpa_supplicant_deinit(global);
6735 return NULL;
6fc6879b
JM
6736 }
6737
c5121837 6738 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
6739 global->drv_count++;
6740 if (global->drv_count == 0) {
6741 wpa_printf(MSG_ERROR, "No drivers enabled");
6742 wpa_supplicant_deinit(global);
6743 return NULL;
6744 }
faebdeaa 6745 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
ac305589
JM
6746 if (global->drv_priv == NULL) {
6747 wpa_supplicant_deinit(global);
6748 return NULL;
6749 }
ac305589 6750
9675ce35
JM
6751#ifdef CONFIG_WIFI_DISPLAY
6752 if (wifi_display_init(global) < 0) {
6753 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
6754 wpa_supplicant_deinit(global);
6755 return NULL;
6756 }
6757#endif /* CONFIG_WIFI_DISPLAY */
6758
8c0d0ff2
JM
6759 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
6760 wpas_periodic, global, NULL);
6761
6fc6879b
JM
6762 return global;
6763}
6764
6765
6766/**
6767 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
6768 * @global: Pointer to global data from wpa_supplicant_init()
6769 * Returns: 0 after successful event loop run, -1 on failure
6770 *
6771 * This function starts the main event loop and continues running as long as
6772 * there are any remaining events. In most cases, this function is running as
6773 * long as the %wpa_supplicant process in still in use.
6774 */
6775int wpa_supplicant_run(struct wpa_global *global)
6776{
6777 struct wpa_supplicant *wpa_s;
6778
6779 if (global->params.daemonize &&
2e69bdd1
RM
6780 (wpa_supplicant_daemon(global->params.pid_file) ||
6781 eloop_sock_requeue()))
6fc6879b
JM
6782 return -1;
6783
2e997eec
RM
6784#ifdef CONFIG_MATCH_IFACE
6785 if (wpa_supplicant_match_existing(global))
6786 return -1;
6787#endif
6788
6fc6879b
JM
6789 if (global->params.wait_for_monitor) {
6790 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
ede77701 6791 if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
6fc6879b
JM
6792 wpa_supplicant_ctrl_iface_wait(
6793 wpa_s->ctrl_iface);
6794 }
6795
0456ea16
JM
6796 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
6797 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
6798
6799 eloop_run();
6800
6801 return 0;
6802}
6803
6804
6805/**
6806 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
6807 * @global: Pointer to global data from wpa_supplicant_init()
6808 *
6809 * This function is called to deinitialize %wpa_supplicant and to free all
6810 * allocated resources. Remaining network interfaces will also be removed.
6811 */
6812void wpa_supplicant_deinit(struct wpa_global *global)
6813{
ac305589
JM
6814 int i;
6815
6fc6879b
JM
6816 if (global == NULL)
6817 return;
6818
8c0d0ff2
JM
6819 eloop_cancel_timeout(wpas_periodic, global, NULL);
6820
9675ce35
JM
6821#ifdef CONFIG_WIFI_DISPLAY
6822 wifi_display_deinit(global);
6823#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 6824
6fc6879b 6825 while (global->ifaces)
df509539 6826 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
6827
6828 if (global->ctrl_iface)
6829 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
6830
6831 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
6832
6833 eap_peer_unregister_methods();
3ec97afe
JM
6834#ifdef CONFIG_AP
6835 eap_server_unregister_methods();
6836#endif /* CONFIG_AP */
6fc6879b 6837
c5121837 6838 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
6839 if (!global->drv_priv[i])
6840 continue;
c5121837 6841 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
6842 }
6843 os_free(global->drv_priv);
6844
d47fa330
JM
6845 random_deinit();
6846
6fc6879b
JM
6847 eloop_destroy();
6848
6849 if (global->params.pid_file) {
6850 os_daemonize_terminate(global->params.pid_file);
6851 os_free(global->params.pid_file);
6852 }
6853 os_free(global->params.ctrl_interface);
29257565 6854 os_free(global->params.ctrl_interface_group);
d27df100
JM
6855 os_free(global->params.override_driver);
6856 os_free(global->params.override_ctrl_interface);
2e997eec
RM
6857#ifdef CONFIG_MATCH_IFACE
6858 os_free(global->params.match_ifaces);
6859#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
6860#ifdef CONFIG_P2P
6861 os_free(global->params.conf_p2p_dev);
6862#endif /* CONFIG_P2P */
6fc6879b 6863
af8a827b 6864 os_free(global->p2p_disallow_freq.range);
253f2e37 6865 os_free(global->p2p_go_avoid_freq.range);
01a57fe4 6866 os_free(global->add_psk);
6f3bc72b 6867
6fc6879b 6868 os_free(global);
daa70d49 6869 wpa_debug_close_syslog();
6fc6879b 6870 wpa_debug_close_file();
4f68895e 6871 wpa_debug_close_linux_tracing();
6fc6879b 6872}
611aea7d
JM
6873
6874
6875void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
6876{
849b5dc7
JM
6877 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
6878 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
6879 char country[3];
6880 country[0] = wpa_s->conf->country[0];
6881 country[1] = wpa_s->conf->country[1];
6882 country[2] = '\0';
6883 if (wpa_drv_set_country(wpa_s, country) < 0) {
6884 wpa_printf(MSG_ERROR, "Failed to set country code "
6885 "'%s'", country);
6886 }
6887 }
6888
306ae225
JM
6889 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
6890 wpas_init_ext_pw(wpa_s);
6891
bea48f77
JM
6892 if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
6893 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
6894
3c7863f8
LD
6895 if (wpa_s->conf->changed_parameters & CFG_CHANGED_WOWLAN_TRIGGERS) {
6896 struct wpa_driver_capa capa;
6897 int res = wpa_drv_get_capa(wpa_s, &capa);
6898
6899 if (res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
6900 wpa_printf(MSG_ERROR,
6901 "Failed to update wowlan_triggers to '%s'",
6902 wpa_s->conf->wowlan_triggers);
6903 }
6904
ef59f987
AB
6905 if (wpa_s->conf->changed_parameters & CFG_CHANGED_DISABLE_BTM)
6906 wpa_supplicant_set_default_scan_ies(wpa_s);
6907
611aea7d
JM
6908#ifdef CONFIG_WPS
6909 wpas_wps_update_config(wpa_s);
6910#endif /* CONFIG_WPS */
b22128ef 6911 wpas_p2p_update_config(wpa_s);
611aea7d
JM
6912 wpa_s->conf->changed_parameters = 0;
6913}
2f9c6aa6
JM
6914
6915
e1117c1c 6916void add_freq(int *freqs, int *num_freqs, int freq)
0fb337c1
JM
6917{
6918 int i;
6919
6920 for (i = 0; i < *num_freqs; i++) {
6921 if (freqs[i] == freq)
6922 return;
6923 }
6924
6925 freqs[*num_freqs] = freq;
6926 (*num_freqs)++;
6927}
6928
6929
6930static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
6931{
6932 struct wpa_bss *bss, *cbss;
6933 const int max_freqs = 10;
6934 int *freqs;
6935 int num_freqs = 0;
6936
faebdeaa 6937 freqs = os_calloc(max_freqs + 1, sizeof(int));
0fb337c1
JM
6938 if (freqs == NULL)
6939 return NULL;
6940
6941 cbss = wpa_s->current_bss;
6942
6943 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
6944 if (bss == cbss)
6945 continue;
6946 if (bss->ssid_len == cbss->ssid_len &&
6947 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
6948 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
6949 add_freq(freqs, &num_freqs, bss->freq);
6950 if (num_freqs == max_freqs)
6951 break;
6952 }
6953 }
6954
6955 if (num_freqs == 0) {
6956 os_free(freqs);
6957 freqs = NULL;
6958 }
6959
6960 return freqs;
6961}
6962
6963
6964void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
6965{
6966 int timeout;
6967 int count;
6968 int *freqs = NULL;
6969
6ac4b15e
JM
6970 wpas_connect_work_done(wpa_s);
6971
5fd9fb27
JM
6972 /*
6973 * Remove possible authentication timeout since the connection failed.
6974 */
6975 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
6976
c2805909
JM
6977 /*
6978 * There is no point in blacklisting the AP if this event is
6979 * generated based on local request to disconnect.
6980 */
6981 if (wpa_s->own_disconnect_req) {
6982 wpa_s->own_disconnect_req = 0;
6983 wpa_dbg(wpa_s, MSG_DEBUG,
6984 "Ignore connection failure due to local request to disconnect");
6985 return;
6986 }
0cdb93fe 6987 if (wpa_s->disconnected) {
0cdb93fe
JM
6988 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
6989 "indication since interface has been put into "
6990 "disconnected state");
6991 return;
6992 }
6993
0fb337c1
JM
6994 /*
6995 * Add the failed BSSID into the blacklist and speed up next scan
6996 * attempt if there could be other APs that could accept association.
6997 * The current blacklist count indicates how many times we have tried
6998 * connecting to this AP and multiple attempts mean that other APs are
6999 * either not available or has already been tried, so that we can start
7000 * increasing the delay here to avoid constant scanning.
7001 */
7002 count = wpa_blacklist_add(wpa_s, bssid);
7003 if (count == 1 && wpa_s->current_bss) {
7004 /*
7005 * This BSS was not in the blacklist before. If there is
7006 * another BSS available for the same ESS, we should try that
7007 * next. Otherwise, we may as well try this one once more
7008 * before allowing other, likely worse, ESSes to be considered.
7009 */
7010 freqs = get_bss_freqs_in_ess(wpa_s);
7011 if (freqs) {
f049052b
BG
7012 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
7013 "has been seen; try it next");
0fb337c1
JM
7014 wpa_blacklist_add(wpa_s, bssid);
7015 /*
7016 * On the next scan, go through only the known channels
7017 * used in this ESS based on previous scans to speed up
7018 * common load balancing use case.
7019 */
7020 os_free(wpa_s->next_scan_freqs);
7021 wpa_s->next_scan_freqs = freqs;
7022 }
7023 }
7024
f1a52633
JM
7025 /*
7026 * Add previous failure count in case the temporary blacklist was
7027 * cleared due to no other BSSes being available.
7028 */
7029 count += wpa_s->extra_blacklist_count;
7030
dd579704
JM
7031 if (count > 3 && wpa_s->current_ssid) {
7032 wpa_printf(MSG_DEBUG, "Continuous association failures - "
7033 "consider temporary network disabling");
b19c098e 7034 wpas_auth_failed(wpa_s, "CONN_FAILED");
dd579704
JM
7035 }
7036
0fb337c1
JM
7037 switch (count) {
7038 case 1:
7039 timeout = 100;
7040 break;
7041 case 2:
7042 timeout = 500;
7043 break;
7044 case 3:
7045 timeout = 1000;
7046 break;
f1a52633 7047 case 4:
0fb337c1 7048 timeout = 5000;
f1a52633
JM
7049 break;
7050 default:
7051 timeout = 10000;
7052 break;
0fb337c1
JM
7053 }
7054
f1a52633
JM
7055 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
7056 "ms", count, timeout);
7057
0fb337c1
JM
7058 /*
7059 * TODO: if more than one possible AP is available in scan results,
7060 * could try the other ones before requesting a new scan.
7061 */
0a42f1ed
IP
7062
7063 /* speed up the connection attempt with normal scan */
7064 wpa_s->normal_scans = 0;
0fb337c1
JM
7065 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
7066 1000 * (timeout % 1000));
7067}
22628eca
JM
7068
7069
af835d75
AB
7070#ifdef CONFIG_FILS
7071void fils_connection_failure(struct wpa_supplicant *wpa_s)
7072{
7073 struct wpa_ssid *ssid = wpa_s->current_ssid;
7074 const u8 *realm, *username, *rrk;
7075 size_t realm_len, username_len, rrk_len;
7076 u16 next_seq_num;
7077
7078 if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt) ||
7079 eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
7080 &username, &username_len,
7081 &realm, &realm_len, &next_seq_num,
7082 &rrk, &rrk_len) != 0 ||
7083 !realm)
7084 return;
7085
7086 wpa_hexdump_ascii(MSG_DEBUG,
7087 "FILS: Store last connection failure realm",
7088 realm, realm_len);
7089 os_free(wpa_s->last_con_fail_realm);
7090 wpa_s->last_con_fail_realm = os_malloc(realm_len);
7091 if (wpa_s->last_con_fail_realm) {
7092 wpa_s->last_con_fail_realm_len = realm_len;
7093 os_memcpy(wpa_s->last_con_fail_realm, realm, realm_len);
7094 }
7095}
7096#endif /* CONFIG_FILS */
7097
7098
22628eca
JM
7099int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
7100{
7101 return wpa_s->conf->ap_scan == 2 ||
7102 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
7103}
d2118814
JM
7104
7105
7106#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
7107int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
7108 struct wpa_ssid *ssid,
7109 const char *field,
7110 const char *value)
7111{
7112#ifdef IEEE8021X_EAPOL
7113 struct eap_peer_config *eap = &ssid->eap;
7114
7115 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
7116 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
7117 (const u8 *) value, os_strlen(value));
7118
7119 switch (wpa_supplicant_ctrl_req_from_string(field)) {
7120 case WPA_CTRL_REQ_EAP_IDENTITY:
7121 os_free(eap->identity);
7122 eap->identity = (u8 *) os_strdup(value);
7123 eap->identity_len = os_strlen(value);
7124 eap->pending_req_identity = 0;
7125 if (ssid == wpa_s->current_ssid)
7126 wpa_s->reassociate = 1;
7127 break;
7128 case WPA_CTRL_REQ_EAP_PASSWORD:
19c48da0 7129 bin_clear_free(eap->password, eap->password_len);
d2118814
JM
7130 eap->password = (u8 *) os_strdup(value);
7131 eap->password_len = os_strlen(value);
7132 eap->pending_req_password = 0;
7133 if (ssid == wpa_s->current_ssid)
7134 wpa_s->reassociate = 1;
7135 break;
7136 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
19c48da0 7137 bin_clear_free(eap->new_password, eap->new_password_len);
d2118814
JM
7138 eap->new_password = (u8 *) os_strdup(value);
7139 eap->new_password_len = os_strlen(value);
7140 eap->pending_req_new_password = 0;
7141 if (ssid == wpa_s->current_ssid)
7142 wpa_s->reassociate = 1;
7143 break;
7144 case WPA_CTRL_REQ_EAP_PIN:
b99c4cad
JM
7145 str_clear_free(eap->cert.pin);
7146 eap->cert.pin = os_strdup(value);
d2118814
JM
7147 eap->pending_req_pin = 0;
7148 if (ssid == wpa_s->current_ssid)
7149 wpa_s->reassociate = 1;
7150 break;
7151 case WPA_CTRL_REQ_EAP_OTP:
19c48da0 7152 bin_clear_free(eap->otp, eap->otp_len);
d2118814
JM
7153 eap->otp = (u8 *) os_strdup(value);
7154 eap->otp_len = os_strlen(value);
7155 os_free(eap->pending_req_otp);
7156 eap->pending_req_otp = NULL;
7157 eap->pending_req_otp_len = 0;
7158 break;
7159 case WPA_CTRL_REQ_EAP_PASSPHRASE:
b99c4cad
JM
7160 str_clear_free(eap->cert.private_key_passwd);
7161 eap->cert.private_key_passwd = os_strdup(value);
d2118814
JM
7162 eap->pending_req_passphrase = 0;
7163 if (ssid == wpa_s->current_ssid)
7164 wpa_s->reassociate = 1;
7165 break;
a5d44ac0 7166 case WPA_CTRL_REQ_SIM:
19c48da0 7167 str_clear_free(eap->external_sim_resp);
a5d44ac0 7168 eap->external_sim_resp = os_strdup(value);
ed9b1c16 7169 eap->pending_req_sim = 0;
a5d44ac0 7170 break;
a52410c2
JM
7171 case WPA_CTRL_REQ_PSK_PASSPHRASE:
7172 if (wpa_config_set(ssid, "psk", value, 0) < 0)
7173 return -1;
7174 ssid->mem_only_psk = 1;
7175 if (ssid->passphrase)
7176 wpa_config_update_psk(ssid);
7177 if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
7178 wpa_supplicant_req_scan(wpa_s, 0, 0);
7179 break;
3c108b75
JM
7180 case WPA_CTRL_REQ_EXT_CERT_CHECK:
7181 if (eap->pending_ext_cert_check != PENDING_CHECK)
7182 return -1;
7183 if (os_strcmp(value, "good") == 0)
7184 eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
7185 else if (os_strcmp(value, "bad") == 0)
7186 eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
7187 else
7188 return -1;
7189 break;
d2118814
JM
7190 default:
7191 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
7192 return -1;
7193 }
7194
7195 return 0;
7196#else /* IEEE8021X_EAPOL */
7197 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
7198 return -1;
7199#endif /* IEEE8021X_EAPOL */
7200}
7201#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
7202
7203
7204int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
7205{
7206 int i;
7207 unsigned int drv_enc;
7208
44b9ea5b
JM
7209 if (wpa_s->p2p_mgmt)
7210 return 1; /* no normal network profiles on p2p_mgmt interface */
7211
349493bd
JM
7212 if (ssid == NULL)
7213 return 1;
7214
7215 if (ssid->disabled)
7216 return 1;
7217
9feadba1 7218 if (wpa_s->drv_capa_known)
349493bd
JM
7219 drv_enc = wpa_s->drv_enc;
7220 else
7221 drv_enc = (unsigned int) -1;
7222
7223 for (i = 0; i < NUM_WEP_KEYS; i++) {
7224 size_t len = ssid->wep_key_len[i];
7225 if (len == 0)
7226 continue;
7227 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
7228 continue;
7229 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
7230 continue;
7231 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
7232 continue;
7233 return 1; /* invalid WEP key */
7234 }
7235
9173b16f 7236 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
a52410c2 7237 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
a34ca59e 7238 !(wpa_key_mgmt_sae(ssid->key_mgmt) && ssid->sae_password) &&
a52410c2 7239 !ssid->mem_only_psk)
2518aad3
JM
7240 return 1;
7241
349493bd
JM
7242 return 0;
7243}
b9cfc09a
JJ
7244
7245
3f56a2b7
JM
7246int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
7247{
3f56a2b7
JM
7248 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
7249 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
7250 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
7251 /*
7252 * Driver does not support BIP -- ignore pmf=1 default
7253 * since the connection with PMF would fail and the
7254 * configuration does not require PMF to be enabled.
7255 */
7256 return NO_MGMT_FRAME_PROTECTION;
7257 }
7258
22950049
JM
7259 if (ssid &&
7260 (ssid->key_mgmt &
7261 ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
7262 WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
7263 /*
7264 * Do not use the default PMF value for non-RSN networks
7265 * since PMF is available only with RSN and pmf=2
7266 * configuration would otherwise prevent connections to
7267 * all open networks.
7268 */
7269 return NO_MGMT_FRAME_PROTECTION;
7270 }
7271
3f56a2b7
JM
7272 return wpa_s->conf->pmf;
7273 }
7274
7275 return ssid->ieee80211w;
3f56a2b7
JM
7276}
7277
7278
b9cfc09a
JJ
7279int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
7280{
7281 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
7282 return 1;
7283 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
7284 return 0;
7285 return -1;
7286}
00e5e3d5
JM
7287
7288
b19c098e 7289void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
00e5e3d5
JM
7290{
7291 struct wpa_ssid *ssid = wpa_s->current_ssid;
7292 int dur;
4e1eae1d 7293 struct os_reltime now;
00e5e3d5
JM
7294
7295 if (ssid == NULL) {
7296 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
7297 "SSID block");
7298 return;
7299 }
7300
7301 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
7302 return;
7303
7304 ssid->auth_failures++;
cbf41ca7
SL
7305
7306#ifdef CONFIG_P2P
7307 if (ssid->p2p_group &&
7308 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
7309 /*
7310 * Skip the wait time since there is a short timeout on the
7311 * connection to a P2P group.
7312 */
7313 return;
7314 }
7315#endif /* CONFIG_P2P */
7316
00e5e3d5
JM
7317 if (ssid->auth_failures > 50)
7318 dur = 300;
00e5e3d5 7319 else if (ssid->auth_failures > 10)
8a77f1be 7320 dur = 120;
00e5e3d5 7321 else if (ssid->auth_failures > 5)
8a77f1be
JM
7322 dur = 90;
7323 else if (ssid->auth_failures > 3)
7324 dur = 60;
7325 else if (ssid->auth_failures > 2)
00e5e3d5
JM
7326 dur = 30;
7327 else if (ssid->auth_failures > 1)
7328 dur = 20;
7329 else
7330 dur = 10;
7331
8a77f1be
JM
7332 if (ssid->auth_failures > 1 &&
7333 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
7334 dur += os_random() % (ssid->auth_failures * 10);
7335
4e1eae1d 7336 os_get_reltime(&now);
00e5e3d5
JM
7337 if (now.sec + dur <= ssid->disabled_until.sec)
7338 return;
7339
7340 ssid->disabled_until.sec = now.sec + dur;
7341
7342 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
b19c098e 7343 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
00e5e3d5 7344 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
b19c098e 7345 ssid->auth_failures, dur, reason);
00e5e3d5
JM
7346}
7347
7348
7349void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
7350 struct wpa_ssid *ssid, int clear_failures)
7351{
7352 if (ssid == NULL)
7353 return;
7354
7355 if (ssid->disabled_until.sec) {
7356 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
7357 "id=%d ssid=\"%s\"",
7358 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
7359 }
7360 ssid->disabled_until.sec = 0;
7361 ssid->disabled_until.usec = 0;
7362 if (clear_failures)
7363 ssid->auth_failures = 0;
7364}
6407f413
JM
7365
7366
7367int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
7368{
7369 size_t i;
7370
7371 if (wpa_s->disallow_aps_bssid == NULL)
7372 return 0;
7373
7374 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
7375 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
7376 bssid, ETH_ALEN) == 0)
7377 return 1;
7378 }
7379
7380 return 0;
7381}
7382
7383
7384int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
7385 size_t ssid_len)
7386{
7387 size_t i;
7388
7389 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
7390 return 0;
7391
7392 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
7393 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
7394 if (ssid_len == s->ssid_len &&
7395 os_memcmp(ssid, s->ssid, ssid_len) == 0)
7396 return 1;
7397 }
7398
7399 return 0;
7400}
9796a86c
JM
7401
7402
7403/**
7404 * wpas_request_connection - Request a new connection
7405 * @wpa_s: Pointer to the network interface
7406 *
7407 * This function is used to request a new connection to be found. It will mark
7408 * the interface to allow reassociation and request a new scan to find a
7409 * suitable network to connect to.
7410 */
7411void wpas_request_connection(struct wpa_supplicant *wpa_s)
7412{
7413 wpa_s->normal_scans = 0;
5214f4fa 7414 wpa_s->scan_req = NORMAL_SCAN_REQ;
9796a86c
JM
7415 wpa_supplicant_reinit_autoscan(wpa_s);
7416 wpa_s->extra_blacklist_count = 0;
7417 wpa_s->disconnected = 0;
7418 wpa_s->reassociate = 1;
2cb40e9f 7419 wpa_s->last_owe_group = 0;
5e24beae
MH
7420
7421 if (wpa_supplicant_fast_associate(wpa_s) != 1)
7422 wpa_supplicant_req_scan(wpa_s, 0, 0);
0c5f01fd
B
7423 else
7424 wpa_s->reattach = 0;
9796a86c 7425}
36b9883d
DG
7426
7427
5f040be4
RP
7428/**
7429 * wpas_request_disconnection - Request disconnection
7430 * @wpa_s: Pointer to the network interface
7431 *
7432 * This function is used to request disconnection from the currently connected
7433 * network. This will stop any ongoing scans and initiate deauthentication.
7434 */
7435void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
7436{
7437#ifdef CONFIG_SME
7438 wpa_s->sme.prev_bssid_set = 0;
7439#endif /* CONFIG_SME */
7440 wpa_s->reassociate = 0;
7441 wpa_s->disconnected = 1;
7442 wpa_supplicant_cancel_sched_scan(wpa_s);
7443 wpa_supplicant_cancel_scan(wpa_s);
7444 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
7445 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
f5db7750
JM
7446 radio_remove_works(wpa_s, "connect", 0);
7447 radio_remove_works(wpa_s, "sme-connect", 0);
5f040be4
RP
7448}
7449
7450
a0c90bb0
IP
7451void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
7452 struct wpa_used_freq_data *freqs_data,
7453 unsigned int len)
7454{
7455 unsigned int i;
7456
7457 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
7458 len, title);
7459 for (i = 0; i < len; i++) {
7460 struct wpa_used_freq_data *cur = &freqs_data[i];
7461 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
7462 i, cur->freq, cur->flags);
7463 }
7464}
7465
7466
53c5dfc2
IP
7467/*
7468 * Find the operating frequencies of any of the virtual interfaces that
a0c90bb0
IP
7469 * are using the same radio as the current interface, and in addition, get
7470 * information about the interface types that are using the frequency.
53c5dfc2 7471 */
a0c90bb0
IP
7472int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
7473 struct wpa_used_freq_data *freqs_data,
7474 unsigned int len)
53c5dfc2 7475{
53c5dfc2
IP
7476 struct wpa_supplicant *ifs;
7477 u8 bssid[ETH_ALEN];
7478 int freq;
7479 unsigned int idx = 0, i;
7480
217cf499
JM
7481 wpa_dbg(wpa_s, MSG_DEBUG,
7482 "Determining shared radio frequencies (max len %u)", len);
a0c90bb0 7483 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
53c5dfc2 7484
0ad3b9c4
JM
7485 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
7486 radio_list) {
a0c90bb0
IP
7487 if (idx == len)
7488 break;
7489
53c5dfc2
IP
7490 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
7491 continue;
7492
7493 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
241c3333
MH
7494 ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
7495 ifs->current_ssid->mode == WPAS_MODE_MESH)
53c5dfc2
IP
7496 freq = ifs->current_ssid->frequency;
7497 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
7498 freq = ifs->assoc_freq;
7499 else
7500 continue;
7501
7502 /* Hold only distinct freqs */
7503 for (i = 0; i < idx; i++)
a0c90bb0 7504 if (freqs_data[i].freq == freq)
53c5dfc2
IP
7505 break;
7506
7507 if (i == idx)
a0c90bb0
IP
7508 freqs_data[idx++].freq = freq;
7509
7510 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
22264b3c 7511 freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
a0c90bb0
IP
7512 WPA_FREQ_USED_BY_P2P_CLIENT :
7513 WPA_FREQ_USED_BY_INFRA_STATION;
7514 }
53c5dfc2 7515 }
217cf499 7516
a0c90bb0 7517 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
53c5dfc2
IP
7518 return idx;
7519}
a0c90bb0
IP
7520
7521
7522/*
7523 * Find the operating frequencies of any of the virtual interfaces that
7524 * are using the same radio as the current interface.
7525 */
7526int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
7527 int *freq_array, unsigned int len)
7528{
7529 struct wpa_used_freq_data *freqs_data;
7530 int num, i;
7531
7532 os_memset(freq_array, 0, sizeof(int) * len);
7533
7534 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
7535 if (!freqs_data)
7536 return -1;
7537
7538 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
7539 for (i = 0; i < num; i++)
7540 freq_array[i] = freqs_data[i].freq;
7541
7542 os_free(freqs_data);
7543
7544 return num;
7545}
b361d580
AK
7546
7547
af041f99
AA
7548struct wpa_supplicant *
7549wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
7550{
7551 switch (frame) {
7552#ifdef CONFIG_P2P
7553 case VENDOR_ELEM_PROBE_REQ_P2P:
7554 case VENDOR_ELEM_PROBE_RESP_P2P:
7555 case VENDOR_ELEM_PROBE_RESP_P2P_GO:
7556 case VENDOR_ELEM_BEACON_P2P_GO:
7557 case VENDOR_ELEM_P2P_PD_REQ:
7558 case VENDOR_ELEM_P2P_PD_RESP:
7559 case VENDOR_ELEM_P2P_GO_NEG_REQ:
7560 case VENDOR_ELEM_P2P_GO_NEG_RESP:
7561 case VENDOR_ELEM_P2P_GO_NEG_CONF:
7562 case VENDOR_ELEM_P2P_INV_REQ:
7563 case VENDOR_ELEM_P2P_INV_RESP:
7564 case VENDOR_ELEM_P2P_ASSOC_REQ:
7565 case VENDOR_ELEM_P2P_ASSOC_RESP:
ba307f85 7566 return wpa_s->p2pdev;
af041f99
AA
7567#endif /* CONFIG_P2P */
7568 default:
7569 return wpa_s;
7570 }
7571}
7572
7573
7574void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
7575{
7576 unsigned int i;
7577 char buf[30];
7578
7579 wpa_printf(MSG_DEBUG, "Update vendor elements");
7580
7581 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
7582 if (wpa_s->vendor_elem[i]) {
7583 int res;
7584
7585 res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
7586 if (!os_snprintf_error(sizeof(buf), res)) {
7587 wpa_hexdump_buf(MSG_DEBUG, buf,
7588 wpa_s->vendor_elem[i]);
7589 }
7590 }
7591 }
7592
7593#ifdef CONFIG_P2P
7594 if (wpa_s->parent == wpa_s &&
7595 wpa_s->global->p2p &&
7596 !wpa_s->global->p2p_disabled)
7597 p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
7598#endif /* CONFIG_P2P */
7599}
7600
7601
7602int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
7603 const u8 *elem, size_t len)
7604{
7605 u8 *ie, *end;
7606
7607 ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
7608 end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
7609
7610 for (; ie + 1 < end; ie += 2 + ie[1]) {
7611 if (ie + len > end)
7612 break;
7613 if (os_memcmp(ie, elem, len) != 0)
7614 continue;
7615
7616 if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
7617 wpabuf_free(wpa_s->vendor_elem[frame]);
7618 wpa_s->vendor_elem[frame] = NULL;
7619 } else {
7620 os_memmove(ie, ie + len, end - (ie + len));
7621 wpa_s->vendor_elem[frame]->used -= len;
7622 }
7623 wpas_vendor_elem_update(wpa_s);
7624 return 0;
7625 }
7626
7627 return -1;
7628}
ea69d973
AS
7629
7630
7631struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
7632 u16 num_modes, enum hostapd_hw_mode mode)
7633{
7634 u16 i;
7635
7636 for (i = 0; i < num_modes; i++) {
7637 if (modes[i].mode == mode)
7638 return &modes[i];
7639 }
7640
7641 return NULL;
7642}
dd599908
AS
7643
7644
7645static struct
7646wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
7647 const u8 *bssid)
7648{
7649 struct wpa_bss_tmp_disallowed *bss;
7650
7651 dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
7652 struct wpa_bss_tmp_disallowed, list) {
7653 if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
7654 return bss;
7655 }
7656
7657 return NULL;
7658}
7659
7660
b04854ce
AP
7661static int wpa_set_driver_tmp_disallow_list(struct wpa_supplicant *wpa_s)
7662{
7663 struct wpa_bss_tmp_disallowed *tmp;
7664 unsigned int num_bssid = 0;
7665 u8 *bssids;
7666 int ret;
7667
7668 bssids = os_malloc(dl_list_len(&wpa_s->bss_tmp_disallowed) * ETH_ALEN);
7669 if (!bssids)
7670 return -1;
7671 dl_list_for_each(tmp, &wpa_s->bss_tmp_disallowed,
7672 struct wpa_bss_tmp_disallowed, list) {
7673 os_memcpy(&bssids[num_bssid * ETH_ALEN], tmp->bssid,
7674 ETH_ALEN);
7675 num_bssid++;
7676 }
7677 ret = wpa_drv_set_bssid_blacklist(wpa_s, num_bssid, bssids);
7678 os_free(bssids);
7679 return ret;
7680}
7681
7682
7683static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx)
7684{
7685 struct wpa_supplicant *wpa_s = eloop_ctx;
7686 struct wpa_bss_tmp_disallowed *tmp, *bss = timeout_ctx;
7687
7688 /* Make sure the bss is not already freed */
7689 dl_list_for_each(tmp, &wpa_s->bss_tmp_disallowed,
7690 struct wpa_bss_tmp_disallowed, list) {
7691 if (bss == tmp) {
7692 dl_list_del(&tmp->list);
7693 os_free(tmp);
7694 wpa_set_driver_tmp_disallow_list(wpa_s);
7695 break;
7696 }
7697 }
7698}
7699
7700
dd599908 7701void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
19677b77 7702 unsigned int sec, int rssi_threshold)
dd599908
AS
7703{
7704 struct wpa_bss_tmp_disallowed *bss;
dd599908
AS
7705
7706 bss = wpas_get_disallowed_bss(wpa_s, bssid);
7707 if (bss) {
b04854ce 7708 eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss);
19677b77 7709 goto finish;
dd599908
AS
7710 }
7711
7712 bss = os_malloc(sizeof(*bss));
7713 if (!bss) {
7714 wpa_printf(MSG_DEBUG,
7715 "Failed to allocate memory for temp disallow BSS");
7716 return;
7717 }
7718
dd599908
AS
7719 os_memcpy(bss->bssid, bssid, ETH_ALEN);
7720 dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
b04854ce 7721 wpa_set_driver_tmp_disallow_list(wpa_s);
19677b77
BL
7722
7723finish:
7724 bss->rssi_threshold = rssi_threshold;
b04854ce
AP
7725 eloop_register_timeout(sec, 0, wpa_bss_tmp_disallow_timeout,
7726 wpa_s, bss);
dd599908
AS
7727}
7728
7729
19677b77
BL
7730int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s,
7731 struct wpa_bss *bss)
dd599908 7732{
19677b77 7733 struct wpa_bss_tmp_disallowed *disallowed = NULL, *tmp, *prev;
dd599908 7734
d010048c
JM
7735 dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
7736 struct wpa_bss_tmp_disallowed, list) {
19677b77
BL
7737 if (os_memcmp(bss->bssid, tmp->bssid, ETH_ALEN) == 0) {
7738 disallowed = tmp;
d010048c
JM
7739 break;
7740 }
7741 }
19677b77
BL
7742 if (!disallowed)
7743 return 0;
7744
7745 if (disallowed->rssi_threshold != 0 &&
7746 bss->level > disallowed->rssi_threshold)
dd599908
AS
7747 return 0;
7748
d010048c 7749 return 1;
dd599908 7750}
91b6eba7
EC
7751
7752
7753int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
7754 unsigned int type, const u8 *addr,
7755 const u8 *mask)
7756{
7757 if ((addr && !mask) || (!addr && mask)) {
7758 wpa_printf(MSG_INFO,
7759 "MAC_ADDR_RAND_SCAN invalid addr/mask combination");
7760 return -1;
7761 }
7762
7763 if (addr && mask && (!(mask[0] & 0x01) || (addr[0] & 0x01))) {
7764 wpa_printf(MSG_INFO,
7765 "MAC_ADDR_RAND_SCAN cannot allow multicast address");
7766 return -1;
7767 }
7768
7769 if (type & MAC_ADDR_RAND_SCAN) {
7770 if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN,
7771 addr, mask))
7772 return -1;
7773 }
7774
7775 if (type & MAC_ADDR_RAND_SCHED_SCAN) {
7776 if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN,
7777 addr, mask))
7778 return -1;
7779
7780 if (wpa_s->sched_scanning && !wpa_s->pno)
7781 wpas_scan_restart_sched_scan(wpa_s);
7782 }
7783
7784 if (type & MAC_ADDR_RAND_PNO) {
7785 if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO,
7786 addr, mask))
7787 return -1;
7788
7789 if (wpa_s->pno) {
7790 wpas_stop_pno(wpa_s);
7791 wpas_start_pno(wpa_s);
7792 }
7793 }
7794
7795 return 0;
7796}
7797
7798
7799int wpas_disable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
7800 unsigned int type)
7801{
7802 wpas_mac_addr_rand_scan_clear(wpa_s, type);
7803 if (wpa_s->pno) {
7804 if (type & MAC_ADDR_RAND_PNO) {
7805 wpas_stop_pno(wpa_s);
7806 wpas_start_pno(wpa_s);
7807 }
7808 } else if (wpa_s->sched_scanning && (type & MAC_ADDR_RAND_SCHED_SCAN)) {
7809 wpas_scan_restart_sched_scan(wpa_s);
7810 }
7811
7812 return 0;
7813}