blob: 5bb1f72c865ae70fd6d41f0733a6e86c534f6a93 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant
Dmitry Shmidtde47be72016-01-07 12:52:55 -08003 * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 *
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"
Dmitry Shmidte4663042016-04-04 10:07:49 -070014#ifdef CONFIG_MATCH_IFACE
15#include <net/if.h>
16#include <fnmatch.h>
17#endif /* CONFIG_MATCH_IFACE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018
19#include "common.h"
20#include "crypto/random.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080021#include "crypto/sha1.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070022#include "eapol_supp/eapol_supp_sm.h"
23#include "eap_peer/eap.h"
Dmitry Shmidt34af3062013-07-11 10:46:32 -070024#include "eap_peer/eap_proxy.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070025#include "eap_server/eap_methods.h"
26#include "rsn_supp/wpa.h"
27#include "eloop.h"
28#include "config.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070029#include "utils/ext_password.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070030#include "l2_packet/l2_packet.h"
31#include "wpa_supplicant_i.h"
32#include "driver_i.h"
33#include "ctrl_iface.h"
34#include "pcsc_funcs.h"
35#include "common/version.h"
36#include "rsn_supp/preauth.h"
37#include "rsn_supp/pmksa_cache.h"
38#include "common/wpa_ctrl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070039#include "common/ieee802_11_defs.h"
Dmitry Shmidtff787d52015-01-12 13:01:47 -080040#include "common/hw_features_common.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070041#include "p2p/p2p.h"
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080042#include "fst/fst.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070043#include "blacklist.h"
44#include "wpas_glue.h"
45#include "wps_supplicant.h"
46#include "ibss_rsn.h"
47#include "sme.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080048#include "gas_query.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070049#include "ap.h"
50#include "p2p_supplicant.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070051#include "wifi_display.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070052#include "notify.h"
53#include "bgscan.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070054#include "autoscan.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070055#include "bss.h"
56#include "scan.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080057#include "offchannel.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070058#include "hs20_supplicant.h"
Dmitry Shmidt44c95782013-05-17 09:51:35 -070059#include "wnm_sta.h"
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -070060#include "wpas_kay.h"
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -080061#include "mesh.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070062
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070063const char *const wpa_supplicant_version =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070064"wpa_supplicant v" VERSION_STR "\n"
Dmitry Shmidtde47be72016-01-07 12:52:55 -080065"Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> and contributors";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070066
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070067const char *const wpa_supplicant_license =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080068"This software may be distributed under the terms of the BSD license.\n"
69"See README for more details.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070070#ifdef EAP_TLS_OPENSSL
71"\nThis product includes software developed by the OpenSSL Project\n"
72"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
73#endif /* EAP_TLS_OPENSSL */
74;
75
76#ifndef CONFIG_NO_STDOUT_DEBUG
77/* Long text divided into parts in order to fit in C89 strings size limits. */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070078const char *const wpa_supplicant_full_license1 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080079"";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070080const char *const wpa_supplicant_full_license2 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080081"This software may be distributed under the terms of the BSD license.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070082"\n"
83"Redistribution and use in source and binary forms, with or without\n"
84"modification, are permitted provided that the following conditions are\n"
85"met:\n"
86"\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070087const char *const wpa_supplicant_full_license3 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070088"1. Redistributions of source code must retain the above copyright\n"
89" notice, this list of conditions and the following disclaimer.\n"
90"\n"
91"2. Redistributions in binary form must reproduce the above copyright\n"
92" notice, this list of conditions and the following disclaimer in the\n"
93" documentation and/or other materials provided with the distribution.\n"
94"\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070095const char *const wpa_supplicant_full_license4 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070096"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
97" names of its contributors may be used to endorse or promote products\n"
98" derived from this software without specific prior written permission.\n"
99"\n"
100"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
101"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
102"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
103"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -0700104const char *const wpa_supplicant_full_license5 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700105"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
106"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
107"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
108"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
109"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
110"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
111"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
112"\n";
113#endif /* CONFIG_NO_STDOUT_DEBUG */
114
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700115/* Configure default/group WEP keys for static WEP */
116int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
117{
118 int i, set = 0;
119
120 for (i = 0; i < NUM_WEP_KEYS; i++) {
121 if (ssid->wep_key_len[i] == 0)
122 continue;
123
124 set = 1;
125 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
126 i, i == ssid->wep_tx_keyidx, NULL, 0,
127 ssid->wep_key[i], ssid->wep_key_len[i]);
128 }
129
130 return set;
131}
132
133
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -0700134int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
135 struct wpa_ssid *ssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700136{
137 u8 key[32];
138 size_t keylen;
139 enum wpa_alg alg;
140 u8 seq[6] = { 0 };
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800141 int ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700142
143 /* IBSS/WPA-None uses only one key (Group) for both receiving and
144 * sending unicast and multicast packets. */
145
146 if (ssid->mode != WPAS_MODE_IBSS) {
147 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
148 "IBSS/ad-hoc) for WPA-None", ssid->mode);
149 return -1;
150 }
151
152 if (!ssid->psk_set) {
153 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
154 "WPA-None");
155 return -1;
156 }
157
158 switch (wpa_s->group_cipher) {
159 case WPA_CIPHER_CCMP:
160 os_memcpy(key, ssid->psk, 16);
161 keylen = 16;
162 alg = WPA_ALG_CCMP;
163 break;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700164 case WPA_CIPHER_GCMP:
165 os_memcpy(key, ssid->psk, 16);
166 keylen = 16;
167 alg = WPA_ALG_GCMP;
168 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700169 case WPA_CIPHER_TKIP:
170 /* WPA-None uses the same Michael MIC key for both TX and RX */
171 os_memcpy(key, ssid->psk, 16 + 8);
172 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
173 keylen = 32;
174 alg = WPA_ALG_TKIP;
175 break;
176 default:
177 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
178 "WPA-None", wpa_s->group_cipher);
179 return -1;
180 }
181
182 /* TODO: should actually remember the previously used seq#, both for TX
183 * and RX from each STA.. */
184
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800185 ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
186 os_memset(key, 0, sizeof(key));
187 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700188}
189
190
191static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
192{
193 struct wpa_supplicant *wpa_s = eloop_ctx;
194 const u8 *bssid = wpa_s->bssid;
195 if (is_zero_ether_addr(bssid))
196 bssid = wpa_s->pending_bssid;
197 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
198 MAC2STR(bssid));
199 wpa_blacklist_add(wpa_s, bssid);
200 wpa_sm_notify_disassoc(wpa_s->wpa);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800201 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700202 wpa_s->reassociate = 1;
203
204 /*
205 * If we timed out, the AP or the local radio may be busy.
206 * So, wait a second until scanning again.
207 */
208 wpa_supplicant_req_scan(wpa_s, 1, 0);
209}
210
211
212/**
213 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
214 * @wpa_s: Pointer to wpa_supplicant data
215 * @sec: Number of seconds after which to time out authentication
216 * @usec: Number of microseconds after which to time out authentication
217 *
218 * This function is used to schedule a timeout for the current authentication
219 * attempt.
220 */
221void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
222 int sec, int usec)
223{
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700224 if (wpa_s->conf->ap_scan == 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700225 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
226 return;
227
228 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
229 "%d usec", sec, usec);
230 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
231 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
232}
233
234
235/**
236 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
237 * @wpa_s: Pointer to wpa_supplicant data
238 *
239 * This function is used to cancel authentication timeout scheduled with
240 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
241 * been completed.
242 */
243void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
244{
245 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
246 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
247 wpa_blacklist_del(wpa_s, wpa_s->bssid);
248}
249
250
251/**
252 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
253 * @wpa_s: Pointer to wpa_supplicant data
254 *
255 * This function is used to configure EAPOL state machine based on the selected
256 * authentication mode.
257 */
258void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
259{
260#ifdef IEEE8021X_EAPOL
261 struct eapol_config eapol_conf;
262 struct wpa_ssid *ssid = wpa_s->current_ssid;
263
264#ifdef CONFIG_IBSS_RSN
265 if (ssid->mode == WPAS_MODE_IBSS &&
266 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
267 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
268 /*
269 * RSN IBSS authentication is per-STA and we can disable the
270 * per-BSSID EAPOL authentication.
271 */
272 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
273 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
274 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
275 return;
276 }
277#endif /* CONFIG_IBSS_RSN */
278
279 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
280 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
281
282 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
283 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
284 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
285 else
286 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
287
288 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
289 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
290 eapol_conf.accept_802_1x_keys = 1;
291 eapol_conf.required_keys = 0;
292 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
293 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
294 }
295 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
296 eapol_conf.required_keys |=
297 EAPOL_REQUIRE_KEY_BROADCAST;
298 }
299
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700300 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700301 eapol_conf.required_keys = 0;
302 }
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700303 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700304 eapol_conf.workaround = ssid->eap_workaround;
305 eapol_conf.eap_disabled =
306 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
307 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
308 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
Dmitry Shmidt051af732013-10-22 13:52:46 -0700309 eapol_conf.external_sim = wpa_s->conf->external_sim;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800310
311#ifdef CONFIG_WPS
312 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
313 eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
314 if (wpa_s->current_bss) {
315 struct wpabuf *ie;
316 ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
317 WPS_IE_VENDOR_TYPE);
318 if (ie) {
319 if (wps_is_20(ie))
320 eapol_conf.wps |=
321 EAPOL_PEER_IS_WPS20_AP;
322 wpabuf_free(ie);
323 }
324 }
325 }
326#endif /* CONFIG_WPS */
327
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700328 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -0700329
330 ieee802_1x_alloc_kay_sm(wpa_s, ssid);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800331#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700332}
333
334
335/**
336 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
337 * @wpa_s: Pointer to wpa_supplicant data
338 * @ssid: Configuration data for the network
339 *
340 * This function is used to configure WPA state machine and related parameters
341 * to a mode where WPA is not enabled. This is called as part of the
342 * authentication configuration when the selected network does not use WPA.
343 */
344void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
345 struct wpa_ssid *ssid)
346{
347 int i;
348
349 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
350 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
351 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
352 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
353 else
354 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
355 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
356 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
357 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
358 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
359 wpa_s->group_cipher = WPA_CIPHER_NONE;
360 wpa_s->mgmt_group_cipher = 0;
361
362 for (i = 0; i < NUM_WEP_KEYS; i++) {
363 if (ssid->wep_key_len[i] > 5) {
364 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
365 wpa_s->group_cipher = WPA_CIPHER_WEP104;
366 break;
367 } else if (ssid->wep_key_len[i] > 0) {
368 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
369 wpa_s->group_cipher = WPA_CIPHER_WEP40;
370 break;
371 }
372 }
373
374 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
375 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
376 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
377 wpa_s->pairwise_cipher);
378 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
379#ifdef CONFIG_IEEE80211W
380 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
381 wpa_s->mgmt_group_cipher);
382#endif /* CONFIG_IEEE80211W */
383
384 pmksa_cache_clear_current(wpa_s->wpa);
385}
386
387
Dmitry Shmidt04949592012-07-19 12:16:46 -0700388void free_hw_features(struct wpa_supplicant *wpa_s)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800389{
390 int i;
391 if (wpa_s->hw.modes == NULL)
392 return;
393
394 for (i = 0; i < wpa_s->hw.num_modes; i++) {
395 os_free(wpa_s->hw.modes[i].channels);
396 os_free(wpa_s->hw.modes[i].rates);
397 }
398
399 os_free(wpa_s->hw.modes);
400 wpa_s->hw.modes = NULL;
401}
402
403
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800404static void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s)
405{
406 struct wpa_bss_tmp_disallowed *bss, *prev;
407
408 dl_list_for_each_safe(bss, prev, &wpa_s->bss_tmp_disallowed,
409 struct wpa_bss_tmp_disallowed, list) {
410 dl_list_del(&bss->list);
411 os_free(bss);
412 }
413}
414
415
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700416static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
417{
Dmitry Shmidt2e67f062014-07-16 09:55:28 -0700418 int i;
419
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700420 bgscan_deinit(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700421 autoscan_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700422 scard_deinit(wpa_s->scard);
423 wpa_s->scard = NULL;
424 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
425 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
426 l2_packet_deinit(wpa_s->l2);
427 wpa_s->l2 = NULL;
428 if (wpa_s->l2_br) {
429 l2_packet_deinit(wpa_s->l2_br);
430 wpa_s->l2_br = NULL;
431 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800432#ifdef CONFIG_TESTING_OPTIONS
433 l2_packet_deinit(wpa_s->l2_test);
434 wpa_s->l2_test = NULL;
435#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700436
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700437 if (wpa_s->conf != NULL) {
438 struct wpa_ssid *ssid;
439 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
440 wpas_notify_network_removed(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700441 }
442
443 os_free(wpa_s->confname);
444 wpa_s->confname = NULL;
445
Jouni Malinen5d1c8ad2013-04-23 12:34:56 -0700446 os_free(wpa_s->confanother);
447 wpa_s->confanother = NULL;
448
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700449 wpa_sm_set_eapol(wpa_s->wpa, NULL);
450 eapol_sm_deinit(wpa_s->eapol);
451 wpa_s->eapol = NULL;
452
453 rsn_preauth_deinit(wpa_s->wpa);
454
455#ifdef CONFIG_TDLS
456 wpa_tdls_deinit(wpa_s->wpa);
457#endif /* CONFIG_TDLS */
458
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800459 wmm_ac_clear_saved_tspecs(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700460 pmksa_candidate_free(wpa_s->wpa);
461 wpa_sm_deinit(wpa_s->wpa);
462 wpa_s->wpa = NULL;
463 wpa_blacklist_clear(wpa_s);
464
465 wpa_bss_deinit(wpa_s);
466
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -0700467 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700468 wpa_supplicant_cancel_scan(wpa_s);
469 wpa_supplicant_cancel_auth_timeout(wpa_s);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800470 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
471#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
472 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
473 wpa_s, NULL);
474#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700475
Dmitry Shmidtdda10c22015-03-24 16:05:01 -0700476 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
477
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700478 wpas_wps_deinit(wpa_s);
479
480 wpabuf_free(wpa_s->pending_eapol_rx);
481 wpa_s->pending_eapol_rx = NULL;
482
483#ifdef CONFIG_IBSS_RSN
484 ibss_rsn_deinit(wpa_s->ibss_rsn);
485 wpa_s->ibss_rsn = NULL;
486#endif /* CONFIG_IBSS_RSN */
487
488 sme_deinit(wpa_s);
489
490#ifdef CONFIG_AP
491 wpa_supplicant_ap_deinit(wpa_s);
492#endif /* CONFIG_AP */
493
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700494 wpas_p2p_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700495
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800496#ifdef CONFIG_OFFCHANNEL
497 offchannel_deinit(wpa_s);
498#endif /* CONFIG_OFFCHANNEL */
499
500 wpa_supplicant_cancel_sched_scan(wpa_s);
501
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700502 os_free(wpa_s->next_scan_freqs);
503 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800504
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800505 os_free(wpa_s->manual_scan_freqs);
506 wpa_s->manual_scan_freqs = NULL;
507
Dmitry Shmidtd11f0192014-03-24 12:09:47 -0700508 os_free(wpa_s->manual_sched_scan_freqs);
509 wpa_s->manual_sched_scan_freqs = NULL;
510
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800511 wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
512
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700513 /*
514 * Need to remove any pending gas-query radio work before the
515 * gas_query_deinit() call because gas_query::work has not yet been set
516 * for works that have not been started. gas_query_free() will be unable
517 * to cancel such pending radio works and once the pending gas-query
518 * radio work eventually gets removed, the deinit notification call to
519 * gas_query_start_cb() would result in dereferencing freed memory.
520 */
521 if (wpa_s->radio)
522 radio_remove_works(wpa_s, "gas-query", 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800523 gas_query_deinit(wpa_s->gas);
524 wpa_s->gas = NULL;
525
526 free_hw_features(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700527
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -0700528 ieee802_1x_dealloc_kay_sm(wpa_s);
529
Dmitry Shmidt04949592012-07-19 12:16:46 -0700530 os_free(wpa_s->bssid_filter);
531 wpa_s->bssid_filter = NULL;
532
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800533 os_free(wpa_s->disallow_aps_bssid);
534 wpa_s->disallow_aps_bssid = NULL;
535 os_free(wpa_s->disallow_aps_ssid);
536 wpa_s->disallow_aps_ssid = NULL;
537
Dmitry Shmidt04949592012-07-19 12:16:46 -0700538 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt44c95782013-05-17 09:51:35 -0700539#ifdef CONFIG_WNM
540 wnm_deallocate_memory(wpa_s);
541#endif /* CONFIG_WNM */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700542
543 ext_password_deinit(wpa_s->ext_pw);
544 wpa_s->ext_pw = NULL;
545
546 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800547 wpa_s->last_gas_resp = NULL;
548 wpabuf_free(wpa_s->prev_gas_resp);
549 wpa_s->prev_gas_resp = NULL;
Dmitry Shmidt9bce59c2012-09-11 15:06:38 -0700550
551 os_free(wpa_s->last_scan_res);
552 wpa_s->last_scan_res = NULL;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800553
554#ifdef CONFIG_HS20
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700555 if (wpa_s->drv_priv)
556 wpa_drv_configure_frame_filters(wpa_s, 0);
Dmitry Shmidt684785c2014-05-12 13:34:29 -0700557 hs20_deinit(wpa_s);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800558#endif /* CONFIG_HS20 */
Dmitry Shmidt2e67f062014-07-16 09:55:28 -0700559
560 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
561 wpabuf_free(wpa_s->vendor_elem[i]);
562 wpa_s->vendor_elem[i] = NULL;
563 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800564
565 wmm_ac_notify_disassoc(wpa_s);
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800566
567 wpa_s->sched_scan_plans_num = 0;
568 os_free(wpa_s->sched_scan_plans);
569 wpa_s->sched_scan_plans = NULL;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800570
571#ifdef CONFIG_MBO
572 wpa_s->non_pref_chan_num = 0;
573 os_free(wpa_s->non_pref_chan);
574 wpa_s->non_pref_chan = NULL;
575#endif /* CONFIG_MBO */
576
577 free_bss_tmp_disallowed(wpa_s);
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700578
579 wpabuf_free(wpa_s->lci);
580 wpa_s->lci = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700581}
582
583
584/**
585 * wpa_clear_keys - Clear keys configured for the driver
586 * @wpa_s: Pointer to wpa_supplicant data
587 * @addr: Previously used BSSID or %NULL if not available
588 *
589 * This function clears the encryption keys that has been previously configured
590 * for the driver.
591 */
592void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
593{
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800594 int i, max;
595
596#ifdef CONFIG_IEEE80211W
597 max = 6;
598#else /* CONFIG_IEEE80211W */
599 max = 4;
600#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700601
602 /* MLME-DELETEKEYS.request */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800603 for (i = 0; i < max; i++) {
604 if (wpa_s->keys_cleared & BIT(i))
605 continue;
606 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
607 NULL, 0);
608 }
609 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
610 !is_zero_ether_addr(addr)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700611 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
612 0);
613 /* MLME-SETPROTECTION.request(None) */
614 wpa_drv_mlme_setprotection(
615 wpa_s, addr,
616 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
617 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
618 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800619 wpa_s->keys_cleared = (u32) -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700620}
621
622
623/**
624 * wpa_supplicant_state_txt - Get the connection state name as a text string
625 * @state: State (wpa_state; WPA_*)
626 * Returns: The state name as a printable text string
627 */
628const char * wpa_supplicant_state_txt(enum wpa_states state)
629{
630 switch (state) {
631 case WPA_DISCONNECTED:
632 return "DISCONNECTED";
633 case WPA_INACTIVE:
634 return "INACTIVE";
635 case WPA_INTERFACE_DISABLED:
636 return "INTERFACE_DISABLED";
637 case WPA_SCANNING:
638 return "SCANNING";
639 case WPA_AUTHENTICATING:
640 return "AUTHENTICATING";
641 case WPA_ASSOCIATING:
642 return "ASSOCIATING";
643 case WPA_ASSOCIATED:
644 return "ASSOCIATED";
645 case WPA_4WAY_HANDSHAKE:
646 return "4WAY_HANDSHAKE";
647 case WPA_GROUP_HANDSHAKE:
648 return "GROUP_HANDSHAKE";
649 case WPA_COMPLETED:
650 return "COMPLETED";
651 default:
652 return "UNKNOWN";
653 }
654}
655
656
657#ifdef CONFIG_BGSCAN
658
659static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
660{
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800661 const char *name;
662
663 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
664 name = wpa_s->current_ssid->bgscan;
665 else
666 name = wpa_s->conf->bgscan;
Dmitry Shmidta38abf92014-03-06 13:38:44 -0800667 if (name == NULL || name[0] == '\0')
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800668 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800669 if (wpas_driver_bss_selection(wpa_s))
670 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700671 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
672 return;
Dmitry Shmidta38abf92014-03-06 13:38:44 -0800673#ifdef CONFIG_P2P
674 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
675 return;
676#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700677
678 bgscan_deinit(wpa_s);
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800679 if (wpa_s->current_ssid) {
680 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700681 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
682 "bgscan");
683 /*
684 * Live without bgscan; it is only used as a roaming
685 * optimization, so the initial connection is not
686 * affected.
687 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700688 } else {
689 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700690 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700691 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
692 0);
693 if (scan_res) {
694 bgscan_notify_scan(wpa_s, scan_res);
695 wpa_scan_results_free(scan_res);
696 }
697 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700698 } else
699 wpa_s->bgscan_ssid = NULL;
700}
701
702
703static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
704{
705 if (wpa_s->bgscan_ssid != NULL) {
706 bgscan_deinit(wpa_s);
707 wpa_s->bgscan_ssid = NULL;
708 }
709}
710
711#endif /* CONFIG_BGSCAN */
712
713
Dmitry Shmidt04949592012-07-19 12:16:46 -0700714static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
715{
716 if (autoscan_init(wpa_s, 0))
717 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
718}
719
720
721static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
722{
723 autoscan_deinit(wpa_s);
724}
725
726
727void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
728{
729 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
730 wpa_s->wpa_state == WPA_SCANNING) {
731 autoscan_deinit(wpa_s);
732 wpa_supplicant_start_autoscan(wpa_s);
733 }
734}
735
736
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700737/**
738 * wpa_supplicant_set_state - Set current connection state
739 * @wpa_s: Pointer to wpa_supplicant data
740 * @state: The new connection state
741 *
742 * This function is called whenever the connection state changes, e.g.,
743 * association is completed for WPA/WPA2 4-Way Handshake is started.
744 */
745void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
746 enum wpa_states state)
747{
748 enum wpa_states old_state = wpa_s->wpa_state;
749
750 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
751 wpa_supplicant_state_txt(wpa_s->wpa_state),
752 wpa_supplicant_state_txt(state));
753
Dmitry Shmidt9e3f8ee2014-01-17 10:52:01 -0800754 if (state == WPA_INTERFACE_DISABLED) {
755 /* Assure normal scan when interface is restored */
756 wpa_s->normal_scans = 0;
757 }
758
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -0700759 if (state == WPA_COMPLETED) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800760 wpas_connect_work_done(wpa_s);
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -0700761 /* Reinitialize normal_scan counter */
762 wpa_s->normal_scans = 0;
763 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800764
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700765#ifdef CONFIG_P2P
766 /*
767 * P2PS client has to reply to Probe Request frames received on the
768 * group operating channel. Enable Probe Request frame reporting for
769 * P2P connected client in case p2p_cli_probe configuration property is
770 * set to 1.
771 */
772 if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid &&
773 wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
774 wpa_s->current_ssid->p2p_group) {
775 if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) {
776 wpa_dbg(wpa_s, MSG_DEBUG,
777 "P2P: Enable CLI Probe Request RX reporting");
778 wpa_s->p2p_cli_probe =
779 wpa_drv_probe_req_report(wpa_s, 1) >= 0;
780 } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) {
781 wpa_dbg(wpa_s, MSG_DEBUG,
782 "P2P: Disable CLI Probe Request RX reporting");
783 wpa_s->p2p_cli_probe = 0;
784 wpa_drv_probe_req_report(wpa_s, 0);
785 }
786 }
787#endif /* CONFIG_P2P */
788
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700789 if (state != WPA_SCANNING)
790 wpa_supplicant_notify_scanning(wpa_s, 0);
791
792 if (state == WPA_COMPLETED && wpa_s->new_connection) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700793 struct wpa_ssid *ssid = wpa_s->current_ssid;
Dmitry Shmidt700a1372013-03-15 14:14:44 -0700794#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700795 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
Dmitry Shmidt8f0dbf42013-11-08 13:35:41 -0800796 MACSTR " completed [id=%d id_str=%s]",
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800797 MAC2STR(wpa_s->bssid),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700798 ssid ? ssid->id : -1,
799 ssid && ssid->id_str ? ssid->id_str : "");
800#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700801 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -0700802 wpa_blacklist_clear(wpa_s);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800803 wpa_s->extra_blacklist_count = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700804 wpa_s->new_connection = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700805 wpa_drv_set_operstate(wpa_s, 1);
806#ifndef IEEE8021X_EAPOL
807 wpa_drv_set_supp_port(wpa_s, 1);
808#endif /* IEEE8021X_EAPOL */
809 wpa_s->after_wps = 0;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700810 wpa_s->known_wps_freq = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700811 wpas_p2p_completed(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700812
813 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700814 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
815 state == WPA_ASSOCIATED) {
816 wpa_s->new_connection = 1;
817 wpa_drv_set_operstate(wpa_s, 0);
818#ifndef IEEE8021X_EAPOL
819 wpa_drv_set_supp_port(wpa_s, 0);
820#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700821 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700822 }
823 wpa_s->wpa_state = state;
824
825#ifdef CONFIG_BGSCAN
826 if (state == WPA_COMPLETED)
827 wpa_supplicant_start_bgscan(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800828 else if (state < WPA_ASSOCIATED)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700829 wpa_supplicant_stop_bgscan(wpa_s);
830#endif /* CONFIG_BGSCAN */
831
Dmitry Shmidt04949592012-07-19 12:16:46 -0700832 if (state == WPA_AUTHENTICATING)
833 wpa_supplicant_stop_autoscan(wpa_s);
834
835 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
836 wpa_supplicant_start_autoscan(wpa_s);
837
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800838 if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
839 wmm_ac_notify_disassoc(wpa_s);
840
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700841 if (wpa_s->wpa_state != old_state) {
842 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
843
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700844 /*
845 * Notify the P2P Device interface about a state change in one
846 * of the interfaces.
847 */
848 wpas_p2p_indicate_state_change(wpa_s);
849
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700850 if (wpa_s->wpa_state == WPA_COMPLETED ||
851 old_state == WPA_COMPLETED)
852 wpas_notify_auth_changed(wpa_s);
853 }
854}
855
856
857void wpa_supplicant_terminate_proc(struct wpa_global *global)
858{
859 int pending = 0;
860#ifdef CONFIG_WPS
861 struct wpa_supplicant *wpa_s = global->ifaces;
862 while (wpa_s) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800863 struct wpa_supplicant *next = wpa_s->next;
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -0700864 if (wpas_wps_terminate_pending(wpa_s) == 1)
865 pending = 1;
Dmitry Shmidt56052862013-10-04 10:23:25 -0700866#ifdef CONFIG_P2P
867 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
868 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
869 wpas_p2p_disconnect(wpa_s);
870#endif /* CONFIG_P2P */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800871 wpa_s = next;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700872 }
873#endif /* CONFIG_WPS */
874 if (pending)
875 return;
876 eloop_terminate();
877}
878
879
880static void wpa_supplicant_terminate(int sig, void *signal_ctx)
881{
882 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700883 wpa_supplicant_terminate_proc(global);
884}
885
886
887void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
888{
889 enum wpa_states old_state = wpa_s->wpa_state;
890
891 wpa_s->pairwise_cipher = 0;
892 wpa_s->group_cipher = 0;
893 wpa_s->mgmt_group_cipher = 0;
894 wpa_s->key_mgmt = 0;
895 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700896 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700897
898 if (wpa_s->wpa_state != old_state)
899 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
900}
901
902
903/**
904 * wpa_supplicant_reload_configuration - Reload configuration data
905 * @wpa_s: Pointer to wpa_supplicant data
906 * Returns: 0 on success or -1 if configuration parsing failed
907 *
908 * This function can be used to request that the configuration data is reloaded
909 * (e.g., after configuration file change). This function is reloading
910 * configuration only for one interface, so this may need to be called multiple
911 * times if %wpa_supplicant is controlling multiple interfaces and all
912 * interfaces need reconfiguration.
913 */
914int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
915{
916 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700917 int reconf_ctrl;
918 int old_ap_scan;
919
920 if (wpa_s->confname == NULL)
921 return -1;
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700922 conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700923 if (conf == NULL) {
924 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
925 "file '%s' - exiting", wpa_s->confname);
926 return -1;
927 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700928 wpa_config_read(wpa_s->confanother, conf);
929
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700930 conf->changed_parameters = (unsigned int) -1;
931
932 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
933 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
934 os_strcmp(conf->ctrl_interface,
935 wpa_s->conf->ctrl_interface) != 0);
936
937 if (reconf_ctrl && wpa_s->ctrl_iface) {
938 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
939 wpa_s->ctrl_iface = NULL;
940 }
941
942 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800943 if (wpa_s->current_ssid) {
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700944 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
945 wpa_s->own_disconnect_req = 1;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800946 wpa_supplicant_deauthenticate(wpa_s,
947 WLAN_REASON_DEAUTH_LEAVING);
948 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700949
950 /*
951 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800952 * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700953 */
954 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
955 /*
956 * Clear forced success to clear EAP state for next
957 * authentication.
958 */
959 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
960 }
961 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
962 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800963 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700964 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
965 rsn_preauth_deinit(wpa_s->wpa);
966
967 old_ap_scan = wpa_s->conf->ap_scan;
968 wpa_config_free(wpa_s->conf);
969 wpa_s->conf = conf;
970 if (old_ap_scan != wpa_s->conf->ap_scan)
971 wpas_notify_ap_scan_changed(wpa_s);
972
973 if (reconf_ctrl)
974 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
975
976 wpa_supplicant_update_config(wpa_s);
977
978 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700979 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700980 wpa_s->reassociate = 1;
981 wpa_supplicant_req_scan(wpa_s, 0, 0);
982 }
983 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
984 return 0;
985}
986
987
988static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
989{
990 struct wpa_global *global = signal_ctx;
991 struct wpa_supplicant *wpa_s;
992 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
993 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
994 sig);
995 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
996 wpa_supplicant_terminate_proc(global);
997 }
998 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800999
1000 if (wpa_debug_reopen_file() < 0) {
1001 /* Ignore errors since we cannot really do much to fix this */
1002 wpa_printf(MSG_DEBUG, "Could not reopen debug log file");
1003 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001004}
1005
1006
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001007static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
1008 struct wpa_ssid *ssid,
1009 struct wpa_ie_data *ie)
1010{
1011 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
1012 if (ret) {
1013 if (ret == -2) {
1014 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
1015 "from association info");
1016 }
1017 return -1;
1018 }
1019
1020 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
1021 "cipher suites");
1022 if (!(ie->group_cipher & ssid->group_cipher)) {
1023 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
1024 "cipher 0x%x (mask 0x%x) - reject",
1025 ie->group_cipher, ssid->group_cipher);
1026 return -1;
1027 }
1028 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
1029 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
1030 "cipher 0x%x (mask 0x%x) - reject",
1031 ie->pairwise_cipher, ssid->pairwise_cipher);
1032 return -1;
1033 }
1034 if (!(ie->key_mgmt & ssid->key_mgmt)) {
1035 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
1036 "management 0x%x (mask 0x%x) - reject",
1037 ie->key_mgmt, ssid->key_mgmt);
1038 return -1;
1039 }
1040
1041#ifdef CONFIG_IEEE80211W
1042 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001043 wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001044 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
1045 "that does not support management frame protection - "
1046 "reject");
1047 return -1;
1048 }
1049#endif /* CONFIG_IEEE80211W */
1050
1051 return 0;
1052}
1053
1054
1055/**
1056 * wpa_supplicant_set_suites - Set authentication and encryption parameters
1057 * @wpa_s: Pointer to wpa_supplicant data
1058 * @bss: Scan results for the selected BSS, or %NULL if not available
1059 * @ssid: Configuration data for the selected network
1060 * @wpa_ie: Buffer for the WPA/RSN IE
1061 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
1062 * used buffer length in case the functions returns success.
1063 * Returns: 0 on success or -1 on failure
1064 *
1065 * This function is used to configure authentication and encryption parameters
1066 * based on the network configuration and scan result for the selected BSS (if
1067 * available).
1068 */
1069int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
1070 struct wpa_bss *bss, struct wpa_ssid *ssid,
1071 u8 *wpa_ie, size_t *wpa_ie_len)
1072{
1073 struct wpa_ie_data ie;
1074 int sel, proto;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001075 const u8 *bss_wpa, *bss_rsn, *bss_osen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001076
1077 if (bss) {
1078 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1079 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001080 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001081 } else
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001082 bss_wpa = bss_rsn = bss_osen = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001083
1084 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
1085 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
1086 (ie.group_cipher & ssid->group_cipher) &&
1087 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1088 (ie.key_mgmt & ssid->key_mgmt)) {
1089 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
1090 proto = WPA_PROTO_RSN;
1091 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001092 wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001093 (ie.group_cipher & ssid->group_cipher) &&
1094 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1095 (ie.key_mgmt & ssid->key_mgmt)) {
1096 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
1097 proto = WPA_PROTO_WPA;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001098#ifdef CONFIG_HS20
1099 } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
1100 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
1101 /* TODO: parse OSEN element */
Dmitry Shmidt623d63a2014-06-13 11:05:14 -07001102 os_memset(&ie, 0, sizeof(ie));
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001103 ie.group_cipher = WPA_CIPHER_CCMP;
1104 ie.pairwise_cipher = WPA_CIPHER_CCMP;
1105 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
1106 proto = WPA_PROTO_OSEN;
1107#endif /* CONFIG_HS20 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001108 } else if (bss) {
1109 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001110 wpa_dbg(wpa_s, MSG_DEBUG,
1111 "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1112 ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
1113 ssid->key_mgmt);
1114 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
1115 MAC2STR(bss->bssid),
1116 wpa_ssid_txt(bss->ssid, bss->ssid_len),
1117 bss_wpa ? " WPA" : "",
1118 bss_rsn ? " RSN" : "",
1119 bss_osen ? " OSEN" : "");
1120 if (bss_rsn) {
1121 wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
1122 if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
1123 wpa_dbg(wpa_s, MSG_DEBUG,
1124 "Could not parse RSN element");
1125 } else {
1126 wpa_dbg(wpa_s, MSG_DEBUG,
1127 "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1128 ie.pairwise_cipher, ie.group_cipher,
1129 ie.key_mgmt);
1130 }
1131 }
1132 if (bss_wpa) {
1133 wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
1134 if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
1135 wpa_dbg(wpa_s, MSG_DEBUG,
1136 "Could not parse WPA element");
1137 } else {
1138 wpa_dbg(wpa_s, MSG_DEBUG,
1139 "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1140 ie.pairwise_cipher, ie.group_cipher,
1141 ie.key_mgmt);
1142 }
1143 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001144 return -1;
1145 } else {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001146 if (ssid->proto & WPA_PROTO_OSEN)
1147 proto = WPA_PROTO_OSEN;
1148 else if (ssid->proto & WPA_PROTO_RSN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001149 proto = WPA_PROTO_RSN;
1150 else
1151 proto = WPA_PROTO_WPA;
1152 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1153 os_memset(&ie, 0, sizeof(ie));
1154 ie.group_cipher = ssid->group_cipher;
1155 ie.pairwise_cipher = ssid->pairwise_cipher;
1156 ie.key_mgmt = ssid->key_mgmt;
1157#ifdef CONFIG_IEEE80211W
1158 ie.mgmt_group_cipher =
1159 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
1160 WPA_CIPHER_AES_128_CMAC : 0;
1161#endif /* CONFIG_IEEE80211W */
1162 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1163 "based on configuration");
1164 } else
1165 proto = ie.proto;
1166 }
1167
1168 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1169 "pairwise %d key_mgmt %d proto %d",
1170 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
1171#ifdef CONFIG_IEEE80211W
1172 if (ssid->ieee80211w) {
1173 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1174 ie.mgmt_group_cipher);
1175 }
1176#endif /* CONFIG_IEEE80211W */
1177
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001178 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001179 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1180 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001181 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001182
1183 if (bss || !wpa_s->ap_ies_from_associnfo) {
1184 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1185 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1186 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1187 bss_rsn ? 2 + bss_rsn[1] : 0))
1188 return -1;
1189 }
1190
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001191#ifdef CONFIG_NO_WPA
1192 wpa_s->group_cipher = WPA_CIPHER_NONE;
1193 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
1194#else /* CONFIG_NO_WPA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001195 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001196 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1197 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001198 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1199 "cipher");
1200 return -1;
1201 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001202 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1203 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001204
1205 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001206 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1207 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001208 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1209 "cipher");
1210 return -1;
1211 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001212 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1213 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001214#endif /* CONFIG_NO_WPA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001215
1216 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001217#ifdef CONFIG_SAE
1218 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1219 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1220#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001221 if (0) {
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001222#ifdef CONFIG_SUITEB192
1223 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1224 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1225 wpa_dbg(wpa_s, MSG_DEBUG,
1226 "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
1227#endif /* CONFIG_SUITEB192 */
1228#ifdef CONFIG_SUITEB
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001229 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1230 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1231 wpa_dbg(wpa_s, MSG_DEBUG,
1232 "WPA: using KEY_MGMT 802.1X with Suite B");
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001233#endif /* CONFIG_SUITEB */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001234#ifdef CONFIG_IEEE80211R
1235 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1236 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1237 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1238 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1239 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1240 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1241#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001242#ifdef CONFIG_SAE
1243 } else if (sel & WPA_KEY_MGMT_SAE) {
1244 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1245 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1246 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1247 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1248 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1249#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001250#ifdef CONFIG_IEEE80211W
1251 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1252 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1253 wpa_dbg(wpa_s, MSG_DEBUG,
1254 "WPA: using KEY_MGMT 802.1X with SHA256");
1255 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1256 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1257 wpa_dbg(wpa_s, MSG_DEBUG,
1258 "WPA: using KEY_MGMT PSK with SHA256");
1259#endif /* CONFIG_IEEE80211W */
1260 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1261 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1262 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1263 } else if (sel & WPA_KEY_MGMT_PSK) {
1264 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1265 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1266 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1267 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1268 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001269#ifdef CONFIG_HS20
1270 } else if (sel & WPA_KEY_MGMT_OSEN) {
1271 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1272 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1273#endif /* CONFIG_HS20 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001274 } else {
1275 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1276 "authenticated key management type");
1277 return -1;
1278 }
1279
1280 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1281 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1282 wpa_s->pairwise_cipher);
1283 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1284
1285#ifdef CONFIG_IEEE80211W
1286 sel = ie.mgmt_group_cipher;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001287 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001288 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1289 sel = 0;
1290 if (sel & WPA_CIPHER_AES_128_CMAC) {
1291 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1292 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1293 "AES-128-CMAC");
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001294 } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1295 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1296 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1297 "BIP-GMAC-128");
1298 } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1299 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1300 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1301 "BIP-GMAC-256");
1302 } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1303 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1304 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1305 "BIP-CMAC-256");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001306 } else {
1307 wpa_s->mgmt_group_cipher = 0;
1308 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1309 }
1310 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1311 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001312 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001313 wpas_get_ssid_pmf(wpa_s, ssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001314#endif /* CONFIG_IEEE80211W */
1315
1316 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1317 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1318 return -1;
1319 }
1320
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001321 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001322 int psk_set = 0;
1323
1324 if (ssid->psk_set) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001325 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL,
1326 NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001327 psk_set = 1;
1328 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001329#ifndef CONFIG_NO_PBKDF2
1330 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1331 ssid->passphrase) {
1332 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001333 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1334 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001335 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1336 psk, PMK_LEN);
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001337 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001338 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001339 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001340 }
1341#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001342#ifdef CONFIG_EXT_PASSWORD
1343 if (ssid->ext_psk) {
1344 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1345 ssid->ext_psk);
1346 char pw_str[64 + 1];
1347 u8 psk[PMK_LEN];
1348
1349 if (pw == NULL) {
1350 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1351 "found from external storage");
1352 return -1;
1353 }
1354
1355 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1356 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1357 "PSK length %d in external storage",
1358 (int) wpabuf_len(pw));
1359 ext_password_free(pw);
1360 return -1;
1361 }
1362
1363 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1364 pw_str[wpabuf_len(pw)] = '\0';
1365
1366#ifndef CONFIG_NO_PBKDF2
1367 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1368 {
1369 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1370 4096, psk, PMK_LEN);
1371 os_memset(pw_str, 0, sizeof(pw_str));
1372 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1373 "external passphrase)",
1374 psk, PMK_LEN);
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001375 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1376 NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001377 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001378 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001379 } else
1380#endif /* CONFIG_NO_PBKDF2 */
1381 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1382 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1383 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1384 "Invalid PSK hex string");
1385 os_memset(pw_str, 0, sizeof(pw_str));
1386 ext_password_free(pw);
1387 return -1;
1388 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001389 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1390 NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001391 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001392 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001393 } else {
1394 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1395 "PSK available");
1396 os_memset(pw_str, 0, sizeof(pw_str));
1397 ext_password_free(pw);
1398 return -1;
1399 }
1400
1401 os_memset(pw_str, 0, sizeof(pw_str));
1402 ext_password_free(pw);
1403 }
1404#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001405
1406 if (!psk_set) {
1407 wpa_msg(wpa_s, MSG_INFO,
1408 "No PSK available for association");
1409 return -1;
1410 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001411 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001412 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1413
1414 return 0;
1415}
1416
1417
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001418static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1419{
1420 *pos = 0x00;
1421
1422 switch (idx) {
1423 case 0: /* Bits 0-7 */
1424 break;
1425 case 1: /* Bits 8-15 */
1426 break;
1427 case 2: /* Bits 16-23 */
1428#ifdef CONFIG_WNM
1429 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1430 *pos |= 0x08; /* Bit 19 - BSS Transition */
1431#endif /* CONFIG_WNM */
1432 break;
1433 case 3: /* Bits 24-31 */
1434#ifdef CONFIG_WNM
1435 *pos |= 0x02; /* Bit 25 - SSID List */
1436#endif /* CONFIG_WNM */
1437#ifdef CONFIG_INTERWORKING
1438 if (wpa_s->conf->interworking)
1439 *pos |= 0x80; /* Bit 31 - Interworking */
1440#endif /* CONFIG_INTERWORKING */
1441 break;
1442 case 4: /* Bits 32-39 */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001443#ifdef CONFIG_INTERWORKING
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001444 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1445 *pos |= 0x01; /* Bit 32 - QoS Map */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001446#endif /* CONFIG_INTERWORKING */
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001447 break;
1448 case 5: /* Bits 40-47 */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001449#ifdef CONFIG_HS20
1450 if (wpa_s->conf->hs20)
1451 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1452#endif /* CONFIG_HS20 */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001453#ifdef CONFIG_MBO
1454 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1455#endif /* CONFIG_MBO */
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001456 break;
1457 case 6: /* Bits 48-55 */
1458 break;
1459 }
1460}
1461
1462
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07001463int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001464{
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001465 u8 *pos = buf;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001466 u8 len = 6, i;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001467
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001468 if (len < wpa_s->extended_capa_len)
1469 len = wpa_s->extended_capa_len;
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07001470 if (buflen < (size_t) len + 2) {
1471 wpa_printf(MSG_INFO,
1472 "Not enough room for building extended capabilities element");
1473 return -1;
1474 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001475
1476 *pos++ = WLAN_EID_EXT_CAPAB;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001477 *pos++ = len;
1478 for (i = 0; i < len; i++, pos++) {
1479 wpas_ext_capab_byte(wpa_s, pos, i);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001480
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001481 if (i < wpa_s->extended_capa_len) {
1482 *pos &= ~wpa_s->extended_capa_mask[i];
1483 *pos |= wpa_s->extended_capa[i];
1484 }
1485 }
1486
1487 while (len > 0 && buf[1 + len] == 0) {
1488 len--;
1489 buf[1] = len;
1490 }
1491 if (len == 0)
1492 return 0;
1493
1494 return 2 + len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001495}
1496
1497
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001498static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1499 struct wpa_bss *test_bss)
1500{
1501 struct wpa_bss *bss;
1502
1503 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1504 if (bss == test_bss)
1505 return 1;
1506 }
1507
1508 return 0;
1509}
1510
1511
1512static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1513 struct wpa_ssid *test_ssid)
1514{
1515 struct wpa_ssid *ssid;
1516
1517 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1518 if (ssid == test_ssid)
1519 return 1;
1520 }
1521
1522 return 0;
1523}
1524
1525
1526int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1527 struct wpa_ssid *test_ssid)
1528{
1529 if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1530 return 0;
1531
1532 return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1533}
1534
1535
1536void wpas_connect_work_free(struct wpa_connect_work *cwork)
1537{
1538 if (cwork == NULL)
1539 return;
1540 os_free(cwork);
1541}
1542
1543
1544void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1545{
1546 struct wpa_connect_work *cwork;
1547 struct wpa_radio_work *work = wpa_s->connect_work;
1548
1549 if (!work)
1550 return;
1551
1552 wpa_s->connect_work = NULL;
1553 cwork = work->ctx;
1554 work->ctx = NULL;
1555 wpas_connect_work_free(cwork);
1556 radio_work_done(work);
1557}
1558
1559
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001560int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
1561{
1562 struct os_reltime now;
1563 u8 addr[ETH_ALEN];
1564
1565 os_get_reltime(&now);
1566 if (wpa_s->last_mac_addr_style == style &&
1567 wpa_s->last_mac_addr_change.sec != 0 &&
1568 !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
1569 wpa_s->conf->rand_addr_lifetime)) {
1570 wpa_msg(wpa_s, MSG_DEBUG,
1571 "Previously selected random MAC address has not yet expired");
1572 return 0;
1573 }
1574
1575 switch (style) {
1576 case 1:
1577 if (random_mac_addr(addr) < 0)
1578 return -1;
1579 break;
1580 case 2:
1581 os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
1582 if (random_mac_addr_keep_oui(addr) < 0)
1583 return -1;
1584 break;
1585 default:
1586 return -1;
1587 }
1588
1589 if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
1590 wpa_msg(wpa_s, MSG_INFO,
1591 "Failed to set random MAC address");
1592 return -1;
1593 }
1594
1595 os_get_reltime(&wpa_s->last_mac_addr_change);
1596 wpa_s->mac_addr_changed = 1;
1597 wpa_s->last_mac_addr_style = style;
1598
1599 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1600 wpa_msg(wpa_s, MSG_INFO,
1601 "Could not update MAC address information");
1602 return -1;
1603 }
1604
1605 wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
1606 MAC2STR(addr));
1607
1608 return 0;
1609}
1610
1611
1612int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
1613{
1614 if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
1615 !wpa_s->conf->preassoc_mac_addr)
1616 return 0;
1617
1618 return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
1619}
1620
1621
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001622static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1623
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001624/**
1625 * wpa_supplicant_associate - Request association
1626 * @wpa_s: Pointer to wpa_supplicant data
1627 * @bss: Scan results for the selected BSS, or %NULL if not available
1628 * @ssid: Configuration data for the selected network
1629 *
1630 * This function is used to request %wpa_supplicant to associate with a BSS.
1631 */
1632void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1633 struct wpa_bss *bss, struct wpa_ssid *ssid)
1634{
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001635 struct wpa_connect_work *cwork;
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001636 int rand_style;
1637
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001638 wpa_s->own_disconnect_req = 0;
1639
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001640 /*
1641 * If we are starting a new connection, any previously pending EAPOL
1642 * RX cannot be valid anymore.
1643 */
1644 wpabuf_free(wpa_s->pending_eapol_rx);
1645 wpa_s->pending_eapol_rx = NULL;
1646
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001647 if (ssid->mac_addr == -1)
1648 rand_style = wpa_s->conf->mac_addr;
1649 else
1650 rand_style = ssid->mac_addr;
1651
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001652 wmm_ac_clear_saved_tspecs(wpa_s);
1653 wpa_s->reassoc_same_bss = 0;
Dmitry Shmidte4663042016-04-04 10:07:49 -07001654 wpa_s->reassoc_same_ess = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001655
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001656 if (wpa_s->last_ssid == ssid) {
1657 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
Dmitry Shmidte4663042016-04-04 10:07:49 -07001658 wpa_s->reassoc_same_ess = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001659 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
1660 wmm_ac_save_tspecs(wpa_s);
1661 wpa_s->reassoc_same_bss = 1;
1662 }
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001663 } else if (rand_style > 0) {
1664 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
1665 return;
1666 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
1667 } else if (wpa_s->mac_addr_changed) {
1668 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1669 wpa_msg(wpa_s, MSG_INFO,
1670 "Could not restore permanent MAC address");
1671 return;
1672 }
1673 wpa_s->mac_addr_changed = 0;
1674 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1675 wpa_msg(wpa_s, MSG_INFO,
1676 "Could not update MAC address information");
1677 return;
1678 }
1679 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1680 }
1681 wpa_s->last_ssid = ssid;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001682
1683#ifdef CONFIG_IBSS_RSN
1684 ibss_rsn_deinit(wpa_s->ibss_rsn);
1685 wpa_s->ibss_rsn = NULL;
1686#endif /* CONFIG_IBSS_RSN */
1687
1688 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1689 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1690#ifdef CONFIG_AP
1691 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1692 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1693 "mode");
1694 return;
1695 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001696 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1697 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt391c59f2013-09-03 12:16:28 -07001698 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1699 wpas_p2p_ap_setup_failed(wpa_s);
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001700 return;
1701 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001702 wpa_s->current_bss = bss;
1703#else /* CONFIG_AP */
1704 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1705 "the build");
1706#endif /* CONFIG_AP */
1707 return;
1708 }
1709
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001710 if (ssid->mode == WPAS_MODE_MESH) {
1711#ifdef CONFIG_MESH
1712 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1713 wpa_msg(wpa_s, MSG_INFO,
1714 "Driver does not support mesh mode");
1715 return;
1716 }
1717 if (bss)
1718 ssid->frequency = bss->freq;
1719 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1720 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1721 return;
1722 }
1723 wpa_s->current_bss = bss;
Dmitry Shmidtde47be72016-01-07 12:52:55 -08001724 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
1725 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1726 ssid->id);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001727#else /* CONFIG_MESH */
1728 wpa_msg(wpa_s, MSG_ERROR,
1729 "mesh mode support not included in the build");
1730#endif /* CONFIG_MESH */
1731 return;
1732 }
1733
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001734#ifdef CONFIG_TDLS
1735 if (bss)
1736 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1737 bss->ie_len);
1738#endif /* CONFIG_TDLS */
1739
1740 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1741 ssid->mode == IEEE80211_MODE_INFRA) {
1742 sme_authenticate(wpa_s, bss, ssid);
1743 return;
1744 }
1745
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001746 if (wpa_s->connect_work) {
1747 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1748 return;
1749 }
1750
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001751 if (radio_work_pending(wpa_s, "connect")) {
1752 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1753 return;
1754 }
1755
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001756 wpas_abort_ongoing_scan(wpa_s);
1757
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001758 cwork = os_zalloc(sizeof(*cwork));
1759 if (cwork == NULL)
1760 return;
1761
1762 cwork->bss = bss;
1763 cwork->ssid = ssid;
1764
1765 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1766 wpas_start_assoc_cb, cwork) < 0) {
1767 os_free(cwork);
1768 }
1769}
1770
1771
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001772static int bss_is_ibss(struct wpa_bss *bss)
1773{
1774 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1775 IEEE80211_CAP_IBSS;
1776}
1777
1778
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001779static int drv_supports_vht(struct wpa_supplicant *wpa_s,
1780 const struct wpa_ssid *ssid)
1781{
1782 enum hostapd_hw_mode hw_mode;
1783 struct hostapd_hw_modes *mode = NULL;
1784 u8 channel;
1785 int i;
1786
1787#ifdef CONFIG_HT_OVERRIDES
1788 if (ssid->disable_ht)
1789 return 0;
1790#endif /* CONFIG_HT_OVERRIDES */
1791
1792 hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
1793 if (hw_mode == NUM_HOSTAPD_MODES)
1794 return 0;
1795 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1796 if (wpa_s->hw.modes[i].mode == hw_mode) {
1797 mode = &wpa_s->hw.modes[i];
1798 break;
1799 }
1800 }
1801
1802 if (!mode)
1803 return 0;
1804
1805 return mode->vht_capab != 0;
1806}
1807
1808
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001809void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1810 const struct wpa_ssid *ssid,
1811 struct hostapd_freq_params *freq)
1812{
1813 enum hostapd_hw_mode hw_mode;
1814 struct hostapd_hw_modes *mode = NULL;
1815 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1816 184, 192 };
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001817 int vht80[] = { 36, 52, 100, 116, 132, 149 };
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001818 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1819 u8 channel;
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001820 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001821 unsigned int j, k;
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001822 struct hostapd_freq_params vht_freq;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001823 int chwidth, seg0, seg1;
1824 u32 vht_caps = 0;
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001825
1826 freq->freq = ssid->frequency;
1827
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001828 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1829 struct wpa_bss *bss = wpa_s->last_scan_res[j];
1830
1831 if (ssid->mode != WPAS_MODE_IBSS)
1832 break;
1833
1834 /* Don't adjust control freq in case of fixed_freq */
1835 if (ssid->fixed_freq)
1836 break;
1837
1838 if (!bss_is_ibss(bss))
1839 continue;
1840
1841 if (ssid->ssid_len == bss->ssid_len &&
1842 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1843 wpa_printf(MSG_DEBUG,
1844 "IBSS already found in scan results, adjust control freq: %d",
1845 bss->freq);
1846 freq->freq = bss->freq;
1847 obss_scan = 0;
1848 break;
1849 }
1850 }
1851
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001852 /* For IBSS check HT_IBSS flag */
1853 if (ssid->mode == WPAS_MODE_IBSS &&
1854 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1855 return;
1856
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001857 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1858 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1859 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1860 wpa_printf(MSG_DEBUG,
1861 "IBSS: WEP/TKIP detected, do not try to enable HT");
1862 return;
1863 }
1864
1865 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001866 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1867 if (wpa_s->hw.modes[i].mode == hw_mode) {
1868 mode = &wpa_s->hw.modes[i];
1869 break;
1870 }
1871 }
1872
1873 if (!mode)
1874 return;
1875
Dmitry Shmidt58d12ad2016-07-28 10:07:03 -07001876#ifdef CONFIG_HT_OVERRIDES
1877 if (ssid->disable_ht) {
1878 freq->ht_enabled = 0;
1879 return;
1880 }
1881#endif /* CONFIG_HT_OVERRIDES */
1882
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001883 freq->ht_enabled = ht_supported(mode);
1884 if (!freq->ht_enabled)
1885 return;
1886
1887 /* Setup higher BW only for 5 GHz */
1888 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1889 return;
1890
1891 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1892 pri_chan = &mode->channels[chan_idx];
1893 if (pri_chan->chan == channel)
1894 break;
1895 pri_chan = NULL;
1896 }
1897 if (!pri_chan)
1898 return;
1899
1900 /* Check primary channel flags */
1901 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1902 return;
1903
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07001904#ifdef CONFIG_HT_OVERRIDES
1905 if (ssid->disable_ht40)
1906 return;
1907#endif /* CONFIG_HT_OVERRIDES */
1908
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001909 /* Check/setup HT40+/HT40- */
1910 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1911 if (ht40plus[j] == channel) {
1912 ht40 = 1;
1913 break;
1914 }
1915 }
1916
1917 /* Find secondary channel */
1918 for (i = 0; i < mode->num_channels; i++) {
1919 sec_chan = &mode->channels[i];
1920 if (sec_chan->chan == channel + ht40 * 4)
1921 break;
1922 sec_chan = NULL;
1923 }
1924 if (!sec_chan)
1925 return;
1926
1927 /* Check secondary channel flags */
1928 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1929 return;
1930
1931 freq->channel = pri_chan->chan;
1932
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07001933 if (ht40 == -1) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001934 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1935 return;
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07001936 } else {
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001937 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1938 return;
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001939 }
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07001940 freq->sec_channel_offset = ht40;
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001941
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07001942 if (obss_scan) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001943 struct wpa_scan_results *scan_res;
1944
1945 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1946 if (scan_res == NULL) {
1947 /* Back to HT20 */
1948 freq->sec_channel_offset = 0;
1949 return;
1950 }
1951
1952 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
1953 sec_chan->chan);
1954 switch (res) {
1955 case 0:
1956 /* Back to HT20 */
1957 freq->sec_channel_offset = 0;
1958 break;
1959 case 1:
1960 /* Configuration allowed */
1961 break;
1962 case 2:
1963 /* Switch pri/sec channels */
1964 freq->freq = hw_get_freq(mode, sec_chan->chan);
1965 freq->sec_channel_offset = -freq->sec_channel_offset;
1966 freq->channel = sec_chan->chan;
1967 break;
1968 default:
1969 freq->sec_channel_offset = 0;
1970 break;
1971 }
1972
1973 wpa_scan_results_free(scan_res);
1974 }
1975
1976 wpa_printf(MSG_DEBUG,
1977 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
1978 freq->channel, freq->sec_channel_offset);
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001979
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001980 if (!drv_supports_vht(wpa_s, ssid))
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001981 return;
1982
1983 /* For IBSS check VHT_IBSS flag */
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001984 if (ssid->mode == WPAS_MODE_IBSS &&
1985 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001986 return;
1987
1988 vht_freq = *freq;
1989
1990 vht_freq.vht_enabled = vht_supported(mode);
1991 if (!vht_freq.vht_enabled)
1992 return;
1993
1994 /* setup center_freq1, bandwidth */
1995 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
1996 if (freq->channel >= vht80[j] &&
1997 freq->channel < vht80[j] + 16)
1998 break;
1999 }
2000
2001 if (j == ARRAY_SIZE(vht80))
2002 return;
2003
2004 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
2005 struct hostapd_channel_data *chan;
2006
2007 chan = hw_get_channel_chan(mode, i, NULL);
2008 if (!chan)
2009 return;
2010
2011 /* Back to HT configuration if channel not usable */
2012 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2013 return;
2014 }
2015
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002016 chwidth = VHT_CHANWIDTH_80MHZ;
2017 seg0 = vht80[j] + 6;
2018 seg1 = 0;
2019
2020 if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) {
2021 /* setup center_freq2, bandwidth */
2022 for (k = 0; k < ARRAY_SIZE(vht80); k++) {
2023 /* Only accept 80 MHz segments separated by a gap */
2024 if (j == k || abs(vht80[j] - vht80[k]) == 16)
2025 continue;
2026 for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
2027 struct hostapd_channel_data *chan;
2028
2029 chan = hw_get_channel_chan(mode, i, NULL);
2030 if (!chan)
2031 continue;
2032
2033 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2034 HOSTAPD_CHAN_NO_IR |
2035 HOSTAPD_CHAN_RADAR))
2036 continue;
2037
2038 /* Found a suitable second segment for 80+80 */
2039 chwidth = VHT_CHANWIDTH_80P80MHZ;
2040 vht_caps |=
2041 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2042 seg1 = vht80[k] + 6;
2043 }
2044
2045 if (chwidth == VHT_CHANWIDTH_80P80MHZ)
2046 break;
2047 }
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -07002048 } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) {
2049 if (freq->freq == 5180) {
2050 chwidth = VHT_CHANWIDTH_160MHZ;
2051 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2052 seg0 = 50;
2053 } else if (freq->freq == 5520) {
2054 chwidth = VHT_CHANWIDTH_160MHZ;
2055 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2056 seg0 = 114;
2057 }
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002058 }
2059
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002060 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
2061 freq->channel, freq->ht_enabled,
2062 vht_freq.vht_enabled,
2063 freq->sec_channel_offset,
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002064 chwidth, seg0, seg1, vht_caps) != 0)
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002065 return;
2066
2067 *freq = vht_freq;
2068
2069 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2070 freq->center_freq1, freq->center_freq2, freq->bandwidth);
Dmitry Shmidtff787d52015-01-12 13:01:47 -08002071}
2072
2073
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002074static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
2075{
2076 struct wpa_connect_work *cwork = work->ctx;
2077 struct wpa_bss *bss = cwork->bss;
2078 struct wpa_ssid *ssid = cwork->ssid;
2079 struct wpa_supplicant *wpa_s = work->wpa_s;
2080 u8 wpa_ie[200];
2081 size_t wpa_ie_len;
2082 int use_crypt, ret, i, bssid_changed;
2083 int algs = WPA_AUTH_ALG_OPEN;
2084 unsigned int cipher_pairwise, cipher_group;
2085 struct wpa_driver_associate_params params;
2086 int wep_keys_set = 0;
2087 int assoc_failed = 0;
2088 struct wpa_ssid *old_ssid;
Dmitry Shmidte4663042016-04-04 10:07:49 -07002089 u8 prev_bssid[ETH_ALEN];
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002090#ifdef CONFIG_HT_OVERRIDES
2091 struct ieee80211_ht_capabilities htcaps;
2092 struct ieee80211_ht_capabilities htcaps_mask;
2093#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002094#ifdef CONFIG_VHT_OVERRIDES
2095 struct ieee80211_vht_capabilities vhtcaps;
2096 struct ieee80211_vht_capabilities vhtcaps_mask;
2097#endif /* CONFIG_VHT_OVERRIDES */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002098#ifdef CONFIG_MBO
2099 const u8 *mbo = NULL;
2100#endif /* CONFIG_MBO */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002101
2102 if (deinit) {
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08002103 if (work->started) {
2104 wpa_s->connect_work = NULL;
2105
2106 /* cancel possible auth. timeout */
2107 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
2108 NULL);
2109 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002110 wpas_connect_work_free(cwork);
2111 return;
2112 }
2113
2114 wpa_s->connect_work = work;
2115
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002116 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
2117 wpas_network_disabled(wpa_s, ssid)) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002118 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
2119 wpas_connect_work_done(wpa_s);
2120 return;
2121 }
2122
Dmitry Shmidte4663042016-04-04 10:07:49 -07002123 os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002124 os_memset(&params, 0, sizeof(params));
2125 wpa_s->reassociate = 0;
Dmitry Shmidt344abd32014-01-14 13:17:00 -08002126 wpa_s->eap_expected_failure = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002127 if (bss &&
2128 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002129#ifdef CONFIG_IEEE80211R
2130 const u8 *ie, *md = NULL;
2131#endif /* CONFIG_IEEE80211R */
2132 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2133 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
2134 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
2135 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2136 os_memset(wpa_s->bssid, 0, ETH_ALEN);
2137 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2138 if (bssid_changed)
2139 wpas_notify_bssid_changed(wpa_s);
2140#ifdef CONFIG_IEEE80211R
2141 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
2142 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
2143 md = ie + 2;
2144 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
2145 if (md) {
2146 /* Prepare for the next transition */
2147 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
2148 }
2149#endif /* CONFIG_IEEE80211R */
2150#ifdef CONFIG_WPS
2151 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
2152 wpa_s->conf->ap_scan == 2 &&
2153 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
2154 /* Use ap_scan==1 style network selection to find the network
2155 */
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002156 wpas_connect_work_done(wpa_s);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002157 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002158 wpa_s->reassociate = 1;
2159 wpa_supplicant_req_scan(wpa_s, 0, 0);
2160 return;
2161#endif /* CONFIG_WPS */
2162 } else {
2163 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
2164 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
2165 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2166 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002167 if (!wpa_s->pno)
2168 wpa_supplicant_cancel_sched_scan(wpa_s);
2169
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002170 wpa_supplicant_cancel_scan(wpa_s);
2171
2172 /* Starting new association, so clear the possibly used WPA IE from the
2173 * previous association. */
2174 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2175
2176#ifdef IEEE8021X_EAPOL
2177 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2178 if (ssid->leap) {
2179 if (ssid->non_leap == 0)
2180 algs = WPA_AUTH_ALG_LEAP;
2181 else
2182 algs |= WPA_AUTH_ALG_LEAP;
2183 }
2184 }
2185#endif /* IEEE8021X_EAPOL */
2186 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
2187 if (ssid->auth_alg) {
2188 algs = ssid->auth_alg;
2189 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
2190 "0x%x", algs);
2191 }
2192
2193 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2194 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002195 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002196 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002197 try_opportunistic = (ssid->proactive_key_caching < 0 ?
2198 wpa_s->conf->okc :
2199 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002200 (ssid->proto & WPA_PROTO_RSN);
2201 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07002202 ssid, try_opportunistic) == 0)
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002203 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002204 wpa_ie_len = sizeof(wpa_ie);
2205 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2206 wpa_ie, &wpa_ie_len)) {
2207 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2208 "key management and encryption suites");
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002209 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002210 return;
2211 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002212 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2213 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2214 /*
2215 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2216 * use non-WPA since the scan results did not indicate that the
2217 * AP is using WPA or WPA2.
2218 */
2219 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2220 wpa_ie_len = 0;
2221 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002222 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002223 wpa_ie_len = sizeof(wpa_ie);
2224 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2225 wpa_ie, &wpa_ie_len)) {
2226 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2227 "key management and encryption suites (no "
2228 "scan results)");
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002229 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002230 return;
2231 }
2232#ifdef CONFIG_WPS
2233 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
2234 struct wpabuf *wps_ie;
2235 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
2236 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2237 wpa_ie_len = wpabuf_len(wps_ie);
2238 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
2239 } else
2240 wpa_ie_len = 0;
2241 wpabuf_free(wps_ie);
2242 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2243 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2244 params.wps = WPS_MODE_PRIVACY;
2245 else
2246 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002247 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002248#endif /* CONFIG_WPS */
2249 } else {
2250 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2251 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002252 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002253 }
2254
2255#ifdef CONFIG_P2P
2256 if (wpa_s->global->p2p) {
2257 u8 *pos;
2258 size_t len;
2259 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002260 pos = wpa_ie + wpa_ie_len;
2261 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002262 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2263 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002264 if (res >= 0)
2265 wpa_ie_len += res;
2266 }
2267
2268 wpa_s->cross_connect_disallowed = 0;
2269 if (bss) {
2270 struct wpabuf *p2p;
2271 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2272 if (p2p) {
2273 wpa_s->cross_connect_disallowed =
2274 p2p_get_cross_connect_disallowed(p2p);
2275 wpabuf_free(p2p);
2276 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2277 "connection",
2278 wpa_s->cross_connect_disallowed ?
2279 "disallows" : "allows");
2280 }
2281 }
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002282
2283 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002284#endif /* CONFIG_P2P */
2285
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002286#ifdef CONFIG_MBO
2287 if (bss) {
2288 mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
2289 if (mbo) {
2290 int len;
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002291
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002292 len = wpas_mbo_supp_op_class_ie(wpa_s, bss->freq,
2293 wpa_ie + wpa_ie_len,
2294 sizeof(wpa_ie) -
2295 wpa_ie_len);
2296 if (len > 0)
2297 wpa_ie_len += len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002298 }
2299 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002300#endif /* CONFIG_MBO */
Dmitry Shmidt04949592012-07-19 12:16:46 -07002301
Dmitry Shmidt56052862013-10-04 10:23:25 -07002302 /*
2303 * Workaround: Add Extended Capabilities element only if the AP
2304 * included this element in Beacon/Probe Response frames. Some older
2305 * APs seem to have interoperability issues if this element is
2306 * included, so while the standard may require us to include the
2307 * element in all cases, it is justifiable to skip it to avoid
2308 * interoperability issues.
2309 */
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -07002310 if (ssid->p2p_group)
2311 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
2312 else
2313 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
2314
Dmitry Shmidt56052862013-10-04 10:23:25 -07002315 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07002316 u8 ext_capab[18];
Dmitry Shmidt56052862013-10-04 10:23:25 -07002317 int ext_capab_len;
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07002318 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2319 sizeof(ext_capab));
Dmitry Shmidt56052862013-10-04 10:23:25 -07002320 if (ext_capab_len > 0) {
2321 u8 *pos = wpa_ie;
2322 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2323 pos += 2 + pos[1];
2324 os_memmove(pos + ext_capab_len, pos,
2325 wpa_ie_len - (pos - wpa_ie));
2326 wpa_ie_len += ext_capab_len;
2327 os_memcpy(pos, ext_capab, ext_capab_len);
2328 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002329 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002330
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002331#ifdef CONFIG_HS20
2332 if (is_hs20_network(wpa_s, ssid, bss)) {
2333 struct wpabuf *hs20;
2334
2335 hs20 = wpabuf_alloc(20);
2336 if (hs20) {
2337 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
2338 size_t len;
2339
2340 wpas_hs20_add_indication(hs20, pps_mo_id);
2341 len = sizeof(wpa_ie) - wpa_ie_len;
2342 if (wpabuf_len(hs20) <= len) {
2343 os_memcpy(wpa_ie + wpa_ie_len,
2344 wpabuf_head(hs20), wpabuf_len(hs20));
2345 wpa_ie_len += wpabuf_len(hs20);
2346 }
2347 wpabuf_free(hs20);
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002348
2349 hs20_configure_frame_filters(wpa_s);
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002350 }
2351 }
2352#endif /* CONFIG_HS20 */
2353
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002354 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2355 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2356 size_t len;
2357
2358 len = sizeof(wpa_ie) - wpa_ie_len;
2359 if (wpabuf_len(buf) <= len) {
2360 os_memcpy(wpa_ie + wpa_ie_len,
2361 wpabuf_head(buf), wpabuf_len(buf));
2362 wpa_ie_len += wpabuf_len(buf);
2363 }
2364 }
2365
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002366#ifdef CONFIG_FST
2367 if (wpa_s->fst_ies) {
2368 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2369
2370 if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
2371 os_memcpy(wpa_ie + wpa_ie_len,
2372 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2373 wpa_ie_len += fst_ies_len;
2374 }
2375 }
2376#endif /* CONFIG_FST */
2377
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002378#ifdef CONFIG_MBO
2379 if (mbo) {
2380 int len;
2381
2382 len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
2383 sizeof(wpa_ie) - wpa_ie_len);
2384 if (len >= 0)
2385 wpa_ie_len += len;
2386 }
2387#endif /* CONFIG_MBO */
2388
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002389 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2390 use_crypt = 1;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002391 cipher_pairwise = wpa_s->pairwise_cipher;
2392 cipher_group = wpa_s->group_cipher;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002393 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2394 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2395 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2396 use_crypt = 0;
2397 if (wpa_set_wep_keys(wpa_s, ssid)) {
2398 use_crypt = 1;
2399 wep_keys_set = 1;
2400 }
2401 }
2402 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2403 use_crypt = 0;
2404
2405#ifdef IEEE8021X_EAPOL
2406 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2407 if ((ssid->eapol_flags &
2408 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2409 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2410 !wep_keys_set) {
2411 use_crypt = 0;
2412 } else {
2413 /* Assume that dynamic WEP-104 keys will be used and
2414 * set cipher suites in order for drivers to expect
2415 * encryption. */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002416 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002417 }
2418 }
2419#endif /* IEEE8021X_EAPOL */
2420
2421 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2422 /* Set the key before (and later after) association */
2423 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2424 }
2425
2426 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
2427 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002428 params.ssid = bss->ssid;
2429 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002430 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
2431 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2432 MACSTR " freq=%u MHz based on scan results "
2433 "(bssid_set=%d)",
2434 MAC2STR(bss->bssid), bss->freq,
2435 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002436 params.bssid = bss->bssid;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002437 params.freq.freq = bss->freq;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002438 }
Dmitry Shmidt96be6222014-02-13 10:16:51 -08002439 params.bssid_hint = bss->bssid;
2440 params.freq_hint = bss->freq;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002441 params.pbss = bss_is_pbss(bss);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002442 } else {
2443 params.ssid = ssid->ssid;
2444 params.ssid_len = ssid->ssid_len;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002445 params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002446 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002447
2448 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2449 wpa_s->conf->ap_scan == 2) {
2450 params.bssid = ssid->bssid;
2451 params.fixed_bssid = 1;
2452 }
2453
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002454 /* Initial frequency for IBSS/mesh */
2455 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
Dmitry Shmidtff787d52015-01-12 13:01:47 -08002456 ssid->frequency > 0 && params.freq.freq == 0)
2457 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
Dmitry Shmidt2ac5f602014-03-07 10:08:21 -08002458
2459 if (ssid->mode == WPAS_MODE_IBSS) {
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002460 params.fixed_freq = ssid->fixed_freq;
Dmitry Shmidt2ac5f602014-03-07 10:08:21 -08002461 if (ssid->beacon_int)
2462 params.beacon_int = ssid->beacon_int;
2463 else
2464 params.beacon_int = wpa_s->conf->beacon_int;
2465 }
2466
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002467 params.wpa_ie = wpa_ie;
2468 params.wpa_ie_len = wpa_ie_len;
2469 params.pairwise_suite = cipher_pairwise;
2470 params.group_suite = cipher_group;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002471 params.key_mgmt_suite = wpa_s->key_mgmt;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002472 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002473 params.auth_alg = algs;
2474 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002475 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002476 for (i = 0; i < NUM_WEP_KEYS; i++) {
2477 if (ssid->wep_key_len[i])
2478 params.wep_key[i] = ssid->wep_key[i];
2479 params.wep_key_len[i] = ssid->wep_key_len[i];
2480 }
2481 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2482
2483 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002484 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2485 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002486 params.passphrase = ssid->passphrase;
2487 if (ssid->psk_set)
2488 params.psk = ssid->psk;
2489 }
2490
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002491 if (wpa_s->conf->key_mgmt_offload) {
2492 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
2493 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002494 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2495 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002496 params.req_key_mgmt_offload =
2497 ssid->proactive_key_caching < 0 ?
2498 wpa_s->conf->okc : ssid->proactive_key_caching;
2499 else
2500 params.req_key_mgmt_offload = 1;
2501
2502 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2503 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2504 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2505 ssid->psk_set)
2506 params.psk = ssid->psk;
2507 }
2508
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002509 params.drop_unencrypted = use_crypt;
2510
2511#ifdef CONFIG_IEEE80211W
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002512 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002513 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002514 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
2515 struct wpa_ie_data ie;
2516 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2517 ie.capabilities &
2518 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
2519 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2520 "MFP: require MFP");
2521 params.mgmt_frame_protection =
2522 MGMT_FRAME_PROTECTION_REQUIRED;
2523 }
2524 }
2525#endif /* CONFIG_IEEE80211W */
2526
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002527 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002528
Dmitry Shmidt9c175262016-03-03 10:20:07 -08002529 if (wpa_s->p2pdev->set_sta_uapsd)
2530 params.uapsd = wpa_s->p2pdev->sta_uapsd;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002531 else
2532 params.uapsd = -1;
2533
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002534#ifdef CONFIG_HT_OVERRIDES
2535 os_memset(&htcaps, 0, sizeof(htcaps));
2536 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2537 params.htcaps = (u8 *) &htcaps;
2538 params.htcaps_mask = (u8 *) &htcaps_mask;
2539 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2540#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002541#ifdef CONFIG_VHT_OVERRIDES
2542 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2543 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2544 params.vhtcaps = &vhtcaps;
2545 params.vhtcaps_mask = &vhtcaps_mask;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002546 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002547#endif /* CONFIG_VHT_OVERRIDES */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002548
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002549#ifdef CONFIG_P2P
2550 /*
2551 * If multi-channel concurrency is not supported, check for any
2552 * frequency conflict. In case of any frequency conflict, remove the
2553 * least prioritized connection.
2554 */
2555 if (wpa_s->num_multichan_concurrent < 2) {
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -07002556 int freq, num;
2557 num = get_shared_radio_freqs(wpa_s, &freq, 1);
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002558 if (num > 0 && freq > 0 && freq != params.freq.freq) {
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -07002559 wpa_printf(MSG_DEBUG,
2560 "Assoc conflicting freq found (%d != %d)",
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002561 freq, params.freq.freq);
2562 if (wpas_p2p_handle_frequency_conflicts(
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002563 wpa_s, params.freq.freq, ssid) < 0) {
2564 wpas_connect_work_done(wpa_s);
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002565 return;
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002566 }
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002567 }
2568 }
2569#endif /* CONFIG_P2P */
2570
Dmitry Shmidte4663042016-04-04 10:07:49 -07002571 if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
2572 wpa_s->current_ssid)
2573 params.prev_bssid = prev_bssid;
2574
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002575 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002576 if (ret < 0) {
2577 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2578 "failed");
2579 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2580 /*
2581 * The driver is known to mean what is saying, so we
2582 * can stop right here; the association will not
2583 * succeed.
2584 */
2585 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002586 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002587 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2588 return;
2589 }
2590 /* try to continue anyway; new association will be tried again
2591 * after timeout */
2592 assoc_failed = 1;
2593 }
2594
2595 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2596 /* Set the key after the association just in case association
2597 * cleared the previously configured key. */
2598 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2599 /* No need to timeout authentication since there is no key
2600 * management. */
2601 wpa_supplicant_cancel_auth_timeout(wpa_s);
2602 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
2603#ifdef CONFIG_IBSS_RSN
2604 } else if (ssid->mode == WPAS_MODE_IBSS &&
2605 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2606 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2607 /*
2608 * RSN IBSS authentication is per-STA and we can disable the
2609 * per-BSSID authentication.
2610 */
2611 wpa_supplicant_cancel_auth_timeout(wpa_s);
2612#endif /* CONFIG_IBSS_RSN */
2613 } else {
2614 /* Timeout for IEEE 802.11 authentication and association */
2615 int timeout = 60;
2616
2617 if (assoc_failed) {
2618 /* give IBSS a bit more time */
2619 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
2620 } else if (wpa_s->conf->ap_scan == 1) {
2621 /* give IBSS a bit more time */
2622 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
2623 }
2624 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2625 }
2626
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -07002627 if (wep_keys_set &&
2628 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002629 /* Set static WEP keys again */
2630 wpa_set_wep_keys(wpa_s, ssid);
2631 }
2632
2633 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2634 /*
2635 * Do not allow EAP session resumption between different
2636 * network configurations.
2637 */
2638 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2639 }
2640 old_ssid = wpa_s->current_ssid;
2641 wpa_s->current_ssid = ssid;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002642
2643 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
Dmitry Shmidtb1e52102015-05-29 12:36:29 -07002644 wpa_s->current_bss = bss;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002645#ifdef CONFIG_HS20
2646 hs20_configure_frame_filters(wpa_s);
2647#endif /* CONFIG_HS20 */
2648 }
2649
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002650 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2651 wpa_supplicant_initiate_eapol(wpa_s);
2652 if (old_ssid != wpa_s->current_ssid)
2653 wpas_notify_network_changed(wpa_s);
2654}
2655
2656
2657static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2658 const u8 *addr)
2659{
2660 struct wpa_ssid *old_ssid;
2661
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002662 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002663 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002664 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002665 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002666 wpa_sm_set_config(wpa_s->wpa, NULL);
2667 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2668 if (old_ssid != wpa_s->current_ssid)
2669 wpas_notify_network_changed(wpa_s);
2670 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2671}
2672
2673
2674/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002675 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2676 * @wpa_s: Pointer to wpa_supplicant data
2677 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2678 *
2679 * This function is used to request %wpa_supplicant to deauthenticate from the
2680 * current AP.
2681 */
2682void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2683 int reason_code)
2684{
2685 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002686 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002687 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002688
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002689 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2690 " pending_bssid=" MACSTR " reason=%d state=%s",
2691 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2692 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2693
2694 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002695 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002696 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2697 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2698 wpa_s->wpa_state == WPA_ASSOCIATING))
2699 addr = wpa_s->pending_bssid;
2700 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2701 /*
2702 * When using driver-based BSS selection, we may not know the
2703 * BSSID with which we are currently trying to associate. We
2704 * need to notify the driver of this disconnection even in such
2705 * a case, so use the all zeros address here.
2706 */
2707 addr = wpa_s->bssid;
2708 zero_addr = 1;
2709 }
2710
Dmitry Shmidtf8623282013-02-20 14:34:59 -08002711#ifdef CONFIG_TDLS
2712 wpa_tdls_teardown_peers(wpa_s->wpa);
2713#endif /* CONFIG_TDLS */
2714
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002715#ifdef CONFIG_MESH
2716 if (wpa_s->ifmsh) {
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002717 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2718 wpa_s->ifname);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002719 wpa_supplicant_leave_mesh(wpa_s);
2720 }
2721#endif /* CONFIG_MESH */
2722
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002723 if (addr) {
2724 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002725 os_memset(&event, 0, sizeof(event));
2726 event.deauth_info.reason_code = (u16) reason_code;
2727 event.deauth_info.locally_generated = 1;
2728 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002729 if (zero_addr)
2730 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002731 }
2732
2733 wpa_supplicant_clear_connection(wpa_s, addr);
2734}
2735
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002736static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2737 struct wpa_ssid *ssid)
2738{
2739 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2740 return;
2741
2742 ssid->disabled = 0;
2743 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2744 wpas_notify_network_enabled_changed(wpa_s, ssid);
2745
2746 /*
2747 * Try to reassociate since there is no current configuration and a new
2748 * network was made available.
2749 */
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07002750 if (!wpa_s->current_ssid && !wpa_s->disconnected)
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002751 wpa_s->reassociate = 1;
2752}
2753
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002754
2755/**
Dmitry Shmidtd13095b2016-08-22 14:02:19 -07002756 * wpa_supplicant_add_network - Add a new network
2757 * @wpa_s: wpa_supplicant structure for a network interface
2758 * Returns: The new network configuration or %NULL if operation failed
2759 *
2760 * This function performs the following operations:
2761 * 1. Adds a new network.
2762 * 2. Send network addition notification.
2763 * 3. Marks the network disabled.
2764 * 4. Set network default parameters.
2765 */
2766struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
2767{
2768 struct wpa_ssid *ssid;
2769
2770 ssid = wpa_config_add_network(wpa_s->conf);
2771 if (!ssid)
2772 return NULL;
2773 wpas_notify_network_added(wpa_s, ssid);
2774 ssid->disabled = 1;
2775 wpa_config_set_network_defaults(ssid);
2776
2777 return ssid;
2778}
2779
2780
2781/**
2782 * wpa_supplicant_remove_network - Remove a configured network based on id
2783 * @wpa_s: wpa_supplicant structure for a network interface
2784 * @id: Unique network id to search for
2785 * Returns: 0 on success, or -1 if the network was not found, -2 if the network
2786 * could not be removed
2787 *
2788 * This function performs the following operations:
2789 * 1. Removes the network.
2790 * 2. Send network removal notification.
2791 * 3. Update internal state machines.
2792 * 4. Stop any running sched scans.
2793 */
2794int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
2795{
2796 struct wpa_ssid *ssid;
2797 int was_disabled;
2798
2799 ssid = wpa_config_get_network(wpa_s->conf, id);
2800 if (!ssid)
2801 return -1;
2802 wpas_notify_network_removed(wpa_s, ssid);
2803
2804 if (wpa_s->last_ssid == ssid)
2805 wpa_s->last_ssid = NULL;
2806
2807 if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
2808#ifdef CONFIG_SME
2809 wpa_s->sme.prev_bssid_set = 0;
2810#endif /* CONFIG_SME */
2811 /*
2812 * Invalidate the EAP session cache if the current or
2813 * previously used network is removed.
2814 */
2815 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2816 }
2817
2818 if (ssid == wpa_s->current_ssid) {
2819 wpa_sm_set_config(wpa_s->wpa, NULL);
2820 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2821
2822 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2823 wpa_s->own_disconnect_req = 1;
2824 wpa_supplicant_deauthenticate(wpa_s,
2825 WLAN_REASON_DEAUTH_LEAVING);
2826 }
2827
2828 was_disabled = ssid->disabled;
2829
2830 if (wpa_config_remove_network(wpa_s->conf, id) < 0)
2831 return -2;
2832
2833 if (!was_disabled && wpa_s->sched_scanning) {
2834 wpa_printf(MSG_DEBUG,
2835 "Stop ongoing sched_scan to remove network from filters");
2836 wpa_supplicant_cancel_sched_scan(wpa_s);
2837 wpa_supplicant_req_scan(wpa_s, 0, 0);
2838 }
2839
2840 return 0;
2841}
2842
2843
2844/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002845 * wpa_supplicant_enable_network - Mark a configured network as enabled
2846 * @wpa_s: wpa_supplicant structure for a network interface
2847 * @ssid: wpa_ssid structure for a configured network or %NULL
2848 *
2849 * Enables the specified network or all networks if no network specified.
2850 */
2851void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2852 struct wpa_ssid *ssid)
2853{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002854 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002855 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2856 wpa_supplicant_enable_one_network(wpa_s, ssid);
2857 } else
2858 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002859
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002860 if (wpa_s->reassociate && !wpa_s->disconnected &&
2861 (!wpa_s->current_ssid ||
2862 wpa_s->wpa_state == WPA_DISCONNECTED ||
2863 wpa_s->wpa_state == WPA_SCANNING)) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002864 if (wpa_s->sched_scanning) {
2865 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2866 "new network to scan filters");
2867 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002868 }
2869
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002870 if (wpa_supplicant_fast_associate(wpa_s) != 1) {
2871 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002872 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002873 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002874 }
2875}
2876
2877
2878/**
2879 * wpa_supplicant_disable_network - Mark a configured network as disabled
2880 * @wpa_s: wpa_supplicant structure for a network interface
2881 * @ssid: wpa_ssid structure for a configured network or %NULL
2882 *
2883 * Disables the specified network or all networks if no network specified.
2884 */
2885void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2886 struct wpa_ssid *ssid)
2887{
2888 struct wpa_ssid *other_ssid;
2889 int was_disabled;
2890
2891 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002892 if (wpa_s->sched_scanning)
2893 wpa_supplicant_cancel_sched_scan(wpa_s);
2894
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002895 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2896 other_ssid = other_ssid->next) {
2897 was_disabled = other_ssid->disabled;
2898 if (was_disabled == 2)
2899 continue; /* do not change persistent P2P group
2900 * data */
2901
2902 other_ssid->disabled = 1;
2903
2904 if (was_disabled != other_ssid->disabled)
2905 wpas_notify_network_enabled_changed(
2906 wpa_s, other_ssid);
2907 }
2908 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002909 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002910 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2911 } else if (ssid->disabled != 2) {
2912 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002913 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002914 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2915
2916 was_disabled = ssid->disabled;
2917
2918 ssid->disabled = 1;
2919
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002920 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002921 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002922 if (wpa_s->sched_scanning) {
2923 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2924 "to remove network from filters");
2925 wpa_supplicant_cancel_sched_scan(wpa_s);
2926 wpa_supplicant_req_scan(wpa_s, 0, 0);
2927 }
2928 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002929 }
2930}
2931
2932
2933/**
2934 * wpa_supplicant_select_network - Attempt association with a network
2935 * @wpa_s: wpa_supplicant structure for a network interface
2936 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2937 */
2938void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2939 struct wpa_ssid *ssid)
2940{
2941
2942 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002943 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002944
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002945 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -07002946 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2947 wpa_s->own_disconnect_req = 1;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002948 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002949 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002950 disconnected = 1;
2951 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002952
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002953 if (ssid)
2954 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2955
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002956 /*
2957 * Mark all other networks disabled or mark all networks enabled if no
2958 * network specified.
2959 */
2960 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2961 other_ssid = other_ssid->next) {
2962 int was_disabled = other_ssid->disabled;
2963 if (was_disabled == 2)
2964 continue; /* do not change persistent P2P group data */
2965
2966 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002967 if (was_disabled && !other_ssid->disabled)
2968 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002969
2970 if (was_disabled != other_ssid->disabled)
2971 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
2972 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002973
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002974 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
2975 wpa_s->wpa_state >= WPA_AUTHENTICATING) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002976 /* We are already associated with the selected network */
2977 wpa_printf(MSG_DEBUG, "Already associated with the "
2978 "selected network - do nothing");
2979 return;
2980 }
2981
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002982 if (ssid) {
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002983 wpa_s->current_ssid = ssid;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002984 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002985 wpa_s->connect_without_scan =
2986 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
Dmitry Shmidtdda10c22015-03-24 16:05:01 -07002987
2988 /*
2989 * Don't optimize next scan freqs since a new ESS has been
2990 * selected.
2991 */
2992 os_free(wpa_s->next_scan_freqs);
2993 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002994 } else {
2995 wpa_s->connect_without_scan = NULL;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002996 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002997
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002998 wpa_s->disconnected = 0;
2999 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08003000
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003001 if (wpa_s->connect_without_scan ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003002 wpa_supplicant_fast_associate(wpa_s) != 1) {
3003 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08003004 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003005 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003006
3007 if (ssid)
3008 wpas_notify_network_selected(wpa_s, ssid);
3009}
3010
3011
3012/**
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08003013 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
3014 * @wpa_s: wpa_supplicant structure for a network interface
3015 * @pkcs11_engine_path: PKCS #11 engine path or NULL
3016 * @pkcs11_module_path: PKCS #11 module path or NULL
3017 * Returns: 0 on success; -1 on failure
3018 *
3019 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
3020 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
3021 * module path fails the paths will be reset to the default value (NULL).
3022 */
3023int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
3024 const char *pkcs11_engine_path,
3025 const char *pkcs11_module_path)
3026{
3027 char *pkcs11_engine_path_copy = NULL;
3028 char *pkcs11_module_path_copy = NULL;
3029
3030 if (pkcs11_engine_path != NULL) {
3031 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
3032 if (pkcs11_engine_path_copy == NULL)
3033 return -1;
3034 }
3035 if (pkcs11_module_path != NULL) {
3036 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
Dmitry Shmidt97672262014-02-03 13:02:54 -08003037 if (pkcs11_module_path_copy == NULL) {
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08003038 os_free(pkcs11_engine_path_copy);
3039 return -1;
3040 }
3041 }
3042
3043 os_free(wpa_s->conf->pkcs11_engine_path);
3044 os_free(wpa_s->conf->pkcs11_module_path);
3045 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
3046 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
3047
3048 wpa_sm_set_eapol(wpa_s->wpa, NULL);
3049 eapol_sm_deinit(wpa_s->eapol);
3050 wpa_s->eapol = NULL;
3051 if (wpa_supplicant_init_eapol(wpa_s)) {
3052 /* Error -> Reset paths to the default value (NULL) once. */
3053 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
3054 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
3055 NULL);
3056
3057 return -1;
3058 }
3059 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3060
3061 return 0;
3062}
3063
3064
3065/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003066 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
3067 * @wpa_s: wpa_supplicant structure for a network interface
3068 * @ap_scan: AP scan mode
3069 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
3070 *
3071 */
3072int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
3073{
3074
3075 int old_ap_scan;
3076
3077 if (ap_scan < 0 || ap_scan > 2)
3078 return -1;
3079
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003080 if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3081 wpa_printf(MSG_INFO,
3082 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3083 }
3084
Dmitry Shmidt114c3862011-08-16 11:52:06 -07003085#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003086 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
3087 wpa_s->wpa_state >= WPA_ASSOCIATING &&
3088 wpa_s->wpa_state < WPA_COMPLETED) {
3089 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
3090 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07003091 return 0;
3092 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003093#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07003094
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003095 old_ap_scan = wpa_s->conf->ap_scan;
3096 wpa_s->conf->ap_scan = ap_scan;
3097
3098 if (old_ap_scan != wpa_s->conf->ap_scan)
3099 wpas_notify_ap_scan_changed(wpa_s);
3100
3101 return 0;
3102}
3103
3104
3105/**
3106 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
3107 * @wpa_s: wpa_supplicant structure for a network interface
3108 * @expire_age: Expiration age in seconds
3109 * Returns: 0 if succeed or -1 if expire_age has an invalid value
3110 *
3111 */
3112int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
3113 unsigned int bss_expire_age)
3114{
3115 if (bss_expire_age < 10) {
3116 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
3117 bss_expire_age);
3118 return -1;
3119 }
3120 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
3121 bss_expire_age);
3122 wpa_s->conf->bss_expiration_age = bss_expire_age;
3123
3124 return 0;
3125}
3126
3127
3128/**
3129 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
3130 * @wpa_s: wpa_supplicant structure for a network interface
3131 * @expire_count: number of scans after which an unseen BSS is reclaimed
3132 * Returns: 0 if succeed or -1 if expire_count has an invalid value
3133 *
3134 */
3135int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
3136 unsigned int bss_expire_count)
3137{
3138 if (bss_expire_count < 1) {
3139 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
3140 bss_expire_count);
3141 return -1;
3142 }
3143 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
3144 bss_expire_count);
3145 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
3146
3147 return 0;
3148}
3149
3150
3151/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07003152 * wpa_supplicant_set_scan_interval - Set scan interval
3153 * @wpa_s: wpa_supplicant structure for a network interface
3154 * @scan_interval: scan interval in seconds
3155 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
3156 *
3157 */
3158int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
3159 int scan_interval)
3160{
3161 if (scan_interval < 0) {
3162 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
3163 scan_interval);
3164 return -1;
3165 }
3166 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
3167 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08003168 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003169
3170 return 0;
3171}
3172
3173
3174/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003175 * wpa_supplicant_set_debug_params - Set global debug params
3176 * @global: wpa_global structure
3177 * @debug_level: debug level
3178 * @debug_timestamp: determines if show timestamp in debug data
3179 * @debug_show_keys: determines if show keys in debug data
3180 * Returns: 0 if succeed or -1 if debug_level has wrong value
3181 */
3182int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
3183 int debug_timestamp, int debug_show_keys)
3184{
3185
3186 int old_level, old_timestamp, old_show_keys;
3187
3188 /* check for allowed debuglevels */
3189 if (debug_level != MSG_EXCESSIVE &&
3190 debug_level != MSG_MSGDUMP &&
3191 debug_level != MSG_DEBUG &&
3192 debug_level != MSG_INFO &&
3193 debug_level != MSG_WARNING &&
3194 debug_level != MSG_ERROR)
3195 return -1;
3196
3197 old_level = wpa_debug_level;
3198 old_timestamp = wpa_debug_timestamp;
3199 old_show_keys = wpa_debug_show_keys;
3200
3201 wpa_debug_level = debug_level;
3202 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
3203 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
3204
3205 if (wpa_debug_level != old_level)
3206 wpas_notify_debug_level_changed(global);
3207 if (wpa_debug_timestamp != old_timestamp)
3208 wpas_notify_debug_timestamp_changed(global);
3209 if (wpa_debug_show_keys != old_show_keys)
3210 wpas_notify_debug_show_keys_changed(global);
3211
3212 return 0;
3213}
3214
3215
3216/**
3217 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
3218 * @wpa_s: Pointer to wpa_supplicant data
3219 * Returns: A pointer to the current network structure or %NULL on failure
3220 */
3221struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
3222{
3223 struct wpa_ssid *entry;
Dmitry Shmidt9d9e6022015-04-23 10:34:55 -07003224 u8 ssid[SSID_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003225 int res;
3226 size_t ssid_len;
3227 u8 bssid[ETH_ALEN];
3228 int wired;
3229
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003230 res = wpa_drv_get_ssid(wpa_s, ssid);
3231 if (res < 0) {
3232 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
3233 "driver");
3234 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003235 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003236 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003237
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003238 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003239 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
3240 "driver");
3241 return NULL;
3242 }
3243
3244 wired = wpa_s->conf->ap_scan == 0 &&
3245 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
3246
3247 entry = wpa_s->conf->ssid;
3248 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07003249 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003250 ((ssid_len == entry->ssid_len &&
3251 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
3252 (!entry->bssid_set ||
3253 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3254 return entry;
3255#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07003256 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003257 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
3258 (entry->ssid == NULL || entry->ssid_len == 0) &&
3259 (!entry->bssid_set ||
3260 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3261 return entry;
3262#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003263
Dmitry Shmidt04949592012-07-19 12:16:46 -07003264 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003265 entry->ssid_len == 0 &&
3266 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
3267 return entry;
3268
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003269 entry = entry->next;
3270 }
3271
3272 return NULL;
3273}
3274
3275
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003276static int select_driver(struct wpa_supplicant *wpa_s, int i)
3277{
3278 struct wpa_global *global = wpa_s->global;
3279
3280 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
Dmitry Shmidte4663042016-04-04 10:07:49 -07003281 global->drv_priv[i] = wpa_drivers[i]->global_init(global);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003282 if (global->drv_priv[i] == NULL) {
3283 wpa_printf(MSG_ERROR, "Failed to initialize driver "
3284 "'%s'", wpa_drivers[i]->name);
3285 return -1;
3286 }
3287 }
3288
3289 wpa_s->driver = wpa_drivers[i];
3290 wpa_s->global_drv_priv = global->drv_priv[i];
3291
3292 return 0;
3293}
3294
3295
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003296static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
3297 const char *name)
3298{
3299 int i;
3300 size_t len;
3301 const char *pos, *driver = name;
3302
3303 if (wpa_s == NULL)
3304 return -1;
3305
3306 if (wpa_drivers[0] == NULL) {
3307 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
3308 "wpa_supplicant");
3309 return -1;
3310 }
3311
3312 if (name == NULL) {
3313 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003314 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003315 }
3316
3317 do {
3318 pos = os_strchr(driver, ',');
3319 if (pos)
3320 len = pos - driver;
3321 else
3322 len = os_strlen(driver);
3323
3324 for (i = 0; wpa_drivers[i]; i++) {
3325 if (os_strlen(wpa_drivers[i]->name) == len &&
3326 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003327 0) {
3328 /* First driver that succeeds wins */
3329 if (select_driver(wpa_s, i) == 0)
3330 return 0;
3331 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003332 }
3333
3334 driver = pos + 1;
3335 } while (pos);
3336
3337 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
3338 return -1;
3339}
3340
3341
3342/**
3343 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
3344 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
3345 * with struct wpa_driver_ops::init()
3346 * @src_addr: Source address of the EAPOL frame
3347 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
3348 * @len: Length of the EAPOL data
3349 *
3350 * This function is called for each received EAPOL frame. Most driver
3351 * interfaces rely on more generic OS mechanism for receiving frames through
3352 * l2_packet, but if such a mechanism is not available, the driver wrapper may
3353 * take care of received EAPOL frames and deliver them to the core supplicant
3354 * code by calling this function.
3355 */
3356void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
3357 const u8 *buf, size_t len)
3358{
3359 struct wpa_supplicant *wpa_s = ctx;
3360
3361 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
3362 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
3363
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003364#ifdef CONFIG_PEERKEY
3365 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
3366 wpa_s->current_ssid->peerkey &&
3367 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
3368 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
3369 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
3370 return;
3371 }
3372#endif /* CONFIG_PEERKEY */
3373
Jouni Malinena05074c2012-12-21 21:35:35 +02003374 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3375 (wpa_s->last_eapol_matches_bssid &&
3376#ifdef CONFIG_AP
3377 !wpa_s->ap_iface &&
3378#endif /* CONFIG_AP */
3379 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003380 /*
3381 * There is possible race condition between receiving the
3382 * association event and the EAPOL frame since they are coming
3383 * through different paths from the driver. In order to avoid
3384 * issues in trying to process the EAPOL frame before receiving
3385 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02003386 * the association event is received. This may also be needed in
3387 * driver-based roaming case, so also use src_addr != BSSID as a
3388 * trigger if we have previously confirmed that the
3389 * Authenticator uses BSSID as the src_addr (which is not the
3390 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003391 */
3392 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02003393 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3394 wpa_supplicant_state_txt(wpa_s->wpa_state),
3395 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003396 wpabuf_free(wpa_s->pending_eapol_rx);
3397 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3398 if (wpa_s->pending_eapol_rx) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003399 os_get_reltime(&wpa_s->pending_eapol_rx_time);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003400 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3401 ETH_ALEN);
3402 }
3403 return;
3404 }
3405
Jouni Malinena05074c2012-12-21 21:35:35 +02003406 wpa_s->last_eapol_matches_bssid =
3407 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3408
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003409#ifdef CONFIG_AP
3410 if (wpa_s->ap_iface) {
3411 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3412 return;
3413 }
3414#endif /* CONFIG_AP */
3415
3416 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
3417 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3418 "no key management is configured");
3419 return;
3420 }
3421
3422 if (wpa_s->eapol_received == 0 &&
3423 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
3424 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
3425 wpa_s->wpa_state != WPA_COMPLETED) &&
3426 (wpa_s->current_ssid == NULL ||
3427 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
3428 /* Timeout for completing IEEE 802.1X and WPA authentication */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003429 int timeout = 10;
3430
3431 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
3432 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3433 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
3434 /* Use longer timeout for IEEE 802.1X/EAP */
3435 timeout = 70;
3436 }
3437
Dmitry Shmidt8bd70b72015-05-26 16:02:19 -07003438#ifdef CONFIG_WPS
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003439 if (wpa_s->current_ssid && wpa_s->current_bss &&
3440 (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
3441 eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
3442 /*
3443 * Use shorter timeout if going through WPS AP iteration
3444 * for PIN config method with an AP that does not
3445 * advertise Selected Registrar.
3446 */
3447 struct wpabuf *wps_ie;
3448
3449 wps_ie = wpa_bss_get_vendor_ie_multi(
3450 wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
3451 if (wps_ie &&
3452 !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
3453 timeout = 10;
3454 wpabuf_free(wps_ie);
3455 }
Dmitry Shmidt8bd70b72015-05-26 16:02:19 -07003456#endif /* CONFIG_WPS */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003457
3458 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003459 }
3460 wpa_s->eapol_received++;
3461
3462 if (wpa_s->countermeasures) {
3463 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3464 "EAPOL packet");
3465 return;
3466 }
3467
3468#ifdef CONFIG_IBSS_RSN
3469 if (wpa_s->current_ssid &&
3470 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
3471 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3472 return;
3473 }
3474#endif /* CONFIG_IBSS_RSN */
3475
3476 /* Source address of the incoming EAPOL frame could be compared to the
3477 * current BSSID. However, it is possible that a centralized
3478 * Authenticator could be using another MAC address than the BSSID of
3479 * an AP, so just allow any address to be used for now. The replies are
3480 * still sent to the current BSSID (if available), though. */
3481
3482 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
3483 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
3484 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3485 return;
3486 wpa_drv_poll(wpa_s);
3487 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
3488 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
3489 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
3490 /*
3491 * Set portValid = TRUE here since we are going to skip 4-way
3492 * handshake processing which would normally set portValid. We
3493 * need this to allow the EAPOL state machines to be completed
3494 * without going through EAPOL-Key handshake.
3495 */
3496 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3497 }
3498}
3499
3500
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003501int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003502{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003503 if ((!wpa_s->p2p_mgmt ||
3504 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3505 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003506 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003507 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3508 wpa_drv_get_mac_addr(wpa_s),
3509 ETH_P_EAPOL,
3510 wpa_supplicant_rx_eapol, wpa_s, 0);
3511 if (wpa_s->l2 == NULL)
3512 return -1;
3513 } else {
3514 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3515 if (addr)
3516 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
3517 }
3518
3519 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
3520 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
3521 return -1;
3522 }
3523
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07003524 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3525
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003526 return 0;
3527}
3528
3529
Dmitry Shmidt04949592012-07-19 12:16:46 -07003530static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3531 const u8 *buf, size_t len)
3532{
3533 struct wpa_supplicant *wpa_s = ctx;
3534 const struct l2_ethhdr *eth;
3535
3536 if (len < sizeof(*eth))
3537 return;
3538 eth = (const struct l2_ethhdr *) buf;
3539
3540 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3541 !(eth->h_dest[0] & 0x01)) {
3542 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3543 " (bridge - not for this interface - ignore)",
3544 MAC2STR(src_addr), MAC2STR(eth->h_dest));
3545 return;
3546 }
3547
3548 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3549 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3550 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3551 len - sizeof(*eth));
3552}
3553
3554
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003555/**
3556 * wpa_supplicant_driver_init - Initialize driver interface parameters
3557 * @wpa_s: Pointer to wpa_supplicant data
3558 * Returns: 0 on success, -1 on failure
3559 *
3560 * This function is called to initialize driver interface parameters.
3561 * wpa_drv_init() must have been called before this function to initialize the
3562 * driver interface.
3563 */
3564int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3565{
3566 static int interface_count = 0;
3567
3568 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3569 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003570
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003571 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3572 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07003573 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003574 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3575
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003576 if (wpa_s->bridge_ifname[0]) {
3577 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3578 "interface '%s'", wpa_s->bridge_ifname);
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003579 wpa_s->l2_br = l2_packet_init_bridge(
3580 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3581 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003582 if (wpa_s->l2_br == NULL) {
3583 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3584 "connection for the bridge interface '%s'",
3585 wpa_s->bridge_ifname);
3586 return -1;
3587 }
3588 }
3589
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003590 if (wpa_s->conf->ap_scan == 2 &&
3591 os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3592 wpa_printf(MSG_INFO,
3593 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3594 }
3595
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003596 wpa_clear_keys(wpa_s, NULL);
3597
3598 /* Make sure that TKIP countermeasures are not left enabled (could
3599 * happen if wpa_supplicant is killed during countermeasures. */
3600 wpa_drv_set_countermeasures(wpa_s, 0);
3601
3602 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
3603 wpa_drv_flush_pmkid(wpa_s);
3604
3605 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003606 wpa_s->prev_scan_wildcard = 0;
3607
Dmitry Shmidt04949592012-07-19 12:16:46 -07003608 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt9e3f8ee2014-01-17 10:52:01 -08003609 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3610 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3611 interface_count = 0;
3612 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003613#ifndef ANDROID
Dmitry Shmidta38abf92014-03-06 13:38:44 -08003614 if (!wpa_s->p2p_mgmt &&
Dmitry Shmidt98660862014-03-11 17:26:21 -07003615 wpa_supplicant_delayed_sched_scan(wpa_s,
3616 interface_count % 3,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003617 100000))
Dmitry Shmidt98660862014-03-11 17:26:21 -07003618 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003619 100000);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003620#endif /* ANDROID */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003621 interface_count++;
3622 } else
3623 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
3624
3625 return 0;
3626}
3627
3628
3629static int wpa_supplicant_daemon(const char *pid_file)
3630{
3631 wpa_printf(MSG_DEBUG, "Daemonize..");
3632 return os_daemonize(pid_file);
3633}
3634
3635
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08003636static struct wpa_supplicant *
3637wpa_supplicant_alloc(struct wpa_supplicant *parent)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003638{
3639 struct wpa_supplicant *wpa_s;
3640
3641 wpa_s = os_zalloc(sizeof(*wpa_s));
3642 if (wpa_s == NULL)
3643 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003644 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003645 wpa_s->scan_interval = 5;
3646 wpa_s->new_connection = 1;
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08003647 wpa_s->parent = parent ? parent : wpa_s;
Dmitry Shmidt9c175262016-03-03 10:20:07 -08003648 wpa_s->p2pdev = wpa_s->parent;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003649 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003650
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003651 dl_list_init(&wpa_s->bss_tmp_disallowed);
3652
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003653 return wpa_s;
3654}
3655
3656
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003657#ifdef CONFIG_HT_OVERRIDES
3658
3659static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3660 struct ieee80211_ht_capabilities *htcaps,
3661 struct ieee80211_ht_capabilities *htcaps_mask,
3662 const char *ht_mcs)
3663{
3664 /* parse ht_mcs into hex array */
3665 int i;
3666 const char *tmp = ht_mcs;
3667 char *end = NULL;
3668
3669 /* If ht_mcs is null, do not set anything */
3670 if (!ht_mcs)
3671 return 0;
3672
3673 /* This is what we are setting in the kernel */
3674 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3675
3676 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3677
3678 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3679 errno = 0;
3680 long v = strtol(tmp, &end, 16);
3681 if (errno == 0) {
3682 wpa_msg(wpa_s, MSG_DEBUG,
3683 "htcap value[%i]: %ld end: %p tmp: %p",
3684 i, v, end, tmp);
3685 if (end == tmp)
3686 break;
3687
3688 htcaps->supported_mcs_set[i] = v;
3689 tmp = end;
3690 } else {
3691 wpa_msg(wpa_s, MSG_ERROR,
3692 "Failed to parse ht-mcs: %s, error: %s\n",
3693 ht_mcs, strerror(errno));
3694 return -1;
3695 }
3696 }
3697
3698 /*
3699 * If we were able to parse any values, then set mask for the MCS set.
3700 */
3701 if (i) {
3702 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3703 IEEE80211_HT_MCS_MASK_LEN - 1);
3704 /* skip the 3 reserved bits */
3705 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3706 0x1f;
3707 }
3708
3709 return 0;
3710}
3711
3712
3713static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3714 struct ieee80211_ht_capabilities *htcaps,
3715 struct ieee80211_ht_capabilities *htcaps_mask,
3716 int disabled)
3717{
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003718 le16 msk;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003719
3720 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3721
3722 if (disabled == -1)
3723 return 0;
3724
3725 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3726 htcaps_mask->ht_capabilities_info |= msk;
3727 if (disabled)
3728 htcaps->ht_capabilities_info &= msk;
3729 else
3730 htcaps->ht_capabilities_info |= msk;
3731
3732 return 0;
3733}
3734
3735
3736static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3737 struct ieee80211_ht_capabilities *htcaps,
3738 struct ieee80211_ht_capabilities *htcaps_mask,
3739 int factor)
3740{
3741 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3742
3743 if (factor == -1)
3744 return 0;
3745
3746 if (factor < 0 || factor > 3) {
3747 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3748 "Must be 0-3 or -1", factor);
3749 return -EINVAL;
3750 }
3751
3752 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3753 htcaps->a_mpdu_params &= ~0x3;
3754 htcaps->a_mpdu_params |= factor & 0x3;
3755
3756 return 0;
3757}
3758
3759
3760static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3761 struct ieee80211_ht_capabilities *htcaps,
3762 struct ieee80211_ht_capabilities *htcaps_mask,
3763 int density)
3764{
3765 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3766
3767 if (density == -1)
3768 return 0;
3769
3770 if (density < 0 || density > 7) {
3771 wpa_msg(wpa_s, MSG_ERROR,
3772 "ampdu_density: %d out of range. Must be 0-7 or -1.",
3773 density);
3774 return -EINVAL;
3775 }
3776
3777 htcaps_mask->a_mpdu_params |= 0x1C;
3778 htcaps->a_mpdu_params &= ~(0x1C);
3779 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3780
3781 return 0;
3782}
3783
3784
3785static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3786 struct ieee80211_ht_capabilities *htcaps,
3787 struct ieee80211_ht_capabilities *htcaps_mask,
3788 int disabled)
3789{
3790 /* Masking these out disables HT40 */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003791 le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3792 HT_CAP_INFO_SHORT_GI40MHZ);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003793
3794 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3795
3796 if (disabled)
3797 htcaps->ht_capabilities_info &= ~msk;
3798 else
3799 htcaps->ht_capabilities_info |= msk;
3800
3801 htcaps_mask->ht_capabilities_info |= msk;
3802
3803 return 0;
3804}
3805
3806
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003807static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3808 struct ieee80211_ht_capabilities *htcaps,
3809 struct ieee80211_ht_capabilities *htcaps_mask,
3810 int disabled)
3811{
3812 /* Masking these out disables SGI */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003813 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3814 HT_CAP_INFO_SHORT_GI40MHZ);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003815
3816 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3817
3818 if (disabled)
3819 htcaps->ht_capabilities_info &= ~msk;
3820 else
3821 htcaps->ht_capabilities_info |= msk;
3822
3823 htcaps_mask->ht_capabilities_info |= msk;
3824
3825 return 0;
3826}
3827
3828
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003829static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3830 struct ieee80211_ht_capabilities *htcaps,
3831 struct ieee80211_ht_capabilities *htcaps_mask,
3832 int disabled)
3833{
3834 /* Masking these out disables LDPC */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003835 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003836
3837 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3838
3839 if (disabled)
3840 htcaps->ht_capabilities_info &= ~msk;
3841 else
3842 htcaps->ht_capabilities_info |= msk;
3843
3844 htcaps_mask->ht_capabilities_info |= msk;
3845
3846 return 0;
3847}
3848
3849
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003850void wpa_supplicant_apply_ht_overrides(
3851 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3852 struct wpa_driver_associate_params *params)
3853{
3854 struct ieee80211_ht_capabilities *htcaps;
3855 struct ieee80211_ht_capabilities *htcaps_mask;
3856
3857 if (!ssid)
3858 return;
3859
3860 params->disable_ht = ssid->disable_ht;
3861 if (!params->htcaps || !params->htcaps_mask)
3862 return;
3863
3864 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3865 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3866 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3867 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3868 ssid->disable_max_amsdu);
3869 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3870 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3871 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003872 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003873 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003874
3875 if (ssid->ht40_intolerant) {
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003876 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003877 htcaps->ht_capabilities_info |= bit;
3878 htcaps_mask->ht_capabilities_info |= bit;
3879 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003880}
3881
3882#endif /* CONFIG_HT_OVERRIDES */
3883
3884
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003885#ifdef CONFIG_VHT_OVERRIDES
3886void wpa_supplicant_apply_vht_overrides(
3887 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3888 struct wpa_driver_associate_params *params)
3889{
3890 struct ieee80211_vht_capabilities *vhtcaps;
3891 struct ieee80211_vht_capabilities *vhtcaps_mask;
3892
3893 if (!ssid)
3894 return;
3895
3896 params->disable_vht = ssid->disable_vht;
3897
3898 vhtcaps = (void *) params->vhtcaps;
3899 vhtcaps_mask = (void *) params->vhtcaps_mask;
3900
3901 if (!vhtcaps || !vhtcaps_mask)
3902 return;
3903
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07003904 vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
3905 vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003906
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003907#ifdef CONFIG_HT_OVERRIDES
3908 /* if max ampdu is <= 3, we have to make the HT cap the same */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003909 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3910 int max_ampdu;
3911
3912 max_ampdu = (ssid->vht_capa &
3913 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3914 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003915
3916 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3917 wpa_set_ampdu_factor(wpa_s,
3918 (void *) params->htcaps,
3919 (void *) params->htcaps_mask,
3920 max_ampdu);
3921 }
3922#endif /* CONFIG_HT_OVERRIDES */
3923
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003924#define OVERRIDE_MCS(i) \
3925 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3926 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07003927 host_to_le16(3 << 2 * (i - 1)); \
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003928 vhtcaps->vht_supported_mcs_set.tx_map |= \
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07003929 host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
3930 2 * (i - 1)); \
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003931 } \
3932 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3933 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07003934 host_to_le16(3 << 2 * (i - 1)); \
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003935 vhtcaps->vht_supported_mcs_set.rx_map |= \
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07003936 host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
3937 2 * (i - 1)); \
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003938 }
3939
3940 OVERRIDE_MCS(1);
3941 OVERRIDE_MCS(2);
3942 OVERRIDE_MCS(3);
3943 OVERRIDE_MCS(4);
3944 OVERRIDE_MCS(5);
3945 OVERRIDE_MCS(6);
3946 OVERRIDE_MCS(7);
3947 OVERRIDE_MCS(8);
3948}
3949#endif /* CONFIG_VHT_OVERRIDES */
3950
3951
Dmitry Shmidt04949592012-07-19 12:16:46 -07003952static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3953{
3954#ifdef PCSC_FUNCS
3955 size_t len;
3956
3957 if (!wpa_s->conf->pcsc_reader)
3958 return 0;
3959
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -08003960 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003961 if (!wpa_s->scard)
3962 return 1;
3963
3964 if (wpa_s->conf->pcsc_pin &&
3965 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
3966 scard_deinit(wpa_s->scard);
3967 wpa_s->scard = NULL;
3968 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
3969 return -1;
3970 }
3971
3972 len = sizeof(wpa_s->imsi) - 1;
3973 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
3974 scard_deinit(wpa_s->scard);
3975 wpa_s->scard = NULL;
3976 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
3977 return -1;
3978 }
3979 wpa_s->imsi[len] = '\0';
3980
3981 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
3982
3983 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
3984 wpa_s->imsi, wpa_s->mnc_len);
3985
3986 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
3987 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
3988#endif /* PCSC_FUNCS */
3989
3990 return 0;
3991}
3992
3993
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003994int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
3995{
3996 char *val, *pos;
3997
3998 ext_password_deinit(wpa_s->ext_pw);
3999 wpa_s->ext_pw = NULL;
4000 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
4001
4002 if (!wpa_s->conf->ext_password_backend)
4003 return 0;
4004
4005 val = os_strdup(wpa_s->conf->ext_password_backend);
4006 if (val == NULL)
4007 return -1;
4008 pos = os_strchr(val, ':');
4009 if (pos)
4010 *pos++ = '\0';
4011
4012 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
4013
4014 wpa_s->ext_pw = ext_password_init(val, pos);
4015 os_free(val);
4016 if (wpa_s->ext_pw == NULL) {
4017 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
4018 return -1;
4019 }
4020 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
4021
4022 return 0;
4023}
4024
4025
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004026#ifdef CONFIG_FST
4027
4028static const u8 * wpas_fst_get_bssid_cb(void *ctx)
4029{
4030 struct wpa_supplicant *wpa_s = ctx;
4031
4032 return (is_zero_ether_addr(wpa_s->bssid) ||
4033 wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
4034}
4035
4036
4037static void wpas_fst_get_channel_info_cb(void *ctx,
4038 enum hostapd_hw_mode *hw_mode,
4039 u8 *channel)
4040{
4041 struct wpa_supplicant *wpa_s = ctx;
4042
4043 if (wpa_s->current_bss) {
4044 *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
4045 channel);
4046 } else if (wpa_s->hw.num_modes) {
4047 *hw_mode = wpa_s->hw.modes[0].mode;
4048 } else {
4049 WPA_ASSERT(0);
4050 *hw_mode = 0;
4051 }
4052}
4053
4054
4055static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
4056{
4057 struct wpa_supplicant *wpa_s = ctx;
4058
4059 *modes = wpa_s->hw.modes;
4060 return wpa_s->hw.num_modes;
4061}
4062
4063
4064static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
4065{
4066 struct wpa_supplicant *wpa_s = ctx;
4067
4068 wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
4069 wpa_s->fst_ies = fst_ies;
4070}
4071
4072
4073static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
4074{
4075 struct wpa_supplicant *wpa_s = ctx;
4076
4077 WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
4078 return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
4079 wpa_s->own_addr, wpa_s->bssid,
4080 wpabuf_head(data), wpabuf_len(data),
4081 0);
4082}
4083
4084
4085static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
4086{
4087 struct wpa_supplicant *wpa_s = ctx;
4088
4089 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4090 return wpa_s->received_mb_ies;
4091}
4092
4093
4094static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
4095 const u8 *buf, size_t size)
4096{
4097 struct wpa_supplicant *wpa_s = ctx;
4098 struct mb_ies_info info;
4099
4100 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4101
4102 if (!mb_ies_info_by_ies(&info, buf, size)) {
4103 wpabuf_free(wpa_s->received_mb_ies);
4104 wpa_s->received_mb_ies = mb_ies_by_info(&info);
4105 }
4106}
4107
4108
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07004109static const u8 * wpas_fst_get_peer_first(void *ctx,
4110 struct fst_get_peer_ctx **get_ctx,
4111 Boolean mb_only)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004112{
4113 struct wpa_supplicant *wpa_s = ctx;
4114
4115 *get_ctx = NULL;
4116 if (!is_zero_ether_addr(wpa_s->bssid))
4117 return (wpa_s->received_mb_ies || !mb_only) ?
4118 wpa_s->bssid : NULL;
4119 return NULL;
4120}
4121
4122
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -07004123static const u8 * wpas_fst_get_peer_next(void *ctx,
4124 struct fst_get_peer_ctx **get_ctx,
4125 Boolean mb_only)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004126{
4127 return NULL;
4128}
4129
4130void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
4131 struct fst_wpa_obj *iface_obj)
4132{
4133 iface_obj->ctx = wpa_s;
4134 iface_obj->get_bssid = wpas_fst_get_bssid_cb;
4135 iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
4136 iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
4137 iface_obj->set_ies = wpas_fst_set_ies_cb;
4138 iface_obj->send_action = wpas_fst_send_action_cb;
4139 iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
4140 iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
4141 iface_obj->get_peer_first = wpas_fst_get_peer_first;
4142 iface_obj->get_peer_next = wpas_fst_get_peer_next;
4143}
4144#endif /* CONFIG_FST */
4145
Dmitry Shmidtc2817022014-07-02 10:32:10 -07004146static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004147 const struct wpa_driver_capa *capa)
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004148{
Dmitry Shmidt0207e232014-09-03 14:58:37 -07004149 struct wowlan_triggers *triggers;
4150 int ret = 0;
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004151
4152 if (!wpa_s->conf->wowlan_triggers)
4153 return 0;
4154
Dmitry Shmidt0207e232014-09-03 14:58:37 -07004155 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
4156 if (triggers) {
4157 ret = wpa_drv_wowlan(wpa_s, triggers);
4158 os_free(triggers);
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004159 }
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004160 return ret;
4161}
4162
4163
Dmitry Shmidt9c175262016-03-03 10:20:07 -08004164enum wpa_radio_work_band wpas_freq_to_band(int freq)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004165{
4166 if (freq < 3000)
4167 return BAND_2_4_GHZ;
4168 if (freq > 50000)
4169 return BAND_60_GHZ;
4170 return BAND_5_GHZ;
4171}
4172
4173
Dmitry Shmidt9c175262016-03-03 10:20:07 -08004174unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004175{
4176 int i;
4177 unsigned int band = 0;
4178
4179 if (freqs) {
4180 /* freqs are specified for the radio work */
4181 for (i = 0; freqs[i]; i++)
4182 band |= wpas_freq_to_band(freqs[i]);
4183 } else {
4184 /*
4185 * freqs are not specified, implies all
4186 * the supported freqs by HW
4187 */
4188 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4189 if (wpa_s->hw.modes[i].num_channels != 0) {
4190 if (wpa_s->hw.modes[i].mode ==
4191 HOSTAPD_MODE_IEEE80211B ||
4192 wpa_s->hw.modes[i].mode ==
4193 HOSTAPD_MODE_IEEE80211G)
4194 band |= BAND_2_4_GHZ;
4195 else if (wpa_s->hw.modes[i].mode ==
4196 HOSTAPD_MODE_IEEE80211A)
4197 band |= BAND_5_GHZ;
4198 else if (wpa_s->hw.modes[i].mode ==
4199 HOSTAPD_MODE_IEEE80211AD)
4200 band |= BAND_60_GHZ;
4201 else if (wpa_s->hw.modes[i].mode ==
4202 HOSTAPD_MODE_IEEE80211ANY)
4203 band = BAND_2_4_GHZ | BAND_5_GHZ |
4204 BAND_60_GHZ;
4205 }
4206 }
4207 }
4208
4209 return band;
4210}
4211
4212
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004213static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
4214 const char *rn)
4215{
4216 struct wpa_supplicant *iface = wpa_s->global->ifaces;
4217 struct wpa_radio *radio;
4218
4219 while (rn && iface) {
4220 radio = iface->radio;
4221 if (radio && os_strcmp(rn, radio->name) == 0) {
4222 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
4223 wpa_s->ifname, rn);
4224 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4225 return radio;
4226 }
Dmitry Shmidt3cf6f792013-12-18 13:12:19 -08004227
4228 iface = iface->next;
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004229 }
4230
4231 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
4232 wpa_s->ifname, rn ? rn : "N/A");
4233 radio = os_zalloc(sizeof(*radio));
4234 if (radio == NULL)
4235 return NULL;
4236
4237 if (rn)
4238 os_strlcpy(radio->name, rn, sizeof(radio->name));
4239 dl_list_init(&radio->ifaces);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004240 dl_list_init(&radio->work);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004241 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4242
4243 return radio;
4244}
4245
4246
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004247static void radio_work_free(struct wpa_radio_work *work)
4248{
4249 if (work->wpa_s->scan_work == work) {
4250 /* This should not really happen. */
4251 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
4252 work->type, work, work->started);
4253 work->wpa_s->scan_work = NULL;
4254 }
4255
4256#ifdef CONFIG_P2P
4257 if (work->wpa_s->p2p_scan_work == work) {
4258 /* This should not really happen. */
4259 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
4260 work->type, work, work->started);
4261 work->wpa_s->p2p_scan_work = NULL;
4262 }
4263#endif /* CONFIG_P2P */
4264
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004265 if (work->started) {
4266 work->wpa_s->radio->num_active_works--;
4267 wpa_dbg(work->wpa_s, MSG_DEBUG,
4268 "radio_work_free('%s'@%p: num_active_works --> %u",
4269 work->type, work,
4270 work->wpa_s->radio->num_active_works);
4271 }
4272
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004273 dl_list_del(&work->list);
4274 os_free(work);
4275}
4276
4277
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004278static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
4279{
4280 struct wpa_radio_work *active_work = NULL;
4281 struct wpa_radio_work *tmp;
4282
4283 /* Get the active work to know the type and band. */
4284 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4285 if (tmp->started) {
4286 active_work = tmp;
4287 break;
4288 }
4289 }
4290
4291 if (!active_work) {
4292 /* No active work, start one */
4293 radio->num_active_works = 0;
4294 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
4295 list) {
4296 if (os_strcmp(tmp->type, "scan") == 0 &&
4297 radio->external_scan_running &&
4298 (((struct wpa_driver_scan_params *)
4299 tmp->ctx)->only_new_results ||
4300 tmp->wpa_s->clear_driver_scan_cache))
4301 continue;
4302 return tmp;
4303 }
4304 return NULL;
4305 }
4306
4307 if (os_strcmp(active_work->type, "sme-connect") == 0 ||
4308 os_strcmp(active_work->type, "connect") == 0) {
4309 /*
4310 * If the active work is either connect or sme-connect,
4311 * do not parallelize them with other radio works.
4312 */
4313 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4314 "Do not parallelize radio work with %s",
4315 active_work->type);
4316 return NULL;
4317 }
4318
4319 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4320 if (tmp->started)
4321 continue;
4322
4323 /*
4324 * If connect or sme-connect are enqueued, parallelize only
4325 * those operations ahead of them in the queue.
4326 */
4327 if (os_strcmp(tmp->type, "connect") == 0 ||
4328 os_strcmp(tmp->type, "sme-connect") == 0)
4329 break;
4330
4331 /*
4332 * Check that the radio works are distinct and
4333 * on different bands.
4334 */
4335 if (os_strcmp(active_work->type, tmp->type) != 0 &&
4336 (active_work->bands != tmp->bands)) {
4337 /*
4338 * If a scan has to be scheduled through nl80211 scan
4339 * interface and if an external scan is already running,
4340 * do not schedule the scan since it is likely to get
4341 * rejected by kernel.
4342 */
4343 if (os_strcmp(tmp->type, "scan") == 0 &&
4344 radio->external_scan_running &&
4345 (((struct wpa_driver_scan_params *)
4346 tmp->ctx)->only_new_results ||
4347 tmp->wpa_s->clear_driver_scan_cache))
4348 continue;
4349
4350 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4351 "active_work:%s new_work:%s",
4352 active_work->type, tmp->type);
4353 return tmp;
4354 }
4355 }
4356
4357 /* Did not find a radio work to schedule in parallel. */
4358 return NULL;
4359}
4360
4361
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004362static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
4363{
4364 struct wpa_radio *radio = eloop_ctx;
4365 struct wpa_radio_work *work;
4366 struct os_reltime now, diff;
4367 struct wpa_supplicant *wpa_s;
4368
4369 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004370 if (work == NULL) {
4371 radio->num_active_works = 0;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004372 return;
4373 }
4374
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004375 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
4376 radio_list);
4377
4378 if (!(wpa_s &&
4379 wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
4380 if (work->started)
4381 return; /* already started and still in progress */
4382
4383 if (wpa_s && wpa_s->radio->external_scan_running) {
4384 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
4385 return;
4386 }
4387 } else {
4388 work = NULL;
4389 if (radio->num_active_works < MAX_ACTIVE_WORKS) {
4390 /* get the work to schedule next */
4391 work = radio_work_get_next_work(radio);
4392 }
4393 if (!work)
4394 return;
4395 }
4396
4397 wpa_s = work->wpa_s;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004398 os_get_reltime(&now);
4399 os_reltime_sub(&now, &work->time, &diff);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004400 wpa_dbg(wpa_s, MSG_DEBUG,
4401 "Starting radio work '%s'@%p after %ld.%06ld second wait",
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004402 work->type, work, diff.sec, diff.usec);
4403 work->started = 1;
4404 work->time = now;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004405 radio->num_active_works++;
4406
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004407 work->cb(work, 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004408
4409 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
4410 radio->num_active_works < MAX_ACTIVE_WORKS)
4411 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004412}
4413
4414
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004415/*
4416 * This function removes both started and pending radio works running on
4417 * the provided interface's radio.
4418 * Prior to the removal of the radio work, its callback (cb) is called with
4419 * deinit set to be 1. Each work's callback is responsible for clearing its
4420 * internal data and restoring to a correct state.
4421 * @wpa_s: wpa_supplicant data
4422 * @type: type of works to be removed
4423 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
4424 * this interface's works.
4425 */
4426void radio_remove_works(struct wpa_supplicant *wpa_s,
4427 const char *type, int remove_all)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004428{
4429 struct wpa_radio_work *work, *tmp;
4430 struct wpa_radio *radio = wpa_s->radio;
4431
4432 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
4433 list) {
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004434 if (type && os_strcmp(type, work->type) != 0)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004435 continue;
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004436
4437 /* skip other ifaces' works */
4438 if (!remove_all && work->wpa_s != wpa_s)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004439 continue;
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004440
4441 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
4442 work->type, work, work->started ? " (started)" : "");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004443 work->cb(work, 1);
4444 radio_work_free(work);
4445 }
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004446
4447 /* in case we removed the started work */
4448 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004449}
4450
4451
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004452static void radio_remove_interface(struct wpa_supplicant *wpa_s)
4453{
4454 struct wpa_radio *radio = wpa_s->radio;
4455
4456 if (!radio)
4457 return;
4458
4459 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
4460 wpa_s->ifname, radio->name);
4461 dl_list_del(&wpa_s->radio_list);
Dmitry Shmidtd11f0192014-03-24 12:09:47 -07004462 radio_remove_works(wpa_s, NULL, 0);
4463 wpa_s->radio = NULL;
4464 if (!dl_list_empty(&radio->ifaces))
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004465 return; /* Interfaces remain for this radio */
4466
4467 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004468 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004469 os_free(radio);
4470}
4471
4472
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004473void radio_work_check_next(struct wpa_supplicant *wpa_s)
4474{
4475 struct wpa_radio *radio = wpa_s->radio;
4476
4477 if (dl_list_empty(&radio->work))
4478 return;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004479 if (wpa_s->ext_work_in_progress) {
4480 wpa_printf(MSG_DEBUG,
4481 "External radio work in progress - delay start of pending item");
4482 return;
4483 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004484 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4485 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
4486}
4487
4488
4489/**
4490 * radio_add_work - Add a radio work item
4491 * @wpa_s: Pointer to wpa_supplicant data
4492 * @freq: Frequency of the offchannel operation in MHz or 0
4493 * @type: Unique identifier for each type of work
4494 * @next: Force as the next work to be executed
4495 * @cb: Callback function for indicating when radio is available
4496 * @ctx: Context pointer for the work (work->ctx in cb())
4497 * Returns: 0 on success, -1 on failure
4498 *
4499 * This function is used to request time for an operation that requires
4500 * exclusive radio control. Once the radio is available, the registered callback
4501 * function will be called. radio_work_done() must be called once the exclusive
4502 * radio operation has been completed, so that the radio is freed for other
4503 * operations. The special case of deinit=1 is used to free the context data
4504 * during interface removal. That does not allow the callback function to start
4505 * the radio operation, i.e., it must free any resources allocated for the radio
4506 * work and return.
4507 *
4508 * The @freq parameter can be used to indicate a single channel on which the
4509 * offchannel operation will occur. This may allow multiple radio work
4510 * operations to be performed in parallel if they apply for the same channel.
4511 * Setting this to 0 indicates that the work item may use multiple channels or
4512 * requires exclusive control of the radio.
4513 */
4514int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
4515 const char *type, int next,
4516 void (*cb)(struct wpa_radio_work *work, int deinit),
4517 void *ctx)
4518{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004519 struct wpa_radio *radio = wpa_s->radio;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004520 struct wpa_radio_work *work;
4521 int was_empty;
4522
4523 work = os_zalloc(sizeof(*work));
4524 if (work == NULL)
4525 return -1;
4526 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
4527 os_get_reltime(&work->time);
4528 work->freq = freq;
4529 work->type = type;
4530 work->wpa_s = wpa_s;
4531 work->cb = cb;
4532 work->ctx = ctx;
4533
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004534 if (freq)
4535 work->bands = wpas_freq_to_band(freq);
4536 else if (os_strcmp(type, "scan") == 0 ||
4537 os_strcmp(type, "p2p-scan") == 0)
4538 work->bands = wpas_get_bands(wpa_s,
4539 ((struct wpa_driver_scan_params *)
4540 ctx)->freqs);
4541 else
4542 work->bands = wpas_get_bands(wpa_s, NULL);
4543
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004544 was_empty = dl_list_empty(&wpa_s->radio->work);
4545 if (next)
4546 dl_list_add(&wpa_s->radio->work, &work->list);
4547 else
4548 dl_list_add_tail(&wpa_s->radio->work, &work->list);
4549 if (was_empty) {
4550 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
4551 radio_work_check_next(wpa_s);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004552 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
4553 && radio->num_active_works < MAX_ACTIVE_WORKS) {
4554 wpa_dbg(wpa_s, MSG_DEBUG,
4555 "Try to schedule a radio work (num_active_works=%u)",
4556 radio->num_active_works);
4557 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004558 }
4559
4560 return 0;
4561}
4562
4563
4564/**
4565 * radio_work_done - Indicate that a radio work item has been completed
4566 * @work: Completed work
4567 *
4568 * This function is called once the callback function registered with
4569 * radio_add_work() has completed its work.
4570 */
4571void radio_work_done(struct wpa_radio_work *work)
4572{
4573 struct wpa_supplicant *wpa_s = work->wpa_s;
4574 struct os_reltime now, diff;
4575 unsigned int started = work->started;
4576
4577 os_get_reltime(&now);
4578 os_reltime_sub(&now, &work->time, &diff);
4579 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
4580 work->type, work, started ? "done" : "canceled",
4581 diff.sec, diff.usec);
4582 radio_work_free(work);
4583 if (started)
4584 radio_work_check_next(wpa_s);
4585}
4586
4587
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004588struct wpa_radio_work *
4589radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004590{
4591 struct wpa_radio_work *work;
4592 struct wpa_radio *radio = wpa_s->radio;
4593
4594 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
4595 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004596 return work;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004597 }
4598
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004599 return NULL;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004600}
4601
4602
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004603static int wpas_init_driver(struct wpa_supplicant *wpa_s,
4604 struct wpa_interface *iface)
4605{
4606 const char *ifname, *driver, *rn;
4607
4608 driver = iface->driver;
4609next_driver:
4610 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
4611 return -1;
4612
4613 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
4614 if (wpa_s->drv_priv == NULL) {
4615 const char *pos;
4616 pos = driver ? os_strchr(driver, ',') : NULL;
4617 if (pos) {
4618 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
4619 "driver interface - try next driver wrapper");
4620 driver = pos + 1;
4621 goto next_driver;
4622 }
4623 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
4624 "interface");
4625 return -1;
4626 }
4627 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
4628 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
4629 "driver_param '%s'", wpa_s->conf->driver_param);
4630 return -1;
4631 }
4632
4633 ifname = wpa_drv_get_ifname(wpa_s);
4634 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
4635 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
4636 "interface name with '%s'", ifname);
4637 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
4638 }
4639
Dmitry Shmidtd11f0192014-03-24 12:09:47 -07004640 rn = wpa_driver_get_radio_name(wpa_s);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004641 if (rn && rn[0] == '\0')
4642 rn = NULL;
4643
4644 wpa_s->radio = radio_add_interface(wpa_s, rn);
4645 if (wpa_s->radio == NULL)
4646 return -1;
4647
4648 return 0;
4649}
4650
4651
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004652static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
4653 struct wpa_interface *iface)
4654{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004655 struct wpa_driver_capa capa;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004656 int capa_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004657
4658 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
4659 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
4660 iface->confname ? iface->confname : "N/A",
4661 iface->driver ? iface->driver : "default",
4662 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
4663 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
4664
4665 if (iface->confname) {
4666#ifdef CONFIG_BACKEND_FILE
4667 wpa_s->confname = os_rel2abs_path(iface->confname);
4668 if (wpa_s->confname == NULL) {
4669 wpa_printf(MSG_ERROR, "Failed to get absolute path "
4670 "for configuration file '%s'.",
4671 iface->confname);
4672 return -1;
4673 }
4674 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
4675 iface->confname, wpa_s->confname);
4676#else /* CONFIG_BACKEND_FILE */
4677 wpa_s->confname = os_strdup(iface->confname);
4678#endif /* CONFIG_BACKEND_FILE */
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07004679 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004680 if (wpa_s->conf == NULL) {
4681 wpa_printf(MSG_ERROR, "Failed to read or parse "
4682 "configuration '%s'.", wpa_s->confname);
4683 return -1;
4684 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07004685 wpa_s->confanother = os_rel2abs_path(iface->confanother);
4686 wpa_config_read(wpa_s->confanother, wpa_s->conf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004687
4688 /*
4689 * Override ctrl_interface and driver_param if set on command
4690 * line.
4691 */
4692 if (iface->ctrl_interface) {
4693 os_free(wpa_s->conf->ctrl_interface);
4694 wpa_s->conf->ctrl_interface =
4695 os_strdup(iface->ctrl_interface);
4696 }
4697
4698 if (iface->driver_param) {
4699 os_free(wpa_s->conf->driver_param);
4700 wpa_s->conf->driver_param =
4701 os_strdup(iface->driver_param);
4702 }
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004703
4704 if (iface->p2p_mgmt && !iface->ctrl_interface) {
4705 os_free(wpa_s->conf->ctrl_interface);
4706 wpa_s->conf->ctrl_interface = NULL;
4707 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004708 } else
4709 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4710 iface->driver_param);
4711
4712 if (wpa_s->conf == NULL) {
4713 wpa_printf(MSG_ERROR, "\nNo configuration found.");
4714 return -1;
4715 }
4716
4717 if (iface->ifname == NULL) {
4718 wpa_printf(MSG_ERROR, "\nInterface name is required.");
4719 return -1;
4720 }
4721 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4722 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4723 iface->ifname);
4724 return -1;
4725 }
4726 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4727
4728 if (iface->bridge_ifname) {
4729 if (os_strlen(iface->bridge_ifname) >=
4730 sizeof(wpa_s->bridge_ifname)) {
4731 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4732 "name '%s'.", iface->bridge_ifname);
4733 return -1;
4734 }
4735 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4736 sizeof(wpa_s->bridge_ifname));
4737 }
4738
4739 /* RSNA Supplicant Key Management - INITIALIZE */
4740 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4741 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4742
4743 /* Initialize driver interface and register driver event handler before
4744 * L2 receive handler so that association events are processed before
4745 * EAPOL-Key packets if both become available for the same select()
4746 * call. */
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004747 if (wpas_init_driver(wpa_s, iface) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004748 return -1;
4749
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004750 if (wpa_supplicant_init_wpa(wpa_s) < 0)
4751 return -1;
4752
4753 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4754 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4755 NULL);
4756 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4757
4758 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4759 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4760 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
4761 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4762 "dot11RSNAConfigPMKLifetime");
4763 return -1;
4764 }
4765
4766 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4767 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4768 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
4769 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4770 "dot11RSNAConfigPMKReauthThreshold");
4771 return -1;
4772 }
4773
4774 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4775 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4776 wpa_s->conf->dot11RSNAConfigSATimeout)) {
4777 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4778 "dot11RSNAConfigSATimeout");
4779 return -1;
4780 }
4781
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004782 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4783 &wpa_s->hw.num_modes,
4784 &wpa_s->hw.flags);
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004785 if (wpa_s->hw.modes) {
4786 u16 i;
4787
4788 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4789 if (wpa_s->hw.modes[i].vht_capab) {
4790 wpa_s->hw_capab = CAPAB_VHT;
4791 break;
4792 }
4793
4794 if (wpa_s->hw.modes[i].ht_capab &
4795 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4796 wpa_s->hw_capab = CAPAB_HT40;
4797 else if (wpa_s->hw.modes[i].ht_capab &&
4798 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4799 wpa_s->hw_capab = CAPAB_HT;
4800 }
4801 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004802
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004803 capa_res = wpa_drv_get_capa(wpa_s, &capa);
4804 if (capa_res == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004805 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004806 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07004807 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004808 wpa_s->drv_smps_modes = capa.smps_modes;
4809 wpa_s->drv_rrm_flags = capa.rrm_flags;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004810 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004811 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004812 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004813 wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
4814 wpa_s->max_sched_scan_plan_interval =
4815 capa.max_sched_scan_plan_interval;
4816 wpa_s->max_sched_scan_plan_iterations =
4817 capa.max_sched_scan_plan_iterations;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004818 wpa_s->sched_scan_supported = capa.sched_scan_supported;
4819 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004820 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
4821 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07004822 wpa_s->extended_capa = capa.extended_capa;
4823 wpa_s->extended_capa_mask = capa.extended_capa_mask;
4824 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07004825 wpa_s->num_multichan_concurrent =
4826 capa.num_multichan_concurrent;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004827 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
4828
4829 if (capa.mac_addr_rand_scan_supported)
4830 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4831 if (wpa_s->sched_scan_supported &&
4832 capa.mac_addr_rand_sched_scan_supported)
4833 wpa_s->mac_addr_rand_supported |=
4834 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004835 }
4836 if (wpa_s->max_remain_on_chan == 0)
4837 wpa_s->max_remain_on_chan = 1000;
4838
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004839 /*
4840 * Only take p2p_mgmt parameters when P2P Device is supported.
4841 * Doing it here as it determines whether l2_packet_init() will be done
4842 * during wpa_supplicant_driver_init().
4843 */
4844 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4845 wpa_s->p2p_mgmt = iface->p2p_mgmt;
4846 else
4847 iface->p2p_mgmt = 1;
4848
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07004849 if (wpa_s->num_multichan_concurrent == 0)
4850 wpa_s->num_multichan_concurrent = 1;
4851
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004852 if (wpa_supplicant_driver_init(wpa_s) < 0)
4853 return -1;
4854
4855#ifdef CONFIG_TDLS
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004856 if ((!iface->p2p_mgmt ||
4857 !(wpa_s->drv_flags &
4858 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4859 wpa_tdls_init(wpa_s->wpa))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004860 return -1;
4861#endif /* CONFIG_TDLS */
4862
4863 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4864 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
4865 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
4866 return -1;
4867 }
4868
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004869#ifdef CONFIG_FST
4870 if (wpa_s->conf->fst_group_id) {
4871 struct fst_iface_cfg cfg;
4872 struct fst_wpa_obj iface_obj;
4873
4874 fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
4875 os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
4876 sizeof(cfg.group_id));
4877 cfg.priority = wpa_s->conf->fst_priority;
4878 cfg.llt = wpa_s->conf->fst_llt;
4879
4880 wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
4881 &iface_obj, &cfg);
4882 if (!wpa_s->fst) {
4883 wpa_msg(wpa_s, MSG_ERROR,
4884 "FST: Cannot attach iface %s to group %s",
4885 wpa_s->ifname, cfg.group_id);
4886 return -1;
4887 }
4888 }
4889#endif /* CONFIG_FST */
4890
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004891 if (wpas_wps_init(wpa_s))
4892 return -1;
4893
4894 if (wpa_supplicant_init_eapol(wpa_s) < 0)
4895 return -1;
4896 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4897
4898 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4899 if (wpa_s->ctrl_iface == NULL) {
4900 wpa_printf(MSG_ERROR,
4901 "Failed to initialize control interface '%s'.\n"
4902 "You may have another wpa_supplicant process "
4903 "already running or the file was\n"
4904 "left by an unclean termination of wpa_supplicant "
4905 "in which case you will need\n"
4906 "to manually remove this file before starting "
4907 "wpa_supplicant again.\n",
4908 wpa_s->conf->ctrl_interface);
4909 return -1;
4910 }
4911
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004912 wpa_s->gas = gas_query_init(wpa_s);
4913 if (wpa_s->gas == NULL) {
4914 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4915 return -1;
4916 }
4917
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004918 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004919 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
4920 return -1;
4921 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004922
4923 if (wpa_bss_init(wpa_s) < 0)
4924 return -1;
4925
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004926 /*
4927 * Set Wake-on-WLAN triggers, if configured.
4928 * Note: We don't restore/remove the triggers on shutdown (it doesn't
4929 * have effect anyway when the interface is down).
4930 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004931 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004932 return -1;
4933
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004934#ifdef CONFIG_EAP_PROXY
4935{
4936 size_t len;
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07004937 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4938 &len);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004939 if (wpa_s->mnc_len > 0) {
4940 wpa_s->imsi[len] = '\0';
4941 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4942 wpa_s->imsi, wpa_s->mnc_len);
4943 } else {
4944 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4945 }
4946}
4947#endif /* CONFIG_EAP_PROXY */
4948
Dmitry Shmidt04949592012-07-19 12:16:46 -07004949 if (pcsc_reader_init(wpa_s) < 0)
4950 return -1;
4951
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004952 if (wpas_init_ext_pw(wpa_s) < 0)
4953 return -1;
4954
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004955 wpas_rrm_reset(wpa_s);
4956
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004957 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
4958
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08004959#ifdef CONFIG_HS20
4960 hs20_init(wpa_s);
4961#endif /* CONFIG_HS20 */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004962#ifdef CONFIG_MBO
4963 wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
4964#endif /* CONFIG_MBO */
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08004965
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -07004966 wpa_supplicant_set_default_scan_ies(wpa_s);
4967
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004968 return 0;
4969}
4970
4971
4972static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004973 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004974{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004975 struct wpa_global *global = wpa_s->global;
4976 struct wpa_supplicant *iface, *prev;
4977
4978 if (wpa_s == wpa_s->parent)
4979 wpas_p2p_group_remove(wpa_s, "*");
4980
4981 iface = global->ifaces;
4982 while (iface) {
Dmitry Shmidt9c175262016-03-03 10:20:07 -08004983 if (iface->p2pdev == wpa_s)
4984 iface->p2pdev = iface->parent;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004985 if (iface == wpa_s || iface->parent != wpa_s) {
4986 iface = iface->next;
4987 continue;
4988 }
4989 wpa_printf(MSG_DEBUG,
4990 "Remove remaining child interface %s from parent %s",
4991 iface->ifname, wpa_s->ifname);
4992 prev = iface;
4993 iface = iface->next;
4994 wpa_supplicant_remove_iface(global, prev, terminate);
4995 }
4996
Dmitry Shmidtea69e842013-05-13 14:52:28 -07004997 wpa_s->disconnected = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004998 if (wpa_s->drv_priv) {
4999 wpa_supplicant_deauthenticate(wpa_s,
5000 WLAN_REASON_DEAUTH_LEAVING);
5001
5002 wpa_drv_set_countermeasures(wpa_s, 0);
5003 wpa_clear_keys(wpa_s, NULL);
5004 }
5005
5006 wpa_supplicant_cleanup(wpa_s);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005007 wpas_p2p_deinit_iface(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005008
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005009 wpas_ctrl_radio_work_flush(wpa_s);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08005010 radio_remove_interface(wpa_s);
5011
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005012#ifdef CONFIG_FST
5013 if (wpa_s->fst) {
5014 fst_detach(wpa_s->fst);
5015 wpa_s->fst = NULL;
5016 }
5017 if (wpa_s->received_mb_ies) {
5018 wpabuf_free(wpa_s->received_mb_ies);
5019 wpa_s->received_mb_ies = NULL;
5020 }
5021#endif /* CONFIG_FST */
5022
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005023 if (wpa_s->drv_priv)
5024 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07005025
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005026 if (notify)
5027 wpas_notify_iface_removed(wpa_s);
5028
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005029 if (terminate)
5030 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07005031
5032 if (wpa_s->ctrl_iface) {
5033 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
5034 wpa_s->ctrl_iface = NULL;
5035 }
5036
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005037#ifdef CONFIG_MESH
5038 if (wpa_s->ifmsh) {
5039 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
5040 wpa_s->ifmsh = NULL;
5041 }
5042#endif /* CONFIG_MESH */
5043
Irfan Sheriff622b66d2011-08-03 09:11:49 -07005044 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07005045 wpa_config_free(wpa_s->conf);
5046 wpa_s->conf = NULL;
5047 }
Dmitry Shmidt8da800a2013-04-24 12:57:01 -07005048
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -07005049 os_free(wpa_s->ssids_from_scan_req);
5050
Dmitry Shmidt8da800a2013-04-24 12:57:01 -07005051 os_free(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005052}
5053
5054
Dmitry Shmidte4663042016-04-04 10:07:49 -07005055#ifdef CONFIG_MATCH_IFACE
5056
5057/**
5058 * wpa_supplicant_match_iface - Match an interface description to a name
5059 * @global: Pointer to global data from wpa_supplicant_init()
5060 * @ifname: Name of the interface to match
5061 * Returns: Pointer to the created interface description or %NULL on failure
5062 */
5063struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
5064 const char *ifname)
5065{
5066 int i;
5067 struct wpa_interface *iface, *miface;
5068
5069 for (i = 0; i < global->params.match_iface_count; i++) {
5070 miface = &global->params.match_ifaces[i];
5071 if (!miface->ifname ||
5072 fnmatch(miface->ifname, ifname, 0) == 0) {
5073 iface = os_zalloc(sizeof(*iface));
5074 if (!iface)
5075 return NULL;
5076 *iface = *miface;
5077 iface->ifname = ifname;
5078 return iface;
5079 }
5080 }
5081
5082 return NULL;
5083}
5084
5085
5086/**
5087 * wpa_supplicant_match_existing - Match existing interfaces
5088 * @global: Pointer to global data from wpa_supplicant_init()
5089 * Returns: 0 on success, -1 on failure
5090 */
5091static int wpa_supplicant_match_existing(struct wpa_global *global)
5092{
5093 struct if_nameindex *ifi, *ifp;
5094 struct wpa_supplicant *wpa_s;
5095 struct wpa_interface *iface;
5096
5097 ifp = if_nameindex();
5098 if (!ifp) {
5099 wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
5100 return -1;
5101 }
5102
5103 for (ifi = ifp; ifi->if_name; ifi++) {
5104 wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
5105 if (wpa_s)
5106 continue;
5107 iface = wpa_supplicant_match_iface(global, ifi->if_name);
5108 if (iface) {
5109 wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
5110 os_free(iface);
5111 if (wpa_s)
5112 wpa_s->matched = 1;
5113 }
5114 }
5115
5116 if_freenameindex(ifp);
5117 return 0;
5118}
5119
5120#endif /* CONFIG_MATCH_IFACE */
5121
5122
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005123/**
5124 * wpa_supplicant_add_iface - Add a new network interface
5125 * @global: Pointer to global data from wpa_supplicant_init()
5126 * @iface: Interface configuration options
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005127 * @parent: Parent interface or %NULL to assign new interface as parent
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005128 * Returns: Pointer to the created interface or %NULL on failure
5129 *
5130 * This function is used to add new network interfaces for %wpa_supplicant.
5131 * This can be called before wpa_supplicant_run() to add interfaces before the
5132 * main event loop has been started. In addition, new interfaces can be added
5133 * dynamically while %wpa_supplicant is already running. This could happen,
5134 * e.g., when a hotplug network adapter is inserted.
5135 */
5136struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005137 struct wpa_interface *iface,
5138 struct wpa_supplicant *parent)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005139{
5140 struct wpa_supplicant *wpa_s;
5141 struct wpa_interface t_iface;
5142 struct wpa_ssid *ssid;
5143
5144 if (global == NULL || iface == NULL)
5145 return NULL;
5146
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005147 wpa_s = wpa_supplicant_alloc(parent);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005148 if (wpa_s == NULL)
5149 return NULL;
5150
5151 wpa_s->global = global;
5152
5153 t_iface = *iface;
5154 if (global->params.override_driver) {
5155 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
5156 "('%s' -> '%s')",
5157 iface->driver, global->params.override_driver);
5158 t_iface.driver = global->params.override_driver;
5159 }
5160 if (global->params.override_ctrl_interface) {
5161 wpa_printf(MSG_DEBUG, "Override interface parameter: "
5162 "ctrl_interface ('%s' -> '%s')",
5163 iface->ctrl_interface,
5164 global->params.override_ctrl_interface);
5165 t_iface.ctrl_interface =
5166 global->params.override_ctrl_interface;
5167 }
5168 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
5169 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
5170 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005171 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005172 return NULL;
5173 }
5174
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005175 if (iface->p2p_mgmt == 0) {
5176 /* Notify the control interfaces about new iface */
5177 if (wpas_notify_iface_added(wpa_s)) {
5178 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
5179 return NULL;
5180 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005181
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005182 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
5183 wpas_notify_network_added(wpa_s, ssid);
5184 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005185
5186 wpa_s->next = global->ifaces;
5187 global->ifaces = wpa_s;
5188
5189 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005190 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005191
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005192#ifdef CONFIG_P2P
5193 if (wpa_s->global->p2p == NULL &&
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07005194 !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005195 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
Dmitry Shmidta3dc3092015-06-23 11:21:28 -07005196 wpas_p2p_add_p2pdev_interface(
5197 wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005198 wpa_printf(MSG_INFO,
5199 "P2P: Failed to enable P2P Device interface");
5200 /* Try to continue without. P2P will be disabled. */
5201 }
5202#endif /* CONFIG_P2P */
5203
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005204 return wpa_s;
5205}
5206
5207
5208/**
5209 * wpa_supplicant_remove_iface - Remove a network interface
5210 * @global: Pointer to global data from wpa_supplicant_init()
5211 * @wpa_s: Pointer to the network interface to be removed
5212 * Returns: 0 if interface was removed, -1 if interface was not found
5213 *
5214 * This function can be used to dynamically remove network interfaces from
5215 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
5216 * addition, this function is used to remove all remaining interfaces when
5217 * %wpa_supplicant is terminated.
5218 */
5219int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005220 struct wpa_supplicant *wpa_s,
5221 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005222{
5223 struct wpa_supplicant *prev;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005224#ifdef CONFIG_MESH
5225 unsigned int mesh_if_created = wpa_s->mesh_if_created;
5226 char *ifname = NULL;
5227#endif /* CONFIG_MESH */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005228
5229 /* Remove interface from the global list of interfaces */
5230 prev = global->ifaces;
5231 if (prev == wpa_s) {
5232 global->ifaces = wpa_s->next;
5233 } else {
5234 while (prev && prev->next != wpa_s)
5235 prev = prev->next;
5236 if (prev == NULL)
5237 return -1;
5238 prev->next = wpa_s->next;
5239 }
5240
5241 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
5242
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005243#ifdef CONFIG_MESH
5244 if (mesh_if_created) {
5245 ifname = os_strdup(wpa_s->ifname);
5246 if (ifname == NULL) {
5247 wpa_dbg(wpa_s, MSG_ERROR,
5248 "mesh: Failed to malloc ifname");
5249 return -1;
5250 }
5251 }
5252#endif /* CONFIG_MESH */
5253
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005254 if (global->p2p_group_formation == wpa_s)
5255 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07005256 if (global->p2p_invite_group == wpa_s)
5257 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005258 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005259
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005260#ifdef CONFIG_MESH
5261 if (mesh_if_created) {
5262 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
5263 os_free(ifname);
5264 }
5265#endif /* CONFIG_MESH */
5266
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005267 return 0;
5268}
5269
5270
5271/**
5272 * wpa_supplicant_get_eap_mode - Get the current EAP mode
5273 * @wpa_s: Pointer to the network interface
5274 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
5275 */
5276const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
5277{
5278 const char *eapol_method;
5279
5280 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
5281 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
5282 return "NO-EAP";
5283 }
5284
5285 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
5286 if (eapol_method == NULL)
5287 return "UNKNOWN-EAP";
5288
5289 return eapol_method;
5290}
5291
5292
5293/**
5294 * wpa_supplicant_get_iface - Get a new network interface
5295 * @global: Pointer to global data from wpa_supplicant_init()
5296 * @ifname: Interface name
5297 * Returns: Pointer to the interface or %NULL if not found
5298 */
5299struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
5300 const char *ifname)
5301{
5302 struct wpa_supplicant *wpa_s;
5303
5304 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5305 if (os_strcmp(wpa_s->ifname, ifname) == 0)
5306 return wpa_s;
5307 }
5308 return NULL;
5309}
5310
5311
5312#ifndef CONFIG_NO_WPA_MSG
5313static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
5314{
5315 struct wpa_supplicant *wpa_s = ctx;
5316 if (wpa_s == NULL)
5317 return NULL;
5318 return wpa_s->ifname;
5319}
5320#endif /* CONFIG_NO_WPA_MSG */
5321
5322
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005323#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
5324#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
5325#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
5326
5327/* Periodic cleanup tasks */
5328static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
5329{
5330 struct wpa_global *global = eloop_ctx;
5331 struct wpa_supplicant *wpa_s;
5332
5333 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5334 wpas_periodic, global, NULL);
5335
5336#ifdef CONFIG_P2P
5337 if (global->p2p)
5338 p2p_expire_peers(global->p2p);
5339#endif /* CONFIG_P2P */
5340
5341 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5342 wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
5343#ifdef CONFIG_AP
5344 ap_periodic(wpa_s);
5345#endif /* CONFIG_AP */
5346 }
5347}
5348
5349
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005350/**
5351 * wpa_supplicant_init - Initialize %wpa_supplicant
5352 * @params: Parameters for %wpa_supplicant
5353 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
5354 *
5355 * This function is used to initialize %wpa_supplicant. After successful
5356 * initialization, the returned data pointer can be used to add and remove
5357 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
5358 */
5359struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
5360{
5361 struct wpa_global *global;
5362 int ret, i;
5363
5364 if (params == NULL)
5365 return NULL;
5366
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005367#ifdef CONFIG_DRIVER_NDIS
5368 {
5369 void driver_ndis_init_ops(void);
5370 driver_ndis_init_ops();
5371 }
5372#endif /* CONFIG_DRIVER_NDIS */
5373
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005374#ifndef CONFIG_NO_WPA_MSG
5375 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
5376#endif /* CONFIG_NO_WPA_MSG */
5377
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005378 if (params->wpa_debug_file_path)
5379 wpa_debug_open_file(params->wpa_debug_file_path);
5380 else
5381 wpa_debug_setup_stdout();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005382 if (params->wpa_debug_syslog)
5383 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07005384 if (params->wpa_debug_tracing) {
5385 ret = wpa_debug_open_linux_tracing();
5386 if (ret) {
5387 wpa_printf(MSG_ERROR,
5388 "Failed to enable trace logging");
5389 return NULL;
5390 }
5391 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005392
5393 ret = eap_register_methods();
5394 if (ret) {
5395 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
5396 if (ret == -2)
5397 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
5398 "the same EAP type.");
5399 return NULL;
5400 }
5401
5402 global = os_zalloc(sizeof(*global));
5403 if (global == NULL)
5404 return NULL;
5405 dl_list_init(&global->p2p_srv_bonjour);
5406 dl_list_init(&global->p2p_srv_upnp);
5407 global->params.daemonize = params->daemonize;
5408 global->params.wait_for_monitor = params->wait_for_monitor;
5409 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
5410 if (params->pid_file)
5411 global->params.pid_file = os_strdup(params->pid_file);
5412 if (params->ctrl_interface)
5413 global->params.ctrl_interface =
5414 os_strdup(params->ctrl_interface);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -07005415 if (params->ctrl_interface_group)
5416 global->params.ctrl_interface_group =
5417 os_strdup(params->ctrl_interface_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005418 if (params->override_driver)
5419 global->params.override_driver =
5420 os_strdup(params->override_driver);
5421 if (params->override_ctrl_interface)
5422 global->params.override_ctrl_interface =
5423 os_strdup(params->override_ctrl_interface);
Dmitry Shmidte4663042016-04-04 10:07:49 -07005424#ifdef CONFIG_MATCH_IFACE
5425 global->params.match_iface_count = params->match_iface_count;
5426 if (params->match_iface_count) {
5427 global->params.match_ifaces =
5428 os_calloc(params->match_iface_count,
5429 sizeof(struct wpa_interface));
5430 os_memcpy(global->params.match_ifaces,
5431 params->match_ifaces,
5432 params->match_iface_count *
5433 sizeof(struct wpa_interface));
5434 }
5435#endif /* CONFIG_MATCH_IFACE */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005436#ifdef CONFIG_P2P
Sasha Levitskiydaa60e52015-08-05 13:02:59 -07005437 if (params->conf_p2p_dev)
5438 global->params.conf_p2p_dev =
5439 os_strdup(params->conf_p2p_dev);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005440#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005441 wpa_debug_level = global->params.wpa_debug_level =
5442 params->wpa_debug_level;
5443 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
5444 params->wpa_debug_show_keys;
5445 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
5446 params->wpa_debug_timestamp;
5447
5448 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
5449
5450 if (eloop_init()) {
5451 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
5452 wpa_supplicant_deinit(global);
5453 return NULL;
5454 }
5455
Jouni Malinen75ecf522011-06-27 15:19:46 -07005456 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005457
5458 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
5459 if (global->ctrl_iface == NULL) {
5460 wpa_supplicant_deinit(global);
5461 return NULL;
5462 }
5463
5464 if (wpas_notify_supplicant_initialized(global)) {
5465 wpa_supplicant_deinit(global);
5466 return NULL;
5467 }
5468
5469 for (i = 0; wpa_drivers[i]; i++)
5470 global->drv_count++;
5471 if (global->drv_count == 0) {
5472 wpa_printf(MSG_ERROR, "No drivers enabled");
5473 wpa_supplicant_deinit(global);
5474 return NULL;
5475 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005476 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005477 if (global->drv_priv == NULL) {
5478 wpa_supplicant_deinit(global);
5479 return NULL;
5480 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005481
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005482#ifdef CONFIG_WIFI_DISPLAY
5483 if (wifi_display_init(global) < 0) {
5484 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
5485 wpa_supplicant_deinit(global);
5486 return NULL;
5487 }
5488#endif /* CONFIG_WIFI_DISPLAY */
5489
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005490 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5491 wpas_periodic, global, NULL);
5492
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005493 return global;
5494}
5495
5496
5497/**
5498 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
5499 * @global: Pointer to global data from wpa_supplicant_init()
5500 * Returns: 0 after successful event loop run, -1 on failure
5501 *
5502 * This function starts the main event loop and continues running as long as
5503 * there are any remaining events. In most cases, this function is running as
5504 * long as the %wpa_supplicant process in still in use.
5505 */
5506int wpa_supplicant_run(struct wpa_global *global)
5507{
5508 struct wpa_supplicant *wpa_s;
5509
5510 if (global->params.daemonize &&
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08005511 (wpa_supplicant_daemon(global->params.pid_file) ||
5512 eloop_sock_requeue()))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005513 return -1;
5514
Dmitry Shmidte4663042016-04-04 10:07:49 -07005515#ifdef CONFIG_MATCH_IFACE
5516 if (wpa_supplicant_match_existing(global))
5517 return -1;
5518#endif
5519
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005520 if (global->params.wait_for_monitor) {
5521 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -08005522 if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005523 wpa_supplicant_ctrl_iface_wait(
5524 wpa_s->ctrl_iface);
5525 }
5526
5527 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
5528 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
5529
5530 eloop_run();
5531
5532 return 0;
5533}
5534
5535
5536/**
5537 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
5538 * @global: Pointer to global data from wpa_supplicant_init()
5539 *
5540 * This function is called to deinitialize %wpa_supplicant and to free all
5541 * allocated resources. Remaining network interfaces will also be removed.
5542 */
5543void wpa_supplicant_deinit(struct wpa_global *global)
5544{
5545 int i;
5546
5547 if (global == NULL)
5548 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005549
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005550 eloop_cancel_timeout(wpas_periodic, global, NULL);
5551
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005552#ifdef CONFIG_WIFI_DISPLAY
5553 wifi_display_deinit(global);
5554#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005555
5556 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005557 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005558
5559 if (global->ctrl_iface)
5560 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
5561
5562 wpas_notify_supplicant_deinitialized(global);
5563
5564 eap_peer_unregister_methods();
5565#ifdef CONFIG_AP
5566 eap_server_unregister_methods();
5567#endif /* CONFIG_AP */
5568
5569 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
5570 if (!global->drv_priv[i])
5571 continue;
5572 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
5573 }
5574 os_free(global->drv_priv);
5575
5576 random_deinit();
5577
5578 eloop_destroy();
5579
5580 if (global->params.pid_file) {
5581 os_daemonize_terminate(global->params.pid_file);
5582 os_free(global->params.pid_file);
5583 }
5584 os_free(global->params.ctrl_interface);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -07005585 os_free(global->params.ctrl_interface_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005586 os_free(global->params.override_driver);
5587 os_free(global->params.override_ctrl_interface);
Dmitry Shmidte4663042016-04-04 10:07:49 -07005588#ifdef CONFIG_MATCH_IFACE
5589 os_free(global->params.match_ifaces);
5590#endif /* CONFIG_MATCH_IFACE */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005591#ifdef CONFIG_P2P
Sasha Levitskiydaa60e52015-08-05 13:02:59 -07005592 os_free(global->params.conf_p2p_dev);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005593#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005594
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07005595 os_free(global->p2p_disallow_freq.range);
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08005596 os_free(global->p2p_go_avoid_freq.range);
Dmitry Shmidt391c59f2013-09-03 12:16:28 -07005597 os_free(global->add_psk);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005598
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005599 os_free(global);
5600 wpa_debug_close_syslog();
5601 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07005602 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005603}
5604
5605
5606void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
5607{
5608 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5609 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5610 char country[3];
5611 country[0] = wpa_s->conf->country[0];
5612 country[1] = wpa_s->conf->country[1];
5613 country[2] = '\0';
5614 if (wpa_drv_set_country(wpa_s, country) < 0) {
5615 wpa_printf(MSG_ERROR, "Failed to set country code "
5616 "'%s'", country);
5617 }
5618 }
5619
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005620 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
5621 wpas_init_ext_pw(wpa_s);
5622
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08005623 if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
5624 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5625
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005626#ifdef CONFIG_WPS
5627 wpas_wps_update_config(wpa_s);
5628#endif /* CONFIG_WPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005629 wpas_p2p_update_config(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005630 wpa_s->conf->changed_parameters = 0;
5631}
5632
5633
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005634void add_freq(int *freqs, int *num_freqs, int freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005635{
5636 int i;
5637
5638 for (i = 0; i < *num_freqs; i++) {
5639 if (freqs[i] == freq)
5640 return;
5641 }
5642
5643 freqs[*num_freqs] = freq;
5644 (*num_freqs)++;
5645}
5646
5647
5648static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
5649{
5650 struct wpa_bss *bss, *cbss;
5651 const int max_freqs = 10;
5652 int *freqs;
5653 int num_freqs = 0;
5654
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005655 freqs = os_calloc(max_freqs + 1, sizeof(int));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005656 if (freqs == NULL)
5657 return NULL;
5658
5659 cbss = wpa_s->current_bss;
5660
5661 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
5662 if (bss == cbss)
5663 continue;
5664 if (bss->ssid_len == cbss->ssid_len &&
5665 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
5666 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
5667 add_freq(freqs, &num_freqs, bss->freq);
5668 if (num_freqs == max_freqs)
5669 break;
5670 }
5671 }
5672
5673 if (num_freqs == 0) {
5674 os_free(freqs);
5675 freqs = NULL;
5676 }
5677
5678 return freqs;
5679}
5680
5681
5682void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
5683{
5684 int timeout;
5685 int count;
5686 int *freqs = NULL;
5687
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005688 wpas_connect_work_done(wpa_s);
5689
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005690 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005691 * Remove possible authentication timeout since the connection failed.
5692 */
5693 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
5694
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005695 /*
5696 * There is no point in blacklisting the AP if this event is
5697 * generated based on local request to disconnect.
5698 */
5699 if (wpa_s->own_disconnect_req) {
5700 wpa_s->own_disconnect_req = 0;
5701 wpa_dbg(wpa_s, MSG_DEBUG,
5702 "Ignore connection failure due to local request to disconnect");
5703 return;
5704 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -07005705 if (wpa_s->disconnected) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -07005706 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
5707 "indication since interface has been put into "
5708 "disconnected state");
5709 return;
5710 }
5711
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005712 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005713 * Add the failed BSSID into the blacklist and speed up next scan
5714 * attempt if there could be other APs that could accept association.
5715 * The current blacklist count indicates how many times we have tried
5716 * connecting to this AP and multiple attempts mean that other APs are
5717 * either not available or has already been tried, so that we can start
5718 * increasing the delay here to avoid constant scanning.
5719 */
5720 count = wpa_blacklist_add(wpa_s, bssid);
5721 if (count == 1 && wpa_s->current_bss) {
5722 /*
5723 * This BSS was not in the blacklist before. If there is
5724 * another BSS available for the same ESS, we should try that
5725 * next. Otherwise, we may as well try this one once more
5726 * before allowing other, likely worse, ESSes to be considered.
5727 */
5728 freqs = get_bss_freqs_in_ess(wpa_s);
5729 if (freqs) {
5730 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
5731 "has been seen; try it next");
5732 wpa_blacklist_add(wpa_s, bssid);
5733 /*
5734 * On the next scan, go through only the known channels
5735 * used in this ESS based on previous scans to speed up
5736 * common load balancing use case.
5737 */
5738 os_free(wpa_s->next_scan_freqs);
5739 wpa_s->next_scan_freqs = freqs;
5740 }
5741 }
5742
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005743 /*
5744 * Add previous failure count in case the temporary blacklist was
5745 * cleared due to no other BSSes being available.
5746 */
5747 count += wpa_s->extra_blacklist_count;
5748
Dmitry Shmidt4b060592013-04-29 16:42:49 -07005749 if (count > 3 && wpa_s->current_ssid) {
5750 wpa_printf(MSG_DEBUG, "Continuous association failures - "
5751 "consider temporary network disabling");
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005752 wpas_auth_failed(wpa_s, "CONN_FAILED");
Dmitry Shmidt4b060592013-04-29 16:42:49 -07005753 }
5754
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005755 switch (count) {
5756 case 1:
5757 timeout = 100;
5758 break;
5759 case 2:
5760 timeout = 500;
5761 break;
5762 case 3:
5763 timeout = 1000;
5764 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005765 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005766 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005767 break;
5768 default:
5769 timeout = 10000;
5770 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005771 }
5772
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005773 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
5774 "ms", count, timeout);
5775
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005776 /*
5777 * TODO: if more than one possible AP is available in scan results,
5778 * could try the other ones before requesting a new scan.
5779 */
5780 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
5781 1000 * (timeout % 1000));
5782}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005783
5784
5785int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
5786{
5787 return wpa_s->conf->ap_scan == 2 ||
5788 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
5789}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005790
Dmitry Shmidt04949592012-07-19 12:16:46 -07005791
5792#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
5793int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
5794 struct wpa_ssid *ssid,
5795 const char *field,
5796 const char *value)
5797{
5798#ifdef IEEE8021X_EAPOL
5799 struct eap_peer_config *eap = &ssid->eap;
5800
5801 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
5802 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
5803 (const u8 *) value, os_strlen(value));
5804
5805 switch (wpa_supplicant_ctrl_req_from_string(field)) {
5806 case WPA_CTRL_REQ_EAP_IDENTITY:
5807 os_free(eap->identity);
5808 eap->identity = (u8 *) os_strdup(value);
5809 eap->identity_len = os_strlen(value);
5810 eap->pending_req_identity = 0;
5811 if (ssid == wpa_s->current_ssid)
5812 wpa_s->reassociate = 1;
5813 break;
5814 case WPA_CTRL_REQ_EAP_PASSWORD:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005815 bin_clear_free(eap->password, eap->password_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005816 eap->password = (u8 *) os_strdup(value);
5817 eap->password_len = os_strlen(value);
5818 eap->pending_req_password = 0;
5819 if (ssid == wpa_s->current_ssid)
5820 wpa_s->reassociate = 1;
5821 break;
5822 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005823 bin_clear_free(eap->new_password, eap->new_password_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005824 eap->new_password = (u8 *) os_strdup(value);
5825 eap->new_password_len = os_strlen(value);
5826 eap->pending_req_new_password = 0;
5827 if (ssid == wpa_s->current_ssid)
5828 wpa_s->reassociate = 1;
5829 break;
5830 case WPA_CTRL_REQ_EAP_PIN:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005831 str_clear_free(eap->pin);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005832 eap->pin = os_strdup(value);
5833 eap->pending_req_pin = 0;
5834 if (ssid == wpa_s->current_ssid)
5835 wpa_s->reassociate = 1;
5836 break;
5837 case WPA_CTRL_REQ_EAP_OTP:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005838 bin_clear_free(eap->otp, eap->otp_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005839 eap->otp = (u8 *) os_strdup(value);
5840 eap->otp_len = os_strlen(value);
5841 os_free(eap->pending_req_otp);
5842 eap->pending_req_otp = NULL;
5843 eap->pending_req_otp_len = 0;
5844 break;
5845 case WPA_CTRL_REQ_EAP_PASSPHRASE:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005846 str_clear_free(eap->private_key_passwd);
5847 eap->private_key_passwd = os_strdup(value);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005848 eap->pending_req_passphrase = 0;
5849 if (ssid == wpa_s->current_ssid)
5850 wpa_s->reassociate = 1;
5851 break;
Dmitry Shmidt051af732013-10-22 13:52:46 -07005852 case WPA_CTRL_REQ_SIM:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005853 str_clear_free(eap->external_sim_resp);
Dmitry Shmidt051af732013-10-22 13:52:46 -07005854 eap->external_sim_resp = os_strdup(value);
5855 break;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07005856 case WPA_CTRL_REQ_PSK_PASSPHRASE:
5857 if (wpa_config_set(ssid, "psk", value, 0) < 0)
5858 return -1;
5859 ssid->mem_only_psk = 1;
5860 if (ssid->passphrase)
5861 wpa_config_update_psk(ssid);
5862 if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
5863 wpa_supplicant_req_scan(wpa_s, 0, 0);
5864 break;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08005865 case WPA_CTRL_REQ_EXT_CERT_CHECK:
5866 if (eap->pending_ext_cert_check != PENDING_CHECK)
5867 return -1;
5868 if (os_strcmp(value, "good") == 0)
5869 eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
5870 else if (os_strcmp(value, "bad") == 0)
5871 eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
5872 else
5873 return -1;
5874 break;
Dmitry Shmidt04949592012-07-19 12:16:46 -07005875 default:
5876 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
5877 return -1;
5878 }
5879
5880 return 0;
5881#else /* IEEE8021X_EAPOL */
5882 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
5883 return -1;
5884#endif /* IEEE8021X_EAPOL */
5885}
5886#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
5887
5888
5889int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5890{
5891 int i;
5892 unsigned int drv_enc;
5893
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005894 if (wpa_s->p2p_mgmt)
5895 return 1; /* no normal network profiles on p2p_mgmt interface */
5896
Dmitry Shmidt04949592012-07-19 12:16:46 -07005897 if (ssid == NULL)
5898 return 1;
5899
5900 if (ssid->disabled)
5901 return 1;
5902
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005903 if (wpa_s->drv_capa_known)
Dmitry Shmidt04949592012-07-19 12:16:46 -07005904 drv_enc = wpa_s->drv_enc;
5905 else
5906 drv_enc = (unsigned int) -1;
5907
5908 for (i = 0; i < NUM_WEP_KEYS; i++) {
5909 size_t len = ssid->wep_key_len[i];
5910 if (len == 0)
5911 continue;
5912 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
5913 continue;
5914 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5915 continue;
5916 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5917 continue;
5918 return 1; /* invalid WEP key */
5919 }
5920
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005921 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07005922 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
5923 !ssid->mem_only_psk)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005924 return 1;
5925
Dmitry Shmidt04949592012-07-19 12:16:46 -07005926 return 0;
5927}
5928
5929
Dmitry Shmidt807291d2015-01-27 13:40:23 -08005930int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5931{
5932#ifdef CONFIG_IEEE80211W
5933 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5934 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5935 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5936 /*
5937 * Driver does not support BIP -- ignore pmf=1 default
5938 * since the connection with PMF would fail and the
5939 * configuration does not require PMF to be enabled.
5940 */
5941 return NO_MGMT_FRAME_PROTECTION;
5942 }
5943
Dmitry Shmidt849734c2016-05-27 09:59:01 -07005944 if (ssid &&
5945 (ssid->key_mgmt &
5946 ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
5947 WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
5948 /*
5949 * Do not use the default PMF value for non-RSN networks
5950 * since PMF is available only with RSN and pmf=2
5951 * configuration would otherwise prevent connections to
5952 * all open networks.
5953 */
5954 return NO_MGMT_FRAME_PROTECTION;
5955 }
5956
Dmitry Shmidt807291d2015-01-27 13:40:23 -08005957 return wpa_s->conf->pmf;
5958 }
5959
5960 return ssid->ieee80211w;
5961#else /* CONFIG_IEEE80211W */
5962 return NO_MGMT_FRAME_PROTECTION;
5963#endif /* CONFIG_IEEE80211W */
5964}
5965
5966
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005967int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005968{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07005969 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005970 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07005971 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005972 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005973 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005974}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005975
5976
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005977void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005978{
5979 struct wpa_ssid *ssid = wpa_s->current_ssid;
5980 int dur;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005981 struct os_reltime now;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005982
5983 if (ssid == NULL) {
5984 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
5985 "SSID block");
5986 return;
5987 }
5988
5989 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
5990 return;
5991
5992 ssid->auth_failures++;
Dmitry Shmidtd5c075b2013-08-05 14:36:10 -07005993
5994#ifdef CONFIG_P2P
5995 if (ssid->p2p_group &&
5996 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
5997 /*
5998 * Skip the wait time since there is a short timeout on the
5999 * connection to a P2P group.
6000 */
6001 return;
6002 }
6003#endif /* CONFIG_P2P */
6004
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006005 if (ssid->auth_failures > 50)
6006 dur = 300;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006007 else if (ssid->auth_failures > 10)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08006008 dur = 120;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006009 else if (ssid->auth_failures > 5)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08006010 dur = 90;
6011 else if (ssid->auth_failures > 3)
6012 dur = 60;
6013 else if (ssid->auth_failures > 2)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006014 dur = 30;
6015 else if (ssid->auth_failures > 1)
6016 dur = 20;
6017 else
6018 dur = 10;
6019
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08006020 if (ssid->auth_failures > 1 &&
6021 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
6022 dur += os_random() % (ssid->auth_failures * 10);
6023
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08006024 os_get_reltime(&now);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006025 if (now.sec + dur <= ssid->disabled_until.sec)
6026 return;
6027
6028 ssid->disabled_until.sec = now.sec + dur;
6029
6030 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07006031 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006032 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07006033 ssid->auth_failures, dur, reason);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07006034}
6035
6036
6037void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
6038 struct wpa_ssid *ssid, int clear_failures)
6039{
6040 if (ssid == NULL)
6041 return;
6042
6043 if (ssid->disabled_until.sec) {
6044 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
6045 "id=%d ssid=\"%s\"",
6046 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
6047 }
6048 ssid->disabled_until.sec = 0;
6049 ssid->disabled_until.usec = 0;
6050 if (clear_failures)
6051 ssid->auth_failures = 0;
6052}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08006053
6054
6055int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
6056{
6057 size_t i;
6058
6059 if (wpa_s->disallow_aps_bssid == NULL)
6060 return 0;
6061
6062 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
6063 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
6064 bssid, ETH_ALEN) == 0)
6065 return 1;
6066 }
6067
6068 return 0;
6069}
6070
6071
6072int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
6073 size_t ssid_len)
6074{
6075 size_t i;
6076
6077 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
6078 return 0;
6079
6080 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
6081 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
6082 if (ssid_len == s->ssid_len &&
6083 os_memcmp(ssid, s->ssid, ssid_len) == 0)
6084 return 1;
6085 }
6086
6087 return 0;
6088}
6089
6090
6091/**
6092 * wpas_request_connection - Request a new connection
6093 * @wpa_s: Pointer to the network interface
6094 *
6095 * This function is used to request a new connection to be found. It will mark
6096 * the interface to allow reassociation and request a new scan to find a
6097 * suitable network to connect to.
6098 */
6099void wpas_request_connection(struct wpa_supplicant *wpa_s)
6100{
6101 wpa_s->normal_scans = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006102 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08006103 wpa_supplicant_reinit_autoscan(wpa_s);
6104 wpa_s->extra_blacklist_count = 0;
6105 wpa_s->disconnected = 0;
6106 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08006107
6108 if (wpa_supplicant_fast_associate(wpa_s) != 1)
6109 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08006110 else
6111 wpa_s->reattach = 0;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08006112}
Dmitry Shmidtea69e842013-05-13 14:52:28 -07006113
6114
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -07006115/**
6116 * wpas_request_disconnection - Request disconnection
6117 * @wpa_s: Pointer to the network interface
6118 *
6119 * This function is used to request disconnection from the currently connected
6120 * network. This will stop any ongoing scans and initiate deauthentication.
6121 */
6122void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
6123{
6124#ifdef CONFIG_SME
6125 wpa_s->sme.prev_bssid_set = 0;
6126#endif /* CONFIG_SME */
6127 wpa_s->reassociate = 0;
6128 wpa_s->disconnected = 1;
6129 wpa_supplicant_cancel_sched_scan(wpa_s);
6130 wpa_supplicant_cancel_scan(wpa_s);
6131 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6132 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
6133}
6134
6135
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006136void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
6137 struct wpa_used_freq_data *freqs_data,
6138 unsigned int len)
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08006139{
6140 unsigned int i;
6141
6142 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
6143 len, title);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006144 for (i = 0; i < len; i++) {
6145 struct wpa_used_freq_data *cur = &freqs_data[i];
6146 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
6147 i, cur->freq, cur->flags);
6148 }
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08006149}
6150
6151
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006152/*
6153 * Find the operating frequencies of any of the virtual interfaces that
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006154 * are using the same radio as the current interface, and in addition, get
6155 * information about the interface types that are using the frequency.
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006156 */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006157int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
6158 struct wpa_used_freq_data *freqs_data,
6159 unsigned int len)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006160{
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006161 struct wpa_supplicant *ifs;
6162 u8 bssid[ETH_ALEN];
6163 int freq;
6164 unsigned int idx = 0, i;
6165
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08006166 wpa_dbg(wpa_s, MSG_DEBUG,
6167 "Determining shared radio frequencies (max len %u)", len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006168 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006169
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08006170 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
6171 radio_list) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006172 if (idx == len)
6173 break;
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006174
6175 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
6176 continue;
6177
6178 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08006179 ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
6180 ifs->current_ssid->mode == WPAS_MODE_MESH)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006181 freq = ifs->current_ssid->frequency;
6182 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
6183 freq = ifs->assoc_freq;
6184 else
6185 continue;
6186
6187 /* Hold only distinct freqs */
6188 for (i = 0; i < idx; i++)
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006189 if (freqs_data[i].freq == freq)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006190 break;
6191
6192 if (i == idx)
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006193 freqs_data[idx++].freq = freq;
6194
6195 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08006196 freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006197 WPA_FREQ_USED_BY_P2P_CLIENT :
6198 WPA_FREQ_USED_BY_INFRA_STATION;
6199 }
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006200 }
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08006201
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006202 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07006203 return idx;
6204}
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07006205
6206
6207/*
6208 * Find the operating frequencies of any of the virtual interfaces that
6209 * are using the same radio as the current interface.
6210 */
6211int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
6212 int *freq_array, unsigned int len)
6213{
6214 struct wpa_used_freq_data *freqs_data;
6215 int num, i;
6216
6217 os_memset(freq_array, 0, sizeof(int) * len);
6218
6219 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
6220 if (!freqs_data)
6221 return -1;
6222
6223 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
6224 for (i = 0; i < num; i++)
6225 freq_array[i] = freqs_data[i].freq;
6226
6227 os_free(freqs_data);
6228
6229 return num;
6230}
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006231
6232
6233static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
6234{
6235 struct rrm_data *rrm = data;
6236
6237 if (!rrm->notify_neighbor_rep) {
6238 wpa_printf(MSG_ERROR,
6239 "RRM: Unexpected neighbor report timeout");
6240 return;
6241 }
6242
6243 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
6244 rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
6245
6246 rrm->notify_neighbor_rep = NULL;
6247 rrm->neighbor_rep_cb_ctx = NULL;
6248}
6249
6250
6251/*
6252 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
6253 * @wpa_s: Pointer to wpa_supplicant
6254 */
6255void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
6256{
6257 wpa_s->rrm.rrm_used = 0;
6258
6259 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6260 NULL);
6261 if (wpa_s->rrm.notify_neighbor_rep)
6262 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
6263 wpa_s->rrm.next_neighbor_rep_token = 1;
6264}
6265
6266
6267/*
6268 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
6269 * @wpa_s: Pointer to wpa_supplicant
6270 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
6271 * @report_len: Length of neighbor report buffer
6272 */
6273void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
6274 const u8 *report, size_t report_len)
6275{
6276 struct wpabuf *neighbor_rep;
6277
6278 wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
6279 if (report_len < 1)
6280 return;
6281
6282 if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
6283 wpa_printf(MSG_DEBUG,
6284 "RRM: Discarding neighbor report with token %d (expected %d)",
6285 report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
6286 return;
6287 }
6288
6289 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6290 NULL);
6291
6292 if (!wpa_s->rrm.notify_neighbor_rep) {
6293 wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
6294 return;
6295 }
6296
6297 /* skipping the first byte, which is only an id (dialog token) */
6298 neighbor_rep = wpabuf_alloc(report_len - 1);
6299 if (neighbor_rep == NULL)
6300 return;
6301 wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
6302 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
6303 report[0]);
6304 wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
6305 neighbor_rep);
6306 wpa_s->rrm.notify_neighbor_rep = NULL;
6307 wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
6308}
6309
6310
Dmitry Shmidtff787d52015-01-12 13:01:47 -08006311#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
6312/* Workaround different, undefined for Windows, error codes used here */
6313#define ENOTCONN -1
6314#define EOPNOTSUPP -1
6315#define ECANCELED -1
6316#endif
6317
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006318/* Measurement Request element + Location Subject + Maximum Age subelement */
6319#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
6320/* Measurement Request element + Location Civic Request */
6321#define MEASURE_REQUEST_CIVIC_LEN (3 + 5)
6322
6323
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006324/**
6325 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
6326 * @wpa_s: Pointer to wpa_supplicant
6327 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
6328 * is sent in the request.
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006329 * @lci: if set, neighbor request will include LCI request
6330 * @civic: if set, neighbor request will include civic location request
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006331 * @cb: Callback function to be called once the requested report arrives, or
6332 * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
6333 * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
6334 * the requester's responsibility to free it.
6335 * In the latter case NULL will be sent in 'neighbor_rep'.
6336 * @cb_ctx: Context value to send the callback function
6337 * Returns: 0 in case of success, negative error code otherwise
6338 *
6339 * In case there is a previous request which has not been answered yet, the
6340 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
6341 * Request must contain a callback function.
6342 */
6343int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006344 const struct wpa_ssid_value *ssid,
6345 int lci, int civic,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006346 void (*cb)(void *ctx,
6347 struct wpabuf *neighbor_rep),
6348 void *cb_ctx)
6349{
6350 struct wpabuf *buf;
6351 const u8 *rrm_ie;
6352
6353 if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
6354 wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
6355 return -ENOTCONN;
6356 }
6357
6358 if (!wpa_s->rrm.rrm_used) {
6359 wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
6360 return -EOPNOTSUPP;
6361 }
6362
6363 rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
6364 WLAN_EID_RRM_ENABLED_CAPABILITIES);
6365 if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
6366 !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
6367 wpa_printf(MSG_DEBUG,
6368 "RRM: No network support for Neighbor Report.");
6369 return -EOPNOTSUPP;
6370 }
6371
6372 if (!cb) {
6373 wpa_printf(MSG_DEBUG,
6374 "RRM: Neighbor Report request must provide a callback.");
6375 return -EINVAL;
6376 }
6377
6378 /* Refuse if there's a live request */
6379 if (wpa_s->rrm.notify_neighbor_rep) {
6380 wpa_printf(MSG_DEBUG,
6381 "RRM: Currently handling previous Neighbor Report.");
6382 return -EBUSY;
6383 }
6384
6385 /* 3 = action category + action code + dialog token */
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006386 buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
6387 (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
6388 (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006389 if (buf == NULL) {
6390 wpa_printf(MSG_DEBUG,
6391 "RRM: Failed to allocate Neighbor Report Request");
6392 return -ENOMEM;
6393 }
6394
6395 wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
6396 (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
6397 wpa_s->rrm.next_neighbor_rep_token);
6398
6399 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6400 wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
6401 wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
6402 if (ssid) {
6403 wpabuf_put_u8(buf, WLAN_EID_SSID);
6404 wpabuf_put_u8(buf, ssid->ssid_len);
6405 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
6406 }
6407
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006408 if (lci) {
6409 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6410 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6411 wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);
6412
6413 /*
6414 * Measurement token; nonzero number that is unique among the
6415 * Measurement Request elements in a particular frame.
6416 */
6417 wpabuf_put_u8(buf, 1); /* Measurement Token */
6418
6419 /*
6420 * Parallel, Enable, Request, and Report bits are 0, Duration is
6421 * reserved.
6422 */
6423 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6424 wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */
6425
6426 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */
6427 /* Location Subject */
6428 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6429
6430 /* Optional Subelements */
6431 /*
6432 * IEEE P802.11-REVmc/D5.0 Figure 9-170
6433 * The Maximum Age subelement is required, otherwise the AP can
6434 * send only data that was determined after receiving the
6435 * request. Setting it here to unlimited age.
6436 */
6437 wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE);
6438 wpabuf_put_u8(buf, 2);
6439 wpabuf_put_le16(buf, 0xffff);
6440 }
6441
6442 if (civic) {
6443 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6444 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6445 wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);
6446
6447 /*
6448 * Measurement token; nonzero number that is unique among the
6449 * Measurement Request elements in a particular frame.
6450 */
6451 wpabuf_put_u8(buf, 2); /* Measurement Token */
6452
6453 /*
6454 * Parallel, Enable, Request, and Report bits are 0, Duration is
6455 * reserved.
6456 */
6457 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6458 /* Measurement Type */
6459 wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);
6460
6461 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.14:
6462 * Location Civic request */
6463 /* Location Subject */
6464 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6465 wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */
6466 /* Location Service Interval Units: Seconds */
6467 wpabuf_put_u8(buf, 0);
6468 /* Location Service Interval: 0 - Only one report is requested
6469 */
6470 wpabuf_put_le16(buf, 0);
6471 /* No optional subelements */
6472 }
6473
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006474 wpa_s->rrm.next_neighbor_rep_token++;
6475
6476 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
6477 wpa_s->own_addr, wpa_s->bssid,
6478 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
6479 wpa_printf(MSG_DEBUG,
6480 "RRM: Failed to send Neighbor Report Request");
6481 wpabuf_free(buf);
6482 return -ECANCELED;
6483 }
6484
6485 wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
6486 wpa_s->rrm.notify_neighbor_rep = cb;
6487 eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
6488 wpas_rrm_neighbor_rep_timeout_handler,
6489 &wpa_s->rrm, NULL);
6490
6491 wpabuf_free(buf);
6492 return 0;
6493}
6494
6495
Dmitry Shmidt849734c2016-05-27 09:59:01 -07006496static struct wpabuf * wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s,
6497 const u8 *request, size_t len,
6498 struct wpabuf *report)
6499{
6500 u8 token, type, subject;
6501 u16 max_age = 0;
6502 struct os_reltime t, diff;
6503 unsigned long diff_l;
6504 u8 *ptoken;
6505 const u8 *subelem;
6506
6507 if (!wpa_s->lci || len < 3 + 4)
6508 return report;
6509
6510 token = *request++;
6511 /* Measurement request mode isn't used */
6512 request++;
6513 type = *request++;
6514 subject = *request++;
6515
6516 wpa_printf(MSG_DEBUG,
6517 "Measurement request token %u type %u location subject %u",
6518 token, type, subject);
6519
6520 if (type != MEASURE_TYPE_LCI || subject != LOCATION_SUBJECT_REMOTE) {
6521 wpa_printf(MSG_INFO,
6522 "Not building LCI report - bad type or location subject");
6523 return report;
6524 }
6525
6526 /* Subelements are formatted exactly like elements */
6527 subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE);
6528 if (subelem && subelem[1] == 2)
6529 max_age = WPA_GET_LE16(subelem + 2);
6530
6531 if (os_get_reltime(&t))
6532 return report;
6533
6534 os_reltime_sub(&t, &wpa_s->lci_time, &diff);
6535 /* LCI age is calculated in 10th of a second units. */
6536 diff_l = diff.sec * 10 + diff.usec / 100000;
6537
6538 if (max_age != 0xffff && max_age < diff_l)
6539 return report;
6540
6541 if (wpabuf_resize(&report, 2 + wpabuf_len(wpa_s->lci)))
6542 return report;
6543
6544 wpabuf_put_u8(report, WLAN_EID_MEASURE_REPORT);
6545 wpabuf_put_u8(report, wpabuf_len(wpa_s->lci));
6546 /* We'll override user's measurement token */
6547 ptoken = wpabuf_put(report, 0);
6548 wpabuf_put_buf(report, wpa_s->lci);
6549 *ptoken = token;
6550
6551 return report;
6552}
6553
6554
6555void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
6556 const u8 *src,
6557 const u8 *frame, size_t len)
6558{
6559 struct wpabuf *buf, *report;
6560 u8 token;
6561 const u8 *ie, *end;
6562
6563 if (wpa_s->wpa_state != WPA_COMPLETED) {
6564 wpa_printf(MSG_INFO,
6565 "RRM: Ignoring radio measurement request: Not associated");
6566 return;
6567 }
6568
6569 if (!wpa_s->rrm.rrm_used) {
6570 wpa_printf(MSG_INFO,
6571 "RRM: Ignoring radio measurement request: Not RRM network");
6572 return;
6573 }
6574
6575 if (len < 3) {
6576 wpa_printf(MSG_INFO,
6577 "RRM: Ignoring too short radio measurement request");
6578 return;
6579 }
6580
6581 end = frame + len;
6582
6583 token = *frame++;
6584
6585 /* Ignore number of repetitions because it's not used in LCI request */
6586 frame += 2;
6587
6588 report = NULL;
6589 while ((ie = get_ie(frame, end - frame, WLAN_EID_MEASURE_REQUEST)) &&
6590 ie[1] >= 3) {
6591 u8 msmt_type;
6592
6593 msmt_type = ie[4];
6594 wpa_printf(MSG_DEBUG, "RRM request %d", msmt_type);
6595
6596 switch (msmt_type) {
6597 case MEASURE_TYPE_LCI:
6598 report = wpas_rrm_build_lci_report(wpa_s, ie + 2, ie[1],
6599 report);
6600 break;
6601 default:
6602 wpa_printf(MSG_INFO,
6603 "RRM: Unsupported radio measurement request %d",
6604 msmt_type);
6605 break;
6606 }
6607
6608 frame = ie + ie[1] + 2;
6609 }
6610
6611 if (!report)
6612 return;
6613
6614 buf = wpabuf_alloc(3 + wpabuf_len(report));
6615 if (!buf) {
6616 wpabuf_free(report);
6617 return;
6618 }
6619
6620 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6621 wpabuf_put_u8(buf, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
6622 wpabuf_put_u8(buf, token);
6623
6624 wpabuf_put_buf(buf, report);
6625 wpabuf_free(report);
6626
6627 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6628 wpa_s->own_addr, wpa_s->bssid,
6629 wpabuf_head(buf), wpabuf_len(buf), 0)) {
6630 wpa_printf(MSG_ERROR,
6631 "RRM: Radio measurement report failed: Sending Action frame failed");
6632 }
6633 wpabuf_free(buf);
6634}
6635
6636
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08006637void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
6638 const u8 *src,
6639 const u8 *frame, size_t len,
6640 int rssi)
6641{
6642 struct wpabuf *buf;
6643 const struct rrm_link_measurement_request *req;
6644 struct rrm_link_measurement_report report;
6645
6646 if (wpa_s->wpa_state != WPA_COMPLETED) {
6647 wpa_printf(MSG_INFO,
6648 "RRM: Ignoring link measurement request. Not associated");
6649 return;
6650 }
6651
6652 if (!wpa_s->rrm.rrm_used) {
6653 wpa_printf(MSG_INFO,
6654 "RRM: Ignoring link measurement request. Not RRM network");
6655 return;
6656 }
6657
6658 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
6659 wpa_printf(MSG_INFO,
6660 "RRM: Measurement report failed. TX power insertion not supported");
6661 return;
6662 }
6663
6664 req = (const struct rrm_link_measurement_request *) frame;
6665 if (len < sizeof(*req)) {
6666 wpa_printf(MSG_INFO,
6667 "RRM: Link measurement report failed. Request too short");
6668 return;
6669 }
6670
6671 os_memset(&report, 0, sizeof(report));
6672 report.tpc.eid = WLAN_EID_TPC_REPORT;
6673 report.tpc.len = 2;
6674 report.rsni = 255; /* 255 indicates that RSNI is not available */
6675 report.dialog_token = req->dialog_token;
6676
6677 /*
6678 * It's possible to estimate RCPI based on RSSI in dBm. This
6679 * calculation will not reflect the correct value for high rates,
6680 * but it's good enough for Action frames which are transmitted
6681 * with up to 24 Mbps rates.
6682 */
6683 if (!rssi)
6684 report.rcpi = 255; /* not available */
6685 else if (rssi < -110)
6686 report.rcpi = 0;
6687 else if (rssi > 0)
6688 report.rcpi = 220;
6689 else
6690 report.rcpi = (rssi + 110) * 2;
6691
6692 /* action_category + action_code */
6693 buf = wpabuf_alloc(2 + sizeof(report));
6694 if (buf == NULL) {
6695 wpa_printf(MSG_ERROR,
6696 "RRM: Link measurement report failed. Buffer allocation failed");
6697 return;
6698 }
6699
6700 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6701 wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
6702 wpabuf_put_data(buf, &report, sizeof(report));
6703 wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
6704 wpabuf_head(buf), wpabuf_len(buf));
6705
6706 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6707 wpa_s->own_addr, wpa_s->bssid,
6708 wpabuf_head(buf), wpabuf_len(buf), 0)) {
6709 wpa_printf(MSG_ERROR,
6710 "RRM: Link measurement report failed. Send action failed");
6711 }
6712 wpabuf_free(buf);
6713}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08006714
6715
6716struct wpa_supplicant *
6717wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
6718{
6719 switch (frame) {
6720#ifdef CONFIG_P2P
6721 case VENDOR_ELEM_PROBE_REQ_P2P:
6722 case VENDOR_ELEM_PROBE_RESP_P2P:
6723 case VENDOR_ELEM_PROBE_RESP_P2P_GO:
6724 case VENDOR_ELEM_BEACON_P2P_GO:
6725 case VENDOR_ELEM_P2P_PD_REQ:
6726 case VENDOR_ELEM_P2P_PD_RESP:
6727 case VENDOR_ELEM_P2P_GO_NEG_REQ:
6728 case VENDOR_ELEM_P2P_GO_NEG_RESP:
6729 case VENDOR_ELEM_P2P_GO_NEG_CONF:
6730 case VENDOR_ELEM_P2P_INV_REQ:
6731 case VENDOR_ELEM_P2P_INV_RESP:
6732 case VENDOR_ELEM_P2P_ASSOC_REQ:
6733 case VENDOR_ELEM_P2P_ASSOC_RESP:
Dmitry Shmidt9c175262016-03-03 10:20:07 -08006734 return wpa_s->p2pdev;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08006735#endif /* CONFIG_P2P */
6736 default:
6737 return wpa_s;
6738 }
6739}
6740
6741
6742void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
6743{
6744 unsigned int i;
6745 char buf[30];
6746
6747 wpa_printf(MSG_DEBUG, "Update vendor elements");
6748
6749 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
6750 if (wpa_s->vendor_elem[i]) {
6751 int res;
6752
6753 res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
6754 if (!os_snprintf_error(sizeof(buf), res)) {
6755 wpa_hexdump_buf(MSG_DEBUG, buf,
6756 wpa_s->vendor_elem[i]);
6757 }
6758 }
6759 }
6760
6761#ifdef CONFIG_P2P
6762 if (wpa_s->parent == wpa_s &&
6763 wpa_s->global->p2p &&
6764 !wpa_s->global->p2p_disabled)
6765 p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
6766#endif /* CONFIG_P2P */
6767}
6768
6769
6770int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
6771 const u8 *elem, size_t len)
6772{
6773 u8 *ie, *end;
6774
6775 ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
6776 end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
6777
6778 for (; ie + 1 < end; ie += 2 + ie[1]) {
6779 if (ie + len > end)
6780 break;
6781 if (os_memcmp(ie, elem, len) != 0)
6782 continue;
6783
6784 if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
6785 wpabuf_free(wpa_s->vendor_elem[frame]);
6786 wpa_s->vendor_elem[frame] = NULL;
6787 } else {
6788 os_memmove(ie, ie + len, end - (ie + len));
6789 wpa_s->vendor_elem[frame]->used -= len;
6790 }
6791 wpas_vendor_elem_update(wpa_s);
6792 return 0;
6793 }
6794
6795 return -1;
6796}
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08006797
6798
6799struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
6800 u16 num_modes, enum hostapd_hw_mode mode)
6801{
6802 u16 i;
6803
6804 for (i = 0; i < num_modes; i++) {
6805 if (modes[i].mode == mode)
6806 return &modes[i];
6807 }
6808
6809 return NULL;
6810}
6811
6812
6813static struct
6814wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
6815 const u8 *bssid)
6816{
6817 struct wpa_bss_tmp_disallowed *bss;
6818
6819 dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
6820 struct wpa_bss_tmp_disallowed, list) {
6821 if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
6822 return bss;
6823 }
6824
6825 return NULL;
6826}
6827
6828
6829void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
6830 unsigned int sec)
6831{
6832 struct wpa_bss_tmp_disallowed *bss;
6833 struct os_reltime until;
6834
6835 os_get_reltime(&until);
6836 until.sec += sec;
6837
6838 bss = wpas_get_disallowed_bss(wpa_s, bssid);
6839 if (bss) {
6840 bss->disallowed_until = until;
6841 return;
6842 }
6843
6844 bss = os_malloc(sizeof(*bss));
6845 if (!bss) {
6846 wpa_printf(MSG_DEBUG,
6847 "Failed to allocate memory for temp disallow BSS");
6848 return;
6849 }
6850
6851 bss->disallowed_until = until;
6852 os_memcpy(bss->bssid, bssid, ETH_ALEN);
6853 dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
6854}
6855
6856
6857int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid)
6858{
6859 struct wpa_bss_tmp_disallowed *bss = NULL, *tmp, *prev;
6860 struct os_reltime now, age;
6861
6862 os_get_reltime(&now);
6863
6864 dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
6865 struct wpa_bss_tmp_disallowed, list) {
6866 if (!os_reltime_before(&now, &tmp->disallowed_until)) {
6867 /* This BSS is not disallowed anymore */
6868 dl_list_del(&tmp->list);
6869 os_free(tmp);
6870 continue;
6871 }
6872 if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
6873 bss = tmp;
6874 break;
6875 }
6876 }
6877 if (!bss)
6878 return 0;
6879
6880 os_reltime_sub(&bss->disallowed_until, &now, &age);
6881 wpa_printf(MSG_DEBUG,
6882 "BSS " MACSTR " disabled for %ld.%0ld seconds",
6883 MAC2STR(bss->bssid), age.sec, age.usec);
6884 return 1;
6885}