blob: 4ef94086dcdbb96eaad26120a6056d9d8a9b6fe1 [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
129static int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
130 struct wpa_ssid *ssid)
131{
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;
1274 struct wpa_driver_capa capa;
1275 int assoc_failed = 0;
1276 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001277 u8 ext_capab[10];
1278 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001279#ifdef CONFIG_HT_OVERRIDES
1280 struct ieee80211_ht_capabilities htcaps;
1281 struct ieee80211_ht_capabilities htcaps_mask;
1282#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001283
1284#ifdef CONFIG_IBSS_RSN
1285 ibss_rsn_deinit(wpa_s->ibss_rsn);
1286 wpa_s->ibss_rsn = NULL;
1287#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001288#ifdef ANDROID_P2P
1289 int freq = 0;
1290#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001291
1292 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1293 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1294#ifdef CONFIG_AP
1295 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1296 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1297 "mode");
1298 return;
1299 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001300 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1301 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1302 return;
1303 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001304 wpa_s->current_bss = bss;
1305#else /* CONFIG_AP */
1306 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1307 "the build");
1308#endif /* CONFIG_AP */
1309 return;
1310 }
1311
1312#ifdef CONFIG_TDLS
1313 if (bss)
1314 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1315 bss->ie_len);
1316#endif /* CONFIG_TDLS */
1317
1318 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1319 ssid->mode == IEEE80211_MODE_INFRA) {
1320 sme_authenticate(wpa_s, bss, ssid);
1321 return;
1322 }
1323
1324 os_memset(&params, 0, sizeof(params));
1325 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001326 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001327#ifdef CONFIG_IEEE80211R
1328 const u8 *ie, *md = NULL;
1329#endif /* CONFIG_IEEE80211R */
1330 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1331 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1332 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1333 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1334 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1335 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1336 if (bssid_changed)
1337 wpas_notify_bssid_changed(wpa_s);
1338#ifdef CONFIG_IEEE80211R
1339 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1340 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1341 md = ie + 2;
1342 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1343 if (md) {
1344 /* Prepare for the next transition */
1345 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1346 }
1347#endif /* CONFIG_IEEE80211R */
1348#ifdef CONFIG_WPS
1349 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1350 wpa_s->conf->ap_scan == 2 &&
1351 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1352 /* Use ap_scan==1 style network selection to find the network
1353 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001354 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001355 wpa_s->reassociate = 1;
1356 wpa_supplicant_req_scan(wpa_s, 0, 0);
1357 return;
1358#endif /* CONFIG_WPS */
1359 } else {
1360 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1361 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1362 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1363 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001364 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001365 wpa_supplicant_cancel_scan(wpa_s);
1366
1367 /* Starting new association, so clear the possibly used WPA IE from the
1368 * previous association. */
1369 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1370
1371#ifdef IEEE8021X_EAPOL
1372 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1373 if (ssid->leap) {
1374 if (ssid->non_leap == 0)
1375 algs = WPA_AUTH_ALG_LEAP;
1376 else
1377 algs |= WPA_AUTH_ALG_LEAP;
1378 }
1379 }
1380#endif /* IEEE8021X_EAPOL */
1381 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1382 if (ssid->auth_alg) {
1383 algs = ssid->auth_alg;
1384 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1385 "0x%x", algs);
1386 }
1387
1388 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1389 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001390 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001391 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001392 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1393 wpa_s->conf->okc :
1394 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001395 (ssid->proto & WPA_PROTO_RSN);
1396 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001397 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001398 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1399 wpa_ie_len = sizeof(wpa_ie);
1400 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1401 wpa_ie, &wpa_ie_len)) {
1402 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1403 "key management and encryption suites");
1404 return;
1405 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001406 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1407 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1408 /*
1409 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1410 * use non-WPA since the scan results did not indicate that the
1411 * AP is using WPA or WPA2.
1412 */
1413 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1414 wpa_ie_len = 0;
1415 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001416 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001417 wpa_ie_len = sizeof(wpa_ie);
1418 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1419 wpa_ie, &wpa_ie_len)) {
1420 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1421 "key management and encryption suites (no "
1422 "scan results)");
1423 return;
1424 }
1425#ifdef CONFIG_WPS
1426 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1427 struct wpabuf *wps_ie;
1428 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1429 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1430 wpa_ie_len = wpabuf_len(wps_ie);
1431 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1432 } else
1433 wpa_ie_len = 0;
1434 wpabuf_free(wps_ie);
1435 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1436 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1437 params.wps = WPS_MODE_PRIVACY;
1438 else
1439 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001440 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001441#endif /* CONFIG_WPS */
1442 } else {
1443 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1444 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001445 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001446 }
1447
1448#ifdef CONFIG_P2P
1449 if (wpa_s->global->p2p) {
1450 u8 *pos;
1451 size_t len;
1452 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001453 pos = wpa_ie + wpa_ie_len;
1454 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001455 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1456 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001457 if (res >= 0)
1458 wpa_ie_len += res;
1459 }
1460
1461 wpa_s->cross_connect_disallowed = 0;
1462 if (bss) {
1463 struct wpabuf *p2p;
1464 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1465 if (p2p) {
1466 wpa_s->cross_connect_disallowed =
1467 p2p_get_cross_connect_disallowed(p2p);
1468 wpabuf_free(p2p);
1469 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1470 "connection",
1471 wpa_s->cross_connect_disallowed ?
1472 "disallows" : "allows");
1473 }
1474 }
1475#endif /* CONFIG_P2P */
1476
Dmitry Shmidt04949592012-07-19 12:16:46 -07001477#ifdef CONFIG_HS20
1478 if (wpa_s->conf->hs20) {
1479 struct wpabuf *hs20;
1480 hs20 = wpabuf_alloc(20);
1481 if (hs20) {
1482 wpas_hs20_add_indication(hs20);
1483 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1484 wpabuf_len(hs20));
1485 wpa_ie_len += wpabuf_len(hs20);
1486 wpabuf_free(hs20);
1487 }
1488 }
1489#endif /* CONFIG_HS20 */
1490
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001491 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1492 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001493 u8 *pos = wpa_ie;
1494 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1495 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001496 os_memmove(pos + ext_capab_len, pos,
1497 wpa_ie_len - (pos - wpa_ie));
1498 wpa_ie_len += ext_capab_len;
1499 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001500 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001501
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001502 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1503 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001504 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1505 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001506 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1507 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1508 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1509 use_crypt = 0;
1510 if (wpa_set_wep_keys(wpa_s, ssid)) {
1511 use_crypt = 1;
1512 wep_keys_set = 1;
1513 }
1514 }
1515 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1516 use_crypt = 0;
1517
1518#ifdef IEEE8021X_EAPOL
1519 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1520 if ((ssid->eapol_flags &
1521 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1522 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1523 !wep_keys_set) {
1524 use_crypt = 0;
1525 } else {
1526 /* Assume that dynamic WEP-104 keys will be used and
1527 * set cipher suites in order for drivers to expect
1528 * encryption. */
1529 cipher_pairwise = cipher_group = CIPHER_WEP104;
1530 }
1531 }
1532#endif /* IEEE8021X_EAPOL */
1533
1534 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1535 /* Set the key before (and later after) association */
1536 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1537 }
1538
1539 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1540 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001541 params.ssid = bss->ssid;
1542 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001543 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1544 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1545 MACSTR " freq=%u MHz based on scan results "
1546 "(bssid_set=%d)",
1547 MAC2STR(bss->bssid), bss->freq,
1548 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001549 params.bssid = bss->bssid;
1550 params.freq = bss->freq;
1551 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001552 } else {
1553 params.ssid = ssid->ssid;
1554 params.ssid_len = ssid->ssid_len;
1555 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001556
1557 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1558 wpa_s->conf->ap_scan == 2) {
1559 params.bssid = ssid->bssid;
1560 params.fixed_bssid = 1;
1561 }
1562
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001563 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1564 params.freq == 0)
1565 params.freq = ssid->frequency; /* Initial channel for IBSS */
1566 params.wpa_ie = wpa_ie;
1567 params.wpa_ie_len = wpa_ie_len;
1568 params.pairwise_suite = cipher_pairwise;
1569 params.group_suite = cipher_group;
1570 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001571 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001572 params.auth_alg = algs;
1573 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001574 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001575 for (i = 0; i < NUM_WEP_KEYS; i++) {
1576 if (ssid->wep_key_len[i])
1577 params.wep_key[i] = ssid->wep_key[i];
1578 params.wep_key_len[i] = ssid->wep_key_len[i];
1579 }
1580 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1581
1582 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1583 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1584 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1585 params.passphrase = ssid->passphrase;
1586 if (ssid->psk_set)
1587 params.psk = ssid->psk;
1588 }
1589
1590 params.drop_unencrypted = use_crypt;
1591
1592#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001593 params.mgmt_frame_protection =
1594 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1595 wpa_s->conf->pmf : ssid->ieee80211w;
1596 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001597 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1598 struct wpa_ie_data ie;
1599 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1600 ie.capabilities &
1601 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1602 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1603 "MFP: require MFP");
1604 params.mgmt_frame_protection =
1605 MGMT_FRAME_PROTECTION_REQUIRED;
1606 }
1607 }
1608#endif /* CONFIG_IEEE80211W */
1609
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001610 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001611
1612 if (wpa_s->parent->set_sta_uapsd)
1613 params.uapsd = wpa_s->parent->sta_uapsd;
1614 else
1615 params.uapsd = -1;
1616
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001617#ifdef CONFIG_HT_OVERRIDES
1618 os_memset(&htcaps, 0, sizeof(htcaps));
1619 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1620 params.htcaps = (u8 *) &htcaps;
1621 params.htcaps_mask = (u8 *) &htcaps_mask;
1622 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1623#endif /* CONFIG_HT_OVERRIDES */
1624
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001625#ifdef ANDROID_P2P
1626 /* If multichannel concurrency is not supported, check for any frequency
1627 * conflict and take appropriate action.
1628 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001629 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1630 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1631 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001632 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001633 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001634 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001635 }
1636#endif
1637 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001638 if (ret < 0) {
1639 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1640 "failed");
1641 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1642 /*
1643 * The driver is known to mean what is saying, so we
1644 * can stop right here; the association will not
1645 * succeed.
1646 */
1647 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001648 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001649 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1650 return;
1651 }
1652 /* try to continue anyway; new association will be tried again
1653 * after timeout */
1654 assoc_failed = 1;
1655 }
1656
1657 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1658 /* Set the key after the association just in case association
1659 * cleared the previously configured key. */
1660 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1661 /* No need to timeout authentication since there is no key
1662 * management. */
1663 wpa_supplicant_cancel_auth_timeout(wpa_s);
1664 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1665#ifdef CONFIG_IBSS_RSN
1666 } else if (ssid->mode == WPAS_MODE_IBSS &&
1667 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1668 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1669 /*
1670 * RSN IBSS authentication is per-STA and we can disable the
1671 * per-BSSID authentication.
1672 */
1673 wpa_supplicant_cancel_auth_timeout(wpa_s);
1674#endif /* CONFIG_IBSS_RSN */
1675 } else {
1676 /* Timeout for IEEE 802.11 authentication and association */
1677 int timeout = 60;
1678
1679 if (assoc_failed) {
1680 /* give IBSS a bit more time */
1681 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1682 } else if (wpa_s->conf->ap_scan == 1) {
1683 /* give IBSS a bit more time */
1684 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1685 }
1686 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1687 }
1688
1689 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1690 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1691 /* Set static WEP keys again */
1692 wpa_set_wep_keys(wpa_s, ssid);
1693 }
1694
1695 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1696 /*
1697 * Do not allow EAP session resumption between different
1698 * network configurations.
1699 */
1700 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1701 }
1702 old_ssid = wpa_s->current_ssid;
1703 wpa_s->current_ssid = ssid;
1704 wpa_s->current_bss = bss;
1705 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1706 wpa_supplicant_initiate_eapol(wpa_s);
1707 if (old_ssid != wpa_s->current_ssid)
1708 wpas_notify_network_changed(wpa_s);
1709}
1710
1711
1712static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1713 const u8 *addr)
1714{
1715 struct wpa_ssid *old_ssid;
1716
1717 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001718 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001719 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001720 wpa_sm_set_config(wpa_s->wpa, NULL);
1721 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1722 if (old_ssid != wpa_s->current_ssid)
1723 wpas_notify_network_changed(wpa_s);
1724 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1725}
1726
1727
1728/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001729 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1730 * @wpa_s: Pointer to wpa_supplicant data
1731 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1732 *
1733 * This function is used to request %wpa_supplicant to deauthenticate from the
1734 * current AP.
1735 */
1736void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1737 int reason_code)
1738{
1739 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001740 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001741 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001742
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001743 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1744 " pending_bssid=" MACSTR " reason=%d state=%s",
1745 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1746 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1747
1748 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001749 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001750 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1751 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1752 wpa_s->wpa_state == WPA_ASSOCIATING))
1753 addr = wpa_s->pending_bssid;
1754 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1755 /*
1756 * When using driver-based BSS selection, we may not know the
1757 * BSSID with which we are currently trying to associate. We
1758 * need to notify the driver of this disconnection even in such
1759 * a case, so use the all zeros address here.
1760 */
1761 addr = wpa_s->bssid;
1762 zero_addr = 1;
1763 }
1764
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001765#ifdef CONFIG_TDLS
1766 wpa_tdls_teardown_peers(wpa_s->wpa);
1767#endif /* CONFIG_TDLS */
1768
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001769 if (addr) {
1770 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001771 os_memset(&event, 0, sizeof(event));
1772 event.deauth_info.reason_code = (u16) reason_code;
1773 event.deauth_info.locally_generated = 1;
1774 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001775 if (zero_addr)
1776 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001777 }
1778
1779 wpa_supplicant_clear_connection(wpa_s, addr);
1780}
1781
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001782static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1783 struct wpa_ssid *ssid)
1784{
1785 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1786 return;
1787
1788 ssid->disabled = 0;
1789 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1790 wpas_notify_network_enabled_changed(wpa_s, ssid);
1791
1792 /*
1793 * Try to reassociate since there is no current configuration and a new
1794 * network was made available.
1795 */
1796 if (!wpa_s->current_ssid)
1797 wpa_s->reassociate = 1;
1798}
1799
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001800
1801/**
1802 * wpa_supplicant_enable_network - Mark a configured network as enabled
1803 * @wpa_s: wpa_supplicant structure for a network interface
1804 * @ssid: wpa_ssid structure for a configured network or %NULL
1805 *
1806 * Enables the specified network or all networks if no network specified.
1807 */
1808void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1809 struct wpa_ssid *ssid)
1810{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001811 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001812 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1813 wpa_supplicant_enable_one_network(wpa_s, ssid);
1814 } else
1815 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001816
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001817 if (wpa_s->reassociate) {
1818 if (wpa_s->sched_scanning) {
1819 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1820 "new network to scan filters");
1821 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001822 }
1823
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001824 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001825 }
1826}
1827
1828
1829/**
1830 * wpa_supplicant_disable_network - Mark a configured network as disabled
1831 * @wpa_s: wpa_supplicant structure for a network interface
1832 * @ssid: wpa_ssid structure for a configured network or %NULL
1833 *
1834 * Disables the specified network or all networks if no network specified.
1835 */
1836void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1837 struct wpa_ssid *ssid)
1838{
1839 struct wpa_ssid *other_ssid;
1840 int was_disabled;
1841
1842 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001843 if (wpa_s->sched_scanning)
1844 wpa_supplicant_cancel_sched_scan(wpa_s);
1845
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001846 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1847 other_ssid = other_ssid->next) {
1848 was_disabled = other_ssid->disabled;
1849 if (was_disabled == 2)
1850 continue; /* do not change persistent P2P group
1851 * data */
1852
1853 other_ssid->disabled = 1;
1854
1855 if (was_disabled != other_ssid->disabled)
1856 wpas_notify_network_enabled_changed(
1857 wpa_s, other_ssid);
1858 }
1859 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001860 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001861 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1862 } else if (ssid->disabled != 2) {
1863 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001864 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001865 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1866
1867 was_disabled = ssid->disabled;
1868
1869 ssid->disabled = 1;
1870
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001871 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001872 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001873 if (wpa_s->sched_scanning) {
1874 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1875 "to remove network from filters");
1876 wpa_supplicant_cancel_sched_scan(wpa_s);
1877 wpa_supplicant_req_scan(wpa_s, 0, 0);
1878 }
1879 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001880 }
1881}
1882
1883
1884/**
1885 * wpa_supplicant_select_network - Attempt association with a network
1886 * @wpa_s: wpa_supplicant structure for a network interface
1887 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1888 */
1889void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1890 struct wpa_ssid *ssid)
1891{
1892
1893 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001894 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001895
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001896 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001897 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001898 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001899 disconnected = 1;
1900 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001901
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001902 if (ssid)
1903 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1904
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001905 /*
1906 * Mark all other networks disabled or mark all networks enabled if no
1907 * network specified.
1908 */
1909 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1910 other_ssid = other_ssid->next) {
1911 int was_disabled = other_ssid->disabled;
1912 if (was_disabled == 2)
1913 continue; /* do not change persistent P2P group data */
1914
1915 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001916 if (was_disabled && !other_ssid->disabled)
1917 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001918
1919 if (was_disabled != other_ssid->disabled)
1920 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1921 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001922
1923 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1924 /* We are already associated with the selected network */
1925 wpa_printf(MSG_DEBUG, "Already associated with the "
1926 "selected network - do nothing");
1927 return;
1928 }
1929
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001930 if (ssid)
1931 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001932 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001933 wpa_s->disconnected = 0;
1934 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001935
1936 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1937 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001938
1939 if (ssid)
1940 wpas_notify_network_selected(wpa_s, ssid);
1941}
1942
1943
1944/**
1945 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1946 * @wpa_s: wpa_supplicant structure for a network interface
1947 * @ap_scan: AP scan mode
1948 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1949 *
1950 */
1951int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1952{
1953
1954 int old_ap_scan;
1955
1956 if (ap_scan < 0 || ap_scan > 2)
1957 return -1;
1958
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001959#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001960 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1961 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1962 wpa_s->wpa_state < WPA_COMPLETED) {
1963 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1964 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001965 return 0;
1966 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001967#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001968
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001969 old_ap_scan = wpa_s->conf->ap_scan;
1970 wpa_s->conf->ap_scan = ap_scan;
1971
1972 if (old_ap_scan != wpa_s->conf->ap_scan)
1973 wpas_notify_ap_scan_changed(wpa_s);
1974
1975 return 0;
1976}
1977
1978
1979/**
1980 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1981 * @wpa_s: wpa_supplicant structure for a network interface
1982 * @expire_age: Expiration age in seconds
1983 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1984 *
1985 */
1986int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1987 unsigned int bss_expire_age)
1988{
1989 if (bss_expire_age < 10) {
1990 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1991 bss_expire_age);
1992 return -1;
1993 }
1994 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1995 bss_expire_age);
1996 wpa_s->conf->bss_expiration_age = bss_expire_age;
1997
1998 return 0;
1999}
2000
2001
2002/**
2003 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2004 * @wpa_s: wpa_supplicant structure for a network interface
2005 * @expire_count: number of scans after which an unseen BSS is reclaimed
2006 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2007 *
2008 */
2009int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2010 unsigned int bss_expire_count)
2011{
2012 if (bss_expire_count < 1) {
2013 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2014 bss_expire_count);
2015 return -1;
2016 }
2017 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2018 bss_expire_count);
2019 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2020
2021 return 0;
2022}
2023
2024
2025/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07002026 * wpa_supplicant_set_scan_interval - Set scan interval
2027 * @wpa_s: wpa_supplicant structure for a network interface
2028 * @scan_interval: scan interval in seconds
2029 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2030 *
2031 */
2032int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2033 int scan_interval)
2034{
2035 if (scan_interval < 0) {
2036 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2037 scan_interval);
2038 return -1;
2039 }
2040 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2041 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002042 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002043
2044 return 0;
2045}
2046
2047
2048/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002049 * wpa_supplicant_set_debug_params - Set global debug params
2050 * @global: wpa_global structure
2051 * @debug_level: debug level
2052 * @debug_timestamp: determines if show timestamp in debug data
2053 * @debug_show_keys: determines if show keys in debug data
2054 * Returns: 0 if succeed or -1 if debug_level has wrong value
2055 */
2056int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2057 int debug_timestamp, int debug_show_keys)
2058{
2059
2060 int old_level, old_timestamp, old_show_keys;
2061
2062 /* check for allowed debuglevels */
2063 if (debug_level != MSG_EXCESSIVE &&
2064 debug_level != MSG_MSGDUMP &&
2065 debug_level != MSG_DEBUG &&
2066 debug_level != MSG_INFO &&
2067 debug_level != MSG_WARNING &&
2068 debug_level != MSG_ERROR)
2069 return -1;
2070
2071 old_level = wpa_debug_level;
2072 old_timestamp = wpa_debug_timestamp;
2073 old_show_keys = wpa_debug_show_keys;
2074
2075 wpa_debug_level = debug_level;
2076 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2077 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2078
2079 if (wpa_debug_level != old_level)
2080 wpas_notify_debug_level_changed(global);
2081 if (wpa_debug_timestamp != old_timestamp)
2082 wpas_notify_debug_timestamp_changed(global);
2083 if (wpa_debug_show_keys != old_show_keys)
2084 wpas_notify_debug_show_keys_changed(global);
2085
2086 return 0;
2087}
2088
2089
2090/**
2091 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2092 * @wpa_s: Pointer to wpa_supplicant data
2093 * Returns: A pointer to the current network structure or %NULL on failure
2094 */
2095struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2096{
2097 struct wpa_ssid *entry;
2098 u8 ssid[MAX_SSID_LEN];
2099 int res;
2100 size_t ssid_len;
2101 u8 bssid[ETH_ALEN];
2102 int wired;
2103
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002104 res = wpa_drv_get_ssid(wpa_s, ssid);
2105 if (res < 0) {
2106 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2107 "driver");
2108 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002109 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002110 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002111
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002112 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002113 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2114 "driver");
2115 return NULL;
2116 }
2117
2118 wired = wpa_s->conf->ap_scan == 0 &&
2119 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2120
2121 entry = wpa_s->conf->ssid;
2122 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002123 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002124 ((ssid_len == entry->ssid_len &&
2125 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2126 (!entry->bssid_set ||
2127 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2128 return entry;
2129#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002130 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002131 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2132 (entry->ssid == NULL || entry->ssid_len == 0) &&
2133 (!entry->bssid_set ||
2134 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2135 return entry;
2136#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002137
Dmitry Shmidt04949592012-07-19 12:16:46 -07002138 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002139 entry->ssid_len == 0 &&
2140 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2141 return entry;
2142
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002143 entry = entry->next;
2144 }
2145
2146 return NULL;
2147}
2148
2149
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002150static int select_driver(struct wpa_supplicant *wpa_s, int i)
2151{
2152 struct wpa_global *global = wpa_s->global;
2153
2154 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2155 global->drv_priv[i] = wpa_drivers[i]->global_init();
2156 if (global->drv_priv[i] == NULL) {
2157 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2158 "'%s'", wpa_drivers[i]->name);
2159 return -1;
2160 }
2161 }
2162
2163 wpa_s->driver = wpa_drivers[i];
2164 wpa_s->global_drv_priv = global->drv_priv[i];
2165
2166 return 0;
2167}
2168
2169
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002170static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2171 const char *name)
2172{
2173 int i;
2174 size_t len;
2175 const char *pos, *driver = name;
2176
2177 if (wpa_s == NULL)
2178 return -1;
2179
2180 if (wpa_drivers[0] == NULL) {
2181 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2182 "wpa_supplicant");
2183 return -1;
2184 }
2185
2186 if (name == NULL) {
2187 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002188 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002189 }
2190
2191 do {
2192 pos = os_strchr(driver, ',');
2193 if (pos)
2194 len = pos - driver;
2195 else
2196 len = os_strlen(driver);
2197
2198 for (i = 0; wpa_drivers[i]; i++) {
2199 if (os_strlen(wpa_drivers[i]->name) == len &&
2200 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002201 0) {
2202 /* First driver that succeeds wins */
2203 if (select_driver(wpa_s, i) == 0)
2204 return 0;
2205 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002206 }
2207
2208 driver = pos + 1;
2209 } while (pos);
2210
2211 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2212 return -1;
2213}
2214
2215
2216/**
2217 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2218 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2219 * with struct wpa_driver_ops::init()
2220 * @src_addr: Source address of the EAPOL frame
2221 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2222 * @len: Length of the EAPOL data
2223 *
2224 * This function is called for each received EAPOL frame. Most driver
2225 * interfaces rely on more generic OS mechanism for receiving frames through
2226 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2227 * take care of received EAPOL frames and deliver them to the core supplicant
2228 * code by calling this function.
2229 */
2230void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2231 const u8 *buf, size_t len)
2232{
2233 struct wpa_supplicant *wpa_s = ctx;
2234
2235 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2236 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2237
Jouni Malinena05074c2012-12-21 21:35:35 +02002238 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2239 (wpa_s->last_eapol_matches_bssid &&
2240#ifdef CONFIG_AP
2241 !wpa_s->ap_iface &&
2242#endif /* CONFIG_AP */
2243 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002244 /*
2245 * There is possible race condition between receiving the
2246 * association event and the EAPOL frame since they are coming
2247 * through different paths from the driver. In order to avoid
2248 * issues in trying to process the EAPOL frame before receiving
2249 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002250 * the association event is received. This may also be needed in
2251 * driver-based roaming case, so also use src_addr != BSSID as a
2252 * trigger if we have previously confirmed that the
2253 * Authenticator uses BSSID as the src_addr (which is not the
2254 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002255 */
2256 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002257 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2258 wpa_supplicant_state_txt(wpa_s->wpa_state),
2259 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002260 wpabuf_free(wpa_s->pending_eapol_rx);
2261 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2262 if (wpa_s->pending_eapol_rx) {
2263 os_get_time(&wpa_s->pending_eapol_rx_time);
2264 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2265 ETH_ALEN);
2266 }
2267 return;
2268 }
2269
Jouni Malinena05074c2012-12-21 21:35:35 +02002270 wpa_s->last_eapol_matches_bssid =
2271 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2272
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002273#ifdef CONFIG_AP
2274 if (wpa_s->ap_iface) {
2275 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2276 return;
2277 }
2278#endif /* CONFIG_AP */
2279
2280 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2281 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2282 "no key management is configured");
2283 return;
2284 }
2285
2286 if (wpa_s->eapol_received == 0 &&
2287 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2288 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2289 wpa_s->wpa_state != WPA_COMPLETED) &&
2290 (wpa_s->current_ssid == NULL ||
2291 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2292 /* Timeout for completing IEEE 802.1X and WPA authentication */
2293 wpa_supplicant_req_auth_timeout(
2294 wpa_s,
2295 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2296 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2297 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2298 70 : 10, 0);
2299 }
2300 wpa_s->eapol_received++;
2301
2302 if (wpa_s->countermeasures) {
2303 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2304 "EAPOL packet");
2305 return;
2306 }
2307
2308#ifdef CONFIG_IBSS_RSN
2309 if (wpa_s->current_ssid &&
2310 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2311 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2312 return;
2313 }
2314#endif /* CONFIG_IBSS_RSN */
2315
2316 /* Source address of the incoming EAPOL frame could be compared to the
2317 * current BSSID. However, it is possible that a centralized
2318 * Authenticator could be using another MAC address than the BSSID of
2319 * an AP, so just allow any address to be used for now. The replies are
2320 * still sent to the current BSSID (if available), though. */
2321
2322 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2323 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2324 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2325 return;
2326 wpa_drv_poll(wpa_s);
2327 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2328 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2329 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2330 /*
2331 * Set portValid = TRUE here since we are going to skip 4-way
2332 * handshake processing which would normally set portValid. We
2333 * need this to allow the EAPOL state machines to be completed
2334 * without going through EAPOL-Key handshake.
2335 */
2336 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2337 }
2338}
2339
2340
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002341int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002342{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002343 if (wpa_s->driver->send_eapol) {
2344 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2345 if (addr)
2346 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2347 } else if (!(wpa_s->drv_flags &
2348 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002349 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002350 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2351 wpa_drv_get_mac_addr(wpa_s),
2352 ETH_P_EAPOL,
2353 wpa_supplicant_rx_eapol, wpa_s, 0);
2354 if (wpa_s->l2 == NULL)
2355 return -1;
2356 } else {
2357 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2358 if (addr)
2359 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2360 }
2361
2362 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2363 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2364 return -1;
2365 }
2366
2367 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2368 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002369 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2370
2371 return 0;
2372}
2373
2374
Dmitry Shmidt04949592012-07-19 12:16:46 -07002375static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2376 const u8 *buf, size_t len)
2377{
2378 struct wpa_supplicant *wpa_s = ctx;
2379 const struct l2_ethhdr *eth;
2380
2381 if (len < sizeof(*eth))
2382 return;
2383 eth = (const struct l2_ethhdr *) buf;
2384
2385 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2386 !(eth->h_dest[0] & 0x01)) {
2387 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2388 " (bridge - not for this interface - ignore)",
2389 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2390 return;
2391 }
2392
2393 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2394 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2395 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2396 len - sizeof(*eth));
2397}
2398
2399
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002400/**
2401 * wpa_supplicant_driver_init - Initialize driver interface parameters
2402 * @wpa_s: Pointer to wpa_supplicant data
2403 * Returns: 0 on success, -1 on failure
2404 *
2405 * This function is called to initialize driver interface parameters.
2406 * wpa_drv_init() must have been called before this function to initialize the
2407 * driver interface.
2408 */
2409int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2410{
2411 static int interface_count = 0;
2412
2413 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2414 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002415
2416 if (wpa_s->bridge_ifname[0]) {
2417 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2418 "interface '%s'", wpa_s->bridge_ifname);
2419 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2420 wpa_s->own_addr,
2421 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002422 wpa_supplicant_rx_eapol_bridge,
2423 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002424 if (wpa_s->l2_br == NULL) {
2425 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2426 "connection for the bridge interface '%s'",
2427 wpa_s->bridge_ifname);
2428 return -1;
2429 }
2430 }
2431
2432 wpa_clear_keys(wpa_s, NULL);
2433
2434 /* Make sure that TKIP countermeasures are not left enabled (could
2435 * happen if wpa_supplicant is killed during countermeasures. */
2436 wpa_drv_set_countermeasures(wpa_s, 0);
2437
2438 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2439 wpa_drv_flush_pmkid(wpa_s);
2440
2441 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002442 wpa_s->prev_scan_wildcard = 0;
2443
Dmitry Shmidt04949592012-07-19 12:16:46 -07002444 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002445 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2446 100000))
2447 wpa_supplicant_req_scan(wpa_s, interface_count,
2448 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002449 interface_count++;
2450 } else
2451 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2452
2453 return 0;
2454}
2455
2456
2457static int wpa_supplicant_daemon(const char *pid_file)
2458{
2459 wpa_printf(MSG_DEBUG, "Daemonize..");
2460 return os_daemonize(pid_file);
2461}
2462
2463
2464static struct wpa_supplicant * wpa_supplicant_alloc(void)
2465{
2466 struct wpa_supplicant *wpa_s;
2467
2468 wpa_s = os_zalloc(sizeof(*wpa_s));
2469 if (wpa_s == NULL)
2470 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002471 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002472 wpa_s->scan_interval = 5;
2473 wpa_s->new_connection = 1;
2474 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002475 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002476
2477 return wpa_s;
2478}
2479
2480
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002481#ifdef CONFIG_HT_OVERRIDES
2482
2483static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2484 struct ieee80211_ht_capabilities *htcaps,
2485 struct ieee80211_ht_capabilities *htcaps_mask,
2486 const char *ht_mcs)
2487{
2488 /* parse ht_mcs into hex array */
2489 int i;
2490 const char *tmp = ht_mcs;
2491 char *end = NULL;
2492
2493 /* If ht_mcs is null, do not set anything */
2494 if (!ht_mcs)
2495 return 0;
2496
2497 /* This is what we are setting in the kernel */
2498 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2499
2500 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2501
2502 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2503 errno = 0;
2504 long v = strtol(tmp, &end, 16);
2505 if (errno == 0) {
2506 wpa_msg(wpa_s, MSG_DEBUG,
2507 "htcap value[%i]: %ld end: %p tmp: %p",
2508 i, v, end, tmp);
2509 if (end == tmp)
2510 break;
2511
2512 htcaps->supported_mcs_set[i] = v;
2513 tmp = end;
2514 } else {
2515 wpa_msg(wpa_s, MSG_ERROR,
2516 "Failed to parse ht-mcs: %s, error: %s\n",
2517 ht_mcs, strerror(errno));
2518 return -1;
2519 }
2520 }
2521
2522 /*
2523 * If we were able to parse any values, then set mask for the MCS set.
2524 */
2525 if (i) {
2526 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2527 IEEE80211_HT_MCS_MASK_LEN - 1);
2528 /* skip the 3 reserved bits */
2529 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2530 0x1f;
2531 }
2532
2533 return 0;
2534}
2535
2536
2537static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2538 struct ieee80211_ht_capabilities *htcaps,
2539 struct ieee80211_ht_capabilities *htcaps_mask,
2540 int disabled)
2541{
2542 u16 msk;
2543
2544 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2545
2546 if (disabled == -1)
2547 return 0;
2548
2549 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2550 htcaps_mask->ht_capabilities_info |= msk;
2551 if (disabled)
2552 htcaps->ht_capabilities_info &= msk;
2553 else
2554 htcaps->ht_capabilities_info |= msk;
2555
2556 return 0;
2557}
2558
2559
2560static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2561 struct ieee80211_ht_capabilities *htcaps,
2562 struct ieee80211_ht_capabilities *htcaps_mask,
2563 int factor)
2564{
2565 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2566
2567 if (factor == -1)
2568 return 0;
2569
2570 if (factor < 0 || factor > 3) {
2571 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2572 "Must be 0-3 or -1", factor);
2573 return -EINVAL;
2574 }
2575
2576 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2577 htcaps->a_mpdu_params &= ~0x3;
2578 htcaps->a_mpdu_params |= factor & 0x3;
2579
2580 return 0;
2581}
2582
2583
2584static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2585 struct ieee80211_ht_capabilities *htcaps,
2586 struct ieee80211_ht_capabilities *htcaps_mask,
2587 int density)
2588{
2589 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2590
2591 if (density == -1)
2592 return 0;
2593
2594 if (density < 0 || density > 7) {
2595 wpa_msg(wpa_s, MSG_ERROR,
2596 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2597 density);
2598 return -EINVAL;
2599 }
2600
2601 htcaps_mask->a_mpdu_params |= 0x1C;
2602 htcaps->a_mpdu_params &= ~(0x1C);
2603 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2604
2605 return 0;
2606}
2607
2608
2609static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2610 struct ieee80211_ht_capabilities *htcaps,
2611 struct ieee80211_ht_capabilities *htcaps_mask,
2612 int disabled)
2613{
2614 /* Masking these out disables HT40 */
2615 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2616 HT_CAP_INFO_SHORT_GI40MHZ);
2617
2618 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2619
2620 if (disabled)
2621 htcaps->ht_capabilities_info &= ~msk;
2622 else
2623 htcaps->ht_capabilities_info |= msk;
2624
2625 htcaps_mask->ht_capabilities_info |= msk;
2626
2627 return 0;
2628}
2629
2630
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002631static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2632 struct ieee80211_ht_capabilities *htcaps,
2633 struct ieee80211_ht_capabilities *htcaps_mask,
2634 int disabled)
2635{
2636 /* Masking these out disables SGI */
2637 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2638 HT_CAP_INFO_SHORT_GI40MHZ);
2639
2640 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2641
2642 if (disabled)
2643 htcaps->ht_capabilities_info &= ~msk;
2644 else
2645 htcaps->ht_capabilities_info |= msk;
2646
2647 htcaps_mask->ht_capabilities_info |= msk;
2648
2649 return 0;
2650}
2651
2652
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002653void wpa_supplicant_apply_ht_overrides(
2654 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2655 struct wpa_driver_associate_params *params)
2656{
2657 struct ieee80211_ht_capabilities *htcaps;
2658 struct ieee80211_ht_capabilities *htcaps_mask;
2659
2660 if (!ssid)
2661 return;
2662
2663 params->disable_ht = ssid->disable_ht;
2664 if (!params->htcaps || !params->htcaps_mask)
2665 return;
2666
2667 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2668 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2669 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2670 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2671 ssid->disable_max_amsdu);
2672 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2673 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2674 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002675 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002676}
2677
2678#endif /* CONFIG_HT_OVERRIDES */
2679
2680
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002681#ifdef CONFIG_VHT_OVERRIDES
2682void wpa_supplicant_apply_vht_overrides(
2683 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2684 struct wpa_driver_associate_params *params)
2685{
2686 struct ieee80211_vht_capabilities *vhtcaps;
2687 struct ieee80211_vht_capabilities *vhtcaps_mask;
2688
2689 if (!ssid)
2690 return;
2691
2692 params->disable_vht = ssid->disable_vht;
2693
2694 vhtcaps = (void *) params->vhtcaps;
2695 vhtcaps_mask = (void *) params->vhtcaps_mask;
2696
2697 if (!vhtcaps || !vhtcaps_mask)
2698 return;
2699
2700 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2701 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2702
2703#define OVERRIDE_MCS(i) \
2704 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2705 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2706 3 << 2 * (i - 1); \
2707 vhtcaps->vht_supported_mcs_set.tx_map |= \
2708 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2709 } \
2710 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2711 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2712 3 << 2 * (i - 1); \
2713 vhtcaps->vht_supported_mcs_set.rx_map |= \
2714 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2715 }
2716
2717 OVERRIDE_MCS(1);
2718 OVERRIDE_MCS(2);
2719 OVERRIDE_MCS(3);
2720 OVERRIDE_MCS(4);
2721 OVERRIDE_MCS(5);
2722 OVERRIDE_MCS(6);
2723 OVERRIDE_MCS(7);
2724 OVERRIDE_MCS(8);
2725}
2726#endif /* CONFIG_VHT_OVERRIDES */
2727
2728
Dmitry Shmidt04949592012-07-19 12:16:46 -07002729static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2730{
2731#ifdef PCSC_FUNCS
2732 size_t len;
2733
2734 if (!wpa_s->conf->pcsc_reader)
2735 return 0;
2736
2737 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2738 if (!wpa_s->scard)
2739 return 1;
2740
2741 if (wpa_s->conf->pcsc_pin &&
2742 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2743 scard_deinit(wpa_s->scard);
2744 wpa_s->scard = NULL;
2745 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2746 return -1;
2747 }
2748
2749 len = sizeof(wpa_s->imsi) - 1;
2750 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2751 scard_deinit(wpa_s->scard);
2752 wpa_s->scard = NULL;
2753 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2754 return -1;
2755 }
2756 wpa_s->imsi[len] = '\0';
2757
2758 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2759
2760 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2761 wpa_s->imsi, wpa_s->mnc_len);
2762
2763 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2764 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2765#endif /* PCSC_FUNCS */
2766
2767 return 0;
2768}
2769
2770
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002771int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2772{
2773 char *val, *pos;
2774
2775 ext_password_deinit(wpa_s->ext_pw);
2776 wpa_s->ext_pw = NULL;
2777 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2778
2779 if (!wpa_s->conf->ext_password_backend)
2780 return 0;
2781
2782 val = os_strdup(wpa_s->conf->ext_password_backend);
2783 if (val == NULL)
2784 return -1;
2785 pos = os_strchr(val, ':');
2786 if (pos)
2787 *pos++ = '\0';
2788
2789 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2790
2791 wpa_s->ext_pw = ext_password_init(val, pos);
2792 os_free(val);
2793 if (wpa_s->ext_pw == NULL) {
2794 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2795 return -1;
2796 }
2797 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2798
2799 return 0;
2800}
2801
2802
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002803static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2804 struct wpa_interface *iface)
2805{
2806 const char *ifname, *driver;
2807 struct wpa_driver_capa capa;
2808
2809 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2810 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2811 iface->confname ? iface->confname : "N/A",
2812 iface->driver ? iface->driver : "default",
2813 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2814 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2815
2816 if (iface->confname) {
2817#ifdef CONFIG_BACKEND_FILE
2818 wpa_s->confname = os_rel2abs_path(iface->confname);
2819 if (wpa_s->confname == NULL) {
2820 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2821 "for configuration file '%s'.",
2822 iface->confname);
2823 return -1;
2824 }
2825 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2826 iface->confname, wpa_s->confname);
2827#else /* CONFIG_BACKEND_FILE */
2828 wpa_s->confname = os_strdup(iface->confname);
2829#endif /* CONFIG_BACKEND_FILE */
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002830 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002831 if (wpa_s->conf == NULL) {
2832 wpa_printf(MSG_ERROR, "Failed to read or parse "
2833 "configuration '%s'.", wpa_s->confname);
2834 return -1;
2835 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002836 wpa_s->confanother = os_rel2abs_path(iface->confanother);
2837 wpa_config_read(wpa_s->confanother, wpa_s->conf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002838
2839 /*
2840 * Override ctrl_interface and driver_param if set on command
2841 * line.
2842 */
2843 if (iface->ctrl_interface) {
2844 os_free(wpa_s->conf->ctrl_interface);
2845 wpa_s->conf->ctrl_interface =
2846 os_strdup(iface->ctrl_interface);
2847 }
2848
2849 if (iface->driver_param) {
2850 os_free(wpa_s->conf->driver_param);
2851 wpa_s->conf->driver_param =
2852 os_strdup(iface->driver_param);
2853 }
2854 } else
2855 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2856 iface->driver_param);
2857
2858 if (wpa_s->conf == NULL) {
2859 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2860 return -1;
2861 }
2862
2863 if (iface->ifname == NULL) {
2864 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2865 return -1;
2866 }
2867 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2868 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2869 iface->ifname);
2870 return -1;
2871 }
2872 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2873
2874 if (iface->bridge_ifname) {
2875 if (os_strlen(iface->bridge_ifname) >=
2876 sizeof(wpa_s->bridge_ifname)) {
2877 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2878 "name '%s'.", iface->bridge_ifname);
2879 return -1;
2880 }
2881 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2882 sizeof(wpa_s->bridge_ifname));
2883 }
2884
2885 /* RSNA Supplicant Key Management - INITIALIZE */
2886 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2887 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2888
2889 /* Initialize driver interface and register driver event handler before
2890 * L2 receive handler so that association events are processed before
2891 * EAPOL-Key packets if both become available for the same select()
2892 * call. */
2893 driver = iface->driver;
2894next_driver:
2895 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2896 return -1;
2897
2898 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2899 if (wpa_s->drv_priv == NULL) {
2900 const char *pos;
2901 pos = driver ? os_strchr(driver, ',') : NULL;
2902 if (pos) {
2903 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2904 "driver interface - try next driver wrapper");
2905 driver = pos + 1;
2906 goto next_driver;
2907 }
2908 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2909 "interface");
2910 return -1;
2911 }
2912 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2913 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2914 "driver_param '%s'", wpa_s->conf->driver_param);
2915 return -1;
2916 }
2917
2918 ifname = wpa_drv_get_ifname(wpa_s);
2919 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2920 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2921 "interface name with '%s'", ifname);
2922 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2923 }
2924
2925 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2926 return -1;
2927
2928 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2929 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2930 NULL);
2931 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2932
2933 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2934 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2935 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2936 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2937 "dot11RSNAConfigPMKLifetime");
2938 return -1;
2939 }
2940
2941 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2942 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2943 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2944 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2945 "dot11RSNAConfigPMKReauthThreshold");
2946 return -1;
2947 }
2948
2949 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2950 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2951 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2952 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2953 "dot11RSNAConfigSATimeout");
2954 return -1;
2955 }
2956
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002957 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2958 &wpa_s->hw.num_modes,
2959 &wpa_s->hw.flags);
2960
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002961 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002962 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002963 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002964 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002965 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002966 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002967 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2968 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2969 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002970 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2971 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07002972 wpa_s->extended_capa = capa.extended_capa;
2973 wpa_s->extended_capa_mask = capa.extended_capa_mask;
2974 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002975 }
2976 if (wpa_s->max_remain_on_chan == 0)
2977 wpa_s->max_remain_on_chan = 1000;
2978
2979 if (wpa_supplicant_driver_init(wpa_s) < 0)
2980 return -1;
2981
2982#ifdef CONFIG_TDLS
2983 if (wpa_tdls_init(wpa_s->wpa))
2984 return -1;
2985#endif /* CONFIG_TDLS */
2986
2987 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2988 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2989 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2990 return -1;
2991 }
2992
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002993 if (wpas_wps_init(wpa_s))
2994 return -1;
2995
2996 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2997 return -1;
2998 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2999
3000 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
3001 if (wpa_s->ctrl_iface == NULL) {
3002 wpa_printf(MSG_ERROR,
3003 "Failed to initialize control interface '%s'.\n"
3004 "You may have another wpa_supplicant process "
3005 "already running or the file was\n"
3006 "left by an unclean termination of wpa_supplicant "
3007 "in which case you will need\n"
3008 "to manually remove this file before starting "
3009 "wpa_supplicant again.\n",
3010 wpa_s->conf->ctrl_interface);
3011 return -1;
3012 }
3013
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003014 wpa_s->gas = gas_query_init(wpa_s);
3015 if (wpa_s->gas == NULL) {
3016 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3017 return -1;
3018 }
3019
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003020#ifdef CONFIG_P2P
3021 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
3022 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
3023 return -1;
3024 }
3025#endif /* CONFIG_P2P */
3026
3027 if (wpa_bss_init(wpa_s) < 0)
3028 return -1;
3029
Dmitry Shmidt04949592012-07-19 12:16:46 -07003030 if (pcsc_reader_init(wpa_s) < 0)
3031 return -1;
3032
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003033 if (wpas_init_ext_pw(wpa_s) < 0)
3034 return -1;
3035
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003036 return 0;
3037}
3038
3039
3040static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003041 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003042{
3043 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
3550 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003551 * Add the failed BSSID into the blacklist and speed up next scan
3552 * attempt if there could be other APs that could accept association.
3553 * The current blacklist count indicates how many times we have tried
3554 * connecting to this AP and multiple attempts mean that other APs are
3555 * either not available or has already been tried, so that we can start
3556 * increasing the delay here to avoid constant scanning.
3557 */
3558 count = wpa_blacklist_add(wpa_s, bssid);
3559 if (count == 1 && wpa_s->current_bss) {
3560 /*
3561 * This BSS was not in the blacklist before. If there is
3562 * another BSS available for the same ESS, we should try that
3563 * next. Otherwise, we may as well try this one once more
3564 * before allowing other, likely worse, ESSes to be considered.
3565 */
3566 freqs = get_bss_freqs_in_ess(wpa_s);
3567 if (freqs) {
3568 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3569 "has been seen; try it next");
3570 wpa_blacklist_add(wpa_s, bssid);
3571 /*
3572 * On the next scan, go through only the known channels
3573 * used in this ESS based on previous scans to speed up
3574 * common load balancing use case.
3575 */
3576 os_free(wpa_s->next_scan_freqs);
3577 wpa_s->next_scan_freqs = freqs;
3578 }
3579 }
3580
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003581 /*
3582 * Add previous failure count in case the temporary blacklist was
3583 * cleared due to no other BSSes being available.
3584 */
3585 count += wpa_s->extra_blacklist_count;
3586
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003587 switch (count) {
3588 case 1:
3589 timeout = 100;
3590 break;
3591 case 2:
3592 timeout = 500;
3593 break;
3594 case 3:
3595 timeout = 1000;
3596 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003597 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003598 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003599 break;
3600 default:
3601 timeout = 10000;
3602 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003603 }
3604
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003605 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3606 "ms", count, timeout);
3607
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003608 /*
3609 * TODO: if more than one possible AP is available in scan results,
3610 * could try the other ones before requesting a new scan.
3611 */
3612 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3613 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003614
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -07003615 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003616}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003617
3618
3619int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3620{
3621 return wpa_s->conf->ap_scan == 2 ||
3622 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3623}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003624
Dmitry Shmidt04949592012-07-19 12:16:46 -07003625
3626#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3627int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3628 struct wpa_ssid *ssid,
3629 const char *field,
3630 const char *value)
3631{
3632#ifdef IEEE8021X_EAPOL
3633 struct eap_peer_config *eap = &ssid->eap;
3634
3635 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3636 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3637 (const u8 *) value, os_strlen(value));
3638
3639 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3640 case WPA_CTRL_REQ_EAP_IDENTITY:
3641 os_free(eap->identity);
3642 eap->identity = (u8 *) os_strdup(value);
3643 eap->identity_len = os_strlen(value);
3644 eap->pending_req_identity = 0;
3645 if (ssid == wpa_s->current_ssid)
3646 wpa_s->reassociate = 1;
3647 break;
3648 case WPA_CTRL_REQ_EAP_PASSWORD:
3649 os_free(eap->password);
3650 eap->password = (u8 *) os_strdup(value);
3651 eap->password_len = os_strlen(value);
3652 eap->pending_req_password = 0;
3653 if (ssid == wpa_s->current_ssid)
3654 wpa_s->reassociate = 1;
3655 break;
3656 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3657 os_free(eap->new_password);
3658 eap->new_password = (u8 *) os_strdup(value);
3659 eap->new_password_len = os_strlen(value);
3660 eap->pending_req_new_password = 0;
3661 if (ssid == wpa_s->current_ssid)
3662 wpa_s->reassociate = 1;
3663 break;
3664 case WPA_CTRL_REQ_EAP_PIN:
3665 os_free(eap->pin);
3666 eap->pin = os_strdup(value);
3667 eap->pending_req_pin = 0;
3668 if (ssid == wpa_s->current_ssid)
3669 wpa_s->reassociate = 1;
3670 break;
3671 case WPA_CTRL_REQ_EAP_OTP:
3672 os_free(eap->otp);
3673 eap->otp = (u8 *) os_strdup(value);
3674 eap->otp_len = os_strlen(value);
3675 os_free(eap->pending_req_otp);
3676 eap->pending_req_otp = NULL;
3677 eap->pending_req_otp_len = 0;
3678 break;
3679 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3680 os_free(eap->private_key_passwd);
3681 eap->private_key_passwd = (u8 *) os_strdup(value);
3682 eap->pending_req_passphrase = 0;
3683 if (ssid == wpa_s->current_ssid)
3684 wpa_s->reassociate = 1;
3685 break;
3686 default:
3687 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3688 return -1;
3689 }
3690
3691 return 0;
3692#else /* IEEE8021X_EAPOL */
3693 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3694 return -1;
3695#endif /* IEEE8021X_EAPOL */
3696}
3697#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3698
3699
3700int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3701{
3702 int i;
3703 unsigned int drv_enc;
3704
3705 if (ssid == NULL)
3706 return 1;
3707
3708 if (ssid->disabled)
3709 return 1;
3710
3711 if (wpa_s && wpa_s->drv_capa_known)
3712 drv_enc = wpa_s->drv_enc;
3713 else
3714 drv_enc = (unsigned int) -1;
3715
3716 for (i = 0; i < NUM_WEP_KEYS; i++) {
3717 size_t len = ssid->wep_key_len[i];
3718 if (len == 0)
3719 continue;
3720 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3721 continue;
3722 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3723 continue;
3724 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3725 continue;
3726 return 1; /* invalid WEP key */
3727 }
3728
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003729 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3730 !ssid->ext_psk)
3731 return 1;
3732
Dmitry Shmidt04949592012-07-19 12:16:46 -07003733 return 0;
3734}
3735
3736
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003737int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003738{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003739 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003740 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003741 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003742 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003743 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003744}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003745
3746
3747void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3748{
3749 struct wpa_ssid *ssid = wpa_s->current_ssid;
3750 int dur;
3751 struct os_time now;
3752
3753 if (ssid == NULL) {
3754 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3755 "SSID block");
3756 return;
3757 }
3758
3759 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3760 return;
3761
3762 ssid->auth_failures++;
3763 if (ssid->auth_failures > 50)
3764 dur = 300;
3765 else if (ssid->auth_failures > 20)
3766 dur = 120;
3767 else if (ssid->auth_failures > 10)
3768 dur = 60;
3769 else if (ssid->auth_failures > 5)
3770 dur = 30;
3771 else if (ssid->auth_failures > 1)
3772 dur = 20;
3773 else
3774 dur = 10;
3775
3776 os_get_time(&now);
3777 if (now.sec + dur <= ssid->disabled_until.sec)
3778 return;
3779
3780 ssid->disabled_until.sec = now.sec + dur;
3781
3782 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3783 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3784 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3785 ssid->auth_failures, dur);
3786}
3787
3788
3789void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3790 struct wpa_ssid *ssid, int clear_failures)
3791{
3792 if (ssid == NULL)
3793 return;
3794
3795 if (ssid->disabled_until.sec) {
3796 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3797 "id=%d ssid=\"%s\"",
3798 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3799 }
3800 ssid->disabled_until.sec = 0;
3801 ssid->disabled_until.usec = 0;
3802 if (clear_failures)
3803 ssid->auth_failures = 0;
3804}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003805
3806
3807int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3808{
3809 size_t i;
3810
3811 if (wpa_s->disallow_aps_bssid == NULL)
3812 return 0;
3813
3814 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3815 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3816 bssid, ETH_ALEN) == 0)
3817 return 1;
3818 }
3819
3820 return 0;
3821}
3822
3823
3824int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3825 size_t ssid_len)
3826{
3827 size_t i;
3828
3829 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3830 return 0;
3831
3832 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3833 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3834 if (ssid_len == s->ssid_len &&
3835 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3836 return 1;
3837 }
3838
3839 return 0;
3840}
3841
3842
3843/**
3844 * wpas_request_connection - Request a new connection
3845 * @wpa_s: Pointer to the network interface
3846 *
3847 * This function is used to request a new connection to be found. It will mark
3848 * the interface to allow reassociation and request a new scan to find a
3849 * suitable network to connect to.
3850 */
3851void wpas_request_connection(struct wpa_supplicant *wpa_s)
3852{
3853 wpa_s->normal_scans = 0;
3854 wpa_supplicant_reinit_autoscan(wpa_s);
3855 wpa_s->extra_blacklist_count = 0;
3856 wpa_s->disconnected = 0;
3857 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003858
3859 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3860 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003861}