blob: 398fca1ada37e64d5d496f3bec525b0c7dc4f042 [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
402 wpa_sm_set_eapol(wpa_s->wpa, NULL);
403 eapol_sm_deinit(wpa_s->eapol);
404 wpa_s->eapol = NULL;
405
406 rsn_preauth_deinit(wpa_s->wpa);
407
408#ifdef CONFIG_TDLS
409 wpa_tdls_deinit(wpa_s->wpa);
410#endif /* CONFIG_TDLS */
411
412 pmksa_candidate_free(wpa_s->wpa);
413 wpa_sm_deinit(wpa_s->wpa);
414 wpa_s->wpa = NULL;
415 wpa_blacklist_clear(wpa_s);
416
417 wpa_bss_deinit(wpa_s);
418
419 wpa_supplicant_cancel_scan(wpa_s);
420 wpa_supplicant_cancel_auth_timeout(wpa_s);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800421 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
422#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
423 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
424 wpa_s, NULL);
425#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700426
427 wpas_wps_deinit(wpa_s);
428
429 wpabuf_free(wpa_s->pending_eapol_rx);
430 wpa_s->pending_eapol_rx = NULL;
431
432#ifdef CONFIG_IBSS_RSN
433 ibss_rsn_deinit(wpa_s->ibss_rsn);
434 wpa_s->ibss_rsn = NULL;
435#endif /* CONFIG_IBSS_RSN */
436
437 sme_deinit(wpa_s);
438
439#ifdef CONFIG_AP
440 wpa_supplicant_ap_deinit(wpa_s);
441#endif /* CONFIG_AP */
442
443#ifdef CONFIG_P2P
444 wpas_p2p_deinit(wpa_s);
445#endif /* CONFIG_P2P */
446
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800447#ifdef CONFIG_OFFCHANNEL
448 offchannel_deinit(wpa_s);
449#endif /* CONFIG_OFFCHANNEL */
450
451 wpa_supplicant_cancel_sched_scan(wpa_s);
452
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700453 os_free(wpa_s->next_scan_freqs);
454 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800455
456 gas_query_deinit(wpa_s->gas);
457 wpa_s->gas = NULL;
458
459 free_hw_features(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700460
461 os_free(wpa_s->bssid_filter);
462 wpa_s->bssid_filter = NULL;
463
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800464 os_free(wpa_s->disallow_aps_bssid);
465 wpa_s->disallow_aps_bssid = NULL;
466 os_free(wpa_s->disallow_aps_ssid);
467 wpa_s->disallow_aps_ssid = NULL;
468
Dmitry Shmidt04949592012-07-19 12:16:46 -0700469 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700470
471 ext_password_deinit(wpa_s->ext_pw);
472 wpa_s->ext_pw = NULL;
473
474 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidt9bce59c2012-09-11 15:06:38 -0700475
476 os_free(wpa_s->last_scan_res);
477 wpa_s->last_scan_res = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700478}
479
480
481/**
482 * wpa_clear_keys - Clear keys configured for the driver
483 * @wpa_s: Pointer to wpa_supplicant data
484 * @addr: Previously used BSSID or %NULL if not available
485 *
486 * This function clears the encryption keys that has been previously configured
487 * for the driver.
488 */
489void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
490{
491 if (wpa_s->keys_cleared) {
492 /* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
493 * timing issues with keys being cleared just before new keys
494 * are set or just after association or something similar. This
495 * shows up in group key handshake failing often because of the
496 * client not receiving the first encrypted packets correctly.
497 * Skipping some of the extra key clearing steps seems to help
498 * in completing group key handshake more reliably. */
499 wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
500 "skip key clearing");
501 return;
502 }
503
504 /* MLME-DELETEKEYS.request */
505 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
506 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
507 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
508 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
509#ifdef CONFIG_IEEE80211W
510 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
511 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
512#endif /* CONFIG_IEEE80211W */
513 if (addr) {
514 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
515 0);
516 /* MLME-SETPROTECTION.request(None) */
517 wpa_drv_mlme_setprotection(
518 wpa_s, addr,
519 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
520 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
521 }
522 wpa_s->keys_cleared = 1;
523}
524
525
526/**
527 * wpa_supplicant_state_txt - Get the connection state name as a text string
528 * @state: State (wpa_state; WPA_*)
529 * Returns: The state name as a printable text string
530 */
531const char * wpa_supplicant_state_txt(enum wpa_states state)
532{
533 switch (state) {
534 case WPA_DISCONNECTED:
535 return "DISCONNECTED";
536 case WPA_INACTIVE:
537 return "INACTIVE";
538 case WPA_INTERFACE_DISABLED:
539 return "INTERFACE_DISABLED";
540 case WPA_SCANNING:
541 return "SCANNING";
542 case WPA_AUTHENTICATING:
543 return "AUTHENTICATING";
544 case WPA_ASSOCIATING:
545 return "ASSOCIATING";
546 case WPA_ASSOCIATED:
547 return "ASSOCIATED";
548 case WPA_4WAY_HANDSHAKE:
549 return "4WAY_HANDSHAKE";
550 case WPA_GROUP_HANDSHAKE:
551 return "GROUP_HANDSHAKE";
552 case WPA_COMPLETED:
553 return "COMPLETED";
554 default:
555 return "UNKNOWN";
556 }
557}
558
559
560#ifdef CONFIG_BGSCAN
561
562static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
563{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800564 if (wpas_driver_bss_selection(wpa_s))
565 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700566 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
567 return;
568
569 bgscan_deinit(wpa_s);
570 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
571 if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
572 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
573 "bgscan");
574 /*
575 * Live without bgscan; it is only used as a roaming
576 * optimization, so the initial connection is not
577 * affected.
578 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700579 } else {
580 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700581 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700582 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
583 0);
584 if (scan_res) {
585 bgscan_notify_scan(wpa_s, scan_res);
586 wpa_scan_results_free(scan_res);
587 }
588 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700589 } else
590 wpa_s->bgscan_ssid = NULL;
591}
592
593
594static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
595{
596 if (wpa_s->bgscan_ssid != NULL) {
597 bgscan_deinit(wpa_s);
598 wpa_s->bgscan_ssid = NULL;
599 }
600}
601
602#endif /* CONFIG_BGSCAN */
603
604
Dmitry Shmidt04949592012-07-19 12:16:46 -0700605static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
606{
607 if (autoscan_init(wpa_s, 0))
608 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
609}
610
611
612static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
613{
614 autoscan_deinit(wpa_s);
615}
616
617
618void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
619{
620 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
621 wpa_s->wpa_state == WPA_SCANNING) {
622 autoscan_deinit(wpa_s);
623 wpa_supplicant_start_autoscan(wpa_s);
624 }
625}
626
627
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700628/**
629 * wpa_supplicant_set_state - Set current connection state
630 * @wpa_s: Pointer to wpa_supplicant data
631 * @state: The new connection state
632 *
633 * This function is called whenever the connection state changes, e.g.,
634 * association is completed for WPA/WPA2 4-Way Handshake is started.
635 */
636void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
637 enum wpa_states state)
638{
639 enum wpa_states old_state = wpa_s->wpa_state;
640
641 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
642 wpa_supplicant_state_txt(wpa_s->wpa_state),
643 wpa_supplicant_state_txt(state));
644
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700645#ifdef ANDROID_P2P
Irfan Sheriff7db4ef72012-06-18 09:39:07 -0700646 if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
647 wpa_s->current_ssid->assoc_retry = 0;
648 }
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700649#endif /* ANDROID_P2P */
650
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700651 if (state != WPA_SCANNING)
652 wpa_supplicant_notify_scanning(wpa_s, 0);
653
654 if (state == WPA_COMPLETED && wpa_s->new_connection) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700655 struct wpa_ssid *ssid = wpa_s->current_ssid;
Dmitry Shmidt700a1372013-03-15 14:14:44 -0700656#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700657 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800658 MACSTR " completed (auth) [id=%d id_str=%s]",
659 MAC2STR(wpa_s->bssid),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700660 ssid ? ssid->id : -1,
661 ssid && ssid->id_str ? ssid->id_str : "");
662#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700663 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800664 wpa_s->extra_blacklist_count = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700665 wpa_s->new_connection = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700666 wpa_drv_set_operstate(wpa_s, 1);
667#ifndef IEEE8021X_EAPOL
668 wpa_drv_set_supp_port(wpa_s, 1);
669#endif /* IEEE8021X_EAPOL */
670 wpa_s->after_wps = 0;
671#ifdef CONFIG_P2P
672 wpas_p2p_completed(wpa_s);
673#endif /* CONFIG_P2P */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700674
675 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700676 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
677 state == WPA_ASSOCIATED) {
678 wpa_s->new_connection = 1;
679 wpa_drv_set_operstate(wpa_s, 0);
680#ifndef IEEE8021X_EAPOL
681 wpa_drv_set_supp_port(wpa_s, 0);
682#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700683 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700684 }
685 wpa_s->wpa_state = state;
686
687#ifdef CONFIG_BGSCAN
688 if (state == WPA_COMPLETED)
689 wpa_supplicant_start_bgscan(wpa_s);
690 else
691 wpa_supplicant_stop_bgscan(wpa_s);
692#endif /* CONFIG_BGSCAN */
693
Dmitry Shmidt04949592012-07-19 12:16:46 -0700694 if (state == WPA_AUTHENTICATING)
695 wpa_supplicant_stop_autoscan(wpa_s);
696
697 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
698 wpa_supplicant_start_autoscan(wpa_s);
699
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700700 if (wpa_s->wpa_state != old_state) {
701 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
702
703 if (wpa_s->wpa_state == WPA_COMPLETED ||
704 old_state == WPA_COMPLETED)
705 wpas_notify_auth_changed(wpa_s);
706 }
707}
708
709
710void wpa_supplicant_terminate_proc(struct wpa_global *global)
711{
712 int pending = 0;
713#ifdef CONFIG_WPS
714 struct wpa_supplicant *wpa_s = global->ifaces;
715 while (wpa_s) {
716 if (wpas_wps_terminate_pending(wpa_s) == 1)
717 pending = 1;
718 wpa_s = wpa_s->next;
719 }
720#endif /* CONFIG_WPS */
721 if (pending)
722 return;
723 eloop_terminate();
724}
725
726
727static void wpa_supplicant_terminate(int sig, void *signal_ctx)
728{
729 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700730 wpa_supplicant_terminate_proc(global);
731}
732
733
734void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
735{
736 enum wpa_states old_state = wpa_s->wpa_state;
737
738 wpa_s->pairwise_cipher = 0;
739 wpa_s->group_cipher = 0;
740 wpa_s->mgmt_group_cipher = 0;
741 wpa_s->key_mgmt = 0;
742 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700743 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700744
745 if (wpa_s->wpa_state != old_state)
746 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
747}
748
749
750/**
751 * wpa_supplicant_reload_configuration - Reload configuration data
752 * @wpa_s: Pointer to wpa_supplicant data
753 * Returns: 0 on success or -1 if configuration parsing failed
754 *
755 * This function can be used to request that the configuration data is reloaded
756 * (e.g., after configuration file change). This function is reloading
757 * configuration only for one interface, so this may need to be called multiple
758 * times if %wpa_supplicant is controlling multiple interfaces and all
759 * interfaces need reconfiguration.
760 */
761int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
762{
763 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700764 int reconf_ctrl;
765 int old_ap_scan;
766
767 if (wpa_s->confname == NULL)
768 return -1;
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700769 conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700770 if (conf == NULL) {
771 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
772 "file '%s' - exiting", wpa_s->confname);
773 return -1;
774 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700775 wpa_config_read(wpa_s->confanother, conf);
776
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700777 conf->changed_parameters = (unsigned int) -1;
778
779 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
780 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
781 os_strcmp(conf->ctrl_interface,
782 wpa_s->conf->ctrl_interface) != 0);
783
784 if (reconf_ctrl && wpa_s->ctrl_iface) {
785 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
786 wpa_s->ctrl_iface = NULL;
787 }
788
789 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800790 if (wpa_s->current_ssid) {
791 wpa_supplicant_deauthenticate(wpa_s,
792 WLAN_REASON_DEAUTH_LEAVING);
793 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700794
795 /*
796 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
797 * pkcs11_engine_path, pkcs11_module_path.
798 */
799 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
800 /*
801 * Clear forced success to clear EAP state for next
802 * authentication.
803 */
804 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
805 }
806 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
807 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800808 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700809 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
810 rsn_preauth_deinit(wpa_s->wpa);
811
812 old_ap_scan = wpa_s->conf->ap_scan;
813 wpa_config_free(wpa_s->conf);
814 wpa_s->conf = conf;
815 if (old_ap_scan != wpa_s->conf->ap_scan)
816 wpas_notify_ap_scan_changed(wpa_s);
817
818 if (reconf_ctrl)
819 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
820
821 wpa_supplicant_update_config(wpa_s);
822
823 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700824 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700825 wpa_s->reassociate = 1;
826 wpa_supplicant_req_scan(wpa_s, 0, 0);
827 }
828 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
829 return 0;
830}
831
832
833static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
834{
835 struct wpa_global *global = signal_ctx;
836 struct wpa_supplicant *wpa_s;
837 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
838 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
839 sig);
840 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
841 wpa_supplicant_terminate_proc(global);
842 }
843 }
844}
845
846
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700847enum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
848{
849 switch (key_mgmt) {
850 case WPA_KEY_MGMT_NONE:
851 return KEY_MGMT_NONE;
852 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
853 return KEY_MGMT_802_1X_NO_WPA;
854 case WPA_KEY_MGMT_IEEE8021X:
855 return KEY_MGMT_802_1X;
856 case WPA_KEY_MGMT_WPA_NONE:
857 return KEY_MGMT_WPA_NONE;
858 case WPA_KEY_MGMT_FT_IEEE8021X:
859 return KEY_MGMT_FT_802_1X;
860 case WPA_KEY_MGMT_FT_PSK:
861 return KEY_MGMT_FT_PSK;
862 case WPA_KEY_MGMT_IEEE8021X_SHA256:
863 return KEY_MGMT_802_1X_SHA256;
864 case WPA_KEY_MGMT_PSK_SHA256:
865 return KEY_MGMT_PSK_SHA256;
866 case WPA_KEY_MGMT_WPS:
867 return KEY_MGMT_WPS;
868 case WPA_KEY_MGMT_PSK:
869 default:
870 return KEY_MGMT_PSK;
871 }
872}
873
874
875static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
876 struct wpa_ssid *ssid,
877 struct wpa_ie_data *ie)
878{
879 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
880 if (ret) {
881 if (ret == -2) {
882 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
883 "from association info");
884 }
885 return -1;
886 }
887
888 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
889 "cipher suites");
890 if (!(ie->group_cipher & ssid->group_cipher)) {
891 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
892 "cipher 0x%x (mask 0x%x) - reject",
893 ie->group_cipher, ssid->group_cipher);
894 return -1;
895 }
896 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
897 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
898 "cipher 0x%x (mask 0x%x) - reject",
899 ie->pairwise_cipher, ssid->pairwise_cipher);
900 return -1;
901 }
902 if (!(ie->key_mgmt & ssid->key_mgmt)) {
903 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
904 "management 0x%x (mask 0x%x) - reject",
905 ie->key_mgmt, ssid->key_mgmt);
906 return -1;
907 }
908
909#ifdef CONFIG_IEEE80211W
910 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800911 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
912 wpa_s->conf->pmf : ssid->ieee80211w) ==
913 MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700914 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
915 "that does not support management frame protection - "
916 "reject");
917 return -1;
918 }
919#endif /* CONFIG_IEEE80211W */
920
921 return 0;
922}
923
924
925/**
926 * wpa_supplicant_set_suites - Set authentication and encryption parameters
927 * @wpa_s: Pointer to wpa_supplicant data
928 * @bss: Scan results for the selected BSS, or %NULL if not available
929 * @ssid: Configuration data for the selected network
930 * @wpa_ie: Buffer for the WPA/RSN IE
931 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
932 * used buffer length in case the functions returns success.
933 * Returns: 0 on success or -1 on failure
934 *
935 * This function is used to configure authentication and encryption parameters
936 * based on the network configuration and scan result for the selected BSS (if
937 * available).
938 */
939int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
940 struct wpa_bss *bss, struct wpa_ssid *ssid,
941 u8 *wpa_ie, size_t *wpa_ie_len)
942{
943 struct wpa_ie_data ie;
944 int sel, proto;
945 const u8 *bss_wpa, *bss_rsn;
946
947 if (bss) {
948 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
949 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
950 } else
951 bss_wpa = bss_rsn = NULL;
952
953 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
954 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
955 (ie.group_cipher & ssid->group_cipher) &&
956 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
957 (ie.key_mgmt & ssid->key_mgmt)) {
958 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
959 proto = WPA_PROTO_RSN;
960 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
961 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
962 (ie.group_cipher & ssid->group_cipher) &&
963 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
964 (ie.key_mgmt & ssid->key_mgmt)) {
965 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
966 proto = WPA_PROTO_WPA;
967 } else if (bss) {
968 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
969 return -1;
970 } else {
971 if (ssid->proto & WPA_PROTO_RSN)
972 proto = WPA_PROTO_RSN;
973 else
974 proto = WPA_PROTO_WPA;
975 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
976 os_memset(&ie, 0, sizeof(ie));
977 ie.group_cipher = ssid->group_cipher;
978 ie.pairwise_cipher = ssid->pairwise_cipher;
979 ie.key_mgmt = ssid->key_mgmt;
980#ifdef CONFIG_IEEE80211W
981 ie.mgmt_group_cipher =
982 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
983 WPA_CIPHER_AES_128_CMAC : 0;
984#endif /* CONFIG_IEEE80211W */
985 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
986 "based on configuration");
987 } else
988 proto = ie.proto;
989 }
990
991 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
992 "pairwise %d key_mgmt %d proto %d",
993 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
994#ifdef CONFIG_IEEE80211W
995 if (ssid->ieee80211w) {
996 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
997 ie.mgmt_group_cipher);
998 }
999#endif /* CONFIG_IEEE80211W */
1000
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001001 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001002 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1003 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1004 !!(ssid->proto & WPA_PROTO_RSN));
1005
1006 if (bss || !wpa_s->ap_ies_from_associnfo) {
1007 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1008 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1009 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1010 bss_rsn ? 2 + bss_rsn[1] : 0))
1011 return -1;
1012 }
1013
1014 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001015 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1016 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001017 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1018 "cipher");
1019 return -1;
1020 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001021 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1022 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001023
1024 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001025 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1026 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001027 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1028 "cipher");
1029 return -1;
1030 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001031 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1032 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001033
1034 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001035#ifdef CONFIG_SAE
1036 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1037 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1038#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001039 if (0) {
1040#ifdef CONFIG_IEEE80211R
1041 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1042 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1043 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1044 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1045 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1046 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1047#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001048#ifdef CONFIG_SAE
1049 } else if (sel & WPA_KEY_MGMT_SAE) {
1050 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1051 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1052 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1053 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1054 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1055#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001056#ifdef CONFIG_IEEE80211W
1057 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1058 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1059 wpa_dbg(wpa_s, MSG_DEBUG,
1060 "WPA: using KEY_MGMT 802.1X with SHA256");
1061 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1062 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1063 wpa_dbg(wpa_s, MSG_DEBUG,
1064 "WPA: using KEY_MGMT PSK with SHA256");
1065#endif /* CONFIG_IEEE80211W */
1066 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1067 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1068 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1069 } else if (sel & WPA_KEY_MGMT_PSK) {
1070 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1071 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1072 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1073 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1074 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1075 } else {
1076 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1077 "authenticated key management type");
1078 return -1;
1079 }
1080
1081 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1082 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1083 wpa_s->pairwise_cipher);
1084 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1085
1086#ifdef CONFIG_IEEE80211W
1087 sel = ie.mgmt_group_cipher;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001088 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1089 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001090 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1091 sel = 0;
1092 if (sel & WPA_CIPHER_AES_128_CMAC) {
1093 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1094 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1095 "AES-128-CMAC");
1096 } else {
1097 wpa_s->mgmt_group_cipher = 0;
1098 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1099 }
1100 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1101 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001102 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1103 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1104 wpa_s->conf->pmf : ssid->ieee80211w));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001105#endif /* CONFIG_IEEE80211W */
1106
1107 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1108 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1109 return -1;
1110 }
1111
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001112 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001113 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001114#ifndef CONFIG_NO_PBKDF2
1115 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1116 ssid->passphrase) {
1117 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001118 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1119 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001120 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1121 psk, PMK_LEN);
1122 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1123 }
1124#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001125#ifdef CONFIG_EXT_PASSWORD
1126 if (ssid->ext_psk) {
1127 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1128 ssid->ext_psk);
1129 char pw_str[64 + 1];
1130 u8 psk[PMK_LEN];
1131
1132 if (pw == NULL) {
1133 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1134 "found from external storage");
1135 return -1;
1136 }
1137
1138 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1139 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1140 "PSK length %d in external storage",
1141 (int) wpabuf_len(pw));
1142 ext_password_free(pw);
1143 return -1;
1144 }
1145
1146 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1147 pw_str[wpabuf_len(pw)] = '\0';
1148
1149#ifndef CONFIG_NO_PBKDF2
1150 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1151 {
1152 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1153 4096, psk, PMK_LEN);
1154 os_memset(pw_str, 0, sizeof(pw_str));
1155 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1156 "external passphrase)",
1157 psk, PMK_LEN);
1158 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1159 } else
1160#endif /* CONFIG_NO_PBKDF2 */
1161 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1162 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1163 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1164 "Invalid PSK hex string");
1165 os_memset(pw_str, 0, sizeof(pw_str));
1166 ext_password_free(pw);
1167 return -1;
1168 }
1169 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1170 } else {
1171 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1172 "PSK available");
1173 os_memset(pw_str, 0, sizeof(pw_str));
1174 ext_password_free(pw);
1175 return -1;
1176 }
1177
1178 os_memset(pw_str, 0, sizeof(pw_str));
1179 ext_password_free(pw);
1180 }
1181#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001182 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001183 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1184
1185 return 0;
1186}
1187
1188
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001189static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1190{
1191 *pos = 0x00;
1192
1193 switch (idx) {
1194 case 0: /* Bits 0-7 */
1195 break;
1196 case 1: /* Bits 8-15 */
1197 break;
1198 case 2: /* Bits 16-23 */
1199#ifdef CONFIG_WNM
1200 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1201 *pos |= 0x08; /* Bit 19 - BSS Transition */
1202#endif /* CONFIG_WNM */
1203 break;
1204 case 3: /* Bits 24-31 */
1205#ifdef CONFIG_WNM
1206 *pos |= 0x02; /* Bit 25 - SSID List */
1207#endif /* CONFIG_WNM */
1208#ifdef CONFIG_INTERWORKING
1209 if (wpa_s->conf->interworking)
1210 *pos |= 0x80; /* Bit 31 - Interworking */
1211#endif /* CONFIG_INTERWORKING */
1212 break;
1213 case 4: /* Bits 32-39 */
1214 break;
1215 case 5: /* Bits 40-47 */
1216 break;
1217 case 6: /* Bits 48-55 */
1218 break;
1219 }
1220}
1221
1222
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001223int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1224{
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001225 u8 *pos = buf;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001226 u8 len = 4, i;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001227
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001228 if (len < wpa_s->extended_capa_len)
1229 len = wpa_s->extended_capa_len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001230
1231 *pos++ = WLAN_EID_EXT_CAPAB;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001232 *pos++ = len;
1233 for (i = 0; i < len; i++, pos++) {
1234 wpas_ext_capab_byte(wpa_s, pos, i);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001235
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001236 if (i < wpa_s->extended_capa_len) {
1237 *pos &= ~wpa_s->extended_capa_mask[i];
1238 *pos |= wpa_s->extended_capa[i];
1239 }
1240 }
1241
1242 while (len > 0 && buf[1 + len] == 0) {
1243 len--;
1244 buf[1] = len;
1245 }
1246 if (len == 0)
1247 return 0;
1248
1249 return 2 + len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001250}
1251
1252
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001253/**
1254 * wpa_supplicant_associate - Request association
1255 * @wpa_s: Pointer to wpa_supplicant data
1256 * @bss: Scan results for the selected BSS, or %NULL if not available
1257 * @ssid: Configuration data for the selected network
1258 *
1259 * This function is used to request %wpa_supplicant to associate with a BSS.
1260 */
1261void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1262 struct wpa_bss *bss, struct wpa_ssid *ssid)
1263{
1264 u8 wpa_ie[200];
1265 size_t wpa_ie_len;
1266 int use_crypt, ret, i, bssid_changed;
1267 int algs = WPA_AUTH_ALG_OPEN;
1268 enum wpa_cipher cipher_pairwise, cipher_group;
1269 struct wpa_driver_associate_params params;
1270 int wep_keys_set = 0;
1271 struct wpa_driver_capa capa;
1272 int assoc_failed = 0;
1273 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001274 u8 ext_capab[10];
1275 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001276#ifdef CONFIG_HT_OVERRIDES
1277 struct ieee80211_ht_capabilities htcaps;
1278 struct ieee80211_ht_capabilities htcaps_mask;
1279#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001280
1281#ifdef CONFIG_IBSS_RSN
1282 ibss_rsn_deinit(wpa_s->ibss_rsn);
1283 wpa_s->ibss_rsn = NULL;
1284#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001285#ifdef ANDROID_P2P
1286 int freq = 0;
1287#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001288
1289 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1290 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1291#ifdef CONFIG_AP
1292 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1293 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1294 "mode");
1295 return;
1296 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001297 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1298 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1299 return;
1300 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001301 wpa_s->current_bss = bss;
1302#else /* CONFIG_AP */
1303 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1304 "the build");
1305#endif /* CONFIG_AP */
1306 return;
1307 }
1308
1309#ifdef CONFIG_TDLS
1310 if (bss)
1311 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1312 bss->ie_len);
1313#endif /* CONFIG_TDLS */
1314
1315 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1316 ssid->mode == IEEE80211_MODE_INFRA) {
1317 sme_authenticate(wpa_s, bss, ssid);
1318 return;
1319 }
1320
1321 os_memset(&params, 0, sizeof(params));
1322 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001323 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001324#ifdef CONFIG_IEEE80211R
1325 const u8 *ie, *md = NULL;
1326#endif /* CONFIG_IEEE80211R */
1327 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1328 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1329 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1330 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1331 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1332 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1333 if (bssid_changed)
1334 wpas_notify_bssid_changed(wpa_s);
1335#ifdef CONFIG_IEEE80211R
1336 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1337 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1338 md = ie + 2;
1339 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1340 if (md) {
1341 /* Prepare for the next transition */
1342 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1343 }
1344#endif /* CONFIG_IEEE80211R */
1345#ifdef CONFIG_WPS
1346 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1347 wpa_s->conf->ap_scan == 2 &&
1348 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1349 /* Use ap_scan==1 style network selection to find the network
1350 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001351 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001352 wpa_s->reassociate = 1;
1353 wpa_supplicant_req_scan(wpa_s, 0, 0);
1354 return;
1355#endif /* CONFIG_WPS */
1356 } else {
1357 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1358 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1359 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1360 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001361 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001362 wpa_supplicant_cancel_scan(wpa_s);
1363
1364 /* Starting new association, so clear the possibly used WPA IE from the
1365 * previous association. */
1366 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1367
1368#ifdef IEEE8021X_EAPOL
1369 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1370 if (ssid->leap) {
1371 if (ssid->non_leap == 0)
1372 algs = WPA_AUTH_ALG_LEAP;
1373 else
1374 algs |= WPA_AUTH_ALG_LEAP;
1375 }
1376 }
1377#endif /* IEEE8021X_EAPOL */
1378 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1379 if (ssid->auth_alg) {
1380 algs = ssid->auth_alg;
1381 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1382 "0x%x", algs);
1383 }
1384
1385 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1386 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001387 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001388 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001389 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1390 wpa_s->conf->okc :
1391 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001392 (ssid->proto & WPA_PROTO_RSN);
1393 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001394 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001395 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1396 wpa_ie_len = sizeof(wpa_ie);
1397 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1398 wpa_ie, &wpa_ie_len)) {
1399 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1400 "key management and encryption suites");
1401 return;
1402 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001403 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1404 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1405 /*
1406 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1407 * use non-WPA since the scan results did not indicate that the
1408 * AP is using WPA or WPA2.
1409 */
1410 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1411 wpa_ie_len = 0;
1412 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001413 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001414 wpa_ie_len = sizeof(wpa_ie);
1415 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1416 wpa_ie, &wpa_ie_len)) {
1417 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1418 "key management and encryption suites (no "
1419 "scan results)");
1420 return;
1421 }
1422#ifdef CONFIG_WPS
1423 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1424 struct wpabuf *wps_ie;
1425 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1426 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1427 wpa_ie_len = wpabuf_len(wps_ie);
1428 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1429 } else
1430 wpa_ie_len = 0;
1431 wpabuf_free(wps_ie);
1432 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1433 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1434 params.wps = WPS_MODE_PRIVACY;
1435 else
1436 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001437 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001438#endif /* CONFIG_WPS */
1439 } else {
1440 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1441 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001442 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001443 }
1444
1445#ifdef CONFIG_P2P
1446 if (wpa_s->global->p2p) {
1447 u8 *pos;
1448 size_t len;
1449 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001450 pos = wpa_ie + wpa_ie_len;
1451 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001452 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1453 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001454 if (res >= 0)
1455 wpa_ie_len += res;
1456 }
1457
1458 wpa_s->cross_connect_disallowed = 0;
1459 if (bss) {
1460 struct wpabuf *p2p;
1461 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1462 if (p2p) {
1463 wpa_s->cross_connect_disallowed =
1464 p2p_get_cross_connect_disallowed(p2p);
1465 wpabuf_free(p2p);
1466 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1467 "connection",
1468 wpa_s->cross_connect_disallowed ?
1469 "disallows" : "allows");
1470 }
1471 }
1472#endif /* CONFIG_P2P */
1473
Dmitry Shmidt04949592012-07-19 12:16:46 -07001474#ifdef CONFIG_HS20
1475 if (wpa_s->conf->hs20) {
1476 struct wpabuf *hs20;
1477 hs20 = wpabuf_alloc(20);
1478 if (hs20) {
1479 wpas_hs20_add_indication(hs20);
1480 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1481 wpabuf_len(hs20));
1482 wpa_ie_len += wpabuf_len(hs20);
1483 wpabuf_free(hs20);
1484 }
1485 }
1486#endif /* CONFIG_HS20 */
1487
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001488 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1489 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001490 u8 *pos = wpa_ie;
1491 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1492 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001493 os_memmove(pos + ext_capab_len, pos,
1494 wpa_ie_len - (pos - wpa_ie));
1495 wpa_ie_len += ext_capab_len;
1496 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001497 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001498
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001499 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1500 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001501 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1502 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001503 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1504 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1505 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1506 use_crypt = 0;
1507 if (wpa_set_wep_keys(wpa_s, ssid)) {
1508 use_crypt = 1;
1509 wep_keys_set = 1;
1510 }
1511 }
1512 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1513 use_crypt = 0;
1514
1515#ifdef IEEE8021X_EAPOL
1516 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1517 if ((ssid->eapol_flags &
1518 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1519 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1520 !wep_keys_set) {
1521 use_crypt = 0;
1522 } else {
1523 /* Assume that dynamic WEP-104 keys will be used and
1524 * set cipher suites in order for drivers to expect
1525 * encryption. */
1526 cipher_pairwise = cipher_group = CIPHER_WEP104;
1527 }
1528 }
1529#endif /* IEEE8021X_EAPOL */
1530
1531 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1532 /* Set the key before (and later after) association */
1533 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1534 }
1535
1536 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1537 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001538 params.ssid = bss->ssid;
1539 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001540 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1541 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1542 MACSTR " freq=%u MHz based on scan results "
1543 "(bssid_set=%d)",
1544 MAC2STR(bss->bssid), bss->freq,
1545 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001546 params.bssid = bss->bssid;
1547 params.freq = bss->freq;
1548 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001549 } else {
1550 params.ssid = ssid->ssid;
1551 params.ssid_len = ssid->ssid_len;
1552 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001553
1554 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1555 wpa_s->conf->ap_scan == 2) {
1556 params.bssid = ssid->bssid;
1557 params.fixed_bssid = 1;
1558 }
1559
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001560 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1561 params.freq == 0)
1562 params.freq = ssid->frequency; /* Initial channel for IBSS */
1563 params.wpa_ie = wpa_ie;
1564 params.wpa_ie_len = wpa_ie_len;
1565 params.pairwise_suite = cipher_pairwise;
1566 params.group_suite = cipher_group;
1567 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001568 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001569 params.auth_alg = algs;
1570 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001571 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001572 for (i = 0; i < NUM_WEP_KEYS; i++) {
1573 if (ssid->wep_key_len[i])
1574 params.wep_key[i] = ssid->wep_key[i];
1575 params.wep_key_len[i] = ssid->wep_key_len[i];
1576 }
1577 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1578
1579 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1580 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1581 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1582 params.passphrase = ssid->passphrase;
1583 if (ssid->psk_set)
1584 params.psk = ssid->psk;
1585 }
1586
1587 params.drop_unencrypted = use_crypt;
1588
1589#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001590 params.mgmt_frame_protection =
1591 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1592 wpa_s->conf->pmf : ssid->ieee80211w;
1593 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001594 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1595 struct wpa_ie_data ie;
1596 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1597 ie.capabilities &
1598 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1599 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1600 "MFP: require MFP");
1601 params.mgmt_frame_protection =
1602 MGMT_FRAME_PROTECTION_REQUIRED;
1603 }
1604 }
1605#endif /* CONFIG_IEEE80211W */
1606
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001607 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001608
1609 if (wpa_s->parent->set_sta_uapsd)
1610 params.uapsd = wpa_s->parent->sta_uapsd;
1611 else
1612 params.uapsd = -1;
1613
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001614#ifdef CONFIG_HT_OVERRIDES
1615 os_memset(&htcaps, 0, sizeof(htcaps));
1616 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1617 params.htcaps = (u8 *) &htcaps;
1618 params.htcaps_mask = (u8 *) &htcaps_mask;
1619 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1620#endif /* CONFIG_HT_OVERRIDES */
1621
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001622#ifdef ANDROID_P2P
1623 /* If multichannel concurrency is not supported, check for any frequency
1624 * conflict and take appropriate action.
1625 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001626 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1627 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1628 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001629 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001630 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001631 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001632 }
1633#endif
1634 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001635 if (ret < 0) {
1636 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1637 "failed");
1638 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1639 /*
1640 * The driver is known to mean what is saying, so we
1641 * can stop right here; the association will not
1642 * succeed.
1643 */
1644 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001645 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001646 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1647 return;
1648 }
1649 /* try to continue anyway; new association will be tried again
1650 * after timeout */
1651 assoc_failed = 1;
1652 }
1653
1654 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1655 /* Set the key after the association just in case association
1656 * cleared the previously configured key. */
1657 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1658 /* No need to timeout authentication since there is no key
1659 * management. */
1660 wpa_supplicant_cancel_auth_timeout(wpa_s);
1661 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1662#ifdef CONFIG_IBSS_RSN
1663 } else if (ssid->mode == WPAS_MODE_IBSS &&
1664 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1665 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1666 /*
1667 * RSN IBSS authentication is per-STA and we can disable the
1668 * per-BSSID authentication.
1669 */
1670 wpa_supplicant_cancel_auth_timeout(wpa_s);
1671#endif /* CONFIG_IBSS_RSN */
1672 } else {
1673 /* Timeout for IEEE 802.11 authentication and association */
1674 int timeout = 60;
1675
1676 if (assoc_failed) {
1677 /* give IBSS a bit more time */
1678 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1679 } else if (wpa_s->conf->ap_scan == 1) {
1680 /* give IBSS a bit more time */
1681 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1682 }
1683 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1684 }
1685
1686 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1687 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1688 /* Set static WEP keys again */
1689 wpa_set_wep_keys(wpa_s, ssid);
1690 }
1691
1692 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1693 /*
1694 * Do not allow EAP session resumption between different
1695 * network configurations.
1696 */
1697 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1698 }
1699 old_ssid = wpa_s->current_ssid;
1700 wpa_s->current_ssid = ssid;
1701 wpa_s->current_bss = bss;
1702 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1703 wpa_supplicant_initiate_eapol(wpa_s);
1704 if (old_ssid != wpa_s->current_ssid)
1705 wpas_notify_network_changed(wpa_s);
1706}
1707
1708
1709static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1710 const u8 *addr)
1711{
1712 struct wpa_ssid *old_ssid;
1713
1714 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001715 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001716 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001717 wpa_sm_set_config(wpa_s->wpa, NULL);
1718 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1719 if (old_ssid != wpa_s->current_ssid)
1720 wpas_notify_network_changed(wpa_s);
1721 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1722}
1723
1724
1725/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001726 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1727 * @wpa_s: Pointer to wpa_supplicant data
1728 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1729 *
1730 * This function is used to request %wpa_supplicant to deauthenticate from the
1731 * current AP.
1732 */
1733void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1734 int reason_code)
1735{
1736 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001737 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001738 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001739
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001740 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1741 " pending_bssid=" MACSTR " reason=%d state=%s",
1742 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1743 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1744
1745 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001746 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001747 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1748 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1749 wpa_s->wpa_state == WPA_ASSOCIATING))
1750 addr = wpa_s->pending_bssid;
1751 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1752 /*
1753 * When using driver-based BSS selection, we may not know the
1754 * BSSID with which we are currently trying to associate. We
1755 * need to notify the driver of this disconnection even in such
1756 * a case, so use the all zeros address here.
1757 */
1758 addr = wpa_s->bssid;
1759 zero_addr = 1;
1760 }
1761
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001762#ifdef CONFIG_TDLS
1763 wpa_tdls_teardown_peers(wpa_s->wpa);
1764#endif /* CONFIG_TDLS */
1765
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001766 if (addr) {
1767 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001768 os_memset(&event, 0, sizeof(event));
1769 event.deauth_info.reason_code = (u16) reason_code;
1770 event.deauth_info.locally_generated = 1;
1771 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001772 if (zero_addr)
1773 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001774 }
1775
1776 wpa_supplicant_clear_connection(wpa_s, addr);
1777}
1778
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001779static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1780 struct wpa_ssid *ssid)
1781{
1782 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1783 return;
1784
1785 ssid->disabled = 0;
1786 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1787 wpas_notify_network_enabled_changed(wpa_s, ssid);
1788
1789 /*
1790 * Try to reassociate since there is no current configuration and a new
1791 * network was made available.
1792 */
1793 if (!wpa_s->current_ssid)
1794 wpa_s->reassociate = 1;
1795}
1796
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001797
1798/**
1799 * wpa_supplicant_enable_network - Mark a configured network as enabled
1800 * @wpa_s: wpa_supplicant structure for a network interface
1801 * @ssid: wpa_ssid structure for a configured network or %NULL
1802 *
1803 * Enables the specified network or all networks if no network specified.
1804 */
1805void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1806 struct wpa_ssid *ssid)
1807{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001808 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001809 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1810 wpa_supplicant_enable_one_network(wpa_s, ssid);
1811 } else
1812 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001813
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001814 if (wpa_s->reassociate) {
1815 if (wpa_s->sched_scanning) {
1816 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1817 "new network to scan filters");
1818 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001819 }
1820
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001821 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001822 }
1823}
1824
1825
1826/**
1827 * wpa_supplicant_disable_network - Mark a configured network as disabled
1828 * @wpa_s: wpa_supplicant structure for a network interface
1829 * @ssid: wpa_ssid structure for a configured network or %NULL
1830 *
1831 * Disables the specified network or all networks if no network specified.
1832 */
1833void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1834 struct wpa_ssid *ssid)
1835{
1836 struct wpa_ssid *other_ssid;
1837 int was_disabled;
1838
1839 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001840 if (wpa_s->sched_scanning)
1841 wpa_supplicant_cancel_sched_scan(wpa_s);
1842
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001843 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1844 other_ssid = other_ssid->next) {
1845 was_disabled = other_ssid->disabled;
1846 if (was_disabled == 2)
1847 continue; /* do not change persistent P2P group
1848 * data */
1849
1850 other_ssid->disabled = 1;
1851
1852 if (was_disabled != other_ssid->disabled)
1853 wpas_notify_network_enabled_changed(
1854 wpa_s, other_ssid);
1855 }
1856 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001857 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001858 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1859 } else if (ssid->disabled != 2) {
1860 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001861 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001862 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1863
1864 was_disabled = ssid->disabled;
1865
1866 ssid->disabled = 1;
1867
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001868 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001869 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001870 if (wpa_s->sched_scanning) {
1871 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1872 "to remove network from filters");
1873 wpa_supplicant_cancel_sched_scan(wpa_s);
1874 wpa_supplicant_req_scan(wpa_s, 0, 0);
1875 }
1876 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001877 }
1878}
1879
1880
1881/**
1882 * wpa_supplicant_select_network - Attempt association with a network
1883 * @wpa_s: wpa_supplicant structure for a network interface
1884 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1885 */
1886void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1887 struct wpa_ssid *ssid)
1888{
1889
1890 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001891 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001892
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001893 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001894 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001895 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001896 disconnected = 1;
1897 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001898
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001899 if (ssid)
1900 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1901
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001902 /*
1903 * Mark all other networks disabled or mark all networks enabled if no
1904 * network specified.
1905 */
1906 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1907 other_ssid = other_ssid->next) {
1908 int was_disabled = other_ssid->disabled;
1909 if (was_disabled == 2)
1910 continue; /* do not change persistent P2P group data */
1911
1912 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001913 if (was_disabled && !other_ssid->disabled)
1914 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001915
1916 if (was_disabled != other_ssid->disabled)
1917 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1918 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001919
1920 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1921 /* We are already associated with the selected network */
1922 wpa_printf(MSG_DEBUG, "Already associated with the "
1923 "selected network - do nothing");
1924 return;
1925 }
1926
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001927 if (ssid)
1928 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001929 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001930 wpa_s->disconnected = 0;
1931 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001932
1933 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1934 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001935
1936 if (ssid)
1937 wpas_notify_network_selected(wpa_s, ssid);
1938}
1939
1940
1941/**
1942 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1943 * @wpa_s: wpa_supplicant structure for a network interface
1944 * @ap_scan: AP scan mode
1945 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1946 *
1947 */
1948int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1949{
1950
1951 int old_ap_scan;
1952
1953 if (ap_scan < 0 || ap_scan > 2)
1954 return -1;
1955
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001956#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001957 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1958 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1959 wpa_s->wpa_state < WPA_COMPLETED) {
1960 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1961 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001962 return 0;
1963 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001964#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001965
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001966 old_ap_scan = wpa_s->conf->ap_scan;
1967 wpa_s->conf->ap_scan = ap_scan;
1968
1969 if (old_ap_scan != wpa_s->conf->ap_scan)
1970 wpas_notify_ap_scan_changed(wpa_s);
1971
1972 return 0;
1973}
1974
1975
1976/**
1977 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1978 * @wpa_s: wpa_supplicant structure for a network interface
1979 * @expire_age: Expiration age in seconds
1980 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1981 *
1982 */
1983int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1984 unsigned int bss_expire_age)
1985{
1986 if (bss_expire_age < 10) {
1987 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1988 bss_expire_age);
1989 return -1;
1990 }
1991 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1992 bss_expire_age);
1993 wpa_s->conf->bss_expiration_age = bss_expire_age;
1994
1995 return 0;
1996}
1997
1998
1999/**
2000 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2001 * @wpa_s: wpa_supplicant structure for a network interface
2002 * @expire_count: number of scans after which an unseen BSS is reclaimed
2003 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2004 *
2005 */
2006int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2007 unsigned int bss_expire_count)
2008{
2009 if (bss_expire_count < 1) {
2010 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2011 bss_expire_count);
2012 return -1;
2013 }
2014 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2015 bss_expire_count);
2016 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2017
2018 return 0;
2019}
2020
2021
2022/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07002023 * wpa_supplicant_set_scan_interval - Set scan interval
2024 * @wpa_s: wpa_supplicant structure for a network interface
2025 * @scan_interval: scan interval in seconds
2026 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2027 *
2028 */
2029int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2030 int scan_interval)
2031{
2032 if (scan_interval < 0) {
2033 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2034 scan_interval);
2035 return -1;
2036 }
2037 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2038 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002039 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002040
2041 return 0;
2042}
2043
2044
2045/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002046 * wpa_supplicant_set_debug_params - Set global debug params
2047 * @global: wpa_global structure
2048 * @debug_level: debug level
2049 * @debug_timestamp: determines if show timestamp in debug data
2050 * @debug_show_keys: determines if show keys in debug data
2051 * Returns: 0 if succeed or -1 if debug_level has wrong value
2052 */
2053int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2054 int debug_timestamp, int debug_show_keys)
2055{
2056
2057 int old_level, old_timestamp, old_show_keys;
2058
2059 /* check for allowed debuglevels */
2060 if (debug_level != MSG_EXCESSIVE &&
2061 debug_level != MSG_MSGDUMP &&
2062 debug_level != MSG_DEBUG &&
2063 debug_level != MSG_INFO &&
2064 debug_level != MSG_WARNING &&
2065 debug_level != MSG_ERROR)
2066 return -1;
2067
2068 old_level = wpa_debug_level;
2069 old_timestamp = wpa_debug_timestamp;
2070 old_show_keys = wpa_debug_show_keys;
2071
2072 wpa_debug_level = debug_level;
2073 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2074 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2075
2076 if (wpa_debug_level != old_level)
2077 wpas_notify_debug_level_changed(global);
2078 if (wpa_debug_timestamp != old_timestamp)
2079 wpas_notify_debug_timestamp_changed(global);
2080 if (wpa_debug_show_keys != old_show_keys)
2081 wpas_notify_debug_show_keys_changed(global);
2082
2083 return 0;
2084}
2085
2086
2087/**
2088 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2089 * @wpa_s: Pointer to wpa_supplicant data
2090 * Returns: A pointer to the current network structure or %NULL on failure
2091 */
2092struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2093{
2094 struct wpa_ssid *entry;
2095 u8 ssid[MAX_SSID_LEN];
2096 int res;
2097 size_t ssid_len;
2098 u8 bssid[ETH_ALEN];
2099 int wired;
2100
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002101 res = wpa_drv_get_ssid(wpa_s, ssid);
2102 if (res < 0) {
2103 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2104 "driver");
2105 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002106 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002107 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002108
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002109 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002110 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2111 "driver");
2112 return NULL;
2113 }
2114
2115 wired = wpa_s->conf->ap_scan == 0 &&
2116 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2117
2118 entry = wpa_s->conf->ssid;
2119 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002120 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002121 ((ssid_len == entry->ssid_len &&
2122 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2123 (!entry->bssid_set ||
2124 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2125 return entry;
2126#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002127 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002128 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2129 (entry->ssid == NULL || entry->ssid_len == 0) &&
2130 (!entry->bssid_set ||
2131 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2132 return entry;
2133#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002134
Dmitry Shmidt04949592012-07-19 12:16:46 -07002135 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002136 entry->ssid_len == 0 &&
2137 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2138 return entry;
2139
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002140 entry = entry->next;
2141 }
2142
2143 return NULL;
2144}
2145
2146
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002147static int select_driver(struct wpa_supplicant *wpa_s, int i)
2148{
2149 struct wpa_global *global = wpa_s->global;
2150
2151 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2152 global->drv_priv[i] = wpa_drivers[i]->global_init();
2153 if (global->drv_priv[i] == NULL) {
2154 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2155 "'%s'", wpa_drivers[i]->name);
2156 return -1;
2157 }
2158 }
2159
2160 wpa_s->driver = wpa_drivers[i];
2161 wpa_s->global_drv_priv = global->drv_priv[i];
2162
2163 return 0;
2164}
2165
2166
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002167static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2168 const char *name)
2169{
2170 int i;
2171 size_t len;
2172 const char *pos, *driver = name;
2173
2174 if (wpa_s == NULL)
2175 return -1;
2176
2177 if (wpa_drivers[0] == NULL) {
2178 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2179 "wpa_supplicant");
2180 return -1;
2181 }
2182
2183 if (name == NULL) {
2184 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002185 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002186 }
2187
2188 do {
2189 pos = os_strchr(driver, ',');
2190 if (pos)
2191 len = pos - driver;
2192 else
2193 len = os_strlen(driver);
2194
2195 for (i = 0; wpa_drivers[i]; i++) {
2196 if (os_strlen(wpa_drivers[i]->name) == len &&
2197 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002198 0) {
2199 /* First driver that succeeds wins */
2200 if (select_driver(wpa_s, i) == 0)
2201 return 0;
2202 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002203 }
2204
2205 driver = pos + 1;
2206 } while (pos);
2207
2208 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2209 return -1;
2210}
2211
2212
2213/**
2214 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2215 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2216 * with struct wpa_driver_ops::init()
2217 * @src_addr: Source address of the EAPOL frame
2218 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2219 * @len: Length of the EAPOL data
2220 *
2221 * This function is called for each received EAPOL frame. Most driver
2222 * interfaces rely on more generic OS mechanism for receiving frames through
2223 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2224 * take care of received EAPOL frames and deliver them to the core supplicant
2225 * code by calling this function.
2226 */
2227void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2228 const u8 *buf, size_t len)
2229{
2230 struct wpa_supplicant *wpa_s = ctx;
2231
2232 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2233 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2234
Jouni Malinena05074c2012-12-21 21:35:35 +02002235 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2236 (wpa_s->last_eapol_matches_bssid &&
2237#ifdef CONFIG_AP
2238 !wpa_s->ap_iface &&
2239#endif /* CONFIG_AP */
2240 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002241 /*
2242 * There is possible race condition between receiving the
2243 * association event and the EAPOL frame since they are coming
2244 * through different paths from the driver. In order to avoid
2245 * issues in trying to process the EAPOL frame before receiving
2246 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002247 * the association event is received. This may also be needed in
2248 * driver-based roaming case, so also use src_addr != BSSID as a
2249 * trigger if we have previously confirmed that the
2250 * Authenticator uses BSSID as the src_addr (which is not the
2251 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002252 */
2253 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002254 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2255 wpa_supplicant_state_txt(wpa_s->wpa_state),
2256 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002257 wpabuf_free(wpa_s->pending_eapol_rx);
2258 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2259 if (wpa_s->pending_eapol_rx) {
2260 os_get_time(&wpa_s->pending_eapol_rx_time);
2261 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2262 ETH_ALEN);
2263 }
2264 return;
2265 }
2266
Jouni Malinena05074c2012-12-21 21:35:35 +02002267 wpa_s->last_eapol_matches_bssid =
2268 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2269
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002270#ifdef CONFIG_AP
2271 if (wpa_s->ap_iface) {
2272 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2273 return;
2274 }
2275#endif /* CONFIG_AP */
2276
2277 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2278 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2279 "no key management is configured");
2280 return;
2281 }
2282
2283 if (wpa_s->eapol_received == 0 &&
2284 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2285 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2286 wpa_s->wpa_state != WPA_COMPLETED) &&
2287 (wpa_s->current_ssid == NULL ||
2288 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2289 /* Timeout for completing IEEE 802.1X and WPA authentication */
2290 wpa_supplicant_req_auth_timeout(
2291 wpa_s,
2292 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2293 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2294 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2295 70 : 10, 0);
2296 }
2297 wpa_s->eapol_received++;
2298
2299 if (wpa_s->countermeasures) {
2300 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2301 "EAPOL packet");
2302 return;
2303 }
2304
2305#ifdef CONFIG_IBSS_RSN
2306 if (wpa_s->current_ssid &&
2307 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2308 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2309 return;
2310 }
2311#endif /* CONFIG_IBSS_RSN */
2312
2313 /* Source address of the incoming EAPOL frame could be compared to the
2314 * current BSSID. However, it is possible that a centralized
2315 * Authenticator could be using another MAC address than the BSSID of
2316 * an AP, so just allow any address to be used for now. The replies are
2317 * still sent to the current BSSID (if available), though. */
2318
2319 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2320 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2321 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2322 return;
2323 wpa_drv_poll(wpa_s);
2324 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2325 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2326 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2327 /*
2328 * Set portValid = TRUE here since we are going to skip 4-way
2329 * handshake processing which would normally set portValid. We
2330 * need this to allow the EAPOL state machines to be completed
2331 * without going through EAPOL-Key handshake.
2332 */
2333 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2334 }
2335}
2336
2337
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002338int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002339{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002340 if (wpa_s->driver->send_eapol) {
2341 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2342 if (addr)
2343 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2344 } else if (!(wpa_s->drv_flags &
2345 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002346 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002347 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2348 wpa_drv_get_mac_addr(wpa_s),
2349 ETH_P_EAPOL,
2350 wpa_supplicant_rx_eapol, wpa_s, 0);
2351 if (wpa_s->l2 == NULL)
2352 return -1;
2353 } else {
2354 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2355 if (addr)
2356 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2357 }
2358
2359 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2360 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2361 return -1;
2362 }
2363
2364 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2365 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002366 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2367
2368 return 0;
2369}
2370
2371
Dmitry Shmidt04949592012-07-19 12:16:46 -07002372static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2373 const u8 *buf, size_t len)
2374{
2375 struct wpa_supplicant *wpa_s = ctx;
2376 const struct l2_ethhdr *eth;
2377
2378 if (len < sizeof(*eth))
2379 return;
2380 eth = (const struct l2_ethhdr *) buf;
2381
2382 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2383 !(eth->h_dest[0] & 0x01)) {
2384 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2385 " (bridge - not for this interface - ignore)",
2386 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2387 return;
2388 }
2389
2390 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2391 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2392 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2393 len - sizeof(*eth));
2394}
2395
2396
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002397/**
2398 * wpa_supplicant_driver_init - Initialize driver interface parameters
2399 * @wpa_s: Pointer to wpa_supplicant data
2400 * Returns: 0 on success, -1 on failure
2401 *
2402 * This function is called to initialize driver interface parameters.
2403 * wpa_drv_init() must have been called before this function to initialize the
2404 * driver interface.
2405 */
2406int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2407{
2408 static int interface_count = 0;
2409
2410 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2411 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002412
2413 if (wpa_s->bridge_ifname[0]) {
2414 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2415 "interface '%s'", wpa_s->bridge_ifname);
2416 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2417 wpa_s->own_addr,
2418 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002419 wpa_supplicant_rx_eapol_bridge,
2420 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002421 if (wpa_s->l2_br == NULL) {
2422 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2423 "connection for the bridge interface '%s'",
2424 wpa_s->bridge_ifname);
2425 return -1;
2426 }
2427 }
2428
2429 wpa_clear_keys(wpa_s, NULL);
2430
2431 /* Make sure that TKIP countermeasures are not left enabled (could
2432 * happen if wpa_supplicant is killed during countermeasures. */
2433 wpa_drv_set_countermeasures(wpa_s, 0);
2434
2435 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2436 wpa_drv_flush_pmkid(wpa_s);
2437
2438 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002439 wpa_s->prev_scan_wildcard = 0;
2440
Dmitry Shmidt04949592012-07-19 12:16:46 -07002441 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002442 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2443 100000))
2444 wpa_supplicant_req_scan(wpa_s, interface_count,
2445 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002446 interface_count++;
2447 } else
2448 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2449
2450 return 0;
2451}
2452
2453
2454static int wpa_supplicant_daemon(const char *pid_file)
2455{
2456 wpa_printf(MSG_DEBUG, "Daemonize..");
2457 return os_daemonize(pid_file);
2458}
2459
2460
2461static struct wpa_supplicant * wpa_supplicant_alloc(void)
2462{
2463 struct wpa_supplicant *wpa_s;
2464
2465 wpa_s = os_zalloc(sizeof(*wpa_s));
2466 if (wpa_s == NULL)
2467 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002468 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002469 wpa_s->scan_interval = 5;
2470 wpa_s->new_connection = 1;
2471 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002472 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002473
2474 return wpa_s;
2475}
2476
2477
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002478#ifdef CONFIG_HT_OVERRIDES
2479
2480static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2481 struct ieee80211_ht_capabilities *htcaps,
2482 struct ieee80211_ht_capabilities *htcaps_mask,
2483 const char *ht_mcs)
2484{
2485 /* parse ht_mcs into hex array */
2486 int i;
2487 const char *tmp = ht_mcs;
2488 char *end = NULL;
2489
2490 /* If ht_mcs is null, do not set anything */
2491 if (!ht_mcs)
2492 return 0;
2493
2494 /* This is what we are setting in the kernel */
2495 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2496
2497 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2498
2499 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2500 errno = 0;
2501 long v = strtol(tmp, &end, 16);
2502 if (errno == 0) {
2503 wpa_msg(wpa_s, MSG_DEBUG,
2504 "htcap value[%i]: %ld end: %p tmp: %p",
2505 i, v, end, tmp);
2506 if (end == tmp)
2507 break;
2508
2509 htcaps->supported_mcs_set[i] = v;
2510 tmp = end;
2511 } else {
2512 wpa_msg(wpa_s, MSG_ERROR,
2513 "Failed to parse ht-mcs: %s, error: %s\n",
2514 ht_mcs, strerror(errno));
2515 return -1;
2516 }
2517 }
2518
2519 /*
2520 * If we were able to parse any values, then set mask for the MCS set.
2521 */
2522 if (i) {
2523 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2524 IEEE80211_HT_MCS_MASK_LEN - 1);
2525 /* skip the 3 reserved bits */
2526 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2527 0x1f;
2528 }
2529
2530 return 0;
2531}
2532
2533
2534static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2535 struct ieee80211_ht_capabilities *htcaps,
2536 struct ieee80211_ht_capabilities *htcaps_mask,
2537 int disabled)
2538{
2539 u16 msk;
2540
2541 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2542
2543 if (disabled == -1)
2544 return 0;
2545
2546 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2547 htcaps_mask->ht_capabilities_info |= msk;
2548 if (disabled)
2549 htcaps->ht_capabilities_info &= msk;
2550 else
2551 htcaps->ht_capabilities_info |= msk;
2552
2553 return 0;
2554}
2555
2556
2557static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2558 struct ieee80211_ht_capabilities *htcaps,
2559 struct ieee80211_ht_capabilities *htcaps_mask,
2560 int factor)
2561{
2562 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2563
2564 if (factor == -1)
2565 return 0;
2566
2567 if (factor < 0 || factor > 3) {
2568 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2569 "Must be 0-3 or -1", factor);
2570 return -EINVAL;
2571 }
2572
2573 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2574 htcaps->a_mpdu_params &= ~0x3;
2575 htcaps->a_mpdu_params |= factor & 0x3;
2576
2577 return 0;
2578}
2579
2580
2581static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2582 struct ieee80211_ht_capabilities *htcaps,
2583 struct ieee80211_ht_capabilities *htcaps_mask,
2584 int density)
2585{
2586 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2587
2588 if (density == -1)
2589 return 0;
2590
2591 if (density < 0 || density > 7) {
2592 wpa_msg(wpa_s, MSG_ERROR,
2593 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2594 density);
2595 return -EINVAL;
2596 }
2597
2598 htcaps_mask->a_mpdu_params |= 0x1C;
2599 htcaps->a_mpdu_params &= ~(0x1C);
2600 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2601
2602 return 0;
2603}
2604
2605
2606static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2607 struct ieee80211_ht_capabilities *htcaps,
2608 struct ieee80211_ht_capabilities *htcaps_mask,
2609 int disabled)
2610{
2611 /* Masking these out disables HT40 */
2612 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2613 HT_CAP_INFO_SHORT_GI40MHZ);
2614
2615 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2616
2617 if (disabled)
2618 htcaps->ht_capabilities_info &= ~msk;
2619 else
2620 htcaps->ht_capabilities_info |= msk;
2621
2622 htcaps_mask->ht_capabilities_info |= msk;
2623
2624 return 0;
2625}
2626
2627
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002628static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2629 struct ieee80211_ht_capabilities *htcaps,
2630 struct ieee80211_ht_capabilities *htcaps_mask,
2631 int disabled)
2632{
2633 /* Masking these out disables SGI */
2634 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2635 HT_CAP_INFO_SHORT_GI40MHZ);
2636
2637 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2638
2639 if (disabled)
2640 htcaps->ht_capabilities_info &= ~msk;
2641 else
2642 htcaps->ht_capabilities_info |= msk;
2643
2644 htcaps_mask->ht_capabilities_info |= msk;
2645
2646 return 0;
2647}
2648
2649
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002650void wpa_supplicant_apply_ht_overrides(
2651 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2652 struct wpa_driver_associate_params *params)
2653{
2654 struct ieee80211_ht_capabilities *htcaps;
2655 struct ieee80211_ht_capabilities *htcaps_mask;
2656
2657 if (!ssid)
2658 return;
2659
2660 params->disable_ht = ssid->disable_ht;
2661 if (!params->htcaps || !params->htcaps_mask)
2662 return;
2663
2664 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2665 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2666 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2667 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2668 ssid->disable_max_amsdu);
2669 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2670 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2671 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002672 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002673}
2674
2675#endif /* CONFIG_HT_OVERRIDES */
2676
2677
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002678#ifdef CONFIG_VHT_OVERRIDES
2679void wpa_supplicant_apply_vht_overrides(
2680 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2681 struct wpa_driver_associate_params *params)
2682{
2683 struct ieee80211_vht_capabilities *vhtcaps;
2684 struct ieee80211_vht_capabilities *vhtcaps_mask;
2685
2686 if (!ssid)
2687 return;
2688
2689 params->disable_vht = ssid->disable_vht;
2690
2691 vhtcaps = (void *) params->vhtcaps;
2692 vhtcaps_mask = (void *) params->vhtcaps_mask;
2693
2694 if (!vhtcaps || !vhtcaps_mask)
2695 return;
2696
2697 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2698 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2699
2700#define OVERRIDE_MCS(i) \
2701 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2702 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2703 3 << 2 * (i - 1); \
2704 vhtcaps->vht_supported_mcs_set.tx_map |= \
2705 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2706 } \
2707 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2708 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2709 3 << 2 * (i - 1); \
2710 vhtcaps->vht_supported_mcs_set.rx_map |= \
2711 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2712 }
2713
2714 OVERRIDE_MCS(1);
2715 OVERRIDE_MCS(2);
2716 OVERRIDE_MCS(3);
2717 OVERRIDE_MCS(4);
2718 OVERRIDE_MCS(5);
2719 OVERRIDE_MCS(6);
2720 OVERRIDE_MCS(7);
2721 OVERRIDE_MCS(8);
2722}
2723#endif /* CONFIG_VHT_OVERRIDES */
2724
2725
Dmitry Shmidt04949592012-07-19 12:16:46 -07002726static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2727{
2728#ifdef PCSC_FUNCS
2729 size_t len;
2730
2731 if (!wpa_s->conf->pcsc_reader)
2732 return 0;
2733
2734 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2735 if (!wpa_s->scard)
2736 return 1;
2737
2738 if (wpa_s->conf->pcsc_pin &&
2739 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2740 scard_deinit(wpa_s->scard);
2741 wpa_s->scard = NULL;
2742 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2743 return -1;
2744 }
2745
2746 len = sizeof(wpa_s->imsi) - 1;
2747 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2748 scard_deinit(wpa_s->scard);
2749 wpa_s->scard = NULL;
2750 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2751 return -1;
2752 }
2753 wpa_s->imsi[len] = '\0';
2754
2755 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2756
2757 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2758 wpa_s->imsi, wpa_s->mnc_len);
2759
2760 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2761 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2762#endif /* PCSC_FUNCS */
2763
2764 return 0;
2765}
2766
2767
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002768int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2769{
2770 char *val, *pos;
2771
2772 ext_password_deinit(wpa_s->ext_pw);
2773 wpa_s->ext_pw = NULL;
2774 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2775
2776 if (!wpa_s->conf->ext_password_backend)
2777 return 0;
2778
2779 val = os_strdup(wpa_s->conf->ext_password_backend);
2780 if (val == NULL)
2781 return -1;
2782 pos = os_strchr(val, ':');
2783 if (pos)
2784 *pos++ = '\0';
2785
2786 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2787
2788 wpa_s->ext_pw = ext_password_init(val, pos);
2789 os_free(val);
2790 if (wpa_s->ext_pw == NULL) {
2791 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2792 return -1;
2793 }
2794 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2795
2796 return 0;
2797}
2798
2799
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002800static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2801 struct wpa_interface *iface)
2802{
2803 const char *ifname, *driver;
2804 struct wpa_driver_capa capa;
2805
2806 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2807 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2808 iface->confname ? iface->confname : "N/A",
2809 iface->driver ? iface->driver : "default",
2810 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2811 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2812
2813 if (iface->confname) {
2814#ifdef CONFIG_BACKEND_FILE
2815 wpa_s->confname = os_rel2abs_path(iface->confname);
2816 if (wpa_s->confname == NULL) {
2817 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2818 "for configuration file '%s'.",
2819 iface->confname);
2820 return -1;
2821 }
2822 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2823 iface->confname, wpa_s->confname);
2824#else /* CONFIG_BACKEND_FILE */
2825 wpa_s->confname = os_strdup(iface->confname);
2826#endif /* CONFIG_BACKEND_FILE */
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002827 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002828 if (wpa_s->conf == NULL) {
2829 wpa_printf(MSG_ERROR, "Failed to read or parse "
2830 "configuration '%s'.", wpa_s->confname);
2831 return -1;
2832 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07002833 wpa_s->confanother = os_rel2abs_path(iface->confanother);
2834 wpa_config_read(wpa_s->confanother, wpa_s->conf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002835
2836 /*
2837 * Override ctrl_interface and driver_param if set on command
2838 * line.
2839 */
2840 if (iface->ctrl_interface) {
2841 os_free(wpa_s->conf->ctrl_interface);
2842 wpa_s->conf->ctrl_interface =
2843 os_strdup(iface->ctrl_interface);
2844 }
2845
2846 if (iface->driver_param) {
2847 os_free(wpa_s->conf->driver_param);
2848 wpa_s->conf->driver_param =
2849 os_strdup(iface->driver_param);
2850 }
2851 } else
2852 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2853 iface->driver_param);
2854
2855 if (wpa_s->conf == NULL) {
2856 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2857 return -1;
2858 }
2859
2860 if (iface->ifname == NULL) {
2861 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2862 return -1;
2863 }
2864 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2865 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2866 iface->ifname);
2867 return -1;
2868 }
2869 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2870
2871 if (iface->bridge_ifname) {
2872 if (os_strlen(iface->bridge_ifname) >=
2873 sizeof(wpa_s->bridge_ifname)) {
2874 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2875 "name '%s'.", iface->bridge_ifname);
2876 return -1;
2877 }
2878 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2879 sizeof(wpa_s->bridge_ifname));
2880 }
2881
2882 /* RSNA Supplicant Key Management - INITIALIZE */
2883 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2884 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2885
2886 /* Initialize driver interface and register driver event handler before
2887 * L2 receive handler so that association events are processed before
2888 * EAPOL-Key packets if both become available for the same select()
2889 * call. */
2890 driver = iface->driver;
2891next_driver:
2892 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2893 return -1;
2894
2895 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2896 if (wpa_s->drv_priv == NULL) {
2897 const char *pos;
2898 pos = driver ? os_strchr(driver, ',') : NULL;
2899 if (pos) {
2900 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2901 "driver interface - try next driver wrapper");
2902 driver = pos + 1;
2903 goto next_driver;
2904 }
2905 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2906 "interface");
2907 return -1;
2908 }
2909 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2910 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2911 "driver_param '%s'", wpa_s->conf->driver_param);
2912 return -1;
2913 }
2914
2915 ifname = wpa_drv_get_ifname(wpa_s);
2916 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2917 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2918 "interface name with '%s'", ifname);
2919 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2920 }
2921
2922 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2923 return -1;
2924
2925 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2926 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2927 NULL);
2928 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2929
2930 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2931 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2932 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2933 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2934 "dot11RSNAConfigPMKLifetime");
2935 return -1;
2936 }
2937
2938 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2939 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2940 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2941 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2942 "dot11RSNAConfigPMKReauthThreshold");
2943 return -1;
2944 }
2945
2946 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2947 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2948 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2949 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2950 "dot11RSNAConfigSATimeout");
2951 return -1;
2952 }
2953
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002954 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2955 &wpa_s->hw.num_modes,
2956 &wpa_s->hw.flags);
2957
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002958 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002959 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002960 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002961 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002962 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002963 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002964 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2965 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2966 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002967 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2968 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07002969 wpa_s->extended_capa = capa.extended_capa;
2970 wpa_s->extended_capa_mask = capa.extended_capa_mask;
2971 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002972 }
2973 if (wpa_s->max_remain_on_chan == 0)
2974 wpa_s->max_remain_on_chan = 1000;
2975
2976 if (wpa_supplicant_driver_init(wpa_s) < 0)
2977 return -1;
2978
2979#ifdef CONFIG_TDLS
2980 if (wpa_tdls_init(wpa_s->wpa))
2981 return -1;
2982#endif /* CONFIG_TDLS */
2983
2984 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2985 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2986 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2987 return -1;
2988 }
2989
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002990 if (wpas_wps_init(wpa_s))
2991 return -1;
2992
2993 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2994 return -1;
2995 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2996
2997 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2998 if (wpa_s->ctrl_iface == NULL) {
2999 wpa_printf(MSG_ERROR,
3000 "Failed to initialize control interface '%s'.\n"
3001 "You may have another wpa_supplicant process "
3002 "already running or the file was\n"
3003 "left by an unclean termination of wpa_supplicant "
3004 "in which case you will need\n"
3005 "to manually remove this file before starting "
3006 "wpa_supplicant again.\n",
3007 wpa_s->conf->ctrl_interface);
3008 return -1;
3009 }
3010
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003011 wpa_s->gas = gas_query_init(wpa_s);
3012 if (wpa_s->gas == NULL) {
3013 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3014 return -1;
3015 }
3016
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003017#ifdef CONFIG_P2P
3018 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
3019 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
3020 return -1;
3021 }
3022#endif /* CONFIG_P2P */
3023
3024 if (wpa_bss_init(wpa_s) < 0)
3025 return -1;
3026
Dmitry Shmidt04949592012-07-19 12:16:46 -07003027 if (pcsc_reader_init(wpa_s) < 0)
3028 return -1;
3029
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003030 if (wpas_init_ext_pw(wpa_s) < 0)
3031 return -1;
3032
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003033 return 0;
3034}
3035
3036
3037static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003038 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003039{
3040 if (wpa_s->drv_priv) {
3041 wpa_supplicant_deauthenticate(wpa_s,
3042 WLAN_REASON_DEAUTH_LEAVING);
3043
3044 wpa_drv_set_countermeasures(wpa_s, 0);
3045 wpa_clear_keys(wpa_s, NULL);
3046 }
3047
3048 wpa_supplicant_cleanup(wpa_s);
3049
Dmitry Shmidt04949592012-07-19 12:16:46 -07003050#ifdef CONFIG_P2P
3051 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3052 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3053 "the management interface is being removed");
3054 wpas_p2p_deinit_global(wpa_s->global);
3055 }
3056#endif /* CONFIG_P2P */
3057
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003058 if (wpa_s->drv_priv)
3059 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003060
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003061 if (notify)
3062 wpas_notify_iface_removed(wpa_s);
3063
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003064 if (terminate)
3065 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003066
3067 if (wpa_s->ctrl_iface) {
3068 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3069 wpa_s->ctrl_iface = NULL;
3070 }
3071
3072 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003073 wpa_config_free(wpa_s->conf);
3074 wpa_s->conf = NULL;
3075 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003076}
3077
3078
3079/**
3080 * wpa_supplicant_add_iface - Add a new network interface
3081 * @global: Pointer to global data from wpa_supplicant_init()
3082 * @iface: Interface configuration options
3083 * Returns: Pointer to the created interface or %NULL on failure
3084 *
3085 * This function is used to add new network interfaces for %wpa_supplicant.
3086 * This can be called before wpa_supplicant_run() to add interfaces before the
3087 * main event loop has been started. In addition, new interfaces can be added
3088 * dynamically while %wpa_supplicant is already running. This could happen,
3089 * e.g., when a hotplug network adapter is inserted.
3090 */
3091struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3092 struct wpa_interface *iface)
3093{
3094 struct wpa_supplicant *wpa_s;
3095 struct wpa_interface t_iface;
3096 struct wpa_ssid *ssid;
3097
3098 if (global == NULL || iface == NULL)
3099 return NULL;
3100
3101 wpa_s = wpa_supplicant_alloc();
3102 if (wpa_s == NULL)
3103 return NULL;
3104
3105 wpa_s->global = global;
3106
3107 t_iface = *iface;
3108 if (global->params.override_driver) {
3109 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3110 "('%s' -> '%s')",
3111 iface->driver, global->params.override_driver);
3112 t_iface.driver = global->params.override_driver;
3113 }
3114 if (global->params.override_ctrl_interface) {
3115 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3116 "ctrl_interface ('%s' -> '%s')",
3117 iface->ctrl_interface,
3118 global->params.override_ctrl_interface);
3119 t_iface.ctrl_interface =
3120 global->params.override_ctrl_interface;
3121 }
3122 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3123 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3124 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003125 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003126 os_free(wpa_s);
3127 return NULL;
3128 }
3129
3130 /* Notify the control interfaces about new iface */
3131 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003132 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003133 os_free(wpa_s);
3134 return NULL;
3135 }
3136
3137 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3138 wpas_notify_network_added(wpa_s, ssid);
3139
3140 wpa_s->next = global->ifaces;
3141 global->ifaces = wpa_s;
3142
3143 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003144 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003145
3146 return wpa_s;
3147}
3148
3149
3150/**
3151 * wpa_supplicant_remove_iface - Remove a network interface
3152 * @global: Pointer to global data from wpa_supplicant_init()
3153 * @wpa_s: Pointer to the network interface to be removed
3154 * Returns: 0 if interface was removed, -1 if interface was not found
3155 *
3156 * This function can be used to dynamically remove network interfaces from
3157 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3158 * addition, this function is used to remove all remaining interfaces when
3159 * %wpa_supplicant is terminated.
3160 */
3161int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003162 struct wpa_supplicant *wpa_s,
3163 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003164{
3165 struct wpa_supplicant *prev;
3166
3167 /* Remove interface from the global list of interfaces */
3168 prev = global->ifaces;
3169 if (prev == wpa_s) {
3170 global->ifaces = wpa_s->next;
3171 } else {
3172 while (prev && prev->next != wpa_s)
3173 prev = prev->next;
3174 if (prev == NULL)
3175 return -1;
3176 prev->next = wpa_s->next;
3177 }
3178
3179 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3180
3181 if (global->p2p_group_formation == wpa_s)
3182 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07003183 if (global->p2p_invite_group == wpa_s)
3184 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003185 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003186 os_free(wpa_s);
3187
3188 return 0;
3189}
3190
3191
3192/**
3193 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3194 * @wpa_s: Pointer to the network interface
3195 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3196 */
3197const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3198{
3199 const char *eapol_method;
3200
3201 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3202 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3203 return "NO-EAP";
3204 }
3205
3206 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3207 if (eapol_method == NULL)
3208 return "UNKNOWN-EAP";
3209
3210 return eapol_method;
3211}
3212
3213
3214/**
3215 * wpa_supplicant_get_iface - Get a new network interface
3216 * @global: Pointer to global data from wpa_supplicant_init()
3217 * @ifname: Interface name
3218 * Returns: Pointer to the interface or %NULL if not found
3219 */
3220struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3221 const char *ifname)
3222{
3223 struct wpa_supplicant *wpa_s;
3224
3225 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3226 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3227 return wpa_s;
3228 }
3229 return NULL;
3230}
3231
3232
3233#ifndef CONFIG_NO_WPA_MSG
3234static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3235{
3236 struct wpa_supplicant *wpa_s = ctx;
3237 if (wpa_s == NULL)
3238 return NULL;
3239 return wpa_s->ifname;
3240}
3241#endif /* CONFIG_NO_WPA_MSG */
3242
3243
3244/**
3245 * wpa_supplicant_init - Initialize %wpa_supplicant
3246 * @params: Parameters for %wpa_supplicant
3247 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3248 *
3249 * This function is used to initialize %wpa_supplicant. After successful
3250 * initialization, the returned data pointer can be used to add and remove
3251 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3252 */
3253struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3254{
3255 struct wpa_global *global;
3256 int ret, i;
3257
3258 if (params == NULL)
3259 return NULL;
3260
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003261#ifdef CONFIG_DRIVER_NDIS
3262 {
3263 void driver_ndis_init_ops(void);
3264 driver_ndis_init_ops();
3265 }
3266#endif /* CONFIG_DRIVER_NDIS */
3267
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003268#ifndef CONFIG_NO_WPA_MSG
3269 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3270#endif /* CONFIG_NO_WPA_MSG */
3271
3272 wpa_debug_open_file(params->wpa_debug_file_path);
3273 if (params->wpa_debug_syslog)
3274 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003275 if (params->wpa_debug_tracing) {
3276 ret = wpa_debug_open_linux_tracing();
3277 if (ret) {
3278 wpa_printf(MSG_ERROR,
3279 "Failed to enable trace logging");
3280 return NULL;
3281 }
3282 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003283
3284 ret = eap_register_methods();
3285 if (ret) {
3286 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3287 if (ret == -2)
3288 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3289 "the same EAP type.");
3290 return NULL;
3291 }
3292
3293 global = os_zalloc(sizeof(*global));
3294 if (global == NULL)
3295 return NULL;
3296 dl_list_init(&global->p2p_srv_bonjour);
3297 dl_list_init(&global->p2p_srv_upnp);
3298 global->params.daemonize = params->daemonize;
3299 global->params.wait_for_monitor = params->wait_for_monitor;
3300 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3301 if (params->pid_file)
3302 global->params.pid_file = os_strdup(params->pid_file);
3303 if (params->ctrl_interface)
3304 global->params.ctrl_interface =
3305 os_strdup(params->ctrl_interface);
3306 if (params->override_driver)
3307 global->params.override_driver =
3308 os_strdup(params->override_driver);
3309 if (params->override_ctrl_interface)
3310 global->params.override_ctrl_interface =
3311 os_strdup(params->override_ctrl_interface);
3312 wpa_debug_level = global->params.wpa_debug_level =
3313 params->wpa_debug_level;
3314 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3315 params->wpa_debug_show_keys;
3316 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3317 params->wpa_debug_timestamp;
3318
3319 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3320
3321 if (eloop_init()) {
3322 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3323 wpa_supplicant_deinit(global);
3324 return NULL;
3325 }
3326
Jouni Malinen75ecf522011-06-27 15:19:46 -07003327 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003328
3329 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3330 if (global->ctrl_iface == NULL) {
3331 wpa_supplicant_deinit(global);
3332 return NULL;
3333 }
3334
3335 if (wpas_notify_supplicant_initialized(global)) {
3336 wpa_supplicant_deinit(global);
3337 return NULL;
3338 }
3339
3340 for (i = 0; wpa_drivers[i]; i++)
3341 global->drv_count++;
3342 if (global->drv_count == 0) {
3343 wpa_printf(MSG_ERROR, "No drivers enabled");
3344 wpa_supplicant_deinit(global);
3345 return NULL;
3346 }
3347 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3348 if (global->drv_priv == NULL) {
3349 wpa_supplicant_deinit(global);
3350 return NULL;
3351 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003352
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003353#ifdef CONFIG_WIFI_DISPLAY
3354 if (wifi_display_init(global) < 0) {
3355 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3356 wpa_supplicant_deinit(global);
3357 return NULL;
3358 }
3359#endif /* CONFIG_WIFI_DISPLAY */
3360
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003361 return global;
3362}
3363
3364
3365/**
3366 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3367 * @global: Pointer to global data from wpa_supplicant_init()
3368 * Returns: 0 after successful event loop run, -1 on failure
3369 *
3370 * This function starts the main event loop and continues running as long as
3371 * there are any remaining events. In most cases, this function is running as
3372 * long as the %wpa_supplicant process in still in use.
3373 */
3374int wpa_supplicant_run(struct wpa_global *global)
3375{
3376 struct wpa_supplicant *wpa_s;
3377
3378 if (global->params.daemonize &&
3379 wpa_supplicant_daemon(global->params.pid_file))
3380 return -1;
3381
3382 if (global->params.wait_for_monitor) {
3383 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3384 if (wpa_s->ctrl_iface)
3385 wpa_supplicant_ctrl_iface_wait(
3386 wpa_s->ctrl_iface);
3387 }
3388
3389 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3390 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3391
3392 eloop_run();
3393
3394 return 0;
3395}
3396
3397
3398/**
3399 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3400 * @global: Pointer to global data from wpa_supplicant_init()
3401 *
3402 * This function is called to deinitialize %wpa_supplicant and to free all
3403 * allocated resources. Remaining network interfaces will also be removed.
3404 */
3405void wpa_supplicant_deinit(struct wpa_global *global)
3406{
3407 int i;
3408
3409 if (global == NULL)
3410 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003411
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003412#ifdef CONFIG_WIFI_DISPLAY
3413 wifi_display_deinit(global);
3414#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003415#ifdef CONFIG_P2P
3416 wpas_p2p_deinit_global(global);
3417#endif /* CONFIG_P2P */
3418
3419 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003420 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003421
3422 if (global->ctrl_iface)
3423 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3424
3425 wpas_notify_supplicant_deinitialized(global);
3426
3427 eap_peer_unregister_methods();
3428#ifdef CONFIG_AP
3429 eap_server_unregister_methods();
3430#endif /* CONFIG_AP */
3431
3432 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3433 if (!global->drv_priv[i])
3434 continue;
3435 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3436 }
3437 os_free(global->drv_priv);
3438
3439 random_deinit();
3440
3441 eloop_destroy();
3442
3443 if (global->params.pid_file) {
3444 os_daemonize_terminate(global->params.pid_file);
3445 os_free(global->params.pid_file);
3446 }
3447 os_free(global->params.ctrl_interface);
3448 os_free(global->params.override_driver);
3449 os_free(global->params.override_ctrl_interface);
3450
Dmitry Shmidt04949592012-07-19 12:16:46 -07003451 os_free(global->p2p_disallow_freq);
3452
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003453 os_free(global);
3454 wpa_debug_close_syslog();
3455 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003456 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003457}
3458
3459
3460void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3461{
3462 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3463 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3464 char country[3];
3465 country[0] = wpa_s->conf->country[0];
3466 country[1] = wpa_s->conf->country[1];
3467 country[2] = '\0';
3468 if (wpa_drv_set_country(wpa_s, country) < 0) {
3469 wpa_printf(MSG_ERROR, "Failed to set country code "
3470 "'%s'", country);
3471 }
3472 }
3473
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003474 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3475 wpas_init_ext_pw(wpa_s);
3476
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003477#ifdef CONFIG_WPS
3478 wpas_wps_update_config(wpa_s);
3479#endif /* CONFIG_WPS */
3480
3481#ifdef CONFIG_P2P
3482 wpas_p2p_update_config(wpa_s);
3483#endif /* CONFIG_P2P */
3484
3485 wpa_s->conf->changed_parameters = 0;
3486}
3487
3488
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003489static void add_freq(int *freqs, int *num_freqs, int freq)
3490{
3491 int i;
3492
3493 for (i = 0; i < *num_freqs; i++) {
3494 if (freqs[i] == freq)
3495 return;
3496 }
3497
3498 freqs[*num_freqs] = freq;
3499 (*num_freqs)++;
3500}
3501
3502
3503static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3504{
3505 struct wpa_bss *bss, *cbss;
3506 const int max_freqs = 10;
3507 int *freqs;
3508 int num_freqs = 0;
3509
3510 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3511 if (freqs == NULL)
3512 return NULL;
3513
3514 cbss = wpa_s->current_bss;
3515
3516 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3517 if (bss == cbss)
3518 continue;
3519 if (bss->ssid_len == cbss->ssid_len &&
3520 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3521 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3522 add_freq(freqs, &num_freqs, bss->freq);
3523 if (num_freqs == max_freqs)
3524 break;
3525 }
3526 }
3527
3528 if (num_freqs == 0) {
3529 os_free(freqs);
3530 freqs = NULL;
3531 }
3532
3533 return freqs;
3534}
3535
3536
3537void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3538{
3539 int timeout;
3540 int count;
3541 int *freqs = NULL;
3542
3543 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003544 * Remove possible authentication timeout since the connection failed.
3545 */
3546 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3547
3548 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003549 * Add the failed BSSID into the blacklist and speed up next scan
3550 * attempt if there could be other APs that could accept association.
3551 * The current blacklist count indicates how many times we have tried
3552 * connecting to this AP and multiple attempts mean that other APs are
3553 * either not available or has already been tried, so that we can start
3554 * increasing the delay here to avoid constant scanning.
3555 */
3556 count = wpa_blacklist_add(wpa_s, bssid);
3557 if (count == 1 && wpa_s->current_bss) {
3558 /*
3559 * This BSS was not in the blacklist before. If there is
3560 * another BSS available for the same ESS, we should try that
3561 * next. Otherwise, we may as well try this one once more
3562 * before allowing other, likely worse, ESSes to be considered.
3563 */
3564 freqs = get_bss_freqs_in_ess(wpa_s);
3565 if (freqs) {
3566 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3567 "has been seen; try it next");
3568 wpa_blacklist_add(wpa_s, bssid);
3569 /*
3570 * On the next scan, go through only the known channels
3571 * used in this ESS based on previous scans to speed up
3572 * common load balancing use case.
3573 */
3574 os_free(wpa_s->next_scan_freqs);
3575 wpa_s->next_scan_freqs = freqs;
3576 }
3577 }
3578
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003579 /*
3580 * Add previous failure count in case the temporary blacklist was
3581 * cleared due to no other BSSes being available.
3582 */
3583 count += wpa_s->extra_blacklist_count;
3584
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003585 switch (count) {
3586 case 1:
3587 timeout = 100;
3588 break;
3589 case 2:
3590 timeout = 500;
3591 break;
3592 case 3:
3593 timeout = 1000;
3594 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003595 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003596 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003597 break;
3598 default:
3599 timeout = 10000;
3600 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003601 }
3602
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003603 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3604 "ms", count, timeout);
3605
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003606 /*
3607 * TODO: if more than one possible AP is available in scan results,
3608 * could try the other ones before requesting a new scan.
3609 */
3610 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3611 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003612
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -07003613 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003614}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003615
3616
3617int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3618{
3619 return wpa_s->conf->ap_scan == 2 ||
3620 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3621}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003622
Dmitry Shmidt04949592012-07-19 12:16:46 -07003623
3624#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3625int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3626 struct wpa_ssid *ssid,
3627 const char *field,
3628 const char *value)
3629{
3630#ifdef IEEE8021X_EAPOL
3631 struct eap_peer_config *eap = &ssid->eap;
3632
3633 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3634 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3635 (const u8 *) value, os_strlen(value));
3636
3637 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3638 case WPA_CTRL_REQ_EAP_IDENTITY:
3639 os_free(eap->identity);
3640 eap->identity = (u8 *) os_strdup(value);
3641 eap->identity_len = os_strlen(value);
3642 eap->pending_req_identity = 0;
3643 if (ssid == wpa_s->current_ssid)
3644 wpa_s->reassociate = 1;
3645 break;
3646 case WPA_CTRL_REQ_EAP_PASSWORD:
3647 os_free(eap->password);
3648 eap->password = (u8 *) os_strdup(value);
3649 eap->password_len = os_strlen(value);
3650 eap->pending_req_password = 0;
3651 if (ssid == wpa_s->current_ssid)
3652 wpa_s->reassociate = 1;
3653 break;
3654 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3655 os_free(eap->new_password);
3656 eap->new_password = (u8 *) os_strdup(value);
3657 eap->new_password_len = os_strlen(value);
3658 eap->pending_req_new_password = 0;
3659 if (ssid == wpa_s->current_ssid)
3660 wpa_s->reassociate = 1;
3661 break;
3662 case WPA_CTRL_REQ_EAP_PIN:
3663 os_free(eap->pin);
3664 eap->pin = os_strdup(value);
3665 eap->pending_req_pin = 0;
3666 if (ssid == wpa_s->current_ssid)
3667 wpa_s->reassociate = 1;
3668 break;
3669 case WPA_CTRL_REQ_EAP_OTP:
3670 os_free(eap->otp);
3671 eap->otp = (u8 *) os_strdup(value);
3672 eap->otp_len = os_strlen(value);
3673 os_free(eap->pending_req_otp);
3674 eap->pending_req_otp = NULL;
3675 eap->pending_req_otp_len = 0;
3676 break;
3677 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3678 os_free(eap->private_key_passwd);
3679 eap->private_key_passwd = (u8 *) os_strdup(value);
3680 eap->pending_req_passphrase = 0;
3681 if (ssid == wpa_s->current_ssid)
3682 wpa_s->reassociate = 1;
3683 break;
3684 default:
3685 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3686 return -1;
3687 }
3688
3689 return 0;
3690#else /* IEEE8021X_EAPOL */
3691 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3692 return -1;
3693#endif /* IEEE8021X_EAPOL */
3694}
3695#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3696
3697
3698int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3699{
3700 int i;
3701 unsigned int drv_enc;
3702
3703 if (ssid == NULL)
3704 return 1;
3705
3706 if (ssid->disabled)
3707 return 1;
3708
3709 if (wpa_s && wpa_s->drv_capa_known)
3710 drv_enc = wpa_s->drv_enc;
3711 else
3712 drv_enc = (unsigned int) -1;
3713
3714 for (i = 0; i < NUM_WEP_KEYS; i++) {
3715 size_t len = ssid->wep_key_len[i];
3716 if (len == 0)
3717 continue;
3718 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3719 continue;
3720 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3721 continue;
3722 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3723 continue;
3724 return 1; /* invalid WEP key */
3725 }
3726
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003727 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3728 !ssid->ext_psk)
3729 return 1;
3730
Dmitry Shmidt04949592012-07-19 12:16:46 -07003731 return 0;
3732}
3733
3734
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003735int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003736{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003737 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003738 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003739 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003740 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003741 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003742}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003743
3744
3745void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3746{
3747 struct wpa_ssid *ssid = wpa_s->current_ssid;
3748 int dur;
3749 struct os_time now;
3750
3751 if (ssid == NULL) {
3752 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3753 "SSID block");
3754 return;
3755 }
3756
3757 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3758 return;
3759
3760 ssid->auth_failures++;
3761 if (ssid->auth_failures > 50)
3762 dur = 300;
3763 else if (ssid->auth_failures > 20)
3764 dur = 120;
3765 else if (ssid->auth_failures > 10)
3766 dur = 60;
3767 else if (ssid->auth_failures > 5)
3768 dur = 30;
3769 else if (ssid->auth_failures > 1)
3770 dur = 20;
3771 else
3772 dur = 10;
3773
3774 os_get_time(&now);
3775 if (now.sec + dur <= ssid->disabled_until.sec)
3776 return;
3777
3778 ssid->disabled_until.sec = now.sec + dur;
3779
3780 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3781 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3782 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3783 ssid->auth_failures, dur);
3784}
3785
3786
3787void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3788 struct wpa_ssid *ssid, int clear_failures)
3789{
3790 if (ssid == NULL)
3791 return;
3792
3793 if (ssid->disabled_until.sec) {
3794 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3795 "id=%d ssid=\"%s\"",
3796 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3797 }
3798 ssid->disabled_until.sec = 0;
3799 ssid->disabled_until.usec = 0;
3800 if (clear_failures)
3801 ssid->auth_failures = 0;
3802}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003803
3804
3805int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3806{
3807 size_t i;
3808
3809 if (wpa_s->disallow_aps_bssid == NULL)
3810 return 0;
3811
3812 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3813 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3814 bssid, ETH_ALEN) == 0)
3815 return 1;
3816 }
3817
3818 return 0;
3819}
3820
3821
3822int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3823 size_t ssid_len)
3824{
3825 size_t i;
3826
3827 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3828 return 0;
3829
3830 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3831 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3832 if (ssid_len == s->ssid_len &&
3833 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3834 return 1;
3835 }
3836
3837 return 0;
3838}
3839
3840
3841/**
3842 * wpas_request_connection - Request a new connection
3843 * @wpa_s: Pointer to the network interface
3844 *
3845 * This function is used to request a new connection to be found. It will mark
3846 * the interface to allow reassociation and request a new scan to find a
3847 * suitable network to connect to.
3848 */
3849void wpas_request_connection(struct wpa_supplicant *wpa_s)
3850{
3851 wpa_s->normal_scans = 0;
3852 wpa_supplicant_reinit_autoscan(wpa_s);
3853 wpa_s->extra_blacklist_count = 0;
3854 wpa_s->disconnected = 0;
3855 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003856
3857 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3858 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003859}