blob: dbdaf19309340933949862fccb865288b943e01f [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003 * Copyright (c) 2003-2012, 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"
14
15#include "common.h"
16#include "crypto/random.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080017#include "crypto/sha1.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018#include "eapol_supp/eapol_supp_sm.h"
19#include "eap_peer/eap.h"
20#include "eap_server/eap_methods.h"
21#include "rsn_supp/wpa.h"
22#include "eloop.h"
23#include "config.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070024#include "utils/ext_password.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070025#include "l2_packet/l2_packet.h"
26#include "wpa_supplicant_i.h"
27#include "driver_i.h"
28#include "ctrl_iface.h"
29#include "pcsc_funcs.h"
30#include "common/version.h"
31#include "rsn_supp/preauth.h"
32#include "rsn_supp/pmksa_cache.h"
33#include "common/wpa_ctrl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034#include "common/ieee802_11_defs.h"
35#include "p2p/p2p.h"
36#include "blacklist.h"
37#include "wpas_glue.h"
38#include "wps_supplicant.h"
39#include "ibss_rsn.h"
40#include "sme.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080041#include "gas_query.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070042#include "ap.h"
43#include "p2p_supplicant.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070044#include "wifi_display.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070045#include "notify.h"
46#include "bgscan.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070047#include "autoscan.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070048#include "bss.h"
49#include "scan.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080050#include "offchannel.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070051#include "hs20_supplicant.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070052
53const char *wpa_supplicant_version =
54"wpa_supplicant v" VERSION_STR "\n"
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -080055"Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> and contributors";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070056
57const char *wpa_supplicant_license =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080058"This software may be distributed under the terms of the BSD license.\n"
59"See README for more details.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070060#ifdef EAP_TLS_OPENSSL
61"\nThis product includes software developed by the OpenSSL Project\n"
62"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
63#endif /* EAP_TLS_OPENSSL */
64;
65
66#ifndef CONFIG_NO_STDOUT_DEBUG
67/* Long text divided into parts in order to fit in C89 strings size limits. */
68const char *wpa_supplicant_full_license1 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080069"";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070070const char *wpa_supplicant_full_license2 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080071"This software may be distributed under the terms of the BSD license.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070072"\n"
73"Redistribution and use in source and binary forms, with or without\n"
74"modification, are permitted provided that the following conditions are\n"
75"met:\n"
76"\n";
77const char *wpa_supplicant_full_license3 =
78"1. Redistributions of source code must retain the above copyright\n"
79" notice, this list of conditions and the following disclaimer.\n"
80"\n"
81"2. Redistributions in binary form must reproduce the above copyright\n"
82" notice, this list of conditions and the following disclaimer in the\n"
83" documentation and/or other materials provided with the distribution.\n"
84"\n";
85const char *wpa_supplicant_full_license4 =
86"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
87" names of its contributors may be used to endorse or promote products\n"
88" derived from this software without specific prior written permission.\n"
89"\n"
90"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
91"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
92"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
93"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
94const char *wpa_supplicant_full_license5 =
95"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
96"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
97"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
98"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
99"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
100"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
101"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
102"\n";
103#endif /* CONFIG_NO_STDOUT_DEBUG */
104
105extern int wpa_debug_level;
106extern int wpa_debug_show_keys;
107extern int wpa_debug_timestamp;
108extern struct wpa_driver_ops *wpa_drivers[];
109
110/* Configure default/group WEP keys for static WEP */
111int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
112{
113 int i, set = 0;
114
115 for (i = 0; i < NUM_WEP_KEYS; i++) {
116 if (ssid->wep_key_len[i] == 0)
117 continue;
118
119 set = 1;
120 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
121 i, i == ssid->wep_tx_keyidx, NULL, 0,
122 ssid->wep_key[i], ssid->wep_key_len[i]);
123 }
124
125 return set;
126}
127
128
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -0700129int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
130 struct wpa_ssid *ssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700131{
132 u8 key[32];
133 size_t keylen;
134 enum wpa_alg alg;
135 u8 seq[6] = { 0 };
136
137 /* IBSS/WPA-None uses only one key (Group) for both receiving and
138 * sending unicast and multicast packets. */
139
140 if (ssid->mode != WPAS_MODE_IBSS) {
141 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
142 "IBSS/ad-hoc) for WPA-None", ssid->mode);
143 return -1;
144 }
145
146 if (!ssid->psk_set) {
147 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
148 "WPA-None");
149 return -1;
150 }
151
152 switch (wpa_s->group_cipher) {
153 case WPA_CIPHER_CCMP:
154 os_memcpy(key, ssid->psk, 16);
155 keylen = 16;
156 alg = WPA_ALG_CCMP;
157 break;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700158 case WPA_CIPHER_GCMP:
159 os_memcpy(key, ssid->psk, 16);
160 keylen = 16;
161 alg = WPA_ALG_GCMP;
162 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700163 case WPA_CIPHER_TKIP:
164 /* WPA-None uses the same Michael MIC key for both TX and RX */
165 os_memcpy(key, ssid->psk, 16 + 8);
166 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
167 keylen = 32;
168 alg = WPA_ALG_TKIP;
169 break;
170 default:
171 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
172 "WPA-None", wpa_s->group_cipher);
173 return -1;
174 }
175
176 /* TODO: should actually remember the previously used seq#, both for TX
177 * and RX from each STA.. */
178
179 return wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
180}
181
182
183static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
184{
185 struct wpa_supplicant *wpa_s = eloop_ctx;
186 const u8 *bssid = wpa_s->bssid;
187 if (is_zero_ether_addr(bssid))
188 bssid = wpa_s->pending_bssid;
189 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
190 MAC2STR(bssid));
191 wpa_blacklist_add(wpa_s, bssid);
192 wpa_sm_notify_disassoc(wpa_s->wpa);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800193 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700194 wpa_s->reassociate = 1;
195
196 /*
197 * If we timed out, the AP or the local radio may be busy.
198 * So, wait a second until scanning again.
199 */
200 wpa_supplicant_req_scan(wpa_s, 1, 0);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700201
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -0700202 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700203}
204
205
206/**
207 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
208 * @wpa_s: Pointer to wpa_supplicant data
209 * @sec: Number of seconds after which to time out authentication
210 * @usec: Number of microseconds after which to time out authentication
211 *
212 * This function is used to schedule a timeout for the current authentication
213 * attempt.
214 */
215void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
216 int sec, int usec)
217{
218 if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
219 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
220 return;
221
222 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
223 "%d usec", sec, usec);
224 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
225 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
226}
227
228
229/**
230 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
231 * @wpa_s: Pointer to wpa_supplicant data
232 *
233 * This function is used to cancel authentication timeout scheduled with
234 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
235 * been completed.
236 */
237void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
238{
239 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
240 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
241 wpa_blacklist_del(wpa_s, wpa_s->bssid);
242}
243
244
245/**
246 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
247 * @wpa_s: Pointer to wpa_supplicant data
248 *
249 * This function is used to configure EAPOL state machine based on the selected
250 * authentication mode.
251 */
252void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
253{
254#ifdef IEEE8021X_EAPOL
255 struct eapol_config eapol_conf;
256 struct wpa_ssid *ssid = wpa_s->current_ssid;
257
258#ifdef CONFIG_IBSS_RSN
259 if (ssid->mode == WPAS_MODE_IBSS &&
260 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
261 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
262 /*
263 * RSN IBSS authentication is per-STA and we can disable the
264 * per-BSSID EAPOL authentication.
265 */
266 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
267 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
268 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
269 return;
270 }
271#endif /* CONFIG_IBSS_RSN */
272
273 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
274 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
275
276 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
277 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
278 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
279 else
280 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
281
282 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
283 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
284 eapol_conf.accept_802_1x_keys = 1;
285 eapol_conf.required_keys = 0;
286 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
287 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
288 }
289 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
290 eapol_conf.required_keys |=
291 EAPOL_REQUIRE_KEY_BROADCAST;
292 }
293
294 if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
295 eapol_conf.required_keys = 0;
296 }
297 if (wpa_s->conf)
298 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
299 eapol_conf.workaround = ssid->eap_workaround;
300 eapol_conf.eap_disabled =
301 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
302 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
303 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
304 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
305#endif /* IEEE8021X_EAPOL */
306}
307
308
309/**
310 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
311 * @wpa_s: Pointer to wpa_supplicant data
312 * @ssid: Configuration data for the network
313 *
314 * This function is used to configure WPA state machine and related parameters
315 * to a mode where WPA is not enabled. This is called as part of the
316 * authentication configuration when the selected network does not use WPA.
317 */
318void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
319 struct wpa_ssid *ssid)
320{
321 int i;
322
323 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
324 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
325 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
326 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
327 else
328 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
329 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
330 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
331 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
332 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
333 wpa_s->group_cipher = WPA_CIPHER_NONE;
334 wpa_s->mgmt_group_cipher = 0;
335
336 for (i = 0; i < NUM_WEP_KEYS; i++) {
337 if (ssid->wep_key_len[i] > 5) {
338 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
339 wpa_s->group_cipher = WPA_CIPHER_WEP104;
340 break;
341 } else if (ssid->wep_key_len[i] > 0) {
342 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
343 wpa_s->group_cipher = WPA_CIPHER_WEP40;
344 break;
345 }
346 }
347
348 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
349 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
350 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
351 wpa_s->pairwise_cipher);
352 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
353#ifdef CONFIG_IEEE80211W
354 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
355 wpa_s->mgmt_group_cipher);
356#endif /* CONFIG_IEEE80211W */
357
358 pmksa_cache_clear_current(wpa_s->wpa);
359}
360
361
Dmitry Shmidt04949592012-07-19 12:16:46 -0700362void free_hw_features(struct wpa_supplicant *wpa_s)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800363{
364 int i;
365 if (wpa_s->hw.modes == NULL)
366 return;
367
368 for (i = 0; i < wpa_s->hw.num_modes; i++) {
369 os_free(wpa_s->hw.modes[i].channels);
370 os_free(wpa_s->hw.modes[i].rates);
371 }
372
373 os_free(wpa_s->hw.modes);
374 wpa_s->hw.modes = NULL;
375}
376
377
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700378static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
379{
380 bgscan_deinit(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700381 autoscan_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700382 scard_deinit(wpa_s->scard);
383 wpa_s->scard = NULL;
384 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
385 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
386 l2_packet_deinit(wpa_s->l2);
387 wpa_s->l2 = NULL;
388 if (wpa_s->l2_br) {
389 l2_packet_deinit(wpa_s->l2_br);
390 wpa_s->l2_br = NULL;
391 }
392
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700393 if (wpa_s->conf != NULL) {
394 struct wpa_ssid *ssid;
395 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
396 wpas_notify_network_removed(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700397 }
398
399 os_free(wpa_s->confname);
400 wpa_s->confname = NULL;
401
Jouni Malinen5d1c8ad2013-04-23 12:34:56 -0700402 os_free(wpa_s->confanother);
403 wpa_s->confanother = NULL;
404
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700405 wpa_sm_set_eapol(wpa_s->wpa, NULL);
406 eapol_sm_deinit(wpa_s->eapol);
407 wpa_s->eapol = NULL;
408
409 rsn_preauth_deinit(wpa_s->wpa);
410
411#ifdef CONFIG_TDLS
412 wpa_tdls_deinit(wpa_s->wpa);
413#endif /* CONFIG_TDLS */
414
415 pmksa_candidate_free(wpa_s->wpa);
416 wpa_sm_deinit(wpa_s->wpa);
417 wpa_s->wpa = NULL;
418 wpa_blacklist_clear(wpa_s);
419
420 wpa_bss_deinit(wpa_s);
421
422 wpa_supplicant_cancel_scan(wpa_s);
423 wpa_supplicant_cancel_auth_timeout(wpa_s);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800424 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
425#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
426 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
427 wpa_s, NULL);
428#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700429
430 wpas_wps_deinit(wpa_s);
431
432 wpabuf_free(wpa_s->pending_eapol_rx);
433 wpa_s->pending_eapol_rx = NULL;
434
435#ifdef CONFIG_IBSS_RSN
436 ibss_rsn_deinit(wpa_s->ibss_rsn);
437 wpa_s->ibss_rsn = NULL;
438#endif /* CONFIG_IBSS_RSN */
439
440 sme_deinit(wpa_s);
441
442#ifdef CONFIG_AP
443 wpa_supplicant_ap_deinit(wpa_s);
444#endif /* CONFIG_AP */
445
446#ifdef CONFIG_P2P
447 wpas_p2p_deinit(wpa_s);
448#endif /* CONFIG_P2P */
449
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800450#ifdef CONFIG_OFFCHANNEL
451 offchannel_deinit(wpa_s);
452#endif /* CONFIG_OFFCHANNEL */
453
454 wpa_supplicant_cancel_sched_scan(wpa_s);
455
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700456 os_free(wpa_s->next_scan_freqs);
457 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800458
459 gas_query_deinit(wpa_s->gas);
460 wpa_s->gas = NULL;
461
462 free_hw_features(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700463
464 os_free(wpa_s->bssid_filter);
465 wpa_s->bssid_filter = NULL;
466
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800467 os_free(wpa_s->disallow_aps_bssid);
468 wpa_s->disallow_aps_bssid = NULL;
469 os_free(wpa_s->disallow_aps_ssid);
470 wpa_s->disallow_aps_ssid = NULL;
471
Dmitry Shmidt04949592012-07-19 12:16:46 -0700472 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700473
474 ext_password_deinit(wpa_s->ext_pw);
475 wpa_s->ext_pw = NULL;
476
477 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidt9bce59c2012-09-11 15:06:38 -0700478
479 os_free(wpa_s->last_scan_res);
480 wpa_s->last_scan_res = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700481}
482
483
484/**
485 * wpa_clear_keys - Clear keys configured for the driver
486 * @wpa_s: Pointer to wpa_supplicant data
487 * @addr: Previously used BSSID or %NULL if not available
488 *
489 * This function clears the encryption keys that has been previously configured
490 * for the driver.
491 */
492void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
493{
494 if (wpa_s->keys_cleared) {
495 /* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
496 * timing issues with keys being cleared just before new keys
497 * are set or just after association or something similar. This
498 * shows up in group key handshake failing often because of the
499 * client not receiving the first encrypted packets correctly.
500 * Skipping some of the extra key clearing steps seems to help
501 * in completing group key handshake more reliably. */
502 wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
503 "skip key clearing");
504 return;
505 }
506
507 /* MLME-DELETEKEYS.request */
508 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
509 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
510 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
511 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
512#ifdef CONFIG_IEEE80211W
513 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
514 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
515#endif /* CONFIG_IEEE80211W */
516 if (addr) {
517 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
518 0);
519 /* MLME-SETPROTECTION.request(None) */
520 wpa_drv_mlme_setprotection(
521 wpa_s, addr,
522 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
523 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
524 }
525 wpa_s->keys_cleared = 1;
526}
527
528
529/**
530 * wpa_supplicant_state_txt - Get the connection state name as a text string
531 * @state: State (wpa_state; WPA_*)
532 * Returns: The state name as a printable text string
533 */
534const char * wpa_supplicant_state_txt(enum wpa_states state)
535{
536 switch (state) {
537 case WPA_DISCONNECTED:
538 return "DISCONNECTED";
539 case WPA_INACTIVE:
540 return "INACTIVE";
541 case WPA_INTERFACE_DISABLED:
542 return "INTERFACE_DISABLED";
543 case WPA_SCANNING:
544 return "SCANNING";
545 case WPA_AUTHENTICATING:
546 return "AUTHENTICATING";
547 case WPA_ASSOCIATING:
548 return "ASSOCIATING";
549 case WPA_ASSOCIATED:
550 return "ASSOCIATED";
551 case WPA_4WAY_HANDSHAKE:
552 return "4WAY_HANDSHAKE";
553 case WPA_GROUP_HANDSHAKE:
554 return "GROUP_HANDSHAKE";
555 case WPA_COMPLETED:
556 return "COMPLETED";
557 default:
558 return "UNKNOWN";
559 }
560}
561
562
563#ifdef CONFIG_BGSCAN
564
565static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
566{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800567 if (wpas_driver_bss_selection(wpa_s))
568 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700569 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
570 return;
571
572 bgscan_deinit(wpa_s);
573 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
574 if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
575 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
576 "bgscan");
577 /*
578 * Live without bgscan; it is only used as a roaming
579 * optimization, so the initial connection is not
580 * affected.
581 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700582 } else {
583 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700584 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700585 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
586 0);
587 if (scan_res) {
588 bgscan_notify_scan(wpa_s, scan_res);
589 wpa_scan_results_free(scan_res);
590 }
591 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700592 } else
593 wpa_s->bgscan_ssid = NULL;
594}
595
596
597static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
598{
599 if (wpa_s->bgscan_ssid != NULL) {
600 bgscan_deinit(wpa_s);
601 wpa_s->bgscan_ssid = NULL;
602 }
603}
604
605#endif /* CONFIG_BGSCAN */
606
607
Dmitry Shmidt04949592012-07-19 12:16:46 -0700608static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
609{
610 if (autoscan_init(wpa_s, 0))
611 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
612}
613
614
615static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
616{
617 autoscan_deinit(wpa_s);
618}
619
620
621void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
622{
623 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
624 wpa_s->wpa_state == WPA_SCANNING) {
625 autoscan_deinit(wpa_s);
626 wpa_supplicant_start_autoscan(wpa_s);
627 }
628}
629
630
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700631/**
632 * wpa_supplicant_set_state - Set current connection state
633 * @wpa_s: Pointer to wpa_supplicant data
634 * @state: The new connection state
635 *
636 * This function is called whenever the connection state changes, e.g.,
637 * association is completed for WPA/WPA2 4-Way Handshake is started.
638 */
639void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
640 enum wpa_states state)
641{
642 enum wpa_states old_state = wpa_s->wpa_state;
643
644 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
645 wpa_supplicant_state_txt(wpa_s->wpa_state),
646 wpa_supplicant_state_txt(state));
647
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700648#ifdef ANDROID_P2P
Irfan Sheriff7db4ef72012-06-18 09:39:07 -0700649 if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
650 wpa_s->current_ssid->assoc_retry = 0;
651 }
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700652#endif /* ANDROID_P2P */
653
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700654 if (state != WPA_SCANNING)
655 wpa_supplicant_notify_scanning(wpa_s, 0);
656
657 if (state == WPA_COMPLETED && wpa_s->new_connection) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700658 struct wpa_ssid *ssid = wpa_s->current_ssid;
Dmitry Shmidt700a1372013-03-15 14:14:44 -0700659#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700660 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800661 MACSTR " completed (auth) [id=%d id_str=%s]",
662 MAC2STR(wpa_s->bssid),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700663 ssid ? ssid->id : -1,
664 ssid && ssid->id_str ? ssid->id_str : "");
665#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700666 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800667 wpa_s->extra_blacklist_count = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700668 wpa_s->new_connection = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700669 wpa_drv_set_operstate(wpa_s, 1);
670#ifndef IEEE8021X_EAPOL
671 wpa_drv_set_supp_port(wpa_s, 1);
672#endif /* IEEE8021X_EAPOL */
673 wpa_s->after_wps = 0;
674#ifdef CONFIG_P2P
675 wpas_p2p_completed(wpa_s);
676#endif /* CONFIG_P2P */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700677
678 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700679 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
680 state == WPA_ASSOCIATED) {
681 wpa_s->new_connection = 1;
682 wpa_drv_set_operstate(wpa_s, 0);
683#ifndef IEEE8021X_EAPOL
684 wpa_drv_set_supp_port(wpa_s, 0);
685#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700686 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700687 }
688 wpa_s->wpa_state = state;
689
690#ifdef CONFIG_BGSCAN
691 if (state == WPA_COMPLETED)
692 wpa_supplicant_start_bgscan(wpa_s);
693 else
694 wpa_supplicant_stop_bgscan(wpa_s);
695#endif /* CONFIG_BGSCAN */
696
Dmitry Shmidt04949592012-07-19 12:16:46 -0700697 if (state == WPA_AUTHENTICATING)
698 wpa_supplicant_stop_autoscan(wpa_s);
699
700 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
701 wpa_supplicant_start_autoscan(wpa_s);
702
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700703 if (wpa_s->wpa_state != old_state) {
704 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
705
706 if (wpa_s->wpa_state == WPA_COMPLETED ||
707 old_state == WPA_COMPLETED)
708 wpas_notify_auth_changed(wpa_s);
709 }
710}
711
712
713void wpa_supplicant_terminate_proc(struct wpa_global *global)
714{
715 int pending = 0;
716#ifdef CONFIG_WPS
717 struct wpa_supplicant *wpa_s = global->ifaces;
718 while (wpa_s) {
719 if (wpas_wps_terminate_pending(wpa_s) == 1)
720 pending = 1;
721 wpa_s = wpa_s->next;
722 }
723#endif /* CONFIG_WPS */
724 if (pending)
725 return;
726 eloop_terminate();
727}
728
729
730static void wpa_supplicant_terminate(int sig, void *signal_ctx)
731{
732 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700733 wpa_supplicant_terminate_proc(global);
734}
735
736
737void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
738{
739 enum wpa_states old_state = wpa_s->wpa_state;
740
741 wpa_s->pairwise_cipher = 0;
742 wpa_s->group_cipher = 0;
743 wpa_s->mgmt_group_cipher = 0;
744 wpa_s->key_mgmt = 0;
745 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700746 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700747
748 if (wpa_s->wpa_state != old_state)
749 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
750}
751
752
753/**
754 * wpa_supplicant_reload_configuration - Reload configuration data
755 * @wpa_s: Pointer to wpa_supplicant data
756 * Returns: 0 on success or -1 if configuration parsing failed
757 *
758 * This function can be used to request that the configuration data is reloaded
759 * (e.g., after configuration file change). This function is reloading
760 * configuration only for one interface, so this may need to be called multiple
761 * times if %wpa_supplicant is controlling multiple interfaces and all
762 * interfaces need reconfiguration.
763 */
764int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
765{
766 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700767 int reconf_ctrl;
768 int old_ap_scan;
769
770 if (wpa_s->confname == NULL)
771 return -1;
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700772 conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700773 if (conf == NULL) {
774 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
775 "file '%s' - exiting", wpa_s->confname);
776 return -1;
777 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700778 wpa_config_read(wpa_s->confanother, conf);
779
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700780 conf->changed_parameters = (unsigned int) -1;
781
782 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
783 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
784 os_strcmp(conf->ctrl_interface,
785 wpa_s->conf->ctrl_interface) != 0);
786
787 if (reconf_ctrl && wpa_s->ctrl_iface) {
788 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
789 wpa_s->ctrl_iface = NULL;
790 }
791
792 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800793 if (wpa_s->current_ssid) {
794 wpa_supplicant_deauthenticate(wpa_s,
795 WLAN_REASON_DEAUTH_LEAVING);
796 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700797
798 /*
799 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
800 * pkcs11_engine_path, pkcs11_module_path.
801 */
802 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
803 /*
804 * Clear forced success to clear EAP state for next
805 * authentication.
806 */
807 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
808 }
809 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
810 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800811 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700812 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
813 rsn_preauth_deinit(wpa_s->wpa);
814
815 old_ap_scan = wpa_s->conf->ap_scan;
816 wpa_config_free(wpa_s->conf);
817 wpa_s->conf = conf;
818 if (old_ap_scan != wpa_s->conf->ap_scan)
819 wpas_notify_ap_scan_changed(wpa_s);
820
821 if (reconf_ctrl)
822 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
823
824 wpa_supplicant_update_config(wpa_s);
825
826 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700827 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700828 wpa_s->reassociate = 1;
829 wpa_supplicant_req_scan(wpa_s, 0, 0);
830 }
831 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
832 return 0;
833}
834
835
836static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
837{
838 struct wpa_global *global = signal_ctx;
839 struct wpa_supplicant *wpa_s;
840 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
841 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
842 sig);
843 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
844 wpa_supplicant_terminate_proc(global);
845 }
846 }
847}
848
849
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700850enum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
851{
852 switch (key_mgmt) {
853 case WPA_KEY_MGMT_NONE:
854 return KEY_MGMT_NONE;
855 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
856 return KEY_MGMT_802_1X_NO_WPA;
857 case WPA_KEY_MGMT_IEEE8021X:
858 return KEY_MGMT_802_1X;
859 case WPA_KEY_MGMT_WPA_NONE:
860 return KEY_MGMT_WPA_NONE;
861 case WPA_KEY_MGMT_FT_IEEE8021X:
862 return KEY_MGMT_FT_802_1X;
863 case WPA_KEY_MGMT_FT_PSK:
864 return KEY_MGMT_FT_PSK;
865 case WPA_KEY_MGMT_IEEE8021X_SHA256:
866 return KEY_MGMT_802_1X_SHA256;
867 case WPA_KEY_MGMT_PSK_SHA256:
868 return KEY_MGMT_PSK_SHA256;
869 case WPA_KEY_MGMT_WPS:
870 return KEY_MGMT_WPS;
871 case WPA_KEY_MGMT_PSK:
872 default:
873 return KEY_MGMT_PSK;
874 }
875}
876
877
878static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
879 struct wpa_ssid *ssid,
880 struct wpa_ie_data *ie)
881{
882 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
883 if (ret) {
884 if (ret == -2) {
885 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
886 "from association info");
887 }
888 return -1;
889 }
890
891 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
892 "cipher suites");
893 if (!(ie->group_cipher & ssid->group_cipher)) {
894 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
895 "cipher 0x%x (mask 0x%x) - reject",
896 ie->group_cipher, ssid->group_cipher);
897 return -1;
898 }
899 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
900 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
901 "cipher 0x%x (mask 0x%x) - reject",
902 ie->pairwise_cipher, ssid->pairwise_cipher);
903 return -1;
904 }
905 if (!(ie->key_mgmt & ssid->key_mgmt)) {
906 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
907 "management 0x%x (mask 0x%x) - reject",
908 ie->key_mgmt, ssid->key_mgmt);
909 return -1;
910 }
911
912#ifdef CONFIG_IEEE80211W
913 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800914 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
915 wpa_s->conf->pmf : ssid->ieee80211w) ==
916 MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700917 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
918 "that does not support management frame protection - "
919 "reject");
920 return -1;
921 }
922#endif /* CONFIG_IEEE80211W */
923
924 return 0;
925}
926
927
928/**
929 * wpa_supplicant_set_suites - Set authentication and encryption parameters
930 * @wpa_s: Pointer to wpa_supplicant data
931 * @bss: Scan results for the selected BSS, or %NULL if not available
932 * @ssid: Configuration data for the selected network
933 * @wpa_ie: Buffer for the WPA/RSN IE
934 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
935 * used buffer length in case the functions returns success.
936 * Returns: 0 on success or -1 on failure
937 *
938 * This function is used to configure authentication and encryption parameters
939 * based on the network configuration and scan result for the selected BSS (if
940 * available).
941 */
942int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
943 struct wpa_bss *bss, struct wpa_ssid *ssid,
944 u8 *wpa_ie, size_t *wpa_ie_len)
945{
946 struct wpa_ie_data ie;
947 int sel, proto;
948 const u8 *bss_wpa, *bss_rsn;
949
950 if (bss) {
951 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
952 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
953 } else
954 bss_wpa = bss_rsn = NULL;
955
956 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
957 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
958 (ie.group_cipher & ssid->group_cipher) &&
959 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
960 (ie.key_mgmt & ssid->key_mgmt)) {
961 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
962 proto = WPA_PROTO_RSN;
963 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
964 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
965 (ie.group_cipher & ssid->group_cipher) &&
966 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
967 (ie.key_mgmt & ssid->key_mgmt)) {
968 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
969 proto = WPA_PROTO_WPA;
970 } else if (bss) {
971 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
972 return -1;
973 } else {
974 if (ssid->proto & WPA_PROTO_RSN)
975 proto = WPA_PROTO_RSN;
976 else
977 proto = WPA_PROTO_WPA;
978 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
979 os_memset(&ie, 0, sizeof(ie));
980 ie.group_cipher = ssid->group_cipher;
981 ie.pairwise_cipher = ssid->pairwise_cipher;
982 ie.key_mgmt = ssid->key_mgmt;
983#ifdef CONFIG_IEEE80211W
984 ie.mgmt_group_cipher =
985 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
986 WPA_CIPHER_AES_128_CMAC : 0;
987#endif /* CONFIG_IEEE80211W */
988 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
989 "based on configuration");
990 } else
991 proto = ie.proto;
992 }
993
994 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
995 "pairwise %d key_mgmt %d proto %d",
996 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
997#ifdef CONFIG_IEEE80211W
998 if (ssid->ieee80211w) {
999 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1000 ie.mgmt_group_cipher);
1001 }
1002#endif /* CONFIG_IEEE80211W */
1003
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001004 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001005 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1006 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1007 !!(ssid->proto & WPA_PROTO_RSN));
1008
1009 if (bss || !wpa_s->ap_ies_from_associnfo) {
1010 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1011 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1012 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1013 bss_rsn ? 2 + bss_rsn[1] : 0))
1014 return -1;
1015 }
1016
1017 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001018 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1019 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001020 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1021 "cipher");
1022 return -1;
1023 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001024 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1025 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001026
1027 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001028 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1029 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001030 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1031 "cipher");
1032 return -1;
1033 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001034 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1035 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001036
1037 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001038#ifdef CONFIG_SAE
1039 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1040 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1041#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001042 if (0) {
1043#ifdef CONFIG_IEEE80211R
1044 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1045 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1046 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1047 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1048 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1049 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1050#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001051#ifdef CONFIG_SAE
1052 } else if (sel & WPA_KEY_MGMT_SAE) {
1053 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1054 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1055 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1056 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1057 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1058#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001059#ifdef CONFIG_IEEE80211W
1060 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1061 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1062 wpa_dbg(wpa_s, MSG_DEBUG,
1063 "WPA: using KEY_MGMT 802.1X with SHA256");
1064 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1065 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1066 wpa_dbg(wpa_s, MSG_DEBUG,
1067 "WPA: using KEY_MGMT PSK with SHA256");
1068#endif /* CONFIG_IEEE80211W */
1069 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1070 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1071 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1072 } else if (sel & WPA_KEY_MGMT_PSK) {
1073 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1074 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1075 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1076 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1077 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1078 } else {
1079 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1080 "authenticated key management type");
1081 return -1;
1082 }
1083
1084 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1085 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1086 wpa_s->pairwise_cipher);
1087 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1088
1089#ifdef CONFIG_IEEE80211W
1090 sel = ie.mgmt_group_cipher;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001091 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1092 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001093 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1094 sel = 0;
1095 if (sel & WPA_CIPHER_AES_128_CMAC) {
1096 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1097 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1098 "AES-128-CMAC");
1099 } else {
1100 wpa_s->mgmt_group_cipher = 0;
1101 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1102 }
1103 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1104 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001105 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1106 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1107 wpa_s->conf->pmf : ssid->ieee80211w));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001108#endif /* CONFIG_IEEE80211W */
1109
1110 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1111 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1112 return -1;
1113 }
1114
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001115 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001116 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001117#ifndef CONFIG_NO_PBKDF2
1118 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1119 ssid->passphrase) {
1120 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001121 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1122 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001123 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1124 psk, PMK_LEN);
1125 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1126 }
1127#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001128#ifdef CONFIG_EXT_PASSWORD
1129 if (ssid->ext_psk) {
1130 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1131 ssid->ext_psk);
1132 char pw_str[64 + 1];
1133 u8 psk[PMK_LEN];
1134
1135 if (pw == NULL) {
1136 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1137 "found from external storage");
1138 return -1;
1139 }
1140
1141 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1142 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1143 "PSK length %d in external storage",
1144 (int) wpabuf_len(pw));
1145 ext_password_free(pw);
1146 return -1;
1147 }
1148
1149 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1150 pw_str[wpabuf_len(pw)] = '\0';
1151
1152#ifndef CONFIG_NO_PBKDF2
1153 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1154 {
1155 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1156 4096, psk, PMK_LEN);
1157 os_memset(pw_str, 0, sizeof(pw_str));
1158 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1159 "external passphrase)",
1160 psk, PMK_LEN);
1161 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1162 } else
1163#endif /* CONFIG_NO_PBKDF2 */
1164 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1165 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1166 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1167 "Invalid PSK hex string");
1168 os_memset(pw_str, 0, sizeof(pw_str));
1169 ext_password_free(pw);
1170 return -1;
1171 }
1172 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1173 } else {
1174 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1175 "PSK available");
1176 os_memset(pw_str, 0, sizeof(pw_str));
1177 ext_password_free(pw);
1178 return -1;
1179 }
1180
1181 os_memset(pw_str, 0, sizeof(pw_str));
1182 ext_password_free(pw);
1183 }
1184#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001185 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001186 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1187
1188 return 0;
1189}
1190
1191
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001192static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1193{
1194 *pos = 0x00;
1195
1196 switch (idx) {
1197 case 0: /* Bits 0-7 */
1198 break;
1199 case 1: /* Bits 8-15 */
1200 break;
1201 case 2: /* Bits 16-23 */
1202#ifdef CONFIG_WNM
1203 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1204 *pos |= 0x08; /* Bit 19 - BSS Transition */
1205#endif /* CONFIG_WNM */
1206 break;
1207 case 3: /* Bits 24-31 */
1208#ifdef CONFIG_WNM
1209 *pos |= 0x02; /* Bit 25 - SSID List */
1210#endif /* CONFIG_WNM */
1211#ifdef CONFIG_INTERWORKING
1212 if (wpa_s->conf->interworking)
1213 *pos |= 0x80; /* Bit 31 - Interworking */
1214#endif /* CONFIG_INTERWORKING */
1215 break;
1216 case 4: /* Bits 32-39 */
1217 break;
1218 case 5: /* Bits 40-47 */
1219 break;
1220 case 6: /* Bits 48-55 */
1221 break;
1222 }
1223}
1224
1225
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001226int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1227{
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001228 u8 *pos = buf;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001229 u8 len = 4, i;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001230
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001231 if (len < wpa_s->extended_capa_len)
1232 len = wpa_s->extended_capa_len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001233
1234 *pos++ = WLAN_EID_EXT_CAPAB;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001235 *pos++ = len;
1236 for (i = 0; i < len; i++, pos++) {
1237 wpas_ext_capab_byte(wpa_s, pos, i);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001238
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001239 if (i < wpa_s->extended_capa_len) {
1240 *pos &= ~wpa_s->extended_capa_mask[i];
1241 *pos |= wpa_s->extended_capa[i];
1242 }
1243 }
1244
1245 while (len > 0 && buf[1 + len] == 0) {
1246 len--;
1247 buf[1] = len;
1248 }
1249 if (len == 0)
1250 return 0;
1251
1252 return 2 + len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001253}
1254
1255
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001256/**
1257 * wpa_supplicant_associate - Request association
1258 * @wpa_s: Pointer to wpa_supplicant data
1259 * @bss: Scan results for the selected BSS, or %NULL if not available
1260 * @ssid: Configuration data for the selected network
1261 *
1262 * This function is used to request %wpa_supplicant to associate with a BSS.
1263 */
1264void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1265 struct wpa_bss *bss, struct wpa_ssid *ssid)
1266{
1267 u8 wpa_ie[200];
1268 size_t wpa_ie_len;
1269 int use_crypt, ret, i, bssid_changed;
1270 int algs = WPA_AUTH_ALG_OPEN;
1271 enum wpa_cipher cipher_pairwise, cipher_group;
1272 struct wpa_driver_associate_params params;
1273 int wep_keys_set = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001274 int assoc_failed = 0;
1275 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001276 u8 ext_capab[10];
1277 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001278#ifdef CONFIG_HT_OVERRIDES
1279 struct ieee80211_ht_capabilities htcaps;
1280 struct ieee80211_ht_capabilities htcaps_mask;
1281#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001282
1283#ifdef CONFIG_IBSS_RSN
1284 ibss_rsn_deinit(wpa_s->ibss_rsn);
1285 wpa_s->ibss_rsn = NULL;
1286#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001287#ifdef ANDROID_P2P
1288 int freq = 0;
1289#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001290
1291 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1292 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1293#ifdef CONFIG_AP
1294 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1295 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1296 "mode");
1297 return;
1298 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001299 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1300 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1301 return;
1302 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001303 wpa_s->current_bss = bss;
1304#else /* CONFIG_AP */
1305 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1306 "the build");
1307#endif /* CONFIG_AP */
1308 return;
1309 }
1310
1311#ifdef CONFIG_TDLS
1312 if (bss)
1313 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1314 bss->ie_len);
1315#endif /* CONFIG_TDLS */
1316
1317 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1318 ssid->mode == IEEE80211_MODE_INFRA) {
1319 sme_authenticate(wpa_s, bss, ssid);
1320 return;
1321 }
1322
1323 os_memset(&params, 0, sizeof(params));
1324 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001325 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001326#ifdef CONFIG_IEEE80211R
1327 const u8 *ie, *md = NULL;
1328#endif /* CONFIG_IEEE80211R */
1329 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1330 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1331 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1332 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1333 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1334 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1335 if (bssid_changed)
1336 wpas_notify_bssid_changed(wpa_s);
1337#ifdef CONFIG_IEEE80211R
1338 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1339 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1340 md = ie + 2;
1341 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1342 if (md) {
1343 /* Prepare for the next transition */
1344 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1345 }
1346#endif /* CONFIG_IEEE80211R */
1347#ifdef CONFIG_WPS
1348 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1349 wpa_s->conf->ap_scan == 2 &&
1350 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1351 /* Use ap_scan==1 style network selection to find the network
1352 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001353 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001354 wpa_s->reassociate = 1;
1355 wpa_supplicant_req_scan(wpa_s, 0, 0);
1356 return;
1357#endif /* CONFIG_WPS */
1358 } else {
1359 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1360 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1361 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1362 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001363 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001364 wpa_supplicant_cancel_scan(wpa_s);
1365
1366 /* Starting new association, so clear the possibly used WPA IE from the
1367 * previous association. */
1368 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1369
1370#ifdef IEEE8021X_EAPOL
1371 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1372 if (ssid->leap) {
1373 if (ssid->non_leap == 0)
1374 algs = WPA_AUTH_ALG_LEAP;
1375 else
1376 algs |= WPA_AUTH_ALG_LEAP;
1377 }
1378 }
1379#endif /* IEEE8021X_EAPOL */
1380 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1381 if (ssid->auth_alg) {
1382 algs = ssid->auth_alg;
1383 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1384 "0x%x", algs);
1385 }
1386
1387 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1388 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001389 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001390 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001391 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1392 wpa_s->conf->okc :
1393 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001394 (ssid->proto & WPA_PROTO_RSN);
1395 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001396 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001397 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1398 wpa_ie_len = sizeof(wpa_ie);
1399 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1400 wpa_ie, &wpa_ie_len)) {
1401 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1402 "key management and encryption suites");
1403 return;
1404 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001405 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1406 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1407 /*
1408 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1409 * use non-WPA since the scan results did not indicate that the
1410 * AP is using WPA or WPA2.
1411 */
1412 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1413 wpa_ie_len = 0;
1414 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001415 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001416 wpa_ie_len = sizeof(wpa_ie);
1417 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1418 wpa_ie, &wpa_ie_len)) {
1419 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1420 "key management and encryption suites (no "
1421 "scan results)");
1422 return;
1423 }
1424#ifdef CONFIG_WPS
1425 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1426 struct wpabuf *wps_ie;
1427 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1428 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1429 wpa_ie_len = wpabuf_len(wps_ie);
1430 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1431 } else
1432 wpa_ie_len = 0;
1433 wpabuf_free(wps_ie);
1434 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1435 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1436 params.wps = WPS_MODE_PRIVACY;
1437 else
1438 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001439 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001440#endif /* CONFIG_WPS */
1441 } else {
1442 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1443 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001444 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001445 }
1446
1447#ifdef CONFIG_P2P
1448 if (wpa_s->global->p2p) {
1449 u8 *pos;
1450 size_t len;
1451 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001452 pos = wpa_ie + wpa_ie_len;
1453 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001454 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1455 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001456 if (res >= 0)
1457 wpa_ie_len += res;
1458 }
1459
1460 wpa_s->cross_connect_disallowed = 0;
1461 if (bss) {
1462 struct wpabuf *p2p;
1463 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1464 if (p2p) {
1465 wpa_s->cross_connect_disallowed =
1466 p2p_get_cross_connect_disallowed(p2p);
1467 wpabuf_free(p2p);
1468 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1469 "connection",
1470 wpa_s->cross_connect_disallowed ?
1471 "disallows" : "allows");
1472 }
1473 }
1474#endif /* CONFIG_P2P */
1475
Dmitry Shmidt04949592012-07-19 12:16:46 -07001476#ifdef CONFIG_HS20
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -07001477 if (is_hs20_network(wpa_s, ssid, bss)) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07001478 struct wpabuf *hs20;
1479 hs20 = wpabuf_alloc(20);
1480 if (hs20) {
1481 wpas_hs20_add_indication(hs20);
1482 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1483 wpabuf_len(hs20));
1484 wpa_ie_len += wpabuf_len(hs20);
1485 wpabuf_free(hs20);
1486 }
1487 }
1488#endif /* CONFIG_HS20 */
1489
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001490 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1491 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001492 u8 *pos = wpa_ie;
1493 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1494 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001495 os_memmove(pos + ext_capab_len, pos,
1496 wpa_ie_len - (pos - wpa_ie));
1497 wpa_ie_len += ext_capab_len;
1498 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001499 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001500
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001501 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1502 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001503 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1504 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001505 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1506 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1507 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1508 use_crypt = 0;
1509 if (wpa_set_wep_keys(wpa_s, ssid)) {
1510 use_crypt = 1;
1511 wep_keys_set = 1;
1512 }
1513 }
1514 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1515 use_crypt = 0;
1516
1517#ifdef IEEE8021X_EAPOL
1518 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1519 if ((ssid->eapol_flags &
1520 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1521 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1522 !wep_keys_set) {
1523 use_crypt = 0;
1524 } else {
1525 /* Assume that dynamic WEP-104 keys will be used and
1526 * set cipher suites in order for drivers to expect
1527 * encryption. */
1528 cipher_pairwise = cipher_group = CIPHER_WEP104;
1529 }
1530 }
1531#endif /* IEEE8021X_EAPOL */
1532
1533 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1534 /* Set the key before (and later after) association */
1535 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1536 }
1537
1538 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1539 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001540 params.ssid = bss->ssid;
1541 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001542 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1543 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1544 MACSTR " freq=%u MHz based on scan results "
1545 "(bssid_set=%d)",
1546 MAC2STR(bss->bssid), bss->freq,
1547 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001548 params.bssid = bss->bssid;
1549 params.freq = bss->freq;
1550 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001551 } else {
1552 params.ssid = ssid->ssid;
1553 params.ssid_len = ssid->ssid_len;
1554 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001555
1556 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1557 wpa_s->conf->ap_scan == 2) {
1558 params.bssid = ssid->bssid;
1559 params.fixed_bssid = 1;
1560 }
1561
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001562 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1563 params.freq == 0)
1564 params.freq = ssid->frequency; /* Initial channel for IBSS */
1565 params.wpa_ie = wpa_ie;
1566 params.wpa_ie_len = wpa_ie_len;
1567 params.pairwise_suite = cipher_pairwise;
1568 params.group_suite = cipher_group;
1569 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001570 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001571 params.auth_alg = algs;
1572 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001573 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001574 for (i = 0; i < NUM_WEP_KEYS; i++) {
1575 if (ssid->wep_key_len[i])
1576 params.wep_key[i] = ssid->wep_key[i];
1577 params.wep_key_len[i] = ssid->wep_key_len[i];
1578 }
1579 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1580
1581 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1582 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1583 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1584 params.passphrase = ssid->passphrase;
1585 if (ssid->psk_set)
1586 params.psk = ssid->psk;
1587 }
1588
1589 params.drop_unencrypted = use_crypt;
1590
1591#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001592 params.mgmt_frame_protection =
1593 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1594 wpa_s->conf->pmf : ssid->ieee80211w;
1595 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001596 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1597 struct wpa_ie_data ie;
1598 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1599 ie.capabilities &
1600 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1601 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1602 "MFP: require MFP");
1603 params.mgmt_frame_protection =
1604 MGMT_FRAME_PROTECTION_REQUIRED;
1605 }
1606 }
1607#endif /* CONFIG_IEEE80211W */
1608
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001609 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001610
1611 if (wpa_s->parent->set_sta_uapsd)
1612 params.uapsd = wpa_s->parent->sta_uapsd;
1613 else
1614 params.uapsd = -1;
1615
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001616#ifdef CONFIG_HT_OVERRIDES
1617 os_memset(&htcaps, 0, sizeof(htcaps));
1618 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1619 params.htcaps = (u8 *) &htcaps;
1620 params.htcaps_mask = (u8 *) &htcaps_mask;
1621 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1622#endif /* CONFIG_HT_OVERRIDES */
1623
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001624#ifdef ANDROID_P2P
1625 /* If multichannel concurrency is not supported, check for any frequency
1626 * conflict and take appropriate action.
1627 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001628 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1629 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1630 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001631 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001632 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001633 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001634 }
1635#endif
1636 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001637 if (ret < 0) {
1638 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1639 "failed");
1640 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1641 /*
1642 * The driver is known to mean what is saying, so we
1643 * can stop right here; the association will not
1644 * succeed.
1645 */
1646 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001647 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001648 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1649 return;
1650 }
1651 /* try to continue anyway; new association will be tried again
1652 * after timeout */
1653 assoc_failed = 1;
1654 }
1655
1656 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1657 /* Set the key after the association just in case association
1658 * cleared the previously configured key. */
1659 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1660 /* No need to timeout authentication since there is no key
1661 * management. */
1662 wpa_supplicant_cancel_auth_timeout(wpa_s);
1663 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1664#ifdef CONFIG_IBSS_RSN
1665 } else if (ssid->mode == WPAS_MODE_IBSS &&
1666 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1667 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1668 /*
1669 * RSN IBSS authentication is per-STA and we can disable the
1670 * per-BSSID authentication.
1671 */
1672 wpa_supplicant_cancel_auth_timeout(wpa_s);
1673#endif /* CONFIG_IBSS_RSN */
1674 } else {
1675 /* Timeout for IEEE 802.11 authentication and association */
1676 int timeout = 60;
1677
1678 if (assoc_failed) {
1679 /* give IBSS a bit more time */
1680 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1681 } else if (wpa_s->conf->ap_scan == 1) {
1682 /* give IBSS a bit more time */
1683 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1684 }
1685 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1686 }
1687
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -07001688 if (wep_keys_set &&
1689 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001690 /* Set static WEP keys again */
1691 wpa_set_wep_keys(wpa_s, ssid);
1692 }
1693
1694 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1695 /*
1696 * Do not allow EAP session resumption between different
1697 * network configurations.
1698 */
1699 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1700 }
1701 old_ssid = wpa_s->current_ssid;
1702 wpa_s->current_ssid = ssid;
1703 wpa_s->current_bss = bss;
1704 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1705 wpa_supplicant_initiate_eapol(wpa_s);
1706 if (old_ssid != wpa_s->current_ssid)
1707 wpas_notify_network_changed(wpa_s);
1708}
1709
1710
1711static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1712 const u8 *addr)
1713{
1714 struct wpa_ssid *old_ssid;
1715
1716 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001717 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001718 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001719 wpa_sm_set_config(wpa_s->wpa, NULL);
1720 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1721 if (old_ssid != wpa_s->current_ssid)
1722 wpas_notify_network_changed(wpa_s);
1723 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1724}
1725
1726
1727/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001728 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1729 * @wpa_s: Pointer to wpa_supplicant data
1730 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1731 *
1732 * This function is used to request %wpa_supplicant to deauthenticate from the
1733 * current AP.
1734 */
1735void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1736 int reason_code)
1737{
1738 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001739 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001740 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001741
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001742 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1743 " pending_bssid=" MACSTR " reason=%d state=%s",
1744 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1745 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1746
1747 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001748 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001749 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1750 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1751 wpa_s->wpa_state == WPA_ASSOCIATING))
1752 addr = wpa_s->pending_bssid;
1753 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1754 /*
1755 * When using driver-based BSS selection, we may not know the
1756 * BSSID with which we are currently trying to associate. We
1757 * need to notify the driver of this disconnection even in such
1758 * a case, so use the all zeros address here.
1759 */
1760 addr = wpa_s->bssid;
1761 zero_addr = 1;
1762 }
1763
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001764#ifdef CONFIG_TDLS
1765 wpa_tdls_teardown_peers(wpa_s->wpa);
1766#endif /* CONFIG_TDLS */
1767
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001768 if (addr) {
1769 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001770 os_memset(&event, 0, sizeof(event));
1771 event.deauth_info.reason_code = (u16) reason_code;
1772 event.deauth_info.locally_generated = 1;
1773 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001774 if (zero_addr)
1775 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001776 }
1777
1778 wpa_supplicant_clear_connection(wpa_s, addr);
1779}
1780
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001781static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1782 struct wpa_ssid *ssid)
1783{
1784 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1785 return;
1786
1787 ssid->disabled = 0;
1788 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1789 wpas_notify_network_enabled_changed(wpa_s, ssid);
1790
1791 /*
1792 * Try to reassociate since there is no current configuration and a new
1793 * network was made available.
1794 */
1795 if (!wpa_s->current_ssid)
1796 wpa_s->reassociate = 1;
1797}
1798
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001799
1800/**
1801 * wpa_supplicant_enable_network - Mark a configured network as enabled
1802 * @wpa_s: wpa_supplicant structure for a network interface
1803 * @ssid: wpa_ssid structure for a configured network or %NULL
1804 *
1805 * Enables the specified network or all networks if no network specified.
1806 */
1807void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1808 struct wpa_ssid *ssid)
1809{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001810 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001811 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1812 wpa_supplicant_enable_one_network(wpa_s, ssid);
1813 } else
1814 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001815
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001816 if (wpa_s->reassociate) {
1817 if (wpa_s->sched_scanning) {
1818 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1819 "new network to scan filters");
1820 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001821 }
1822
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001823 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001824 }
1825}
1826
1827
1828/**
1829 * wpa_supplicant_disable_network - Mark a configured network as disabled
1830 * @wpa_s: wpa_supplicant structure for a network interface
1831 * @ssid: wpa_ssid structure for a configured network or %NULL
1832 *
1833 * Disables the specified network or all networks if no network specified.
1834 */
1835void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1836 struct wpa_ssid *ssid)
1837{
1838 struct wpa_ssid *other_ssid;
1839 int was_disabled;
1840
1841 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001842 if (wpa_s->sched_scanning)
1843 wpa_supplicant_cancel_sched_scan(wpa_s);
1844
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001845 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1846 other_ssid = other_ssid->next) {
1847 was_disabled = other_ssid->disabled;
1848 if (was_disabled == 2)
1849 continue; /* do not change persistent P2P group
1850 * data */
1851
1852 other_ssid->disabled = 1;
1853
1854 if (was_disabled != other_ssid->disabled)
1855 wpas_notify_network_enabled_changed(
1856 wpa_s, other_ssid);
1857 }
1858 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001859 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001860 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1861 } else if (ssid->disabled != 2) {
1862 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001863 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001864 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1865
1866 was_disabled = ssid->disabled;
1867
1868 ssid->disabled = 1;
1869
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001870 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001871 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001872 if (wpa_s->sched_scanning) {
1873 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1874 "to remove network from filters");
1875 wpa_supplicant_cancel_sched_scan(wpa_s);
1876 wpa_supplicant_req_scan(wpa_s, 0, 0);
1877 }
1878 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001879 }
1880}
1881
1882
1883/**
1884 * wpa_supplicant_select_network - Attempt association with a network
1885 * @wpa_s: wpa_supplicant structure for a network interface
1886 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1887 */
1888void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1889 struct wpa_ssid *ssid)
1890{
1891
1892 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001893 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001894
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001895 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001896 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001897 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001898 disconnected = 1;
1899 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001900
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001901 if (ssid)
1902 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1903
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001904 /*
1905 * Mark all other networks disabled or mark all networks enabled if no
1906 * network specified.
1907 */
1908 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1909 other_ssid = other_ssid->next) {
1910 int was_disabled = other_ssid->disabled;
1911 if (was_disabled == 2)
1912 continue; /* do not change persistent P2P group data */
1913
1914 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001915 if (was_disabled && !other_ssid->disabled)
1916 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001917
1918 if (was_disabled != other_ssid->disabled)
1919 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1920 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001921
1922 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1923 /* We are already associated with the selected network */
1924 wpa_printf(MSG_DEBUG, "Already associated with the "
1925 "selected network - do nothing");
1926 return;
1927 }
1928
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001929 if (ssid)
1930 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001931 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001932 wpa_s->disconnected = 0;
1933 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001934
1935 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1936 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001937
1938 if (ssid)
1939 wpas_notify_network_selected(wpa_s, ssid);
1940}
1941
1942
1943/**
1944 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1945 * @wpa_s: wpa_supplicant structure for a network interface
1946 * @ap_scan: AP scan mode
1947 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1948 *
1949 */
1950int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1951{
1952
1953 int old_ap_scan;
1954
1955 if (ap_scan < 0 || ap_scan > 2)
1956 return -1;
1957
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001958#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001959 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1960 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1961 wpa_s->wpa_state < WPA_COMPLETED) {
1962 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1963 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001964 return 0;
1965 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001966#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001967
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001968 old_ap_scan = wpa_s->conf->ap_scan;
1969 wpa_s->conf->ap_scan = ap_scan;
1970
1971 if (old_ap_scan != wpa_s->conf->ap_scan)
1972 wpas_notify_ap_scan_changed(wpa_s);
1973
1974 return 0;
1975}
1976
1977
1978/**
1979 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1980 * @wpa_s: wpa_supplicant structure for a network interface
1981 * @expire_age: Expiration age in seconds
1982 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1983 *
1984 */
1985int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1986 unsigned int bss_expire_age)
1987{
1988 if (bss_expire_age < 10) {
1989 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1990 bss_expire_age);
1991 return -1;
1992 }
1993 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1994 bss_expire_age);
1995 wpa_s->conf->bss_expiration_age = bss_expire_age;
1996
1997 return 0;
1998}
1999
2000
2001/**
2002 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2003 * @wpa_s: wpa_supplicant structure for a network interface
2004 * @expire_count: number of scans after which an unseen BSS is reclaimed
2005 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2006 *
2007 */
2008int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2009 unsigned int bss_expire_count)
2010{
2011 if (bss_expire_count < 1) {
2012 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2013 bss_expire_count);
2014 return -1;
2015 }
2016 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2017 bss_expire_count);
2018 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2019
2020 return 0;
2021}
2022
2023
2024/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07002025 * wpa_supplicant_set_scan_interval - Set scan interval
2026 * @wpa_s: wpa_supplicant structure for a network interface
2027 * @scan_interval: scan interval in seconds
2028 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2029 *
2030 */
2031int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2032 int scan_interval)
2033{
2034 if (scan_interval < 0) {
2035 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2036 scan_interval);
2037 return -1;
2038 }
2039 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2040 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002041 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002042
2043 return 0;
2044}
2045
2046
2047/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002048 * wpa_supplicant_set_debug_params - Set global debug params
2049 * @global: wpa_global structure
2050 * @debug_level: debug level
2051 * @debug_timestamp: determines if show timestamp in debug data
2052 * @debug_show_keys: determines if show keys in debug data
2053 * Returns: 0 if succeed or -1 if debug_level has wrong value
2054 */
2055int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2056 int debug_timestamp, int debug_show_keys)
2057{
2058
2059 int old_level, old_timestamp, old_show_keys;
2060
2061 /* check for allowed debuglevels */
2062 if (debug_level != MSG_EXCESSIVE &&
2063 debug_level != MSG_MSGDUMP &&
2064 debug_level != MSG_DEBUG &&
2065 debug_level != MSG_INFO &&
2066 debug_level != MSG_WARNING &&
2067 debug_level != MSG_ERROR)
2068 return -1;
2069
2070 old_level = wpa_debug_level;
2071 old_timestamp = wpa_debug_timestamp;
2072 old_show_keys = wpa_debug_show_keys;
2073
2074 wpa_debug_level = debug_level;
2075 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2076 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2077
2078 if (wpa_debug_level != old_level)
2079 wpas_notify_debug_level_changed(global);
2080 if (wpa_debug_timestamp != old_timestamp)
2081 wpas_notify_debug_timestamp_changed(global);
2082 if (wpa_debug_show_keys != old_show_keys)
2083 wpas_notify_debug_show_keys_changed(global);
2084
2085 return 0;
2086}
2087
2088
2089/**
2090 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2091 * @wpa_s: Pointer to wpa_supplicant data
2092 * Returns: A pointer to the current network structure or %NULL on failure
2093 */
2094struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2095{
2096 struct wpa_ssid *entry;
2097 u8 ssid[MAX_SSID_LEN];
2098 int res;
2099 size_t ssid_len;
2100 u8 bssid[ETH_ALEN];
2101 int wired;
2102
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002103 res = wpa_drv_get_ssid(wpa_s, ssid);
2104 if (res < 0) {
2105 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2106 "driver");
2107 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002108 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002109 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002110
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002111 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002112 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2113 "driver");
2114 return NULL;
2115 }
2116
2117 wired = wpa_s->conf->ap_scan == 0 &&
2118 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2119
2120 entry = wpa_s->conf->ssid;
2121 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002122 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002123 ((ssid_len == entry->ssid_len &&
2124 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2125 (!entry->bssid_set ||
2126 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2127 return entry;
2128#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002129 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002130 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2131 (entry->ssid == NULL || entry->ssid_len == 0) &&
2132 (!entry->bssid_set ||
2133 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2134 return entry;
2135#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002136
Dmitry Shmidt04949592012-07-19 12:16:46 -07002137 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002138 entry->ssid_len == 0 &&
2139 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2140 return entry;
2141
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002142 entry = entry->next;
2143 }
2144
2145 return NULL;
2146}
2147
2148
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002149static int select_driver(struct wpa_supplicant *wpa_s, int i)
2150{
2151 struct wpa_global *global = wpa_s->global;
2152
2153 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2154 global->drv_priv[i] = wpa_drivers[i]->global_init();
2155 if (global->drv_priv[i] == NULL) {
2156 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2157 "'%s'", wpa_drivers[i]->name);
2158 return -1;
2159 }
2160 }
2161
2162 wpa_s->driver = wpa_drivers[i];
2163 wpa_s->global_drv_priv = global->drv_priv[i];
2164
2165 return 0;
2166}
2167
2168
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002169static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2170 const char *name)
2171{
2172 int i;
2173 size_t len;
2174 const char *pos, *driver = name;
2175
2176 if (wpa_s == NULL)
2177 return -1;
2178
2179 if (wpa_drivers[0] == NULL) {
2180 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2181 "wpa_supplicant");
2182 return -1;
2183 }
2184
2185 if (name == NULL) {
2186 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002187 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002188 }
2189
2190 do {
2191 pos = os_strchr(driver, ',');
2192 if (pos)
2193 len = pos - driver;
2194 else
2195 len = os_strlen(driver);
2196
2197 for (i = 0; wpa_drivers[i]; i++) {
2198 if (os_strlen(wpa_drivers[i]->name) == len &&
2199 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002200 0) {
2201 /* First driver that succeeds wins */
2202 if (select_driver(wpa_s, i) == 0)
2203 return 0;
2204 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002205 }
2206
2207 driver = pos + 1;
2208 } while (pos);
2209
2210 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2211 return -1;
2212}
2213
2214
2215/**
2216 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2217 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2218 * with struct wpa_driver_ops::init()
2219 * @src_addr: Source address of the EAPOL frame
2220 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2221 * @len: Length of the EAPOL data
2222 *
2223 * This function is called for each received EAPOL frame. Most driver
2224 * interfaces rely on more generic OS mechanism for receiving frames through
2225 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2226 * take care of received EAPOL frames and deliver them to the core supplicant
2227 * code by calling this function.
2228 */
2229void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2230 const u8 *buf, size_t len)
2231{
2232 struct wpa_supplicant *wpa_s = ctx;
2233
2234 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2235 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2236
Jouni Malinena05074c2012-12-21 21:35:35 +02002237 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2238 (wpa_s->last_eapol_matches_bssid &&
2239#ifdef CONFIG_AP
2240 !wpa_s->ap_iface &&
2241#endif /* CONFIG_AP */
2242 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002243 /*
2244 * There is possible race condition between receiving the
2245 * association event and the EAPOL frame since they are coming
2246 * through different paths from the driver. In order to avoid
2247 * issues in trying to process the EAPOL frame before receiving
2248 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002249 * the association event is received. This may also be needed in
2250 * driver-based roaming case, so also use src_addr != BSSID as a
2251 * trigger if we have previously confirmed that the
2252 * Authenticator uses BSSID as the src_addr (which is not the
2253 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002254 */
2255 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002256 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2257 wpa_supplicant_state_txt(wpa_s->wpa_state),
2258 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002259 wpabuf_free(wpa_s->pending_eapol_rx);
2260 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2261 if (wpa_s->pending_eapol_rx) {
2262 os_get_time(&wpa_s->pending_eapol_rx_time);
2263 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2264 ETH_ALEN);
2265 }
2266 return;
2267 }
2268
Jouni Malinena05074c2012-12-21 21:35:35 +02002269 wpa_s->last_eapol_matches_bssid =
2270 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2271
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002272#ifdef CONFIG_AP
2273 if (wpa_s->ap_iface) {
2274 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2275 return;
2276 }
2277#endif /* CONFIG_AP */
2278
2279 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2280 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2281 "no key management is configured");
2282 return;
2283 }
2284
2285 if (wpa_s->eapol_received == 0 &&
2286 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2287 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2288 wpa_s->wpa_state != WPA_COMPLETED) &&
2289 (wpa_s->current_ssid == NULL ||
2290 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2291 /* Timeout for completing IEEE 802.1X and WPA authentication */
2292 wpa_supplicant_req_auth_timeout(
2293 wpa_s,
2294 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2295 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2296 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2297 70 : 10, 0);
2298 }
2299 wpa_s->eapol_received++;
2300
2301 if (wpa_s->countermeasures) {
2302 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2303 "EAPOL packet");
2304 return;
2305 }
2306
2307#ifdef CONFIG_IBSS_RSN
2308 if (wpa_s->current_ssid &&
2309 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2310 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2311 return;
2312 }
2313#endif /* CONFIG_IBSS_RSN */
2314
2315 /* Source address of the incoming EAPOL frame could be compared to the
2316 * current BSSID. However, it is possible that a centralized
2317 * Authenticator could be using another MAC address than the BSSID of
2318 * an AP, so just allow any address to be used for now. The replies are
2319 * still sent to the current BSSID (if available), though. */
2320
2321 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2322 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2323 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2324 return;
2325 wpa_drv_poll(wpa_s);
2326 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2327 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2328 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2329 /*
2330 * Set portValid = TRUE here since we are going to skip 4-way
2331 * handshake processing which would normally set portValid. We
2332 * need this to allow the EAPOL state machines to be completed
2333 * without going through EAPOL-Key handshake.
2334 */
2335 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2336 }
2337}
2338
2339
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002340int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002341{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002342 if (wpa_s->driver->send_eapol) {
2343 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2344 if (addr)
2345 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2346 } else if (!(wpa_s->drv_flags &
2347 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002348 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002349 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2350 wpa_drv_get_mac_addr(wpa_s),
2351 ETH_P_EAPOL,
2352 wpa_supplicant_rx_eapol, wpa_s, 0);
2353 if (wpa_s->l2 == NULL)
2354 return -1;
2355 } else {
2356 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2357 if (addr)
2358 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2359 }
2360
2361 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2362 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2363 return -1;
2364 }
2365
2366 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2367 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002368 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2369
2370 return 0;
2371}
2372
2373
Dmitry Shmidt04949592012-07-19 12:16:46 -07002374static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2375 const u8 *buf, size_t len)
2376{
2377 struct wpa_supplicant *wpa_s = ctx;
2378 const struct l2_ethhdr *eth;
2379
2380 if (len < sizeof(*eth))
2381 return;
2382 eth = (const struct l2_ethhdr *) buf;
2383
2384 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2385 !(eth->h_dest[0] & 0x01)) {
2386 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2387 " (bridge - not for this interface - ignore)",
2388 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2389 return;
2390 }
2391
2392 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2393 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2394 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2395 len - sizeof(*eth));
2396}
2397
2398
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002399/**
2400 * wpa_supplicant_driver_init - Initialize driver interface parameters
2401 * @wpa_s: Pointer to wpa_supplicant data
2402 * Returns: 0 on success, -1 on failure
2403 *
2404 * This function is called to initialize driver interface parameters.
2405 * wpa_drv_init() must have been called before this function to initialize the
2406 * driver interface.
2407 */
2408int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2409{
2410 static int interface_count = 0;
2411
2412 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2413 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002414
2415 if (wpa_s->bridge_ifname[0]) {
2416 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2417 "interface '%s'", wpa_s->bridge_ifname);
2418 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2419 wpa_s->own_addr,
2420 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002421 wpa_supplicant_rx_eapol_bridge,
2422 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002423 if (wpa_s->l2_br == NULL) {
2424 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2425 "connection for the bridge interface '%s'",
2426 wpa_s->bridge_ifname);
2427 return -1;
2428 }
2429 }
2430
2431 wpa_clear_keys(wpa_s, NULL);
2432
2433 /* Make sure that TKIP countermeasures are not left enabled (could
2434 * happen if wpa_supplicant is killed during countermeasures. */
2435 wpa_drv_set_countermeasures(wpa_s, 0);
2436
2437 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2438 wpa_drv_flush_pmkid(wpa_s);
2439
2440 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002441 wpa_s->prev_scan_wildcard = 0;
2442
Dmitry Shmidt04949592012-07-19 12:16:46 -07002443 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002444 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2445 100000))
2446 wpa_supplicant_req_scan(wpa_s, interface_count,
2447 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002448 interface_count++;
2449 } else
2450 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2451
2452 return 0;
2453}
2454
2455
2456static int wpa_supplicant_daemon(const char *pid_file)
2457{
2458 wpa_printf(MSG_DEBUG, "Daemonize..");
2459 return os_daemonize(pid_file);
2460}
2461
2462
2463static struct wpa_supplicant * wpa_supplicant_alloc(void)
2464{
2465 struct wpa_supplicant *wpa_s;
2466
2467 wpa_s = os_zalloc(sizeof(*wpa_s));
2468 if (wpa_s == NULL)
2469 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002470 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002471 wpa_s->scan_interval = 5;
2472 wpa_s->new_connection = 1;
2473 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002474 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002475
2476 return wpa_s;
2477}
2478
2479
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002480#ifdef CONFIG_HT_OVERRIDES
2481
2482static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2483 struct ieee80211_ht_capabilities *htcaps,
2484 struct ieee80211_ht_capabilities *htcaps_mask,
2485 const char *ht_mcs)
2486{
2487 /* parse ht_mcs into hex array */
2488 int i;
2489 const char *tmp = ht_mcs;
2490 char *end = NULL;
2491
2492 /* If ht_mcs is null, do not set anything */
2493 if (!ht_mcs)
2494 return 0;
2495
2496 /* This is what we are setting in the kernel */
2497 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2498
2499 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2500
2501 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2502 errno = 0;
2503 long v = strtol(tmp, &end, 16);
2504 if (errno == 0) {
2505 wpa_msg(wpa_s, MSG_DEBUG,
2506 "htcap value[%i]: %ld end: %p tmp: %p",
2507 i, v, end, tmp);
2508 if (end == tmp)
2509 break;
2510
2511 htcaps->supported_mcs_set[i] = v;
2512 tmp = end;
2513 } else {
2514 wpa_msg(wpa_s, MSG_ERROR,
2515 "Failed to parse ht-mcs: %s, error: %s\n",
2516 ht_mcs, strerror(errno));
2517 return -1;
2518 }
2519 }
2520
2521 /*
2522 * If we were able to parse any values, then set mask for the MCS set.
2523 */
2524 if (i) {
2525 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2526 IEEE80211_HT_MCS_MASK_LEN - 1);
2527 /* skip the 3 reserved bits */
2528 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2529 0x1f;
2530 }
2531
2532 return 0;
2533}
2534
2535
2536static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2537 struct ieee80211_ht_capabilities *htcaps,
2538 struct ieee80211_ht_capabilities *htcaps_mask,
2539 int disabled)
2540{
2541 u16 msk;
2542
2543 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2544
2545 if (disabled == -1)
2546 return 0;
2547
2548 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2549 htcaps_mask->ht_capabilities_info |= msk;
2550 if (disabled)
2551 htcaps->ht_capabilities_info &= msk;
2552 else
2553 htcaps->ht_capabilities_info |= msk;
2554
2555 return 0;
2556}
2557
2558
2559static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2560 struct ieee80211_ht_capabilities *htcaps,
2561 struct ieee80211_ht_capabilities *htcaps_mask,
2562 int factor)
2563{
2564 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2565
2566 if (factor == -1)
2567 return 0;
2568
2569 if (factor < 0 || factor > 3) {
2570 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2571 "Must be 0-3 or -1", factor);
2572 return -EINVAL;
2573 }
2574
2575 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2576 htcaps->a_mpdu_params &= ~0x3;
2577 htcaps->a_mpdu_params |= factor & 0x3;
2578
2579 return 0;
2580}
2581
2582
2583static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2584 struct ieee80211_ht_capabilities *htcaps,
2585 struct ieee80211_ht_capabilities *htcaps_mask,
2586 int density)
2587{
2588 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2589
2590 if (density == -1)
2591 return 0;
2592
2593 if (density < 0 || density > 7) {
2594 wpa_msg(wpa_s, MSG_ERROR,
2595 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2596 density);
2597 return -EINVAL;
2598 }
2599
2600 htcaps_mask->a_mpdu_params |= 0x1C;
2601 htcaps->a_mpdu_params &= ~(0x1C);
2602 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2603
2604 return 0;
2605}
2606
2607
2608static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2609 struct ieee80211_ht_capabilities *htcaps,
2610 struct ieee80211_ht_capabilities *htcaps_mask,
2611 int disabled)
2612{
2613 /* Masking these out disables HT40 */
2614 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2615 HT_CAP_INFO_SHORT_GI40MHZ);
2616
2617 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2618
2619 if (disabled)
2620 htcaps->ht_capabilities_info &= ~msk;
2621 else
2622 htcaps->ht_capabilities_info |= msk;
2623
2624 htcaps_mask->ht_capabilities_info |= msk;
2625
2626 return 0;
2627}
2628
2629
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002630static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2631 struct ieee80211_ht_capabilities *htcaps,
2632 struct ieee80211_ht_capabilities *htcaps_mask,
2633 int disabled)
2634{
2635 /* Masking these out disables SGI */
2636 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2637 HT_CAP_INFO_SHORT_GI40MHZ);
2638
2639 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2640
2641 if (disabled)
2642 htcaps->ht_capabilities_info &= ~msk;
2643 else
2644 htcaps->ht_capabilities_info |= msk;
2645
2646 htcaps_mask->ht_capabilities_info |= msk;
2647
2648 return 0;
2649}
2650
2651
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002652void wpa_supplicant_apply_ht_overrides(
2653 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2654 struct wpa_driver_associate_params *params)
2655{
2656 struct ieee80211_ht_capabilities *htcaps;
2657 struct ieee80211_ht_capabilities *htcaps_mask;
2658
2659 if (!ssid)
2660 return;
2661
2662 params->disable_ht = ssid->disable_ht;
2663 if (!params->htcaps || !params->htcaps_mask)
2664 return;
2665
2666 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2667 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2668 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2669 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2670 ssid->disable_max_amsdu);
2671 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2672 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2673 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002674 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002675}
2676
2677#endif /* CONFIG_HT_OVERRIDES */
2678
2679
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002680#ifdef CONFIG_VHT_OVERRIDES
2681void wpa_supplicant_apply_vht_overrides(
2682 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2683 struct wpa_driver_associate_params *params)
2684{
2685 struct ieee80211_vht_capabilities *vhtcaps;
2686 struct ieee80211_vht_capabilities *vhtcaps_mask;
2687
2688 if (!ssid)
2689 return;
2690
2691 params->disable_vht = ssid->disable_vht;
2692
2693 vhtcaps = (void *) params->vhtcaps;
2694 vhtcaps_mask = (void *) params->vhtcaps_mask;
2695
2696 if (!vhtcaps || !vhtcaps_mask)
2697 return;
2698
2699 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2700 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2701
2702#define OVERRIDE_MCS(i) \
2703 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2704 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2705 3 << 2 * (i - 1); \
2706 vhtcaps->vht_supported_mcs_set.tx_map |= \
2707 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2708 } \
2709 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2710 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2711 3 << 2 * (i - 1); \
2712 vhtcaps->vht_supported_mcs_set.rx_map |= \
2713 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2714 }
2715
2716 OVERRIDE_MCS(1);
2717 OVERRIDE_MCS(2);
2718 OVERRIDE_MCS(3);
2719 OVERRIDE_MCS(4);
2720 OVERRIDE_MCS(5);
2721 OVERRIDE_MCS(6);
2722 OVERRIDE_MCS(7);
2723 OVERRIDE_MCS(8);
2724}
2725#endif /* CONFIG_VHT_OVERRIDES */
2726
2727
Dmitry Shmidt04949592012-07-19 12:16:46 -07002728static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2729{
2730#ifdef PCSC_FUNCS
2731 size_t len;
2732
2733 if (!wpa_s->conf->pcsc_reader)
2734 return 0;
2735
2736 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2737 if (!wpa_s->scard)
2738 return 1;
2739
2740 if (wpa_s->conf->pcsc_pin &&
2741 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2742 scard_deinit(wpa_s->scard);
2743 wpa_s->scard = NULL;
2744 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2745 return -1;
2746 }
2747
2748 len = sizeof(wpa_s->imsi) - 1;
2749 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2750 scard_deinit(wpa_s->scard);
2751 wpa_s->scard = NULL;
2752 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2753 return -1;
2754 }
2755 wpa_s->imsi[len] = '\0';
2756
2757 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2758
2759 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2760 wpa_s->imsi, wpa_s->mnc_len);
2761
2762 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2763 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2764#endif /* PCSC_FUNCS */
2765
2766 return 0;
2767}
2768
2769
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002770int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2771{
2772 char *val, *pos;
2773
2774 ext_password_deinit(wpa_s->ext_pw);
2775 wpa_s->ext_pw = NULL;
2776 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2777
2778 if (!wpa_s->conf->ext_password_backend)
2779 return 0;
2780
2781 val = os_strdup(wpa_s->conf->ext_password_backend);
2782 if (val == NULL)
2783 return -1;
2784 pos = os_strchr(val, ':');
2785 if (pos)
2786 *pos++ = '\0';
2787
2788 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2789
2790 wpa_s->ext_pw = ext_password_init(val, pos);
2791 os_free(val);
2792 if (wpa_s->ext_pw == NULL) {
2793 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2794 return -1;
2795 }
2796 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2797
2798 return 0;
2799}
2800
2801
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002802static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2803 struct wpa_interface *iface)
2804{
2805 const char *ifname, *driver;
2806 struct wpa_driver_capa capa;
2807
2808 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2809 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2810 iface->confname ? iface->confname : "N/A",
2811 iface->driver ? iface->driver : "default",
2812 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2813 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2814
2815 if (iface->confname) {
2816#ifdef CONFIG_BACKEND_FILE
2817 wpa_s->confname = os_rel2abs_path(iface->confname);
2818 if (wpa_s->confname == NULL) {
2819 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2820 "for configuration file '%s'.",
2821 iface->confname);
2822 return -1;
2823 }
2824 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2825 iface->confname, wpa_s->confname);
2826#else /* CONFIG_BACKEND_FILE */
2827 wpa_s->confname = os_strdup(iface->confname);
2828#endif /* CONFIG_BACKEND_FILE */
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002829 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002830 if (wpa_s->conf == NULL) {
2831 wpa_printf(MSG_ERROR, "Failed to read or parse "
2832 "configuration '%s'.", wpa_s->confname);
2833 return -1;
2834 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002835 wpa_s->confanother = os_rel2abs_path(iface->confanother);
2836 wpa_config_read(wpa_s->confanother, wpa_s->conf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002837
2838 /*
2839 * Override ctrl_interface and driver_param if set on command
2840 * line.
2841 */
2842 if (iface->ctrl_interface) {
2843 os_free(wpa_s->conf->ctrl_interface);
2844 wpa_s->conf->ctrl_interface =
2845 os_strdup(iface->ctrl_interface);
2846 }
2847
2848 if (iface->driver_param) {
2849 os_free(wpa_s->conf->driver_param);
2850 wpa_s->conf->driver_param =
2851 os_strdup(iface->driver_param);
2852 }
2853 } else
2854 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2855 iface->driver_param);
2856
2857 if (wpa_s->conf == NULL) {
2858 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2859 return -1;
2860 }
2861
2862 if (iface->ifname == NULL) {
2863 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2864 return -1;
2865 }
2866 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2867 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2868 iface->ifname);
2869 return -1;
2870 }
2871 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2872
2873 if (iface->bridge_ifname) {
2874 if (os_strlen(iface->bridge_ifname) >=
2875 sizeof(wpa_s->bridge_ifname)) {
2876 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2877 "name '%s'.", iface->bridge_ifname);
2878 return -1;
2879 }
2880 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2881 sizeof(wpa_s->bridge_ifname));
2882 }
2883
2884 /* RSNA Supplicant Key Management - INITIALIZE */
2885 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2886 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2887
2888 /* Initialize driver interface and register driver event handler before
2889 * L2 receive handler so that association events are processed before
2890 * EAPOL-Key packets if both become available for the same select()
2891 * call. */
2892 driver = iface->driver;
2893next_driver:
2894 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2895 return -1;
2896
2897 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2898 if (wpa_s->drv_priv == NULL) {
2899 const char *pos;
2900 pos = driver ? os_strchr(driver, ',') : NULL;
2901 if (pos) {
2902 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2903 "driver interface - try next driver wrapper");
2904 driver = pos + 1;
2905 goto next_driver;
2906 }
2907 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2908 "interface");
2909 return -1;
2910 }
2911 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2912 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2913 "driver_param '%s'", wpa_s->conf->driver_param);
2914 return -1;
2915 }
2916
2917 ifname = wpa_drv_get_ifname(wpa_s);
2918 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2919 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2920 "interface name with '%s'", ifname);
2921 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2922 }
2923
2924 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2925 return -1;
2926
2927 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2928 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2929 NULL);
2930 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2931
2932 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2933 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2934 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2935 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2936 "dot11RSNAConfigPMKLifetime");
2937 return -1;
2938 }
2939
2940 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2941 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2942 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2943 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2944 "dot11RSNAConfigPMKReauthThreshold");
2945 return -1;
2946 }
2947
2948 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2949 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2950 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2951 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2952 "dot11RSNAConfigSATimeout");
2953 return -1;
2954 }
2955
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002956 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2957 &wpa_s->hw.num_modes,
2958 &wpa_s->hw.flags);
2959
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002960 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002961 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002962 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002963 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002964 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002965 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002966 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2967 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2968 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002969 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2970 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07002971 wpa_s->extended_capa = capa.extended_capa;
2972 wpa_s->extended_capa_mask = capa.extended_capa_mask;
2973 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002974 }
2975 if (wpa_s->max_remain_on_chan == 0)
2976 wpa_s->max_remain_on_chan = 1000;
2977
2978 if (wpa_supplicant_driver_init(wpa_s) < 0)
2979 return -1;
2980
2981#ifdef CONFIG_TDLS
2982 if (wpa_tdls_init(wpa_s->wpa))
2983 return -1;
2984#endif /* CONFIG_TDLS */
2985
2986 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2987 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2988 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2989 return -1;
2990 }
2991
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002992 if (wpas_wps_init(wpa_s))
2993 return -1;
2994
2995 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2996 return -1;
2997 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2998
2999 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
3000 if (wpa_s->ctrl_iface == NULL) {
3001 wpa_printf(MSG_ERROR,
3002 "Failed to initialize control interface '%s'.\n"
3003 "You may have another wpa_supplicant process "
3004 "already running or the file was\n"
3005 "left by an unclean termination of wpa_supplicant "
3006 "in which case you will need\n"
3007 "to manually remove this file before starting "
3008 "wpa_supplicant again.\n",
3009 wpa_s->conf->ctrl_interface);
3010 return -1;
3011 }
3012
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003013 wpa_s->gas = gas_query_init(wpa_s);
3014 if (wpa_s->gas == NULL) {
3015 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3016 return -1;
3017 }
3018
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003019#ifdef CONFIG_P2P
3020 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
3021 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
3022 return -1;
3023 }
3024#endif /* CONFIG_P2P */
3025
3026 if (wpa_bss_init(wpa_s) < 0)
3027 return -1;
3028
Dmitry Shmidt04949592012-07-19 12:16:46 -07003029 if (pcsc_reader_init(wpa_s) < 0)
3030 return -1;
3031
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003032 if (wpas_init_ext_pw(wpa_s) < 0)
3033 return -1;
3034
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003035 return 0;
3036}
3037
3038
3039static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003040 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003041{
Dmitry Shmidtea69e842013-05-13 14:52:28 -07003042 wpa_s->disconnected = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003043 if (wpa_s->drv_priv) {
3044 wpa_supplicant_deauthenticate(wpa_s,
3045 WLAN_REASON_DEAUTH_LEAVING);
3046
3047 wpa_drv_set_countermeasures(wpa_s, 0);
3048 wpa_clear_keys(wpa_s, NULL);
3049 }
3050
3051 wpa_supplicant_cleanup(wpa_s);
3052
Dmitry Shmidt04949592012-07-19 12:16:46 -07003053#ifdef CONFIG_P2P
3054 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3055 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3056 "the management interface is being removed");
3057 wpas_p2p_deinit_global(wpa_s->global);
3058 }
3059#endif /* CONFIG_P2P */
3060
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003061 if (wpa_s->drv_priv)
3062 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003063
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003064 if (notify)
3065 wpas_notify_iface_removed(wpa_s);
3066
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003067 if (terminate)
3068 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003069
3070 if (wpa_s->ctrl_iface) {
3071 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3072 wpa_s->ctrl_iface = NULL;
3073 }
3074
3075 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003076 wpa_config_free(wpa_s->conf);
3077 wpa_s->conf = NULL;
3078 }
Dmitry Shmidt8da800a2013-04-24 12:57:01 -07003079
3080 os_free(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003081}
3082
3083
3084/**
3085 * wpa_supplicant_add_iface - Add a new network interface
3086 * @global: Pointer to global data from wpa_supplicant_init()
3087 * @iface: Interface configuration options
3088 * Returns: Pointer to the created interface or %NULL on failure
3089 *
3090 * This function is used to add new network interfaces for %wpa_supplicant.
3091 * This can be called before wpa_supplicant_run() to add interfaces before the
3092 * main event loop has been started. In addition, new interfaces can be added
3093 * dynamically while %wpa_supplicant is already running. This could happen,
3094 * e.g., when a hotplug network adapter is inserted.
3095 */
3096struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3097 struct wpa_interface *iface)
3098{
3099 struct wpa_supplicant *wpa_s;
3100 struct wpa_interface t_iface;
3101 struct wpa_ssid *ssid;
3102
3103 if (global == NULL || iface == NULL)
3104 return NULL;
3105
3106 wpa_s = wpa_supplicant_alloc();
3107 if (wpa_s == NULL)
3108 return NULL;
3109
3110 wpa_s->global = global;
3111
3112 t_iface = *iface;
3113 if (global->params.override_driver) {
3114 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3115 "('%s' -> '%s')",
3116 iface->driver, global->params.override_driver);
3117 t_iface.driver = global->params.override_driver;
3118 }
3119 if (global->params.override_ctrl_interface) {
3120 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3121 "ctrl_interface ('%s' -> '%s')",
3122 iface->ctrl_interface,
3123 global->params.override_ctrl_interface);
3124 t_iface.ctrl_interface =
3125 global->params.override_ctrl_interface;
3126 }
3127 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3128 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3129 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003130 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003131 return NULL;
3132 }
3133
3134 /* Notify the control interfaces about new iface */
3135 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003136 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003137 return NULL;
3138 }
3139
3140 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3141 wpas_notify_network_added(wpa_s, ssid);
3142
3143 wpa_s->next = global->ifaces;
3144 global->ifaces = wpa_s;
3145
3146 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003147 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003148
3149 return wpa_s;
3150}
3151
3152
3153/**
3154 * wpa_supplicant_remove_iface - Remove a network interface
3155 * @global: Pointer to global data from wpa_supplicant_init()
3156 * @wpa_s: Pointer to the network interface to be removed
3157 * Returns: 0 if interface was removed, -1 if interface was not found
3158 *
3159 * This function can be used to dynamically remove network interfaces from
3160 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3161 * addition, this function is used to remove all remaining interfaces when
3162 * %wpa_supplicant is terminated.
3163 */
3164int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003165 struct wpa_supplicant *wpa_s,
3166 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003167{
3168 struct wpa_supplicant *prev;
3169
3170 /* Remove interface from the global list of interfaces */
3171 prev = global->ifaces;
3172 if (prev == wpa_s) {
3173 global->ifaces = wpa_s->next;
3174 } else {
3175 while (prev && prev->next != wpa_s)
3176 prev = prev->next;
3177 if (prev == NULL)
3178 return -1;
3179 prev->next = wpa_s->next;
3180 }
3181
3182 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3183
3184 if (global->p2p_group_formation == wpa_s)
3185 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07003186 if (global->p2p_invite_group == wpa_s)
3187 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003188 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003189
3190 return 0;
3191}
3192
3193
3194/**
3195 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3196 * @wpa_s: Pointer to the network interface
3197 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3198 */
3199const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3200{
3201 const char *eapol_method;
3202
3203 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3204 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3205 return "NO-EAP";
3206 }
3207
3208 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3209 if (eapol_method == NULL)
3210 return "UNKNOWN-EAP";
3211
3212 return eapol_method;
3213}
3214
3215
3216/**
3217 * wpa_supplicant_get_iface - Get a new network interface
3218 * @global: Pointer to global data from wpa_supplicant_init()
3219 * @ifname: Interface name
3220 * Returns: Pointer to the interface or %NULL if not found
3221 */
3222struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3223 const char *ifname)
3224{
3225 struct wpa_supplicant *wpa_s;
3226
3227 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3228 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3229 return wpa_s;
3230 }
3231 return NULL;
3232}
3233
3234
3235#ifndef CONFIG_NO_WPA_MSG
3236static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3237{
3238 struct wpa_supplicant *wpa_s = ctx;
3239 if (wpa_s == NULL)
3240 return NULL;
3241 return wpa_s->ifname;
3242}
3243#endif /* CONFIG_NO_WPA_MSG */
3244
3245
3246/**
3247 * wpa_supplicant_init - Initialize %wpa_supplicant
3248 * @params: Parameters for %wpa_supplicant
3249 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3250 *
3251 * This function is used to initialize %wpa_supplicant. After successful
3252 * initialization, the returned data pointer can be used to add and remove
3253 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3254 */
3255struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3256{
3257 struct wpa_global *global;
3258 int ret, i;
3259
3260 if (params == NULL)
3261 return NULL;
3262
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003263#ifdef CONFIG_DRIVER_NDIS
3264 {
3265 void driver_ndis_init_ops(void);
3266 driver_ndis_init_ops();
3267 }
3268#endif /* CONFIG_DRIVER_NDIS */
3269
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003270#ifndef CONFIG_NO_WPA_MSG
3271 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3272#endif /* CONFIG_NO_WPA_MSG */
3273
3274 wpa_debug_open_file(params->wpa_debug_file_path);
3275 if (params->wpa_debug_syslog)
3276 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003277 if (params->wpa_debug_tracing) {
3278 ret = wpa_debug_open_linux_tracing();
3279 if (ret) {
3280 wpa_printf(MSG_ERROR,
3281 "Failed to enable trace logging");
3282 return NULL;
3283 }
3284 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003285
3286 ret = eap_register_methods();
3287 if (ret) {
3288 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3289 if (ret == -2)
3290 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3291 "the same EAP type.");
3292 return NULL;
3293 }
3294
3295 global = os_zalloc(sizeof(*global));
3296 if (global == NULL)
3297 return NULL;
3298 dl_list_init(&global->p2p_srv_bonjour);
3299 dl_list_init(&global->p2p_srv_upnp);
3300 global->params.daemonize = params->daemonize;
3301 global->params.wait_for_monitor = params->wait_for_monitor;
3302 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3303 if (params->pid_file)
3304 global->params.pid_file = os_strdup(params->pid_file);
3305 if (params->ctrl_interface)
3306 global->params.ctrl_interface =
3307 os_strdup(params->ctrl_interface);
3308 if (params->override_driver)
3309 global->params.override_driver =
3310 os_strdup(params->override_driver);
3311 if (params->override_ctrl_interface)
3312 global->params.override_ctrl_interface =
3313 os_strdup(params->override_ctrl_interface);
3314 wpa_debug_level = global->params.wpa_debug_level =
3315 params->wpa_debug_level;
3316 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3317 params->wpa_debug_show_keys;
3318 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3319 params->wpa_debug_timestamp;
3320
3321 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3322
3323 if (eloop_init()) {
3324 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3325 wpa_supplicant_deinit(global);
3326 return NULL;
3327 }
3328
Jouni Malinen75ecf522011-06-27 15:19:46 -07003329 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003330
3331 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3332 if (global->ctrl_iface == NULL) {
3333 wpa_supplicant_deinit(global);
3334 return NULL;
3335 }
3336
3337 if (wpas_notify_supplicant_initialized(global)) {
3338 wpa_supplicant_deinit(global);
3339 return NULL;
3340 }
3341
3342 for (i = 0; wpa_drivers[i]; i++)
3343 global->drv_count++;
3344 if (global->drv_count == 0) {
3345 wpa_printf(MSG_ERROR, "No drivers enabled");
3346 wpa_supplicant_deinit(global);
3347 return NULL;
3348 }
3349 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3350 if (global->drv_priv == NULL) {
3351 wpa_supplicant_deinit(global);
3352 return NULL;
3353 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003354
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003355#ifdef CONFIG_WIFI_DISPLAY
3356 if (wifi_display_init(global) < 0) {
3357 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3358 wpa_supplicant_deinit(global);
3359 return NULL;
3360 }
3361#endif /* CONFIG_WIFI_DISPLAY */
3362
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003363 return global;
3364}
3365
3366
3367/**
3368 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3369 * @global: Pointer to global data from wpa_supplicant_init()
3370 * Returns: 0 after successful event loop run, -1 on failure
3371 *
3372 * This function starts the main event loop and continues running as long as
3373 * there are any remaining events. In most cases, this function is running as
3374 * long as the %wpa_supplicant process in still in use.
3375 */
3376int wpa_supplicant_run(struct wpa_global *global)
3377{
3378 struct wpa_supplicant *wpa_s;
3379
3380 if (global->params.daemonize &&
3381 wpa_supplicant_daemon(global->params.pid_file))
3382 return -1;
3383
3384 if (global->params.wait_for_monitor) {
3385 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3386 if (wpa_s->ctrl_iface)
3387 wpa_supplicant_ctrl_iface_wait(
3388 wpa_s->ctrl_iface);
3389 }
3390
3391 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3392 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3393
3394 eloop_run();
3395
3396 return 0;
3397}
3398
3399
3400/**
3401 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3402 * @global: Pointer to global data from wpa_supplicant_init()
3403 *
3404 * This function is called to deinitialize %wpa_supplicant and to free all
3405 * allocated resources. Remaining network interfaces will also be removed.
3406 */
3407void wpa_supplicant_deinit(struct wpa_global *global)
3408{
3409 int i;
3410
3411 if (global == NULL)
3412 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003413
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003414#ifdef CONFIG_WIFI_DISPLAY
3415 wifi_display_deinit(global);
3416#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003417#ifdef CONFIG_P2P
3418 wpas_p2p_deinit_global(global);
3419#endif /* CONFIG_P2P */
3420
3421 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003422 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003423
3424 if (global->ctrl_iface)
3425 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3426
3427 wpas_notify_supplicant_deinitialized(global);
3428
3429 eap_peer_unregister_methods();
3430#ifdef CONFIG_AP
3431 eap_server_unregister_methods();
3432#endif /* CONFIG_AP */
3433
3434 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3435 if (!global->drv_priv[i])
3436 continue;
3437 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3438 }
3439 os_free(global->drv_priv);
3440
3441 random_deinit();
3442
3443 eloop_destroy();
3444
3445 if (global->params.pid_file) {
3446 os_daemonize_terminate(global->params.pid_file);
3447 os_free(global->params.pid_file);
3448 }
3449 os_free(global->params.ctrl_interface);
3450 os_free(global->params.override_driver);
3451 os_free(global->params.override_ctrl_interface);
3452
Dmitry Shmidt04949592012-07-19 12:16:46 -07003453 os_free(global->p2p_disallow_freq);
3454
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003455 os_free(global);
3456 wpa_debug_close_syslog();
3457 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003458 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003459}
3460
3461
3462void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3463{
3464 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3465 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3466 char country[3];
3467 country[0] = wpa_s->conf->country[0];
3468 country[1] = wpa_s->conf->country[1];
3469 country[2] = '\0';
3470 if (wpa_drv_set_country(wpa_s, country) < 0) {
3471 wpa_printf(MSG_ERROR, "Failed to set country code "
3472 "'%s'", country);
3473 }
3474 }
3475
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003476 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3477 wpas_init_ext_pw(wpa_s);
3478
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003479#ifdef CONFIG_WPS
3480 wpas_wps_update_config(wpa_s);
3481#endif /* CONFIG_WPS */
3482
3483#ifdef CONFIG_P2P
3484 wpas_p2p_update_config(wpa_s);
3485#endif /* CONFIG_P2P */
3486
3487 wpa_s->conf->changed_parameters = 0;
3488}
3489
3490
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003491static void add_freq(int *freqs, int *num_freqs, int freq)
3492{
3493 int i;
3494
3495 for (i = 0; i < *num_freqs; i++) {
3496 if (freqs[i] == freq)
3497 return;
3498 }
3499
3500 freqs[*num_freqs] = freq;
3501 (*num_freqs)++;
3502}
3503
3504
3505static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3506{
3507 struct wpa_bss *bss, *cbss;
3508 const int max_freqs = 10;
3509 int *freqs;
3510 int num_freqs = 0;
3511
3512 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3513 if (freqs == NULL)
3514 return NULL;
3515
3516 cbss = wpa_s->current_bss;
3517
3518 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3519 if (bss == cbss)
3520 continue;
3521 if (bss->ssid_len == cbss->ssid_len &&
3522 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3523 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3524 add_freq(freqs, &num_freqs, bss->freq);
3525 if (num_freqs == max_freqs)
3526 break;
3527 }
3528 }
3529
3530 if (num_freqs == 0) {
3531 os_free(freqs);
3532 freqs = NULL;
3533 }
3534
3535 return freqs;
3536}
3537
3538
3539void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3540{
3541 int timeout;
3542 int count;
3543 int *freqs = NULL;
3544
3545 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003546 * Remove possible authentication timeout since the connection failed.
3547 */
3548 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3549
Dmitry Shmidtea69e842013-05-13 14:52:28 -07003550 if (wpa_s->disconnected) {
3551 /*
3552 * There is no point in blacklisting the AP if this event is
3553 * generated based on local request to disconnect.
3554 */
3555 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
3556 "indication since interface has been put into "
3557 "disconnected state");
3558 return;
3559 }
3560
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003561 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003562 * Add the failed BSSID into the blacklist and speed up next scan
3563 * attempt if there could be other APs that could accept association.
3564 * The current blacklist count indicates how many times we have tried
3565 * connecting to this AP and multiple attempts mean that other APs are
3566 * either not available or has already been tried, so that we can start
3567 * increasing the delay here to avoid constant scanning.
3568 */
3569 count = wpa_blacklist_add(wpa_s, bssid);
3570 if (count == 1 && wpa_s->current_bss) {
3571 /*
3572 * This BSS was not in the blacklist before. If there is
3573 * another BSS available for the same ESS, we should try that
3574 * next. Otherwise, we may as well try this one once more
3575 * before allowing other, likely worse, ESSes to be considered.
3576 */
3577 freqs = get_bss_freqs_in_ess(wpa_s);
3578 if (freqs) {
3579 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3580 "has been seen; try it next");
3581 wpa_blacklist_add(wpa_s, bssid);
3582 /*
3583 * On the next scan, go through only the known channels
3584 * used in this ESS based on previous scans to speed up
3585 * common load balancing use case.
3586 */
3587 os_free(wpa_s->next_scan_freqs);
3588 wpa_s->next_scan_freqs = freqs;
3589 }
3590 }
3591
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003592 /*
3593 * Add previous failure count in case the temporary blacklist was
3594 * cleared due to no other BSSes being available.
3595 */
3596 count += wpa_s->extra_blacklist_count;
3597
Dmitry Shmidt4b060592013-04-29 16:42:49 -07003598 if (count > 3 && wpa_s->current_ssid) {
3599 wpa_printf(MSG_DEBUG, "Continuous association failures - "
3600 "consider temporary network disabling");
3601 wpas_auth_failed(wpa_s);
3602 }
3603
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003604 switch (count) {
3605 case 1:
3606 timeout = 100;
3607 break;
3608 case 2:
3609 timeout = 500;
3610 break;
3611 case 3:
3612 timeout = 1000;
3613 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003614 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003615 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003616 break;
3617 default:
3618 timeout = 10000;
3619 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003620 }
3621
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003622 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3623 "ms", count, timeout);
3624
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003625 /*
3626 * TODO: if more than one possible AP is available in scan results,
3627 * could try the other ones before requesting a new scan.
3628 */
3629 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3630 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003631
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -07003632 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003633}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003634
3635
3636int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3637{
3638 return wpa_s->conf->ap_scan == 2 ||
3639 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3640}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003641
Dmitry Shmidt04949592012-07-19 12:16:46 -07003642
3643#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3644int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3645 struct wpa_ssid *ssid,
3646 const char *field,
3647 const char *value)
3648{
3649#ifdef IEEE8021X_EAPOL
3650 struct eap_peer_config *eap = &ssid->eap;
3651
3652 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3653 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3654 (const u8 *) value, os_strlen(value));
3655
3656 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3657 case WPA_CTRL_REQ_EAP_IDENTITY:
3658 os_free(eap->identity);
3659 eap->identity = (u8 *) os_strdup(value);
3660 eap->identity_len = os_strlen(value);
3661 eap->pending_req_identity = 0;
3662 if (ssid == wpa_s->current_ssid)
3663 wpa_s->reassociate = 1;
3664 break;
3665 case WPA_CTRL_REQ_EAP_PASSWORD:
3666 os_free(eap->password);
3667 eap->password = (u8 *) os_strdup(value);
3668 eap->password_len = os_strlen(value);
3669 eap->pending_req_password = 0;
3670 if (ssid == wpa_s->current_ssid)
3671 wpa_s->reassociate = 1;
3672 break;
3673 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3674 os_free(eap->new_password);
3675 eap->new_password = (u8 *) os_strdup(value);
3676 eap->new_password_len = os_strlen(value);
3677 eap->pending_req_new_password = 0;
3678 if (ssid == wpa_s->current_ssid)
3679 wpa_s->reassociate = 1;
3680 break;
3681 case WPA_CTRL_REQ_EAP_PIN:
3682 os_free(eap->pin);
3683 eap->pin = os_strdup(value);
3684 eap->pending_req_pin = 0;
3685 if (ssid == wpa_s->current_ssid)
3686 wpa_s->reassociate = 1;
3687 break;
3688 case WPA_CTRL_REQ_EAP_OTP:
3689 os_free(eap->otp);
3690 eap->otp = (u8 *) os_strdup(value);
3691 eap->otp_len = os_strlen(value);
3692 os_free(eap->pending_req_otp);
3693 eap->pending_req_otp = NULL;
3694 eap->pending_req_otp_len = 0;
3695 break;
3696 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3697 os_free(eap->private_key_passwd);
3698 eap->private_key_passwd = (u8 *) os_strdup(value);
3699 eap->pending_req_passphrase = 0;
3700 if (ssid == wpa_s->current_ssid)
3701 wpa_s->reassociate = 1;
3702 break;
3703 default:
3704 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3705 return -1;
3706 }
3707
3708 return 0;
3709#else /* IEEE8021X_EAPOL */
3710 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3711 return -1;
3712#endif /* IEEE8021X_EAPOL */
3713}
3714#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3715
3716
3717int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3718{
3719 int i;
3720 unsigned int drv_enc;
3721
3722 if (ssid == NULL)
3723 return 1;
3724
3725 if (ssid->disabled)
3726 return 1;
3727
3728 if (wpa_s && wpa_s->drv_capa_known)
3729 drv_enc = wpa_s->drv_enc;
3730 else
3731 drv_enc = (unsigned int) -1;
3732
3733 for (i = 0; i < NUM_WEP_KEYS; i++) {
3734 size_t len = ssid->wep_key_len[i];
3735 if (len == 0)
3736 continue;
3737 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3738 continue;
3739 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3740 continue;
3741 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3742 continue;
3743 return 1; /* invalid WEP key */
3744 }
3745
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003746 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3747 !ssid->ext_psk)
3748 return 1;
3749
Dmitry Shmidt04949592012-07-19 12:16:46 -07003750 return 0;
3751}
3752
3753
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003754int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003755{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003756 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003757 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003758 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003759 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003760 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003761}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003762
3763
3764void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3765{
3766 struct wpa_ssid *ssid = wpa_s->current_ssid;
3767 int dur;
3768 struct os_time now;
3769
3770 if (ssid == NULL) {
3771 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3772 "SSID block");
3773 return;
3774 }
3775
3776 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3777 return;
3778
3779 ssid->auth_failures++;
3780 if (ssid->auth_failures > 50)
3781 dur = 300;
3782 else if (ssid->auth_failures > 20)
3783 dur = 120;
3784 else if (ssid->auth_failures > 10)
3785 dur = 60;
3786 else if (ssid->auth_failures > 5)
3787 dur = 30;
3788 else if (ssid->auth_failures > 1)
3789 dur = 20;
3790 else
3791 dur = 10;
3792
3793 os_get_time(&now);
3794 if (now.sec + dur <= ssid->disabled_until.sec)
3795 return;
3796
3797 ssid->disabled_until.sec = now.sec + dur;
3798
3799 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3800 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3801 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3802 ssid->auth_failures, dur);
3803}
3804
3805
3806void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3807 struct wpa_ssid *ssid, int clear_failures)
3808{
3809 if (ssid == NULL)
3810 return;
3811
3812 if (ssid->disabled_until.sec) {
3813 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3814 "id=%d ssid=\"%s\"",
3815 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3816 }
3817 ssid->disabled_until.sec = 0;
3818 ssid->disabled_until.usec = 0;
3819 if (clear_failures)
3820 ssid->auth_failures = 0;
3821}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003822
3823
3824int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3825{
3826 size_t i;
3827
3828 if (wpa_s->disallow_aps_bssid == NULL)
3829 return 0;
3830
3831 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3832 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3833 bssid, ETH_ALEN) == 0)
3834 return 1;
3835 }
3836
3837 return 0;
3838}
3839
3840
3841int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3842 size_t ssid_len)
3843{
3844 size_t i;
3845
3846 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3847 return 0;
3848
3849 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3850 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3851 if (ssid_len == s->ssid_len &&
3852 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3853 return 1;
3854 }
3855
3856 return 0;
3857}
3858
3859
3860/**
3861 * wpas_request_connection - Request a new connection
3862 * @wpa_s: Pointer to the network interface
3863 *
3864 * This function is used to request a new connection to be found. It will mark
3865 * the interface to allow reassociation and request a new scan to find a
3866 * suitable network to connect to.
3867 */
3868void wpas_request_connection(struct wpa_supplicant *wpa_s)
3869{
3870 wpa_s->normal_scans = 0;
3871 wpa_supplicant_reinit_autoscan(wpa_s);
3872 wpa_s->extra_blacklist_count = 0;
3873 wpa_s->disconnected = 0;
3874 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003875
3876 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3877 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003878}
Dmitry Shmidtea69e842013-05-13 14:52:28 -07003879
3880
3881/**
3882 * wpas_wpa_is_in_progress - Check whether a connection is in progress
3883 * @wpa_s: Pointer to wpa_supplicant data
3884 *
3885 * This function is to check if the wpa state is in beginning of the connection
3886 * during 4-way handshake or group key handshake with WPA on any shared
3887 * interface.
3888 */
3889int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s)
3890{
3891 const char *rn, *rn2;
3892 struct wpa_supplicant *ifs;
3893
3894 if (!wpa_s->driver->get_radio_name)
3895 return 0;
3896
3897 rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
3898 if (rn == NULL || rn[0] == '\0')
3899 return 0;
3900
3901 for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
3902 if (ifs == wpa_s || !ifs->driver->get_radio_name)
3903 continue;
3904
3905 rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
3906 if (!rn2 || os_strcmp(rn, rn2) != 0)
3907 continue;
3908 if (ifs->wpa_state >= WPA_AUTHENTICATING &&
3909 ifs->wpa_state != WPA_COMPLETED) {
3910 wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress "
3911 "on interface %s - defer scan", ifs->ifname);
3912 return 1;
3913 }
3914 }
3915
3916 return 0;
3917}