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