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