blob: 6fb1caee7a17f014561a891dd541ee7f83af7ccc [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;
769 conf = wpa_config_read(wpa_s->confname);
770 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 }
775 conf->changed_parameters = (unsigned int) -1;
776
777 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
778 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
779 os_strcmp(conf->ctrl_interface,
780 wpa_s->conf->ctrl_interface) != 0);
781
782 if (reconf_ctrl && wpa_s->ctrl_iface) {
783 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
784 wpa_s->ctrl_iface = NULL;
785 }
786
787 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800788 if (wpa_s->current_ssid) {
789 wpa_supplicant_deauthenticate(wpa_s,
790 WLAN_REASON_DEAUTH_LEAVING);
791 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700792
793 /*
794 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
795 * pkcs11_engine_path, pkcs11_module_path.
796 */
797 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
798 /*
799 * Clear forced success to clear EAP state for next
800 * authentication.
801 */
802 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
803 }
804 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
805 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800806 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700807 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
808 rsn_preauth_deinit(wpa_s->wpa);
809
810 old_ap_scan = wpa_s->conf->ap_scan;
811 wpa_config_free(wpa_s->conf);
812 wpa_s->conf = conf;
813 if (old_ap_scan != wpa_s->conf->ap_scan)
814 wpas_notify_ap_scan_changed(wpa_s);
815
816 if (reconf_ctrl)
817 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
818
819 wpa_supplicant_update_config(wpa_s);
820
821 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700822 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823 wpa_s->reassociate = 1;
824 wpa_supplicant_req_scan(wpa_s, 0, 0);
825 }
826 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
827 return 0;
828}
829
830
831static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
832{
833 struct wpa_global *global = signal_ctx;
834 struct wpa_supplicant *wpa_s;
835 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
836 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
837 sig);
838 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
839 wpa_supplicant_terminate_proc(global);
840 }
841 }
842}
843
844
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700845enum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
846{
847 switch (key_mgmt) {
848 case WPA_KEY_MGMT_NONE:
849 return KEY_MGMT_NONE;
850 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
851 return KEY_MGMT_802_1X_NO_WPA;
852 case WPA_KEY_MGMT_IEEE8021X:
853 return KEY_MGMT_802_1X;
854 case WPA_KEY_MGMT_WPA_NONE:
855 return KEY_MGMT_WPA_NONE;
856 case WPA_KEY_MGMT_FT_IEEE8021X:
857 return KEY_MGMT_FT_802_1X;
858 case WPA_KEY_MGMT_FT_PSK:
859 return KEY_MGMT_FT_PSK;
860 case WPA_KEY_MGMT_IEEE8021X_SHA256:
861 return KEY_MGMT_802_1X_SHA256;
862 case WPA_KEY_MGMT_PSK_SHA256:
863 return KEY_MGMT_PSK_SHA256;
864 case WPA_KEY_MGMT_WPS:
865 return KEY_MGMT_WPS;
866 case WPA_KEY_MGMT_PSK:
867 default:
868 return KEY_MGMT_PSK;
869 }
870}
871
872
873static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
874 struct wpa_ssid *ssid,
875 struct wpa_ie_data *ie)
876{
877 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
878 if (ret) {
879 if (ret == -2) {
880 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
881 "from association info");
882 }
883 return -1;
884 }
885
886 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
887 "cipher suites");
888 if (!(ie->group_cipher & ssid->group_cipher)) {
889 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
890 "cipher 0x%x (mask 0x%x) - reject",
891 ie->group_cipher, ssid->group_cipher);
892 return -1;
893 }
894 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
895 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
896 "cipher 0x%x (mask 0x%x) - reject",
897 ie->pairwise_cipher, ssid->pairwise_cipher);
898 return -1;
899 }
900 if (!(ie->key_mgmt & ssid->key_mgmt)) {
901 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
902 "management 0x%x (mask 0x%x) - reject",
903 ie->key_mgmt, ssid->key_mgmt);
904 return -1;
905 }
906
907#ifdef CONFIG_IEEE80211W
908 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800909 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
910 wpa_s->conf->pmf : ssid->ieee80211w) ==
911 MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700912 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
913 "that does not support management frame protection - "
914 "reject");
915 return -1;
916 }
917#endif /* CONFIG_IEEE80211W */
918
919 return 0;
920}
921
922
923/**
924 * wpa_supplicant_set_suites - Set authentication and encryption parameters
925 * @wpa_s: Pointer to wpa_supplicant data
926 * @bss: Scan results for the selected BSS, or %NULL if not available
927 * @ssid: Configuration data for the selected network
928 * @wpa_ie: Buffer for the WPA/RSN IE
929 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
930 * used buffer length in case the functions returns success.
931 * Returns: 0 on success or -1 on failure
932 *
933 * This function is used to configure authentication and encryption parameters
934 * based on the network configuration and scan result for the selected BSS (if
935 * available).
936 */
937int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
938 struct wpa_bss *bss, struct wpa_ssid *ssid,
939 u8 *wpa_ie, size_t *wpa_ie_len)
940{
941 struct wpa_ie_data ie;
942 int sel, proto;
943 const u8 *bss_wpa, *bss_rsn;
944
945 if (bss) {
946 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
947 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
948 } else
949 bss_wpa = bss_rsn = NULL;
950
951 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
952 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
953 (ie.group_cipher & ssid->group_cipher) &&
954 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
955 (ie.key_mgmt & ssid->key_mgmt)) {
956 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
957 proto = WPA_PROTO_RSN;
958 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
959 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
960 (ie.group_cipher & ssid->group_cipher) &&
961 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
962 (ie.key_mgmt & ssid->key_mgmt)) {
963 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
964 proto = WPA_PROTO_WPA;
965 } else if (bss) {
966 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
967 return -1;
968 } else {
969 if (ssid->proto & WPA_PROTO_RSN)
970 proto = WPA_PROTO_RSN;
971 else
972 proto = WPA_PROTO_WPA;
973 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
974 os_memset(&ie, 0, sizeof(ie));
975 ie.group_cipher = ssid->group_cipher;
976 ie.pairwise_cipher = ssid->pairwise_cipher;
977 ie.key_mgmt = ssid->key_mgmt;
978#ifdef CONFIG_IEEE80211W
979 ie.mgmt_group_cipher =
980 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
981 WPA_CIPHER_AES_128_CMAC : 0;
982#endif /* CONFIG_IEEE80211W */
983 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
984 "based on configuration");
985 } else
986 proto = ie.proto;
987 }
988
989 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
990 "pairwise %d key_mgmt %d proto %d",
991 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
992#ifdef CONFIG_IEEE80211W
993 if (ssid->ieee80211w) {
994 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
995 ie.mgmt_group_cipher);
996 }
997#endif /* CONFIG_IEEE80211W */
998
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800999 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001000 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1001 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1002 !!(ssid->proto & WPA_PROTO_RSN));
1003
1004 if (bss || !wpa_s->ap_ies_from_associnfo) {
1005 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1006 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1007 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1008 bss_rsn ? 2 + bss_rsn[1] : 0))
1009 return -1;
1010 }
1011
1012 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001013 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1014 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001015 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1016 "cipher");
1017 return -1;
1018 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001019 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1020 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001021
1022 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001023 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1024 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001025 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1026 "cipher");
1027 return -1;
1028 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001029 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1030 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001031
1032 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001033#ifdef CONFIG_SAE
1034 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1035 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1036#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001037 if (0) {
1038#ifdef CONFIG_IEEE80211R
1039 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1040 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1041 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1042 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1043 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1044 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1045#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001046#ifdef CONFIG_SAE
1047 } else if (sel & WPA_KEY_MGMT_SAE) {
1048 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1049 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1050 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1051 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1052 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1053#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001054#ifdef CONFIG_IEEE80211W
1055 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1056 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1057 wpa_dbg(wpa_s, MSG_DEBUG,
1058 "WPA: using KEY_MGMT 802.1X with SHA256");
1059 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1060 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1061 wpa_dbg(wpa_s, MSG_DEBUG,
1062 "WPA: using KEY_MGMT PSK with SHA256");
1063#endif /* CONFIG_IEEE80211W */
1064 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1065 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1066 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1067 } else if (sel & WPA_KEY_MGMT_PSK) {
1068 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1069 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1070 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1071 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1072 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1073 } else {
1074 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1075 "authenticated key management type");
1076 return -1;
1077 }
1078
1079 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1080 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1081 wpa_s->pairwise_cipher);
1082 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1083
1084#ifdef CONFIG_IEEE80211W
1085 sel = ie.mgmt_group_cipher;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001086 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1087 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001088 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1089 sel = 0;
1090 if (sel & WPA_CIPHER_AES_128_CMAC) {
1091 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1092 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1093 "AES-128-CMAC");
1094 } else {
1095 wpa_s->mgmt_group_cipher = 0;
1096 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1097 }
1098 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1099 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001100 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1101 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1102 wpa_s->conf->pmf : ssid->ieee80211w));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001103#endif /* CONFIG_IEEE80211W */
1104
1105 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1106 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1107 return -1;
1108 }
1109
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001110 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001111 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001112#ifndef CONFIG_NO_PBKDF2
1113 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1114 ssid->passphrase) {
1115 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001116 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1117 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001118 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1119 psk, PMK_LEN);
1120 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1121 }
1122#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001123#ifdef CONFIG_EXT_PASSWORD
1124 if (ssid->ext_psk) {
1125 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1126 ssid->ext_psk);
1127 char pw_str[64 + 1];
1128 u8 psk[PMK_LEN];
1129
1130 if (pw == NULL) {
1131 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1132 "found from external storage");
1133 return -1;
1134 }
1135
1136 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1137 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1138 "PSK length %d in external storage",
1139 (int) wpabuf_len(pw));
1140 ext_password_free(pw);
1141 return -1;
1142 }
1143
1144 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1145 pw_str[wpabuf_len(pw)] = '\0';
1146
1147#ifndef CONFIG_NO_PBKDF2
1148 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1149 {
1150 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1151 4096, psk, PMK_LEN);
1152 os_memset(pw_str, 0, sizeof(pw_str));
1153 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1154 "external passphrase)",
1155 psk, PMK_LEN);
1156 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1157 } else
1158#endif /* CONFIG_NO_PBKDF2 */
1159 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1160 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1161 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1162 "Invalid PSK hex string");
1163 os_memset(pw_str, 0, sizeof(pw_str));
1164 ext_password_free(pw);
1165 return -1;
1166 }
1167 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1168 } else {
1169 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1170 "PSK available");
1171 os_memset(pw_str, 0, sizeof(pw_str));
1172 ext_password_free(pw);
1173 return -1;
1174 }
1175
1176 os_memset(pw_str, 0, sizeof(pw_str));
1177 ext_password_free(pw);
1178 }
1179#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001180 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001181 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1182
1183 return 0;
1184}
1185
1186
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001187int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1188{
1189 u32 ext_capab = 0;
1190 u8 *pos = buf;
1191
1192#ifdef CONFIG_INTERWORKING
1193 if (wpa_s->conf->interworking)
1194 ext_capab |= BIT(31); /* Interworking */
1195#endif /* CONFIG_INTERWORKING */
1196
1197#ifdef CONFIG_WNM
1198 ext_capab |= BIT(17); /* WNM-Sleep Mode */
1199 ext_capab |= BIT(19); /* BSS Transition */
1200#endif /* CONFIG_WNM */
1201
1202 if (!ext_capab)
1203 return 0;
1204
1205 *pos++ = WLAN_EID_EXT_CAPAB;
1206 *pos++ = 4;
1207 WPA_PUT_LE32(pos, ext_capab);
1208 pos += 4;
1209
1210 return pos - buf;
1211}
1212
1213
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001214/**
1215 * wpa_supplicant_associate - Request association
1216 * @wpa_s: Pointer to wpa_supplicant data
1217 * @bss: Scan results for the selected BSS, or %NULL if not available
1218 * @ssid: Configuration data for the selected network
1219 *
1220 * This function is used to request %wpa_supplicant to associate with a BSS.
1221 */
1222void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1223 struct wpa_bss *bss, struct wpa_ssid *ssid)
1224{
1225 u8 wpa_ie[200];
1226 size_t wpa_ie_len;
1227 int use_crypt, ret, i, bssid_changed;
1228 int algs = WPA_AUTH_ALG_OPEN;
1229 enum wpa_cipher cipher_pairwise, cipher_group;
1230 struct wpa_driver_associate_params params;
1231 int wep_keys_set = 0;
1232 struct wpa_driver_capa capa;
1233 int assoc_failed = 0;
1234 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001235 u8 ext_capab[10];
1236 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001237#ifdef CONFIG_HT_OVERRIDES
1238 struct ieee80211_ht_capabilities htcaps;
1239 struct ieee80211_ht_capabilities htcaps_mask;
1240#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001241
1242#ifdef CONFIG_IBSS_RSN
1243 ibss_rsn_deinit(wpa_s->ibss_rsn);
1244 wpa_s->ibss_rsn = NULL;
1245#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001246#ifdef ANDROID_P2P
1247 int freq = 0;
1248#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001249
1250 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1251 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1252#ifdef CONFIG_AP
1253 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1254 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1255 "mode");
1256 return;
1257 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001258 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1259 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1260 return;
1261 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001262 wpa_s->current_bss = bss;
1263#else /* CONFIG_AP */
1264 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1265 "the build");
1266#endif /* CONFIG_AP */
1267 return;
1268 }
1269
1270#ifdef CONFIG_TDLS
1271 if (bss)
1272 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1273 bss->ie_len);
1274#endif /* CONFIG_TDLS */
1275
1276 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1277 ssid->mode == IEEE80211_MODE_INFRA) {
1278 sme_authenticate(wpa_s, bss, ssid);
1279 return;
1280 }
1281
1282 os_memset(&params, 0, sizeof(params));
1283 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001284 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001285#ifdef CONFIG_IEEE80211R
1286 const u8 *ie, *md = NULL;
1287#endif /* CONFIG_IEEE80211R */
1288 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1289 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1290 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1291 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1292 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1293 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1294 if (bssid_changed)
1295 wpas_notify_bssid_changed(wpa_s);
1296#ifdef CONFIG_IEEE80211R
1297 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1298 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1299 md = ie + 2;
1300 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1301 if (md) {
1302 /* Prepare for the next transition */
1303 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1304 }
1305#endif /* CONFIG_IEEE80211R */
1306#ifdef CONFIG_WPS
1307 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1308 wpa_s->conf->ap_scan == 2 &&
1309 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1310 /* Use ap_scan==1 style network selection to find the network
1311 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001312 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001313 wpa_s->reassociate = 1;
1314 wpa_supplicant_req_scan(wpa_s, 0, 0);
1315 return;
1316#endif /* CONFIG_WPS */
1317 } else {
1318 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1319 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1320 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1321 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001322 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001323 wpa_supplicant_cancel_scan(wpa_s);
1324
1325 /* Starting new association, so clear the possibly used WPA IE from the
1326 * previous association. */
1327 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1328
1329#ifdef IEEE8021X_EAPOL
1330 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1331 if (ssid->leap) {
1332 if (ssid->non_leap == 0)
1333 algs = WPA_AUTH_ALG_LEAP;
1334 else
1335 algs |= WPA_AUTH_ALG_LEAP;
1336 }
1337 }
1338#endif /* IEEE8021X_EAPOL */
1339 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1340 if (ssid->auth_alg) {
1341 algs = ssid->auth_alg;
1342 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1343 "0x%x", algs);
1344 }
1345
1346 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1347 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001348 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001349 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001350 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1351 wpa_s->conf->okc :
1352 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001353 (ssid->proto & WPA_PROTO_RSN);
1354 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001355 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001356 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1357 wpa_ie_len = sizeof(wpa_ie);
1358 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1359 wpa_ie, &wpa_ie_len)) {
1360 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1361 "key management and encryption suites");
1362 return;
1363 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001364 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1365 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1366 /*
1367 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1368 * use non-WPA since the scan results did not indicate that the
1369 * AP is using WPA or WPA2.
1370 */
1371 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1372 wpa_ie_len = 0;
1373 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001374 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001375 wpa_ie_len = sizeof(wpa_ie);
1376 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1377 wpa_ie, &wpa_ie_len)) {
1378 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1379 "key management and encryption suites (no "
1380 "scan results)");
1381 return;
1382 }
1383#ifdef CONFIG_WPS
1384 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1385 struct wpabuf *wps_ie;
1386 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1387 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1388 wpa_ie_len = wpabuf_len(wps_ie);
1389 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1390 } else
1391 wpa_ie_len = 0;
1392 wpabuf_free(wps_ie);
1393 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1394 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1395 params.wps = WPS_MODE_PRIVACY;
1396 else
1397 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001398 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001399#endif /* CONFIG_WPS */
1400 } else {
1401 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1402 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001403 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001404 }
1405
1406#ifdef CONFIG_P2P
1407 if (wpa_s->global->p2p) {
1408 u8 *pos;
1409 size_t len;
1410 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001411 pos = wpa_ie + wpa_ie_len;
1412 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001413 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1414 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001415 if (res >= 0)
1416 wpa_ie_len += res;
1417 }
1418
1419 wpa_s->cross_connect_disallowed = 0;
1420 if (bss) {
1421 struct wpabuf *p2p;
1422 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1423 if (p2p) {
1424 wpa_s->cross_connect_disallowed =
1425 p2p_get_cross_connect_disallowed(p2p);
1426 wpabuf_free(p2p);
1427 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1428 "connection",
1429 wpa_s->cross_connect_disallowed ?
1430 "disallows" : "allows");
1431 }
1432 }
1433#endif /* CONFIG_P2P */
1434
Dmitry Shmidt04949592012-07-19 12:16:46 -07001435#ifdef CONFIG_HS20
1436 if (wpa_s->conf->hs20) {
1437 struct wpabuf *hs20;
1438 hs20 = wpabuf_alloc(20);
1439 if (hs20) {
1440 wpas_hs20_add_indication(hs20);
1441 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1442 wpabuf_len(hs20));
1443 wpa_ie_len += wpabuf_len(hs20);
1444 wpabuf_free(hs20);
1445 }
1446 }
1447#endif /* CONFIG_HS20 */
1448
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001449 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1450 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001451 u8 *pos = wpa_ie;
1452 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1453 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001454 os_memmove(pos + ext_capab_len, pos,
1455 wpa_ie_len - (pos - wpa_ie));
1456 wpa_ie_len += ext_capab_len;
1457 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001458 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001459
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001460 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1461 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001462 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1463 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001464 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1465 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1466 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1467 use_crypt = 0;
1468 if (wpa_set_wep_keys(wpa_s, ssid)) {
1469 use_crypt = 1;
1470 wep_keys_set = 1;
1471 }
1472 }
1473 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1474 use_crypt = 0;
1475
1476#ifdef IEEE8021X_EAPOL
1477 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1478 if ((ssid->eapol_flags &
1479 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1480 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1481 !wep_keys_set) {
1482 use_crypt = 0;
1483 } else {
1484 /* Assume that dynamic WEP-104 keys will be used and
1485 * set cipher suites in order for drivers to expect
1486 * encryption. */
1487 cipher_pairwise = cipher_group = CIPHER_WEP104;
1488 }
1489 }
1490#endif /* IEEE8021X_EAPOL */
1491
1492 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1493 /* Set the key before (and later after) association */
1494 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1495 }
1496
1497 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1498 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001499 params.ssid = bss->ssid;
1500 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001501 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1502 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1503 MACSTR " freq=%u MHz based on scan results "
1504 "(bssid_set=%d)",
1505 MAC2STR(bss->bssid), bss->freq,
1506 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001507 params.bssid = bss->bssid;
1508 params.freq = bss->freq;
1509 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001510 } else {
1511 params.ssid = ssid->ssid;
1512 params.ssid_len = ssid->ssid_len;
1513 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001514
1515 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1516 wpa_s->conf->ap_scan == 2) {
1517 params.bssid = ssid->bssid;
1518 params.fixed_bssid = 1;
1519 }
1520
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001521 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1522 params.freq == 0)
1523 params.freq = ssid->frequency; /* Initial channel for IBSS */
1524 params.wpa_ie = wpa_ie;
1525 params.wpa_ie_len = wpa_ie_len;
1526 params.pairwise_suite = cipher_pairwise;
1527 params.group_suite = cipher_group;
1528 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001529 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001530 params.auth_alg = algs;
1531 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001532 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001533 for (i = 0; i < NUM_WEP_KEYS; i++) {
1534 if (ssid->wep_key_len[i])
1535 params.wep_key[i] = ssid->wep_key[i];
1536 params.wep_key_len[i] = ssid->wep_key_len[i];
1537 }
1538 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1539
1540 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1541 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1542 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1543 params.passphrase = ssid->passphrase;
1544 if (ssid->psk_set)
1545 params.psk = ssid->psk;
1546 }
1547
1548 params.drop_unencrypted = use_crypt;
1549
1550#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001551 params.mgmt_frame_protection =
1552 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1553 wpa_s->conf->pmf : ssid->ieee80211w;
1554 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001555 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1556 struct wpa_ie_data ie;
1557 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1558 ie.capabilities &
1559 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1560 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1561 "MFP: require MFP");
1562 params.mgmt_frame_protection =
1563 MGMT_FRAME_PROTECTION_REQUIRED;
1564 }
1565 }
1566#endif /* CONFIG_IEEE80211W */
1567
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001568 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001569
1570 if (wpa_s->parent->set_sta_uapsd)
1571 params.uapsd = wpa_s->parent->sta_uapsd;
1572 else
1573 params.uapsd = -1;
1574
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001575#ifdef CONFIG_HT_OVERRIDES
1576 os_memset(&htcaps, 0, sizeof(htcaps));
1577 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1578 params.htcaps = (u8 *) &htcaps;
1579 params.htcaps_mask = (u8 *) &htcaps_mask;
1580 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1581#endif /* CONFIG_HT_OVERRIDES */
1582
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001583#ifdef ANDROID_P2P
1584 /* If multichannel concurrency is not supported, check for any frequency
1585 * conflict and take appropriate action.
1586 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001587 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1588 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1589 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001590 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001591 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001592 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001593 }
1594#endif
1595 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001596 if (ret < 0) {
1597 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1598 "failed");
1599 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1600 /*
1601 * The driver is known to mean what is saying, so we
1602 * can stop right here; the association will not
1603 * succeed.
1604 */
1605 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001606 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001607 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1608 return;
1609 }
1610 /* try to continue anyway; new association will be tried again
1611 * after timeout */
1612 assoc_failed = 1;
1613 }
1614
1615 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1616 /* Set the key after the association just in case association
1617 * cleared the previously configured key. */
1618 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1619 /* No need to timeout authentication since there is no key
1620 * management. */
1621 wpa_supplicant_cancel_auth_timeout(wpa_s);
1622 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1623#ifdef CONFIG_IBSS_RSN
1624 } else if (ssid->mode == WPAS_MODE_IBSS &&
1625 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1626 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1627 /*
1628 * RSN IBSS authentication is per-STA and we can disable the
1629 * per-BSSID authentication.
1630 */
1631 wpa_supplicant_cancel_auth_timeout(wpa_s);
1632#endif /* CONFIG_IBSS_RSN */
1633 } else {
1634 /* Timeout for IEEE 802.11 authentication and association */
1635 int timeout = 60;
1636
1637 if (assoc_failed) {
1638 /* give IBSS a bit more time */
1639 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1640 } else if (wpa_s->conf->ap_scan == 1) {
1641 /* give IBSS a bit more time */
1642 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1643 }
1644 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1645 }
1646
1647 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1648 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1649 /* Set static WEP keys again */
1650 wpa_set_wep_keys(wpa_s, ssid);
1651 }
1652
1653 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1654 /*
1655 * Do not allow EAP session resumption between different
1656 * network configurations.
1657 */
1658 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1659 }
1660 old_ssid = wpa_s->current_ssid;
1661 wpa_s->current_ssid = ssid;
1662 wpa_s->current_bss = bss;
1663 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1664 wpa_supplicant_initiate_eapol(wpa_s);
1665 if (old_ssid != wpa_s->current_ssid)
1666 wpas_notify_network_changed(wpa_s);
1667}
1668
1669
1670static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1671 const u8 *addr)
1672{
1673 struct wpa_ssid *old_ssid;
1674
1675 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001676 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001677 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001678 wpa_sm_set_config(wpa_s->wpa, NULL);
1679 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1680 if (old_ssid != wpa_s->current_ssid)
1681 wpas_notify_network_changed(wpa_s);
1682 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1683}
1684
1685
1686/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001687 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1688 * @wpa_s: Pointer to wpa_supplicant data
1689 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1690 *
1691 * This function is used to request %wpa_supplicant to deauthenticate from the
1692 * current AP.
1693 */
1694void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1695 int reason_code)
1696{
1697 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001698 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001699 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001700
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001701 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1702 " pending_bssid=" MACSTR " reason=%d state=%s",
1703 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1704 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1705
1706 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001707 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001708 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1709 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1710 wpa_s->wpa_state == WPA_ASSOCIATING))
1711 addr = wpa_s->pending_bssid;
1712 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1713 /*
1714 * When using driver-based BSS selection, we may not know the
1715 * BSSID with which we are currently trying to associate. We
1716 * need to notify the driver of this disconnection even in such
1717 * a case, so use the all zeros address here.
1718 */
1719 addr = wpa_s->bssid;
1720 zero_addr = 1;
1721 }
1722
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001723#ifdef CONFIG_TDLS
1724 wpa_tdls_teardown_peers(wpa_s->wpa);
1725#endif /* CONFIG_TDLS */
1726
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001727 if (addr) {
1728 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001729 os_memset(&event, 0, sizeof(event));
1730 event.deauth_info.reason_code = (u16) reason_code;
1731 event.deauth_info.locally_generated = 1;
1732 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001733 if (zero_addr)
1734 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001735 }
1736
1737 wpa_supplicant_clear_connection(wpa_s, addr);
1738}
1739
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001740static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1741 struct wpa_ssid *ssid)
1742{
1743 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1744 return;
1745
1746 ssid->disabled = 0;
1747 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1748 wpas_notify_network_enabled_changed(wpa_s, ssid);
1749
1750 /*
1751 * Try to reassociate since there is no current configuration and a new
1752 * network was made available.
1753 */
1754 if (!wpa_s->current_ssid)
1755 wpa_s->reassociate = 1;
1756}
1757
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001758
1759/**
1760 * wpa_supplicant_enable_network - Mark a configured network as enabled
1761 * @wpa_s: wpa_supplicant structure for a network interface
1762 * @ssid: wpa_ssid structure for a configured network or %NULL
1763 *
1764 * Enables the specified network or all networks if no network specified.
1765 */
1766void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1767 struct wpa_ssid *ssid)
1768{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001769 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001770 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1771 wpa_supplicant_enable_one_network(wpa_s, ssid);
1772 } else
1773 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001774
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001775 if (wpa_s->reassociate) {
1776 if (wpa_s->sched_scanning) {
1777 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1778 "new network to scan filters");
1779 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001780 }
1781
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001782 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001783 }
1784}
1785
1786
1787/**
1788 * wpa_supplicant_disable_network - Mark a configured network as disabled
1789 * @wpa_s: wpa_supplicant structure for a network interface
1790 * @ssid: wpa_ssid structure for a configured network or %NULL
1791 *
1792 * Disables the specified network or all networks if no network specified.
1793 */
1794void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1795 struct wpa_ssid *ssid)
1796{
1797 struct wpa_ssid *other_ssid;
1798 int was_disabled;
1799
1800 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001801 if (wpa_s->sched_scanning)
1802 wpa_supplicant_cancel_sched_scan(wpa_s);
1803
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001804 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1805 other_ssid = other_ssid->next) {
1806 was_disabled = other_ssid->disabled;
1807 if (was_disabled == 2)
1808 continue; /* do not change persistent P2P group
1809 * data */
1810
1811 other_ssid->disabled = 1;
1812
1813 if (was_disabled != other_ssid->disabled)
1814 wpas_notify_network_enabled_changed(
1815 wpa_s, other_ssid);
1816 }
1817 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001818 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001819 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1820 } else if (ssid->disabled != 2) {
1821 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001822 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001823 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1824
1825 was_disabled = ssid->disabled;
1826
1827 ssid->disabled = 1;
1828
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001829 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001830 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001831 if (wpa_s->sched_scanning) {
1832 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1833 "to remove network from filters");
1834 wpa_supplicant_cancel_sched_scan(wpa_s);
1835 wpa_supplicant_req_scan(wpa_s, 0, 0);
1836 }
1837 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001838 }
1839}
1840
1841
1842/**
1843 * wpa_supplicant_select_network - Attempt association with a network
1844 * @wpa_s: wpa_supplicant structure for a network interface
1845 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1846 */
1847void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1848 struct wpa_ssid *ssid)
1849{
1850
1851 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001852 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001853
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001854 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001855 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001856 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001857 disconnected = 1;
1858 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001859
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001860 if (ssid)
1861 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1862
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001863 /*
1864 * Mark all other networks disabled or mark all networks enabled if no
1865 * network specified.
1866 */
1867 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1868 other_ssid = other_ssid->next) {
1869 int was_disabled = other_ssid->disabled;
1870 if (was_disabled == 2)
1871 continue; /* do not change persistent P2P group data */
1872
1873 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001874 if (was_disabled && !other_ssid->disabled)
1875 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001876
1877 if (was_disabled != other_ssid->disabled)
1878 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1879 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001880
1881 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1882 /* We are already associated with the selected network */
1883 wpa_printf(MSG_DEBUG, "Already associated with the "
1884 "selected network - do nothing");
1885 return;
1886 }
1887
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001888 if (ssid)
1889 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001890 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001891 wpa_s->disconnected = 0;
1892 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001893
1894 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1895 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001896
1897 if (ssid)
1898 wpas_notify_network_selected(wpa_s, ssid);
1899}
1900
1901
1902/**
1903 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1904 * @wpa_s: wpa_supplicant structure for a network interface
1905 * @ap_scan: AP scan mode
1906 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1907 *
1908 */
1909int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1910{
1911
1912 int old_ap_scan;
1913
1914 if (ap_scan < 0 || ap_scan > 2)
1915 return -1;
1916
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001917#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001918 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1919 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1920 wpa_s->wpa_state < WPA_COMPLETED) {
1921 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1922 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001923 return 0;
1924 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001925#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001926
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001927 old_ap_scan = wpa_s->conf->ap_scan;
1928 wpa_s->conf->ap_scan = ap_scan;
1929
1930 if (old_ap_scan != wpa_s->conf->ap_scan)
1931 wpas_notify_ap_scan_changed(wpa_s);
1932
1933 return 0;
1934}
1935
1936
1937/**
1938 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1939 * @wpa_s: wpa_supplicant structure for a network interface
1940 * @expire_age: Expiration age in seconds
1941 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1942 *
1943 */
1944int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1945 unsigned int bss_expire_age)
1946{
1947 if (bss_expire_age < 10) {
1948 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1949 bss_expire_age);
1950 return -1;
1951 }
1952 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1953 bss_expire_age);
1954 wpa_s->conf->bss_expiration_age = bss_expire_age;
1955
1956 return 0;
1957}
1958
1959
1960/**
1961 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
1962 * @wpa_s: wpa_supplicant structure for a network interface
1963 * @expire_count: number of scans after which an unseen BSS is reclaimed
1964 * Returns: 0 if succeed or -1 if expire_count has an invalid value
1965 *
1966 */
1967int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
1968 unsigned int bss_expire_count)
1969{
1970 if (bss_expire_count < 1) {
1971 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
1972 bss_expire_count);
1973 return -1;
1974 }
1975 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
1976 bss_expire_count);
1977 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
1978
1979 return 0;
1980}
1981
1982
1983/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07001984 * wpa_supplicant_set_scan_interval - Set scan interval
1985 * @wpa_s: wpa_supplicant structure for a network interface
1986 * @scan_interval: scan interval in seconds
1987 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
1988 *
1989 */
1990int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
1991 int scan_interval)
1992{
1993 if (scan_interval < 0) {
1994 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
1995 scan_interval);
1996 return -1;
1997 }
1998 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
1999 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002000 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002001
2002 return 0;
2003}
2004
2005
2006/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002007 * wpa_supplicant_set_debug_params - Set global debug params
2008 * @global: wpa_global structure
2009 * @debug_level: debug level
2010 * @debug_timestamp: determines if show timestamp in debug data
2011 * @debug_show_keys: determines if show keys in debug data
2012 * Returns: 0 if succeed or -1 if debug_level has wrong value
2013 */
2014int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2015 int debug_timestamp, int debug_show_keys)
2016{
2017
2018 int old_level, old_timestamp, old_show_keys;
2019
2020 /* check for allowed debuglevels */
2021 if (debug_level != MSG_EXCESSIVE &&
2022 debug_level != MSG_MSGDUMP &&
2023 debug_level != MSG_DEBUG &&
2024 debug_level != MSG_INFO &&
2025 debug_level != MSG_WARNING &&
2026 debug_level != MSG_ERROR)
2027 return -1;
2028
2029 old_level = wpa_debug_level;
2030 old_timestamp = wpa_debug_timestamp;
2031 old_show_keys = wpa_debug_show_keys;
2032
2033 wpa_debug_level = debug_level;
2034 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2035 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2036
2037 if (wpa_debug_level != old_level)
2038 wpas_notify_debug_level_changed(global);
2039 if (wpa_debug_timestamp != old_timestamp)
2040 wpas_notify_debug_timestamp_changed(global);
2041 if (wpa_debug_show_keys != old_show_keys)
2042 wpas_notify_debug_show_keys_changed(global);
2043
2044 return 0;
2045}
2046
2047
2048/**
2049 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2050 * @wpa_s: Pointer to wpa_supplicant data
2051 * Returns: A pointer to the current network structure or %NULL on failure
2052 */
2053struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2054{
2055 struct wpa_ssid *entry;
2056 u8 ssid[MAX_SSID_LEN];
2057 int res;
2058 size_t ssid_len;
2059 u8 bssid[ETH_ALEN];
2060 int wired;
2061
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002062 res = wpa_drv_get_ssid(wpa_s, ssid);
2063 if (res < 0) {
2064 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2065 "driver");
2066 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002067 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002068 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002069
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002070 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002071 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2072 "driver");
2073 return NULL;
2074 }
2075
2076 wired = wpa_s->conf->ap_scan == 0 &&
2077 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2078
2079 entry = wpa_s->conf->ssid;
2080 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002081 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002082 ((ssid_len == entry->ssid_len &&
2083 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2084 (!entry->bssid_set ||
2085 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2086 return entry;
2087#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002088 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002089 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2090 (entry->ssid == NULL || entry->ssid_len == 0) &&
2091 (!entry->bssid_set ||
2092 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2093 return entry;
2094#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002095
Dmitry Shmidt04949592012-07-19 12:16:46 -07002096 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002097 entry->ssid_len == 0 &&
2098 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2099 return entry;
2100
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002101 entry = entry->next;
2102 }
2103
2104 return NULL;
2105}
2106
2107
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002108static int select_driver(struct wpa_supplicant *wpa_s, int i)
2109{
2110 struct wpa_global *global = wpa_s->global;
2111
2112 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2113 global->drv_priv[i] = wpa_drivers[i]->global_init();
2114 if (global->drv_priv[i] == NULL) {
2115 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2116 "'%s'", wpa_drivers[i]->name);
2117 return -1;
2118 }
2119 }
2120
2121 wpa_s->driver = wpa_drivers[i];
2122 wpa_s->global_drv_priv = global->drv_priv[i];
2123
2124 return 0;
2125}
2126
2127
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002128static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2129 const char *name)
2130{
2131 int i;
2132 size_t len;
2133 const char *pos, *driver = name;
2134
2135 if (wpa_s == NULL)
2136 return -1;
2137
2138 if (wpa_drivers[0] == NULL) {
2139 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2140 "wpa_supplicant");
2141 return -1;
2142 }
2143
2144 if (name == NULL) {
2145 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002146 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002147 }
2148
2149 do {
2150 pos = os_strchr(driver, ',');
2151 if (pos)
2152 len = pos - driver;
2153 else
2154 len = os_strlen(driver);
2155
2156 for (i = 0; wpa_drivers[i]; i++) {
2157 if (os_strlen(wpa_drivers[i]->name) == len &&
2158 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002159 0) {
2160 /* First driver that succeeds wins */
2161 if (select_driver(wpa_s, i) == 0)
2162 return 0;
2163 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002164 }
2165
2166 driver = pos + 1;
2167 } while (pos);
2168
2169 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2170 return -1;
2171}
2172
2173
2174/**
2175 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2176 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2177 * with struct wpa_driver_ops::init()
2178 * @src_addr: Source address of the EAPOL frame
2179 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2180 * @len: Length of the EAPOL data
2181 *
2182 * This function is called for each received EAPOL frame. Most driver
2183 * interfaces rely on more generic OS mechanism for receiving frames through
2184 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2185 * take care of received EAPOL frames and deliver them to the core supplicant
2186 * code by calling this function.
2187 */
2188void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2189 const u8 *buf, size_t len)
2190{
2191 struct wpa_supplicant *wpa_s = ctx;
2192
2193 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2194 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2195
Jouni Malinena05074c2012-12-21 21:35:35 +02002196 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2197 (wpa_s->last_eapol_matches_bssid &&
2198#ifdef CONFIG_AP
2199 !wpa_s->ap_iface &&
2200#endif /* CONFIG_AP */
2201 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002202 /*
2203 * There is possible race condition between receiving the
2204 * association event and the EAPOL frame since they are coming
2205 * through different paths from the driver. In order to avoid
2206 * issues in trying to process the EAPOL frame before receiving
2207 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002208 * the association event is received. This may also be needed in
2209 * driver-based roaming case, so also use src_addr != BSSID as a
2210 * trigger if we have previously confirmed that the
2211 * Authenticator uses BSSID as the src_addr (which is not the
2212 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002213 */
2214 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002215 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2216 wpa_supplicant_state_txt(wpa_s->wpa_state),
2217 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002218 wpabuf_free(wpa_s->pending_eapol_rx);
2219 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2220 if (wpa_s->pending_eapol_rx) {
2221 os_get_time(&wpa_s->pending_eapol_rx_time);
2222 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2223 ETH_ALEN);
2224 }
2225 return;
2226 }
2227
Jouni Malinena05074c2012-12-21 21:35:35 +02002228 wpa_s->last_eapol_matches_bssid =
2229 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2230
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002231#ifdef CONFIG_AP
2232 if (wpa_s->ap_iface) {
2233 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2234 return;
2235 }
2236#endif /* CONFIG_AP */
2237
2238 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2239 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2240 "no key management is configured");
2241 return;
2242 }
2243
2244 if (wpa_s->eapol_received == 0 &&
2245 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2246 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2247 wpa_s->wpa_state != WPA_COMPLETED) &&
2248 (wpa_s->current_ssid == NULL ||
2249 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2250 /* Timeout for completing IEEE 802.1X and WPA authentication */
2251 wpa_supplicant_req_auth_timeout(
2252 wpa_s,
2253 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2254 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2255 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2256 70 : 10, 0);
2257 }
2258 wpa_s->eapol_received++;
2259
2260 if (wpa_s->countermeasures) {
2261 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2262 "EAPOL packet");
2263 return;
2264 }
2265
2266#ifdef CONFIG_IBSS_RSN
2267 if (wpa_s->current_ssid &&
2268 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2269 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2270 return;
2271 }
2272#endif /* CONFIG_IBSS_RSN */
2273
2274 /* Source address of the incoming EAPOL frame could be compared to the
2275 * current BSSID. However, it is possible that a centralized
2276 * Authenticator could be using another MAC address than the BSSID of
2277 * an AP, so just allow any address to be used for now. The replies are
2278 * still sent to the current BSSID (if available), though. */
2279
2280 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2281 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2282 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2283 return;
2284 wpa_drv_poll(wpa_s);
2285 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2286 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2287 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2288 /*
2289 * Set portValid = TRUE here since we are going to skip 4-way
2290 * handshake processing which would normally set portValid. We
2291 * need this to allow the EAPOL state machines to be completed
2292 * without going through EAPOL-Key handshake.
2293 */
2294 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2295 }
2296}
2297
2298
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002299int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002300{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002301 if (wpa_s->driver->send_eapol) {
2302 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2303 if (addr)
2304 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2305 } else if (!(wpa_s->drv_flags &
2306 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002307 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002308 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2309 wpa_drv_get_mac_addr(wpa_s),
2310 ETH_P_EAPOL,
2311 wpa_supplicant_rx_eapol, wpa_s, 0);
2312 if (wpa_s->l2 == NULL)
2313 return -1;
2314 } else {
2315 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2316 if (addr)
2317 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2318 }
2319
2320 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2321 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2322 return -1;
2323 }
2324
2325 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2326 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002327 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2328
2329 return 0;
2330}
2331
2332
Dmitry Shmidt04949592012-07-19 12:16:46 -07002333static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2334 const u8 *buf, size_t len)
2335{
2336 struct wpa_supplicant *wpa_s = ctx;
2337 const struct l2_ethhdr *eth;
2338
2339 if (len < sizeof(*eth))
2340 return;
2341 eth = (const struct l2_ethhdr *) buf;
2342
2343 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2344 !(eth->h_dest[0] & 0x01)) {
2345 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2346 " (bridge - not for this interface - ignore)",
2347 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2348 return;
2349 }
2350
2351 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2352 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2353 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2354 len - sizeof(*eth));
2355}
2356
2357
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002358/**
2359 * wpa_supplicant_driver_init - Initialize driver interface parameters
2360 * @wpa_s: Pointer to wpa_supplicant data
2361 * Returns: 0 on success, -1 on failure
2362 *
2363 * This function is called to initialize driver interface parameters.
2364 * wpa_drv_init() must have been called before this function to initialize the
2365 * driver interface.
2366 */
2367int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2368{
2369 static int interface_count = 0;
2370
2371 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2372 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002373
2374 if (wpa_s->bridge_ifname[0]) {
2375 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2376 "interface '%s'", wpa_s->bridge_ifname);
2377 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2378 wpa_s->own_addr,
2379 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002380 wpa_supplicant_rx_eapol_bridge,
2381 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002382 if (wpa_s->l2_br == NULL) {
2383 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2384 "connection for the bridge interface '%s'",
2385 wpa_s->bridge_ifname);
2386 return -1;
2387 }
2388 }
2389
2390 wpa_clear_keys(wpa_s, NULL);
2391
2392 /* Make sure that TKIP countermeasures are not left enabled (could
2393 * happen if wpa_supplicant is killed during countermeasures. */
2394 wpa_drv_set_countermeasures(wpa_s, 0);
2395
2396 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2397 wpa_drv_flush_pmkid(wpa_s);
2398
2399 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002400 wpa_s->prev_scan_wildcard = 0;
2401
Dmitry Shmidt04949592012-07-19 12:16:46 -07002402 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002403 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2404 100000))
2405 wpa_supplicant_req_scan(wpa_s, interface_count,
2406 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002407 interface_count++;
2408 } else
2409 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2410
2411 return 0;
2412}
2413
2414
2415static int wpa_supplicant_daemon(const char *pid_file)
2416{
2417 wpa_printf(MSG_DEBUG, "Daemonize..");
2418 return os_daemonize(pid_file);
2419}
2420
2421
2422static struct wpa_supplicant * wpa_supplicant_alloc(void)
2423{
2424 struct wpa_supplicant *wpa_s;
2425
2426 wpa_s = os_zalloc(sizeof(*wpa_s));
2427 if (wpa_s == NULL)
2428 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002429 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002430 wpa_s->scan_interval = 5;
2431 wpa_s->new_connection = 1;
2432 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002433 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002434
2435 return wpa_s;
2436}
2437
2438
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002439#ifdef CONFIG_HT_OVERRIDES
2440
2441static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2442 struct ieee80211_ht_capabilities *htcaps,
2443 struct ieee80211_ht_capabilities *htcaps_mask,
2444 const char *ht_mcs)
2445{
2446 /* parse ht_mcs into hex array */
2447 int i;
2448 const char *tmp = ht_mcs;
2449 char *end = NULL;
2450
2451 /* If ht_mcs is null, do not set anything */
2452 if (!ht_mcs)
2453 return 0;
2454
2455 /* This is what we are setting in the kernel */
2456 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2457
2458 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2459
2460 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2461 errno = 0;
2462 long v = strtol(tmp, &end, 16);
2463 if (errno == 0) {
2464 wpa_msg(wpa_s, MSG_DEBUG,
2465 "htcap value[%i]: %ld end: %p tmp: %p",
2466 i, v, end, tmp);
2467 if (end == tmp)
2468 break;
2469
2470 htcaps->supported_mcs_set[i] = v;
2471 tmp = end;
2472 } else {
2473 wpa_msg(wpa_s, MSG_ERROR,
2474 "Failed to parse ht-mcs: %s, error: %s\n",
2475 ht_mcs, strerror(errno));
2476 return -1;
2477 }
2478 }
2479
2480 /*
2481 * If we were able to parse any values, then set mask for the MCS set.
2482 */
2483 if (i) {
2484 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2485 IEEE80211_HT_MCS_MASK_LEN - 1);
2486 /* skip the 3 reserved bits */
2487 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2488 0x1f;
2489 }
2490
2491 return 0;
2492}
2493
2494
2495static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2496 struct ieee80211_ht_capabilities *htcaps,
2497 struct ieee80211_ht_capabilities *htcaps_mask,
2498 int disabled)
2499{
2500 u16 msk;
2501
2502 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2503
2504 if (disabled == -1)
2505 return 0;
2506
2507 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2508 htcaps_mask->ht_capabilities_info |= msk;
2509 if (disabled)
2510 htcaps->ht_capabilities_info &= msk;
2511 else
2512 htcaps->ht_capabilities_info |= msk;
2513
2514 return 0;
2515}
2516
2517
2518static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2519 struct ieee80211_ht_capabilities *htcaps,
2520 struct ieee80211_ht_capabilities *htcaps_mask,
2521 int factor)
2522{
2523 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2524
2525 if (factor == -1)
2526 return 0;
2527
2528 if (factor < 0 || factor > 3) {
2529 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2530 "Must be 0-3 or -1", factor);
2531 return -EINVAL;
2532 }
2533
2534 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2535 htcaps->a_mpdu_params &= ~0x3;
2536 htcaps->a_mpdu_params |= factor & 0x3;
2537
2538 return 0;
2539}
2540
2541
2542static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2543 struct ieee80211_ht_capabilities *htcaps,
2544 struct ieee80211_ht_capabilities *htcaps_mask,
2545 int density)
2546{
2547 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2548
2549 if (density == -1)
2550 return 0;
2551
2552 if (density < 0 || density > 7) {
2553 wpa_msg(wpa_s, MSG_ERROR,
2554 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2555 density);
2556 return -EINVAL;
2557 }
2558
2559 htcaps_mask->a_mpdu_params |= 0x1C;
2560 htcaps->a_mpdu_params &= ~(0x1C);
2561 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2562
2563 return 0;
2564}
2565
2566
2567static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2568 struct ieee80211_ht_capabilities *htcaps,
2569 struct ieee80211_ht_capabilities *htcaps_mask,
2570 int disabled)
2571{
2572 /* Masking these out disables HT40 */
2573 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2574 HT_CAP_INFO_SHORT_GI40MHZ);
2575
2576 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2577
2578 if (disabled)
2579 htcaps->ht_capabilities_info &= ~msk;
2580 else
2581 htcaps->ht_capabilities_info |= msk;
2582
2583 htcaps_mask->ht_capabilities_info |= msk;
2584
2585 return 0;
2586}
2587
2588
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002589static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2590 struct ieee80211_ht_capabilities *htcaps,
2591 struct ieee80211_ht_capabilities *htcaps_mask,
2592 int disabled)
2593{
2594 /* Masking these out disables SGI */
2595 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2596 HT_CAP_INFO_SHORT_GI40MHZ);
2597
2598 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2599
2600 if (disabled)
2601 htcaps->ht_capabilities_info &= ~msk;
2602 else
2603 htcaps->ht_capabilities_info |= msk;
2604
2605 htcaps_mask->ht_capabilities_info |= msk;
2606
2607 return 0;
2608}
2609
2610
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002611void wpa_supplicant_apply_ht_overrides(
2612 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2613 struct wpa_driver_associate_params *params)
2614{
2615 struct ieee80211_ht_capabilities *htcaps;
2616 struct ieee80211_ht_capabilities *htcaps_mask;
2617
2618 if (!ssid)
2619 return;
2620
2621 params->disable_ht = ssid->disable_ht;
2622 if (!params->htcaps || !params->htcaps_mask)
2623 return;
2624
2625 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2626 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2627 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2628 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2629 ssid->disable_max_amsdu);
2630 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2631 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2632 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002633 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002634}
2635
2636#endif /* CONFIG_HT_OVERRIDES */
2637
2638
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002639#ifdef CONFIG_VHT_OVERRIDES
2640void wpa_supplicant_apply_vht_overrides(
2641 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2642 struct wpa_driver_associate_params *params)
2643{
2644 struct ieee80211_vht_capabilities *vhtcaps;
2645 struct ieee80211_vht_capabilities *vhtcaps_mask;
2646
2647 if (!ssid)
2648 return;
2649
2650 params->disable_vht = ssid->disable_vht;
2651
2652 vhtcaps = (void *) params->vhtcaps;
2653 vhtcaps_mask = (void *) params->vhtcaps_mask;
2654
2655 if (!vhtcaps || !vhtcaps_mask)
2656 return;
2657
2658 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2659 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2660
2661#define OVERRIDE_MCS(i) \
2662 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2663 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2664 3 << 2 * (i - 1); \
2665 vhtcaps->vht_supported_mcs_set.tx_map |= \
2666 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2667 } \
2668 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2669 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2670 3 << 2 * (i - 1); \
2671 vhtcaps->vht_supported_mcs_set.rx_map |= \
2672 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2673 }
2674
2675 OVERRIDE_MCS(1);
2676 OVERRIDE_MCS(2);
2677 OVERRIDE_MCS(3);
2678 OVERRIDE_MCS(4);
2679 OVERRIDE_MCS(5);
2680 OVERRIDE_MCS(6);
2681 OVERRIDE_MCS(7);
2682 OVERRIDE_MCS(8);
2683}
2684#endif /* CONFIG_VHT_OVERRIDES */
2685
2686
Dmitry Shmidt04949592012-07-19 12:16:46 -07002687static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2688{
2689#ifdef PCSC_FUNCS
2690 size_t len;
2691
2692 if (!wpa_s->conf->pcsc_reader)
2693 return 0;
2694
2695 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2696 if (!wpa_s->scard)
2697 return 1;
2698
2699 if (wpa_s->conf->pcsc_pin &&
2700 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2701 scard_deinit(wpa_s->scard);
2702 wpa_s->scard = NULL;
2703 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2704 return -1;
2705 }
2706
2707 len = sizeof(wpa_s->imsi) - 1;
2708 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2709 scard_deinit(wpa_s->scard);
2710 wpa_s->scard = NULL;
2711 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2712 return -1;
2713 }
2714 wpa_s->imsi[len] = '\0';
2715
2716 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2717
2718 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2719 wpa_s->imsi, wpa_s->mnc_len);
2720
2721 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2722 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2723#endif /* PCSC_FUNCS */
2724
2725 return 0;
2726}
2727
2728
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002729int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2730{
2731 char *val, *pos;
2732
2733 ext_password_deinit(wpa_s->ext_pw);
2734 wpa_s->ext_pw = NULL;
2735 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2736
2737 if (!wpa_s->conf->ext_password_backend)
2738 return 0;
2739
2740 val = os_strdup(wpa_s->conf->ext_password_backend);
2741 if (val == NULL)
2742 return -1;
2743 pos = os_strchr(val, ':');
2744 if (pos)
2745 *pos++ = '\0';
2746
2747 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2748
2749 wpa_s->ext_pw = ext_password_init(val, pos);
2750 os_free(val);
2751 if (wpa_s->ext_pw == NULL) {
2752 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2753 return -1;
2754 }
2755 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2756
2757 return 0;
2758}
2759
2760
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002761static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2762 struct wpa_interface *iface)
2763{
2764 const char *ifname, *driver;
2765 struct wpa_driver_capa capa;
2766
2767 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2768 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2769 iface->confname ? iface->confname : "N/A",
2770 iface->driver ? iface->driver : "default",
2771 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2772 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2773
2774 if (iface->confname) {
2775#ifdef CONFIG_BACKEND_FILE
2776 wpa_s->confname = os_rel2abs_path(iface->confname);
2777 if (wpa_s->confname == NULL) {
2778 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2779 "for configuration file '%s'.",
2780 iface->confname);
2781 return -1;
2782 }
2783 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2784 iface->confname, wpa_s->confname);
2785#else /* CONFIG_BACKEND_FILE */
2786 wpa_s->confname = os_strdup(iface->confname);
2787#endif /* CONFIG_BACKEND_FILE */
2788 wpa_s->conf = wpa_config_read(wpa_s->confname);
2789 if (wpa_s->conf == NULL) {
2790 wpa_printf(MSG_ERROR, "Failed to read or parse "
2791 "configuration '%s'.", wpa_s->confname);
2792 return -1;
2793 }
2794
2795 /*
2796 * Override ctrl_interface and driver_param if set on command
2797 * line.
2798 */
2799 if (iface->ctrl_interface) {
2800 os_free(wpa_s->conf->ctrl_interface);
2801 wpa_s->conf->ctrl_interface =
2802 os_strdup(iface->ctrl_interface);
2803 }
2804
2805 if (iface->driver_param) {
2806 os_free(wpa_s->conf->driver_param);
2807 wpa_s->conf->driver_param =
2808 os_strdup(iface->driver_param);
2809 }
2810 } else
2811 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2812 iface->driver_param);
2813
2814 if (wpa_s->conf == NULL) {
2815 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2816 return -1;
2817 }
2818
2819 if (iface->ifname == NULL) {
2820 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2821 return -1;
2822 }
2823 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2824 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2825 iface->ifname);
2826 return -1;
2827 }
2828 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2829
2830 if (iface->bridge_ifname) {
2831 if (os_strlen(iface->bridge_ifname) >=
2832 sizeof(wpa_s->bridge_ifname)) {
2833 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2834 "name '%s'.", iface->bridge_ifname);
2835 return -1;
2836 }
2837 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2838 sizeof(wpa_s->bridge_ifname));
2839 }
2840
2841 /* RSNA Supplicant Key Management - INITIALIZE */
2842 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2843 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2844
2845 /* Initialize driver interface and register driver event handler before
2846 * L2 receive handler so that association events are processed before
2847 * EAPOL-Key packets if both become available for the same select()
2848 * call. */
2849 driver = iface->driver;
2850next_driver:
2851 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2852 return -1;
2853
2854 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2855 if (wpa_s->drv_priv == NULL) {
2856 const char *pos;
2857 pos = driver ? os_strchr(driver, ',') : NULL;
2858 if (pos) {
2859 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2860 "driver interface - try next driver wrapper");
2861 driver = pos + 1;
2862 goto next_driver;
2863 }
2864 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2865 "interface");
2866 return -1;
2867 }
2868 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2869 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2870 "driver_param '%s'", wpa_s->conf->driver_param);
2871 return -1;
2872 }
2873
2874 ifname = wpa_drv_get_ifname(wpa_s);
2875 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2876 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2877 "interface name with '%s'", ifname);
2878 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2879 }
2880
2881 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2882 return -1;
2883
2884 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2885 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2886 NULL);
2887 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2888
2889 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2890 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2891 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2892 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2893 "dot11RSNAConfigPMKLifetime");
2894 return -1;
2895 }
2896
2897 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2898 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2899 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2900 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2901 "dot11RSNAConfigPMKReauthThreshold");
2902 return -1;
2903 }
2904
2905 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2906 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2907 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2908 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2909 "dot11RSNAConfigSATimeout");
2910 return -1;
2911 }
2912
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002913 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2914 &wpa_s->hw.num_modes,
2915 &wpa_s->hw.flags);
2916
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002917 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002918 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002919 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002920 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002921 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002922 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002923 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2924 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2925 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002926 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2927 wpa_s->max_stations = capa.max_stations;
2928 }
2929 if (wpa_s->max_remain_on_chan == 0)
2930 wpa_s->max_remain_on_chan = 1000;
2931
2932 if (wpa_supplicant_driver_init(wpa_s) < 0)
2933 return -1;
2934
2935#ifdef CONFIG_TDLS
2936 if (wpa_tdls_init(wpa_s->wpa))
2937 return -1;
2938#endif /* CONFIG_TDLS */
2939
2940 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2941 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2942 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2943 return -1;
2944 }
2945
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002946 if (wpas_wps_init(wpa_s))
2947 return -1;
2948
2949 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2950 return -1;
2951 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2952
2953 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2954 if (wpa_s->ctrl_iface == NULL) {
2955 wpa_printf(MSG_ERROR,
2956 "Failed to initialize control interface '%s'.\n"
2957 "You may have another wpa_supplicant process "
2958 "already running or the file was\n"
2959 "left by an unclean termination of wpa_supplicant "
2960 "in which case you will need\n"
2961 "to manually remove this file before starting "
2962 "wpa_supplicant again.\n",
2963 wpa_s->conf->ctrl_interface);
2964 return -1;
2965 }
2966
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002967 wpa_s->gas = gas_query_init(wpa_s);
2968 if (wpa_s->gas == NULL) {
2969 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
2970 return -1;
2971 }
2972
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002973#ifdef CONFIG_P2P
2974 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
2975 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
2976 return -1;
2977 }
2978#endif /* CONFIG_P2P */
2979
2980 if (wpa_bss_init(wpa_s) < 0)
2981 return -1;
2982
Dmitry Shmidt04949592012-07-19 12:16:46 -07002983 if (pcsc_reader_init(wpa_s) < 0)
2984 return -1;
2985
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002986 if (wpas_init_ext_pw(wpa_s) < 0)
2987 return -1;
2988
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002989 return 0;
2990}
2991
2992
2993static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07002994 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002995{
2996 if (wpa_s->drv_priv) {
2997 wpa_supplicant_deauthenticate(wpa_s,
2998 WLAN_REASON_DEAUTH_LEAVING);
2999
3000 wpa_drv_set_countermeasures(wpa_s, 0);
3001 wpa_clear_keys(wpa_s, NULL);
3002 }
3003
3004 wpa_supplicant_cleanup(wpa_s);
3005
Dmitry Shmidt04949592012-07-19 12:16:46 -07003006#ifdef CONFIG_P2P
3007 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3008 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3009 "the management interface is being removed");
3010 wpas_p2p_deinit_global(wpa_s->global);
3011 }
3012#endif /* CONFIG_P2P */
3013
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003014 if (wpa_s->drv_priv)
3015 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003016
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003017 if (notify)
3018 wpas_notify_iface_removed(wpa_s);
3019
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003020 if (terminate)
3021 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003022
3023 if (wpa_s->ctrl_iface) {
3024 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3025 wpa_s->ctrl_iface = NULL;
3026 }
3027
3028 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003029 wpa_config_free(wpa_s->conf);
3030 wpa_s->conf = NULL;
3031 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003032}
3033
3034
3035/**
3036 * wpa_supplicant_add_iface - Add a new network interface
3037 * @global: Pointer to global data from wpa_supplicant_init()
3038 * @iface: Interface configuration options
3039 * Returns: Pointer to the created interface or %NULL on failure
3040 *
3041 * This function is used to add new network interfaces for %wpa_supplicant.
3042 * This can be called before wpa_supplicant_run() to add interfaces before the
3043 * main event loop has been started. In addition, new interfaces can be added
3044 * dynamically while %wpa_supplicant is already running. This could happen,
3045 * e.g., when a hotplug network adapter is inserted.
3046 */
3047struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3048 struct wpa_interface *iface)
3049{
3050 struct wpa_supplicant *wpa_s;
3051 struct wpa_interface t_iface;
3052 struct wpa_ssid *ssid;
3053
3054 if (global == NULL || iface == NULL)
3055 return NULL;
3056
3057 wpa_s = wpa_supplicant_alloc();
3058 if (wpa_s == NULL)
3059 return NULL;
3060
3061 wpa_s->global = global;
3062
3063 t_iface = *iface;
3064 if (global->params.override_driver) {
3065 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3066 "('%s' -> '%s')",
3067 iface->driver, global->params.override_driver);
3068 t_iface.driver = global->params.override_driver;
3069 }
3070 if (global->params.override_ctrl_interface) {
3071 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3072 "ctrl_interface ('%s' -> '%s')",
3073 iface->ctrl_interface,
3074 global->params.override_ctrl_interface);
3075 t_iface.ctrl_interface =
3076 global->params.override_ctrl_interface;
3077 }
3078 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3079 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3080 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003081 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003082 os_free(wpa_s);
3083 return NULL;
3084 }
3085
3086 /* Notify the control interfaces about new iface */
3087 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003088 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003089 os_free(wpa_s);
3090 return NULL;
3091 }
3092
3093 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3094 wpas_notify_network_added(wpa_s, ssid);
3095
3096 wpa_s->next = global->ifaces;
3097 global->ifaces = wpa_s;
3098
3099 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003100 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003101
3102 return wpa_s;
3103}
3104
3105
3106/**
3107 * wpa_supplicant_remove_iface - Remove a network interface
3108 * @global: Pointer to global data from wpa_supplicant_init()
3109 * @wpa_s: Pointer to the network interface to be removed
3110 * Returns: 0 if interface was removed, -1 if interface was not found
3111 *
3112 * This function can be used to dynamically remove network interfaces from
3113 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3114 * addition, this function is used to remove all remaining interfaces when
3115 * %wpa_supplicant is terminated.
3116 */
3117int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003118 struct wpa_supplicant *wpa_s,
3119 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003120{
3121 struct wpa_supplicant *prev;
3122
3123 /* Remove interface from the global list of interfaces */
3124 prev = global->ifaces;
3125 if (prev == wpa_s) {
3126 global->ifaces = wpa_s->next;
3127 } else {
3128 while (prev && prev->next != wpa_s)
3129 prev = prev->next;
3130 if (prev == NULL)
3131 return -1;
3132 prev->next = wpa_s->next;
3133 }
3134
3135 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3136
3137 if (global->p2p_group_formation == wpa_s)
3138 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07003139 if (global->p2p_invite_group == wpa_s)
3140 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003141 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003142 os_free(wpa_s);
3143
3144 return 0;
3145}
3146
3147
3148/**
3149 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3150 * @wpa_s: Pointer to the network interface
3151 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3152 */
3153const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3154{
3155 const char *eapol_method;
3156
3157 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3158 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3159 return "NO-EAP";
3160 }
3161
3162 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3163 if (eapol_method == NULL)
3164 return "UNKNOWN-EAP";
3165
3166 return eapol_method;
3167}
3168
3169
3170/**
3171 * wpa_supplicant_get_iface - Get a new network interface
3172 * @global: Pointer to global data from wpa_supplicant_init()
3173 * @ifname: Interface name
3174 * Returns: Pointer to the interface or %NULL if not found
3175 */
3176struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3177 const char *ifname)
3178{
3179 struct wpa_supplicant *wpa_s;
3180
3181 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3182 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3183 return wpa_s;
3184 }
3185 return NULL;
3186}
3187
3188
3189#ifndef CONFIG_NO_WPA_MSG
3190static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3191{
3192 struct wpa_supplicant *wpa_s = ctx;
3193 if (wpa_s == NULL)
3194 return NULL;
3195 return wpa_s->ifname;
3196}
3197#endif /* CONFIG_NO_WPA_MSG */
3198
3199
3200/**
3201 * wpa_supplicant_init - Initialize %wpa_supplicant
3202 * @params: Parameters for %wpa_supplicant
3203 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3204 *
3205 * This function is used to initialize %wpa_supplicant. After successful
3206 * initialization, the returned data pointer can be used to add and remove
3207 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3208 */
3209struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3210{
3211 struct wpa_global *global;
3212 int ret, i;
3213
3214 if (params == NULL)
3215 return NULL;
3216
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003217#ifdef CONFIG_DRIVER_NDIS
3218 {
3219 void driver_ndis_init_ops(void);
3220 driver_ndis_init_ops();
3221 }
3222#endif /* CONFIG_DRIVER_NDIS */
3223
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003224#ifndef CONFIG_NO_WPA_MSG
3225 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3226#endif /* CONFIG_NO_WPA_MSG */
3227
3228 wpa_debug_open_file(params->wpa_debug_file_path);
3229 if (params->wpa_debug_syslog)
3230 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003231 if (params->wpa_debug_tracing) {
3232 ret = wpa_debug_open_linux_tracing();
3233 if (ret) {
3234 wpa_printf(MSG_ERROR,
3235 "Failed to enable trace logging");
3236 return NULL;
3237 }
3238 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003239
3240 ret = eap_register_methods();
3241 if (ret) {
3242 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3243 if (ret == -2)
3244 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3245 "the same EAP type.");
3246 return NULL;
3247 }
3248
3249 global = os_zalloc(sizeof(*global));
3250 if (global == NULL)
3251 return NULL;
3252 dl_list_init(&global->p2p_srv_bonjour);
3253 dl_list_init(&global->p2p_srv_upnp);
3254 global->params.daemonize = params->daemonize;
3255 global->params.wait_for_monitor = params->wait_for_monitor;
3256 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3257 if (params->pid_file)
3258 global->params.pid_file = os_strdup(params->pid_file);
3259 if (params->ctrl_interface)
3260 global->params.ctrl_interface =
3261 os_strdup(params->ctrl_interface);
3262 if (params->override_driver)
3263 global->params.override_driver =
3264 os_strdup(params->override_driver);
3265 if (params->override_ctrl_interface)
3266 global->params.override_ctrl_interface =
3267 os_strdup(params->override_ctrl_interface);
3268 wpa_debug_level = global->params.wpa_debug_level =
3269 params->wpa_debug_level;
3270 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3271 params->wpa_debug_show_keys;
3272 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3273 params->wpa_debug_timestamp;
3274
3275 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3276
3277 if (eloop_init()) {
3278 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3279 wpa_supplicant_deinit(global);
3280 return NULL;
3281 }
3282
Jouni Malinen75ecf522011-06-27 15:19:46 -07003283 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003284
3285 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3286 if (global->ctrl_iface == NULL) {
3287 wpa_supplicant_deinit(global);
3288 return NULL;
3289 }
3290
3291 if (wpas_notify_supplicant_initialized(global)) {
3292 wpa_supplicant_deinit(global);
3293 return NULL;
3294 }
3295
3296 for (i = 0; wpa_drivers[i]; i++)
3297 global->drv_count++;
3298 if (global->drv_count == 0) {
3299 wpa_printf(MSG_ERROR, "No drivers enabled");
3300 wpa_supplicant_deinit(global);
3301 return NULL;
3302 }
3303 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3304 if (global->drv_priv == NULL) {
3305 wpa_supplicant_deinit(global);
3306 return NULL;
3307 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003308
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003309#ifdef CONFIG_WIFI_DISPLAY
3310 if (wifi_display_init(global) < 0) {
3311 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3312 wpa_supplicant_deinit(global);
3313 return NULL;
3314 }
3315#endif /* CONFIG_WIFI_DISPLAY */
3316
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003317 return global;
3318}
3319
3320
3321/**
3322 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3323 * @global: Pointer to global data from wpa_supplicant_init()
3324 * Returns: 0 after successful event loop run, -1 on failure
3325 *
3326 * This function starts the main event loop and continues running as long as
3327 * there are any remaining events. In most cases, this function is running as
3328 * long as the %wpa_supplicant process in still in use.
3329 */
3330int wpa_supplicant_run(struct wpa_global *global)
3331{
3332 struct wpa_supplicant *wpa_s;
3333
3334 if (global->params.daemonize &&
3335 wpa_supplicant_daemon(global->params.pid_file))
3336 return -1;
3337
3338 if (global->params.wait_for_monitor) {
3339 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3340 if (wpa_s->ctrl_iface)
3341 wpa_supplicant_ctrl_iface_wait(
3342 wpa_s->ctrl_iface);
3343 }
3344
3345 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3346 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3347
3348 eloop_run();
3349
3350 return 0;
3351}
3352
3353
3354/**
3355 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3356 * @global: Pointer to global data from wpa_supplicant_init()
3357 *
3358 * This function is called to deinitialize %wpa_supplicant and to free all
3359 * allocated resources. Remaining network interfaces will also be removed.
3360 */
3361void wpa_supplicant_deinit(struct wpa_global *global)
3362{
3363 int i;
3364
3365 if (global == NULL)
3366 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003367
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003368#ifdef CONFIG_WIFI_DISPLAY
3369 wifi_display_deinit(global);
3370#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003371#ifdef CONFIG_P2P
3372 wpas_p2p_deinit_global(global);
3373#endif /* CONFIG_P2P */
3374
3375 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003376 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003377
3378 if (global->ctrl_iface)
3379 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3380
3381 wpas_notify_supplicant_deinitialized(global);
3382
3383 eap_peer_unregister_methods();
3384#ifdef CONFIG_AP
3385 eap_server_unregister_methods();
3386#endif /* CONFIG_AP */
3387
3388 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3389 if (!global->drv_priv[i])
3390 continue;
3391 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3392 }
3393 os_free(global->drv_priv);
3394
3395 random_deinit();
3396
3397 eloop_destroy();
3398
3399 if (global->params.pid_file) {
3400 os_daemonize_terminate(global->params.pid_file);
3401 os_free(global->params.pid_file);
3402 }
3403 os_free(global->params.ctrl_interface);
3404 os_free(global->params.override_driver);
3405 os_free(global->params.override_ctrl_interface);
3406
Dmitry Shmidt04949592012-07-19 12:16:46 -07003407 os_free(global->p2p_disallow_freq);
3408
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003409 os_free(global);
3410 wpa_debug_close_syslog();
3411 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003412 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003413}
3414
3415
3416void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3417{
3418 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3419 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3420 char country[3];
3421 country[0] = wpa_s->conf->country[0];
3422 country[1] = wpa_s->conf->country[1];
3423 country[2] = '\0';
3424 if (wpa_drv_set_country(wpa_s, country) < 0) {
3425 wpa_printf(MSG_ERROR, "Failed to set country code "
3426 "'%s'", country);
3427 }
3428 }
3429
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003430 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3431 wpas_init_ext_pw(wpa_s);
3432
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003433#ifdef CONFIG_WPS
3434 wpas_wps_update_config(wpa_s);
3435#endif /* CONFIG_WPS */
3436
3437#ifdef CONFIG_P2P
3438 wpas_p2p_update_config(wpa_s);
3439#endif /* CONFIG_P2P */
3440
3441 wpa_s->conf->changed_parameters = 0;
3442}
3443
3444
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003445static void add_freq(int *freqs, int *num_freqs, int freq)
3446{
3447 int i;
3448
3449 for (i = 0; i < *num_freqs; i++) {
3450 if (freqs[i] == freq)
3451 return;
3452 }
3453
3454 freqs[*num_freqs] = freq;
3455 (*num_freqs)++;
3456}
3457
3458
3459static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3460{
3461 struct wpa_bss *bss, *cbss;
3462 const int max_freqs = 10;
3463 int *freqs;
3464 int num_freqs = 0;
3465
3466 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3467 if (freqs == NULL)
3468 return NULL;
3469
3470 cbss = wpa_s->current_bss;
3471
3472 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3473 if (bss == cbss)
3474 continue;
3475 if (bss->ssid_len == cbss->ssid_len &&
3476 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3477 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3478 add_freq(freqs, &num_freqs, bss->freq);
3479 if (num_freqs == max_freqs)
3480 break;
3481 }
3482 }
3483
3484 if (num_freqs == 0) {
3485 os_free(freqs);
3486 freqs = NULL;
3487 }
3488
3489 return freqs;
3490}
3491
3492
3493void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3494{
3495 int timeout;
3496 int count;
3497 int *freqs = NULL;
3498
3499 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003500 * Remove possible authentication timeout since the connection failed.
3501 */
3502 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3503
3504 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003505 * Add the failed BSSID into the blacklist and speed up next scan
3506 * attempt if there could be other APs that could accept association.
3507 * The current blacklist count indicates how many times we have tried
3508 * connecting to this AP and multiple attempts mean that other APs are
3509 * either not available or has already been tried, so that we can start
3510 * increasing the delay here to avoid constant scanning.
3511 */
3512 count = wpa_blacklist_add(wpa_s, bssid);
3513 if (count == 1 && wpa_s->current_bss) {
3514 /*
3515 * This BSS was not in the blacklist before. If there is
3516 * another BSS available for the same ESS, we should try that
3517 * next. Otherwise, we may as well try this one once more
3518 * before allowing other, likely worse, ESSes to be considered.
3519 */
3520 freqs = get_bss_freqs_in_ess(wpa_s);
3521 if (freqs) {
3522 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3523 "has been seen; try it next");
3524 wpa_blacklist_add(wpa_s, bssid);
3525 /*
3526 * On the next scan, go through only the known channels
3527 * used in this ESS based on previous scans to speed up
3528 * common load balancing use case.
3529 */
3530 os_free(wpa_s->next_scan_freqs);
3531 wpa_s->next_scan_freqs = freqs;
3532 }
3533 }
3534
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003535 /*
3536 * Add previous failure count in case the temporary blacklist was
3537 * cleared due to no other BSSes being available.
3538 */
3539 count += wpa_s->extra_blacklist_count;
3540
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003541 switch (count) {
3542 case 1:
3543 timeout = 100;
3544 break;
3545 case 2:
3546 timeout = 500;
3547 break;
3548 case 3:
3549 timeout = 1000;
3550 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003551 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003552 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003553 break;
3554 default:
3555 timeout = 10000;
3556 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003557 }
3558
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003559 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3560 "ms", count, timeout);
3561
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003562 /*
3563 * TODO: if more than one possible AP is available in scan results,
3564 * could try the other ones before requesting a new scan.
3565 */
3566 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3567 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003568
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -07003569 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003570}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003571
3572
3573int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3574{
3575 return wpa_s->conf->ap_scan == 2 ||
3576 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3577}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003578
Dmitry Shmidt04949592012-07-19 12:16:46 -07003579
3580#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3581int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3582 struct wpa_ssid *ssid,
3583 const char *field,
3584 const char *value)
3585{
3586#ifdef IEEE8021X_EAPOL
3587 struct eap_peer_config *eap = &ssid->eap;
3588
3589 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3590 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3591 (const u8 *) value, os_strlen(value));
3592
3593 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3594 case WPA_CTRL_REQ_EAP_IDENTITY:
3595 os_free(eap->identity);
3596 eap->identity = (u8 *) os_strdup(value);
3597 eap->identity_len = os_strlen(value);
3598 eap->pending_req_identity = 0;
3599 if (ssid == wpa_s->current_ssid)
3600 wpa_s->reassociate = 1;
3601 break;
3602 case WPA_CTRL_REQ_EAP_PASSWORD:
3603 os_free(eap->password);
3604 eap->password = (u8 *) os_strdup(value);
3605 eap->password_len = os_strlen(value);
3606 eap->pending_req_password = 0;
3607 if (ssid == wpa_s->current_ssid)
3608 wpa_s->reassociate = 1;
3609 break;
3610 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3611 os_free(eap->new_password);
3612 eap->new_password = (u8 *) os_strdup(value);
3613 eap->new_password_len = os_strlen(value);
3614 eap->pending_req_new_password = 0;
3615 if (ssid == wpa_s->current_ssid)
3616 wpa_s->reassociate = 1;
3617 break;
3618 case WPA_CTRL_REQ_EAP_PIN:
3619 os_free(eap->pin);
3620 eap->pin = os_strdup(value);
3621 eap->pending_req_pin = 0;
3622 if (ssid == wpa_s->current_ssid)
3623 wpa_s->reassociate = 1;
3624 break;
3625 case WPA_CTRL_REQ_EAP_OTP:
3626 os_free(eap->otp);
3627 eap->otp = (u8 *) os_strdup(value);
3628 eap->otp_len = os_strlen(value);
3629 os_free(eap->pending_req_otp);
3630 eap->pending_req_otp = NULL;
3631 eap->pending_req_otp_len = 0;
3632 break;
3633 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3634 os_free(eap->private_key_passwd);
3635 eap->private_key_passwd = (u8 *) os_strdup(value);
3636 eap->pending_req_passphrase = 0;
3637 if (ssid == wpa_s->current_ssid)
3638 wpa_s->reassociate = 1;
3639 break;
3640 default:
3641 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3642 return -1;
3643 }
3644
3645 return 0;
3646#else /* IEEE8021X_EAPOL */
3647 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3648 return -1;
3649#endif /* IEEE8021X_EAPOL */
3650}
3651#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3652
3653
3654int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3655{
3656 int i;
3657 unsigned int drv_enc;
3658
3659 if (ssid == NULL)
3660 return 1;
3661
3662 if (ssid->disabled)
3663 return 1;
3664
3665 if (wpa_s && wpa_s->drv_capa_known)
3666 drv_enc = wpa_s->drv_enc;
3667 else
3668 drv_enc = (unsigned int) -1;
3669
3670 for (i = 0; i < NUM_WEP_KEYS; i++) {
3671 size_t len = ssid->wep_key_len[i];
3672 if (len == 0)
3673 continue;
3674 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3675 continue;
3676 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3677 continue;
3678 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3679 continue;
3680 return 1; /* invalid WEP key */
3681 }
3682
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003683 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3684 !ssid->ext_psk)
3685 return 1;
3686
Dmitry Shmidt04949592012-07-19 12:16:46 -07003687 return 0;
3688}
3689
3690
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003691int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003692{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003693 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003694 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003695 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003696 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003697 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003698}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003699
3700
3701void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3702{
3703 struct wpa_ssid *ssid = wpa_s->current_ssid;
3704 int dur;
3705 struct os_time now;
3706
3707 if (ssid == NULL) {
3708 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3709 "SSID block");
3710 return;
3711 }
3712
3713 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3714 return;
3715
3716 ssid->auth_failures++;
3717 if (ssid->auth_failures > 50)
3718 dur = 300;
3719 else if (ssid->auth_failures > 20)
3720 dur = 120;
3721 else if (ssid->auth_failures > 10)
3722 dur = 60;
3723 else if (ssid->auth_failures > 5)
3724 dur = 30;
3725 else if (ssid->auth_failures > 1)
3726 dur = 20;
3727 else
3728 dur = 10;
3729
3730 os_get_time(&now);
3731 if (now.sec + dur <= ssid->disabled_until.sec)
3732 return;
3733
3734 ssid->disabled_until.sec = now.sec + dur;
3735
3736 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3737 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3738 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3739 ssid->auth_failures, dur);
3740}
3741
3742
3743void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3744 struct wpa_ssid *ssid, int clear_failures)
3745{
3746 if (ssid == NULL)
3747 return;
3748
3749 if (ssid->disabled_until.sec) {
3750 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3751 "id=%d ssid=\"%s\"",
3752 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3753 }
3754 ssid->disabled_until.sec = 0;
3755 ssid->disabled_until.usec = 0;
3756 if (clear_failures)
3757 ssid->auth_failures = 0;
3758}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003759
3760
3761int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3762{
3763 size_t i;
3764
3765 if (wpa_s->disallow_aps_bssid == NULL)
3766 return 0;
3767
3768 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3769 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3770 bssid, ETH_ALEN) == 0)
3771 return 1;
3772 }
3773
3774 return 0;
3775}
3776
3777
3778int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3779 size_t ssid_len)
3780{
3781 size_t i;
3782
3783 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3784 return 0;
3785
3786 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3787 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3788 if (ssid_len == s->ssid_len &&
3789 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3790 return 1;
3791 }
3792
3793 return 0;
3794}
3795
3796
3797/**
3798 * wpas_request_connection - Request a new connection
3799 * @wpa_s: Pointer to the network interface
3800 *
3801 * This function is used to request a new connection to be found. It will mark
3802 * the interface to allow reassociation and request a new scan to find a
3803 * suitable network to connect to.
3804 */
3805void wpas_request_connection(struct wpa_supplicant *wpa_s)
3806{
3807 wpa_s->normal_scans = 0;
3808 wpa_supplicant_reinit_autoscan(wpa_s);
3809 wpa_s->extra_blacklist_count = 0;
3810 wpa_s->disconnected = 0;
3811 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003812
3813 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3814 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003815}