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