]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
Use radio work for GAS requests
[thirdparty/hostap.git] / wpa_supplicant / wpa_supplicant.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA Supplicant
b1ae396f 3 * Copyright (c) 2003-2014, 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"
72044390 36#include "p2p/p2p.h"
6fc6879b
JM
37#include "blacklist.h"
38#include "wpas_glue.h"
116654ce 39#include "wps_supplicant.h"
11ef8d35 40#include "ibss_rsn.h"
c2a04078 41#include "sme.h"
04ea7b79 42#include "gas_query.h"
1f1b62a0 43#include "ap.h"
b22128ef 44#include "p2p_supplicant.h"
9675ce35 45#include "wifi_display.h"
8bac466b 46#include "notify.h"
60b94c98 47#include "bgscan.h"
7c865c68 48#include "autoscan.h"
83922c2d 49#include "bss.h"
9ba9fa07 50#include "scan.h"
24f6497c 51#include "offchannel.h"
cb418324 52#include "hs20_supplicant.h"
e27d20bb 53#include "wnm_sta.h"
6fc6879b
JM
54
55const char *wpa_supplicant_version =
56"wpa_supplicant v" VERSION_STR "\n"
b1ae396f 57"Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b
JM
58
59const char *wpa_supplicant_license =
331f89ff
JM
60"This software may be distributed under the terms of the BSD license.\n"
61"See README for more details.\n"
6fc6879b
JM
62#ifdef EAP_TLS_OPENSSL
63"\nThis product includes software developed by the OpenSSL Project\n"
64"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
65#endif /* EAP_TLS_OPENSSL */
66;
67
68#ifndef CONFIG_NO_STDOUT_DEBUG
69/* Long text divided into parts in order to fit in C89 strings size limits. */
70const char *wpa_supplicant_full_license1 =
331f89ff 71"";
6fc6879b 72const char *wpa_supplicant_full_license2 =
331f89ff 73"This software may be distributed under the terms of the BSD license.\n"
6fc6879b
JM
74"\n"
75"Redistribution and use in source and binary forms, with or without\n"
76"modification, are permitted provided that the following conditions are\n"
77"met:\n"
78"\n";
79const char *wpa_supplicant_full_license3 =
80"1. Redistributions of source code must retain the above copyright\n"
81" notice, this list of conditions and the following disclaimer.\n"
82"\n"
83"2. Redistributions in binary form must reproduce the above copyright\n"
84" notice, this list of conditions and the following disclaimer in the\n"
85" documentation and/or other materials provided with the distribution.\n"
86"\n";
87const char *wpa_supplicant_full_license4 =
88"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
89" names of its contributors may be used to endorse or promote products\n"
90" derived from this software without specific prior written permission.\n"
91"\n"
92"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
93"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
94"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
95"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
96const char *wpa_supplicant_full_license5 =
97"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
98"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
99"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
100"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
101"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
102"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
103"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
104"\n";
105#endif /* CONFIG_NO_STDOUT_DEBUG */
106
6fc6879b 107/* Configure default/group WEP keys for static WEP */
0194fedb 108int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
6fc6879b
JM
109{
110 int i, set = 0;
111
112 for (i = 0; i < NUM_WEP_KEYS; i++) {
113 if (ssid->wep_key_len[i] == 0)
114 continue;
115
116 set = 1;
0382097e 117 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
da64c266 118 i, i == ssid->wep_tx_keyidx, NULL, 0,
6fc6879b
JM
119 ssid->wep_key[i], ssid->wep_key_len[i]);
120 }
121
122 return set;
123}
124
125
6ea1f413
JM
126int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
127 struct wpa_ssid *ssid)
6fc6879b
JM
128{
129 u8 key[32];
130 size_t keylen;
71934751 131 enum wpa_alg alg;
6fc6879b
JM
132 u8 seq[6] = { 0 };
133
134 /* IBSS/WPA-None uses only one key (Group) for both receiving and
135 * sending unicast and multicast packets. */
136
d7dcba70 137 if (ssid->mode != WPAS_MODE_IBSS) {
f049052b
BG
138 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
139 "IBSS/ad-hoc) for WPA-None", ssid->mode);
6fc6879b
JM
140 return -1;
141 }
142
143 if (!ssid->psk_set) {
f049052b
BG
144 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
145 "WPA-None");
6fc6879b
JM
146 return -1;
147 }
148
149 switch (wpa_s->group_cipher) {
150 case WPA_CIPHER_CCMP:
151 os_memcpy(key, ssid->psk, 16);
152 keylen = 16;
153 alg = WPA_ALG_CCMP;
154 break;
eb7719ff
JM
155 case WPA_CIPHER_GCMP:
156 os_memcpy(key, ssid->psk, 16);
157 keylen = 16;
158 alg = WPA_ALG_GCMP;
159 break;
6fc6879b
JM
160 case WPA_CIPHER_TKIP:
161 /* WPA-None uses the same Michael MIC key for both TX and RX */
162 os_memcpy(key, ssid->psk, 16 + 8);
163 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
164 keylen = 32;
165 alg = WPA_ALG_TKIP;
166 break;
167 default:
f049052b
BG
168 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
169 "WPA-None", wpa_s->group_cipher);
6fc6879b
JM
170 return -1;
171 }
172
173 /* TODO: should actually remember the previously used seq#, both for TX
174 * and RX from each STA.. */
175
0382097e 176 return wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
6fc6879b
JM
177}
178
179
180static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
181{
182 struct wpa_supplicant *wpa_s = eloop_ctx;
183 const u8 *bssid = wpa_s->bssid;
a8e16edc 184 if (is_zero_ether_addr(bssid))
6fc6879b
JM
185 bssid = wpa_s->pending_bssid;
186 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
187 MAC2STR(bssid));
188 wpa_blacklist_add(wpa_s, bssid);
189 wpa_sm_notify_disassoc(wpa_s->wpa);
07783eaa 190 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6fc6879b 191 wpa_s->reassociate = 1;
48b84f18
BG
192
193 /*
194 * If we timed out, the AP or the local radio may be busy.
195 * So, wait a second until scanning again.
196 */
197 wpa_supplicant_req_scan(wpa_s, 1, 0);
6fc6879b
JM
198}
199
200
201/**
202 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
203 * @wpa_s: Pointer to wpa_supplicant data
204 * @sec: Number of seconds after which to time out authentication
205 * @usec: Number of microseconds after which to time out authentication
206 *
207 * This function is used to schedule a timeout for the current authentication
208 * attempt.
209 */
210void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
211 int sec, int usec)
212{
a2a535f8 213 if (wpa_s->conf->ap_scan == 0 &&
c2a04078 214 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
6fc6879b
JM
215 return;
216
f049052b 217 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
6fc6879b
JM
218 "%d usec", sec, usec);
219 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
220 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
221}
222
223
224/**
225 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
226 * @wpa_s: Pointer to wpa_supplicant data
227 *
228 * This function is used to cancel authentication timeout scheduled with
229 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
230 * been completed.
231 */
232void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
233{
f049052b 234 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
6fc6879b
JM
235 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
236 wpa_blacklist_del(wpa_s, wpa_s->bssid);
237}
238
239
240/**
241 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
242 * @wpa_s: Pointer to wpa_supplicant data
243 *
244 * This function is used to configure EAPOL state machine based on the selected
245 * authentication mode.
246 */
247void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
248{
249#ifdef IEEE8021X_EAPOL
250 struct eapol_config eapol_conf;
251 struct wpa_ssid *ssid = wpa_s->current_ssid;
252
53895c3b 253#ifdef CONFIG_IBSS_RSN
d7dcba70 254 if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
255 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
256 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
257 /*
258 * RSN IBSS authentication is per-STA and we can disable the
259 * per-BSSID EAPOL authentication.
260 */
261 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
262 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
263 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
264 return;
265 }
266#endif /* CONFIG_IBSS_RSN */
267
0a40ec6a
JM
268 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
269 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
270
6fc6879b
JM
271 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
272 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
273 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
274 else
275 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
276
277 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
278 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
279 eapol_conf.accept_802_1x_keys = 1;
280 eapol_conf.required_keys = 0;
281 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
282 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
283 }
284 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
285 eapol_conf.required_keys |=
286 EAPOL_REQUIRE_KEY_BROADCAST;
287 }
288
a2a535f8 289 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
6fc6879b 290 eapol_conf.required_keys = 0;
6fc6879b 291 }
a2a535f8 292 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
6fc6879b 293 eapol_conf.workaround = ssid->eap_workaround;
56586197
JM
294 eapol_conf.eap_disabled =
295 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
ad08c363
JM
296 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
297 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
a5d44ac0 298 eapol_conf.external_sim = wpa_s->conf->external_sim;
6fc6879b
JM
299 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
300#endif /* IEEE8021X_EAPOL */
301}
302
303
304/**
305 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
306 * @wpa_s: Pointer to wpa_supplicant data
307 * @ssid: Configuration data for the network
308 *
309 * This function is used to configure WPA state machine and related parameters
310 * to a mode where WPA is not enabled. This is called as part of the
311 * authentication configuration when the selected network does not use WPA.
312 */
313void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
314 struct wpa_ssid *ssid)
315{
316 int i;
317
ad08c363
JM
318 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
319 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
320 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
6fc6879b
JM
321 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
322 else
323 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
324 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
325 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
326 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
327 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
328 wpa_s->group_cipher = WPA_CIPHER_NONE;
329 wpa_s->mgmt_group_cipher = 0;
330
331 for (i = 0; i < NUM_WEP_KEYS; i++) {
332 if (ssid->wep_key_len[i] > 5) {
333 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
334 wpa_s->group_cipher = WPA_CIPHER_WEP104;
335 break;
336 } else if (ssid->wep_key_len[i] > 0) {
337 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
338 wpa_s->group_cipher = WPA_CIPHER_WEP40;
339 break;
340 }
341 }
342
343 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
344 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
345 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
346 wpa_s->pairwise_cipher);
347 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
348#ifdef CONFIG_IEEE80211W
349 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
350 wpa_s->mgmt_group_cipher);
351#endif /* CONFIG_IEEE80211W */
352
353 pmksa_cache_clear_current(wpa_s->wpa);
354}
355
356
6979582c 357void free_hw_features(struct wpa_supplicant *wpa_s)
6bf731e8
CL
358{
359 int i;
360 if (wpa_s->hw.modes == NULL)
361 return;
362
363 for (i = 0; i < wpa_s->hw.num_modes; i++) {
364 os_free(wpa_s->hw.modes[i].channels);
365 os_free(wpa_s->hw.modes[i].rates);
366 }
367
368 os_free(wpa_s->hw.modes);
369 wpa_s->hw.modes = NULL;
370}
371
372
6fc6879b
JM
373static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
374{
60b94c98 375 bgscan_deinit(wpa_s);
7c865c68 376 autoscan_deinit(wpa_s);
6fc6879b
JM
377 scard_deinit(wpa_s->scard);
378 wpa_s->scard = NULL;
379 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
380 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
381 l2_packet_deinit(wpa_s->l2);
382 wpa_s->l2 = NULL;
383 if (wpa_s->l2_br) {
384 l2_packet_deinit(wpa_s->l2_br);
385 wpa_s->l2_br = NULL;
386 }
387
6fc6879b 388 if (wpa_s->conf != NULL) {
8e56d189
JM
389 struct wpa_ssid *ssid;
390 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
391 wpas_notify_network_removed(wpa_s, ssid);
6fc6879b
JM
392 }
393
394 os_free(wpa_s->confname);
395 wpa_s->confname = NULL;
396
e6304cad
DS
397 os_free(wpa_s->confanother);
398 wpa_s->confanother = NULL;
399
6fc6879b
JM
400 wpa_sm_set_eapol(wpa_s->wpa, NULL);
401 eapol_sm_deinit(wpa_s->eapol);
402 wpa_s->eapol = NULL;
403
404 rsn_preauth_deinit(wpa_s->wpa);
405
281ff0aa
GP
406#ifdef CONFIG_TDLS
407 wpa_tdls_deinit(wpa_s->wpa);
408#endif /* CONFIG_TDLS */
409
6fc6879b
JM
410 pmksa_candidate_free(wpa_s->wpa);
411 wpa_sm_deinit(wpa_s->wpa);
412 wpa_s->wpa = NULL;
413 wpa_blacklist_clear(wpa_s);
414
83922c2d 415 wpa_bss_deinit(wpa_s);
6fc6879b 416
831770bf 417 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
6fc6879b
JM
418 wpa_supplicant_cancel_scan(wpa_s);
419 wpa_supplicant_cancel_auth_timeout(wpa_s);
01a17491
JM
420 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
421#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
422 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
423 wpa_s, NULL);
424#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
6fc6879b 425
116654ce 426 wpas_wps_deinit(wpa_s);
11ef8d35 427
1ff73338
JM
428 wpabuf_free(wpa_s->pending_eapol_rx);
429 wpa_s->pending_eapol_rx = NULL;
430
11ef8d35
JM
431#ifdef CONFIG_IBSS_RSN
432 ibss_rsn_deinit(wpa_s->ibss_rsn);
433 wpa_s->ibss_rsn = NULL;
434#endif /* CONFIG_IBSS_RSN */
c2a04078 435
e29853bb 436 sme_deinit(wpa_s);
2d5b792d
JM
437
438#ifdef CONFIG_AP
439 wpa_supplicant_ap_deinit(wpa_s);
440#endif /* CONFIG_AP */
b22128ef
JM
441
442#ifdef CONFIG_P2P
443 wpas_p2p_deinit(wpa_s);
444#endif /* CONFIG_P2P */
f47d639d 445
24f6497c
JM
446#ifdef CONFIG_OFFCHANNEL
447 offchannel_deinit(wpa_s);
448#endif /* CONFIG_OFFCHANNEL */
449
a4cba8f1
LC
450 wpa_supplicant_cancel_sched_scan(wpa_s);
451
f47d639d
JM
452 os_free(wpa_s->next_scan_freqs);
453 wpa_s->next_scan_freqs = NULL;
fee52342
JM
454
455 os_free(wpa_s->manual_scan_freqs);
456 wpa_s->manual_scan_freqs = NULL;
04ea7b79
JM
457
458 gas_query_deinit(wpa_s->gas);
459 wpa_s->gas = NULL;
6bf731e8
CL
460
461 free_hw_features(wpa_s);
d445a5cd
JM
462
463 os_free(wpa_s->bssid_filter);
464 wpa_s->bssid_filter = NULL;
b6668734 465
6407f413
JM
466 os_free(wpa_s->disallow_aps_bssid);
467 wpa_s->disallow_aps_bssid = NULL;
468 os_free(wpa_s->disallow_aps_ssid);
469 wpa_s->disallow_aps_ssid = NULL;
470
b6668734 471 wnm_bss_keep_alive_deinit(wpa_s);
e27d20bb
VK
472#ifdef CONFIG_WNM
473 wnm_deallocate_memory(wpa_s);
474#endif /* CONFIG_WNM */
306ae225
JM
475
476 ext_password_deinit(wpa_s->ext_pw);
477 wpa_s->ext_pw = NULL;
b1f12296
JM
478
479 wpabuf_free(wpa_s->last_gas_resp);
a297201d
JM
480
481 os_free(wpa_s->last_scan_res);
482 wpa_s->last_scan_res = NULL;
6fc6879b
JM
483}
484
485
486/**
487 * wpa_clear_keys - Clear keys configured for the driver
488 * @wpa_s: Pointer to wpa_supplicant data
489 * @addr: Previously used BSSID or %NULL if not available
490 *
491 * This function clears the encryption keys that has been previously configured
492 * for the driver.
493 */
494void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
495{
2f30cac3 496 int i, max;
6fc6879b 497
0e27f655 498#ifdef CONFIG_IEEE80211W
2f30cac3
JM
499 max = 6;
500#else /* CONFIG_IEEE80211W */
501 max = 4;
0e27f655 502#endif /* CONFIG_IEEE80211W */
2f30cac3
JM
503
504 /* MLME-DELETEKEYS.request */
505 for (i = 0; i < max; i++) {
506 if (wpa_s->keys_cleared & BIT(i))
507 continue;
508 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
509 NULL, 0);
510 }
511 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
512 !is_zero_ether_addr(addr)) {
6fc6879b
JM
513 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
514 0);
515 /* MLME-SETPROTECTION.request(None) */
516 wpa_drv_mlme_setprotection(
517 wpa_s, addr,
518 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
519 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
520 }
2f30cac3 521 wpa_s->keys_cleared = (u32) -1;
6fc6879b
JM
522}
523
524
525/**
526 * wpa_supplicant_state_txt - Get the connection state name as a text string
527 * @state: State (wpa_state; WPA_*)
528 * Returns: The state name as a printable text string
529 */
71934751 530const char * wpa_supplicant_state_txt(enum wpa_states state)
6fc6879b
JM
531{
532 switch (state) {
533 case WPA_DISCONNECTED:
534 return "DISCONNECTED";
535 case WPA_INACTIVE:
536 return "INACTIVE";
8401a6b0
JM
537 case WPA_INTERFACE_DISABLED:
538 return "INTERFACE_DISABLED";
6fc6879b
JM
539 case WPA_SCANNING:
540 return "SCANNING";
c2a04078
JM
541 case WPA_AUTHENTICATING:
542 return "AUTHENTICATING";
6fc6879b
JM
543 case WPA_ASSOCIATING:
544 return "ASSOCIATING";
545 case WPA_ASSOCIATED:
546 return "ASSOCIATED";
547 case WPA_4WAY_HANDSHAKE:
548 return "4WAY_HANDSHAKE";
549 case WPA_GROUP_HANDSHAKE:
550 return "GROUP_HANDSHAKE";
551 case WPA_COMPLETED:
552 return "COMPLETED";
553 default:
554 return "UNKNOWN";
555 }
556}
557
558
cfe53c9a
PS
559#ifdef CONFIG_BGSCAN
560
561static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
562{
31392709
HD
563 const char *name;
564
565 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
566 name = wpa_s->current_ssid->bgscan;
567 else
568 name = wpa_s->conf->bgscan;
569 if (name == NULL)
570 return;
0096c427
JM
571 if (wpas_driver_bss_selection(wpa_s))
572 return;
cfe53c9a
PS
573 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
574 return;
575
576 bgscan_deinit(wpa_s);
31392709
HD
577 if (wpa_s->current_ssid) {
578 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
cfe53c9a
PS
579 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
580 "bgscan");
581 /*
582 * Live without bgscan; it is only used as a roaming
583 * optimization, so the initial connection is not
584 * affected.
585 */
6409b7a7
YD
586 } else {
587 struct wpa_scan_results *scan_res;
cfe53c9a 588 wpa_s->bgscan_ssid = wpa_s->current_ssid;
6409b7a7
YD
589 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
590 0);
591 if (scan_res) {
592 bgscan_notify_scan(wpa_s, scan_res);
593 wpa_scan_results_free(scan_res);
594 }
595 }
cfe53c9a
PS
596 } else
597 wpa_s->bgscan_ssid = NULL;
598}
599
600
601static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
602{
603 if (wpa_s->bgscan_ssid != NULL) {
604 bgscan_deinit(wpa_s);
605 wpa_s->bgscan_ssid = NULL;
606 }
607}
608
609#endif /* CONFIG_BGSCAN */
610
611
7c865c68
TB
612static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
613{
99218999 614 if (autoscan_init(wpa_s, 0))
7c865c68
TB
615 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
616}
617
618
619static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
620{
621 autoscan_deinit(wpa_s);
622}
623
624
c3d12238
JM
625void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
626{
627 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
628 wpa_s->wpa_state == WPA_SCANNING) {
629 autoscan_deinit(wpa_s);
630 wpa_supplicant_start_autoscan(wpa_s);
631 }
632}
633
634
6fc6879b
JM
635/**
636 * wpa_supplicant_set_state - Set current connection state
637 * @wpa_s: Pointer to wpa_supplicant data
638 * @state: The new connection state
639 *
640 * This function is called whenever the connection state changes, e.g.,
641 * association is completed for WPA/WPA2 4-Way Handshake is started.
642 */
71934751
JM
643void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
644 enum wpa_states state)
6fc6879b 645{
27f43d8d
MH
646 enum wpa_states old_state = wpa_s->wpa_state;
647
f049052b
BG
648 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
649 wpa_supplicant_state_txt(wpa_s->wpa_state),
650 wpa_supplicant_state_txt(state));
6fc6879b 651
cb8564b1
DW
652 if (state != WPA_SCANNING)
653 wpa_supplicant_notify_scanning(wpa_s, 0);
654
6fc6879b 655 if (state == WPA_COMPLETED && wpa_s->new_connection) {
6fc6879b 656 struct wpa_ssid *ssid = wpa_s->current_ssid;
7d37a357 657#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6fc6879b 658 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
1cfc6787
JM
659 MACSTR " completed [id=%d id_str=%s]",
660 MAC2STR(wpa_s->bssid),
6fc6879b
JM
661 ssid ? ssid->id : -1,
662 ssid && ssid->id_str ? ssid->id_str : "");
663#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
00e5e3d5 664 wpas_clear_temp_disabled(wpa_s, ssid, 1);
f1a52633 665 wpa_s->extra_blacklist_count = 0;
6fc6879b 666 wpa_s->new_connection = 0;
6fc6879b 667 wpa_drv_set_operstate(wpa_s, 1);
99ac2913
FF
668#ifndef IEEE8021X_EAPOL
669 wpa_drv_set_supp_port(wpa_s, 1);
670#endif /* IEEE8021X_EAPOL */
17a4734d 671 wpa_s->after_wps = 0;
4d9fb08d 672 wpa_s->known_wps_freq = 0;
b22128ef
JM
673#ifdef CONFIG_P2P
674 wpas_p2p_completed(wpa_s);
675#endif /* CONFIG_P2P */
c3701c66
RM
676
677 sme_sched_obss_scan(wpa_s, 1);
6fc6879b
JM
678 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
679 state == WPA_ASSOCIATED) {
680 wpa_s->new_connection = 1;
681 wpa_drv_set_operstate(wpa_s, 0);
99ac2913
FF
682#ifndef IEEE8021X_EAPOL
683 wpa_drv_set_supp_port(wpa_s, 0);
684#endif /* IEEE8021X_EAPOL */
c3701c66 685 sme_sched_obss_scan(wpa_s, 0);
6fc6879b
JM
686 }
687 wpa_s->wpa_state = state;
27f43d8d 688
cfe53c9a
PS
689#ifdef CONFIG_BGSCAN
690 if (state == WPA_COMPLETED)
691 wpa_supplicant_start_bgscan(wpa_s);
37271232 692 else if (state < WPA_ASSOCIATED)
cfe53c9a
PS
693 wpa_supplicant_stop_bgscan(wpa_s);
694#endif /* CONFIG_BGSCAN */
695
7c865c68
TB
696 if (state == WPA_AUTHENTICATING)
697 wpa_supplicant_stop_autoscan(wpa_s);
698
699 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
700 wpa_supplicant_start_autoscan(wpa_s);
701
5bbf9f10 702 if (wpa_s->wpa_state != old_state) {
27f43d8d 703 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
5bbf9f10
PS
704
705 if (wpa_s->wpa_state == WPA_COMPLETED ||
706 old_state == WPA_COMPLETED)
707 wpas_notify_auth_changed(wpa_s);
708 }
6fc6879b
JM
709}
710
711
1a1bf008
JM
712void wpa_supplicant_terminate_proc(struct wpa_global *global)
713{
714 int pending = 0;
715#ifdef CONFIG_WPS
716 struct wpa_supplicant *wpa_s = global->ifaces;
717 while (wpa_s) {
ab41595f 718 struct wpa_supplicant *next = wpa_s->next;
20625e97
JM
719#ifdef CONFIG_P2P
720 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
721 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
722 wpas_p2p_disconnect(wpa_s);
723#endif /* CONFIG_P2P */
1a1bf008
JM
724 if (wpas_wps_terminate_pending(wpa_s) == 1)
725 pending = 1;
ab41595f 726 wpa_s = next;
1a1bf008
JM
727 }
728#endif /* CONFIG_WPS */
729 if (pending)
730 return;
731 eloop_terminate();
732}
733
734
0456ea16 735static void wpa_supplicant_terminate(int sig, void *signal_ctx)
6fc6879b 736{
0456ea16 737 struct wpa_global *global = signal_ctx;
1a1bf008 738 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
739}
740
741
b22128ef 742void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
6fc6879b 743{
71934751 744 enum wpa_states old_state = wpa_s->wpa_state;
27f43d8d 745
6fc6879b
JM
746 wpa_s->pairwise_cipher = 0;
747 wpa_s->group_cipher = 0;
748 wpa_s->mgmt_group_cipher = 0;
749 wpa_s->key_mgmt = 0;
8401a6b0 750 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
99218999 751 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
27f43d8d
MH
752
753 if (wpa_s->wpa_state != old_state)
754 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
6fc6879b
JM
755}
756
757
758/**
759 * wpa_supplicant_reload_configuration - Reload configuration data
760 * @wpa_s: Pointer to wpa_supplicant data
761 * Returns: 0 on success or -1 if configuration parsing failed
762 *
763 * This function can be used to request that the configuration data is reloaded
764 * (e.g., after configuration file change). This function is reloading
765 * configuration only for one interface, so this may need to be called multiple
766 * times if %wpa_supplicant is controlling multiple interfaces and all
767 * interfaces need reconfiguration.
768 */
769int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
770{
771 struct wpa_config *conf;
772 int reconf_ctrl;
8bac466b
JM
773 int old_ap_scan;
774
6fc6879b
JM
775 if (wpa_s->confname == NULL)
776 return -1;
e6304cad 777 conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
778 if (conf == NULL) {
779 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
780 "file '%s' - exiting", wpa_s->confname);
781 return -1;
782 }
e6304cad
DS
783 wpa_config_read(wpa_s->confanother, conf);
784
611aea7d 785 conf->changed_parameters = (unsigned int) -1;
6fc6879b
JM
786
787 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
788 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
789 os_strcmp(conf->ctrl_interface,
790 wpa_s->conf->ctrl_interface) != 0);
791
792 if (reconf_ctrl && wpa_s->ctrl_iface) {
793 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
794 wpa_s->ctrl_iface = NULL;
795 }
796
797 eapol_sm_invalidate_cached_session(wpa_s->eapol);
7b7ce8aa
JM
798 if (wpa_s->current_ssid) {
799 wpa_supplicant_deauthenticate(wpa_s,
800 WLAN_REASON_DEAUTH_LEAVING);
801 }
8bac466b 802
6fc6879b
JM
803 /*
804 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
805 * pkcs11_engine_path, pkcs11_module_path.
806 */
56586197 807 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
6fc6879b
JM
808 /*
809 * Clear forced success to clear EAP state for next
810 * authentication.
811 */
812 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
813 }
814 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
815 wpa_sm_set_config(wpa_s->wpa, NULL);
d8a790b9 816 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
6fc6879b
JM
817 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
818 rsn_preauth_deinit(wpa_s->wpa);
8bac466b
JM
819
820 old_ap_scan = wpa_s->conf->ap_scan;
6fc6879b
JM
821 wpa_config_free(wpa_s->conf);
822 wpa_s->conf = conf;
8bac466b
JM
823 if (old_ap_scan != wpa_s->conf->ap_scan)
824 wpas_notify_ap_scan_changed(wpa_s);
825
6fc6879b
JM
826 if (reconf_ctrl)
827 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
828
611aea7d
JM
829 wpa_supplicant_update_config(wpa_s);
830
6fc6879b 831 wpa_supplicant_clear_status(wpa_s);
349493bd 832 if (wpa_supplicant_enabled_networks(wpa_s)) {
43a38635
JM
833 wpa_s->reassociate = 1;
834 wpa_supplicant_req_scan(wpa_s, 0, 0);
835 }
f049052b 836 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
6fc6879b
JM
837 return 0;
838}
839
840
0456ea16 841static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
6fc6879b 842{
0456ea16 843 struct wpa_global *global = signal_ctx;
6fc6879b 844 struct wpa_supplicant *wpa_s;
6fc6879b 845 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
f049052b
BG
846 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
847 sig);
6fc6879b 848 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
1a1bf008 849 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
850 }
851 }
852}
853
854
6fc6879b
JM
855static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
856 struct wpa_ssid *ssid,
857 struct wpa_ie_data *ie)
858{
859 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
860 if (ret) {
861 if (ret == -2) {
862 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
863 "from association info");
864 }
865 return -1;
866 }
867
f049052b
BG
868 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
869 "cipher suites");
6fc6879b
JM
870 if (!(ie->group_cipher & ssid->group_cipher)) {
871 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
872 "cipher 0x%x (mask 0x%x) - reject",
873 ie->group_cipher, ssid->group_cipher);
874 return -1;
875 }
876 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
877 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
878 "cipher 0x%x (mask 0x%x) - reject",
879 ie->pairwise_cipher, ssid->pairwise_cipher);
880 return -1;
881 }
882 if (!(ie->key_mgmt & ssid->key_mgmt)) {
883 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
884 "management 0x%x (mask 0x%x) - reject",
885 ie->key_mgmt, ssid->key_mgmt);
886 return -1;
887 }
888
889#ifdef CONFIG_IEEE80211W
0b60b0aa 890 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
62d49803
JM
891 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
892 wpa_s->conf->pmf : ssid->ieee80211w) ==
893 MGMT_FRAME_PROTECTION_REQUIRED) {
6fc6879b
JM
894 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
895 "that does not support management frame protection - "
896 "reject");
897 return -1;
898 }
899#endif /* CONFIG_IEEE80211W */
900
901 return 0;
902}
903
904
905/**
906 * wpa_supplicant_set_suites - Set authentication and encryption parameters
907 * @wpa_s: Pointer to wpa_supplicant data
908 * @bss: Scan results for the selected BSS, or %NULL if not available
909 * @ssid: Configuration data for the selected network
910 * @wpa_ie: Buffer for the WPA/RSN IE
911 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
912 * used buffer length in case the functions returns success.
913 * Returns: 0 on success or -1 on failure
914 *
915 * This function is used to configure authentication and encryption parameters
916 * based on the network configuration and scan result for the selected BSS (if
917 * available).
918 */
919int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
6fa81a3b 920 struct wpa_bss *bss, struct wpa_ssid *ssid,
6fc6879b
JM
921 u8 *wpa_ie, size_t *wpa_ie_len)
922{
923 struct wpa_ie_data ie;
924 int sel, proto;
925 const u8 *bss_wpa, *bss_rsn;
926
927 if (bss) {
6fa81a3b
JM
928 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
929 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
6fc6879b
JM
930 } else
931 bss_wpa = bss_rsn = NULL;
932
933 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
934 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
935 (ie.group_cipher & ssid->group_cipher) &&
936 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
937 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 938 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
6fc6879b
JM
939 proto = WPA_PROTO_RSN;
940 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
941 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
942 (ie.group_cipher & ssid->group_cipher) &&
943 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
944 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 945 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
6fc6879b
JM
946 proto = WPA_PROTO_WPA;
947 } else if (bss) {
948 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
949 return -1;
950 } else {
951 if (ssid->proto & WPA_PROTO_RSN)
952 proto = WPA_PROTO_RSN;
953 else
954 proto = WPA_PROTO_WPA;
955 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
956 os_memset(&ie, 0, sizeof(ie));
957 ie.group_cipher = ssid->group_cipher;
958 ie.pairwise_cipher = ssid->pairwise_cipher;
959 ie.key_mgmt = ssid->key_mgmt;
960#ifdef CONFIG_IEEE80211W
961 ie.mgmt_group_cipher =
70f8cc8e 962 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
6fc6879b
JM
963 WPA_CIPHER_AES_128_CMAC : 0;
964#endif /* CONFIG_IEEE80211W */
f049052b
BG
965 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
966 "based on configuration");
6fc6879b
JM
967 } else
968 proto = ie.proto;
969 }
970
f049052b
BG
971 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
972 "pairwise %d key_mgmt %d proto %d",
973 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
6fc6879b
JM
974#ifdef CONFIG_IEEE80211W
975 if (ssid->ieee80211w) {
f049052b
BG
976 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
977 ie.mgmt_group_cipher);
6fc6879b
JM
978 }
979#endif /* CONFIG_IEEE80211W */
980
64fa840a 981 wpa_s->wpa_proto = proto;
6fc6879b
JM
982 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
983 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
984 !!(ssid->proto & WPA_PROTO_RSN));
985
986 if (bss || !wpa_s->ap_ies_from_associnfo) {
987 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
988 bss_wpa ? 2 + bss_wpa[1] : 0) ||
989 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
990 bss_rsn ? 2 + bss_rsn[1] : 0))
991 return -1;
992 }
993
994 sel = ie.group_cipher & ssid->group_cipher;
edbd2a19
JM
995 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
996 if (wpa_s->group_cipher < 0) {
f049052b
BG
997 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
998 "cipher");
6fc6879b
JM
999 return -1;
1000 }
edbd2a19
JM
1001 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1002 wpa_cipher_txt(wpa_s->group_cipher));
6fc6879b
JM
1003
1004 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
edbd2a19
JM
1005 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1006 if (wpa_s->pairwise_cipher < 0) {
f049052b
BG
1007 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1008 "cipher");
6fc6879b
JM
1009 return -1;
1010 }
edbd2a19
JM
1011 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1012 wpa_cipher_txt(wpa_s->pairwise_cipher));
6fc6879b
JM
1013
1014 sel = ie.key_mgmt & ssid->key_mgmt;
c10347f2
JM
1015#ifdef CONFIG_SAE
1016 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1017 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1018#endif /* CONFIG_SAE */
6fc6879b
JM
1019 if (0) {
1020#ifdef CONFIG_IEEE80211R
1021 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1022 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
f049052b 1023 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
6fc6879b
JM
1024 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1025 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
f049052b 1026 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
6fc6879b 1027#endif /* CONFIG_IEEE80211R */
c10347f2
JM
1028#ifdef CONFIG_SAE
1029 } else if (sel & WPA_KEY_MGMT_SAE) {
1030 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1031 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1032 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1033 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1034 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1035#endif /* CONFIG_SAE */
56586197
JM
1036#ifdef CONFIG_IEEE80211W
1037 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1038 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
f049052b 1039 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1040 "WPA: using KEY_MGMT 802.1X with SHA256");
1041 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1042 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
f049052b 1043 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1044 "WPA: using KEY_MGMT PSK with SHA256");
1045#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
1046 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1047 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
f049052b 1048 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
6fc6879b
JM
1049 } else if (sel & WPA_KEY_MGMT_PSK) {
1050 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
f049052b 1051 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
6fc6879b
JM
1052 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1053 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
f049052b 1054 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
6fc6879b 1055 } else {
f049052b
BG
1056 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1057 "authenticated key management type");
6fc6879b
JM
1058 return -1;
1059 }
1060
1061 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1062 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1063 wpa_s->pairwise_cipher);
1064 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1065
1066#ifdef CONFIG_IEEE80211W
1067 sel = ie.mgmt_group_cipher;
62d49803
JM
1068 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1069 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
0b60b0aa 1070 !(ie.capabilities & WPA_CAPABILITY_MFPC))
6fc6879b
JM
1071 sel = 0;
1072 if (sel & WPA_CIPHER_AES_128_CMAC) {
1073 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
f049052b 1074 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
6fc6879b
JM
1075 "AES-128-CMAC");
1076 } else {
1077 wpa_s->mgmt_group_cipher = 0;
f049052b 1078 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
6fc6879b
JM
1079 }
1080 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1081 wpa_s->mgmt_group_cipher);
62d49803
JM
1082 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1083 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1084 wpa_s->conf->pmf : ssid->ieee80211w));
6fc6879b
JM
1085#endif /* CONFIG_IEEE80211W */
1086
1087 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
f049052b 1088 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
6fc6879b
JM
1089 return -1;
1090 }
1091
0bf927a0 1092 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
6fc6879b 1093 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
7d232e23
ZC
1094#ifndef CONFIG_NO_PBKDF2
1095 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1096 ssid->passphrase) {
1097 u8 psk[PMK_LEN];
986de33d
JM
1098 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1099 4096, psk, PMK_LEN);
7d232e23
ZC
1100 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1101 psk, PMK_LEN);
1102 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1103 }
1104#endif /* CONFIG_NO_PBKDF2 */
9173b16f
JM
1105#ifdef CONFIG_EXT_PASSWORD
1106 if (ssid->ext_psk) {
1107 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1108 ssid->ext_psk);
1109 char pw_str[64 + 1];
1110 u8 psk[PMK_LEN];
1111
1112 if (pw == NULL) {
1113 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1114 "found from external storage");
1115 return -1;
1116 }
1117
1118 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1119 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1120 "PSK length %d in external storage",
1121 (int) wpabuf_len(pw));
1122 ext_password_free(pw);
1123 return -1;
1124 }
1125
1126 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1127 pw_str[wpabuf_len(pw)] = '\0';
1128
1129#ifndef CONFIG_NO_PBKDF2
1130 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1131 {
986de33d
JM
1132 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1133 4096, psk, PMK_LEN);
9173b16f
JM
1134 os_memset(pw_str, 0, sizeof(pw_str));
1135 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1136 "external passphrase)",
1137 psk, PMK_LEN);
1138 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1139 } else
1140#endif /* CONFIG_NO_PBKDF2 */
1141 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1142 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1143 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1144 "Invalid PSK hex string");
1145 os_memset(pw_str, 0, sizeof(pw_str));
1146 ext_password_free(pw);
1147 return -1;
1148 }
1149 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1150 } else {
1151 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1152 "PSK available");
1153 os_memset(pw_str, 0, sizeof(pw_str));
1154 ext_password_free(pw);
1155 return -1;
1156 }
1157
1158 os_memset(pw_str, 0, sizeof(pw_str));
1159 ext_password_free(pw);
1160 }
1161#endif /* CONFIG_EXT_PASSWORD */
7d232e23 1162 } else
6fc6879b
JM
1163 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1164
1165 return 0;
1166}
1167
1168
8cd6b7bc 1169static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
03e47c9c 1170{
8cd6b7bc 1171 *pos = 0x00;
03e47c9c 1172
8cd6b7bc
JB
1173 switch (idx) {
1174 case 0: /* Bits 0-7 */
1175 break;
1176 case 1: /* Bits 8-15 */
1177 break;
1178 case 2: /* Bits 16-23 */
1179#ifdef CONFIG_WNM
1180 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1181 *pos |= 0x08; /* Bit 19 - BSS Transition */
1182#endif /* CONFIG_WNM */
1183 break;
1184 case 3: /* Bits 24-31 */
1185#ifdef CONFIG_WNM
1186 *pos |= 0x02; /* Bit 25 - SSID List */
1187#endif /* CONFIG_WNM */
03e47c9c 1188#ifdef CONFIG_INTERWORKING
8cd6b7bc
JB
1189 if (wpa_s->conf->interworking)
1190 *pos |= 0x80; /* Bit 31 - Interworking */
03e47c9c 1191#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1192 break;
1193 case 4: /* Bits 32-39 */
56f5af48 1194#ifdef CONFIG_INTERWORKING
429dd9af
JM
1195 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1196 *pos |= 0x01; /* Bit 32 - QoS Map */
56f5af48 1197#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1198 break;
1199 case 5: /* Bits 40-47 */
1200 break;
1201 case 6: /* Bits 48-55 */
1202 break;
1203 }
1204}
03e47c9c 1205
03e47c9c 1206
8cd6b7bc
JB
1207int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1208{
1209 u8 *pos = buf;
1210 u8 len = 4, i;
1211
1212 if (len < wpa_s->extended_capa_len)
1213 len = wpa_s->extended_capa_len;
03e47c9c
JM
1214
1215 *pos++ = WLAN_EID_EXT_CAPAB;
8cd6b7bc
JB
1216 *pos++ = len;
1217 for (i = 0; i < len; i++, pos++) {
1218 wpas_ext_capab_byte(wpa_s, pos, i);
1219
1220 if (i < wpa_s->extended_capa_len) {
1221 *pos &= ~wpa_s->extended_capa_mask[i];
1222 *pos |= wpa_s->extended_capa[i];
1223 }
1224 }
03e47c9c 1225
3db5439a
JM
1226 while (len > 0 && buf[1 + len] == 0) {
1227 len--;
1228 buf[1] = len;
1229 }
1230 if (len == 0)
1231 return 0;
1232
1233 return 2 + len;
03e47c9c
JM
1234}
1235
1236
6fc6879b
JM
1237/**
1238 * wpa_supplicant_associate - Request association
1239 * @wpa_s: Pointer to wpa_supplicant data
1240 * @bss: Scan results for the selected BSS, or %NULL if not available
1241 * @ssid: Configuration data for the selected network
1242 *
1243 * This function is used to request %wpa_supplicant to associate with a BSS.
1244 */
1245void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
6fa81a3b 1246 struct wpa_bss *bss, struct wpa_ssid *ssid)
6fc6879b 1247{
5f3a6aa0 1248 u8 wpa_ie[200];
6fc6879b 1249 size_t wpa_ie_len;
8bac466b 1250 int use_crypt, ret, i, bssid_changed;
abd9fafa 1251 int algs = WPA_AUTH_ALG_OPEN;
4848a38d 1252 unsigned int cipher_pairwise, cipher_group;
6fc6879b
JM
1253 struct wpa_driver_associate_params params;
1254 int wep_keys_set = 0;
6fc6879b 1255 int assoc_failed = 0;
8bac466b 1256 struct wpa_ssid *old_ssid;
80e8a5ee
BG
1257#ifdef CONFIG_HT_OVERRIDES
1258 struct ieee80211_ht_capabilities htcaps;
1259 struct ieee80211_ht_capabilities htcaps_mask;
1260#endif /* CONFIG_HT_OVERRIDES */
6fc6879b 1261
78177a00
JM
1262#ifdef CONFIG_IBSS_RSN
1263 ibss_rsn_deinit(wpa_s->ibss_rsn);
1264 wpa_s->ibss_rsn = NULL;
1265#endif /* CONFIG_IBSS_RSN */
1266
2c5d725c
JM
1267 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1268 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
1269#ifdef CONFIG_AP
1270 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
1271 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1272 "mode");
1581b38b
JM
1273 return;
1274 }
8c981d17
DW
1275 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1276 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
1277 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1278 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
1279 return;
1280 }
8f770587 1281 wpa_s->current_bss = bss;
1581b38b 1282#else /* CONFIG_AP */
f049052b
BG
1283 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1284 "the build");
1581b38b
JM
1285#endif /* CONFIG_AP */
1286 return;
1287 }
1288
52c9e6f3 1289#ifdef CONFIG_TDLS
95cb2d88
JM
1290 if (bss)
1291 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1292 bss->ie_len);
52c9e6f3
JM
1293#endif /* CONFIG_TDLS */
1294
5cc4d64b
JM
1295 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1296 ssid->mode == IEEE80211_MODE_INFRA) {
c2a04078
JM
1297 sme_authenticate(wpa_s, bss, ssid);
1298 return;
1299 }
1300
0c80427d 1301 os_memset(&params, 0, sizeof(params));
6fc6879b 1302 wpa_s->reassociate = 0;
22628eca 1303 if (bss && !wpas_driver_bss_selection(wpa_s)) {
6fc6879b 1304#ifdef CONFIG_IEEE80211R
6fa81a3b 1305 const u8 *ie, *md = NULL;
6fc6879b 1306#endif /* CONFIG_IEEE80211R */
6fc6879b
JM
1307 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1308 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
6fa81a3b 1309 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
8bac466b 1310 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
6fc6879b
JM
1311 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1312 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
8bac466b
JM
1313 if (bssid_changed)
1314 wpas_notify_bssid_changed(wpa_s);
6fc6879b 1315#ifdef CONFIG_IEEE80211R
6fa81a3b 1316 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
6fc6879b
JM
1317 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1318 md = ie + 2;
e7846b68 1319 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
91a05482
JM
1320 if (md) {
1321 /* Prepare for the next transition */
76b7981d 1322 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
91a05482 1323 }
6fc6879b 1324#endif /* CONFIG_IEEE80211R */
24c23d1b
JM
1325#ifdef CONFIG_WPS
1326 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1327 wpa_s->conf->ap_scan == 2 &&
1328 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1329 /* Use ap_scan==1 style network selection to find the network
1330 */
4115303b 1331 wpa_s->scan_req = MANUAL_SCAN_REQ;
24c23d1b
JM
1332 wpa_s->reassociate = 1;
1333 wpa_supplicant_req_scan(wpa_s, 0, 0);
1334 return;
1335#endif /* CONFIG_WPS */
6fc6879b
JM
1336 } else {
1337 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1338 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1339 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1340 }
a4cba8f1 1341 wpa_supplicant_cancel_sched_scan(wpa_s);
6fc6879b
JM
1342 wpa_supplicant_cancel_scan(wpa_s);
1343
1344 /* Starting new association, so clear the possibly used WPA IE from the
1345 * previous association. */
1346 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1347
1348#ifdef IEEE8021X_EAPOL
1349 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1350 if (ssid->leap) {
1351 if (ssid->non_leap == 0)
abd9fafa 1352 algs = WPA_AUTH_ALG_LEAP;
6fc6879b 1353 else
abd9fafa 1354 algs |= WPA_AUTH_ALG_LEAP;
6fc6879b
JM
1355 }
1356 }
1357#endif /* IEEE8021X_EAPOL */
f049052b 1358 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
6fc6879b 1359 if (ssid->auth_alg) {
abd9fafa 1360 algs = ssid->auth_alg;
f049052b
BG
1361 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1362 "0x%x", algs);
6fc6879b 1363 }
6fc6879b 1364
6fa81a3b
JM
1365 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1366 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 1367 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 1368 int try_opportunistic;
6e202021
JM
1369 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1370 wpa_s->conf->okc :
1371 ssid->proactive_key_caching) &&
6fc6879b
JM
1372 (ssid->proto & WPA_PROTO_RSN);
1373 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
b2a12c4f 1374 ssid, try_opportunistic) == 0)
6fc6879b
JM
1375 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1376 wpa_ie_len = sizeof(wpa_ie);
1377 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1378 wpa_ie, &wpa_ie_len)) {
f049052b
BG
1379 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1380 "key management and encryption suites");
6fc6879b
JM
1381 return;
1382 }
a3f7e518
JM
1383 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1384 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1385 /*
1386 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1387 * use non-WPA since the scan results did not indicate that the
1388 * AP is using WPA or WPA2.
1389 */
1390 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1391 wpa_ie_len = 0;
1392 wpa_s->wpa_proto = 0;
0bf927a0 1393 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
6fc6879b
JM
1394 wpa_ie_len = sizeof(wpa_ie);
1395 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1396 wpa_ie, &wpa_ie_len)) {
f049052b
BG
1397 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1398 "key management and encryption suites (no "
1399 "scan results)");
6fc6879b
JM
1400 return;
1401 }
ad08c363
JM
1402#ifdef CONFIG_WPS
1403 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
1404 struct wpabuf *wps_ie;
1405 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
ad08c363
JM
1406 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1407 wpa_ie_len = wpabuf_len(wps_ie);
1408 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
1409 } else
1410 wpa_ie_len = 0;
ad08c363
JM
1411 wpabuf_free(wps_ie);
1412 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d
JM
1413 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1414 params.wps = WPS_MODE_PRIVACY;
1415 else
1416 params.wps = WPS_MODE_OPEN;
cf546f1a 1417 wpa_s->wpa_proto = 0;
ad08c363 1418#endif /* CONFIG_WPS */
6fc6879b
JM
1419 } else {
1420 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1421 wpa_ie_len = 0;
cf546f1a 1422 wpa_s->wpa_proto = 0;
6fc6879b
JM
1423 }
1424
5f3a6aa0
JM
1425#ifdef CONFIG_P2P
1426 if (wpa_s->global->p2p) {
1427 u8 *pos;
1428 size_t len;
1429 int res;
5f3a6aa0
JM
1430 pos = wpa_ie + wpa_ie_len;
1431 len = sizeof(wpa_ie) - wpa_ie_len;
b8a8d677
JM
1432 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1433 ssid->p2p_group);
5f3a6aa0
JM
1434 if (res >= 0)
1435 wpa_ie_len += res;
1436 }
72044390
JM
1437
1438 wpa_s->cross_connect_disallowed = 0;
1439 if (bss) {
1440 struct wpabuf *p2p;
1441 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1442 if (p2p) {
1443 wpa_s->cross_connect_disallowed =
1444 p2p_get_cross_connect_disallowed(p2p);
1445 wpabuf_free(p2p);
f049052b
BG
1446 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1447 "connection",
1448 wpa_s->cross_connect_disallowed ?
1449 "disallows" : "allows");
72044390
JM
1450 }
1451 }
5f3a6aa0
JM
1452#endif /* CONFIG_P2P */
1453
cb418324 1454#ifdef CONFIG_HS20
55a2df43 1455 if (is_hs20_network(wpa_s, ssid, bss)) {
cb418324
JM
1456 struct wpabuf *hs20;
1457 hs20 = wpabuf_alloc(20);
1458 if (hs20) {
1459 wpas_hs20_add_indication(hs20);
1460 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1461 wpabuf_len(hs20));
1462 wpa_ie_len += wpabuf_len(hs20);
1463 wpabuf_free(hs20);
1464 }
1465 }
1466#endif /* CONFIG_HS20 */
1467
8b3b803a
AH
1468 /*
1469 * Workaround: Add Extended Capabilities element only if the AP
1470 * included this element in Beacon/Probe Response frames. Some older
1471 * APs seem to have interoperability issues if this element is
1472 * included, so while the standard may require us to include the
1473 * element in all cases, it is justifiable to skip it to avoid
1474 * interoperability issues.
1475 */
1476 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
1477 u8 ext_capab[10];
1478 int ext_capab_len;
1479 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1480 if (ext_capab_len > 0) {
1481 u8 *pos = wpa_ie;
1482 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1483 pos += 2 + pos[1];
1484 os_memmove(pos + ext_capab_len, pos,
1485 wpa_ie_len - (pos - wpa_ie));
1486 wpa_ie_len += ext_capab_len;
1487 os_memcpy(pos, ext_capab, ext_capab_len);
1488 }
92cbcf91 1489 }
92cbcf91 1490
6fc6879b
JM
1491 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1492 use_crypt = 1;
4848a38d
JM
1493 cipher_pairwise = wpa_s->pairwise_cipher;
1494 cipher_group = wpa_s->group_cipher;
6fc6879b
JM
1495 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1496 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1497 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1498 use_crypt = 0;
1499 if (wpa_set_wep_keys(wpa_s, ssid)) {
1500 use_crypt = 1;
1501 wep_keys_set = 1;
1502 }
1503 }
ad08c363
JM
1504 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1505 use_crypt = 0;
6fc6879b
JM
1506
1507#ifdef IEEE8021X_EAPOL
1508 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1509 if ((ssid->eapol_flags &
1510 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1511 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1512 !wep_keys_set) {
1513 use_crypt = 0;
1514 } else {
1515 /* Assume that dynamic WEP-104 keys will be used and
1516 * set cipher suites in order for drivers to expect
1517 * encryption. */
4848a38d 1518 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
1519 }
1520 }
1521#endif /* IEEE8021X_EAPOL */
1522
1523 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1524 /* Set the key before (and later after) association */
1525 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1526 }
1527
6fc6879b 1528 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 1529 if (bss) {
6fa81a3b
JM
1530 params.ssid = bss->ssid;
1531 params.ssid_len = bss->ssid_len;
f15854d1
JM
1532 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1533 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1534 MACSTR " freq=%u MHz based on scan results "
1535 "(bssid_set=%d)",
1536 MAC2STR(bss->bssid), bss->freq,
1537 ssid->bssid_set);
22628eca
JM
1538 params.bssid = bss->bssid;
1539 params.freq = bss->freq;
1540 }
6fc6879b
JM
1541 } else {
1542 params.ssid = ssid->ssid;
1543 params.ssid_len = ssid->ssid_len;
1544 }
9e2af29f
NC
1545
1546 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1547 wpa_s->conf->ap_scan == 2) {
1548 params.bssid = ssid->bssid;
1549 params.fixed_bssid = 1;
1550 }
1551
d7dcba70
JM
1552 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1553 params.freq == 0)
6fc6879b
JM
1554 params.freq = ssid->frequency; /* Initial channel for IBSS */
1555 params.wpa_ie = wpa_ie;
1556 params.wpa_ie_len = wpa_ie_len;
1557 params.pairwise_suite = cipher_pairwise;
1558 params.group_suite = cipher_group;
4848a38d 1559 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 1560 params.wpa_proto = wpa_s->wpa_proto;
6fc6879b
JM
1561 params.auth_alg = algs;
1562 params.mode = ssid->mode;
1f6c0ab8 1563 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
1564 for (i = 0; i < NUM_WEP_KEYS; i++) {
1565 if (ssid->wep_key_len[i])
1566 params.wep_key[i] = ssid->wep_key[i];
1567 params.wep_key_len[i] = ssid->wep_key_len[i];
1568 }
1569 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1570
c2a04078 1571 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
4848a38d
JM
1572 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
1573 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
1574 params.passphrase = ssid->passphrase;
1575 if (ssid->psk_set)
1576 params.psk = ssid->psk;
1577 }
1578
36b15723
JM
1579 params.drop_unencrypted = use_crypt;
1580
6fc6879b 1581#ifdef CONFIG_IEEE80211W
62d49803
JM
1582 params.mgmt_frame_protection =
1583 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1584 wpa_s->conf->pmf : ssid->ieee80211w;
1585 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 1586 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
1587 struct wpa_ie_data ie;
1588 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1589 ie.capabilities &
1590 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
1591 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1592 "MFP: require MFP");
97d3497e
JM
1593 params.mgmt_frame_protection =
1594 MGMT_FRAME_PROTECTION_REQUIRED;
1595 }
1596 }
6fc6879b
JM
1597#endif /* CONFIG_IEEE80211W */
1598
ffad8858 1599 params.p2p = ssid->p2p_group;
6e3f4b89 1600
eea2fd9e
JM
1601 if (wpa_s->parent->set_sta_uapsd)
1602 params.uapsd = wpa_s->parent->sta_uapsd;
1603 else
1604 params.uapsd = -1;
1605
80e8a5ee
BG
1606#ifdef CONFIG_HT_OVERRIDES
1607 os_memset(&htcaps, 0, sizeof(htcaps));
1608 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1609 params.htcaps = (u8 *) &htcaps;
1610 params.htcaps_mask = (u8 *) &htcaps_mask;
1611 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1612#endif /* CONFIG_HT_OVERRIDES */
1613
8567866d
JJ
1614#ifdef CONFIG_P2P
1615 /*
1616 * If multi-channel concurrency is not supported, check for any
1617 * frequency conflict. In case of any frequency conflict, remove the
1618 * least prioritized connection.
1619 */
1620 if (wpa_s->num_multichan_concurrent < 2) {
1621 int freq = wpa_drv_shared_freq(wpa_s);
1622 if (freq > 0 && freq != params.freq) {
1623 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)",
1624 freq, params.freq);
1625 if (wpas_p2p_handle_frequency_conflicts(wpa_s,
1626 params.freq,
1627 ssid) < 0)
1628 return;
1629 }
1630 }
1631#endif /* CONFIG_P2P */
1632
17fbb751 1633 ret = wpa_drv_associate(wpa_s, &params);
6fc6879b
JM
1634 if (ret < 0) {
1635 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1636 "failed");
871f4dd0
JM
1637 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1638 /*
1639 * The driver is known to mean what is saying, so we
1640 * can stop right here; the association will not
1641 * succeed.
1642 */
1643 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 1644 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
1645 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1646 return;
1647 }
6fc6879b
JM
1648 /* try to continue anyway; new association will be tried again
1649 * after timeout */
1650 assoc_failed = 1;
1651 }
1652
1653 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1654 /* Set the key after the association just in case association
1655 * cleared the previously configured key. */
1656 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1657 /* No need to timeout authentication since there is no key
1658 * management. */
1659 wpa_supplicant_cancel_auth_timeout(wpa_s);
1660 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 1661#ifdef CONFIG_IBSS_RSN
d7dcba70 1662 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
1663 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1664 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1665 /*
1666 * RSN IBSS authentication is per-STA and we can disable the
1667 * per-BSSID authentication.
1668 */
1669 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 1670#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
1671 } else {
1672 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
1673 int timeout = 60;
1674
1675 if (assoc_failed) {
1676 /* give IBSS a bit more time */
d7dcba70 1677 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
1678 } else if (wpa_s->conf->ap_scan == 1) {
1679 /* give IBSS a bit more time */
d7dcba70 1680 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 1681 }
6fc6879b
JM
1682 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1683 }
1684
66562e9c
JM
1685 if (wep_keys_set &&
1686 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
1687 /* Set static WEP keys again */
1688 wpa_set_wep_keys(wpa_s, ssid);
1689 }
1690
1691 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1692 /*
1693 * Do not allow EAP session resumption between different
1694 * network configurations.
1695 */
1696 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1697 }
8bac466b 1698 old_ssid = wpa_s->current_ssid;
6fc6879b 1699 wpa_s->current_ssid = ssid;
8f770587 1700 wpa_s->current_bss = bss;
6fc6879b
JM
1701 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1702 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
1703 if (old_ssid != wpa_s->current_ssid)
1704 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
1705}
1706
1707
09f58c09
JM
1708static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1709 const u8 *addr)
1710{
1711 struct wpa_ssid *old_ssid;
1712
1713 wpa_clear_keys(wpa_s, addr);
09f58c09 1714 old_ssid = wpa_s->current_ssid;
0d30cc24 1715 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
1716 wpa_sm_set_config(wpa_s->wpa, NULL);
1717 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1718 if (old_ssid != wpa_s->current_ssid)
1719 wpas_notify_network_changed(wpa_s);
1720 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1721}
1722
1723
6fc6879b
JM
1724/**
1725 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1726 * @wpa_s: Pointer to wpa_supplicant data
1727 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1728 *
073ab58f 1729 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
1730 * current AP.
1731 */
1732void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1733 int reason_code)
1734{
1735 u8 *addr = NULL;
ef48ff94 1736 union wpa_event_data event;
42d23547 1737 int zero_addr = 0;
8bac466b 1738
42d23547
JM
1739 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1740 " pending_bssid=" MACSTR " reason=%d state=%s",
1741 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1742 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1743
1744 if (!is_zero_ether_addr(wpa_s->bssid))
1745 addr = wpa_s->bssid;
1746 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1747 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1748 wpa_s->wpa_state == WPA_ASSOCIATING))
1749 addr = wpa_s->pending_bssid;
1750 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1751 /*
1752 * When using driver-based BSS selection, we may not know the
1753 * BSSID with which we are currently trying to associate. We
1754 * need to notify the driver of this disconnection even in such
1755 * a case, so use the all zeros address here.
1756 */
6fc6879b 1757 addr = wpa_s->bssid;
42d23547
JM
1758 zero_addr = 1;
1759 }
1760
7b44ff2c
SD
1761#ifdef CONFIG_TDLS
1762 wpa_tdls_teardown_peers(wpa_s->wpa);
1763#endif /* CONFIG_TDLS */
1764
42d23547
JM
1765 if (addr) {
1766 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94
JM
1767 os_memset(&event, 0, sizeof(event));
1768 event.deauth_info.reason_code = (u16) reason_code;
1769 event.deauth_info.locally_generated = 1;
1770 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
1771 if (zero_addr)
1772 addr = NULL;
6fc6879b 1773 }
09f58c09
JM
1774
1775 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
1776}
1777
dca1a511
DS
1778static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1779 struct wpa_ssid *ssid)
1780{
1781 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1782 return;
1783
1784 ssid->disabled = 0;
1785 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1786 wpas_notify_network_enabled_changed(wpa_s, ssid);
1787
1788 /*
1789 * Try to reassociate since there is no current configuration and a new
1790 * network was made available.
1791 */
d2592497 1792 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
1793 wpa_s->reassociate = 1;
1794}
1795
6fc6879b 1796
86b89452
WS
1797/**
1798 * wpa_supplicant_enable_network - Mark a configured network as enabled
1799 * @wpa_s: wpa_supplicant structure for a network interface
1800 * @ssid: wpa_ssid structure for a configured network or %NULL
1801 *
1802 * Enables the specified network or all networks if no network specified.
1803 */
1804void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1805 struct wpa_ssid *ssid)
1806{
86b89452 1807 if (ssid == NULL) {
14f79078
JM
1808 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1809 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
1810 } else
1811 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 1812
d2592497 1813 if (wpa_s->reassociate && !wpa_s->disconnected) {
dca1a511
DS
1814 if (wpa_s->sched_scanning) {
1815 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1816 "new network to scan filters");
1817 wpa_supplicant_cancel_sched_scan(wpa_s);
1818 }
86b89452 1819
dad153d1
JM
1820 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1821 wpa_supplicant_req_scan(wpa_s, 0, 0);
86b89452
WS
1822 }
1823}
1824
1825
1826/**
1827 * wpa_supplicant_disable_network - Mark a configured network as disabled
1828 * @wpa_s: wpa_supplicant structure for a network interface
1829 * @ssid: wpa_ssid structure for a configured network or %NULL
1830 *
1831 * Disables the specified network or all networks if no network specified.
1832 */
1833void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1834 struct wpa_ssid *ssid)
1835{
1836 struct wpa_ssid *other_ssid;
1837 int was_disabled;
1838
1839 if (ssid == NULL) {
725fc39e
DS
1840 if (wpa_s->sched_scanning)
1841 wpa_supplicant_cancel_sched_scan(wpa_s);
1842
4dac0245
JM
1843 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1844 other_ssid = other_ssid->next) {
86b89452 1845 was_disabled = other_ssid->disabled;
4dac0245
JM
1846 if (was_disabled == 2)
1847 continue; /* do not change persistent P2P group
1848 * data */
86b89452
WS
1849
1850 other_ssid->disabled = 1;
1851
1852 if (was_disabled != other_ssid->disabled)
1853 wpas_notify_network_enabled_changed(
1854 wpa_s, other_ssid);
86b89452
WS
1855 }
1856 if (wpa_s->current_ssid)
07783eaa 1857 wpa_supplicant_deauthenticate(
86b89452 1858 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
4dac0245 1859 } else if (ssid->disabled != 2) {
86b89452 1860 if (ssid == wpa_s->current_ssid)
07783eaa 1861 wpa_supplicant_deauthenticate(
86b89452
WS
1862 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1863
1864 was_disabled = ssid->disabled;
1865
1866 ssid->disabled = 1;
1867
725fc39e 1868 if (was_disabled != ssid->disabled) {
86b89452 1869 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
1870 if (wpa_s->sched_scanning) {
1871 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1872 "to remove network from filters");
1873 wpa_supplicant_cancel_sched_scan(wpa_s);
1874 wpa_supplicant_req_scan(wpa_s, 0, 0);
1875 }
1876 }
86b89452
WS
1877 }
1878}
1879
1880
1881/**
1882 * wpa_supplicant_select_network - Attempt association with a network
1883 * @wpa_s: wpa_supplicant structure for a network interface
1884 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1885 */
1886void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1887 struct wpa_ssid *ssid)
1888{
1889
1890 struct wpa_ssid *other_ssid;
d93dfbd5 1891 int disconnected = 0;
86b89452 1892
d93dfbd5 1893 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
07783eaa 1894 wpa_supplicant_deauthenticate(
86b89452 1895 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
1896 disconnected = 1;
1897 }
86b89452 1898
00e5e3d5
JM
1899 if (ssid)
1900 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1901
86b89452
WS
1902 /*
1903 * Mark all other networks disabled or mark all networks enabled if no
1904 * network specified.
1905 */
4dac0245
JM
1906 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1907 other_ssid = other_ssid->next) {
86b89452 1908 int was_disabled = other_ssid->disabled;
4dac0245
JM
1909 if (was_disabled == 2)
1910 continue; /* do not change persistent P2P group data */
86b89452
WS
1911
1912 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
1913 if (was_disabled && !other_ssid->disabled)
1914 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
1915
1916 if (was_disabled != other_ssid->disabled)
1917 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 1918 }
2a6f78fb
JJ
1919
1920 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1921 /* We are already associated with the selected network */
1922 wpa_printf(MSG_DEBUG, "Already associated with the "
1923 "selected network - do nothing");
1924 return;
1925 }
1926
25a8f9e3 1927 if (ssid) {
96efeeb6 1928 wpa_s->current_ssid = ssid;
25a8f9e3
JM
1929 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1930 }
7dcdcfd6 1931 wpa_s->connect_without_scan = NULL;
86b89452
WS
1932 wpa_s->disconnected = 0;
1933 wpa_s->reassociate = 1;
cecdddc1
PS
1934
1935 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1936 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
86b89452 1937
a1641d26
JM
1938 if (ssid)
1939 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
1940}
1941
1942
bdec7ee5
MS
1943/**
1944 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
1945 * @wpa_s: wpa_supplicant structure for a network interface
1946 * @pkcs11_engine_path: PKCS #11 engine path or NULL
1947 * @pkcs11_module_path: PKCS #11 module path or NULL
1948 * Returns: 0 on success; -1 on failure
1949 *
1950 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
1951 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
1952 * module path fails the paths will be reset to the default value (NULL).
1953 */
1954int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
1955 const char *pkcs11_engine_path,
1956 const char *pkcs11_module_path)
1957{
1958 char *pkcs11_engine_path_copy = NULL;
1959 char *pkcs11_module_path_copy = NULL;
1960
1961 if (pkcs11_engine_path != NULL) {
1962 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
1963 if (pkcs11_engine_path_copy == NULL)
1964 return -1;
1965 }
1966 if (pkcs11_module_path != NULL) {
1967 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
1968 if (pkcs11_engine_path_copy == NULL) {
1969 os_free(pkcs11_engine_path_copy);
1970 return -1;
1971 }
1972 }
1973
1974 os_free(wpa_s->conf->pkcs11_engine_path);
1975 os_free(wpa_s->conf->pkcs11_module_path);
1976 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
1977 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
1978
1979 wpa_sm_set_eapol(wpa_s->wpa, NULL);
1980 eapol_sm_deinit(wpa_s->eapol);
1981 wpa_s->eapol = NULL;
1982 if (wpa_supplicant_init_eapol(wpa_s)) {
1983 /* Error -> Reset paths to the default value (NULL) once. */
1984 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
1985 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
1986 NULL);
1987
1988 return -1;
1989 }
1990 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
1991
1992 return 0;
1993}
1994
1995
86b89452
WS
1996/**
1997 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1998 * @wpa_s: wpa_supplicant structure for a network interface
1999 * @ap_scan: AP scan mode
2000 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
2001 *
2002 */
2003int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
2004{
2005
2006 int old_ap_scan;
2007
2008 if (ap_scan < 0 || ap_scan > 2)
2009 return -1;
2010
48f8e036
DS
2011#ifdef ANDROID
2012 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
2013 wpa_s->wpa_state >= WPA_ASSOCIATING &&
2014 wpa_s->wpa_state < WPA_COMPLETED) {
2015 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
2016 "associating", wpa_s->conf->ap_scan, ap_scan);
2017 return 0;
2018 }
2019#endif /* ANDROID */
2020
86b89452
WS
2021 old_ap_scan = wpa_s->conf->ap_scan;
2022 wpa_s->conf->ap_scan = ap_scan;
2023
2024 if (old_ap_scan != wpa_s->conf->ap_scan)
2025 wpas_notify_ap_scan_changed(wpa_s);
2026
2027 return 0;
2028}
2029
2030
78633c37
SL
2031/**
2032 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
2033 * @wpa_s: wpa_supplicant structure for a network interface
2034 * @expire_age: Expiration age in seconds
2035 * Returns: 0 if succeed or -1 if expire_age has an invalid value
2036 *
2037 */
2038int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
2039 unsigned int bss_expire_age)
2040{
2041 if (bss_expire_age < 10) {
2042 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
2043 bss_expire_age);
2044 return -1;
2045 }
2046 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
2047 bss_expire_age);
2048 wpa_s->conf->bss_expiration_age = bss_expire_age;
2049
2050 return 0;
2051}
2052
2053
2054/**
2055 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2056 * @wpa_s: wpa_supplicant structure for a network interface
2057 * @expire_count: number of scans after which an unseen BSS is reclaimed
2058 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2059 *
2060 */
2061int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2062 unsigned int bss_expire_count)
2063{
2064 if (bss_expire_count < 1) {
2065 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2066 bss_expire_count);
2067 return -1;
2068 }
2069 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2070 bss_expire_count);
2071 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2072
2073 return 0;
2074}
2075
2076
c6e86b63
MA
2077/**
2078 * wpa_supplicant_set_scan_interval - Set scan interval
2079 * @wpa_s: wpa_supplicant structure for a network interface
2080 * @scan_interval: scan interval in seconds
2081 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2082 *
2083 */
2084int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2085 int scan_interval)
2086{
2087 if (scan_interval < 0) {
2088 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2089 scan_interval);
2090 return -1;
2091 }
2092 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2093 scan_interval);
9e737f08 2094 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
2095
2096 return 0;
2097}
2098
2099
86b89452
WS
2100/**
2101 * wpa_supplicant_set_debug_params - Set global debug params
2102 * @global: wpa_global structure
2103 * @debug_level: debug level
2104 * @debug_timestamp: determines if show timestamp in debug data
2105 * @debug_show_keys: determines if show keys in debug data
2106 * Returns: 0 if succeed or -1 if debug_level has wrong value
2107 */
2108int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2109 int debug_timestamp, int debug_show_keys)
2110{
2111
2112 int old_level, old_timestamp, old_show_keys;
2113
2114 /* check for allowed debuglevels */
14dc0011
PS
2115 if (debug_level != MSG_EXCESSIVE &&
2116 debug_level != MSG_MSGDUMP &&
86b89452
WS
2117 debug_level != MSG_DEBUG &&
2118 debug_level != MSG_INFO &&
2119 debug_level != MSG_WARNING &&
2120 debug_level != MSG_ERROR)
2121 return -1;
2122
2123 old_level = wpa_debug_level;
2124 old_timestamp = wpa_debug_timestamp;
2125 old_show_keys = wpa_debug_show_keys;
2126
2127 wpa_debug_level = debug_level;
2128 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2129 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2130
db9133ac
WS
2131 if (wpa_debug_level != old_level)
2132 wpas_notify_debug_level_changed(global);
2133 if (wpa_debug_timestamp != old_timestamp)
2134 wpas_notify_debug_timestamp_changed(global);
2135 if (wpa_debug_show_keys != old_show_keys)
2136 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
2137
2138 return 0;
2139}
2140
2141
6fc6879b
JM
2142/**
2143 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2144 * @wpa_s: Pointer to wpa_supplicant data
2145 * Returns: A pointer to the current network structure or %NULL on failure
2146 */
2147struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2148{
2149 struct wpa_ssid *entry;
2150 u8 ssid[MAX_SSID_LEN];
2151 int res;
2152 size_t ssid_len;
2153 u8 bssid[ETH_ALEN];
2154 int wired;
2155
17fbb751
JM
2156 res = wpa_drv_get_ssid(wpa_s, ssid);
2157 if (res < 0) {
2158 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2159 "driver");
2160 return NULL;
6fc6879b 2161 }
17fbb751 2162 ssid_len = res;
6fc6879b 2163
17fbb751 2164 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
2165 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2166 "driver");
6fc6879b
JM
2167 return NULL;
2168 }
2169
c2a04078
JM
2170 wired = wpa_s->conf->ap_scan == 0 &&
2171 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
2172
2173 entry = wpa_s->conf->ssid;
2174 while (entry) {
349493bd 2175 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b
JM
2176 ((ssid_len == entry->ssid_len &&
2177 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2178 (!entry->bssid_set ||
2179 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2180 return entry;
24c23d1b 2181#ifdef CONFIG_WPS
349493bd 2182 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
2183 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2184 (entry->ssid == NULL || entry->ssid_len == 0) &&
2185 (!entry->bssid_set ||
2186 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2187 return entry;
2188#endif /* CONFIG_WPS */
7d232e23 2189
349493bd 2190 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
2191 entry->ssid_len == 0 &&
2192 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2193 return entry;
2194
6fc6879b
JM
2195 entry = entry->next;
2196 }
2197
2198 return NULL;
2199}
2200
2201
7756114f
JM
2202static int select_driver(struct wpa_supplicant *wpa_s, int i)
2203{
2204 struct wpa_global *global = wpa_s->global;
2205
2206 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2207 global->drv_priv[i] = wpa_drivers[i]->global_init();
2208 if (global->drv_priv[i] == NULL) {
2209 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2210 "'%s'", wpa_drivers[i]->name);
2211 return -1;
2212 }
2213 }
2214
2215 wpa_s->driver = wpa_drivers[i];
2216 wpa_s->global_drv_priv = global->drv_priv[i];
2217
2218 return 0;
2219}
2220
2221
6fc6879b
JM
2222static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2223 const char *name)
2224{
2225 int i;
362f781e 2226 size_t len;
74b1c84a 2227 const char *pos, *driver = name;
6fc6879b
JM
2228
2229 if (wpa_s == NULL)
2230 return -1;
2231
c5121837 2232 if (wpa_drivers[0] == NULL) {
f049052b
BG
2233 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2234 "wpa_supplicant");
6fc6879b
JM
2235 return -1;
2236 }
2237
2238 if (name == NULL) {
2239 /* default to first driver in the list */
7756114f 2240 return select_driver(wpa_s, 0);
6fc6879b
JM
2241 }
2242
74b1c84a
SO
2243 do {
2244 pos = os_strchr(driver, ',');
2245 if (pos)
2246 len = pos - driver;
2247 else
2248 len = os_strlen(driver);
2249
2250 for (i = 0; wpa_drivers[i]; i++) {
2251 if (os_strlen(wpa_drivers[i]->name) == len &&
2252 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
2253 0) {
2254 /* First driver that succeeds wins */
2255 if (select_driver(wpa_s, i) == 0)
2256 return 0;
2257 }
6fc6879b 2258 }
74b1c84a
SO
2259
2260 driver = pos + 1;
2261 } while (pos);
6fc6879b 2262
f049052b 2263 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
2264 return -1;
2265}
2266
2267
a8e0505b
JM
2268/**
2269 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2270 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2271 * with struct wpa_driver_ops::init()
2272 * @src_addr: Source address of the EAPOL frame
2273 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2274 * @len: Length of the EAPOL data
2275 *
2276 * This function is called for each received EAPOL frame. Most driver
2277 * interfaces rely on more generic OS mechanism for receiving frames through
2278 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2279 * take care of received EAPOL frames and deliver them to the core supplicant
2280 * code by calling this function.
2281 */
6fc6879b
JM
2282void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2283 const u8 *buf, size_t len)
2284{
2285 struct wpa_supplicant *wpa_s = ctx;
2286
f049052b 2287 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
2288 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2289
db76aa64
JM
2290#ifdef CONFIG_PEERKEY
2291 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
2292 wpa_s->current_ssid->peerkey &&
2293 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
2294 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
2295 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
2296 return;
2297 }
2298#endif /* CONFIG_PEERKEY */
2299
3ab35a66
JM
2300 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2301 (wpa_s->last_eapol_matches_bssid &&
2302#ifdef CONFIG_AP
2303 !wpa_s->ap_iface &&
2304#endif /* CONFIG_AP */
2305 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
2306 /*
2307 * There is possible race condition between receiving the
2308 * association event and the EAPOL frame since they are coming
2309 * through different paths from the driver. In order to avoid
2310 * issues in trying to process the EAPOL frame before receiving
2311 * association information, lets queue it for processing until
3ab35a66
JM
2312 * the association event is received. This may also be needed in
2313 * driver-based roaming case, so also use src_addr != BSSID as a
2314 * trigger if we have previously confirmed that the
2315 * Authenticator uses BSSID as the src_addr (which is not the
2316 * case with wired IEEE 802.1X).
1ff73338 2317 */
f049052b 2318 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
2319 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2320 wpa_supplicant_state_txt(wpa_s->wpa_state),
2321 MAC2STR(wpa_s->bssid));
1ff73338
JM
2322 wpabuf_free(wpa_s->pending_eapol_rx);
2323 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2324 if (wpa_s->pending_eapol_rx) {
c2be937c 2325 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
2326 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2327 ETH_ALEN);
2328 }
2329 return;
2330 }
2331
3ab35a66
JM
2332 wpa_s->last_eapol_matches_bssid =
2333 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2334
db149ac9
JM
2335#ifdef CONFIG_AP
2336 if (wpa_s->ap_iface) {
2337 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2338 return;
2339 }
2340#endif /* CONFIG_AP */
2341
6fc6879b 2342 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
2343 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2344 "no key management is configured");
6fc6879b
JM
2345 return;
2346 }
2347
2348 if (wpa_s->eapol_received == 0 &&
c2a04078 2349 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
56586197 2350 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
2351 wpa_s->wpa_state != WPA_COMPLETED) &&
2352 (wpa_s->current_ssid == NULL ||
2353 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
6fc6879b
JM
2354 /* Timeout for completing IEEE 802.1X and WPA authentication */
2355 wpa_supplicant_req_auth_timeout(
2356 wpa_s,
56586197 2357 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
a6f06dab
AT
2358 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2359 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
6fc6879b
JM
2360 70 : 10, 0);
2361 }
2362 wpa_s->eapol_received++;
2363
2364 if (wpa_s->countermeasures) {
f049052b
BG
2365 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2366 "EAPOL packet");
6fc6879b
JM
2367 return;
2368 }
2369
8be18440
JM
2370#ifdef CONFIG_IBSS_RSN
2371 if (wpa_s->current_ssid &&
d7dcba70 2372 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
2373 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2374 return;
2375 }
2376#endif /* CONFIG_IBSS_RSN */
2377
6fc6879b
JM
2378 /* Source address of the incoming EAPOL frame could be compared to the
2379 * current BSSID. However, it is possible that a centralized
2380 * Authenticator could be using another MAC address than the BSSID of
2381 * an AP, so just allow any address to be used for now. The replies are
2382 * still sent to the current BSSID (if available), though. */
2383
2384 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 2385 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
6fc6879b
JM
2386 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2387 return;
2388 wpa_drv_poll(wpa_s);
c2a04078 2389 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
6fc6879b 2390 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 2391 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
2392 /*
2393 * Set portValid = TRUE here since we are going to skip 4-way
2394 * handshake processing which would normally set portValid. We
2395 * need this to allow the EAPOL state machines to be completed
2396 * without going through EAPOL-Key handshake.
2397 */
2398 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2399 }
2400}
2401
2402
bfba8deb 2403int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 2404{
6fc6879b
JM
2405 if (wpa_s->driver->send_eapol) {
2406 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2407 if (addr)
2408 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
1c42b42f
JM
2409 } else if ((!wpa_s->p2p_mgmt ||
2410 !(wpa_s->drv_flags &
2411 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
c68f6200 2412 !(wpa_s->drv_flags &
fdadd5fe 2413 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 2414 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
2415 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2416 wpa_drv_get_mac_addr(wpa_s),
2417 ETH_P_EAPOL,
2418 wpa_supplicant_rx_eapol, wpa_s, 0);
2419 if (wpa_s->l2 == NULL)
2420 return -1;
fdadd5fe
JM
2421 } else {
2422 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2423 if (addr)
2424 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
2425 }
2426
2427 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 2428 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
2429 return -1;
2430 }
2431
bfba8deb
JM
2432 return 0;
2433}
2434
2435
25f839c6
JM
2436static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2437 const u8 *buf, size_t len)
2438{
2439 struct wpa_supplicant *wpa_s = ctx;
2440 const struct l2_ethhdr *eth;
2441
2442 if (len < sizeof(*eth))
2443 return;
2444 eth = (const struct l2_ethhdr *) buf;
2445
2446 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2447 !(eth->h_dest[0] & 0x01)) {
2448 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2449 " (bridge - not for this interface - ignore)",
2450 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2451 return;
2452 }
2453
2454 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2455 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2456 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2457 len - sizeof(*eth));
2458}
2459
2460
bfba8deb
JM
2461/**
2462 * wpa_supplicant_driver_init - Initialize driver interface parameters
2463 * @wpa_s: Pointer to wpa_supplicant data
2464 * Returns: 0 on success, -1 on failure
2465 *
2466 * This function is called to initialize driver interface parameters.
2467 * wpa_drv_init() must have been called before this function to initialize the
2468 * driver interface.
2469 */
2470int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2471{
2472 static int interface_count = 0;
2473
2474 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2475 return -1;
2476
c68f6200
AS
2477 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2478 MAC2STR(wpa_s->own_addr));
2479 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2480
6fc6879b 2481 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
2482 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2483 "interface '%s'", wpa_s->bridge_ifname);
6fc6879b
JM
2484 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2485 wpa_s->own_addr,
2486 ETH_P_EAPOL,
25f839c6
JM
2487 wpa_supplicant_rx_eapol_bridge,
2488 wpa_s, 1);
6fc6879b 2489 if (wpa_s->l2_br == NULL) {
f049052b
BG
2490 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2491 "connection for the bridge interface '%s'",
2492 wpa_s->bridge_ifname);
6fc6879b
JM
2493 return -1;
2494 }
2495 }
2496
6fc6879b
JM
2497 wpa_clear_keys(wpa_s, NULL);
2498
2499 /* Make sure that TKIP countermeasures are not left enabled (could
2500 * happen if wpa_supplicant is killed during countermeasures. */
2501 wpa_drv_set_countermeasures(wpa_s, 0);
2502
f049052b 2503 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
2504 wpa_drv_flush_pmkid(wpa_s);
2505
ba2a573c 2506 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
2507 wpa_s->prev_scan_wildcard = 0;
2508
349493bd 2509 if (wpa_supplicant_enabled_networks(wpa_s)) {
6a90053c
LC
2510 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2511 100000))
a4cba8f1
LC
2512 wpa_supplicant_req_scan(wpa_s, interface_count,
2513 100000);
74e259ec
JM
2514 interface_count++;
2515 } else
2516 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
2517
2518 return 0;
2519}
2520
2521
2522static int wpa_supplicant_daemon(const char *pid_file)
2523{
2524 wpa_printf(MSG_DEBUG, "Daemonize..");
2525 return os_daemonize(pid_file);
2526}
2527
2528
2529static struct wpa_supplicant * wpa_supplicant_alloc(void)
2530{
2531 struct wpa_supplicant *wpa_s;
2532
2533 wpa_s = os_zalloc(sizeof(*wpa_s));
2534 if (wpa_s == NULL)
2535 return NULL;
4115303b 2536 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 2537 wpa_s->scan_interval = 5;
c302f207 2538 wpa_s->new_connection = 1;
b22128ef 2539 wpa_s->parent = wpa_s;
cbdf3507 2540 wpa_s->sched_scanning = 0;
6fc6879b
JM
2541
2542 return wpa_s;
2543}
2544
2545
80e8a5ee
BG
2546#ifdef CONFIG_HT_OVERRIDES
2547
2548static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2549 struct ieee80211_ht_capabilities *htcaps,
2550 struct ieee80211_ht_capabilities *htcaps_mask,
2551 const char *ht_mcs)
2552{
2553 /* parse ht_mcs into hex array */
2554 int i;
2555 const char *tmp = ht_mcs;
2556 char *end = NULL;
2557
2558 /* If ht_mcs is null, do not set anything */
2559 if (!ht_mcs)
2560 return 0;
2561
2562 /* This is what we are setting in the kernel */
2563 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2564
2565 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2566
2567 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2568 errno = 0;
2569 long v = strtol(tmp, &end, 16);
2570 if (errno == 0) {
2571 wpa_msg(wpa_s, MSG_DEBUG,
2572 "htcap value[%i]: %ld end: %p tmp: %p",
2573 i, v, end, tmp);
2574 if (end == tmp)
2575 break;
2576
2577 htcaps->supported_mcs_set[i] = v;
2578 tmp = end;
2579 } else {
2580 wpa_msg(wpa_s, MSG_ERROR,
2581 "Failed to parse ht-mcs: %s, error: %s\n",
2582 ht_mcs, strerror(errno));
2583 return -1;
2584 }
2585 }
2586
2587 /*
2588 * If we were able to parse any values, then set mask for the MCS set.
2589 */
2590 if (i) {
2591 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2592 IEEE80211_HT_MCS_MASK_LEN - 1);
2593 /* skip the 3 reserved bits */
2594 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2595 0x1f;
2596 }
2597
2598 return 0;
2599}
2600
2601
2602static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2603 struct ieee80211_ht_capabilities *htcaps,
2604 struct ieee80211_ht_capabilities *htcaps_mask,
2605 int disabled)
2606{
2607 u16 msk;
2608
2609 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2610
2611 if (disabled == -1)
2612 return 0;
2613
2614 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2615 htcaps_mask->ht_capabilities_info |= msk;
2616 if (disabled)
2617 htcaps->ht_capabilities_info &= msk;
2618 else
2619 htcaps->ht_capabilities_info |= msk;
2620
2621 return 0;
2622}
2623
2624
2625static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2626 struct ieee80211_ht_capabilities *htcaps,
2627 struct ieee80211_ht_capabilities *htcaps_mask,
2628 int factor)
2629{
2630 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2631
2632 if (factor == -1)
2633 return 0;
2634
2635 if (factor < 0 || factor > 3) {
2636 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2637 "Must be 0-3 or -1", factor);
2638 return -EINVAL;
2639 }
2640
2641 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2642 htcaps->a_mpdu_params &= ~0x3;
2643 htcaps->a_mpdu_params |= factor & 0x3;
2644
2645 return 0;
2646}
2647
2648
2649static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2650 struct ieee80211_ht_capabilities *htcaps,
2651 struct ieee80211_ht_capabilities *htcaps_mask,
2652 int density)
2653{
2654 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2655
2656 if (density == -1)
2657 return 0;
2658
2659 if (density < 0 || density > 7) {
2660 wpa_msg(wpa_s, MSG_ERROR,
2661 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2662 density);
2663 return -EINVAL;
2664 }
2665
2666 htcaps_mask->a_mpdu_params |= 0x1C;
2667 htcaps->a_mpdu_params &= ~(0x1C);
2668 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2669
2670 return 0;
2671}
2672
2673
2674static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2675 struct ieee80211_ht_capabilities *htcaps,
2676 struct ieee80211_ht_capabilities *htcaps_mask,
2677 int disabled)
2678{
2679 /* Masking these out disables HT40 */
2680 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2681 HT_CAP_INFO_SHORT_GI40MHZ);
2682
2683 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2684
2685 if (disabled)
2686 htcaps->ht_capabilities_info &= ~msk;
2687 else
2688 htcaps->ht_capabilities_info |= msk;
2689
2690 htcaps_mask->ht_capabilities_info |= msk;
2691
2692 return 0;
2693}
2694
2695
a90497f8
BG
2696static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2697 struct ieee80211_ht_capabilities *htcaps,
2698 struct ieee80211_ht_capabilities *htcaps_mask,
2699 int disabled)
2700{
2701 /* Masking these out disables SGI */
2702 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2703 HT_CAP_INFO_SHORT_GI40MHZ);
2704
2705 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2706
2707 if (disabled)
2708 htcaps->ht_capabilities_info &= ~msk;
2709 else
2710 htcaps->ht_capabilities_info |= msk;
2711
2712 htcaps_mask->ht_capabilities_info |= msk;
2713
2714 return 0;
2715}
2716
2717
80e8a5ee
BG
2718void wpa_supplicant_apply_ht_overrides(
2719 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2720 struct wpa_driver_associate_params *params)
2721{
2722 struct ieee80211_ht_capabilities *htcaps;
2723 struct ieee80211_ht_capabilities *htcaps_mask;
2724
2725 if (!ssid)
2726 return;
2727
2728 params->disable_ht = ssid->disable_ht;
2729 if (!params->htcaps || !params->htcaps_mask)
2730 return;
2731
2732 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2733 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2734 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2735 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2736 ssid->disable_max_amsdu);
2737 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2738 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2739 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 2740 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
80e8a5ee
BG
2741}
2742
2743#endif /* CONFIG_HT_OVERRIDES */
2744
2745
e9ee8dc3
JB
2746#ifdef CONFIG_VHT_OVERRIDES
2747void wpa_supplicant_apply_vht_overrides(
2748 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2749 struct wpa_driver_associate_params *params)
2750{
2751 struct ieee80211_vht_capabilities *vhtcaps;
2752 struct ieee80211_vht_capabilities *vhtcaps_mask;
2753
2754 if (!ssid)
2755 return;
2756
2757 params->disable_vht = ssid->disable_vht;
2758
2759 vhtcaps = (void *) params->vhtcaps;
2760 vhtcaps_mask = (void *) params->vhtcaps_mask;
2761
2762 if (!vhtcaps || !vhtcaps_mask)
2763 return;
2764
2765 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2766 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2767
2768#define OVERRIDE_MCS(i) \
2769 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2770 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2771 3 << 2 * (i - 1); \
2772 vhtcaps->vht_supported_mcs_set.tx_map |= \
2773 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2774 } \
2775 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2776 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2777 3 << 2 * (i - 1); \
2778 vhtcaps->vht_supported_mcs_set.rx_map |= \
2779 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2780 }
2781
2782 OVERRIDE_MCS(1);
2783 OVERRIDE_MCS(2);
2784 OVERRIDE_MCS(3);
2785 OVERRIDE_MCS(4);
2786 OVERRIDE_MCS(5);
2787 OVERRIDE_MCS(6);
2788 OVERRIDE_MCS(7);
2789 OVERRIDE_MCS(8);
2790}
2791#endif /* CONFIG_VHT_OVERRIDES */
2792
2793
f64adcd7
JM
2794static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2795{
2796#ifdef PCSC_FUNCS
2797 size_t len;
2798
2799 if (!wpa_s->conf->pcsc_reader)
2800 return 0;
2801
22cf7d73 2802 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
2803 if (!wpa_s->scard)
2804 return 1;
2805
2806 if (wpa_s->conf->pcsc_pin &&
2807 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2808 scard_deinit(wpa_s->scard);
2809 wpa_s->scard = NULL;
2810 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2811 return -1;
2812 }
2813
2814 len = sizeof(wpa_s->imsi) - 1;
2815 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2816 scard_deinit(wpa_s->scard);
2817 wpa_s->scard = NULL;
2818 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2819 return -1;
2820 }
2821 wpa_s->imsi[len] = '\0';
2822
2823 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2824
2825 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2826 wpa_s->imsi, wpa_s->mnc_len);
2827
2828 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2829 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2830#endif /* PCSC_FUNCS */
2831
2832 return 0;
2833}
2834
2835
306ae225
JM
2836int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2837{
2838 char *val, *pos;
2839
2840 ext_password_deinit(wpa_s->ext_pw);
2841 wpa_s->ext_pw = NULL;
2842 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2843
2844 if (!wpa_s->conf->ext_password_backend)
2845 return 0;
2846
2847 val = os_strdup(wpa_s->conf->ext_password_backend);
2848 if (val == NULL)
2849 return -1;
2850 pos = os_strchr(val, ':');
2851 if (pos)
2852 *pos++ = '\0';
2853
2854 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2855
2856 wpa_s->ext_pw = ext_password_init(val, pos);
2857 os_free(val);
2858 if (wpa_s->ext_pw == NULL) {
2859 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2860 return -1;
2861 }
2862 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2863
2864 return 0;
2865}
2866
2867
202dec2a
JM
2868static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
2869 const char *rn)
2870{
2871 struct wpa_supplicant *iface = wpa_s->global->ifaces;
2872 struct wpa_radio *radio;
2873
2874 while (rn && iface) {
2875 radio = iface->radio;
2876 if (radio && os_strcmp(rn, radio->name) == 0) {
2877 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
2878 wpa_s->ifname, rn);
2879 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
2880 return radio;
2881 }
b154a24e
TB
2882
2883 iface = iface->next;
202dec2a
JM
2884 }
2885
2886 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
2887 wpa_s->ifname, rn ? rn : "N/A");
2888 radio = os_zalloc(sizeof(*radio));
2889 if (radio == NULL)
2890 return NULL;
2891
2892 if (rn)
2893 os_strlcpy(radio->name, rn, sizeof(radio->name));
2894 dl_list_init(&radio->ifaces);
b1ae396f 2895 dl_list_init(&radio->work);
202dec2a
JM
2896 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
2897
2898 return radio;
2899}
2900
2901
b1ae396f
JM
2902static void radio_work_free(struct wpa_radio_work *work)
2903{
d12a51b5
JM
2904 if (work->wpa_s->scan_work == work) {
2905 /* This should not really happen. */
2906 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
2907 work->type, work, work->started);
2908 work->wpa_s->scan_work = NULL;
2909 }
2910
1b5d4714
JM
2911#ifdef CONFIG_P2P
2912 if (work->wpa_s->p2p_scan_work == work) {
2913 /* This should not really happen. */
2914 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
2915 work->type, work, work->started);
2916 work->wpa_s->p2p_scan_work = NULL;
2917 }
2918#endif /* CONFIG_P2P */
2919
b1ae396f
JM
2920 dl_list_del(&work->list);
2921 os_free(work);
2922}
2923
2924
2925static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
2926{
2927 struct wpa_radio *radio = eloop_ctx;
2928 struct wpa_radio_work *work;
2929 struct os_reltime now, diff;
2930
2931 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
2932 if (work == NULL)
2933 return;
2934
2935 if (work->started)
2936 return; /* already started and still in progress */
2937
2938 os_get_reltime(&now);
2939 os_reltime_sub(&now, &work->time, &diff);
2940 wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
2941 work->type, work, diff.sec, diff.usec);
2942 work->started = 1;
2943 work->time = now;
2944 work->cb(work, 0);
2945}
2946
2947
2948void radio_remove_unstarted_work(struct wpa_supplicant *wpa_s, const char *type)
2949{
2950 struct wpa_radio_work *work, *tmp;
2951 struct wpa_radio *radio = wpa_s->radio;
2952
2953 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
2954 list) {
2955 if (type && (work->started || os_strcmp(type, work->type) != 0))
2956 continue;
2957 if (work->started) {
2958 wpa_dbg(wpa_s, MSG_DEBUG, "Leaving started radio work '%s'@%p in the list",
2959 work->type, work);
2960 continue;
2961 }
2962 wpa_dbg(wpa_s, MSG_DEBUG, "Remove unstarted radio work '%s'@%p",
2963 work->type, work);
2964 work->cb(work, 1);
2965 radio_work_free(work);
2966 }
2967}
2968
2969
202dec2a
JM
2970static void radio_remove_interface(struct wpa_supplicant *wpa_s)
2971{
2972 struct wpa_radio *radio = wpa_s->radio;
2973
2974 if (!radio)
2975 return;
2976
2977 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
2978 wpa_s->ifname, radio->name);
2979 dl_list_del(&wpa_s->radio_list);
b1ae396f
JM
2980 if (!dl_list_empty(&radio->ifaces)) {
2981 wpa_s->radio = NULL;
202dec2a 2982 return; /* Interfaces remain for this radio */
b1ae396f 2983 }
202dec2a
JM
2984
2985 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f
JM
2986 radio_remove_unstarted_work(wpa_s, NULL);
2987 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
2988 wpa_s->radio = NULL;
202dec2a
JM
2989 os_free(radio);
2990}
2991
2992
b1ae396f
JM
2993static void radio_work_check_next(struct wpa_supplicant *wpa_s)
2994{
2995 struct wpa_radio *radio = wpa_s->radio;
2996
2997 if (dl_list_empty(&radio->work))
2998 return;
2999 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
3000 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
3001}
3002
3003
3004/**
3005 * radio_add_work - Add a radio work item
3006 * @wpa_s: Pointer to wpa_supplicant data
3007 * @freq: Frequency of the offchannel operation in MHz or 0
3008 * @type: Unique identifier for each type of work
3009 * @next: Force as the next work to be executed
3010 * @cb: Callback function for indicating when radio is available
3011 * @ctx: Context pointer for the work (work->ctx in cb())
3012 * Returns: 0 on success, -1 on failure
3013 *
3014 * This function is used to request time for an operation that requires
3015 * exclusive radio control. Once the radio is available, the registered callback
3016 * function will be called. radio_work_done() must be called once the exclusive
3017 * radio operation has been completed, so that the radio is freed for other
3018 * operations. The special case of deinit=1 is used to free the context data
3019 * during interface removal. That does not allow the callback function to start
3020 * the radio operation, i.e., it must free any resources allocated for the radio
3021 * work and return.
3022 *
3023 * The @freq parameter can be used to indicate a single channel on which the
3024 * offchannel operation will occur. This may allow multiple radio work
3025 * operations to be performed in parallel if they apply for the same channel.
3026 * Setting this to 0 indicates that the work item may use multiple channels or
3027 * requires exclusive control of the radio.
3028 */
3029int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
3030 const char *type, int next,
3031 void (*cb)(struct wpa_radio_work *work, int deinit),
3032 void *ctx)
3033{
3034 struct wpa_radio_work *work;
3035 int was_empty;
3036
3037 work = os_zalloc(sizeof(*work));
3038 if (work == NULL)
3039 return -1;
3040 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
3041 os_get_reltime(&work->time);
3042 work->freq = freq;
3043 work->type = type;
3044 work->wpa_s = wpa_s;
3045 work->cb = cb;
3046 work->ctx = ctx;
3047
3048 was_empty = dl_list_empty(&wpa_s->radio->work);
3049 if (next)
3050 dl_list_add(&wpa_s->radio->work, &work->list);
3051 else
3052 dl_list_add_tail(&wpa_s->radio->work, &work->list);
3053 if (was_empty) {
3054 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
3055 radio_work_check_next(wpa_s);
3056 }
3057
3058 return 0;
3059}
3060
3061
3062/**
3063 * radio_work_done - Indicate that a radio work item has been completed
3064 * @work: Completed work
3065 *
3066 * This function is called once the callback function registered with
3067 * radio_add_work() has completed its work.
3068 */
3069void radio_work_done(struct wpa_radio_work *work)
3070{
3071 struct wpa_supplicant *wpa_s = work->wpa_s;
3072 struct os_reltime now, diff;
3073
3074 os_get_reltime(&now);
3075 os_reltime_sub(&now, &work->time, &diff);
3076 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p done in %ld.%06ld seconds",
3077 work->type, work, diff.sec, diff.usec);
3078 radio_work_free(work);
3079 radio_work_check_next(wpa_s);
3080}
3081
3082
73c00fd7
JM
3083static int wpas_init_driver(struct wpa_supplicant *wpa_s,
3084 struct wpa_interface *iface)
3085{
202dec2a 3086 const char *ifname, *driver, *rn;
73c00fd7
JM
3087
3088 driver = iface->driver;
3089next_driver:
3090 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
3091 return -1;
3092
3093 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
3094 if (wpa_s->drv_priv == NULL) {
3095 const char *pos;
3096 pos = driver ? os_strchr(driver, ',') : NULL;
3097 if (pos) {
3098 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
3099 "driver interface - try next driver wrapper");
3100 driver = pos + 1;
3101 goto next_driver;
3102 }
3103 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
3104 "interface");
3105 return -1;
3106 }
3107 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
3108 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
3109 "driver_param '%s'", wpa_s->conf->driver_param);
3110 return -1;
3111 }
3112
3113 ifname = wpa_drv_get_ifname(wpa_s);
3114 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
3115 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
3116 "interface name with '%s'", ifname);
3117 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
3118 }
3119
202dec2a
JM
3120 if (wpa_s->driver->get_radio_name)
3121 rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
3122 else
3123 rn = NULL;
3124 if (rn && rn[0] == '\0')
3125 rn = NULL;
3126
3127 wpa_s->radio = radio_add_interface(wpa_s, rn);
3128 if (wpa_s->radio == NULL)
3129 return -1;
3130
73c00fd7
JM
3131 return 0;
3132}
3133
3134
6fc6879b
JM
3135static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
3136 struct wpa_interface *iface)
3137{
362f781e
JM
3138 struct wpa_driver_capa capa;
3139
6fc6879b
JM
3140 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
3141 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
3142 iface->confname ? iface->confname : "N/A",
3143 iface->driver ? iface->driver : "default",
3144 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
3145 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
3146
6fc6879b
JM
3147 if (iface->confname) {
3148#ifdef CONFIG_BACKEND_FILE
3149 wpa_s->confname = os_rel2abs_path(iface->confname);
3150 if (wpa_s->confname == NULL) {
3151 wpa_printf(MSG_ERROR, "Failed to get absolute path "
3152 "for configuration file '%s'.",
3153 iface->confname);
3154 return -1;
3155 }
3156 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
3157 iface->confname, wpa_s->confname);
3158#else /* CONFIG_BACKEND_FILE */
3159 wpa_s->confname = os_strdup(iface->confname);
3160#endif /* CONFIG_BACKEND_FILE */
e6304cad 3161 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
3162 if (wpa_s->conf == NULL) {
3163 wpa_printf(MSG_ERROR, "Failed to read or parse "
3164 "configuration '%s'.", wpa_s->confname);
3165 return -1;
3166 }
e6304cad
DS
3167 wpa_s->confanother = os_rel2abs_path(iface->confanother);
3168 wpa_config_read(wpa_s->confanother, wpa_s->conf);
6fc6879b
JM
3169
3170 /*
3171 * Override ctrl_interface and driver_param if set on command
3172 * line.
3173 */
3174 if (iface->ctrl_interface) {
3175 os_free(wpa_s->conf->ctrl_interface);
3176 wpa_s->conf->ctrl_interface =
3177 os_strdup(iface->ctrl_interface);
3178 }
3179
3180 if (iface->driver_param) {
3181 os_free(wpa_s->conf->driver_param);
3182 wpa_s->conf->driver_param =
3183 os_strdup(iface->driver_param);
3184 }
78f79fe5
JM
3185
3186 if (iface->p2p_mgmt && !iface->ctrl_interface) {
3187 os_free(wpa_s->conf->ctrl_interface);
3188 wpa_s->conf->ctrl_interface = NULL;
3189 }
6fc6879b
JM
3190 } else
3191 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
3192 iface->driver_param);
3193
3194 if (wpa_s->conf == NULL) {
3195 wpa_printf(MSG_ERROR, "\nNo configuration found.");
3196 return -1;
3197 }
3198
3199 if (iface->ifname == NULL) {
3200 wpa_printf(MSG_ERROR, "\nInterface name is required.");
3201 return -1;
3202 }
3203 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
3204 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
3205 iface->ifname);
3206 return -1;
3207 }
3208 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
3209
3210 if (iface->bridge_ifname) {
3211 if (os_strlen(iface->bridge_ifname) >=
3212 sizeof(wpa_s->bridge_ifname)) {
3213 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
3214 "name '%s'.", iface->bridge_ifname);
3215 return -1;
3216 }
3217 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
3218 sizeof(wpa_s->bridge_ifname));
3219 }
3220
6fc6879b
JM
3221 /* RSNA Supplicant Key Management - INITIALIZE */
3222 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
3223 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
3224
3225 /* Initialize driver interface and register driver event handler before
3226 * L2 receive handler so that association events are processed before
3227 * EAPOL-Key packets if both become available for the same select()
3228 * call. */
73c00fd7 3229 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
3230 return -1;
3231
6fc6879b
JM
3232 if (wpa_supplicant_init_wpa(wpa_s) < 0)
3233 return -1;
3234
3235 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
3236 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
3237 NULL);
3238 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
3239
3240 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
3241 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
3242 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
3243 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
3244 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
3245 return -1;
3246 }
3247
3248 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
3249 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
3250 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 3251 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
3252 "dot11RSNAConfigPMKReauthThreshold");
3253 return -1;
3254 }
3255
3256 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
3257 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
3258 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
3259 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
3260 "dot11RSNAConfigSATimeout");
6fc6879b
JM
3261 return -1;
3262 }
3263
6bf731e8
CL
3264 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
3265 &wpa_s->hw.num_modes,
3266 &wpa_s->hw.flags);
3267
814782b9 3268 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
c58ab8f2 3269 wpa_s->drv_capa_known = 1;
814782b9 3270 wpa_s->drv_flags = capa.flags;
349493bd 3271 wpa_s->drv_enc = capa.enc;
4f73d88a 3272 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 3273 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507
LC
3274 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
3275 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 3276 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 3277 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 3278 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
3279 wpa_s->extended_capa = capa.extended_capa;
3280 wpa_s->extended_capa_mask = capa.extended_capa_mask;
3281 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
3282 wpa_s->num_multichan_concurrent =
3283 capa.num_multichan_concurrent;
814782b9
JM
3284 }
3285 if (wpa_s->max_remain_on_chan == 0)
3286 wpa_s->max_remain_on_chan = 1000;
3287
c68f6200
AS
3288 /*
3289 * Only take p2p_mgmt parameters when P2P Device is supported.
3290 * Doing it here as it determines whether l2_packet_init() will be done
3291 * during wpa_supplicant_driver_init().
3292 */
3293 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
3294 wpa_s->p2p_mgmt = iface->p2p_mgmt;
3295 else
3296 iface->p2p_mgmt = 1;
3297
4752147d
IP
3298 if (wpa_s->num_multichan_concurrent == 0)
3299 wpa_s->num_multichan_concurrent = 1;
3300
6fc6879b
JM
3301 if (wpa_supplicant_driver_init(wpa_s) < 0)
3302 return -1;
3303
281ff0aa 3304#ifdef CONFIG_TDLS
1c42b42f
JM
3305 if ((!iface->p2p_mgmt ||
3306 !(wpa_s->drv_flags &
3307 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3308 wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
3309 return -1;
3310#endif /* CONFIG_TDLS */
3311
315ce40a
JM
3312 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
3313 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 3314 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
3315 return -1;
3316 }
3317
116654ce
JM
3318 if (wpas_wps_init(wpa_s))
3319 return -1;
3320
6fc6879b
JM
3321 if (wpa_supplicant_init_eapol(wpa_s) < 0)
3322 return -1;
3323 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3324
3325 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
3326 if (wpa_s->ctrl_iface == NULL) {
3327 wpa_printf(MSG_ERROR,
3328 "Failed to initialize control interface '%s'.\n"
3329 "You may have another wpa_supplicant process "
3330 "already running or the file was\n"
3331 "left by an unclean termination of wpa_supplicant "
3332 "in which case you will need\n"
3333 "to manually remove this file before starting "
3334 "wpa_supplicant again.\n",
3335 wpa_s->conf->ctrl_interface);
3336 return -1;
3337 }
3338
04ea7b79
JM
3339 wpa_s->gas = gas_query_init(wpa_s);
3340 if (wpa_s->gas == NULL) {
3341 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3342 return -1;
3343 }
3344
b22128ef 3345#ifdef CONFIG_P2P
c68f6200 3346 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 3347 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
3348 return -1;
3349 }
3350#endif /* CONFIG_P2P */
3351
83922c2d
JM
3352 if (wpa_bss_init(wpa_s) < 0)
3353 return -1;
83922c2d 3354
ec7b97ab
JM
3355#ifdef CONFIG_EAP_PROXY
3356{
3357 size_t len;
07041c6f
NJ
3358 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
3359 &len);
ec7b97ab
JM
3360 if (wpa_s->mnc_len > 0) {
3361 wpa_s->imsi[len] = '\0';
3362 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
3363 wpa_s->imsi, wpa_s->mnc_len);
3364 } else {
3365 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
3366 }
3367}
3368#endif /* CONFIG_EAP_PROXY */
3369
f64adcd7
JM
3370 if (pcsc_reader_init(wpa_s) < 0)
3371 return -1;
3372
306ae225
JM
3373 if (wpas_init_ext_pw(wpa_s) < 0)
3374 return -1;
3375
6fc6879b
JM
3376 return 0;
3377}
3378
3379
2ee055b3 3380static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 3381 int notify, int terminate)
6fc6879b 3382{
e679f140 3383 wpa_s->disconnected = 1;
6fc6879b
JM
3384 if (wpa_s->drv_priv) {
3385 wpa_supplicant_deauthenticate(wpa_s,
3386 WLAN_REASON_DEAUTH_LEAVING);
3387
6fc6879b
JM
3388 wpa_drv_set_countermeasures(wpa_s, 0);
3389 wpa_clear_keys(wpa_s, NULL);
3390 }
3391
8e56d189
JM
3392 wpa_supplicant_cleanup(wpa_s);
3393
ab28911d
JM
3394#ifdef CONFIG_P2P
3395 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3396 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3397 "the management interface is being removed");
3398 wpas_p2p_deinit_global(wpa_s->global);
3399 }
3400#endif /* CONFIG_P2P */
3401
202dec2a
JM
3402 radio_remove_interface(wpa_s);
3403
6fc6879b
JM
3404 if (wpa_s->drv_priv)
3405 wpa_drv_deinit(wpa_s);
2523ff6e
DS
3406
3407 if (notify)
3408 wpas_notify_iface_removed(wpa_s);
f0811516
DS
3409
3410 if (terminate)
3411 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
3412
3413 if (wpa_s->ctrl_iface) {
3414 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3415 wpa_s->ctrl_iface = NULL;
3416 }
3417
3418 if (wpa_s->conf != NULL) {
3419 wpa_config_free(wpa_s->conf);
3420 wpa_s->conf = NULL;
3421 }
18e00b5e
JM
3422
3423 os_free(wpa_s);
6fc6879b
JM
3424}
3425
3426
3427/**
3428 * wpa_supplicant_add_iface - Add a new network interface
3429 * @global: Pointer to global data from wpa_supplicant_init()
3430 * @iface: Interface configuration options
3431 * Returns: Pointer to the created interface or %NULL on failure
3432 *
3433 * This function is used to add new network interfaces for %wpa_supplicant.
3434 * This can be called before wpa_supplicant_run() to add interfaces before the
3435 * main event loop has been started. In addition, new interfaces can be added
3436 * dynamically while %wpa_supplicant is already running. This could happen,
3437 * e.g., when a hotplug network adapter is inserted.
3438 */
3439struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3440 struct wpa_interface *iface)
3441{
3442 struct wpa_supplicant *wpa_s;
d27df100 3443 struct wpa_interface t_iface;
8e56d189 3444 struct wpa_ssid *ssid;
6fc6879b
JM
3445
3446 if (global == NULL || iface == NULL)
3447 return NULL;
3448
3449 wpa_s = wpa_supplicant_alloc();
3450 if (wpa_s == NULL)
3451 return NULL;
3452
d8222ae3
JM
3453 wpa_s->global = global;
3454
d27df100
JM
3455 t_iface = *iface;
3456 if (global->params.override_driver) {
3457 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3458 "('%s' -> '%s')",
3459 iface->driver, global->params.override_driver);
3460 t_iface.driver = global->params.override_driver;
3461 }
3462 if (global->params.override_ctrl_interface) {
3463 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3464 "ctrl_interface ('%s' -> '%s')",
3465 iface->ctrl_interface,
3466 global->params.override_ctrl_interface);
3467 t_iface.ctrl_interface =
3468 global->params.override_ctrl_interface;
3469 }
3470 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
3471 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3472 iface->ifname);
df509539 3473 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
3474 return NULL;
3475 }
3476
dc461de4
WS
3477 /* Notify the control interfaces about new iface */
3478 if (wpas_notify_iface_added(wpa_s)) {
df509539 3479 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
6fc6879b
JM
3480 return NULL;
3481 }
1bd3f426 3482
8e56d189
JM
3483 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3484 wpas_notify_network_added(wpa_s, ssid);
3485
6fc6879b
JM
3486 wpa_s->next = global->ifaces;
3487 global->ifaces = wpa_s;
3488
f049052b 3489 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 3490 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b
JM
3491
3492 return wpa_s;
3493}
3494
3495
3496/**
3497 * wpa_supplicant_remove_iface - Remove a network interface
3498 * @global: Pointer to global data from wpa_supplicant_init()
3499 * @wpa_s: Pointer to the network interface to be removed
3500 * Returns: 0 if interface was removed, -1 if interface was not found
3501 *
3502 * This function can be used to dynamically remove network interfaces from
3503 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3504 * addition, this function is used to remove all remaining interfaces when
3505 * %wpa_supplicant is terminated.
3506 */
3507int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
3508 struct wpa_supplicant *wpa_s,
3509 int terminate)
6fc6879b
JM
3510{
3511 struct wpa_supplicant *prev;
3512
3513 /* Remove interface from the global list of interfaces */
3514 prev = global->ifaces;
3515 if (prev == wpa_s) {
3516 global->ifaces = wpa_s->next;
3517 } else {
3518 while (prev && prev->next != wpa_s)
3519 prev = prev->next;
3520 if (prev == NULL)
3521 return -1;
3522 prev->next = wpa_s->next;
3523 }
3524
f049052b 3525 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 3526
b22128ef
JM
3527 if (global->p2p_group_formation == wpa_s)
3528 global->p2p_group_formation = NULL;
dbca75f8
JM
3529 if (global->p2p_invite_group == wpa_s)
3530 global->p2p_invite_group = NULL;
df509539 3531 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b
JM
3532
3533 return 0;
3534}
3535
3536
cf83fb0b
PS
3537/**
3538 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3539 * @wpa_s: Pointer to the network interface
3540 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3541 */
3542const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3543{
3544 const char *eapol_method;
3545
3546 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3547 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3548 return "NO-EAP";
3549 }
3550
3551 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3552 if (eapol_method == NULL)
3553 return "UNKNOWN-EAP";
3554
3555 return eapol_method;
3556}
3557
3558
6fc6879b
JM
3559/**
3560 * wpa_supplicant_get_iface - Get a new network interface
3561 * @global: Pointer to global data from wpa_supplicant_init()
3562 * @ifname: Interface name
3563 * Returns: Pointer to the interface or %NULL if not found
3564 */
3565struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3566 const char *ifname)
3567{
3568 struct wpa_supplicant *wpa_s;
3569
3570 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3571 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3572 return wpa_s;
3573 }
3574 return NULL;
3575}
3576
3577
50b16da1 3578#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
3579static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3580{
3581 struct wpa_supplicant *wpa_s = ctx;
3582 if (wpa_s == NULL)
3583 return NULL;
3584 return wpa_s->ifname;
3585}
50b16da1 3586#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
3587
3588
6fc6879b
JM
3589/**
3590 * wpa_supplicant_init - Initialize %wpa_supplicant
3591 * @params: Parameters for %wpa_supplicant
3592 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3593 *
3594 * This function is used to initialize %wpa_supplicant. After successful
3595 * initialization, the returned data pointer can be used to add and remove
3596 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3597 */
3598struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3599{
3600 struct wpa_global *global;
ac305589 3601 int ret, i;
6fc6879b
JM
3602
3603 if (params == NULL)
3604 return NULL;
3605
39e7d718
JM
3606#ifdef CONFIG_DRIVER_NDIS
3607 {
3608 void driver_ndis_init_ops(void);
3609 driver_ndis_init_ops();
3610 }
3611#endif /* CONFIG_DRIVER_NDIS */
3612
50b16da1 3613#ifndef CONFIG_NO_WPA_MSG
4f1495ae 3614 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 3615#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 3616
6fc6879b 3617 wpa_debug_open_file(params->wpa_debug_file_path);
daa70d49
SL
3618 if (params->wpa_debug_syslog)
3619 wpa_debug_open_syslog();
4f68895e
JB
3620 if (params->wpa_debug_tracing) {
3621 ret = wpa_debug_open_linux_tracing();
3622 if (ret) {
3623 wpa_printf(MSG_ERROR,
3624 "Failed to enable trace logging");
3625 return NULL;
3626 }
3627 }
6fc6879b 3628
12760815 3629 ret = eap_register_methods();
6fc6879b
JM
3630 if (ret) {
3631 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3632 if (ret == -2)
3633 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3634 "the same EAP type.");
3635 return NULL;
3636 }
3637
3638 global = os_zalloc(sizeof(*global));
3639 if (global == NULL)
3640 return NULL;
b22128ef
JM
3641 dl_list_init(&global->p2p_srv_bonjour);
3642 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
3643 global->params.daemonize = params->daemonize;
3644 global->params.wait_for_monitor = params->wait_for_monitor;
3645 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3646 if (params->pid_file)
3647 global->params.pid_file = os_strdup(params->pid_file);
3648 if (params->ctrl_interface)
3649 global->params.ctrl_interface =
3650 os_strdup(params->ctrl_interface);
29257565
JM
3651 if (params->ctrl_interface_group)
3652 global->params.ctrl_interface_group =
3653 os_strdup(params->ctrl_interface_group);
d27df100
JM
3654 if (params->override_driver)
3655 global->params.override_driver =
3656 os_strdup(params->override_driver);
3657 if (params->override_ctrl_interface)
3658 global->params.override_ctrl_interface =
3659 os_strdup(params->override_ctrl_interface);
6fc6879b
JM
3660 wpa_debug_level = global->params.wpa_debug_level =
3661 params->wpa_debug_level;
3662 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3663 params->wpa_debug_show_keys;
3664 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3665 params->wpa_debug_timestamp;
3666
f19858f5
JM
3667 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3668
0456ea16 3669 if (eloop_init()) {
6fc6879b
JM
3670 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3671 wpa_supplicant_deinit(global);
3672 return NULL;
3673 }
3674
38e24575 3675 random_init(params->entropy_file);
d47fa330 3676
6fc6879b
JM
3677 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3678 if (global->ctrl_iface == NULL) {
3679 wpa_supplicant_deinit(global);
3680 return NULL;
3681 }
3682
dc461de4
WS
3683 if (wpas_notify_supplicant_initialized(global)) {
3684 wpa_supplicant_deinit(global);
3685 return NULL;
6fc6879b
JM
3686 }
3687
c5121837 3688 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
3689 global->drv_count++;
3690 if (global->drv_count == 0) {
3691 wpa_printf(MSG_ERROR, "No drivers enabled");
3692 wpa_supplicant_deinit(global);
3693 return NULL;
3694 }
3695 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3696 if (global->drv_priv == NULL) {
3697 wpa_supplicant_deinit(global);
3698 return NULL;
3699 }
ac305589 3700
9675ce35
JM
3701#ifdef CONFIG_WIFI_DISPLAY
3702 if (wifi_display_init(global) < 0) {
3703 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3704 wpa_supplicant_deinit(global);
3705 return NULL;
3706 }
3707#endif /* CONFIG_WIFI_DISPLAY */
3708
6fc6879b
JM
3709 return global;
3710}
3711
3712
3713/**
3714 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3715 * @global: Pointer to global data from wpa_supplicant_init()
3716 * Returns: 0 after successful event loop run, -1 on failure
3717 *
3718 * This function starts the main event loop and continues running as long as
3719 * there are any remaining events. In most cases, this function is running as
3720 * long as the %wpa_supplicant process in still in use.
3721 */
3722int wpa_supplicant_run(struct wpa_global *global)
3723{
3724 struct wpa_supplicant *wpa_s;
3725
3726 if (global->params.daemonize &&
3727 wpa_supplicant_daemon(global->params.pid_file))
3728 return -1;
3729
3730 if (global->params.wait_for_monitor) {
3731 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3732 if (wpa_s->ctrl_iface)
3733 wpa_supplicant_ctrl_iface_wait(
3734 wpa_s->ctrl_iface);
3735 }
3736
0456ea16
JM
3737 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3738 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
3739
3740 eloop_run();
3741
3742 return 0;
3743}
3744
3745
3746/**
3747 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3748 * @global: Pointer to global data from wpa_supplicant_init()
3749 *
3750 * This function is called to deinitialize %wpa_supplicant and to free all
3751 * allocated resources. Remaining network interfaces will also be removed.
3752 */
3753void wpa_supplicant_deinit(struct wpa_global *global)
3754{
ac305589
JM
3755 int i;
3756
6fc6879b
JM
3757 if (global == NULL)
3758 return;
3759
9675ce35
JM
3760#ifdef CONFIG_WIFI_DISPLAY
3761 wifi_display_deinit(global);
3762#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 3763
6fc6879b 3764 while (global->ifaces)
df509539 3765 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
3766
3767 if (global->ctrl_iface)
3768 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
3769
3770 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
3771
3772 eap_peer_unregister_methods();
3ec97afe
JM
3773#ifdef CONFIG_AP
3774 eap_server_unregister_methods();
3775#endif /* CONFIG_AP */
6fc6879b 3776
c5121837 3777 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
3778 if (!global->drv_priv[i])
3779 continue;
c5121837 3780 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
3781 }
3782 os_free(global->drv_priv);
3783
d47fa330
JM
3784 random_deinit();
3785
6fc6879b
JM
3786 eloop_destroy();
3787
3788 if (global->params.pid_file) {
3789 os_daemonize_terminate(global->params.pid_file);
3790 os_free(global->params.pid_file);
3791 }
3792 os_free(global->params.ctrl_interface);
29257565 3793 os_free(global->params.ctrl_interface_group);
d27df100
JM
3794 os_free(global->params.override_driver);
3795 os_free(global->params.override_ctrl_interface);
6fc6879b 3796
af8a827b 3797 os_free(global->p2p_disallow_freq.range);
01a57fe4 3798 os_free(global->add_psk);
6f3bc72b 3799
6fc6879b 3800 os_free(global);
daa70d49 3801 wpa_debug_close_syslog();
6fc6879b 3802 wpa_debug_close_file();
4f68895e 3803 wpa_debug_close_linux_tracing();
6fc6879b 3804}
611aea7d
JM
3805
3806
3807void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3808{
849b5dc7
JM
3809 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3810 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3811 char country[3];
3812 country[0] = wpa_s->conf->country[0];
3813 country[1] = wpa_s->conf->country[1];
3814 country[2] = '\0';
3815 if (wpa_drv_set_country(wpa_s, country) < 0) {
3816 wpa_printf(MSG_ERROR, "Failed to set country code "
3817 "'%s'", country);
3818 }
3819 }
3820
306ae225
JM
3821 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3822 wpas_init_ext_pw(wpa_s);
3823
611aea7d
JM
3824#ifdef CONFIG_WPS
3825 wpas_wps_update_config(wpa_s);
3826#endif /* CONFIG_WPS */
3827
b22128ef
JM
3828#ifdef CONFIG_P2P
3829 wpas_p2p_update_config(wpa_s);
3830#endif /* CONFIG_P2P */
3831
611aea7d
JM
3832 wpa_s->conf->changed_parameters = 0;
3833}
2f9c6aa6
JM
3834
3835
0fb337c1
JM
3836static void add_freq(int *freqs, int *num_freqs, int freq)
3837{
3838 int i;
3839
3840 for (i = 0; i < *num_freqs; i++) {
3841 if (freqs[i] == freq)
3842 return;
3843 }
3844
3845 freqs[*num_freqs] = freq;
3846 (*num_freqs)++;
3847}
3848
3849
3850static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3851{
3852 struct wpa_bss *bss, *cbss;
3853 const int max_freqs = 10;
3854 int *freqs;
3855 int num_freqs = 0;
3856
3857 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3858 if (freqs == NULL)
3859 return NULL;
3860
3861 cbss = wpa_s->current_bss;
3862
3863 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3864 if (bss == cbss)
3865 continue;
3866 if (bss->ssid_len == cbss->ssid_len &&
3867 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3868 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3869 add_freq(freqs, &num_freqs, bss->freq);
3870 if (num_freqs == max_freqs)
3871 break;
3872 }
3873 }
3874
3875 if (num_freqs == 0) {
3876 os_free(freqs);
3877 freqs = NULL;
3878 }
3879
3880 return freqs;
3881}
3882
3883
3884void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3885{
3886 int timeout;
3887 int count;
3888 int *freqs = NULL;
3889
5fd9fb27
JM
3890 /*
3891 * Remove possible authentication timeout since the connection failed.
3892 */
3893 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3894
0cdb93fe
JM
3895 if (wpa_s->disconnected) {
3896 /*
3897 * There is no point in blacklisting the AP if this event is
3898 * generated based on local request to disconnect.
3899 */
3900 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
3901 "indication since interface has been put into "
3902 "disconnected state");
3903 return;
3904 }
3905
0fb337c1
JM
3906 /*
3907 * Add the failed BSSID into the blacklist and speed up next scan
3908 * attempt if there could be other APs that could accept association.
3909 * The current blacklist count indicates how many times we have tried
3910 * connecting to this AP and multiple attempts mean that other APs are
3911 * either not available or has already been tried, so that we can start
3912 * increasing the delay here to avoid constant scanning.
3913 */
3914 count = wpa_blacklist_add(wpa_s, bssid);
3915 if (count == 1 && wpa_s->current_bss) {
3916 /*
3917 * This BSS was not in the blacklist before. If there is
3918 * another BSS available for the same ESS, we should try that
3919 * next. Otherwise, we may as well try this one once more
3920 * before allowing other, likely worse, ESSes to be considered.
3921 */
3922 freqs = get_bss_freqs_in_ess(wpa_s);
3923 if (freqs) {
f049052b
BG
3924 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3925 "has been seen; try it next");
0fb337c1
JM
3926 wpa_blacklist_add(wpa_s, bssid);
3927 /*
3928 * On the next scan, go through only the known channels
3929 * used in this ESS based on previous scans to speed up
3930 * common load balancing use case.
3931 */
3932 os_free(wpa_s->next_scan_freqs);
3933 wpa_s->next_scan_freqs = freqs;
3934 }
3935 }
3936
f1a52633
JM
3937 /*
3938 * Add previous failure count in case the temporary blacklist was
3939 * cleared due to no other BSSes being available.
3940 */
3941 count += wpa_s->extra_blacklist_count;
3942
dd579704
JM
3943 if (count > 3 && wpa_s->current_ssid) {
3944 wpa_printf(MSG_DEBUG, "Continuous association failures - "
3945 "consider temporary network disabling");
3946 wpas_auth_failed(wpa_s);
3947 }
3948
0fb337c1
JM
3949 switch (count) {
3950 case 1:
3951 timeout = 100;
3952 break;
3953 case 2:
3954 timeout = 500;
3955 break;
3956 case 3:
3957 timeout = 1000;
3958 break;
f1a52633 3959 case 4:
0fb337c1 3960 timeout = 5000;
f1a52633
JM
3961 break;
3962 default:
3963 timeout = 10000;
3964 break;
0fb337c1
JM
3965 }
3966
f1a52633
JM
3967 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3968 "ms", count, timeout);
3969
0fb337c1
JM
3970 /*
3971 * TODO: if more than one possible AP is available in scan results,
3972 * could try the other ones before requesting a new scan.
3973 */
3974 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3975 1000 * (timeout % 1000));
3976}
22628eca
JM
3977
3978
3979int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3980{
3981 return wpa_s->conf->ap_scan == 2 ||
3982 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3983}
d2118814
JM
3984
3985
3986#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3987int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3988 struct wpa_ssid *ssid,
3989 const char *field,
3990 const char *value)
3991{
3992#ifdef IEEE8021X_EAPOL
3993 struct eap_peer_config *eap = &ssid->eap;
3994
3995 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3996 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3997 (const u8 *) value, os_strlen(value));
3998
3999 switch (wpa_supplicant_ctrl_req_from_string(field)) {
4000 case WPA_CTRL_REQ_EAP_IDENTITY:
4001 os_free(eap->identity);
4002 eap->identity = (u8 *) os_strdup(value);
4003 eap->identity_len = os_strlen(value);
4004 eap->pending_req_identity = 0;
4005 if (ssid == wpa_s->current_ssid)
4006 wpa_s->reassociate = 1;
4007 break;
4008 case WPA_CTRL_REQ_EAP_PASSWORD:
4009 os_free(eap->password);
4010 eap->password = (u8 *) os_strdup(value);
4011 eap->password_len = os_strlen(value);
4012 eap->pending_req_password = 0;
4013 if (ssid == wpa_s->current_ssid)
4014 wpa_s->reassociate = 1;
4015 break;
4016 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
4017 os_free(eap->new_password);
4018 eap->new_password = (u8 *) os_strdup(value);
4019 eap->new_password_len = os_strlen(value);
4020 eap->pending_req_new_password = 0;
4021 if (ssid == wpa_s->current_ssid)
4022 wpa_s->reassociate = 1;
4023 break;
4024 case WPA_CTRL_REQ_EAP_PIN:
4025 os_free(eap->pin);
4026 eap->pin = os_strdup(value);
4027 eap->pending_req_pin = 0;
4028 if (ssid == wpa_s->current_ssid)
4029 wpa_s->reassociate = 1;
4030 break;
4031 case WPA_CTRL_REQ_EAP_OTP:
4032 os_free(eap->otp);
4033 eap->otp = (u8 *) os_strdup(value);
4034 eap->otp_len = os_strlen(value);
4035 os_free(eap->pending_req_otp);
4036 eap->pending_req_otp = NULL;
4037 eap->pending_req_otp_len = 0;
4038 break;
4039 case WPA_CTRL_REQ_EAP_PASSPHRASE:
4040 os_free(eap->private_key_passwd);
4041 eap->private_key_passwd = (u8 *) os_strdup(value);
4042 eap->pending_req_passphrase = 0;
4043 if (ssid == wpa_s->current_ssid)
4044 wpa_s->reassociate = 1;
4045 break;
a5d44ac0
JM
4046 case WPA_CTRL_REQ_SIM:
4047 os_free(eap->external_sim_resp);
4048 eap->external_sim_resp = os_strdup(value);
4049 break;
d2118814
JM
4050 default:
4051 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
4052 return -1;
4053 }
4054
4055 return 0;
4056#else /* IEEE8021X_EAPOL */
4057 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
4058 return -1;
4059#endif /* IEEE8021X_EAPOL */
4060}
4061#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
4062
4063
4064int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
4065{
4066 int i;
4067 unsigned int drv_enc;
4068
4069 if (ssid == NULL)
4070 return 1;
4071
4072 if (ssid->disabled)
4073 return 1;
4074
4075 if (wpa_s && wpa_s->drv_capa_known)
4076 drv_enc = wpa_s->drv_enc;
4077 else
4078 drv_enc = (unsigned int) -1;
4079
4080 for (i = 0; i < NUM_WEP_KEYS; i++) {
4081 size_t len = ssid->wep_key_len[i];
4082 if (len == 0)
4083 continue;
4084 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
4085 continue;
4086 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
4087 continue;
4088 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
4089 continue;
4090 return 1; /* invalid WEP key */
4091 }
4092
9173b16f
JM
4093 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
4094 !ssid->ext_psk)
2518aad3
JM
4095 return 1;
4096
349493bd
JM
4097 return 0;
4098}
b9cfc09a
JJ
4099
4100
4101int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
4102{
4103 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
4104 return 1;
4105 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
4106 return 0;
4107 return -1;
4108}
00e5e3d5
JM
4109
4110
4111void wpas_auth_failed(struct wpa_supplicant *wpa_s)
4112{
4113 struct wpa_ssid *ssid = wpa_s->current_ssid;
4114 int dur;
4e1eae1d 4115 struct os_reltime now;
00e5e3d5
JM
4116
4117 if (ssid == NULL) {
4118 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
4119 "SSID block");
4120 return;
4121 }
4122
4123 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
4124 return;
4125
4126 ssid->auth_failures++;
cbf41ca7
SL
4127
4128#ifdef CONFIG_P2P
4129 if (ssid->p2p_group &&
4130 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
4131 /*
4132 * Skip the wait time since there is a short timeout on the
4133 * connection to a P2P group.
4134 */
4135 return;
4136 }
4137#endif /* CONFIG_P2P */
4138
00e5e3d5
JM
4139 if (ssid->auth_failures > 50)
4140 dur = 300;
4141 else if (ssid->auth_failures > 20)
4142 dur = 120;
4143 else if (ssid->auth_failures > 10)
4144 dur = 60;
4145 else if (ssid->auth_failures > 5)
4146 dur = 30;
4147 else if (ssid->auth_failures > 1)
4148 dur = 20;
4149 else
4150 dur = 10;
4151
4e1eae1d 4152 os_get_reltime(&now);
00e5e3d5
JM
4153 if (now.sec + dur <= ssid->disabled_until.sec)
4154 return;
4155
4156 ssid->disabled_until.sec = now.sec + dur;
4157
4158 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
4159 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
4160 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
4161 ssid->auth_failures, dur);
4162}
4163
4164
4165void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
4166 struct wpa_ssid *ssid, int clear_failures)
4167{
4168 if (ssid == NULL)
4169 return;
4170
4171 if (ssid->disabled_until.sec) {
4172 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
4173 "id=%d ssid=\"%s\"",
4174 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
4175 }
4176 ssid->disabled_until.sec = 0;
4177 ssid->disabled_until.usec = 0;
4178 if (clear_failures)
4179 ssid->auth_failures = 0;
4180}
6407f413
JM
4181
4182
4183int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
4184{
4185 size_t i;
4186
4187 if (wpa_s->disallow_aps_bssid == NULL)
4188 return 0;
4189
4190 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
4191 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
4192 bssid, ETH_ALEN) == 0)
4193 return 1;
4194 }
4195
4196 return 0;
4197}
4198
4199
4200int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
4201 size_t ssid_len)
4202{
4203 size_t i;
4204
4205 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
4206 return 0;
4207
4208 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
4209 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
4210 if (ssid_len == s->ssid_len &&
4211 os_memcmp(ssid, s->ssid, ssid_len) == 0)
4212 return 1;
4213 }
4214
4215 return 0;
4216}
9796a86c
JM
4217
4218
4219/**
4220 * wpas_request_connection - Request a new connection
4221 * @wpa_s: Pointer to the network interface
4222 *
4223 * This function is used to request a new connection to be found. It will mark
4224 * the interface to allow reassociation and request a new scan to find a
4225 * suitable network to connect to.
4226 */
4227void wpas_request_connection(struct wpa_supplicant *wpa_s)
4228{
4229 wpa_s->normal_scans = 0;
4230 wpa_supplicant_reinit_autoscan(wpa_s);
4231 wpa_s->extra_blacklist_count = 0;
4232 wpa_s->disconnected = 0;
4233 wpa_s->reassociate = 1;
5e24beae
MH
4234
4235 if (wpa_supplicant_fast_associate(wpa_s) != 1)
4236 wpa_supplicant_req_scan(wpa_s, 0, 0);
9796a86c 4237}
36b9883d
DG
4238
4239
c3775143
KP
4240static int wpas_conn_in_progress(struct wpa_supplicant *wpa_s)
4241{
4242 return wpa_s->wpa_state >= WPA_AUTHENTICATING &&
4243 wpa_s->wpa_state != WPA_COMPLETED;
4244}
4245
4246
36b9883d
DG
4247/**
4248 * wpas_wpa_is_in_progress - Check whether a connection is in progress
4249 * @wpa_s: Pointer to wpa_supplicant data
c3775143 4250 * @include_current: Whether to consider specified interface
36b9883d
DG
4251 *
4252 * This function is to check if the wpa state is in beginning of the connection
4253 * during 4-way handshake or group key handshake with WPA on any shared
4254 * interface.
4255 */
c3775143 4256int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s, int include_current)
36b9883d 4257{
36b9883d
DG
4258 struct wpa_supplicant *ifs;
4259
1b544ffa
JM
4260 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
4261 radio_list) {
c3775143
KP
4262 if (!include_current && ifs == wpa_s)
4263 continue;
36b9883d 4264
c3775143 4265 if (wpas_conn_in_progress(ifs)) {
36b9883d 4266 wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress "
c3775143 4267 "on interface %s - defer", ifs->ifname);
36b9883d
DG
4268 return 1;
4269 }
4270 }
4271
4272 return 0;
4273}
53c5dfc2
IP
4274
4275
217cf499
JM
4276void dump_freq_array(struct wpa_supplicant *wpa_s, const char *title,
4277 int *freq_array, unsigned int len)
4278{
4279 unsigned int i;
4280
4281 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
4282 len, title);
4283 for (i = 0; i < len; i++)
4284 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d", i, freq_array[i]);
4285}
4286
4287
53c5dfc2
IP
4288/*
4289 * Find the operating frequencies of any of the virtual interfaces that
4290 * are using the same radio as the current interface.
4291 */
4292int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
4293 int *freq_array, unsigned int len)
4294{
53c5dfc2
IP
4295 struct wpa_supplicant *ifs;
4296 u8 bssid[ETH_ALEN];
4297 int freq;
4298 unsigned int idx = 0, i;
4299
217cf499
JM
4300 wpa_dbg(wpa_s, MSG_DEBUG,
4301 "Determining shared radio frequencies (max len %u)", len);
53c5dfc2
IP
4302 os_memset(freq_array, 0, sizeof(int) * len);
4303
4304 /* First add the frequency of the local interface */
4305 if (wpa_s->current_ssid != NULL && wpa_s->assoc_freq != 0) {
4306 if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
4307 wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)
4308 freq_array[idx++] = wpa_s->current_ssid->frequency;
4309 else if (wpa_drv_get_bssid(wpa_s, bssid) == 0)
4310 freq_array[idx++] = wpa_s->assoc_freq;
4311 }
4312
4313 /* If get_radio_name is not supported, use only the local freq */
a21816a9
JM
4314 if (!wpa_s->driver->get_radio_name) {
4315 freq = wpa_drv_shared_freq(wpa_s);
4316 if (freq > 0 && idx < len &&
4317 (idx == 0 || freq_array[0] != freq))
4318 freq_array[idx++] = freq;
217cf499 4319 dump_freq_array(wpa_s, "No get_radio_name", freq_array, idx);
53c5dfc2 4320 return idx;
a21816a9 4321 }
53c5dfc2 4322
0ad3b9c4
JM
4323 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
4324 radio_list) {
4325 if (wpa_s == ifs)
53c5dfc2
IP
4326 continue;
4327
4328 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
4329 continue;
4330
4331 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
4332 ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
4333 freq = ifs->current_ssid->frequency;
4334 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
4335 freq = ifs->assoc_freq;
4336 else
4337 continue;
4338
4339 /* Hold only distinct freqs */
4340 for (i = 0; i < idx; i++)
4341 if (freq_array[i] == freq)
4342 break;
4343
4344 if (i == idx)
4345 freq_array[idx++] = freq;
4346 }
217cf499
JM
4347
4348 dump_freq_array(wpa_s, "completed iteration", freq_array, idx);
53c5dfc2
IP
4349 return idx;
4350}