]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
P2P: Fix interface deinit for failed group interface initialization
[thirdparty/hostap.git] / wpa_supplicant / wpa_supplicant.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA Supplicant
5e3b5197 3 * Copyright (c) 2003-2015, 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"
14
15#include "common.h"
d47fa330 16#include "crypto/random.h"
7d232e23 17#include "crypto/sha1.h"
6fc6879b
JM
18#include "eapol_supp/eapol_supp_sm.h"
19#include "eap_peer/eap.h"
ec7b97ab 20#include "eap_peer/eap_proxy.h"
3ec97afe 21#include "eap_server/eap_methods.h"
3acb5005 22#include "rsn_supp/wpa.h"
6fc6879b 23#include "eloop.h"
6fc6879b 24#include "config.h"
306ae225 25#include "utils/ext_password.h"
6fc6879b
JM
26#include "l2_packet/l2_packet.h"
27#include "wpa_supplicant_i.h"
2d5b792d 28#include "driver_i.h"
6fc6879b 29#include "ctrl_iface.h"
6fc6879b 30#include "pcsc_funcs.h"
90973fb2 31#include "common/version.h"
3acb5005
JM
32#include "rsn_supp/preauth.h"
33#include "rsn_supp/pmksa_cache.h"
90973fb2 34#include "common/wpa_ctrl.h"
90973fb2 35#include "common/ieee802_11_defs.h"
6b8b0774 36#include "common/hw_features_common.h"
72044390 37#include "p2p/p2p.h"
6fc6879b
JM
38#include "blacklist.h"
39#include "wpas_glue.h"
116654ce 40#include "wps_supplicant.h"
11ef8d35 41#include "ibss_rsn.h"
c2a04078 42#include "sme.h"
04ea7b79 43#include "gas_query.h"
1f1b62a0 44#include "ap.h"
b22128ef 45#include "p2p_supplicant.h"
9675ce35 46#include "wifi_display.h"
8bac466b 47#include "notify.h"
60b94c98 48#include "bgscan.h"
7c865c68 49#include "autoscan.h"
83922c2d 50#include "bss.h"
9ba9fa07 51#include "scan.h"
24f6497c 52#include "offchannel.h"
cb418324 53#include "hs20_supplicant.h"
e27d20bb 54#include "wnm_sta.h"
dd10abcc 55#include "wpas_kay.h"
603a3f34 56#include "mesh.h"
6fc6879b
JM
57
58const char *wpa_supplicant_version =
59"wpa_supplicant v" VERSION_STR "\n"
937403b5 60"Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b
JM
61
62const char *wpa_supplicant_license =
331f89ff
JM
63"This software may be distributed under the terms of the BSD license.\n"
64"See README for more details.\n"
6fc6879b
JM
65#ifdef EAP_TLS_OPENSSL
66"\nThis product includes software developed by the OpenSSL Project\n"
67"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
68#endif /* EAP_TLS_OPENSSL */
69;
70
71#ifndef CONFIG_NO_STDOUT_DEBUG
72/* Long text divided into parts in order to fit in C89 strings size limits. */
73const char *wpa_supplicant_full_license1 =
331f89ff 74"";
6fc6879b 75const char *wpa_supplicant_full_license2 =
331f89ff 76"This software may be distributed under the terms of the BSD license.\n"
6fc6879b
JM
77"\n"
78"Redistribution and use in source and binary forms, with or without\n"
79"modification, are permitted provided that the following conditions are\n"
80"met:\n"
81"\n";
82const char *wpa_supplicant_full_license3 =
83"1. Redistributions of source code must retain the above copyright\n"
84" notice, this list of conditions and the following disclaimer.\n"
85"\n"
86"2. Redistributions in binary form must reproduce the above copyright\n"
87" notice, this list of conditions and the following disclaimer in the\n"
88" documentation and/or other materials provided with the distribution.\n"
89"\n";
90const char *wpa_supplicant_full_license4 =
91"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
92" names of its contributors may be used to endorse or promote products\n"
93" derived from this software without specific prior written permission.\n"
94"\n"
95"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
96"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
97"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
98"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
99const char *wpa_supplicant_full_license5 =
100"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
101"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
102"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
103"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
104"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
105"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
106"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
107"\n";
108#endif /* CONFIG_NO_STDOUT_DEBUG */
109
6fc6879b 110/* Configure default/group WEP keys for static WEP */
0194fedb 111int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
6fc6879b
JM
112{
113 int i, set = 0;
114
115 for (i = 0; i < NUM_WEP_KEYS; i++) {
116 if (ssid->wep_key_len[i] == 0)
117 continue;
118
119 set = 1;
0382097e 120 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
da64c266 121 i, i == ssid->wep_tx_keyidx, NULL, 0,
6fc6879b
JM
122 ssid->wep_key[i], ssid->wep_key_len[i]);
123 }
124
125 return set;
126}
127
128
6ea1f413
JM
129int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
130 struct wpa_ssid *ssid)
6fc6879b
JM
131{
132 u8 key[32];
133 size_t keylen;
71934751 134 enum wpa_alg alg;
6fc6879b 135 u8 seq[6] = { 0 };
658da804 136 int ret;
6fc6879b
JM
137
138 /* IBSS/WPA-None uses only one key (Group) for both receiving and
139 * sending unicast and multicast packets. */
140
d7dcba70 141 if (ssid->mode != WPAS_MODE_IBSS) {
f049052b
BG
142 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
143 "IBSS/ad-hoc) for WPA-None", ssid->mode);
6fc6879b
JM
144 return -1;
145 }
146
147 if (!ssid->psk_set) {
f049052b
BG
148 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
149 "WPA-None");
6fc6879b
JM
150 return -1;
151 }
152
153 switch (wpa_s->group_cipher) {
154 case WPA_CIPHER_CCMP:
155 os_memcpy(key, ssid->psk, 16);
156 keylen = 16;
157 alg = WPA_ALG_CCMP;
158 break;
eb7719ff
JM
159 case WPA_CIPHER_GCMP:
160 os_memcpy(key, ssid->psk, 16);
161 keylen = 16;
162 alg = WPA_ALG_GCMP;
163 break;
6fc6879b
JM
164 case WPA_CIPHER_TKIP:
165 /* WPA-None uses the same Michael MIC key for both TX and RX */
166 os_memcpy(key, ssid->psk, 16 + 8);
167 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
168 keylen = 32;
169 alg = WPA_ALG_TKIP;
170 break;
171 default:
f049052b
BG
172 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
173 "WPA-None", wpa_s->group_cipher);
6fc6879b
JM
174 return -1;
175 }
176
177 /* TODO: should actually remember the previously used seq#, both for TX
178 * and RX from each STA.. */
179
658da804
JM
180 ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
181 os_memset(key, 0, sizeof(key));
182 return ret;
6fc6879b
JM
183}
184
185
186static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
187{
188 struct wpa_supplicant *wpa_s = eloop_ctx;
189 const u8 *bssid = wpa_s->bssid;
a8e16edc 190 if (is_zero_ether_addr(bssid))
6fc6879b
JM
191 bssid = wpa_s->pending_bssid;
192 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
193 MAC2STR(bssid));
194 wpa_blacklist_add(wpa_s, bssid);
195 wpa_sm_notify_disassoc(wpa_s->wpa);
07783eaa 196 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6fc6879b 197 wpa_s->reassociate = 1;
48b84f18
BG
198
199 /*
200 * If we timed out, the AP or the local radio may be busy.
201 * So, wait a second until scanning again.
202 */
203 wpa_supplicant_req_scan(wpa_s, 1, 0);
6fc6879b
JM
204}
205
206
207/**
208 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
209 * @wpa_s: Pointer to wpa_supplicant data
210 * @sec: Number of seconds after which to time out authentication
211 * @usec: Number of microseconds after which to time out authentication
212 *
213 * This function is used to schedule a timeout for the current authentication
214 * attempt.
215 */
216void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
217 int sec, int usec)
218{
a2a535f8 219 if (wpa_s->conf->ap_scan == 0 &&
c2a04078 220 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
6fc6879b
JM
221 return;
222
f049052b 223 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
6fc6879b
JM
224 "%d usec", sec, usec);
225 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
226 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
227}
228
229
230/**
231 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
232 * @wpa_s: Pointer to wpa_supplicant data
233 *
234 * This function is used to cancel authentication timeout scheduled with
235 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
236 * been completed.
237 */
238void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
239{
f049052b 240 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
6fc6879b
JM
241 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
242 wpa_blacklist_del(wpa_s, wpa_s->bssid);
243}
244
245
246/**
247 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
248 * @wpa_s: Pointer to wpa_supplicant data
249 *
250 * This function is used to configure EAPOL state machine based on the selected
251 * authentication mode.
252 */
253void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
254{
255#ifdef IEEE8021X_EAPOL
256 struct eapol_config eapol_conf;
257 struct wpa_ssid *ssid = wpa_s->current_ssid;
258
53895c3b 259#ifdef CONFIG_IBSS_RSN
d7dcba70 260 if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
261 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
262 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
263 /*
264 * RSN IBSS authentication is per-STA and we can disable the
265 * per-BSSID EAPOL authentication.
266 */
267 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
268 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
269 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
270 return;
271 }
272#endif /* CONFIG_IBSS_RSN */
273
0a40ec6a
JM
274 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
275 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
276
6fc6879b
JM
277 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
278 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
279 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
280 else
281 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
282
283 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
284 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
285 eapol_conf.accept_802_1x_keys = 1;
286 eapol_conf.required_keys = 0;
287 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
288 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
289 }
290 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
291 eapol_conf.required_keys |=
292 EAPOL_REQUIRE_KEY_BROADCAST;
293 }
294
a2a535f8 295 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
6fc6879b 296 eapol_conf.required_keys = 0;
6fc6879b 297 }
a2a535f8 298 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
6fc6879b 299 eapol_conf.workaround = ssid->eap_workaround;
56586197
JM
300 eapol_conf.eap_disabled =
301 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
ad08c363
JM
302 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
303 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
a5d44ac0 304 eapol_conf.external_sim = wpa_s->conf->external_sim;
3f7ac058
JS
305
306#ifdef CONFIG_WPS
307 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
308 eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
309 if (wpa_s->current_bss) {
310 struct wpabuf *ie;
311 ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
312 WPS_IE_VENDOR_TYPE);
313 if (ie) {
314 if (wps_is_20(ie))
315 eapol_conf.wps |=
316 EAPOL_PEER_IS_WPS20_AP;
317 wpabuf_free(ie);
318 }
319 }
320 }
321#endif /* CONFIG_WPS */
322
6fc6879b 323 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
dd10abcc
HW
324
325 ieee802_1x_alloc_kay_sm(wpa_s, ssid);
cd3153a9 326#endif /* IEEE8021X_EAPOL */
6fc6879b
JM
327}
328
329
330/**
331 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
332 * @wpa_s: Pointer to wpa_supplicant data
333 * @ssid: Configuration data for the network
334 *
335 * This function is used to configure WPA state machine and related parameters
336 * to a mode where WPA is not enabled. This is called as part of the
337 * authentication configuration when the selected network does not use WPA.
338 */
339void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
340 struct wpa_ssid *ssid)
341{
342 int i;
343
ad08c363
JM
344 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
345 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
346 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
6fc6879b
JM
347 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
348 else
349 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
350 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
351 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
352 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
353 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
354 wpa_s->group_cipher = WPA_CIPHER_NONE;
355 wpa_s->mgmt_group_cipher = 0;
356
357 for (i = 0; i < NUM_WEP_KEYS; i++) {
358 if (ssid->wep_key_len[i] > 5) {
359 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
360 wpa_s->group_cipher = WPA_CIPHER_WEP104;
361 break;
362 } else if (ssid->wep_key_len[i] > 0) {
363 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
364 wpa_s->group_cipher = WPA_CIPHER_WEP40;
365 break;
366 }
367 }
368
369 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
370 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
371 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
372 wpa_s->pairwise_cipher);
373 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
374#ifdef CONFIG_IEEE80211W
375 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
376 wpa_s->mgmt_group_cipher);
377#endif /* CONFIG_IEEE80211W */
378
379 pmksa_cache_clear_current(wpa_s->wpa);
380}
381
382
6979582c 383void free_hw_features(struct wpa_supplicant *wpa_s)
6bf731e8
CL
384{
385 int i;
386 if (wpa_s->hw.modes == NULL)
387 return;
388
389 for (i = 0; i < wpa_s->hw.num_modes; i++) {
390 os_free(wpa_s->hw.modes[i].channels);
391 os_free(wpa_s->hw.modes[i].rates);
392 }
393
394 os_free(wpa_s->hw.modes);
395 wpa_s->hw.modes = NULL;
396}
397
398
6fc6879b
JM
399static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
400{
86bd36f0
JM
401 int i;
402
60b94c98 403 bgscan_deinit(wpa_s);
7c865c68 404 autoscan_deinit(wpa_s);
6fc6879b
JM
405 scard_deinit(wpa_s->scard);
406 wpa_s->scard = NULL;
407 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
408 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
409 l2_packet_deinit(wpa_s->l2);
410 wpa_s->l2 = NULL;
411 if (wpa_s->l2_br) {
412 l2_packet_deinit(wpa_s->l2_br);
413 wpa_s->l2_br = NULL;
414 }
4a6cc862
JM
415#ifdef CONFIG_TESTING_OPTIONS
416 l2_packet_deinit(wpa_s->l2_test);
417 wpa_s->l2_test = NULL;
418#endif /* CONFIG_TESTING_OPTIONS */
6fc6879b 419
6fc6879b 420 if (wpa_s->conf != NULL) {
8e56d189
JM
421 struct wpa_ssid *ssid;
422 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
423 wpas_notify_network_removed(wpa_s, ssid);
6fc6879b
JM
424 }
425
426 os_free(wpa_s->confname);
427 wpa_s->confname = NULL;
428
e6304cad
DS
429 os_free(wpa_s->confanother);
430 wpa_s->confanother = NULL;
431
6fc6879b
JM
432 wpa_sm_set_eapol(wpa_s->wpa, NULL);
433 eapol_sm_deinit(wpa_s->eapol);
434 wpa_s->eapol = NULL;
435
436 rsn_preauth_deinit(wpa_s->wpa);
437
281ff0aa
GP
438#ifdef CONFIG_TDLS
439 wpa_tdls_deinit(wpa_s->wpa);
440#endif /* CONFIG_TDLS */
441
8c42b369 442 wmm_ac_clear_saved_tspecs(wpa_s);
6fc6879b
JM
443 pmksa_candidate_free(wpa_s->wpa);
444 wpa_sm_deinit(wpa_s->wpa);
445 wpa_s->wpa = NULL;
446 wpa_blacklist_clear(wpa_s);
447
83922c2d 448 wpa_bss_deinit(wpa_s);
6fc6879b 449
831770bf 450 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
6fc6879b
JM
451 wpa_supplicant_cancel_scan(wpa_s);
452 wpa_supplicant_cancel_auth_timeout(wpa_s);
01a17491
JM
453 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
454#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
455 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
456 wpa_s, NULL);
457#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
6fc6879b 458
116654ce 459 wpas_wps_deinit(wpa_s);
11ef8d35 460
1ff73338
JM
461 wpabuf_free(wpa_s->pending_eapol_rx);
462 wpa_s->pending_eapol_rx = NULL;
463
11ef8d35
JM
464#ifdef CONFIG_IBSS_RSN
465 ibss_rsn_deinit(wpa_s->ibss_rsn);
466 wpa_s->ibss_rsn = NULL;
467#endif /* CONFIG_IBSS_RSN */
c2a04078 468
e29853bb 469 sme_deinit(wpa_s);
2d5b792d
JM
470
471#ifdef CONFIG_AP
472 wpa_supplicant_ap_deinit(wpa_s);
473#endif /* CONFIG_AP */
b22128ef 474
b22128ef 475 wpas_p2p_deinit(wpa_s);
f47d639d 476
24f6497c
JM
477#ifdef CONFIG_OFFCHANNEL
478 offchannel_deinit(wpa_s);
479#endif /* CONFIG_OFFCHANNEL */
480
a4cba8f1
LC
481 wpa_supplicant_cancel_sched_scan(wpa_s);
482
f47d639d
JM
483 os_free(wpa_s->next_scan_freqs);
484 wpa_s->next_scan_freqs = NULL;
fee52342
JM
485
486 os_free(wpa_s->manual_scan_freqs);
487 wpa_s->manual_scan_freqs = NULL;
04ea7b79 488
d3c9c35f
DS
489 os_free(wpa_s->manual_sched_scan_freqs);
490 wpa_s->manual_sched_scan_freqs = NULL;
491
56c76fa5
IP
492 wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
493
04ea7b79
JM
494 gas_query_deinit(wpa_s->gas);
495 wpa_s->gas = NULL;
6bf731e8
CL
496
497 free_hw_features(wpa_s);
d445a5cd 498
dd10abcc
HW
499 ieee802_1x_dealloc_kay_sm(wpa_s);
500
d445a5cd
JM
501 os_free(wpa_s->bssid_filter);
502 wpa_s->bssid_filter = NULL;
b6668734 503
6407f413
JM
504 os_free(wpa_s->disallow_aps_bssid);
505 wpa_s->disallow_aps_bssid = NULL;
506 os_free(wpa_s->disallow_aps_ssid);
507 wpa_s->disallow_aps_ssid = NULL;
508
b6668734 509 wnm_bss_keep_alive_deinit(wpa_s);
e27d20bb
VK
510#ifdef CONFIG_WNM
511 wnm_deallocate_memory(wpa_s);
512#endif /* CONFIG_WNM */
306ae225
JM
513
514 ext_password_deinit(wpa_s->ext_pw);
515 wpa_s->ext_pw = NULL;
b1f12296
JM
516
517 wpabuf_free(wpa_s->last_gas_resp);
b6a9590b
JM
518 wpa_s->last_gas_resp = NULL;
519 wpabuf_free(wpa_s->prev_gas_resp);
520 wpa_s->prev_gas_resp = NULL;
a297201d
JM
521
522 os_free(wpa_s->last_scan_res);
523 wpa_s->last_scan_res = NULL;
b572df86
JM
524
525#ifdef CONFIG_HS20
fb2ac53d 526 hs20_deinit(wpa_s);
b572df86 527#endif /* CONFIG_HS20 */
86bd36f0
JM
528
529 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
530 wpabuf_free(wpa_s->vendor_elem[i]);
531 wpa_s->vendor_elem[i] = NULL;
532 }
3882a708
JM
533
534 wmm_ac_notify_disassoc(wpa_s);
6fc6879b
JM
535}
536
537
538/**
539 * wpa_clear_keys - Clear keys configured for the driver
540 * @wpa_s: Pointer to wpa_supplicant data
541 * @addr: Previously used BSSID or %NULL if not available
542 *
543 * This function clears the encryption keys that has been previously configured
544 * for the driver.
545 */
546void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
547{
2f30cac3 548 int i, max;
6fc6879b 549
0e27f655 550#ifdef CONFIG_IEEE80211W
2f30cac3
JM
551 max = 6;
552#else /* CONFIG_IEEE80211W */
553 max = 4;
0e27f655 554#endif /* CONFIG_IEEE80211W */
2f30cac3
JM
555
556 /* MLME-DELETEKEYS.request */
557 for (i = 0; i < max; i++) {
558 if (wpa_s->keys_cleared & BIT(i))
559 continue;
560 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
561 NULL, 0);
562 }
563 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
564 !is_zero_ether_addr(addr)) {
6fc6879b
JM
565 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
566 0);
567 /* MLME-SETPROTECTION.request(None) */
568 wpa_drv_mlme_setprotection(
569 wpa_s, addr,
570 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
571 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
572 }
2f30cac3 573 wpa_s->keys_cleared = (u32) -1;
6fc6879b
JM
574}
575
576
577/**
578 * wpa_supplicant_state_txt - Get the connection state name as a text string
579 * @state: State (wpa_state; WPA_*)
580 * Returns: The state name as a printable text string
581 */
71934751 582const char * wpa_supplicant_state_txt(enum wpa_states state)
6fc6879b
JM
583{
584 switch (state) {
585 case WPA_DISCONNECTED:
586 return "DISCONNECTED";
587 case WPA_INACTIVE:
588 return "INACTIVE";
8401a6b0
JM
589 case WPA_INTERFACE_DISABLED:
590 return "INTERFACE_DISABLED";
6fc6879b
JM
591 case WPA_SCANNING:
592 return "SCANNING";
c2a04078
JM
593 case WPA_AUTHENTICATING:
594 return "AUTHENTICATING";
6fc6879b
JM
595 case WPA_ASSOCIATING:
596 return "ASSOCIATING";
597 case WPA_ASSOCIATED:
598 return "ASSOCIATED";
599 case WPA_4WAY_HANDSHAKE:
600 return "4WAY_HANDSHAKE";
601 case WPA_GROUP_HANDSHAKE:
602 return "GROUP_HANDSHAKE";
603 case WPA_COMPLETED:
604 return "COMPLETED";
605 default:
606 return "UNKNOWN";
607 }
608}
609
610
cfe53c9a
PS
611#ifdef CONFIG_BGSCAN
612
613static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
614{
31392709
HD
615 const char *name;
616
617 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
618 name = wpa_s->current_ssid->bgscan;
619 else
620 name = wpa_s->conf->bgscan;
268043d5 621 if (name == NULL || name[0] == '\0')
31392709 622 return;
0096c427
JM
623 if (wpas_driver_bss_selection(wpa_s))
624 return;
cfe53c9a
PS
625 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
626 return;
aa109830
DS
627#ifdef CONFIG_P2P
628 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
629 return;
630#endif /* CONFIG_P2P */
cfe53c9a
PS
631
632 bgscan_deinit(wpa_s);
31392709
HD
633 if (wpa_s->current_ssid) {
634 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
cfe53c9a
PS
635 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
636 "bgscan");
637 /*
638 * Live without bgscan; it is only used as a roaming
639 * optimization, so the initial connection is not
640 * affected.
641 */
6409b7a7
YD
642 } else {
643 struct wpa_scan_results *scan_res;
cfe53c9a 644 wpa_s->bgscan_ssid = wpa_s->current_ssid;
6409b7a7
YD
645 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
646 0);
647 if (scan_res) {
648 bgscan_notify_scan(wpa_s, scan_res);
649 wpa_scan_results_free(scan_res);
650 }
651 }
cfe53c9a
PS
652 } else
653 wpa_s->bgscan_ssid = NULL;
654}
655
656
657static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
658{
659 if (wpa_s->bgscan_ssid != NULL) {
660 bgscan_deinit(wpa_s);
661 wpa_s->bgscan_ssid = NULL;
662 }
663}
664
665#endif /* CONFIG_BGSCAN */
666
667
7c865c68
TB
668static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
669{
99218999 670 if (autoscan_init(wpa_s, 0))
7c865c68
TB
671 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
672}
673
674
675static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
676{
677 autoscan_deinit(wpa_s);
678}
679
680
c3d12238
JM
681void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
682{
683 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
684 wpa_s->wpa_state == WPA_SCANNING) {
685 autoscan_deinit(wpa_s);
686 wpa_supplicant_start_autoscan(wpa_s);
687 }
688}
689
690
6fc6879b
JM
691/**
692 * wpa_supplicant_set_state - Set current connection state
693 * @wpa_s: Pointer to wpa_supplicant data
694 * @state: The new connection state
695 *
696 * This function is called whenever the connection state changes, e.g.,
697 * association is completed for WPA/WPA2 4-Way Handshake is started.
698 */
71934751
JM
699void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
700 enum wpa_states state)
6fc6879b 701{
27f43d8d
MH
702 enum wpa_states old_state = wpa_s->wpa_state;
703
f049052b
BG
704 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
705 wpa_supplicant_state_txt(wpa_s->wpa_state),
706 wpa_supplicant_state_txt(state));
6fc6879b 707
5ddd07cb
AS
708 if (state == WPA_INTERFACE_DISABLED) {
709 /* Assure normal scan when interface is restored */
710 wpa_s->normal_scans = 0;
711 }
712
0cf24fda 713 if (state == WPA_COMPLETED) {
6ac4b15e 714 wpas_connect_work_done(wpa_s);
0cf24fda
LC
715 /* Reinitialize normal_scan counter */
716 wpa_s->normal_scans = 0;
717 }
6ac4b15e 718
cb8564b1
DW
719 if (state != WPA_SCANNING)
720 wpa_supplicant_notify_scanning(wpa_s, 0);
721
6fc6879b 722 if (state == WPA_COMPLETED && wpa_s->new_connection) {
6fc6879b 723 struct wpa_ssid *ssid = wpa_s->current_ssid;
7d37a357 724#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6fc6879b 725 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
1cfc6787
JM
726 MACSTR " completed [id=%d id_str=%s]",
727 MAC2STR(wpa_s->bssid),
6fc6879b
JM
728 ssid ? ssid->id : -1,
729 ssid && ssid->id_str ? ssid->id_str : "");
730#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
00e5e3d5 731 wpas_clear_temp_disabled(wpa_s, ssid, 1);
f1a52633 732 wpa_s->extra_blacklist_count = 0;
6fc6879b 733 wpa_s->new_connection = 0;
6fc6879b 734 wpa_drv_set_operstate(wpa_s, 1);
99ac2913
FF
735#ifndef IEEE8021X_EAPOL
736 wpa_drv_set_supp_port(wpa_s, 1);
737#endif /* IEEE8021X_EAPOL */
17a4734d 738 wpa_s->after_wps = 0;
4d9fb08d 739 wpa_s->known_wps_freq = 0;
b22128ef 740 wpas_p2p_completed(wpa_s);
c3701c66
RM
741
742 sme_sched_obss_scan(wpa_s, 1);
6fc6879b
JM
743 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
744 state == WPA_ASSOCIATED) {
745 wpa_s->new_connection = 1;
746 wpa_drv_set_operstate(wpa_s, 0);
99ac2913
FF
747#ifndef IEEE8021X_EAPOL
748 wpa_drv_set_supp_port(wpa_s, 0);
749#endif /* IEEE8021X_EAPOL */
c3701c66 750 sme_sched_obss_scan(wpa_s, 0);
6fc6879b
JM
751 }
752 wpa_s->wpa_state = state;
27f43d8d 753
cfe53c9a
PS
754#ifdef CONFIG_BGSCAN
755 if (state == WPA_COMPLETED)
756 wpa_supplicant_start_bgscan(wpa_s);
37271232 757 else if (state < WPA_ASSOCIATED)
cfe53c9a
PS
758 wpa_supplicant_stop_bgscan(wpa_s);
759#endif /* CONFIG_BGSCAN */
760
7c865c68
TB
761 if (state == WPA_AUTHENTICATING)
762 wpa_supplicant_stop_autoscan(wpa_s);
763
764 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
765 wpa_supplicant_start_autoscan(wpa_s);
766
fecc2bb5
EP
767 if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
768 wmm_ac_notify_disassoc(wpa_s);
769
5bbf9f10 770 if (wpa_s->wpa_state != old_state) {
27f43d8d 771 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
5bbf9f10 772
e3bd6e9d
IP
773 /*
774 * Notify the P2P Device interface about a state change in one
775 * of the interfaces.
776 */
777 wpas_p2p_indicate_state_change(wpa_s);
e3bd6e9d 778
5bbf9f10
PS
779 if (wpa_s->wpa_state == WPA_COMPLETED ||
780 old_state == WPA_COMPLETED)
781 wpas_notify_auth_changed(wpa_s);
782 }
6fc6879b
JM
783}
784
785
1a1bf008
JM
786void wpa_supplicant_terminate_proc(struct wpa_global *global)
787{
788 int pending = 0;
789#ifdef CONFIG_WPS
790 struct wpa_supplicant *wpa_s = global->ifaces;
791 while (wpa_s) {
ab41595f 792 struct wpa_supplicant *next = wpa_s->next;
5516ed32
EA
793 if (wpas_wps_terminate_pending(wpa_s) == 1)
794 pending = 1;
20625e97
JM
795#ifdef CONFIG_P2P
796 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
797 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
798 wpas_p2p_disconnect(wpa_s);
799#endif /* CONFIG_P2P */
ab41595f 800 wpa_s = next;
1a1bf008
JM
801 }
802#endif /* CONFIG_WPS */
803 if (pending)
804 return;
805 eloop_terminate();
806}
807
808
0456ea16 809static void wpa_supplicant_terminate(int sig, void *signal_ctx)
6fc6879b 810{
0456ea16 811 struct wpa_global *global = signal_ctx;
1a1bf008 812 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
813}
814
815
b22128ef 816void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
6fc6879b 817{
71934751 818 enum wpa_states old_state = wpa_s->wpa_state;
27f43d8d 819
6fc6879b
JM
820 wpa_s->pairwise_cipher = 0;
821 wpa_s->group_cipher = 0;
822 wpa_s->mgmt_group_cipher = 0;
823 wpa_s->key_mgmt = 0;
8401a6b0 824 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
99218999 825 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
27f43d8d
MH
826
827 if (wpa_s->wpa_state != old_state)
828 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
6fc6879b
JM
829}
830
831
832/**
833 * wpa_supplicant_reload_configuration - Reload configuration data
834 * @wpa_s: Pointer to wpa_supplicant data
835 * Returns: 0 on success or -1 if configuration parsing failed
836 *
837 * This function can be used to request that the configuration data is reloaded
838 * (e.g., after configuration file change). This function is reloading
839 * configuration only for one interface, so this may need to be called multiple
840 * times if %wpa_supplicant is controlling multiple interfaces and all
841 * interfaces need reconfiguration.
842 */
843int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
844{
845 struct wpa_config *conf;
846 int reconf_ctrl;
8bac466b
JM
847 int old_ap_scan;
848
6fc6879b
JM
849 if (wpa_s->confname == NULL)
850 return -1;
e6304cad 851 conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
852 if (conf == NULL) {
853 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
854 "file '%s' - exiting", wpa_s->confname);
855 return -1;
856 }
e6304cad
DS
857 wpa_config_read(wpa_s->confanother, conf);
858
611aea7d 859 conf->changed_parameters = (unsigned int) -1;
6fc6879b
JM
860
861 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
862 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
863 os_strcmp(conf->ctrl_interface,
864 wpa_s->conf->ctrl_interface) != 0);
865
866 if (reconf_ctrl && wpa_s->ctrl_iface) {
867 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
868 wpa_s->ctrl_iface = NULL;
869 }
870
871 eapol_sm_invalidate_cached_session(wpa_s->eapol);
7b7ce8aa 872 if (wpa_s->current_ssid) {
c2805909 873 wpa_s->own_disconnect_req = 1;
7b7ce8aa
JM
874 wpa_supplicant_deauthenticate(wpa_s,
875 WLAN_REASON_DEAUTH_LEAVING);
876 }
8bac466b 877
6fc6879b
JM
878 /*
879 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
07e2de31 880 * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
6fc6879b 881 */
56586197 882 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
6fc6879b
JM
883 /*
884 * Clear forced success to clear EAP state for next
885 * authentication.
886 */
887 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
888 }
889 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
890 wpa_sm_set_config(wpa_s->wpa, NULL);
d8a790b9 891 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
6fc6879b
JM
892 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
893 rsn_preauth_deinit(wpa_s->wpa);
8bac466b
JM
894
895 old_ap_scan = wpa_s->conf->ap_scan;
6fc6879b
JM
896 wpa_config_free(wpa_s->conf);
897 wpa_s->conf = conf;
8bac466b
JM
898 if (old_ap_scan != wpa_s->conf->ap_scan)
899 wpas_notify_ap_scan_changed(wpa_s);
900
6fc6879b
JM
901 if (reconf_ctrl)
902 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
903
611aea7d
JM
904 wpa_supplicant_update_config(wpa_s);
905
6fc6879b 906 wpa_supplicant_clear_status(wpa_s);
349493bd 907 if (wpa_supplicant_enabled_networks(wpa_s)) {
43a38635
JM
908 wpa_s->reassociate = 1;
909 wpa_supplicant_req_scan(wpa_s, 0, 0);
910 }
f049052b 911 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
6fc6879b
JM
912 return 0;
913}
914
915
0456ea16 916static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
6fc6879b 917{
0456ea16 918 struct wpa_global *global = signal_ctx;
6fc6879b 919 struct wpa_supplicant *wpa_s;
6fc6879b 920 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
f049052b
BG
921 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
922 sig);
6fc6879b 923 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
1a1bf008 924 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
925 }
926 }
927}
928
929
6fc6879b
JM
930static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
931 struct wpa_ssid *ssid,
932 struct wpa_ie_data *ie)
933{
934 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
935 if (ret) {
936 if (ret == -2) {
937 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
938 "from association info");
939 }
940 return -1;
941 }
942
f049052b
BG
943 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
944 "cipher suites");
6fc6879b
JM
945 if (!(ie->group_cipher & ssid->group_cipher)) {
946 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
947 "cipher 0x%x (mask 0x%x) - reject",
948 ie->group_cipher, ssid->group_cipher);
949 return -1;
950 }
951 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
952 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
953 "cipher 0x%x (mask 0x%x) - reject",
954 ie->pairwise_cipher, ssid->pairwise_cipher);
955 return -1;
956 }
957 if (!(ie->key_mgmt & ssid->key_mgmt)) {
958 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
959 "management 0x%x (mask 0x%x) - reject",
960 ie->key_mgmt, ssid->key_mgmt);
961 return -1;
962 }
963
964#ifdef CONFIG_IEEE80211W
0b60b0aa 965 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
3f56a2b7 966 wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
6fc6879b
JM
967 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
968 "that does not support management frame protection - "
969 "reject");
970 return -1;
971 }
972#endif /* CONFIG_IEEE80211W */
973
974 return 0;
975}
976
977
978/**
979 * wpa_supplicant_set_suites - Set authentication and encryption parameters
980 * @wpa_s: Pointer to wpa_supplicant data
981 * @bss: Scan results for the selected BSS, or %NULL if not available
982 * @ssid: Configuration data for the selected network
983 * @wpa_ie: Buffer for the WPA/RSN IE
984 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
985 * used buffer length in case the functions returns success.
986 * Returns: 0 on success or -1 on failure
987 *
988 * This function is used to configure authentication and encryption parameters
989 * based on the network configuration and scan result for the selected BSS (if
990 * available).
991 */
992int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
6fa81a3b 993 struct wpa_bss *bss, struct wpa_ssid *ssid,
6fc6879b
JM
994 u8 *wpa_ie, size_t *wpa_ie_len)
995{
996 struct wpa_ie_data ie;
997 int sel, proto;
df0f01d9 998 const u8 *bss_wpa, *bss_rsn, *bss_osen;
6fc6879b
JM
999
1000 if (bss) {
6fa81a3b
JM
1001 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1002 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
df0f01d9 1003 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
6fc6879b 1004 } else
df0f01d9 1005 bss_wpa = bss_rsn = bss_osen = NULL;
6fc6879b
JM
1006
1007 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
1008 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
1009 (ie.group_cipher & ssid->group_cipher) &&
1010 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1011 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 1012 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
6fc6879b
JM
1013 proto = WPA_PROTO_RSN;
1014 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
267ac3bc 1015 wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
6fc6879b
JM
1016 (ie.group_cipher & ssid->group_cipher) &&
1017 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1018 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 1019 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
6fc6879b 1020 proto = WPA_PROTO_WPA;
df0f01d9
JM
1021#ifdef CONFIG_HS20
1022 } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
1023 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
1024 /* TODO: parse OSEN element */
137ff332 1025 os_memset(&ie, 0, sizeof(ie));
df0f01d9
JM
1026 ie.group_cipher = WPA_CIPHER_CCMP;
1027 ie.pairwise_cipher = WPA_CIPHER_CCMP;
1028 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
1029 proto = WPA_PROTO_OSEN;
1030#endif /* CONFIG_HS20 */
6fc6879b
JM
1031 } else if (bss) {
1032 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
267ac3bc
JM
1033 wpa_dbg(wpa_s, MSG_DEBUG,
1034 "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1035 ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
1036 ssid->key_mgmt);
1037 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
1038 MAC2STR(bss->bssid),
1039 wpa_ssid_txt(bss->ssid, bss->ssid_len),
1040 bss_wpa ? " WPA" : "",
1041 bss_rsn ? " RSN" : "",
1042 bss_osen ? " OSEN" : "");
1043 if (bss_rsn) {
1044 wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
1045 if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
1046 wpa_dbg(wpa_s, MSG_DEBUG,
1047 "Could not parse RSN element");
1048 } else {
1049 wpa_dbg(wpa_s, MSG_DEBUG,
1050 "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1051 ie.pairwise_cipher, ie.group_cipher,
1052 ie.key_mgmt);
1053 }
1054 }
1055 if (bss_wpa) {
1056 wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
1057 if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
1058 wpa_dbg(wpa_s, MSG_DEBUG,
1059 "Could not parse WPA element");
1060 } else {
1061 wpa_dbg(wpa_s, MSG_DEBUG,
1062 "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1063 ie.pairwise_cipher, ie.group_cipher,
1064 ie.key_mgmt);
1065 }
1066 }
6fc6879b
JM
1067 return -1;
1068 } else {
df0f01d9
JM
1069 if (ssid->proto & WPA_PROTO_OSEN)
1070 proto = WPA_PROTO_OSEN;
1071 else if (ssid->proto & WPA_PROTO_RSN)
6fc6879b
JM
1072 proto = WPA_PROTO_RSN;
1073 else
1074 proto = WPA_PROTO_WPA;
1075 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1076 os_memset(&ie, 0, sizeof(ie));
1077 ie.group_cipher = ssid->group_cipher;
1078 ie.pairwise_cipher = ssid->pairwise_cipher;
1079 ie.key_mgmt = ssid->key_mgmt;
1080#ifdef CONFIG_IEEE80211W
1081 ie.mgmt_group_cipher =
70f8cc8e 1082 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
6fc6879b
JM
1083 WPA_CIPHER_AES_128_CMAC : 0;
1084#endif /* CONFIG_IEEE80211W */
f049052b
BG
1085 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1086 "based on configuration");
6fc6879b
JM
1087 } else
1088 proto = ie.proto;
1089 }
1090
f049052b
BG
1091 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1092 "pairwise %d key_mgmt %d proto %d",
1093 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
6fc6879b
JM
1094#ifdef CONFIG_IEEE80211W
1095 if (ssid->ieee80211w) {
f049052b
BG
1096 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1097 ie.mgmt_group_cipher);
6fc6879b
JM
1098 }
1099#endif /* CONFIG_IEEE80211W */
1100
64fa840a 1101 wpa_s->wpa_proto = proto;
6fc6879b
JM
1102 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1103 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
df0f01d9 1104 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
6fc6879b
JM
1105
1106 if (bss || !wpa_s->ap_ies_from_associnfo) {
1107 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1108 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1109 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1110 bss_rsn ? 2 + bss_rsn[1] : 0))
1111 return -1;
1112 }
1113
1114 sel = ie.group_cipher & ssid->group_cipher;
edbd2a19
JM
1115 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1116 if (wpa_s->group_cipher < 0) {
f049052b
BG
1117 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1118 "cipher");
6fc6879b
JM
1119 return -1;
1120 }
edbd2a19
JM
1121 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1122 wpa_cipher_txt(wpa_s->group_cipher));
6fc6879b
JM
1123
1124 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
edbd2a19
JM
1125 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1126 if (wpa_s->pairwise_cipher < 0) {
f049052b
BG
1127 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1128 "cipher");
6fc6879b
JM
1129 return -1;
1130 }
edbd2a19
JM
1131 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1132 wpa_cipher_txt(wpa_s->pairwise_cipher));
6fc6879b
JM
1133
1134 sel = ie.key_mgmt & ssid->key_mgmt;
c10347f2
JM
1135#ifdef CONFIG_SAE
1136 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1137 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1138#endif /* CONFIG_SAE */
6fc6879b 1139 if (0) {
5e3b5197
JM
1140#ifdef CONFIG_SUITEB192
1141 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1142 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1143 wpa_dbg(wpa_s, MSG_DEBUG,
1144 "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
1145#endif /* CONFIG_SUITEB192 */
1146#ifdef CONFIG_SUITEB
666497c8
JM
1147 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1148 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1149 wpa_dbg(wpa_s, MSG_DEBUG,
1150 "WPA: using KEY_MGMT 802.1X with Suite B");
5e3b5197 1151#endif /* CONFIG_SUITEB */
6fc6879b
JM
1152#ifdef CONFIG_IEEE80211R
1153 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1154 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
f049052b 1155 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
6fc6879b
JM
1156 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1157 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
f049052b 1158 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
6fc6879b 1159#endif /* CONFIG_IEEE80211R */
c10347f2
JM
1160#ifdef CONFIG_SAE
1161 } else if (sel & WPA_KEY_MGMT_SAE) {
1162 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1163 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1164 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1165 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1166 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1167#endif /* CONFIG_SAE */
56586197
JM
1168#ifdef CONFIG_IEEE80211W
1169 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1170 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
f049052b 1171 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1172 "WPA: using KEY_MGMT 802.1X with SHA256");
1173 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1174 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
f049052b 1175 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1176 "WPA: using KEY_MGMT PSK with SHA256");
1177#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
1178 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1179 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
f049052b 1180 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
6fc6879b
JM
1181 } else if (sel & WPA_KEY_MGMT_PSK) {
1182 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
f049052b 1183 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
6fc6879b
JM
1184 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1185 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
f049052b 1186 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
df0f01d9
JM
1187#ifdef CONFIG_HS20
1188 } else if (sel & WPA_KEY_MGMT_OSEN) {
1189 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1190 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1191#endif /* CONFIG_HS20 */
6fc6879b 1192 } else {
f049052b
BG
1193 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1194 "authenticated key management type");
6fc6879b
JM
1195 return -1;
1196 }
1197
1198 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1199 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1200 wpa_s->pairwise_cipher);
1201 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1202
1203#ifdef CONFIG_IEEE80211W
1204 sel = ie.mgmt_group_cipher;
3f56a2b7 1205 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
0b60b0aa 1206 !(ie.capabilities & WPA_CAPABILITY_MFPC))
6fc6879b
JM
1207 sel = 0;
1208 if (sel & WPA_CIPHER_AES_128_CMAC) {
1209 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
f049052b 1210 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
6fc6879b 1211 "AES-128-CMAC");
8dd9f9cd
JM
1212 } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1213 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1214 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1215 "BIP-GMAC-128");
1216 } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1217 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1218 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1219 "BIP-GMAC-256");
1220 } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1221 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1222 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1223 "BIP-CMAC-256");
6fc6879b
JM
1224 } else {
1225 wpa_s->mgmt_group_cipher = 0;
f049052b 1226 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
6fc6879b
JM
1227 }
1228 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1229 wpa_s->mgmt_group_cipher);
62d49803 1230 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
3f56a2b7 1231 wpas_get_ssid_pmf(wpa_s, ssid));
6fc6879b
JM
1232#endif /* CONFIG_IEEE80211W */
1233
1234 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
f049052b 1235 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
6fc6879b
JM
1236 return -1;
1237 }
1238
0bf927a0 1239 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
bc26ac50 1240 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
7d232e23
ZC
1241#ifndef CONFIG_NO_PBKDF2
1242 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1243 ssid->passphrase) {
1244 u8 psk[PMK_LEN];
986de33d
JM
1245 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1246 4096, psk, PMK_LEN);
7d232e23
ZC
1247 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1248 psk, PMK_LEN);
bc26ac50 1249 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
e886c88e 1250 os_memset(psk, 0, sizeof(psk));
7d232e23
ZC
1251 }
1252#endif /* CONFIG_NO_PBKDF2 */
9173b16f
JM
1253#ifdef CONFIG_EXT_PASSWORD
1254 if (ssid->ext_psk) {
1255 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1256 ssid->ext_psk);
1257 char pw_str[64 + 1];
1258 u8 psk[PMK_LEN];
1259
1260 if (pw == NULL) {
1261 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1262 "found from external storage");
1263 return -1;
1264 }
1265
1266 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1267 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1268 "PSK length %d in external storage",
1269 (int) wpabuf_len(pw));
1270 ext_password_free(pw);
1271 return -1;
1272 }
1273
1274 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1275 pw_str[wpabuf_len(pw)] = '\0';
1276
1277#ifndef CONFIG_NO_PBKDF2
1278 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1279 {
986de33d
JM
1280 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1281 4096, psk, PMK_LEN);
9173b16f
JM
1282 os_memset(pw_str, 0, sizeof(pw_str));
1283 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1284 "external passphrase)",
1285 psk, PMK_LEN);
bc26ac50 1286 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
e886c88e 1287 os_memset(psk, 0, sizeof(psk));
9173b16f
JM
1288 } else
1289#endif /* CONFIG_NO_PBKDF2 */
1290 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1291 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1292 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1293 "Invalid PSK hex string");
1294 os_memset(pw_str, 0, sizeof(pw_str));
1295 ext_password_free(pw);
1296 return -1;
1297 }
bc26ac50 1298 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
e886c88e 1299 os_memset(psk, 0, sizeof(psk));
9173b16f
JM
1300 } else {
1301 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1302 "PSK available");
1303 os_memset(pw_str, 0, sizeof(pw_str));
1304 ext_password_free(pw);
1305 return -1;
1306 }
1307
1308 os_memset(pw_str, 0, sizeof(pw_str));
1309 ext_password_free(pw);
1310 }
1311#endif /* CONFIG_EXT_PASSWORD */
7d232e23 1312 } else
6fc6879b
JM
1313 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1314
1315 return 0;
1316}
1317
1318
8cd6b7bc 1319static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
03e47c9c 1320{
8cd6b7bc 1321 *pos = 0x00;
03e47c9c 1322
8cd6b7bc
JB
1323 switch (idx) {
1324 case 0: /* Bits 0-7 */
1325 break;
1326 case 1: /* Bits 8-15 */
1327 break;
1328 case 2: /* Bits 16-23 */
1329#ifdef CONFIG_WNM
1330 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1331 *pos |= 0x08; /* Bit 19 - BSS Transition */
1332#endif /* CONFIG_WNM */
1333 break;
1334 case 3: /* Bits 24-31 */
1335#ifdef CONFIG_WNM
1336 *pos |= 0x02; /* Bit 25 - SSID List */
1337#endif /* CONFIG_WNM */
03e47c9c 1338#ifdef CONFIG_INTERWORKING
8cd6b7bc
JB
1339 if (wpa_s->conf->interworking)
1340 *pos |= 0x80; /* Bit 31 - Interworking */
03e47c9c 1341#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1342 break;
1343 case 4: /* Bits 32-39 */
56f5af48 1344#ifdef CONFIG_INTERWORKING
429dd9af
JM
1345 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1346 *pos |= 0x01; /* Bit 32 - QoS Map */
56f5af48 1347#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1348 break;
1349 case 5: /* Bits 40-47 */
95a3ea94
JM
1350#ifdef CONFIG_HS20
1351 if (wpa_s->conf->hs20)
1352 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1353#endif /* CONFIG_HS20 */
8cd6b7bc
JB
1354 break;
1355 case 6: /* Bits 48-55 */
1356 break;
1357 }
1358}
03e47c9c 1359
03e47c9c 1360
0bbaa9b9 1361int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
8cd6b7bc
JB
1362{
1363 u8 *pos = buf;
95a3ea94 1364 u8 len = 6, i;
8cd6b7bc
JB
1365
1366 if (len < wpa_s->extended_capa_len)
1367 len = wpa_s->extended_capa_len;
0bbaa9b9
JM
1368 if (buflen < (size_t) len + 2) {
1369 wpa_printf(MSG_INFO,
1370 "Not enough room for building extended capabilities element");
1371 return -1;
1372 }
03e47c9c
JM
1373
1374 *pos++ = WLAN_EID_EXT_CAPAB;
8cd6b7bc
JB
1375 *pos++ = len;
1376 for (i = 0; i < len; i++, pos++) {
1377 wpas_ext_capab_byte(wpa_s, pos, i);
1378
1379 if (i < wpa_s->extended_capa_len) {
1380 *pos &= ~wpa_s->extended_capa_mask[i];
1381 *pos |= wpa_s->extended_capa[i];
1382 }
1383 }
03e47c9c 1384
3db5439a
JM
1385 while (len > 0 && buf[1 + len] == 0) {
1386 len--;
1387 buf[1] = len;
1388 }
1389 if (len == 0)
1390 return 0;
1391
1392 return 2 + len;
03e47c9c
JM
1393}
1394
1395
6ac4b15e
JM
1396static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1397 struct wpa_bss *test_bss)
1398{
1399 struct wpa_bss *bss;
1400
1401 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1402 if (bss == test_bss)
1403 return 1;
1404 }
1405
1406 return 0;
1407}
1408
1409
1410static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1411 struct wpa_ssid *test_ssid)
1412{
1413 struct wpa_ssid *ssid;
1414
1415 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1416 if (ssid == test_ssid)
1417 return 1;
1418 }
1419
1420 return 0;
1421}
1422
1423
1424int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1425 struct wpa_ssid *test_ssid)
1426{
1427 if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1428 return 0;
1429
1430 return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1431}
1432
1433
1434void wpas_connect_work_free(struct wpa_connect_work *cwork)
1435{
1436 if (cwork == NULL)
1437 return;
1438 os_free(cwork);
1439}
1440
1441
1442void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1443{
1444 struct wpa_connect_work *cwork;
1445 struct wpa_radio_work *work = wpa_s->connect_work;
1446
1447 if (!work)
1448 return;
1449
1450 wpa_s->connect_work = NULL;
1451 cwork = work->ctx;
1452 work->ctx = NULL;
1453 wpas_connect_work_free(cwork);
1454 radio_work_done(work);
1455}
1456
1457
a313d17d 1458int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
c267753b
JM
1459{
1460 struct os_reltime now;
1461 u8 addr[ETH_ALEN];
1462
1463 os_get_reltime(&now);
a313d17d
JM
1464 if (wpa_s->last_mac_addr_style == style &&
1465 wpa_s->last_mac_addr_change.sec != 0 &&
c267753b
JM
1466 !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
1467 wpa_s->conf->rand_addr_lifetime)) {
1468 wpa_msg(wpa_s, MSG_DEBUG,
1469 "Previously selected random MAC address has not yet expired");
1470 return 0;
1471 }
1472
a313d17d
JM
1473 switch (style) {
1474 case 1:
1475 if (random_mac_addr(addr) < 0)
1476 return -1;
1477 break;
1478 case 2:
1479 os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
1480 if (random_mac_addr_keep_oui(addr) < 0)
1481 return -1;
1482 break;
1483 default:
c267753b 1484 return -1;
a313d17d 1485 }
c267753b
JM
1486
1487 if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
1488 wpa_msg(wpa_s, MSG_INFO,
1489 "Failed to set random MAC address");
1490 return -1;
1491 }
1492
1493 os_get_reltime(&wpa_s->last_mac_addr_change);
1494 wpa_s->mac_addr_changed = 1;
a313d17d 1495 wpa_s->last_mac_addr_style = style;
c267753b
JM
1496
1497 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1498 wpa_msg(wpa_s, MSG_INFO,
1499 "Could not update MAC address information");
1500 return -1;
1501 }
1502
1503 wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
1504 MAC2STR(addr));
1505
1506 return 0;
1507}
1508
1509
1510int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
1511{
1512 if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
1513 !wpa_s->conf->preassoc_mac_addr)
1514 return 0;
1515
a313d17d 1516 return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
c267753b
JM
1517}
1518
1519
6ac4b15e
JM
1520static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1521
6fc6879b
JM
1522/**
1523 * wpa_supplicant_associate - Request association
1524 * @wpa_s: Pointer to wpa_supplicant data
1525 * @bss: Scan results for the selected BSS, or %NULL if not available
1526 * @ssid: Configuration data for the selected network
1527 *
1528 * This function is used to request %wpa_supplicant to associate with a BSS.
1529 */
1530void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
6fa81a3b 1531 struct wpa_bss *bss, struct wpa_ssid *ssid)
6fc6879b 1532{
6ac4b15e 1533 struct wpa_connect_work *cwork;
a313d17d
JM
1534 int rand_style;
1535
1536 if (ssid->mac_addr == -1)
1537 rand_style = wpa_s->conf->mac_addr;
1538 else
1539 rand_style = ssid->mac_addr;
6fc6879b 1540
8c42b369
EP
1541 wmm_ac_clear_saved_tspecs(wpa_s);
1542 wpa_s->reassoc_same_bss = 0;
1543
c267753b
JM
1544 if (wpa_s->last_ssid == ssid) {
1545 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
8c42b369
EP
1546 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
1547 wmm_ac_save_tspecs(wpa_s);
1548 wpa_s->reassoc_same_bss = 1;
1549 }
a313d17d
JM
1550 } else if (rand_style > 0) {
1551 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
c267753b
JM
1552 return;
1553 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
1554 } else if (wpa_s->mac_addr_changed) {
1555 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1556 wpa_msg(wpa_s, MSG_INFO,
1557 "Could not restore permanent MAC address");
1558 return;
1559 }
1560 wpa_s->mac_addr_changed = 0;
1561 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1562 wpa_msg(wpa_s, MSG_INFO,
1563 "Could not update MAC address information");
1564 return;
1565 }
1566 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1567 }
1568 wpa_s->last_ssid = ssid;
1569
78177a00
JM
1570#ifdef CONFIG_IBSS_RSN
1571 ibss_rsn_deinit(wpa_s->ibss_rsn);
1572 wpa_s->ibss_rsn = NULL;
1573#endif /* CONFIG_IBSS_RSN */
1574
2c5d725c
JM
1575 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1576 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
1577#ifdef CONFIG_AP
1578 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
1579 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1580 "mode");
1581b38b
JM
1581 return;
1582 }
8c981d17
DW
1583 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1584 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
1585 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1586 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
1587 return;
1588 }
8f770587 1589 wpa_s->current_bss = bss;
1581b38b 1590#else /* CONFIG_AP */
f049052b
BG
1591 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1592 "the build");
1581b38b
JM
1593#endif /* CONFIG_AP */
1594 return;
1595 }
1596
603a3f34
JL
1597 if (ssid->mode == WPAS_MODE_MESH) {
1598#ifdef CONFIG_MESH
1599 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1600 wpa_msg(wpa_s, MSG_INFO,
1601 "Driver does not support mesh mode");
1602 return;
1603 }
1604 if (bss)
1605 ssid->frequency = bss->freq;
1606 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1607 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1608 return;
1609 }
1610 wpa_s->current_bss = bss;
1611 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_STARTED
1612 "ssid=\"%s\" id=%d",
1613 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1614 ssid->id);
1615#else /* CONFIG_MESH */
1616 wpa_msg(wpa_s, MSG_ERROR,
1617 "mesh mode support not included in the build");
1618#endif /* CONFIG_MESH */
1619 return;
1620 }
1621
52c9e6f3 1622#ifdef CONFIG_TDLS
95cb2d88
JM
1623 if (bss)
1624 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1625 bss->ie_len);
52c9e6f3
JM
1626#endif /* CONFIG_TDLS */
1627
5cc4d64b
JM
1628 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1629 ssid->mode == IEEE80211_MODE_INFRA) {
c2a04078
JM
1630 sme_authenticate(wpa_s, bss, ssid);
1631 return;
1632 }
1633
6ac4b15e
JM
1634 if (wpa_s->connect_work) {
1635 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1636 return;
1637 }
1638
f0e30c84
JM
1639 if (radio_work_pending(wpa_s, "connect")) {
1640 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1641 return;
1642 }
1643
6ac4b15e
JM
1644 cwork = os_zalloc(sizeof(*cwork));
1645 if (cwork == NULL)
1646 return;
1647
1648 cwork->bss = bss;
1649 cwork->ssid = ssid;
1650
1651 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1652 wpas_start_assoc_cb, cwork) < 0) {
1653 os_free(cwork);
1654 }
1655}
1656
1657
98479dc9
JD
1658static int bss_is_ibss(struct wpa_bss *bss)
1659{
1660 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1661 IEEE80211_CAP_IBSS;
1662}
1663
1664
54fe48b9
JM
1665void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1666 const struct wpa_ssid *ssid,
1667 struct hostapd_freq_params *freq)
1830817e
JD
1668{
1669 enum hostapd_hw_mode hw_mode;
1670 struct hostapd_hw_modes *mode = NULL;
6b8b0774
JD
1671 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1672 184, 192 };
563ee183 1673 int vht80[] = { 36, 52, 100, 116, 132, 149 };
6b8b0774 1674 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1830817e 1675 u8 channel;
98479dc9 1676 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
6b8b0774 1677 unsigned int j;
563ee183 1678 struct hostapd_freq_params vht_freq;
1830817e
JD
1679
1680 freq->freq = ssid->frequency;
1681
98479dc9
JD
1682 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1683 struct wpa_bss *bss = wpa_s->last_scan_res[j];
1684
1685 if (ssid->mode != WPAS_MODE_IBSS)
1686 break;
1687
1688 /* Don't adjust control freq in case of fixed_freq */
1689 if (ssid->fixed_freq)
1690 break;
1691
1692 if (!bss_is_ibss(bss))
1693 continue;
1694
1695 if (ssid->ssid_len == bss->ssid_len &&
1696 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1697 wpa_printf(MSG_DEBUG,
1698 "IBSS already found in scan results, adjust control freq: %d",
1699 bss->freq);
1700 freq->freq = bss->freq;
1701 obss_scan = 0;
1702 break;
1703 }
1704 }
1705
1830817e
JD
1706 /* For IBSS check HT_IBSS flag */
1707 if (ssid->mode == WPAS_MODE_IBSS &&
1708 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1709 return;
1710
d9a9bc04
JD
1711 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1712 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1713 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1714 wpa_printf(MSG_DEBUG,
1715 "IBSS: WEP/TKIP detected, do not try to enable HT");
1716 return;
1717 }
1718
98479dc9 1719 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
1830817e
JD
1720 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1721 if (wpa_s->hw.modes[i].mode == hw_mode) {
1722 mode = &wpa_s->hw.modes[i];
1723 break;
1724 }
1725 }
1726
1727 if (!mode)
1728 return;
1729
1730 freq->ht_enabled = ht_supported(mode);
6b8b0774
JD
1731 if (!freq->ht_enabled)
1732 return;
1733
1734 /* Setup higher BW only for 5 GHz */
1735 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1736 return;
1737
1738 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1739 pri_chan = &mode->channels[chan_idx];
1740 if (pri_chan->chan == channel)
1741 break;
1742 pri_chan = NULL;
1743 }
1744 if (!pri_chan)
1745 return;
1746
1747 /* Check primary channel flags */
1748 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1749 return;
1750
1751 /* Check/setup HT40+/HT40- */
1752 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1753 if (ht40plus[j] == channel) {
1754 ht40 = 1;
1755 break;
1756 }
1757 }
1758
1759 /* Find secondary channel */
1760 for (i = 0; i < mode->num_channels; i++) {
1761 sec_chan = &mode->channels[i];
1762 if (sec_chan->chan == channel + ht40 * 4)
1763 break;
1764 sec_chan = NULL;
1765 }
1766 if (!sec_chan)
1767 return;
1768
1769 /* Check secondary channel flags */
1770 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1771 return;
1772
1773 freq->channel = pri_chan->chan;
1774
1775 switch (ht40) {
1776 case -1:
1777 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1778 return;
1779 freq->sec_channel_offset = -1;
1780 break;
1781 case 1:
1782 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1783 return;
1784 freq->sec_channel_offset = 1;
1785 break;
1786 default:
1787 break;
1788 }
1789
98479dc9 1790 if (freq->sec_channel_offset && obss_scan) {
6b8b0774
JD
1791 struct wpa_scan_results *scan_res;
1792
1793 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1794 if (scan_res == NULL) {
1795 /* Back to HT20 */
1796 freq->sec_channel_offset = 0;
1797 return;
1798 }
1799
1800 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
1801 sec_chan->chan);
1802 switch (res) {
1803 case 0:
1804 /* Back to HT20 */
1805 freq->sec_channel_offset = 0;
1806 break;
1807 case 1:
1808 /* Configuration allowed */
1809 break;
1810 case 2:
1811 /* Switch pri/sec channels */
1812 freq->freq = hw_get_freq(mode, sec_chan->chan);
1813 freq->sec_channel_offset = -freq->sec_channel_offset;
1814 freq->channel = sec_chan->chan;
1815 break;
1816 default:
1817 freq->sec_channel_offset = 0;
1818 break;
1819 }
1820
1821 wpa_scan_results_free(scan_res);
1822 }
1823
1824 wpa_printf(MSG_DEBUG,
1825 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
1826 freq->channel, freq->sec_channel_offset);
563ee183
JD
1827
1828 /* Not sure if mesh is ready for VHT */
1829 if (ssid->mode != WPAS_MODE_IBSS)
1830 return;
1831
1832 /* For IBSS check VHT_IBSS flag */
1833 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
1834 return;
1835
1836 vht_freq = *freq;
1837
1838 vht_freq.vht_enabled = vht_supported(mode);
1839 if (!vht_freq.vht_enabled)
1840 return;
1841
1842 /* setup center_freq1, bandwidth */
1843 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
1844 if (freq->channel >= vht80[j] &&
1845 freq->channel < vht80[j] + 16)
1846 break;
1847 }
1848
1849 if (j == ARRAY_SIZE(vht80))
1850 return;
1851
1852 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
1853 struct hostapd_channel_data *chan;
1854
1855 chan = hw_get_channel_chan(mode, i, NULL);
1856 if (!chan)
1857 return;
1858
1859 /* Back to HT configuration if channel not usable */
1860 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1861 return;
1862 }
1863
1864 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
1865 freq->channel, freq->ht_enabled,
1866 vht_freq.vht_enabled,
1867 freq->sec_channel_offset,
1868 VHT_CHANWIDTH_80MHZ,
c3dabf5a 1869 vht80[j] + 6, 0, 0) != 0)
563ee183
JD
1870 return;
1871
1872 *freq = vht_freq;
1873
1874 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
1875 freq->center_freq1, freq->center_freq2, freq->bandwidth);
1830817e
JD
1876}
1877
1878
6ac4b15e
JM
1879static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
1880{
1881 struct wpa_connect_work *cwork = work->ctx;
1882 struct wpa_bss *bss = cwork->bss;
1883 struct wpa_ssid *ssid = cwork->ssid;
1884 struct wpa_supplicant *wpa_s = work->wpa_s;
1885 u8 wpa_ie[200];
1886 size_t wpa_ie_len;
1887 int use_crypt, ret, i, bssid_changed;
1888 int algs = WPA_AUTH_ALG_OPEN;
1889 unsigned int cipher_pairwise, cipher_group;
1890 struct wpa_driver_associate_params params;
1891 int wep_keys_set = 0;
1892 int assoc_failed = 0;
1893 struct wpa_ssid *old_ssid;
1894#ifdef CONFIG_HT_OVERRIDES
1895 struct ieee80211_ht_capabilities htcaps;
1896 struct ieee80211_ht_capabilities htcaps_mask;
1897#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
1898#ifdef CONFIG_VHT_OVERRIDES
1899 struct ieee80211_vht_capabilities vhtcaps;
1900 struct ieee80211_vht_capabilities vhtcaps_mask;
1901#endif /* CONFIG_VHT_OVERRIDES */
6ac4b15e
JM
1902
1903 if (deinit) {
b3253ebb
AO
1904 if (work->started) {
1905 wpa_s->connect_work = NULL;
1906
1907 /* cancel possible auth. timeout */
1908 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
1909 NULL);
1910 }
6ac4b15e
JM
1911 wpas_connect_work_free(cwork);
1912 return;
1913 }
1914
1915 wpa_s->connect_work = work;
1916
a7f5271d 1917 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid)) {
6ac4b15e
JM
1918 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
1919 wpas_connect_work_done(wpa_s);
1920 return;
1921 }
1922
0c80427d 1923 os_memset(&params, 0, sizeof(params));
6fc6879b 1924 wpa_s->reassociate = 0;
c60ba9f7 1925 wpa_s->eap_expected_failure = 0;
76d81b32
JM
1926 if (bss &&
1927 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
6fc6879b 1928#ifdef CONFIG_IEEE80211R
6fa81a3b 1929 const u8 *ie, *md = NULL;
6fc6879b 1930#endif /* CONFIG_IEEE80211R */
6fc6879b
JM
1931 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1932 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
6fa81a3b 1933 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
8bac466b 1934 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
6fc6879b
JM
1935 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1936 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
8bac466b
JM
1937 if (bssid_changed)
1938 wpas_notify_bssid_changed(wpa_s);
6fc6879b 1939#ifdef CONFIG_IEEE80211R
6fa81a3b 1940 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
6fc6879b
JM
1941 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1942 md = ie + 2;
e7846b68 1943 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
91a05482
JM
1944 if (md) {
1945 /* Prepare for the next transition */
76b7981d 1946 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
91a05482 1947 }
6fc6879b 1948#endif /* CONFIG_IEEE80211R */
24c23d1b
JM
1949#ifdef CONFIG_WPS
1950 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1951 wpa_s->conf->ap_scan == 2 &&
1952 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1953 /* Use ap_scan==1 style network selection to find the network
1954 */
74656400 1955 wpas_connect_work_done(wpa_s);
4115303b 1956 wpa_s->scan_req = MANUAL_SCAN_REQ;
24c23d1b
JM
1957 wpa_s->reassociate = 1;
1958 wpa_supplicant_req_scan(wpa_s, 0, 0);
1959 return;
1960#endif /* CONFIG_WPS */
6fc6879b
JM
1961 } else {
1962 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1963 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1964 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1965 }
a4cba8f1 1966 wpa_supplicant_cancel_sched_scan(wpa_s);
6fc6879b
JM
1967 wpa_supplicant_cancel_scan(wpa_s);
1968
1969 /* Starting new association, so clear the possibly used WPA IE from the
1970 * previous association. */
1971 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1972
1973#ifdef IEEE8021X_EAPOL
1974 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1975 if (ssid->leap) {
1976 if (ssid->non_leap == 0)
abd9fafa 1977 algs = WPA_AUTH_ALG_LEAP;
6fc6879b 1978 else
abd9fafa 1979 algs |= WPA_AUTH_ALG_LEAP;
6fc6879b
JM
1980 }
1981 }
1982#endif /* IEEE8021X_EAPOL */
f049052b 1983 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
6fc6879b 1984 if (ssid->auth_alg) {
abd9fafa 1985 algs = ssid->auth_alg;
f049052b
BG
1986 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1987 "0x%x", algs);
6fc6879b 1988 }
6fc6879b 1989
6fa81a3b
JM
1990 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1991 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 1992 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 1993 int try_opportunistic;
6e202021
JM
1994 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1995 wpa_s->conf->okc :
1996 ssid->proactive_key_caching) &&
6fc6879b
JM
1997 (ssid->proto & WPA_PROTO_RSN);
1998 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
b2a12c4f 1999 ssid, try_opportunistic) == 0)
ba422613 2000 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
6fc6879b
JM
2001 wpa_ie_len = sizeof(wpa_ie);
2002 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2003 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2004 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2005 "key management and encryption suites");
74656400 2006 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2007 return;
2008 }
a3f7e518
JM
2009 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2010 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2011 /*
2012 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2013 * use non-WPA since the scan results did not indicate that the
2014 * AP is using WPA or WPA2.
2015 */
2016 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2017 wpa_ie_len = 0;
2018 wpa_s->wpa_proto = 0;
0bf927a0 2019 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
6fc6879b
JM
2020 wpa_ie_len = sizeof(wpa_ie);
2021 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2022 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2023 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2024 "key management and encryption suites (no "
2025 "scan results)");
74656400 2026 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2027 return;
2028 }
ad08c363
JM
2029#ifdef CONFIG_WPS
2030 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
2031 struct wpabuf *wps_ie;
2032 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
ad08c363
JM
2033 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2034 wpa_ie_len = wpabuf_len(wps_ie);
2035 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
2036 } else
2037 wpa_ie_len = 0;
ad08c363
JM
2038 wpabuf_free(wps_ie);
2039 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d
JM
2040 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2041 params.wps = WPS_MODE_PRIVACY;
2042 else
2043 params.wps = WPS_MODE_OPEN;
cf546f1a 2044 wpa_s->wpa_proto = 0;
ad08c363 2045#endif /* CONFIG_WPS */
6fc6879b
JM
2046 } else {
2047 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2048 wpa_ie_len = 0;
cf546f1a 2049 wpa_s->wpa_proto = 0;
6fc6879b
JM
2050 }
2051
5f3a6aa0
JM
2052#ifdef CONFIG_P2P
2053 if (wpa_s->global->p2p) {
2054 u8 *pos;
2055 size_t len;
2056 int res;
5f3a6aa0
JM
2057 pos = wpa_ie + wpa_ie_len;
2058 len = sizeof(wpa_ie) - wpa_ie_len;
b8a8d677
JM
2059 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2060 ssid->p2p_group);
5f3a6aa0
JM
2061 if (res >= 0)
2062 wpa_ie_len += res;
2063 }
72044390
JM
2064
2065 wpa_s->cross_connect_disallowed = 0;
2066 if (bss) {
2067 struct wpabuf *p2p;
2068 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2069 if (p2p) {
2070 wpa_s->cross_connect_disallowed =
2071 p2p_get_cross_connect_disallowed(p2p);
2072 wpabuf_free(p2p);
f049052b
BG
2073 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2074 "connection",
2075 wpa_s->cross_connect_disallowed ?
2076 "disallows" : "allows");
72044390
JM
2077 }
2078 }
25ef8529
JM
2079
2080 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
5f3a6aa0
JM
2081#endif /* CONFIG_P2P */
2082
cb418324 2083#ifdef CONFIG_HS20
55a2df43 2084 if (is_hs20_network(wpa_s, ssid, bss)) {
cb418324
JM
2085 struct wpabuf *hs20;
2086 hs20 = wpabuf_alloc(20);
2087 if (hs20) {
f9cd147d 2088 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
745ef184
JM
2089 size_t len;
2090
f9cd147d 2091 wpas_hs20_add_indication(hs20, pps_mo_id);
745ef184
JM
2092 len = sizeof(wpa_ie) - wpa_ie_len;
2093 if (wpabuf_len(hs20) <= len) {
2094 os_memcpy(wpa_ie + wpa_ie_len,
2095 wpabuf_head(hs20), wpabuf_len(hs20));
2096 wpa_ie_len += wpabuf_len(hs20);
2097 }
cb418324
JM
2098 wpabuf_free(hs20);
2099 }
2100 }
2101#endif /* CONFIG_HS20 */
2102
8b3b803a
AH
2103 /*
2104 * Workaround: Add Extended Capabilities element only if the AP
2105 * included this element in Beacon/Probe Response frames. Some older
2106 * APs seem to have interoperability issues if this element is
2107 * included, so while the standard may require us to include the
2108 * element in all cases, it is justifiable to skip it to avoid
2109 * interoperability issues.
2110 */
2111 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
0bbaa9b9 2112 u8 ext_capab[18];
8b3b803a 2113 int ext_capab_len;
0bbaa9b9
JM
2114 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2115 sizeof(ext_capab));
8b3b803a
AH
2116 if (ext_capab_len > 0) {
2117 u8 *pos = wpa_ie;
2118 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2119 pos += 2 + pos[1];
2120 os_memmove(pos + ext_capab_len, pos,
2121 wpa_ie_len - (pos - wpa_ie));
2122 wpa_ie_len += ext_capab_len;
2123 os_memcpy(pos, ext_capab, ext_capab_len);
2124 }
92cbcf91 2125 }
92cbcf91 2126
d29fa3a7
JM
2127 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2128 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2129 size_t len;
2130
2131 len = sizeof(wpa_ie) - wpa_ie_len;
2132 if (wpabuf_len(buf) <= len) {
2133 os_memcpy(wpa_ie + wpa_ie_len,
2134 wpabuf_head(buf), wpabuf_len(buf));
2135 wpa_ie_len += wpabuf_len(buf);
2136 }
2137 }
2138
6fc6879b
JM
2139 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2140 use_crypt = 1;
4848a38d
JM
2141 cipher_pairwise = wpa_s->pairwise_cipher;
2142 cipher_group = wpa_s->group_cipher;
6fc6879b
JM
2143 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2144 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2145 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2146 use_crypt = 0;
2147 if (wpa_set_wep_keys(wpa_s, ssid)) {
2148 use_crypt = 1;
2149 wep_keys_set = 1;
2150 }
2151 }
ad08c363
JM
2152 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2153 use_crypt = 0;
6fc6879b
JM
2154
2155#ifdef IEEE8021X_EAPOL
2156 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2157 if ((ssid->eapol_flags &
2158 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2159 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2160 !wep_keys_set) {
2161 use_crypt = 0;
2162 } else {
2163 /* Assume that dynamic WEP-104 keys will be used and
2164 * set cipher suites in order for drivers to expect
2165 * encryption. */
4848a38d 2166 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
2167 }
2168 }
2169#endif /* IEEE8021X_EAPOL */
2170
2171 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2172 /* Set the key before (and later after) association */
2173 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2174 }
2175
6fc6879b 2176 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 2177 if (bss) {
6fa81a3b
JM
2178 params.ssid = bss->ssid;
2179 params.ssid_len = bss->ssid_len;
f15854d1
JM
2180 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
2181 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2182 MACSTR " freq=%u MHz based on scan results "
2183 "(bssid_set=%d)",
2184 MAC2STR(bss->bssid), bss->freq,
2185 ssid->bssid_set);
22628eca 2186 params.bssid = bss->bssid;
4ec68377 2187 params.freq.freq = bss->freq;
22628eca 2188 }
7ac7fd43
DS
2189 params.bssid_hint = bss->bssid;
2190 params.freq_hint = bss->freq;
6fc6879b
JM
2191 } else {
2192 params.ssid = ssid->ssid;
2193 params.ssid_len = ssid->ssid_len;
2194 }
9e2af29f
NC
2195
2196 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2197 wpa_s->conf->ap_scan == 2) {
2198 params.bssid = ssid->bssid;
2199 params.fixed_bssid = 1;
2200 }
2201
603a3f34
JL
2202 /* Initial frequency for IBSS/mesh */
2203 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
1830817e
JD
2204 ssid->frequency > 0 && params.freq.freq == 0)
2205 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
dc152f32 2206
8f05577d 2207 if (ssid->mode == WPAS_MODE_IBSS) {
4d9e6fba 2208 params.fixed_freq = ssid->fixed_freq;
8f05577d
JM
2209 if (ssid->beacon_int)
2210 params.beacon_int = ssid->beacon_int;
2211 else
2212 params.beacon_int = wpa_s->conf->beacon_int;
2213 }
2214
6fc6879b
JM
2215 params.wpa_ie = wpa_ie;
2216 params.wpa_ie_len = wpa_ie_len;
2217 params.pairwise_suite = cipher_pairwise;
2218 params.group_suite = cipher_group;
4848a38d 2219 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 2220 params.wpa_proto = wpa_s->wpa_proto;
6fc6879b
JM
2221 params.auth_alg = algs;
2222 params.mode = ssid->mode;
1f6c0ab8 2223 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
2224 for (i = 0; i < NUM_WEP_KEYS; i++) {
2225 if (ssid->wep_key_len[i])
2226 params.wep_key[i] = ssid->wep_key[i];
2227 params.wep_key_len[i] = ssid->wep_key_len[i];
2228 }
2229 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2230
c2a04078 2231 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
4848a38d
JM
2232 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2233 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
2234 params.passphrase = ssid->passphrase;
2235 if (ssid->psk_set)
2236 params.psk = ssid->psk;
b41f2684
CL
2237 }
2238
2239 if (wpa_s->conf->key_mgmt_offload) {
2240 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
666497c8 2241 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
5e3b5197
JM
2242 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2243 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
b41f2684
CL
2244 params.req_key_mgmt_offload =
2245 ssid->proactive_key_caching < 0 ?
2246 wpa_s->conf->okc : ssid->proactive_key_caching;
2247 else
2248 params.req_key_mgmt_offload = 1;
2249
2250 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2251 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2252 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2253 ssid->psk_set)
2254 params.psk = ssid->psk;
6fc6879b
JM
2255 }
2256
36b15723
JM
2257 params.drop_unencrypted = use_crypt;
2258
6fc6879b 2259#ifdef CONFIG_IEEE80211W
3f56a2b7 2260 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
62d49803 2261 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 2262 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
2263 struct wpa_ie_data ie;
2264 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2265 ie.capabilities &
2266 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
2267 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2268 "MFP: require MFP");
97d3497e
JM
2269 params.mgmt_frame_protection =
2270 MGMT_FRAME_PROTECTION_REQUIRED;
2271 }
2272 }
6fc6879b
JM
2273#endif /* CONFIG_IEEE80211W */
2274
ffad8858 2275 params.p2p = ssid->p2p_group;
6e3f4b89 2276
eea2fd9e
JM
2277 if (wpa_s->parent->set_sta_uapsd)
2278 params.uapsd = wpa_s->parent->sta_uapsd;
2279 else
2280 params.uapsd = -1;
2281
80e8a5ee
BG
2282#ifdef CONFIG_HT_OVERRIDES
2283 os_memset(&htcaps, 0, sizeof(htcaps));
2284 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2285 params.htcaps = (u8 *) &htcaps;
2286 params.htcaps_mask = (u8 *) &htcaps_mask;
2287 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2288#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
2289#ifdef CONFIG_VHT_OVERRIDES
2290 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2291 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2292 params.vhtcaps = &vhtcaps;
2293 params.vhtcaps_mask = &vhtcaps_mask;
95ff3069 2294 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
6aa1cd4e 2295#endif /* CONFIG_VHT_OVERRIDES */
80e8a5ee 2296
8567866d
JJ
2297#ifdef CONFIG_P2P
2298 /*
2299 * If multi-channel concurrency is not supported, check for any
2300 * frequency conflict. In case of any frequency conflict, remove the
2301 * least prioritized connection.
2302 */
2303 if (wpa_s->num_multichan_concurrent < 2) {
d0df6437
IP
2304 int freq, num;
2305 num = get_shared_radio_freqs(wpa_s, &freq, 1);
4ec68377 2306 if (num > 0 && freq > 0 && freq != params.freq.freq) {
d0df6437
IP
2307 wpa_printf(MSG_DEBUG,
2308 "Assoc conflicting freq found (%d != %d)",
4ec68377
JD
2309 freq, params.freq.freq);
2310 if (wpas_p2p_handle_frequency_conflicts(
74656400
SD
2311 wpa_s, params.freq.freq, ssid) < 0) {
2312 wpas_connect_work_done(wpa_s);
8567866d 2313 return;
74656400 2314 }
8567866d
JJ
2315 }
2316 }
2317#endif /* CONFIG_P2P */
2318
17fbb751 2319 ret = wpa_drv_associate(wpa_s, &params);
6fc6879b
JM
2320 if (ret < 0) {
2321 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2322 "failed");
871f4dd0
JM
2323 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2324 /*
2325 * The driver is known to mean what is saying, so we
2326 * can stop right here; the association will not
2327 * succeed.
2328 */
2329 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 2330 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
2331 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2332 return;
2333 }
6fc6879b
JM
2334 /* try to continue anyway; new association will be tried again
2335 * after timeout */
2336 assoc_failed = 1;
2337 }
2338
2339 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2340 /* Set the key after the association just in case association
2341 * cleared the previously configured key. */
2342 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2343 /* No need to timeout authentication since there is no key
2344 * management. */
2345 wpa_supplicant_cancel_auth_timeout(wpa_s);
2346 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 2347#ifdef CONFIG_IBSS_RSN
d7dcba70 2348 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
2349 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2350 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2351 /*
2352 * RSN IBSS authentication is per-STA and we can disable the
2353 * per-BSSID authentication.
2354 */
2355 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 2356#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
2357 } else {
2358 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
2359 int timeout = 60;
2360
2361 if (assoc_failed) {
2362 /* give IBSS a bit more time */
d7dcba70 2363 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
2364 } else if (wpa_s->conf->ap_scan == 1) {
2365 /* give IBSS a bit more time */
d7dcba70 2366 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 2367 }
6fc6879b
JM
2368 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2369 }
2370
66562e9c
JM
2371 if (wep_keys_set &&
2372 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
2373 /* Set static WEP keys again */
2374 wpa_set_wep_keys(wpa_s, ssid);
2375 }
2376
2377 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2378 /*
2379 * Do not allow EAP session resumption between different
2380 * network configurations.
2381 */
2382 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2383 }
8bac466b 2384 old_ssid = wpa_s->current_ssid;
6fc6879b 2385 wpa_s->current_ssid = ssid;
8f770587 2386 wpa_s->current_bss = bss;
6fc6879b
JM
2387 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2388 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
2389 if (old_ssid != wpa_s->current_ssid)
2390 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
2391}
2392
2393
09f58c09
JM
2394static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2395 const u8 *addr)
2396{
2397 struct wpa_ssid *old_ssid;
2398
c155305f 2399 wpas_connect_work_done(wpa_s);
09f58c09 2400 wpa_clear_keys(wpa_s, addr);
09f58c09 2401 old_ssid = wpa_s->current_ssid;
0d30cc24 2402 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
2403 wpa_sm_set_config(wpa_s->wpa, NULL);
2404 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2405 if (old_ssid != wpa_s->current_ssid)
2406 wpas_notify_network_changed(wpa_s);
2407 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2408}
2409
2410
6fc6879b
JM
2411/**
2412 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2413 * @wpa_s: Pointer to wpa_supplicant data
2414 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2415 *
073ab58f 2416 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
2417 * current AP.
2418 */
2419void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2420 int reason_code)
2421{
2422 u8 *addr = NULL;
ef48ff94 2423 union wpa_event_data event;
42d23547 2424 int zero_addr = 0;
8bac466b 2425
42d23547
JM
2426 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2427 " pending_bssid=" MACSTR " reason=%d state=%s",
2428 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2429 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2430
2431 if (!is_zero_ether_addr(wpa_s->bssid))
2432 addr = wpa_s->bssid;
2433 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2434 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2435 wpa_s->wpa_state == WPA_ASSOCIATING))
2436 addr = wpa_s->pending_bssid;
2437 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2438 /*
2439 * When using driver-based BSS selection, we may not know the
2440 * BSSID with which we are currently trying to associate. We
2441 * need to notify the driver of this disconnection even in such
2442 * a case, so use the all zeros address here.
2443 */
6fc6879b 2444 addr = wpa_s->bssid;
42d23547
JM
2445 zero_addr = 1;
2446 }
2447
7b44ff2c
SD
2448#ifdef CONFIG_TDLS
2449 wpa_tdls_teardown_peers(wpa_s->wpa);
2450#endif /* CONFIG_TDLS */
2451
603a3f34
JL
2452#ifdef CONFIG_MESH
2453 if (wpa_s->ifmsh) {
2454 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2455 wpa_s->ifname);
2456 wpa_supplicant_leave_mesh(wpa_s);
2457 }
2458#endif /* CONFIG_MESH */
2459
42d23547
JM
2460 if (addr) {
2461 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94
JM
2462 os_memset(&event, 0, sizeof(event));
2463 event.deauth_info.reason_code = (u16) reason_code;
2464 event.deauth_info.locally_generated = 1;
2465 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
2466 if (zero_addr)
2467 addr = NULL;
6fc6879b 2468 }
09f58c09
JM
2469
2470 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
2471}
2472
dca1a511
DS
2473static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2474 struct wpa_ssid *ssid)
2475{
2476 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2477 return;
2478
2479 ssid->disabled = 0;
2480 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2481 wpas_notify_network_enabled_changed(wpa_s, ssid);
2482
2483 /*
2484 * Try to reassociate since there is no current configuration and a new
2485 * network was made available.
2486 */
d2592497 2487 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
2488 wpa_s->reassociate = 1;
2489}
2490
6fc6879b 2491
86b89452
WS
2492/**
2493 * wpa_supplicant_enable_network - Mark a configured network as enabled
2494 * @wpa_s: wpa_supplicant structure for a network interface
2495 * @ssid: wpa_ssid structure for a configured network or %NULL
2496 *
2497 * Enables the specified network or all networks if no network specified.
2498 */
2499void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2500 struct wpa_ssid *ssid)
2501{
86b89452 2502 if (ssid == NULL) {
14f79078
JM
2503 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2504 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
2505 } else
2506 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 2507
d2592497 2508 if (wpa_s->reassociate && !wpa_s->disconnected) {
dca1a511
DS
2509 if (wpa_s->sched_scanning) {
2510 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2511 "new network to scan filters");
2512 wpa_supplicant_cancel_sched_scan(wpa_s);
2513 }
86b89452 2514
dad153d1
JM
2515 if (wpa_supplicant_fast_associate(wpa_s) != 1)
2516 wpa_supplicant_req_scan(wpa_s, 0, 0);
86b89452
WS
2517 }
2518}
2519
2520
2521/**
2522 * wpa_supplicant_disable_network - Mark a configured network as disabled
2523 * @wpa_s: wpa_supplicant structure for a network interface
2524 * @ssid: wpa_ssid structure for a configured network or %NULL
2525 *
2526 * Disables the specified network or all networks if no network specified.
2527 */
2528void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2529 struct wpa_ssid *ssid)
2530{
2531 struct wpa_ssid *other_ssid;
2532 int was_disabled;
2533
2534 if (ssid == NULL) {
725fc39e
DS
2535 if (wpa_s->sched_scanning)
2536 wpa_supplicant_cancel_sched_scan(wpa_s);
2537
4dac0245
JM
2538 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2539 other_ssid = other_ssid->next) {
86b89452 2540 was_disabled = other_ssid->disabled;
4dac0245
JM
2541 if (was_disabled == 2)
2542 continue; /* do not change persistent P2P group
2543 * data */
86b89452
WS
2544
2545 other_ssid->disabled = 1;
2546
2547 if (was_disabled != other_ssid->disabled)
2548 wpas_notify_network_enabled_changed(
2549 wpa_s, other_ssid);
86b89452
WS
2550 }
2551 if (wpa_s->current_ssid)
07783eaa 2552 wpa_supplicant_deauthenticate(
86b89452 2553 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
4dac0245 2554 } else if (ssid->disabled != 2) {
86b89452 2555 if (ssid == wpa_s->current_ssid)
07783eaa 2556 wpa_supplicant_deauthenticate(
86b89452
WS
2557 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2558
2559 was_disabled = ssid->disabled;
2560
2561 ssid->disabled = 1;
2562
725fc39e 2563 if (was_disabled != ssid->disabled) {
86b89452 2564 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
2565 if (wpa_s->sched_scanning) {
2566 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2567 "to remove network from filters");
2568 wpa_supplicant_cancel_sched_scan(wpa_s);
2569 wpa_supplicant_req_scan(wpa_s, 0, 0);
2570 }
2571 }
86b89452
WS
2572 }
2573}
2574
2575
2576/**
2577 * wpa_supplicant_select_network - Attempt association with a network
2578 * @wpa_s: wpa_supplicant structure for a network interface
2579 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2580 */
2581void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2582 struct wpa_ssid *ssid)
2583{
2584
2585 struct wpa_ssid *other_ssid;
d93dfbd5 2586 int disconnected = 0;
86b89452 2587
d93dfbd5 2588 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
c2805909 2589 wpa_s->own_disconnect_req = 1;
07783eaa 2590 wpa_supplicant_deauthenticate(
86b89452 2591 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
2592 disconnected = 1;
2593 }
86b89452 2594
00e5e3d5
JM
2595 if (ssid)
2596 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2597
86b89452
WS
2598 /*
2599 * Mark all other networks disabled or mark all networks enabled if no
2600 * network specified.
2601 */
4dac0245
JM
2602 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2603 other_ssid = other_ssid->next) {
86b89452 2604 int was_disabled = other_ssid->disabled;
4dac0245
JM
2605 if (was_disabled == 2)
2606 continue; /* do not change persistent P2P group data */
86b89452
WS
2607
2608 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
2609 if (was_disabled && !other_ssid->disabled)
2610 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
2611
2612 if (was_disabled != other_ssid->disabled)
2613 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 2614 }
2a6f78fb
JJ
2615
2616 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
2617 /* We are already associated with the selected network */
2618 wpa_printf(MSG_DEBUG, "Already associated with the "
2619 "selected network - do nothing");
2620 return;
2621 }
2622
25a8f9e3 2623 if (ssid) {
96efeeb6 2624 wpa_s->current_ssid = ssid;
25a8f9e3 2625 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
603a3f34
JL
2626 wpa_s->connect_without_scan =
2627 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
2628 } else {
2629 wpa_s->connect_without_scan = NULL;
25a8f9e3 2630 }
603a3f34 2631
86b89452
WS
2632 wpa_s->disconnected = 0;
2633 wpa_s->reassociate = 1;
cecdddc1 2634
e4a35f07
JM
2635 if (wpa_s->connect_without_scan ||
2636 wpa_supplicant_fast_associate(wpa_s) != 1)
cecdddc1 2637 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
86b89452 2638
a1641d26
JM
2639 if (ssid)
2640 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
2641}
2642
2643
bdec7ee5
MS
2644/**
2645 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2646 * @wpa_s: wpa_supplicant structure for a network interface
2647 * @pkcs11_engine_path: PKCS #11 engine path or NULL
2648 * @pkcs11_module_path: PKCS #11 module path or NULL
2649 * Returns: 0 on success; -1 on failure
2650 *
2651 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
2652 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
2653 * module path fails the paths will be reset to the default value (NULL).
2654 */
2655int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
2656 const char *pkcs11_engine_path,
2657 const char *pkcs11_module_path)
2658{
2659 char *pkcs11_engine_path_copy = NULL;
2660 char *pkcs11_module_path_copy = NULL;
2661
2662 if (pkcs11_engine_path != NULL) {
2663 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
2664 if (pkcs11_engine_path_copy == NULL)
2665 return -1;
2666 }
2667 if (pkcs11_module_path != NULL) {
2668 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
04c366cb 2669 if (pkcs11_module_path_copy == NULL) {
bdec7ee5
MS
2670 os_free(pkcs11_engine_path_copy);
2671 return -1;
2672 }
2673 }
2674
2675 os_free(wpa_s->conf->pkcs11_engine_path);
2676 os_free(wpa_s->conf->pkcs11_module_path);
2677 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
2678 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
2679
2680 wpa_sm_set_eapol(wpa_s->wpa, NULL);
2681 eapol_sm_deinit(wpa_s->eapol);
2682 wpa_s->eapol = NULL;
2683 if (wpa_supplicant_init_eapol(wpa_s)) {
2684 /* Error -> Reset paths to the default value (NULL) once. */
2685 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
2686 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
2687 NULL);
2688
2689 return -1;
2690 }
2691 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2692
2693 return 0;
2694}
2695
2696
86b89452
WS
2697/**
2698 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
2699 * @wpa_s: wpa_supplicant structure for a network interface
2700 * @ap_scan: AP scan mode
2701 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
2702 *
2703 */
2704int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
2705{
2706
2707 int old_ap_scan;
2708
2709 if (ap_scan < 0 || ap_scan > 2)
2710 return -1;
2711
48f8e036
DS
2712#ifdef ANDROID
2713 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
2714 wpa_s->wpa_state >= WPA_ASSOCIATING &&
2715 wpa_s->wpa_state < WPA_COMPLETED) {
2716 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
2717 "associating", wpa_s->conf->ap_scan, ap_scan);
2718 return 0;
2719 }
2720#endif /* ANDROID */
2721
86b89452
WS
2722 old_ap_scan = wpa_s->conf->ap_scan;
2723 wpa_s->conf->ap_scan = ap_scan;
2724
2725 if (old_ap_scan != wpa_s->conf->ap_scan)
2726 wpas_notify_ap_scan_changed(wpa_s);
2727
2728 return 0;
2729}
2730
2731
78633c37
SL
2732/**
2733 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
2734 * @wpa_s: wpa_supplicant structure for a network interface
2735 * @expire_age: Expiration age in seconds
2736 * Returns: 0 if succeed or -1 if expire_age has an invalid value
2737 *
2738 */
2739int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
2740 unsigned int bss_expire_age)
2741{
2742 if (bss_expire_age < 10) {
2743 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
2744 bss_expire_age);
2745 return -1;
2746 }
2747 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
2748 bss_expire_age);
2749 wpa_s->conf->bss_expiration_age = bss_expire_age;
2750
2751 return 0;
2752}
2753
2754
2755/**
2756 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2757 * @wpa_s: wpa_supplicant structure for a network interface
2758 * @expire_count: number of scans after which an unseen BSS is reclaimed
2759 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2760 *
2761 */
2762int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2763 unsigned int bss_expire_count)
2764{
2765 if (bss_expire_count < 1) {
2766 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2767 bss_expire_count);
2768 return -1;
2769 }
2770 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2771 bss_expire_count);
2772 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2773
2774 return 0;
2775}
2776
2777
c6e86b63
MA
2778/**
2779 * wpa_supplicant_set_scan_interval - Set scan interval
2780 * @wpa_s: wpa_supplicant structure for a network interface
2781 * @scan_interval: scan interval in seconds
2782 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2783 *
2784 */
2785int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2786 int scan_interval)
2787{
2788 if (scan_interval < 0) {
2789 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2790 scan_interval);
2791 return -1;
2792 }
2793 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2794 scan_interval);
9e737f08 2795 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
2796
2797 return 0;
2798}
2799
2800
86b89452
WS
2801/**
2802 * wpa_supplicant_set_debug_params - Set global debug params
2803 * @global: wpa_global structure
2804 * @debug_level: debug level
2805 * @debug_timestamp: determines if show timestamp in debug data
2806 * @debug_show_keys: determines if show keys in debug data
2807 * Returns: 0 if succeed or -1 if debug_level has wrong value
2808 */
2809int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2810 int debug_timestamp, int debug_show_keys)
2811{
2812
2813 int old_level, old_timestamp, old_show_keys;
2814
2815 /* check for allowed debuglevels */
14dc0011
PS
2816 if (debug_level != MSG_EXCESSIVE &&
2817 debug_level != MSG_MSGDUMP &&
86b89452
WS
2818 debug_level != MSG_DEBUG &&
2819 debug_level != MSG_INFO &&
2820 debug_level != MSG_WARNING &&
2821 debug_level != MSG_ERROR)
2822 return -1;
2823
2824 old_level = wpa_debug_level;
2825 old_timestamp = wpa_debug_timestamp;
2826 old_show_keys = wpa_debug_show_keys;
2827
2828 wpa_debug_level = debug_level;
2829 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2830 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2831
db9133ac
WS
2832 if (wpa_debug_level != old_level)
2833 wpas_notify_debug_level_changed(global);
2834 if (wpa_debug_timestamp != old_timestamp)
2835 wpas_notify_debug_timestamp_changed(global);
2836 if (wpa_debug_show_keys != old_show_keys)
2837 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
2838
2839 return 0;
2840}
2841
2842
6fc6879b
JM
2843/**
2844 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2845 * @wpa_s: Pointer to wpa_supplicant data
2846 * Returns: A pointer to the current network structure or %NULL on failure
2847 */
2848struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2849{
2850 struct wpa_ssid *entry;
2851 u8 ssid[MAX_SSID_LEN];
2852 int res;
2853 size_t ssid_len;
2854 u8 bssid[ETH_ALEN];
2855 int wired;
2856
17fbb751
JM
2857 res = wpa_drv_get_ssid(wpa_s, ssid);
2858 if (res < 0) {
2859 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2860 "driver");
2861 return NULL;
6fc6879b 2862 }
17fbb751 2863 ssid_len = res;
6fc6879b 2864
17fbb751 2865 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
2866 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2867 "driver");
6fc6879b
JM
2868 return NULL;
2869 }
2870
c2a04078
JM
2871 wired = wpa_s->conf->ap_scan == 0 &&
2872 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
2873
2874 entry = wpa_s->conf->ssid;
2875 while (entry) {
349493bd 2876 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b
JM
2877 ((ssid_len == entry->ssid_len &&
2878 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2879 (!entry->bssid_set ||
2880 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2881 return entry;
24c23d1b 2882#ifdef CONFIG_WPS
349493bd 2883 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
2884 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2885 (entry->ssid == NULL || entry->ssid_len == 0) &&
2886 (!entry->bssid_set ||
2887 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2888 return entry;
2889#endif /* CONFIG_WPS */
7d232e23 2890
349493bd 2891 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
2892 entry->ssid_len == 0 &&
2893 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2894 return entry;
2895
6fc6879b
JM
2896 entry = entry->next;
2897 }
2898
2899 return NULL;
2900}
2901
2902
7756114f
JM
2903static int select_driver(struct wpa_supplicant *wpa_s, int i)
2904{
2905 struct wpa_global *global = wpa_s->global;
2906
2907 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2908 global->drv_priv[i] = wpa_drivers[i]->global_init();
2909 if (global->drv_priv[i] == NULL) {
2910 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2911 "'%s'", wpa_drivers[i]->name);
2912 return -1;
2913 }
2914 }
2915
2916 wpa_s->driver = wpa_drivers[i];
2917 wpa_s->global_drv_priv = global->drv_priv[i];
2918
2919 return 0;
2920}
2921
2922
6fc6879b
JM
2923static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2924 const char *name)
2925{
2926 int i;
362f781e 2927 size_t len;
74b1c84a 2928 const char *pos, *driver = name;
6fc6879b
JM
2929
2930 if (wpa_s == NULL)
2931 return -1;
2932
c5121837 2933 if (wpa_drivers[0] == NULL) {
f049052b
BG
2934 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2935 "wpa_supplicant");
6fc6879b
JM
2936 return -1;
2937 }
2938
2939 if (name == NULL) {
2940 /* default to first driver in the list */
7756114f 2941 return select_driver(wpa_s, 0);
6fc6879b
JM
2942 }
2943
74b1c84a
SO
2944 do {
2945 pos = os_strchr(driver, ',');
2946 if (pos)
2947 len = pos - driver;
2948 else
2949 len = os_strlen(driver);
2950
2951 for (i = 0; wpa_drivers[i]; i++) {
2952 if (os_strlen(wpa_drivers[i]->name) == len &&
2953 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
2954 0) {
2955 /* First driver that succeeds wins */
2956 if (select_driver(wpa_s, i) == 0)
2957 return 0;
2958 }
6fc6879b 2959 }
74b1c84a
SO
2960
2961 driver = pos + 1;
2962 } while (pos);
6fc6879b 2963
f049052b 2964 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
2965 return -1;
2966}
2967
2968
a8e0505b
JM
2969/**
2970 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2971 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2972 * with struct wpa_driver_ops::init()
2973 * @src_addr: Source address of the EAPOL frame
2974 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2975 * @len: Length of the EAPOL data
2976 *
2977 * This function is called for each received EAPOL frame. Most driver
2978 * interfaces rely on more generic OS mechanism for receiving frames through
2979 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2980 * take care of received EAPOL frames and deliver them to the core supplicant
2981 * code by calling this function.
2982 */
6fc6879b
JM
2983void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2984 const u8 *buf, size_t len)
2985{
2986 struct wpa_supplicant *wpa_s = ctx;
2987
f049052b 2988 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
2989 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2990
db76aa64
JM
2991#ifdef CONFIG_PEERKEY
2992 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
2993 wpa_s->current_ssid->peerkey &&
2994 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
2995 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
2996 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
2997 return;
2998 }
2999#endif /* CONFIG_PEERKEY */
3000
3ab35a66
JM
3001 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3002 (wpa_s->last_eapol_matches_bssid &&
3003#ifdef CONFIG_AP
3004 !wpa_s->ap_iface &&
3005#endif /* CONFIG_AP */
3006 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
3007 /*
3008 * There is possible race condition between receiving the
3009 * association event and the EAPOL frame since they are coming
3010 * through different paths from the driver. In order to avoid
3011 * issues in trying to process the EAPOL frame before receiving
3012 * association information, lets queue it for processing until
3ab35a66
JM
3013 * the association event is received. This may also be needed in
3014 * driver-based roaming case, so also use src_addr != BSSID as a
3015 * trigger if we have previously confirmed that the
3016 * Authenticator uses BSSID as the src_addr (which is not the
3017 * case with wired IEEE 802.1X).
1ff73338 3018 */
f049052b 3019 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
3020 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3021 wpa_supplicant_state_txt(wpa_s->wpa_state),
3022 MAC2STR(wpa_s->bssid));
1ff73338
JM
3023 wpabuf_free(wpa_s->pending_eapol_rx);
3024 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3025 if (wpa_s->pending_eapol_rx) {
c2be937c 3026 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
3027 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3028 ETH_ALEN);
3029 }
3030 return;
3031 }
3032
3ab35a66
JM
3033 wpa_s->last_eapol_matches_bssid =
3034 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3035
db149ac9
JM
3036#ifdef CONFIG_AP
3037 if (wpa_s->ap_iface) {
3038 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3039 return;
3040 }
3041#endif /* CONFIG_AP */
3042
6fc6879b 3043 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
3044 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3045 "no key management is configured");
6fc6879b
JM
3046 return;
3047 }
3048
3049 if (wpa_s->eapol_received == 0 &&
c2a04078 3050 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
56586197 3051 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
3052 wpa_s->wpa_state != WPA_COMPLETED) &&
3053 (wpa_s->current_ssid == NULL ||
3054 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
6fc6879b
JM
3055 /* Timeout for completing IEEE 802.1X and WPA authentication */
3056 wpa_supplicant_req_auth_timeout(
3057 wpa_s,
56586197 3058 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
a6f06dab
AT
3059 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3060 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
6fc6879b
JM
3061 70 : 10, 0);
3062 }
3063 wpa_s->eapol_received++;
3064
3065 if (wpa_s->countermeasures) {
f049052b
BG
3066 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3067 "EAPOL packet");
6fc6879b
JM
3068 return;
3069 }
3070
8be18440
JM
3071#ifdef CONFIG_IBSS_RSN
3072 if (wpa_s->current_ssid &&
d7dcba70 3073 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
3074 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3075 return;
3076 }
3077#endif /* CONFIG_IBSS_RSN */
3078
6fc6879b
JM
3079 /* Source address of the incoming EAPOL frame could be compared to the
3080 * current BSSID. However, it is possible that a centralized
3081 * Authenticator could be using another MAC address than the BSSID of
3082 * an AP, so just allow any address to be used for now. The replies are
3083 * still sent to the current BSSID (if available), though. */
3084
3085 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 3086 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
6fc6879b
JM
3087 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3088 return;
3089 wpa_drv_poll(wpa_s);
c2a04078 3090 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
6fc6879b 3091 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 3092 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
3093 /*
3094 * Set portValid = TRUE here since we are going to skip 4-way
3095 * handshake processing which would normally set portValid. We
3096 * need this to allow the EAPOL state machines to be completed
3097 * without going through EAPOL-Key handshake.
3098 */
3099 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3100 }
3101}
3102
3103
bfba8deb 3104int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 3105{
2961bfa8
JM
3106 if ((!wpa_s->p2p_mgmt ||
3107 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3108 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 3109 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
3110 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3111 wpa_drv_get_mac_addr(wpa_s),
3112 ETH_P_EAPOL,
3113 wpa_supplicant_rx_eapol, wpa_s, 0);
3114 if (wpa_s->l2 == NULL)
3115 return -1;
fdadd5fe
JM
3116 } else {
3117 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3118 if (addr)
3119 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
3120 }
3121
3122 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 3123 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
3124 return -1;
3125 }
3126
c267753b
JM
3127 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3128
bfba8deb
JM
3129 return 0;
3130}
3131
3132
25f839c6
JM
3133static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3134 const u8 *buf, size_t len)
3135{
3136 struct wpa_supplicant *wpa_s = ctx;
3137 const struct l2_ethhdr *eth;
3138
3139 if (len < sizeof(*eth))
3140 return;
3141 eth = (const struct l2_ethhdr *) buf;
3142
3143 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3144 !(eth->h_dest[0] & 0x01)) {
3145 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3146 " (bridge - not for this interface - ignore)",
3147 MAC2STR(src_addr), MAC2STR(eth->h_dest));
3148 return;
3149 }
3150
3151 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3152 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3153 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3154 len - sizeof(*eth));
3155}
3156
3157
bfba8deb
JM
3158/**
3159 * wpa_supplicant_driver_init - Initialize driver interface parameters
3160 * @wpa_s: Pointer to wpa_supplicant data
3161 * Returns: 0 on success, -1 on failure
3162 *
3163 * This function is called to initialize driver interface parameters.
3164 * wpa_drv_init() must have been called before this function to initialize the
3165 * driver interface.
3166 */
3167int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3168{
3169 static int interface_count = 0;
3170
3171 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3172 return -1;
3173
c68f6200
AS
3174 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3175 MAC2STR(wpa_s->own_addr));
a313d17d 3176 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
c68f6200
AS
3177 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3178
6fc6879b 3179 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
3180 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3181 "interface '%s'", wpa_s->bridge_ifname);
e6dd8196
JM
3182 wpa_s->l2_br = l2_packet_init_bridge(
3183 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3184 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
6fc6879b 3185 if (wpa_s->l2_br == NULL) {
f049052b
BG
3186 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3187 "connection for the bridge interface '%s'",
3188 wpa_s->bridge_ifname);
6fc6879b
JM
3189 return -1;
3190 }
3191 }
3192
6fc6879b
JM
3193 wpa_clear_keys(wpa_s, NULL);
3194
3195 /* Make sure that TKIP countermeasures are not left enabled (could
3196 * happen if wpa_supplicant is killed during countermeasures. */
3197 wpa_drv_set_countermeasures(wpa_s, 0);
3198
f049052b 3199 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
3200 wpa_drv_flush_pmkid(wpa_s);
3201
ba2a573c 3202 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
3203 wpa_s->prev_scan_wildcard = 0;
3204
349493bd 3205 if (wpa_supplicant_enabled_networks(wpa_s)) {
a0e9d892
AS
3206 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3207 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3208 interface_count = 0;
3209 }
ee82e33d 3210#ifndef ANDROID
3a94adbf 3211 if (!wpa_s->p2p_mgmt &&
5d0d72a3
BG
3212 wpa_supplicant_delayed_sched_scan(wpa_s,
3213 interface_count % 3,
6a90053c 3214 100000))
5d0d72a3 3215 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
a4cba8f1 3216 100000);
ee82e33d 3217#endif /* ANDROID */
74e259ec
JM
3218 interface_count++;
3219 } else
3220 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
3221
3222 return 0;
3223}
3224
3225
3226static int wpa_supplicant_daemon(const char *pid_file)
3227{
3228 wpa_printf(MSG_DEBUG, "Daemonize..");
3229 return os_daemonize(pid_file);
3230}
3231
3232
1772d348
JM
3233static struct wpa_supplicant *
3234wpa_supplicant_alloc(struct wpa_supplicant *parent)
6fc6879b
JM
3235{
3236 struct wpa_supplicant *wpa_s;
3237
3238 wpa_s = os_zalloc(sizeof(*wpa_s));
3239 if (wpa_s == NULL)
3240 return NULL;
4115303b 3241 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 3242 wpa_s->scan_interval = 5;
c302f207 3243 wpa_s->new_connection = 1;
1772d348 3244 wpa_s->parent = parent ? parent : wpa_s;
cbdf3507 3245 wpa_s->sched_scanning = 0;
6fc6879b
JM
3246
3247 return wpa_s;
3248}
3249
3250
80e8a5ee
BG
3251#ifdef CONFIG_HT_OVERRIDES
3252
3253static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3254 struct ieee80211_ht_capabilities *htcaps,
3255 struct ieee80211_ht_capabilities *htcaps_mask,
3256 const char *ht_mcs)
3257{
3258 /* parse ht_mcs into hex array */
3259 int i;
3260 const char *tmp = ht_mcs;
3261 char *end = NULL;
3262
3263 /* If ht_mcs is null, do not set anything */
3264 if (!ht_mcs)
3265 return 0;
3266
3267 /* This is what we are setting in the kernel */
3268 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3269
3270 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3271
3272 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3273 errno = 0;
3274 long v = strtol(tmp, &end, 16);
3275 if (errno == 0) {
3276 wpa_msg(wpa_s, MSG_DEBUG,
3277 "htcap value[%i]: %ld end: %p tmp: %p",
3278 i, v, end, tmp);
3279 if (end == tmp)
3280 break;
3281
3282 htcaps->supported_mcs_set[i] = v;
3283 tmp = end;
3284 } else {
3285 wpa_msg(wpa_s, MSG_ERROR,
3286 "Failed to parse ht-mcs: %s, error: %s\n",
3287 ht_mcs, strerror(errno));
3288 return -1;
3289 }
3290 }
3291
3292 /*
3293 * If we were able to parse any values, then set mask for the MCS set.
3294 */
3295 if (i) {
3296 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3297 IEEE80211_HT_MCS_MASK_LEN - 1);
3298 /* skip the 3 reserved bits */
3299 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3300 0x1f;
3301 }
3302
3303 return 0;
3304}
3305
3306
3307static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3308 struct ieee80211_ht_capabilities *htcaps,
3309 struct ieee80211_ht_capabilities *htcaps_mask,
3310 int disabled)
3311{
5bc28571 3312 le16 msk;
80e8a5ee
BG
3313
3314 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3315
3316 if (disabled == -1)
3317 return 0;
3318
3319 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3320 htcaps_mask->ht_capabilities_info |= msk;
3321 if (disabled)
3322 htcaps->ht_capabilities_info &= msk;
3323 else
3324 htcaps->ht_capabilities_info |= msk;
3325
3326 return 0;
3327}
3328
3329
3330static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3331 struct ieee80211_ht_capabilities *htcaps,
3332 struct ieee80211_ht_capabilities *htcaps_mask,
3333 int factor)
3334{
3335 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3336
3337 if (factor == -1)
3338 return 0;
3339
3340 if (factor < 0 || factor > 3) {
3341 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3342 "Must be 0-3 or -1", factor);
3343 return -EINVAL;
3344 }
3345
3346 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3347 htcaps->a_mpdu_params &= ~0x3;
3348 htcaps->a_mpdu_params |= factor & 0x3;
3349
3350 return 0;
3351}
3352
3353
3354static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3355 struct ieee80211_ht_capabilities *htcaps,
3356 struct ieee80211_ht_capabilities *htcaps_mask,
3357 int density)
3358{
3359 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3360
3361 if (density == -1)
3362 return 0;
3363
3364 if (density < 0 || density > 7) {
3365 wpa_msg(wpa_s, MSG_ERROR,
3366 "ampdu_density: %d out of range. Must be 0-7 or -1.",
3367 density);
3368 return -EINVAL;
3369 }
3370
3371 htcaps_mask->a_mpdu_params |= 0x1C;
3372 htcaps->a_mpdu_params &= ~(0x1C);
3373 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3374
3375 return 0;
3376}
3377
3378
3379static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3380 struct ieee80211_ht_capabilities *htcaps,
3381 struct ieee80211_ht_capabilities *htcaps_mask,
3382 int disabled)
3383{
3384 /* Masking these out disables HT40 */
5bc28571
JM
3385 le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3386 HT_CAP_INFO_SHORT_GI40MHZ);
80e8a5ee
BG
3387
3388 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3389
3390 if (disabled)
3391 htcaps->ht_capabilities_info &= ~msk;
3392 else
3393 htcaps->ht_capabilities_info |= msk;
3394
3395 htcaps_mask->ht_capabilities_info |= msk;
3396
3397 return 0;
3398}
3399
3400
a90497f8
BG
3401static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3402 struct ieee80211_ht_capabilities *htcaps,
3403 struct ieee80211_ht_capabilities *htcaps_mask,
3404 int disabled)
3405{
3406 /* Masking these out disables SGI */
5bc28571
JM
3407 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3408 HT_CAP_INFO_SHORT_GI40MHZ);
a90497f8
BG
3409
3410 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3411
3412 if (disabled)
3413 htcaps->ht_capabilities_info &= ~msk;
3414 else
3415 htcaps->ht_capabilities_info |= msk;
3416
3417 htcaps_mask->ht_capabilities_info |= msk;
3418
3419 return 0;
3420}
3421
3422
39a5800f
PK
3423static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3424 struct ieee80211_ht_capabilities *htcaps,
3425 struct ieee80211_ht_capabilities *htcaps_mask,
3426 int disabled)
3427{
3428 /* Masking these out disables LDPC */
5bc28571 3429 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
39a5800f
PK
3430
3431 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3432
3433 if (disabled)
3434 htcaps->ht_capabilities_info &= ~msk;
3435 else
3436 htcaps->ht_capabilities_info |= msk;
3437
3438 htcaps_mask->ht_capabilities_info |= msk;
3439
3440 return 0;
3441}
3442
3443
80e8a5ee
BG
3444void wpa_supplicant_apply_ht_overrides(
3445 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3446 struct wpa_driver_associate_params *params)
3447{
3448 struct ieee80211_ht_capabilities *htcaps;
3449 struct ieee80211_ht_capabilities *htcaps_mask;
3450
3451 if (!ssid)
3452 return;
3453
3454 params->disable_ht = ssid->disable_ht;
3455 if (!params->htcaps || !params->htcaps_mask)
3456 return;
3457
3458 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3459 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3460 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3461 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3462 ssid->disable_max_amsdu);
3463 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3464 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3465 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 3466 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
39a5800f 3467 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
d41cc8cc
JM
3468
3469 if (ssid->ht40_intolerant) {
5bc28571 3470 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
d41cc8cc
JM
3471 htcaps->ht_capabilities_info |= bit;
3472 htcaps_mask->ht_capabilities_info |= bit;
3473 }
80e8a5ee
BG
3474}
3475
3476#endif /* CONFIG_HT_OVERRIDES */
3477
3478
e9ee8dc3
JB
3479#ifdef CONFIG_VHT_OVERRIDES
3480void wpa_supplicant_apply_vht_overrides(
3481 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3482 struct wpa_driver_associate_params *params)
3483{
3484 struct ieee80211_vht_capabilities *vhtcaps;
3485 struct ieee80211_vht_capabilities *vhtcaps_mask;
3486
3487 if (!ssid)
3488 return;
3489
3490 params->disable_vht = ssid->disable_vht;
3491
3492 vhtcaps = (void *) params->vhtcaps;
3493 vhtcaps_mask = (void *) params->vhtcaps_mask;
3494
3495 if (!vhtcaps || !vhtcaps_mask)
3496 return;
3497
3498 vhtcaps->vht_capabilities_info = ssid->vht_capa;
3499 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
3500
4f560cde
EP
3501#ifdef CONFIG_HT_OVERRIDES
3502 /* if max ampdu is <= 3, we have to make the HT cap the same */
b0f33467
JM
3503 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3504 int max_ampdu;
3505
3506 max_ampdu = (ssid->vht_capa &
3507 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3508 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
4f560cde
EP
3509
3510 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3511 wpa_set_ampdu_factor(wpa_s,
3512 (void *) params->htcaps,
3513 (void *) params->htcaps_mask,
3514 max_ampdu);
3515 }
3516#endif /* CONFIG_HT_OVERRIDES */
3517
e9ee8dc3
JB
3518#define OVERRIDE_MCS(i) \
3519 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3520 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
3521 3 << 2 * (i - 1); \
3522 vhtcaps->vht_supported_mcs_set.tx_map |= \
3523 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
3524 } \
3525 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3526 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
3527 3 << 2 * (i - 1); \
3528 vhtcaps->vht_supported_mcs_set.rx_map |= \
3529 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
3530 }
3531
3532 OVERRIDE_MCS(1);
3533 OVERRIDE_MCS(2);
3534 OVERRIDE_MCS(3);
3535 OVERRIDE_MCS(4);
3536 OVERRIDE_MCS(5);
3537 OVERRIDE_MCS(6);
3538 OVERRIDE_MCS(7);
3539 OVERRIDE_MCS(8);
3540}
3541#endif /* CONFIG_VHT_OVERRIDES */
3542
3543
f64adcd7
JM
3544static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3545{
3546#ifdef PCSC_FUNCS
3547 size_t len;
3548
3549 if (!wpa_s->conf->pcsc_reader)
3550 return 0;
3551
22cf7d73 3552 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
3553 if (!wpa_s->scard)
3554 return 1;
3555
3556 if (wpa_s->conf->pcsc_pin &&
3557 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
3558 scard_deinit(wpa_s->scard);
3559 wpa_s->scard = NULL;
3560 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
3561 return -1;
3562 }
3563
3564 len = sizeof(wpa_s->imsi) - 1;
3565 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
3566 scard_deinit(wpa_s->scard);
3567 wpa_s->scard = NULL;
3568 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
3569 return -1;
3570 }
3571 wpa_s->imsi[len] = '\0';
3572
3573 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
3574
3575 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
3576 wpa_s->imsi, wpa_s->mnc_len);
3577
3578 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
3579 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
3580#endif /* PCSC_FUNCS */
3581
3582 return 0;
3583}
3584
3585
306ae225
JM
3586int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
3587{
3588 char *val, *pos;
3589
3590 ext_password_deinit(wpa_s->ext_pw);
3591 wpa_s->ext_pw = NULL;
3592 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
3593
3594 if (!wpa_s->conf->ext_password_backend)
3595 return 0;
3596
3597 val = os_strdup(wpa_s->conf->ext_password_backend);
3598 if (val == NULL)
3599 return -1;
3600 pos = os_strchr(val, ':');
3601 if (pos)
3602 *pos++ = '\0';
3603
3604 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
3605
3606 wpa_s->ext_pw = ext_password_init(val, pos);
3607 os_free(val);
3608 if (wpa_s->ext_pw == NULL) {
3609 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
3610 return -1;
3611 }
3612 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
3613
3614 return 0;
3615}
3616
3617
a520bf4a 3618static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
6cbdb0c5 3619 const struct wpa_driver_capa *capa)
e4fa8b12 3620{
88cb27c7
DS
3621 struct wowlan_triggers *triggers;
3622 int ret = 0;
e4fa8b12
EP
3623
3624 if (!wpa_s->conf->wowlan_triggers)
3625 return 0;
3626
88cb27c7
DS
3627 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
3628 if (triggers) {
3629 ret = wpa_drv_wowlan(wpa_s, triggers);
3630 os_free(triggers);
e4fa8b12 3631 }
e4fa8b12
EP
3632 return ret;
3633}
3634
3635
202dec2a
JM
3636static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
3637 const char *rn)
3638{
3639 struct wpa_supplicant *iface = wpa_s->global->ifaces;
3640 struct wpa_radio *radio;
3641
3642 while (rn && iface) {
3643 radio = iface->radio;
3644 if (radio && os_strcmp(rn, radio->name) == 0) {
3645 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
3646 wpa_s->ifname, rn);
3647 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
3648 return radio;
3649 }
b154a24e
TB
3650
3651 iface = iface->next;
202dec2a
JM
3652 }
3653
3654 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
3655 wpa_s->ifname, rn ? rn : "N/A");
3656 radio = os_zalloc(sizeof(*radio));
3657 if (radio == NULL)
3658 return NULL;
3659
3660 if (rn)
3661 os_strlcpy(radio->name, rn, sizeof(radio->name));
3662 dl_list_init(&radio->ifaces);
b1ae396f 3663 dl_list_init(&radio->work);
202dec2a
JM
3664 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
3665
3666 return radio;
3667}
3668
3669
b1ae396f
JM
3670static void radio_work_free(struct wpa_radio_work *work)
3671{
d12a51b5
JM
3672 if (work->wpa_s->scan_work == work) {
3673 /* This should not really happen. */
3674 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
3675 work->type, work, work->started);
3676 work->wpa_s->scan_work = NULL;
3677 }
3678
1b5d4714
JM
3679#ifdef CONFIG_P2P
3680 if (work->wpa_s->p2p_scan_work == work) {
3681 /* This should not really happen. */
3682 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
3683 work->type, work, work->started);
3684 work->wpa_s->p2p_scan_work = NULL;
3685 }
3686#endif /* CONFIG_P2P */
3687
b1ae396f
JM
3688 dl_list_del(&work->list);
3689 os_free(work);
3690}
3691
3692
3693static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
3694{
3695 struct wpa_radio *radio = eloop_ctx;
3696 struct wpa_radio_work *work;
3697 struct os_reltime now, diff;
6428d0a7 3698 struct wpa_supplicant *wpa_s;
b1ae396f
JM
3699
3700 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
3701 if (work == NULL)
3702 return;
3703
3704 if (work->started)
3705 return; /* already started and still in progress */
3706
6428d0a7
JM
3707 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
3708 radio_list);
d90bfa97 3709 if (wpa_s && wpa_s->radio->external_scan_running) {
6428d0a7
JM
3710 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
3711 return;
3712 }
3713
b1ae396f
JM
3714 os_get_reltime(&now);
3715 os_reltime_sub(&now, &work->time, &diff);
3716 wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
3717 work->type, work, diff.sec, diff.usec);
3718 work->started = 1;
3719 work->time = now;
3720 work->cb(work, 0);
3721}
3722
3723
b3253ebb
AO
3724/*
3725 * This function removes both started and pending radio works running on
3726 * the provided interface's radio.
3727 * Prior to the removal of the radio work, its callback (cb) is called with
3728 * deinit set to be 1. Each work's callback is responsible for clearing its
3729 * internal data and restoring to a correct state.
3730 * @wpa_s: wpa_supplicant data
3731 * @type: type of works to be removed
3732 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
3733 * this interface's works.
3734 */
3735void radio_remove_works(struct wpa_supplicant *wpa_s,
3736 const char *type, int remove_all)
b1ae396f
JM
3737{
3738 struct wpa_radio_work *work, *tmp;
3739 struct wpa_radio *radio = wpa_s->radio;
3740
3741 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
3742 list) {
b3253ebb 3743 if (type && os_strcmp(type, work->type) != 0)
b1ae396f 3744 continue;
b3253ebb
AO
3745
3746 /* skip other ifaces' works */
3747 if (!remove_all && work->wpa_s != wpa_s)
b1ae396f 3748 continue;
b3253ebb
AO
3749
3750 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
3751 work->type, work, work->started ? " (started)" : "");
b1ae396f
JM
3752 work->cb(work, 1);
3753 radio_work_free(work);
3754 }
b3253ebb
AO
3755
3756 /* in case we removed the started work */
3757 radio_work_check_next(wpa_s);
b1ae396f
JM
3758}
3759
3760
202dec2a
JM
3761static void radio_remove_interface(struct wpa_supplicant *wpa_s)
3762{
3763 struct wpa_radio *radio = wpa_s->radio;
3764
3765 if (!radio)
3766 return;
3767
3768 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
3769 wpa_s->ifname, radio->name);
3770 dl_list_del(&wpa_s->radio_list);
c46235aa
AO
3771 radio_remove_works(wpa_s, NULL, 0);
3772 wpa_s->radio = NULL;
3773 if (!dl_list_empty(&radio->ifaces))
202dec2a
JM
3774 return; /* Interfaces remain for this radio */
3775
3776 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f 3777 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
202dec2a
JM
3778 os_free(radio);
3779}
3780
3781
6428d0a7 3782void radio_work_check_next(struct wpa_supplicant *wpa_s)
b1ae396f
JM
3783{
3784 struct wpa_radio *radio = wpa_s->radio;
3785
3786 if (dl_list_empty(&radio->work))
3787 return;
e3745228
JM
3788 if (wpa_s->ext_work_in_progress) {
3789 wpa_printf(MSG_DEBUG,
3790 "External radio work in progress - delay start of pending item");
3791 return;
3792 }
b1ae396f
JM
3793 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
3794 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
3795}
3796
3797
3798/**
3799 * radio_add_work - Add a radio work item
3800 * @wpa_s: Pointer to wpa_supplicant data
3801 * @freq: Frequency of the offchannel operation in MHz or 0
3802 * @type: Unique identifier for each type of work
3803 * @next: Force as the next work to be executed
3804 * @cb: Callback function for indicating when radio is available
3805 * @ctx: Context pointer for the work (work->ctx in cb())
3806 * Returns: 0 on success, -1 on failure
3807 *
3808 * This function is used to request time for an operation that requires
3809 * exclusive radio control. Once the radio is available, the registered callback
3810 * function will be called. radio_work_done() must be called once the exclusive
3811 * radio operation has been completed, so that the radio is freed for other
3812 * operations. The special case of deinit=1 is used to free the context data
3813 * during interface removal. That does not allow the callback function to start
3814 * the radio operation, i.e., it must free any resources allocated for the radio
3815 * work and return.
3816 *
3817 * The @freq parameter can be used to indicate a single channel on which the
3818 * offchannel operation will occur. This may allow multiple radio work
3819 * operations to be performed in parallel if they apply for the same channel.
3820 * Setting this to 0 indicates that the work item may use multiple channels or
3821 * requires exclusive control of the radio.
3822 */
3823int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
3824 const char *type, int next,
3825 void (*cb)(struct wpa_radio_work *work, int deinit),
3826 void *ctx)
3827{
3828 struct wpa_radio_work *work;
3829 int was_empty;
3830
3831 work = os_zalloc(sizeof(*work));
3832 if (work == NULL)
3833 return -1;
3834 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
3835 os_get_reltime(&work->time);
3836 work->freq = freq;
3837 work->type = type;
3838 work->wpa_s = wpa_s;
3839 work->cb = cb;
3840 work->ctx = ctx;
3841
3842 was_empty = dl_list_empty(&wpa_s->radio->work);
3843 if (next)
3844 dl_list_add(&wpa_s->radio->work, &work->list);
3845 else
3846 dl_list_add_tail(&wpa_s->radio->work, &work->list);
3847 if (was_empty) {
3848 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
3849 radio_work_check_next(wpa_s);
3850 }
3851
3852 return 0;
3853}
3854
3855
3856/**
3857 * radio_work_done - Indicate that a radio work item has been completed
3858 * @work: Completed work
3859 *
3860 * This function is called once the callback function registered with
3861 * radio_add_work() has completed its work.
3862 */
3863void radio_work_done(struct wpa_radio_work *work)
3864{
3865 struct wpa_supplicant *wpa_s = work->wpa_s;
3866 struct os_reltime now, diff;
1f965e62 3867 unsigned int started = work->started;
b1ae396f
JM
3868
3869 os_get_reltime(&now);
3870 os_reltime_sub(&now, &work->time, &diff);
1f965e62
JM
3871 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
3872 work->type, work, started ? "done" : "canceled",
3873 diff.sec, diff.usec);
b1ae396f 3874 radio_work_free(work);
1f965e62
JM
3875 if (started)
3876 radio_work_check_next(wpa_s);
b1ae396f
JM
3877}
3878
3879
a7f5271d
JM
3880struct wpa_radio_work *
3881radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
f0e30c84
JM
3882{
3883 struct wpa_radio_work *work;
3884 struct wpa_radio *radio = wpa_s->radio;
3885
3886 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
3887 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
a7f5271d 3888 return work;
f0e30c84
JM
3889 }
3890
a7f5271d 3891 return NULL;
f0e30c84
JM
3892}
3893
3894
73c00fd7
JM
3895static int wpas_init_driver(struct wpa_supplicant *wpa_s,
3896 struct wpa_interface *iface)
3897{
202dec2a 3898 const char *ifname, *driver, *rn;
73c00fd7
JM
3899
3900 driver = iface->driver;
3901next_driver:
3902 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
3903 return -1;
3904
3905 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
3906 if (wpa_s->drv_priv == NULL) {
3907 const char *pos;
3908 pos = driver ? os_strchr(driver, ',') : NULL;
3909 if (pos) {
3910 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
3911 "driver interface - try next driver wrapper");
3912 driver = pos + 1;
3913 goto next_driver;
3914 }
3915 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
3916 "interface");
3917 return -1;
3918 }
3919 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
3920 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
3921 "driver_param '%s'", wpa_s->conf->driver_param);
3922 return -1;
3923 }
3924
3925 ifname = wpa_drv_get_ifname(wpa_s);
3926 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
3927 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
3928 "interface name with '%s'", ifname);
3929 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
3930 }
3931
95bf699f 3932 rn = wpa_driver_get_radio_name(wpa_s);
202dec2a
JM
3933 if (rn && rn[0] == '\0')
3934 rn = NULL;
3935
3936 wpa_s->radio = radio_add_interface(wpa_s, rn);
3937 if (wpa_s->radio == NULL)
3938 return -1;
3939
73c00fd7
JM
3940 return 0;
3941}
3942
3943
6fc6879b
JM
3944static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
3945 struct wpa_interface *iface)
3946{
362f781e 3947 struct wpa_driver_capa capa;
6cbdb0c5 3948 int capa_res;
362f781e 3949
6fc6879b
JM
3950 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
3951 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
3952 iface->confname ? iface->confname : "N/A",
3953 iface->driver ? iface->driver : "default",
3954 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
3955 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
3956
6fc6879b
JM
3957 if (iface->confname) {
3958#ifdef CONFIG_BACKEND_FILE
3959 wpa_s->confname = os_rel2abs_path(iface->confname);
3960 if (wpa_s->confname == NULL) {
3961 wpa_printf(MSG_ERROR, "Failed to get absolute path "
3962 "for configuration file '%s'.",
3963 iface->confname);
3964 return -1;
3965 }
3966 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
3967 iface->confname, wpa_s->confname);
3968#else /* CONFIG_BACKEND_FILE */
3969 wpa_s->confname = os_strdup(iface->confname);
3970#endif /* CONFIG_BACKEND_FILE */
e6304cad 3971 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
3972 if (wpa_s->conf == NULL) {
3973 wpa_printf(MSG_ERROR, "Failed to read or parse "
3974 "configuration '%s'.", wpa_s->confname);
3975 return -1;
3976 }
e6304cad
DS
3977 wpa_s->confanother = os_rel2abs_path(iface->confanother);
3978 wpa_config_read(wpa_s->confanother, wpa_s->conf);
6fc6879b
JM
3979
3980 /*
3981 * Override ctrl_interface and driver_param if set on command
3982 * line.
3983 */
3984 if (iface->ctrl_interface) {
3985 os_free(wpa_s->conf->ctrl_interface);
3986 wpa_s->conf->ctrl_interface =
3987 os_strdup(iface->ctrl_interface);
3988 }
3989
3990 if (iface->driver_param) {
3991 os_free(wpa_s->conf->driver_param);
3992 wpa_s->conf->driver_param =
3993 os_strdup(iface->driver_param);
3994 }
78f79fe5
JM
3995
3996 if (iface->p2p_mgmt && !iface->ctrl_interface) {
3997 os_free(wpa_s->conf->ctrl_interface);
3998 wpa_s->conf->ctrl_interface = NULL;
3999 }
6fc6879b
JM
4000 } else
4001 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4002 iface->driver_param);
4003
4004 if (wpa_s->conf == NULL) {
4005 wpa_printf(MSG_ERROR, "\nNo configuration found.");
4006 return -1;
4007 }
4008
4009 if (iface->ifname == NULL) {
4010 wpa_printf(MSG_ERROR, "\nInterface name is required.");
4011 return -1;
4012 }
4013 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4014 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4015 iface->ifname);
4016 return -1;
4017 }
4018 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4019
4020 if (iface->bridge_ifname) {
4021 if (os_strlen(iface->bridge_ifname) >=
4022 sizeof(wpa_s->bridge_ifname)) {
4023 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4024 "name '%s'.", iface->bridge_ifname);
4025 return -1;
4026 }
4027 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4028 sizeof(wpa_s->bridge_ifname));
4029 }
4030
6fc6879b
JM
4031 /* RSNA Supplicant Key Management - INITIALIZE */
4032 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4033 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4034
4035 /* Initialize driver interface and register driver event handler before
4036 * L2 receive handler so that association events are processed before
4037 * EAPOL-Key packets if both become available for the same select()
4038 * call. */
73c00fd7 4039 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
4040 return -1;
4041
6fc6879b
JM
4042 if (wpa_supplicant_init_wpa(wpa_s) < 0)
4043 return -1;
4044
4045 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4046 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4047 NULL);
4048 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4049
4050 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4051 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4052 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
4053 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4054 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
4055 return -1;
4056 }
4057
4058 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4059 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4060 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 4061 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
4062 "dot11RSNAConfigPMKReauthThreshold");
4063 return -1;
4064 }
4065
4066 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4067 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4068 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
4069 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4070 "dot11RSNAConfigSATimeout");
6fc6879b
JM
4071 return -1;
4072 }
4073
6bf731e8
CL
4074 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4075 &wpa_s->hw.num_modes,
4076 &wpa_s->hw.flags);
a1b790eb
JM
4077 if (wpa_s->hw.modes) {
4078 u16 i;
4079
4080 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4081 if (wpa_s->hw.modes[i].vht_capab) {
4082 wpa_s->hw_capab = CAPAB_VHT;
4083 break;
4084 }
4085
4086 if (wpa_s->hw.modes[i].ht_capab &
4087 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4088 wpa_s->hw_capab = CAPAB_HT40;
4089 else if (wpa_s->hw.modes[i].ht_capab &&
4090 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4091 wpa_s->hw_capab = CAPAB_HT;
4092 }
4093 }
6bf731e8 4094
6cbdb0c5
JM
4095 capa_res = wpa_drv_get_capa(wpa_s, &capa);
4096 if (capa_res == 0) {
c58ab8f2 4097 wpa_s->drv_capa_known = 1;
814782b9 4098 wpa_s->drv_flags = capa.flags;
349493bd 4099 wpa_s->drv_enc = capa.enc;
04ee647d 4100 wpa_s->drv_smps_modes = capa.smps_modes;
f936b73c 4101 wpa_s->drv_rrm_flags = capa.rrm_flags;
4f73d88a 4102 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 4103 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507
LC
4104 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
4105 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 4106 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 4107 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 4108 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
4109 wpa_s->extended_capa = capa.extended_capa;
4110 wpa_s->extended_capa_mask = capa.extended_capa_mask;
4111 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
4112 wpa_s->num_multichan_concurrent =
4113 capa.num_multichan_concurrent;
471cd6e1 4114 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
56c76fa5
IP
4115
4116 if (capa.mac_addr_rand_scan_supported)
4117 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4118 if (wpa_s->sched_scan_supported &&
4119 capa.mac_addr_rand_sched_scan_supported)
4120 wpa_s->mac_addr_rand_supported |=
4121 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
814782b9
JM
4122 }
4123 if (wpa_s->max_remain_on_chan == 0)
4124 wpa_s->max_remain_on_chan = 1000;
4125
c68f6200
AS
4126 /*
4127 * Only take p2p_mgmt parameters when P2P Device is supported.
4128 * Doing it here as it determines whether l2_packet_init() will be done
4129 * during wpa_supplicant_driver_init().
4130 */
4131 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4132 wpa_s->p2p_mgmt = iface->p2p_mgmt;
4133 else
4134 iface->p2p_mgmt = 1;
4135
4752147d
IP
4136 if (wpa_s->num_multichan_concurrent == 0)
4137 wpa_s->num_multichan_concurrent = 1;
4138
6fc6879b
JM
4139 if (wpa_supplicant_driver_init(wpa_s) < 0)
4140 return -1;
4141
281ff0aa 4142#ifdef CONFIG_TDLS
1c42b42f
JM
4143 if ((!iface->p2p_mgmt ||
4144 !(wpa_s->drv_flags &
4145 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4146 wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
4147 return -1;
4148#endif /* CONFIG_TDLS */
4149
315ce40a
JM
4150 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4151 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 4152 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
4153 return -1;
4154 }
4155
116654ce
JM
4156 if (wpas_wps_init(wpa_s))
4157 return -1;
4158
6fc6879b
JM
4159 if (wpa_supplicant_init_eapol(wpa_s) < 0)
4160 return -1;
4161 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4162
4163 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4164 if (wpa_s->ctrl_iface == NULL) {
4165 wpa_printf(MSG_ERROR,
4166 "Failed to initialize control interface '%s'.\n"
4167 "You may have another wpa_supplicant process "
4168 "already running or the file was\n"
4169 "left by an unclean termination of wpa_supplicant "
4170 "in which case you will need\n"
4171 "to manually remove this file before starting "
4172 "wpa_supplicant again.\n",
4173 wpa_s->conf->ctrl_interface);
4174 return -1;
4175 }
4176
04ea7b79
JM
4177 wpa_s->gas = gas_query_init(wpa_s);
4178 if (wpa_s->gas == NULL) {
4179 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4180 return -1;
4181 }
4182
c68f6200 4183 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 4184 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
4185 return -1;
4186 }
b22128ef 4187
83922c2d
JM
4188 if (wpa_bss_init(wpa_s) < 0)
4189 return -1;
83922c2d 4190
e4fa8b12
EP
4191 /*
4192 * Set Wake-on-WLAN triggers, if configured.
4193 * Note: We don't restore/remove the triggers on shutdown (it doesn't
4194 * have effect anyway when the interface is down).
4195 */
6cbdb0c5 4196 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
e4fa8b12
EP
4197 return -1;
4198
ec7b97ab
JM
4199#ifdef CONFIG_EAP_PROXY
4200{
4201 size_t len;
07041c6f
NJ
4202 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4203 &len);
ec7b97ab
JM
4204 if (wpa_s->mnc_len > 0) {
4205 wpa_s->imsi[len] = '\0';
4206 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4207 wpa_s->imsi, wpa_s->mnc_len);
4208 } else {
4209 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4210 }
4211}
4212#endif /* CONFIG_EAP_PROXY */
4213
f64adcd7
JM
4214 if (pcsc_reader_init(wpa_s) < 0)
4215 return -1;
4216
306ae225
JM
4217 if (wpas_init_ext_pw(wpa_s) < 0)
4218 return -1;
4219
b361d580
AK
4220 wpas_rrm_reset(wpa_s);
4221
6fc6879b
JM
4222 return 0;
4223}
4224
4225
2ee055b3 4226static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 4227 int notify, int terminate)
6fc6879b 4228{
26fc96e8
JM
4229 struct wpa_global *global = wpa_s->global;
4230 struct wpa_supplicant *iface, *prev;
4231
4232 if (wpa_s == wpa_s->parent)
4233 wpas_p2p_group_remove(wpa_s, "*");
4234
4235 iface = global->ifaces;
4236 while (iface) {
4237 if (iface == wpa_s || iface->parent != wpa_s) {
4238 iface = iface->next;
4239 continue;
4240 }
4241 wpa_printf(MSG_DEBUG,
4242 "Remove remaining child interface %s from parent %s",
4243 iface->ifname, wpa_s->ifname);
4244 prev = iface;
4245 iface = iface->next;
4246 wpa_supplicant_remove_iface(global, prev, terminate);
4247 }
4248
e679f140 4249 wpa_s->disconnected = 1;
6fc6879b
JM
4250 if (wpa_s->drv_priv) {
4251 wpa_supplicant_deauthenticate(wpa_s,
4252 WLAN_REASON_DEAUTH_LEAVING);
4253
6fc6879b
JM
4254 wpa_drv_set_countermeasures(wpa_s, 0);
4255 wpa_clear_keys(wpa_s, NULL);
4256 }
4257
8e56d189 4258 wpa_supplicant_cleanup(wpa_s);
bd10d938 4259 wpas_p2p_deinit_iface(wpa_s);
ab28911d 4260
1f965e62 4261 wpas_ctrl_radio_work_flush(wpa_s);
202dec2a
JM
4262 radio_remove_interface(wpa_s);
4263
6fc6879b
JM
4264 if (wpa_s->drv_priv)
4265 wpa_drv_deinit(wpa_s);
2523ff6e
DS
4266
4267 if (notify)
4268 wpas_notify_iface_removed(wpa_s);
f0811516
DS
4269
4270 if (terminate)
4271 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
4272
4273 if (wpa_s->ctrl_iface) {
4274 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
4275 wpa_s->ctrl_iface = NULL;
4276 }
4277
603a3f34
JL
4278#ifdef CONFIG_MESH
4279 if (wpa_s->ifmsh) {
4280 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
4281 wpa_s->ifmsh = NULL;
4282 }
4283#endif /* CONFIG_MESH */
4284
f0811516
DS
4285 if (wpa_s->conf != NULL) {
4286 wpa_config_free(wpa_s->conf);
4287 wpa_s->conf = NULL;
4288 }
18e00b5e
JM
4289
4290 os_free(wpa_s);
6fc6879b
JM
4291}
4292
4293
4294/**
4295 * wpa_supplicant_add_iface - Add a new network interface
4296 * @global: Pointer to global data from wpa_supplicant_init()
4297 * @iface: Interface configuration options
1772d348 4298 * @parent: Parent interface or %NULL to assign new interface as parent
6fc6879b
JM
4299 * Returns: Pointer to the created interface or %NULL on failure
4300 *
4301 * This function is used to add new network interfaces for %wpa_supplicant.
4302 * This can be called before wpa_supplicant_run() to add interfaces before the
4303 * main event loop has been started. In addition, new interfaces can be added
4304 * dynamically while %wpa_supplicant is already running. This could happen,
4305 * e.g., when a hotplug network adapter is inserted.
4306 */
4307struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
1772d348
JM
4308 struct wpa_interface *iface,
4309 struct wpa_supplicant *parent)
6fc6879b
JM
4310{
4311 struct wpa_supplicant *wpa_s;
d27df100 4312 struct wpa_interface t_iface;
8e56d189 4313 struct wpa_ssid *ssid;
6fc6879b
JM
4314
4315 if (global == NULL || iface == NULL)
4316 return NULL;
4317
1772d348 4318 wpa_s = wpa_supplicant_alloc(parent);
6fc6879b
JM
4319 if (wpa_s == NULL)
4320 return NULL;
4321
d8222ae3
JM
4322 wpa_s->global = global;
4323
d27df100
JM
4324 t_iface = *iface;
4325 if (global->params.override_driver) {
4326 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
4327 "('%s' -> '%s')",
4328 iface->driver, global->params.override_driver);
4329 t_iface.driver = global->params.override_driver;
4330 }
4331 if (global->params.override_ctrl_interface) {
4332 wpa_printf(MSG_DEBUG, "Override interface parameter: "
4333 "ctrl_interface ('%s' -> '%s')",
4334 iface->ctrl_interface,
4335 global->params.override_ctrl_interface);
4336 t_iface.ctrl_interface =
4337 global->params.override_ctrl_interface;
4338 }
4339 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
4340 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
4341 iface->ifname);
df509539 4342 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
4343 return NULL;
4344 }
4345
21efc940
TB
4346 if (iface->p2p_mgmt == 0) {
4347 /* Notify the control interfaces about new iface */
4348 if (wpas_notify_iface_added(wpa_s)) {
4349 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
4350 return NULL;
4351 }
1bd3f426 4352
21efc940
TB
4353 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
4354 wpas_notify_network_added(wpa_s, ssid);
4355 }
8e56d189 4356
6fc6879b
JM
4357 wpa_s->next = global->ifaces;
4358 global->ifaces = wpa_s;
4359
f049052b 4360 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 4361 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b 4362
c3c4b3ed
JM
4363#ifdef CONFIG_P2P
4364 if (wpa_s->global->p2p == NULL &&
4365 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
4366 wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) < 0) {
4367 wpa_printf(MSG_INFO,
4368 "P2P: Failed to enable P2P Device interface");
4369 /* Try to continue without. P2P will be disabled. */
4370 }
4371#endif /* CONFIG_P2P */
4372
6fc6879b
JM
4373 return wpa_s;
4374}
4375
4376
4377/**
4378 * wpa_supplicant_remove_iface - Remove a network interface
4379 * @global: Pointer to global data from wpa_supplicant_init()
4380 * @wpa_s: Pointer to the network interface to be removed
4381 * Returns: 0 if interface was removed, -1 if interface was not found
4382 *
4383 * This function can be used to dynamically remove network interfaces from
4384 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
4385 * addition, this function is used to remove all remaining interfaces when
4386 * %wpa_supplicant is terminated.
4387 */
4388int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
4389 struct wpa_supplicant *wpa_s,
4390 int terminate)
6fc6879b
JM
4391{
4392 struct wpa_supplicant *prev;
5b78493f
MH
4393#ifdef CONFIG_MESH
4394 unsigned int mesh_if_created = wpa_s->mesh_if_created;
4395 char *ifname = NULL;
4396#endif /* CONFIG_MESH */
6fc6879b
JM
4397
4398 /* Remove interface from the global list of interfaces */
4399 prev = global->ifaces;
4400 if (prev == wpa_s) {
4401 global->ifaces = wpa_s->next;
4402 } else {
4403 while (prev && prev->next != wpa_s)
4404 prev = prev->next;
4405 if (prev == NULL)
4406 return -1;
4407 prev->next = wpa_s->next;
4408 }
4409
f049052b 4410 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 4411
5b78493f
MH
4412#ifdef CONFIG_MESH
4413 if (mesh_if_created) {
4414 ifname = os_strdup(wpa_s->ifname);
4415 if (ifname == NULL) {
4416 wpa_dbg(wpa_s, MSG_ERROR,
4417 "mesh: Failed to malloc ifname");
4418 return -1;
4419 }
4420 }
4421#endif /* CONFIG_MESH */
4422
b22128ef
JM
4423 if (global->p2p_group_formation == wpa_s)
4424 global->p2p_group_formation = NULL;
dbca75f8
JM
4425 if (global->p2p_invite_group == wpa_s)
4426 global->p2p_invite_group = NULL;
df509539 4427 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b 4428
5b78493f
MH
4429#ifdef CONFIG_MESH
4430 if (mesh_if_created) {
4431 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
4432 os_free(ifname);
4433 }
4434#endif /* CONFIG_MESH */
4435
6fc6879b
JM
4436 return 0;
4437}
4438
4439
cf83fb0b
PS
4440/**
4441 * wpa_supplicant_get_eap_mode - Get the current EAP mode
4442 * @wpa_s: Pointer to the network interface
4443 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
4444 */
4445const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
4446{
4447 const char *eapol_method;
4448
4449 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
4450 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
4451 return "NO-EAP";
4452 }
4453
4454 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
4455 if (eapol_method == NULL)
4456 return "UNKNOWN-EAP";
4457
4458 return eapol_method;
4459}
4460
4461
6fc6879b
JM
4462/**
4463 * wpa_supplicant_get_iface - Get a new network interface
4464 * @global: Pointer to global data from wpa_supplicant_init()
4465 * @ifname: Interface name
4466 * Returns: Pointer to the interface or %NULL if not found
4467 */
4468struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
4469 const char *ifname)
4470{
4471 struct wpa_supplicant *wpa_s;
4472
4473 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
4474 if (os_strcmp(wpa_s->ifname, ifname) == 0)
4475 return wpa_s;
4476 }
4477 return NULL;
4478}
4479
4480
50b16da1 4481#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
4482static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
4483{
4484 struct wpa_supplicant *wpa_s = ctx;
4485 if (wpa_s == NULL)
4486 return NULL;
4487 return wpa_s->ifname;
4488}
50b16da1 4489#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
4490
4491
6fc6879b
JM
4492/**
4493 * wpa_supplicant_init - Initialize %wpa_supplicant
4494 * @params: Parameters for %wpa_supplicant
4495 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
4496 *
4497 * This function is used to initialize %wpa_supplicant. After successful
4498 * initialization, the returned data pointer can be used to add and remove
4499 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
4500 */
4501struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
4502{
4503 struct wpa_global *global;
ac305589 4504 int ret, i;
6fc6879b
JM
4505
4506 if (params == NULL)
4507 return NULL;
4508
39e7d718
JM
4509#ifdef CONFIG_DRIVER_NDIS
4510 {
4511 void driver_ndis_init_ops(void);
4512 driver_ndis_init_ops();
4513 }
4514#endif /* CONFIG_DRIVER_NDIS */
4515
50b16da1 4516#ifndef CONFIG_NO_WPA_MSG
4f1495ae 4517 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 4518#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 4519
f4637fe0
JM
4520 if (params->wpa_debug_file_path)
4521 wpa_debug_open_file(params->wpa_debug_file_path);
4522 else
4523 wpa_debug_setup_stdout();
daa70d49
SL
4524 if (params->wpa_debug_syslog)
4525 wpa_debug_open_syslog();
4f68895e
JB
4526 if (params->wpa_debug_tracing) {
4527 ret = wpa_debug_open_linux_tracing();
4528 if (ret) {
4529 wpa_printf(MSG_ERROR,
4530 "Failed to enable trace logging");
4531 return NULL;
4532 }
4533 }
6fc6879b 4534
12760815 4535 ret = eap_register_methods();
6fc6879b
JM
4536 if (ret) {
4537 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
4538 if (ret == -2)
4539 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
4540 "the same EAP type.");
4541 return NULL;
4542 }
4543
4544 global = os_zalloc(sizeof(*global));
4545 if (global == NULL)
4546 return NULL;
b22128ef
JM
4547 dl_list_init(&global->p2p_srv_bonjour);
4548 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
4549 global->params.daemonize = params->daemonize;
4550 global->params.wait_for_monitor = params->wait_for_monitor;
4551 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
4552 if (params->pid_file)
4553 global->params.pid_file = os_strdup(params->pid_file);
4554 if (params->ctrl_interface)
4555 global->params.ctrl_interface =
4556 os_strdup(params->ctrl_interface);
29257565
JM
4557 if (params->ctrl_interface_group)
4558 global->params.ctrl_interface_group =
4559 os_strdup(params->ctrl_interface_group);
d27df100
JM
4560 if (params->override_driver)
4561 global->params.override_driver =
4562 os_strdup(params->override_driver);
4563 if (params->override_ctrl_interface)
4564 global->params.override_ctrl_interface =
4565 os_strdup(params->override_ctrl_interface);
6fc6879b
JM
4566 wpa_debug_level = global->params.wpa_debug_level =
4567 params->wpa_debug_level;
4568 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
4569 params->wpa_debug_show_keys;
4570 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
4571 params->wpa_debug_timestamp;
4572
f19858f5
JM
4573 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
4574
0456ea16 4575 if (eloop_init()) {
6fc6879b
JM
4576 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
4577 wpa_supplicant_deinit(global);
4578 return NULL;
4579 }
4580
38e24575 4581 random_init(params->entropy_file);
d47fa330 4582
6fc6879b
JM
4583 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
4584 if (global->ctrl_iface == NULL) {
4585 wpa_supplicant_deinit(global);
4586 return NULL;
4587 }
4588
dc461de4
WS
4589 if (wpas_notify_supplicant_initialized(global)) {
4590 wpa_supplicant_deinit(global);
4591 return NULL;
6fc6879b
JM
4592 }
4593
c5121837 4594 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
4595 global->drv_count++;
4596 if (global->drv_count == 0) {
4597 wpa_printf(MSG_ERROR, "No drivers enabled");
4598 wpa_supplicant_deinit(global);
4599 return NULL;
4600 }
faebdeaa 4601 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
ac305589
JM
4602 if (global->drv_priv == NULL) {
4603 wpa_supplicant_deinit(global);
4604 return NULL;
4605 }
ac305589 4606
9675ce35
JM
4607#ifdef CONFIG_WIFI_DISPLAY
4608 if (wifi_display_init(global) < 0) {
4609 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
4610 wpa_supplicant_deinit(global);
4611 return NULL;
4612 }
4613#endif /* CONFIG_WIFI_DISPLAY */
4614
6fc6879b
JM
4615 return global;
4616}
4617
4618
4619/**
4620 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
4621 * @global: Pointer to global data from wpa_supplicant_init()
4622 * Returns: 0 after successful event loop run, -1 on failure
4623 *
4624 * This function starts the main event loop and continues running as long as
4625 * there are any remaining events. In most cases, this function is running as
4626 * long as the %wpa_supplicant process in still in use.
4627 */
4628int wpa_supplicant_run(struct wpa_global *global)
4629{
4630 struct wpa_supplicant *wpa_s;
4631
4632 if (global->params.daemonize &&
4633 wpa_supplicant_daemon(global->params.pid_file))
4634 return -1;
4635
4636 if (global->params.wait_for_monitor) {
4637 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
4638 if (wpa_s->ctrl_iface)
4639 wpa_supplicant_ctrl_iface_wait(
4640 wpa_s->ctrl_iface);
4641 }
4642
0456ea16
JM
4643 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
4644 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
4645
4646 eloop_run();
4647
4648 return 0;
4649}
4650
4651
4652/**
4653 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
4654 * @global: Pointer to global data from wpa_supplicant_init()
4655 *
4656 * This function is called to deinitialize %wpa_supplicant and to free all
4657 * allocated resources. Remaining network interfaces will also be removed.
4658 */
4659void wpa_supplicant_deinit(struct wpa_global *global)
4660{
ac305589
JM
4661 int i;
4662
6fc6879b
JM
4663 if (global == NULL)
4664 return;
4665
9675ce35
JM
4666#ifdef CONFIG_WIFI_DISPLAY
4667 wifi_display_deinit(global);
4668#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 4669
6fc6879b 4670 while (global->ifaces)
df509539 4671 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
4672
4673 if (global->ctrl_iface)
4674 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
4675
4676 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
4677
4678 eap_peer_unregister_methods();
3ec97afe
JM
4679#ifdef CONFIG_AP
4680 eap_server_unregister_methods();
4681#endif /* CONFIG_AP */
6fc6879b 4682
c5121837 4683 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
4684 if (!global->drv_priv[i])
4685 continue;
c5121837 4686 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
4687 }
4688 os_free(global->drv_priv);
4689
d47fa330
JM
4690 random_deinit();
4691
6fc6879b
JM
4692 eloop_destroy();
4693
4694 if (global->params.pid_file) {
4695 os_daemonize_terminate(global->params.pid_file);
4696 os_free(global->params.pid_file);
4697 }
4698 os_free(global->params.ctrl_interface);
29257565 4699 os_free(global->params.ctrl_interface_group);
d27df100
JM
4700 os_free(global->params.override_driver);
4701 os_free(global->params.override_ctrl_interface);
6fc6879b 4702
af8a827b 4703 os_free(global->p2p_disallow_freq.range);
253f2e37 4704 os_free(global->p2p_go_avoid_freq.range);
01a57fe4 4705 os_free(global->add_psk);
6f3bc72b 4706
6fc6879b 4707 os_free(global);
daa70d49 4708 wpa_debug_close_syslog();
6fc6879b 4709 wpa_debug_close_file();
4f68895e 4710 wpa_debug_close_linux_tracing();
6fc6879b 4711}
611aea7d
JM
4712
4713
4714void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
4715{
849b5dc7
JM
4716 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
4717 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
4718 char country[3];
4719 country[0] = wpa_s->conf->country[0];
4720 country[1] = wpa_s->conf->country[1];
4721 country[2] = '\0';
4722 if (wpa_drv_set_country(wpa_s, country) < 0) {
4723 wpa_printf(MSG_ERROR, "Failed to set country code "
4724 "'%s'", country);
4725 }
4726 }
4727
306ae225
JM
4728 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
4729 wpas_init_ext_pw(wpa_s);
4730
611aea7d
JM
4731#ifdef CONFIG_WPS
4732 wpas_wps_update_config(wpa_s);
4733#endif /* CONFIG_WPS */
b22128ef 4734 wpas_p2p_update_config(wpa_s);
611aea7d
JM
4735 wpa_s->conf->changed_parameters = 0;
4736}
2f9c6aa6
JM
4737
4738
e1117c1c 4739void add_freq(int *freqs, int *num_freqs, int freq)
0fb337c1
JM
4740{
4741 int i;
4742
4743 for (i = 0; i < *num_freqs; i++) {
4744 if (freqs[i] == freq)
4745 return;
4746 }
4747
4748 freqs[*num_freqs] = freq;
4749 (*num_freqs)++;
4750}
4751
4752
4753static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
4754{
4755 struct wpa_bss *bss, *cbss;
4756 const int max_freqs = 10;
4757 int *freqs;
4758 int num_freqs = 0;
4759
faebdeaa 4760 freqs = os_calloc(max_freqs + 1, sizeof(int));
0fb337c1
JM
4761 if (freqs == NULL)
4762 return NULL;
4763
4764 cbss = wpa_s->current_bss;
4765
4766 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
4767 if (bss == cbss)
4768 continue;
4769 if (bss->ssid_len == cbss->ssid_len &&
4770 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
4771 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
4772 add_freq(freqs, &num_freqs, bss->freq);
4773 if (num_freqs == max_freqs)
4774 break;
4775 }
4776 }
4777
4778 if (num_freqs == 0) {
4779 os_free(freqs);
4780 freqs = NULL;
4781 }
4782
4783 return freqs;
4784}
4785
4786
4787void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
4788{
4789 int timeout;
4790 int count;
4791 int *freqs = NULL;
4792
6ac4b15e
JM
4793 wpas_connect_work_done(wpa_s);
4794
5fd9fb27
JM
4795 /*
4796 * Remove possible authentication timeout since the connection failed.
4797 */
4798 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
4799
c2805909
JM
4800 /*
4801 * There is no point in blacklisting the AP if this event is
4802 * generated based on local request to disconnect.
4803 */
4804 if (wpa_s->own_disconnect_req) {
4805 wpa_s->own_disconnect_req = 0;
4806 wpa_dbg(wpa_s, MSG_DEBUG,
4807 "Ignore connection failure due to local request to disconnect");
4808 return;
4809 }
0cdb93fe 4810 if (wpa_s->disconnected) {
0cdb93fe
JM
4811 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
4812 "indication since interface has been put into "
4813 "disconnected state");
4814 return;
4815 }
4816
0fb337c1
JM
4817 /*
4818 * Add the failed BSSID into the blacklist and speed up next scan
4819 * attempt if there could be other APs that could accept association.
4820 * The current blacklist count indicates how many times we have tried
4821 * connecting to this AP and multiple attempts mean that other APs are
4822 * either not available or has already been tried, so that we can start
4823 * increasing the delay here to avoid constant scanning.
4824 */
4825 count = wpa_blacklist_add(wpa_s, bssid);
4826 if (count == 1 && wpa_s->current_bss) {
4827 /*
4828 * This BSS was not in the blacklist before. If there is
4829 * another BSS available for the same ESS, we should try that
4830 * next. Otherwise, we may as well try this one once more
4831 * before allowing other, likely worse, ESSes to be considered.
4832 */
4833 freqs = get_bss_freqs_in_ess(wpa_s);
4834 if (freqs) {
f049052b
BG
4835 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
4836 "has been seen; try it next");
0fb337c1
JM
4837 wpa_blacklist_add(wpa_s, bssid);
4838 /*
4839 * On the next scan, go through only the known channels
4840 * used in this ESS based on previous scans to speed up
4841 * common load balancing use case.
4842 */
4843 os_free(wpa_s->next_scan_freqs);
4844 wpa_s->next_scan_freqs = freqs;
4845 }
4846 }
4847
f1a52633
JM
4848 /*
4849 * Add previous failure count in case the temporary blacklist was
4850 * cleared due to no other BSSes being available.
4851 */
4852 count += wpa_s->extra_blacklist_count;
4853
dd579704
JM
4854 if (count > 3 && wpa_s->current_ssid) {
4855 wpa_printf(MSG_DEBUG, "Continuous association failures - "
4856 "consider temporary network disabling");
b19c098e 4857 wpas_auth_failed(wpa_s, "CONN_FAILED");
dd579704
JM
4858 }
4859
0fb337c1
JM
4860 switch (count) {
4861 case 1:
4862 timeout = 100;
4863 break;
4864 case 2:
4865 timeout = 500;
4866 break;
4867 case 3:
4868 timeout = 1000;
4869 break;
f1a52633 4870 case 4:
0fb337c1 4871 timeout = 5000;
f1a52633
JM
4872 break;
4873 default:
4874 timeout = 10000;
4875 break;
0fb337c1
JM
4876 }
4877
f1a52633
JM
4878 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
4879 "ms", count, timeout);
4880
0fb337c1
JM
4881 /*
4882 * TODO: if more than one possible AP is available in scan results,
4883 * could try the other ones before requesting a new scan.
4884 */
4885 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
4886 1000 * (timeout % 1000));
4887}
22628eca
JM
4888
4889
4890int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
4891{
4892 return wpa_s->conf->ap_scan == 2 ||
4893 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
4894}
d2118814
JM
4895
4896
4897#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
4898int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
4899 struct wpa_ssid *ssid,
4900 const char *field,
4901 const char *value)
4902{
4903#ifdef IEEE8021X_EAPOL
4904 struct eap_peer_config *eap = &ssid->eap;
4905
4906 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
4907 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
4908 (const u8 *) value, os_strlen(value));
4909
4910 switch (wpa_supplicant_ctrl_req_from_string(field)) {
4911 case WPA_CTRL_REQ_EAP_IDENTITY:
4912 os_free(eap->identity);
4913 eap->identity = (u8 *) os_strdup(value);
4914 eap->identity_len = os_strlen(value);
4915 eap->pending_req_identity = 0;
4916 if (ssid == wpa_s->current_ssid)
4917 wpa_s->reassociate = 1;
4918 break;
4919 case WPA_CTRL_REQ_EAP_PASSWORD:
19c48da0 4920 bin_clear_free(eap->password, eap->password_len);
d2118814
JM
4921 eap->password = (u8 *) os_strdup(value);
4922 eap->password_len = os_strlen(value);
4923 eap->pending_req_password = 0;
4924 if (ssid == wpa_s->current_ssid)
4925 wpa_s->reassociate = 1;
4926 break;
4927 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
19c48da0 4928 bin_clear_free(eap->new_password, eap->new_password_len);
d2118814
JM
4929 eap->new_password = (u8 *) os_strdup(value);
4930 eap->new_password_len = os_strlen(value);
4931 eap->pending_req_new_password = 0;
4932 if (ssid == wpa_s->current_ssid)
4933 wpa_s->reassociate = 1;
4934 break;
4935 case WPA_CTRL_REQ_EAP_PIN:
19c48da0 4936 str_clear_free(eap->pin);
d2118814
JM
4937 eap->pin = os_strdup(value);
4938 eap->pending_req_pin = 0;
4939 if (ssid == wpa_s->current_ssid)
4940 wpa_s->reassociate = 1;
4941 break;
4942 case WPA_CTRL_REQ_EAP_OTP:
19c48da0 4943 bin_clear_free(eap->otp, eap->otp_len);
d2118814
JM
4944 eap->otp = (u8 *) os_strdup(value);
4945 eap->otp_len = os_strlen(value);
4946 os_free(eap->pending_req_otp);
4947 eap->pending_req_otp = NULL;
4948 eap->pending_req_otp_len = 0;
4949 break;
4950 case WPA_CTRL_REQ_EAP_PASSPHRASE:
19c48da0
JM
4951 str_clear_free(eap->private_key_passwd);
4952 eap->private_key_passwd = os_strdup(value);
d2118814
JM
4953 eap->pending_req_passphrase = 0;
4954 if (ssid == wpa_s->current_ssid)
4955 wpa_s->reassociate = 1;
4956 break;
a5d44ac0 4957 case WPA_CTRL_REQ_SIM:
19c48da0 4958 str_clear_free(eap->external_sim_resp);
a5d44ac0
JM
4959 eap->external_sim_resp = os_strdup(value);
4960 break;
d2118814
JM
4961 default:
4962 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
4963 return -1;
4964 }
4965
4966 return 0;
4967#else /* IEEE8021X_EAPOL */
4968 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
4969 return -1;
4970#endif /* IEEE8021X_EAPOL */
4971}
4972#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
4973
4974
4975int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
4976{
4977 int i;
4978 unsigned int drv_enc;
4979
44b9ea5b
JM
4980 if (wpa_s->p2p_mgmt)
4981 return 1; /* no normal network profiles on p2p_mgmt interface */
4982
349493bd
JM
4983 if (ssid == NULL)
4984 return 1;
4985
4986 if (ssid->disabled)
4987 return 1;
4988
4989 if (wpa_s && wpa_s->drv_capa_known)
4990 drv_enc = wpa_s->drv_enc;
4991 else
4992 drv_enc = (unsigned int) -1;
4993
4994 for (i = 0; i < NUM_WEP_KEYS; i++) {
4995 size_t len = ssid->wep_key_len[i];
4996 if (len == 0)
4997 continue;
4998 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
4999 continue;
5000 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5001 continue;
5002 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5003 continue;
5004 return 1; /* invalid WEP key */
5005 }
5006
9173b16f 5007 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
759ff2f0 5008 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk)
2518aad3
JM
5009 return 1;
5010
349493bd
JM
5011 return 0;
5012}
b9cfc09a
JJ
5013
5014
3f56a2b7
JM
5015int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5016{
5017#ifdef CONFIG_IEEE80211W
5018 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5019 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5020 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5021 /*
5022 * Driver does not support BIP -- ignore pmf=1 default
5023 * since the connection with PMF would fail and the
5024 * configuration does not require PMF to be enabled.
5025 */
5026 return NO_MGMT_FRAME_PROTECTION;
5027 }
5028
5029 return wpa_s->conf->pmf;
5030 }
5031
5032 return ssid->ieee80211w;
5033#else /* CONFIG_IEEE80211W */
5034 return NO_MGMT_FRAME_PROTECTION;
5035#endif /* CONFIG_IEEE80211W */
5036}
5037
5038
b9cfc09a
JJ
5039int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
5040{
5041 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
5042 return 1;
5043 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
5044 return 0;
5045 return -1;
5046}
00e5e3d5
JM
5047
5048
b19c098e 5049void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
00e5e3d5
JM
5050{
5051 struct wpa_ssid *ssid = wpa_s->current_ssid;
5052 int dur;
4e1eae1d 5053 struct os_reltime now;
00e5e3d5
JM
5054
5055 if (ssid == NULL) {
5056 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
5057 "SSID block");
5058 return;
5059 }
5060
5061 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
5062 return;
5063
5064 ssid->auth_failures++;
cbf41ca7
SL
5065
5066#ifdef CONFIG_P2P
5067 if (ssid->p2p_group &&
5068 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
5069 /*
5070 * Skip the wait time since there is a short timeout on the
5071 * connection to a P2P group.
5072 */
5073 return;
5074 }
5075#endif /* CONFIG_P2P */
5076
00e5e3d5
JM
5077 if (ssid->auth_failures > 50)
5078 dur = 300;
00e5e3d5 5079 else if (ssid->auth_failures > 10)
8a77f1be 5080 dur = 120;
00e5e3d5 5081 else if (ssid->auth_failures > 5)
8a77f1be
JM
5082 dur = 90;
5083 else if (ssid->auth_failures > 3)
5084 dur = 60;
5085 else if (ssid->auth_failures > 2)
00e5e3d5
JM
5086 dur = 30;
5087 else if (ssid->auth_failures > 1)
5088 dur = 20;
5089 else
5090 dur = 10;
5091
8a77f1be
JM
5092 if (ssid->auth_failures > 1 &&
5093 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
5094 dur += os_random() % (ssid->auth_failures * 10);
5095
4e1eae1d 5096 os_get_reltime(&now);
00e5e3d5
JM
5097 if (now.sec + dur <= ssid->disabled_until.sec)
5098 return;
5099
5100 ssid->disabled_until.sec = now.sec + dur;
5101
5102 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
b19c098e 5103 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
00e5e3d5 5104 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
b19c098e 5105 ssid->auth_failures, dur, reason);
00e5e3d5
JM
5106}
5107
5108
5109void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
5110 struct wpa_ssid *ssid, int clear_failures)
5111{
5112 if (ssid == NULL)
5113 return;
5114
5115 if (ssid->disabled_until.sec) {
5116 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
5117 "id=%d ssid=\"%s\"",
5118 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
5119 }
5120 ssid->disabled_until.sec = 0;
5121 ssid->disabled_until.usec = 0;
5122 if (clear_failures)
5123 ssid->auth_failures = 0;
5124}
6407f413
JM
5125
5126
5127int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
5128{
5129 size_t i;
5130
5131 if (wpa_s->disallow_aps_bssid == NULL)
5132 return 0;
5133
5134 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
5135 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
5136 bssid, ETH_ALEN) == 0)
5137 return 1;
5138 }
5139
5140 return 0;
5141}
5142
5143
5144int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
5145 size_t ssid_len)
5146{
5147 size_t i;
5148
5149 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
5150 return 0;
5151
5152 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
5153 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
5154 if (ssid_len == s->ssid_len &&
5155 os_memcmp(ssid, s->ssid, ssid_len) == 0)
5156 return 1;
5157 }
5158
5159 return 0;
5160}
9796a86c
JM
5161
5162
5163/**
5164 * wpas_request_connection - Request a new connection
5165 * @wpa_s: Pointer to the network interface
5166 *
5167 * This function is used to request a new connection to be found. It will mark
5168 * the interface to allow reassociation and request a new scan to find a
5169 * suitable network to connect to.
5170 */
5171void wpas_request_connection(struct wpa_supplicant *wpa_s)
5172{
5173 wpa_s->normal_scans = 0;
5214f4fa 5174 wpa_s->scan_req = NORMAL_SCAN_REQ;
9796a86c
JM
5175 wpa_supplicant_reinit_autoscan(wpa_s);
5176 wpa_s->extra_blacklist_count = 0;
5177 wpa_s->disconnected = 0;
5178 wpa_s->reassociate = 1;
5e24beae
MH
5179
5180 if (wpa_supplicant_fast_associate(wpa_s) != 1)
5181 wpa_supplicant_req_scan(wpa_s, 0, 0);
0c5f01fd
B
5182 else
5183 wpa_s->reattach = 0;
9796a86c 5184}
36b9883d
DG
5185
5186
a0c90bb0
IP
5187void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
5188 struct wpa_used_freq_data *freqs_data,
5189 unsigned int len)
5190{
5191 unsigned int i;
5192
5193 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
5194 len, title);
5195 for (i = 0; i < len; i++) {
5196 struct wpa_used_freq_data *cur = &freqs_data[i];
5197 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
5198 i, cur->freq, cur->flags);
5199 }
5200}
5201
5202
53c5dfc2
IP
5203/*
5204 * Find the operating frequencies of any of the virtual interfaces that
a0c90bb0
IP
5205 * are using the same radio as the current interface, and in addition, get
5206 * information about the interface types that are using the frequency.
53c5dfc2 5207 */
a0c90bb0
IP
5208int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
5209 struct wpa_used_freq_data *freqs_data,
5210 unsigned int len)
53c5dfc2 5211{
53c5dfc2
IP
5212 struct wpa_supplicant *ifs;
5213 u8 bssid[ETH_ALEN];
5214 int freq;
5215 unsigned int idx = 0, i;
5216
217cf499
JM
5217 wpa_dbg(wpa_s, MSG_DEBUG,
5218 "Determining shared radio frequencies (max len %u)", len);
a0c90bb0 5219 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
53c5dfc2 5220
0ad3b9c4
JM
5221 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
5222 radio_list) {
a0c90bb0
IP
5223 if (idx == len)
5224 break;
5225
53c5dfc2
IP
5226 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
5227 continue;
5228
5229 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
5230 ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
5231 freq = ifs->current_ssid->frequency;
5232 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
5233 freq = ifs->assoc_freq;
5234 else
5235 continue;
5236
5237 /* Hold only distinct freqs */
5238 for (i = 0; i < idx; i++)
a0c90bb0 5239 if (freqs_data[i].freq == freq)
53c5dfc2
IP
5240 break;
5241
5242 if (i == idx)
a0c90bb0
IP
5243 freqs_data[idx++].freq = freq;
5244
5245 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
5246 freqs_data[i].flags = ifs->current_ssid->p2p_group ?
5247 WPA_FREQ_USED_BY_P2P_CLIENT :
5248 WPA_FREQ_USED_BY_INFRA_STATION;
5249 }
53c5dfc2 5250 }
217cf499 5251
a0c90bb0 5252 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
53c5dfc2
IP
5253 return idx;
5254}
a0c90bb0
IP
5255
5256
5257/*
5258 * Find the operating frequencies of any of the virtual interfaces that
5259 * are using the same radio as the current interface.
5260 */
5261int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
5262 int *freq_array, unsigned int len)
5263{
5264 struct wpa_used_freq_data *freqs_data;
5265 int num, i;
5266
5267 os_memset(freq_array, 0, sizeof(int) * len);
5268
5269 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
5270 if (!freqs_data)
5271 return -1;
5272
5273 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
5274 for (i = 0; i < num; i++)
5275 freq_array[i] = freqs_data[i].freq;
5276
5277 os_free(freqs_data);
5278
5279 return num;
5280}
b361d580
AK
5281
5282
d89c0701
AK
5283static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
5284{
5285 struct rrm_data *rrm = data;
5286
5287 if (!rrm->notify_neighbor_rep) {
5288 wpa_printf(MSG_ERROR,
5289 "RRM: Unexpected neighbor report timeout");
5290 return;
5291 }
5292
5293 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
5294 rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
5295
5296 rrm->notify_neighbor_rep = NULL;
5297 rrm->neighbor_rep_cb_ctx = NULL;
5298}
5299
5300
b361d580
AK
5301/*
5302 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
5303 * @wpa_s: Pointer to wpa_supplicant
5304 */
5305void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
5306{
5307 wpa_s->rrm.rrm_used = 0;
d89c0701
AK
5308
5309 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
5310 NULL);
5311 if (wpa_s->rrm.notify_neighbor_rep)
5312 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
5313 wpa_s->rrm.next_neighbor_rep_token = 1;
5314}
5315
5316
5317/*
5318 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
5319 * @wpa_s: Pointer to wpa_supplicant
5320 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
5321 * @report_len: Length of neighbor report buffer
5322 */
5323void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
5324 const u8 *report, size_t report_len)
5325{
5326 struct wpabuf *neighbor_rep;
5327
5328 wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
5329 if (report_len < 1)
5330 return;
5331
5332 if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
5333 wpa_printf(MSG_DEBUG,
5334 "RRM: Discarding neighbor report with token %d (expected %d)",
5335 report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
5336 return;
5337 }
5338
5339 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
5340 NULL);
5341
5342 if (!wpa_s->rrm.notify_neighbor_rep) {
5343 wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
5344 return;
5345 }
5346
5347 /* skipping the first byte, which is only an id (dialog token) */
5348 neighbor_rep = wpabuf_alloc(report_len - 1);
5349 if (neighbor_rep == NULL)
5350 return;
5351 wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
5352 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
5353 report[0]);
5354 wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
5355 neighbor_rep);
5356 wpa_s->rrm.notify_neighbor_rep = NULL;
5357 wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
5358}
5359
5360
b09baf37
JM
5361#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
5362/* Workaround different, undefined for Windows, error codes used here */
5363#define ENOTCONN -1
5364#define EOPNOTSUPP -1
5365#define ECANCELED -1
5366#endif
5367
d89c0701
AK
5368/**
5369 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
5370 * @wpa_s: Pointer to wpa_supplicant
4c4b2305
AK
5371 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
5372 * is sent in the request.
d89c0701
AK
5373 * @cb: Callback function to be called once the requested report arrives, or
5374 * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
5375 * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
5376 * the requester's responsibility to free it.
5377 * In the latter case NULL will be sent in 'neighbor_rep'.
5378 * @cb_ctx: Context value to send the callback function
5379 * Returns: 0 in case of success, negative error code otherwise
5380 *
5381 * In case there is a previous request which has not been answered yet, the
5382 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
5383 * Request must contain a callback function.
d89c0701
AK
5384 */
5385int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
4c4b2305 5386 const struct wpa_ssid *ssid,
d89c0701
AK
5387 void (*cb)(void *ctx,
5388 struct wpabuf *neighbor_rep),
5389 void *cb_ctx)
5390{
5391 struct wpabuf *buf;
5392 const u8 *rrm_ie;
5393
5394 if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
5395 wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
5396 return -ENOTCONN;
5397 }
5398
5399 if (!wpa_s->rrm.rrm_used) {
5400 wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
5401 return -EOPNOTSUPP;
5402 }
5403
5404 rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
5405 WLAN_EID_RRM_ENABLED_CAPABILITIES);
5406 if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
5407 !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
5408 wpa_printf(MSG_DEBUG,
5409 "RRM: No network support for Neighbor Report.");
5410 return -EOPNOTSUPP;
5411 }
5412
5413 if (!cb) {
5414 wpa_printf(MSG_DEBUG,
5415 "RRM: Neighbor Report request must provide a callback.");
5416 return -EINVAL;
5417 }
5418
5419 /* Refuse if there's a live request */
5420 if (wpa_s->rrm.notify_neighbor_rep) {
5421 wpa_printf(MSG_DEBUG,
5422 "RRM: Currently handling previous Neighbor Report.");
5423 return -EBUSY;
5424 }
5425
4c4b2305
AK
5426 /* 3 = action category + action code + dialog token */
5427 buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0));
d89c0701
AK
5428 if (buf == NULL) {
5429 wpa_printf(MSG_DEBUG,
5430 "RRM: Failed to allocate Neighbor Report Request");
5431 return -ENOMEM;
5432 }
5433
5434 wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
4c4b2305 5435 (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
d89c0701
AK
5436 wpa_s->rrm.next_neighbor_rep_token);
5437
5438 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
5439 wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
5440 wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
4c4b2305
AK
5441 if (ssid) {
5442 wpabuf_put_u8(buf, WLAN_EID_SSID);
5443 wpabuf_put_u8(buf, ssid->ssid_len);
5444 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
5445 }
d89c0701
AK
5446
5447 wpa_s->rrm.next_neighbor_rep_token++;
5448
5449 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
5450 wpa_s->own_addr, wpa_s->bssid,
5451 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
5452 wpa_printf(MSG_DEBUG,
5453 "RRM: Failed to send Neighbor Report Request");
5454 wpabuf_free(buf);
5455 return -ECANCELED;
5456 }
5457
5458 wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
5459 wpa_s->rrm.notify_neighbor_rep = cb;
5460 eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
5461 wpas_rrm_neighbor_rep_timeout_handler,
5462 &wpa_s->rrm, NULL);
5463
5464 wpabuf_free(buf);
5465 return 0;
b361d580 5466}
70d1e728
AO
5467
5468
5469void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
5470 const u8 *src,
5471 const u8 *frame, size_t len,
5472 int rssi)
5473{
5474 struct wpabuf *buf;
5475 const struct rrm_link_measurement_request *req;
5476 struct rrm_link_measurement_report report;
5477
5478 if (wpa_s->wpa_state != WPA_COMPLETED) {
5479 wpa_printf(MSG_INFO,
5480 "RRM: Ignoring link measurement request. Not associated");
5481 return;
5482 }
5483
5484 if (!wpa_s->rrm.rrm_used) {
5485 wpa_printf(MSG_INFO,
5486 "RRM: Ignoring link measurement request. Not RRM network");
5487 return;
5488 }
5489
5490 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
5491 wpa_printf(MSG_INFO,
5492 "RRM: Measurement report failed. TX power insertion not supported");
5493 return;
5494 }
5495
5496 req = (const struct rrm_link_measurement_request *) frame;
5497 if (len < sizeof(*req)) {
5498 wpa_printf(MSG_INFO,
5499 "RRM: Link measurement report failed. Request too short");
5500 return;
5501 }
5502
5503 os_memset(&report, 0, sizeof(report));
5504 report.tpc.eid = WLAN_EID_TPC_REPORT;
5505 report.tpc.len = 2;
5506 report.rsni = 255; /* 255 indicates that RSNI is not available */
5507 report.dialog_token = req->dialog_token;
5508
5509 /*
5510 * It's possible to estimate RCPI based on RSSI in dBm. This
5511 * calculation will not reflect the correct value for high rates,
5512 * but it's good enough for Action frames which are transmitted
5513 * with up to 24 Mbps rates.
5514 */
5515 if (!rssi)
5516 report.rcpi = 255; /* not available */
5517 else if (rssi < -110)
5518 report.rcpi = 0;
5519 else if (rssi > 0)
5520 report.rcpi = 220;
5521 else
5522 report.rcpi = (rssi + 110) * 2;
5523
5524 /* action_category + action_code */
5525 buf = wpabuf_alloc(2 + sizeof(report));
5526 if (buf == NULL) {
5527 wpa_printf(MSG_ERROR,
5528 "RRM: Link measurement report failed. Buffer allocation failed");
5529 return;
5530 }
5531
5532 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
5533 wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
5534 wpabuf_put_data(buf, &report, sizeof(report));
5535 wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
5536 wpabuf_head(buf), wpabuf_len(buf));
5537
5538 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
5539 wpa_s->own_addr, wpa_s->bssid,
5540 wpabuf_head(buf), wpabuf_len(buf), 0)) {
5541 wpa_printf(MSG_ERROR,
5542 "RRM: Link measurement report failed. Send action failed");
5543 }
5544 wpabuf_free(buf);
5545}