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