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