blob: a6478b68aa812b464ab13d3aae90d1832b90fc8a [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 Shmidt444d5672013-04-01 13:08:44 -07001187static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1188{
1189 *pos = 0x00;
1190
1191 switch (idx) {
1192 case 0: /* Bits 0-7 */
1193 break;
1194 case 1: /* Bits 8-15 */
1195 break;
1196 case 2: /* Bits 16-23 */
1197#ifdef CONFIG_WNM
1198 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1199 *pos |= 0x08; /* Bit 19 - BSS Transition */
1200#endif /* CONFIG_WNM */
1201 break;
1202 case 3: /* Bits 24-31 */
1203#ifdef CONFIG_WNM
1204 *pos |= 0x02; /* Bit 25 - SSID List */
1205#endif /* CONFIG_WNM */
1206#ifdef CONFIG_INTERWORKING
1207 if (wpa_s->conf->interworking)
1208 *pos |= 0x80; /* Bit 31 - Interworking */
1209#endif /* CONFIG_INTERWORKING */
1210 break;
1211 case 4: /* Bits 32-39 */
1212 break;
1213 case 5: /* Bits 40-47 */
1214 break;
1215 case 6: /* Bits 48-55 */
1216 break;
1217 }
1218}
1219
1220
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001221int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1222{
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001223 u8 *pos = buf;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001224 u8 len = 4, i;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001225
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001226 if (len < wpa_s->extended_capa_len)
1227 len = wpa_s->extended_capa_len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001228
1229 *pos++ = WLAN_EID_EXT_CAPAB;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001230 *pos++ = len;
1231 for (i = 0; i < len; i++, pos++) {
1232 wpas_ext_capab_byte(wpa_s, pos, i);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001233
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001234 if (i < wpa_s->extended_capa_len) {
1235 *pos &= ~wpa_s->extended_capa_mask[i];
1236 *pos |= wpa_s->extended_capa[i];
1237 }
1238 }
1239
1240 while (len > 0 && buf[1 + len] == 0) {
1241 len--;
1242 buf[1] = len;
1243 }
1244 if (len == 0)
1245 return 0;
1246
1247 return 2 + len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001248}
1249
1250
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001251/**
1252 * wpa_supplicant_associate - Request association
1253 * @wpa_s: Pointer to wpa_supplicant data
1254 * @bss: Scan results for the selected BSS, or %NULL if not available
1255 * @ssid: Configuration data for the selected network
1256 *
1257 * This function is used to request %wpa_supplicant to associate with a BSS.
1258 */
1259void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1260 struct wpa_bss *bss, struct wpa_ssid *ssid)
1261{
1262 u8 wpa_ie[200];
1263 size_t wpa_ie_len;
1264 int use_crypt, ret, i, bssid_changed;
1265 int algs = WPA_AUTH_ALG_OPEN;
1266 enum wpa_cipher cipher_pairwise, cipher_group;
1267 struct wpa_driver_associate_params params;
1268 int wep_keys_set = 0;
1269 struct wpa_driver_capa capa;
1270 int assoc_failed = 0;
1271 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001272 u8 ext_capab[10];
1273 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001274#ifdef CONFIG_HT_OVERRIDES
1275 struct ieee80211_ht_capabilities htcaps;
1276 struct ieee80211_ht_capabilities htcaps_mask;
1277#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001278
1279#ifdef CONFIG_IBSS_RSN
1280 ibss_rsn_deinit(wpa_s->ibss_rsn);
1281 wpa_s->ibss_rsn = NULL;
1282#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001283#ifdef ANDROID_P2P
1284 int freq = 0;
1285#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001286
1287 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1288 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1289#ifdef CONFIG_AP
1290 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1291 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1292 "mode");
1293 return;
1294 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001295 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1296 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1297 return;
1298 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001299 wpa_s->current_bss = bss;
1300#else /* CONFIG_AP */
1301 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1302 "the build");
1303#endif /* CONFIG_AP */
1304 return;
1305 }
1306
1307#ifdef CONFIG_TDLS
1308 if (bss)
1309 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1310 bss->ie_len);
1311#endif /* CONFIG_TDLS */
1312
1313 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1314 ssid->mode == IEEE80211_MODE_INFRA) {
1315 sme_authenticate(wpa_s, bss, ssid);
1316 return;
1317 }
1318
1319 os_memset(&params, 0, sizeof(params));
1320 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001321 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001322#ifdef CONFIG_IEEE80211R
1323 const u8 *ie, *md = NULL;
1324#endif /* CONFIG_IEEE80211R */
1325 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1326 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1327 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1328 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1329 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1330 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1331 if (bssid_changed)
1332 wpas_notify_bssid_changed(wpa_s);
1333#ifdef CONFIG_IEEE80211R
1334 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1335 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1336 md = ie + 2;
1337 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1338 if (md) {
1339 /* Prepare for the next transition */
1340 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1341 }
1342#endif /* CONFIG_IEEE80211R */
1343#ifdef CONFIG_WPS
1344 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1345 wpa_s->conf->ap_scan == 2 &&
1346 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1347 /* Use ap_scan==1 style network selection to find the network
1348 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001349 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001350 wpa_s->reassociate = 1;
1351 wpa_supplicant_req_scan(wpa_s, 0, 0);
1352 return;
1353#endif /* CONFIG_WPS */
1354 } else {
1355 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1356 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1357 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1358 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001359 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001360 wpa_supplicant_cancel_scan(wpa_s);
1361
1362 /* Starting new association, so clear the possibly used WPA IE from the
1363 * previous association. */
1364 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1365
1366#ifdef IEEE8021X_EAPOL
1367 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1368 if (ssid->leap) {
1369 if (ssid->non_leap == 0)
1370 algs = WPA_AUTH_ALG_LEAP;
1371 else
1372 algs |= WPA_AUTH_ALG_LEAP;
1373 }
1374 }
1375#endif /* IEEE8021X_EAPOL */
1376 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1377 if (ssid->auth_alg) {
1378 algs = ssid->auth_alg;
1379 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1380 "0x%x", algs);
1381 }
1382
1383 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1384 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001385 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001386 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001387 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1388 wpa_s->conf->okc :
1389 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001390 (ssid->proto & WPA_PROTO_RSN);
1391 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001392 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001393 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1394 wpa_ie_len = sizeof(wpa_ie);
1395 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1396 wpa_ie, &wpa_ie_len)) {
1397 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1398 "key management and encryption suites");
1399 return;
1400 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001401 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1402 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1403 /*
1404 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1405 * use non-WPA since the scan results did not indicate that the
1406 * AP is using WPA or WPA2.
1407 */
1408 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1409 wpa_ie_len = 0;
1410 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001411 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001412 wpa_ie_len = sizeof(wpa_ie);
1413 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1414 wpa_ie, &wpa_ie_len)) {
1415 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1416 "key management and encryption suites (no "
1417 "scan results)");
1418 return;
1419 }
1420#ifdef CONFIG_WPS
1421 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1422 struct wpabuf *wps_ie;
1423 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1424 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1425 wpa_ie_len = wpabuf_len(wps_ie);
1426 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1427 } else
1428 wpa_ie_len = 0;
1429 wpabuf_free(wps_ie);
1430 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1431 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1432 params.wps = WPS_MODE_PRIVACY;
1433 else
1434 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001435 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001436#endif /* CONFIG_WPS */
1437 } else {
1438 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1439 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001440 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001441 }
1442
1443#ifdef CONFIG_P2P
1444 if (wpa_s->global->p2p) {
1445 u8 *pos;
1446 size_t len;
1447 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001448 pos = wpa_ie + wpa_ie_len;
1449 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001450 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1451 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001452 if (res >= 0)
1453 wpa_ie_len += res;
1454 }
1455
1456 wpa_s->cross_connect_disallowed = 0;
1457 if (bss) {
1458 struct wpabuf *p2p;
1459 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1460 if (p2p) {
1461 wpa_s->cross_connect_disallowed =
1462 p2p_get_cross_connect_disallowed(p2p);
1463 wpabuf_free(p2p);
1464 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1465 "connection",
1466 wpa_s->cross_connect_disallowed ?
1467 "disallows" : "allows");
1468 }
1469 }
1470#endif /* CONFIG_P2P */
1471
Dmitry Shmidt04949592012-07-19 12:16:46 -07001472#ifdef CONFIG_HS20
1473 if (wpa_s->conf->hs20) {
1474 struct wpabuf *hs20;
1475 hs20 = wpabuf_alloc(20);
1476 if (hs20) {
1477 wpas_hs20_add_indication(hs20);
1478 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1479 wpabuf_len(hs20));
1480 wpa_ie_len += wpabuf_len(hs20);
1481 wpabuf_free(hs20);
1482 }
1483 }
1484#endif /* CONFIG_HS20 */
1485
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001486 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1487 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001488 u8 *pos = wpa_ie;
1489 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1490 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001491 os_memmove(pos + ext_capab_len, pos,
1492 wpa_ie_len - (pos - wpa_ie));
1493 wpa_ie_len += ext_capab_len;
1494 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001495 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001496
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001497 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1498 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001499 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1500 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001501 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1502 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1503 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1504 use_crypt = 0;
1505 if (wpa_set_wep_keys(wpa_s, ssid)) {
1506 use_crypt = 1;
1507 wep_keys_set = 1;
1508 }
1509 }
1510 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1511 use_crypt = 0;
1512
1513#ifdef IEEE8021X_EAPOL
1514 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1515 if ((ssid->eapol_flags &
1516 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1517 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1518 !wep_keys_set) {
1519 use_crypt = 0;
1520 } else {
1521 /* Assume that dynamic WEP-104 keys will be used and
1522 * set cipher suites in order for drivers to expect
1523 * encryption. */
1524 cipher_pairwise = cipher_group = CIPHER_WEP104;
1525 }
1526 }
1527#endif /* IEEE8021X_EAPOL */
1528
1529 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1530 /* Set the key before (and later after) association */
1531 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1532 }
1533
1534 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1535 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001536 params.ssid = bss->ssid;
1537 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001538 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1539 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1540 MACSTR " freq=%u MHz based on scan results "
1541 "(bssid_set=%d)",
1542 MAC2STR(bss->bssid), bss->freq,
1543 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001544 params.bssid = bss->bssid;
1545 params.freq = bss->freq;
1546 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001547 } else {
1548 params.ssid = ssid->ssid;
1549 params.ssid_len = ssid->ssid_len;
1550 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001551
1552 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1553 wpa_s->conf->ap_scan == 2) {
1554 params.bssid = ssid->bssid;
1555 params.fixed_bssid = 1;
1556 }
1557
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001558 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1559 params.freq == 0)
1560 params.freq = ssid->frequency; /* Initial channel for IBSS */
1561 params.wpa_ie = wpa_ie;
1562 params.wpa_ie_len = wpa_ie_len;
1563 params.pairwise_suite = cipher_pairwise;
1564 params.group_suite = cipher_group;
1565 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001566 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001567 params.auth_alg = algs;
1568 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001569 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001570 for (i = 0; i < NUM_WEP_KEYS; i++) {
1571 if (ssid->wep_key_len[i])
1572 params.wep_key[i] = ssid->wep_key[i];
1573 params.wep_key_len[i] = ssid->wep_key_len[i];
1574 }
1575 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1576
1577 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1578 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1579 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1580 params.passphrase = ssid->passphrase;
1581 if (ssid->psk_set)
1582 params.psk = ssid->psk;
1583 }
1584
1585 params.drop_unencrypted = use_crypt;
1586
1587#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001588 params.mgmt_frame_protection =
1589 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1590 wpa_s->conf->pmf : ssid->ieee80211w;
1591 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001592 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1593 struct wpa_ie_data ie;
1594 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1595 ie.capabilities &
1596 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1597 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1598 "MFP: require MFP");
1599 params.mgmt_frame_protection =
1600 MGMT_FRAME_PROTECTION_REQUIRED;
1601 }
1602 }
1603#endif /* CONFIG_IEEE80211W */
1604
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001605 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001606
1607 if (wpa_s->parent->set_sta_uapsd)
1608 params.uapsd = wpa_s->parent->sta_uapsd;
1609 else
1610 params.uapsd = -1;
1611
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001612#ifdef CONFIG_HT_OVERRIDES
1613 os_memset(&htcaps, 0, sizeof(htcaps));
1614 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1615 params.htcaps = (u8 *) &htcaps;
1616 params.htcaps_mask = (u8 *) &htcaps_mask;
1617 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1618#endif /* CONFIG_HT_OVERRIDES */
1619
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001620#ifdef ANDROID_P2P
1621 /* If multichannel concurrency is not supported, check for any frequency
1622 * conflict and take appropriate action.
1623 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001624 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1625 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1626 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001627 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001628 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001629 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001630 }
1631#endif
1632 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001633 if (ret < 0) {
1634 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1635 "failed");
1636 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1637 /*
1638 * The driver is known to mean what is saying, so we
1639 * can stop right here; the association will not
1640 * succeed.
1641 */
1642 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001643 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001644 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1645 return;
1646 }
1647 /* try to continue anyway; new association will be tried again
1648 * after timeout */
1649 assoc_failed = 1;
1650 }
1651
1652 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1653 /* Set the key after the association just in case association
1654 * cleared the previously configured key. */
1655 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1656 /* No need to timeout authentication since there is no key
1657 * management. */
1658 wpa_supplicant_cancel_auth_timeout(wpa_s);
1659 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1660#ifdef CONFIG_IBSS_RSN
1661 } else if (ssid->mode == WPAS_MODE_IBSS &&
1662 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1663 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1664 /*
1665 * RSN IBSS authentication is per-STA and we can disable the
1666 * per-BSSID authentication.
1667 */
1668 wpa_supplicant_cancel_auth_timeout(wpa_s);
1669#endif /* CONFIG_IBSS_RSN */
1670 } else {
1671 /* Timeout for IEEE 802.11 authentication and association */
1672 int timeout = 60;
1673
1674 if (assoc_failed) {
1675 /* give IBSS a bit more time */
1676 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1677 } else if (wpa_s->conf->ap_scan == 1) {
1678 /* give IBSS a bit more time */
1679 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1680 }
1681 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1682 }
1683
1684 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1685 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1686 /* Set static WEP keys again */
1687 wpa_set_wep_keys(wpa_s, ssid);
1688 }
1689
1690 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1691 /*
1692 * Do not allow EAP session resumption between different
1693 * network configurations.
1694 */
1695 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1696 }
1697 old_ssid = wpa_s->current_ssid;
1698 wpa_s->current_ssid = ssid;
1699 wpa_s->current_bss = bss;
1700 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1701 wpa_supplicant_initiate_eapol(wpa_s);
1702 if (old_ssid != wpa_s->current_ssid)
1703 wpas_notify_network_changed(wpa_s);
1704}
1705
1706
1707static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1708 const u8 *addr)
1709{
1710 struct wpa_ssid *old_ssid;
1711
1712 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001713 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001714 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001715 wpa_sm_set_config(wpa_s->wpa, NULL);
1716 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1717 if (old_ssid != wpa_s->current_ssid)
1718 wpas_notify_network_changed(wpa_s);
1719 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1720}
1721
1722
1723/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001724 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1725 * @wpa_s: Pointer to wpa_supplicant data
1726 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1727 *
1728 * This function is used to request %wpa_supplicant to deauthenticate from the
1729 * current AP.
1730 */
1731void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1732 int reason_code)
1733{
1734 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001735 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001736 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001737
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001738 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1739 " pending_bssid=" MACSTR " reason=%d state=%s",
1740 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1741 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1742
1743 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001744 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001745 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1746 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1747 wpa_s->wpa_state == WPA_ASSOCIATING))
1748 addr = wpa_s->pending_bssid;
1749 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1750 /*
1751 * When using driver-based BSS selection, we may not know the
1752 * BSSID with which we are currently trying to associate. We
1753 * need to notify the driver of this disconnection even in such
1754 * a case, so use the all zeros address here.
1755 */
1756 addr = wpa_s->bssid;
1757 zero_addr = 1;
1758 }
1759
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001760#ifdef CONFIG_TDLS
1761 wpa_tdls_teardown_peers(wpa_s->wpa);
1762#endif /* CONFIG_TDLS */
1763
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001764 if (addr) {
1765 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001766 os_memset(&event, 0, sizeof(event));
1767 event.deauth_info.reason_code = (u16) reason_code;
1768 event.deauth_info.locally_generated = 1;
1769 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001770 if (zero_addr)
1771 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001772 }
1773
1774 wpa_supplicant_clear_connection(wpa_s, addr);
1775}
1776
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001777static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1778 struct wpa_ssid *ssid)
1779{
1780 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1781 return;
1782
1783 ssid->disabled = 0;
1784 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1785 wpas_notify_network_enabled_changed(wpa_s, ssid);
1786
1787 /*
1788 * Try to reassociate since there is no current configuration and a new
1789 * network was made available.
1790 */
1791 if (!wpa_s->current_ssid)
1792 wpa_s->reassociate = 1;
1793}
1794
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001795
1796/**
1797 * wpa_supplicant_enable_network - Mark a configured network as enabled
1798 * @wpa_s: wpa_supplicant structure for a network interface
1799 * @ssid: wpa_ssid structure for a configured network or %NULL
1800 *
1801 * Enables the specified network or all networks if no network specified.
1802 */
1803void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1804 struct wpa_ssid *ssid)
1805{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001806 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001807 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1808 wpa_supplicant_enable_one_network(wpa_s, ssid);
1809 } else
1810 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001811
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001812 if (wpa_s->reassociate) {
1813 if (wpa_s->sched_scanning) {
1814 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1815 "new network to scan filters");
1816 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001817 }
1818
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001819 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001820 }
1821}
1822
1823
1824/**
1825 * wpa_supplicant_disable_network - Mark a configured network as disabled
1826 * @wpa_s: wpa_supplicant structure for a network interface
1827 * @ssid: wpa_ssid structure for a configured network or %NULL
1828 *
1829 * Disables the specified network or all networks if no network specified.
1830 */
1831void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1832 struct wpa_ssid *ssid)
1833{
1834 struct wpa_ssid *other_ssid;
1835 int was_disabled;
1836
1837 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001838 if (wpa_s->sched_scanning)
1839 wpa_supplicant_cancel_sched_scan(wpa_s);
1840
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001841 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1842 other_ssid = other_ssid->next) {
1843 was_disabled = other_ssid->disabled;
1844 if (was_disabled == 2)
1845 continue; /* do not change persistent P2P group
1846 * data */
1847
1848 other_ssid->disabled = 1;
1849
1850 if (was_disabled != other_ssid->disabled)
1851 wpas_notify_network_enabled_changed(
1852 wpa_s, other_ssid);
1853 }
1854 if (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);
1857 } else if (ssid->disabled != 2) {
1858 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001859 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001860 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1861
1862 was_disabled = ssid->disabled;
1863
1864 ssid->disabled = 1;
1865
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001866 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001867 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001868 if (wpa_s->sched_scanning) {
1869 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1870 "to remove network from filters");
1871 wpa_supplicant_cancel_sched_scan(wpa_s);
1872 wpa_supplicant_req_scan(wpa_s, 0, 0);
1873 }
1874 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001875 }
1876}
1877
1878
1879/**
1880 * wpa_supplicant_select_network - Attempt association with a network
1881 * @wpa_s: wpa_supplicant structure for a network interface
1882 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1883 */
1884void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1885 struct wpa_ssid *ssid)
1886{
1887
1888 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001889 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001890
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001891 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001892 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001893 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001894 disconnected = 1;
1895 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001896
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001897 if (ssid)
1898 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1899
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001900 /*
1901 * Mark all other networks disabled or mark all networks enabled if no
1902 * network specified.
1903 */
1904 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1905 other_ssid = other_ssid->next) {
1906 int was_disabled = other_ssid->disabled;
1907 if (was_disabled == 2)
1908 continue; /* do not change persistent P2P group data */
1909
1910 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001911 if (was_disabled && !other_ssid->disabled)
1912 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001913
1914 if (was_disabled != other_ssid->disabled)
1915 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1916 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001917
1918 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1919 /* We are already associated with the selected network */
1920 wpa_printf(MSG_DEBUG, "Already associated with the "
1921 "selected network - do nothing");
1922 return;
1923 }
1924
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001925 if (ssid)
1926 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001927 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001928 wpa_s->disconnected = 0;
1929 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001930
1931 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1932 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001933
1934 if (ssid)
1935 wpas_notify_network_selected(wpa_s, ssid);
1936}
1937
1938
1939/**
1940 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1941 * @wpa_s: wpa_supplicant structure for a network interface
1942 * @ap_scan: AP scan mode
1943 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1944 *
1945 */
1946int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1947{
1948
1949 int old_ap_scan;
1950
1951 if (ap_scan < 0 || ap_scan > 2)
1952 return -1;
1953
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001954#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001955 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1956 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1957 wpa_s->wpa_state < WPA_COMPLETED) {
1958 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1959 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001960 return 0;
1961 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001962#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001963
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001964 old_ap_scan = wpa_s->conf->ap_scan;
1965 wpa_s->conf->ap_scan = ap_scan;
1966
1967 if (old_ap_scan != wpa_s->conf->ap_scan)
1968 wpas_notify_ap_scan_changed(wpa_s);
1969
1970 return 0;
1971}
1972
1973
1974/**
1975 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1976 * @wpa_s: wpa_supplicant structure for a network interface
1977 * @expire_age: Expiration age in seconds
1978 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1979 *
1980 */
1981int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1982 unsigned int bss_expire_age)
1983{
1984 if (bss_expire_age < 10) {
1985 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1986 bss_expire_age);
1987 return -1;
1988 }
1989 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1990 bss_expire_age);
1991 wpa_s->conf->bss_expiration_age = bss_expire_age;
1992
1993 return 0;
1994}
1995
1996
1997/**
1998 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
1999 * @wpa_s: wpa_supplicant structure for a network interface
2000 * @expire_count: number of scans after which an unseen BSS is reclaimed
2001 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2002 *
2003 */
2004int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2005 unsigned int bss_expire_count)
2006{
2007 if (bss_expire_count < 1) {
2008 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2009 bss_expire_count);
2010 return -1;
2011 }
2012 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2013 bss_expire_count);
2014 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2015
2016 return 0;
2017}
2018
2019
2020/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07002021 * wpa_supplicant_set_scan_interval - Set scan interval
2022 * @wpa_s: wpa_supplicant structure for a network interface
2023 * @scan_interval: scan interval in seconds
2024 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2025 *
2026 */
2027int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2028 int scan_interval)
2029{
2030 if (scan_interval < 0) {
2031 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2032 scan_interval);
2033 return -1;
2034 }
2035 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2036 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002037 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002038
2039 return 0;
2040}
2041
2042
2043/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002044 * wpa_supplicant_set_debug_params - Set global debug params
2045 * @global: wpa_global structure
2046 * @debug_level: debug level
2047 * @debug_timestamp: determines if show timestamp in debug data
2048 * @debug_show_keys: determines if show keys in debug data
2049 * Returns: 0 if succeed or -1 if debug_level has wrong value
2050 */
2051int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2052 int debug_timestamp, int debug_show_keys)
2053{
2054
2055 int old_level, old_timestamp, old_show_keys;
2056
2057 /* check for allowed debuglevels */
2058 if (debug_level != MSG_EXCESSIVE &&
2059 debug_level != MSG_MSGDUMP &&
2060 debug_level != MSG_DEBUG &&
2061 debug_level != MSG_INFO &&
2062 debug_level != MSG_WARNING &&
2063 debug_level != MSG_ERROR)
2064 return -1;
2065
2066 old_level = wpa_debug_level;
2067 old_timestamp = wpa_debug_timestamp;
2068 old_show_keys = wpa_debug_show_keys;
2069
2070 wpa_debug_level = debug_level;
2071 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2072 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2073
2074 if (wpa_debug_level != old_level)
2075 wpas_notify_debug_level_changed(global);
2076 if (wpa_debug_timestamp != old_timestamp)
2077 wpas_notify_debug_timestamp_changed(global);
2078 if (wpa_debug_show_keys != old_show_keys)
2079 wpas_notify_debug_show_keys_changed(global);
2080
2081 return 0;
2082}
2083
2084
2085/**
2086 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2087 * @wpa_s: Pointer to wpa_supplicant data
2088 * Returns: A pointer to the current network structure or %NULL on failure
2089 */
2090struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2091{
2092 struct wpa_ssid *entry;
2093 u8 ssid[MAX_SSID_LEN];
2094 int res;
2095 size_t ssid_len;
2096 u8 bssid[ETH_ALEN];
2097 int wired;
2098
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002099 res = wpa_drv_get_ssid(wpa_s, ssid);
2100 if (res < 0) {
2101 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2102 "driver");
2103 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002104 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002105 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002106
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002107 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002108 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2109 "driver");
2110 return NULL;
2111 }
2112
2113 wired = wpa_s->conf->ap_scan == 0 &&
2114 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2115
2116 entry = wpa_s->conf->ssid;
2117 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002118 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002119 ((ssid_len == entry->ssid_len &&
2120 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2121 (!entry->bssid_set ||
2122 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2123 return entry;
2124#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002125 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002126 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2127 (entry->ssid == NULL || entry->ssid_len == 0) &&
2128 (!entry->bssid_set ||
2129 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2130 return entry;
2131#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002132
Dmitry Shmidt04949592012-07-19 12:16:46 -07002133 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002134 entry->ssid_len == 0 &&
2135 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2136 return entry;
2137
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002138 entry = entry->next;
2139 }
2140
2141 return NULL;
2142}
2143
2144
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002145static int select_driver(struct wpa_supplicant *wpa_s, int i)
2146{
2147 struct wpa_global *global = wpa_s->global;
2148
2149 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2150 global->drv_priv[i] = wpa_drivers[i]->global_init();
2151 if (global->drv_priv[i] == NULL) {
2152 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2153 "'%s'", wpa_drivers[i]->name);
2154 return -1;
2155 }
2156 }
2157
2158 wpa_s->driver = wpa_drivers[i];
2159 wpa_s->global_drv_priv = global->drv_priv[i];
2160
2161 return 0;
2162}
2163
2164
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002165static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2166 const char *name)
2167{
2168 int i;
2169 size_t len;
2170 const char *pos, *driver = name;
2171
2172 if (wpa_s == NULL)
2173 return -1;
2174
2175 if (wpa_drivers[0] == NULL) {
2176 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2177 "wpa_supplicant");
2178 return -1;
2179 }
2180
2181 if (name == NULL) {
2182 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002183 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002184 }
2185
2186 do {
2187 pos = os_strchr(driver, ',');
2188 if (pos)
2189 len = pos - driver;
2190 else
2191 len = os_strlen(driver);
2192
2193 for (i = 0; wpa_drivers[i]; i++) {
2194 if (os_strlen(wpa_drivers[i]->name) == len &&
2195 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002196 0) {
2197 /* First driver that succeeds wins */
2198 if (select_driver(wpa_s, i) == 0)
2199 return 0;
2200 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002201 }
2202
2203 driver = pos + 1;
2204 } while (pos);
2205
2206 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2207 return -1;
2208}
2209
2210
2211/**
2212 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2213 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2214 * with struct wpa_driver_ops::init()
2215 * @src_addr: Source address of the EAPOL frame
2216 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2217 * @len: Length of the EAPOL data
2218 *
2219 * This function is called for each received EAPOL frame. Most driver
2220 * interfaces rely on more generic OS mechanism for receiving frames through
2221 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2222 * take care of received EAPOL frames and deliver them to the core supplicant
2223 * code by calling this function.
2224 */
2225void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2226 const u8 *buf, size_t len)
2227{
2228 struct wpa_supplicant *wpa_s = ctx;
2229
2230 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2231 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2232
Jouni Malinena05074c2012-12-21 21:35:35 +02002233 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2234 (wpa_s->last_eapol_matches_bssid &&
2235#ifdef CONFIG_AP
2236 !wpa_s->ap_iface &&
2237#endif /* CONFIG_AP */
2238 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002239 /*
2240 * There is possible race condition between receiving the
2241 * association event and the EAPOL frame since they are coming
2242 * through different paths from the driver. In order to avoid
2243 * issues in trying to process the EAPOL frame before receiving
2244 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002245 * the association event is received. This may also be needed in
2246 * driver-based roaming case, so also use src_addr != BSSID as a
2247 * trigger if we have previously confirmed that the
2248 * Authenticator uses BSSID as the src_addr (which is not the
2249 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002250 */
2251 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002252 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2253 wpa_supplicant_state_txt(wpa_s->wpa_state),
2254 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002255 wpabuf_free(wpa_s->pending_eapol_rx);
2256 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2257 if (wpa_s->pending_eapol_rx) {
2258 os_get_time(&wpa_s->pending_eapol_rx_time);
2259 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2260 ETH_ALEN);
2261 }
2262 return;
2263 }
2264
Jouni Malinena05074c2012-12-21 21:35:35 +02002265 wpa_s->last_eapol_matches_bssid =
2266 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2267
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002268#ifdef CONFIG_AP
2269 if (wpa_s->ap_iface) {
2270 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2271 return;
2272 }
2273#endif /* CONFIG_AP */
2274
2275 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2276 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2277 "no key management is configured");
2278 return;
2279 }
2280
2281 if (wpa_s->eapol_received == 0 &&
2282 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2283 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2284 wpa_s->wpa_state != WPA_COMPLETED) &&
2285 (wpa_s->current_ssid == NULL ||
2286 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2287 /* Timeout for completing IEEE 802.1X and WPA authentication */
2288 wpa_supplicant_req_auth_timeout(
2289 wpa_s,
2290 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2291 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2292 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2293 70 : 10, 0);
2294 }
2295 wpa_s->eapol_received++;
2296
2297 if (wpa_s->countermeasures) {
2298 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2299 "EAPOL packet");
2300 return;
2301 }
2302
2303#ifdef CONFIG_IBSS_RSN
2304 if (wpa_s->current_ssid &&
2305 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2306 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2307 return;
2308 }
2309#endif /* CONFIG_IBSS_RSN */
2310
2311 /* Source address of the incoming EAPOL frame could be compared to the
2312 * current BSSID. However, it is possible that a centralized
2313 * Authenticator could be using another MAC address than the BSSID of
2314 * an AP, so just allow any address to be used for now. The replies are
2315 * still sent to the current BSSID (if available), though. */
2316
2317 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2318 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2319 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2320 return;
2321 wpa_drv_poll(wpa_s);
2322 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2323 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2324 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2325 /*
2326 * Set portValid = TRUE here since we are going to skip 4-way
2327 * handshake processing which would normally set portValid. We
2328 * need this to allow the EAPOL state machines to be completed
2329 * without going through EAPOL-Key handshake.
2330 */
2331 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2332 }
2333}
2334
2335
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002336int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002337{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002338 if (wpa_s->driver->send_eapol) {
2339 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2340 if (addr)
2341 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2342 } else if (!(wpa_s->drv_flags &
2343 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002344 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002345 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2346 wpa_drv_get_mac_addr(wpa_s),
2347 ETH_P_EAPOL,
2348 wpa_supplicant_rx_eapol, wpa_s, 0);
2349 if (wpa_s->l2 == NULL)
2350 return -1;
2351 } else {
2352 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2353 if (addr)
2354 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2355 }
2356
2357 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2358 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2359 return -1;
2360 }
2361
2362 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2363 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002364 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2365
2366 return 0;
2367}
2368
2369
Dmitry Shmidt04949592012-07-19 12:16:46 -07002370static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2371 const u8 *buf, size_t len)
2372{
2373 struct wpa_supplicant *wpa_s = ctx;
2374 const struct l2_ethhdr *eth;
2375
2376 if (len < sizeof(*eth))
2377 return;
2378 eth = (const struct l2_ethhdr *) buf;
2379
2380 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2381 !(eth->h_dest[0] & 0x01)) {
2382 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2383 " (bridge - not for this interface - ignore)",
2384 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2385 return;
2386 }
2387
2388 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2389 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2390 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2391 len - sizeof(*eth));
2392}
2393
2394
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002395/**
2396 * wpa_supplicant_driver_init - Initialize driver interface parameters
2397 * @wpa_s: Pointer to wpa_supplicant data
2398 * Returns: 0 on success, -1 on failure
2399 *
2400 * This function is called to initialize driver interface parameters.
2401 * wpa_drv_init() must have been called before this function to initialize the
2402 * driver interface.
2403 */
2404int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2405{
2406 static int interface_count = 0;
2407
2408 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2409 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002410
2411 if (wpa_s->bridge_ifname[0]) {
2412 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2413 "interface '%s'", wpa_s->bridge_ifname);
2414 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2415 wpa_s->own_addr,
2416 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002417 wpa_supplicant_rx_eapol_bridge,
2418 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002419 if (wpa_s->l2_br == NULL) {
2420 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2421 "connection for the bridge interface '%s'",
2422 wpa_s->bridge_ifname);
2423 return -1;
2424 }
2425 }
2426
2427 wpa_clear_keys(wpa_s, NULL);
2428
2429 /* Make sure that TKIP countermeasures are not left enabled (could
2430 * happen if wpa_supplicant is killed during countermeasures. */
2431 wpa_drv_set_countermeasures(wpa_s, 0);
2432
2433 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2434 wpa_drv_flush_pmkid(wpa_s);
2435
2436 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002437 wpa_s->prev_scan_wildcard = 0;
2438
Dmitry Shmidt04949592012-07-19 12:16:46 -07002439 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002440 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2441 100000))
2442 wpa_supplicant_req_scan(wpa_s, interface_count,
2443 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002444 interface_count++;
2445 } else
2446 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2447
2448 return 0;
2449}
2450
2451
2452static int wpa_supplicant_daemon(const char *pid_file)
2453{
2454 wpa_printf(MSG_DEBUG, "Daemonize..");
2455 return os_daemonize(pid_file);
2456}
2457
2458
2459static struct wpa_supplicant * wpa_supplicant_alloc(void)
2460{
2461 struct wpa_supplicant *wpa_s;
2462
2463 wpa_s = os_zalloc(sizeof(*wpa_s));
2464 if (wpa_s == NULL)
2465 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002466 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002467 wpa_s->scan_interval = 5;
2468 wpa_s->new_connection = 1;
2469 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002470 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002471
2472 return wpa_s;
2473}
2474
2475
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002476#ifdef CONFIG_HT_OVERRIDES
2477
2478static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2479 struct ieee80211_ht_capabilities *htcaps,
2480 struct ieee80211_ht_capabilities *htcaps_mask,
2481 const char *ht_mcs)
2482{
2483 /* parse ht_mcs into hex array */
2484 int i;
2485 const char *tmp = ht_mcs;
2486 char *end = NULL;
2487
2488 /* If ht_mcs is null, do not set anything */
2489 if (!ht_mcs)
2490 return 0;
2491
2492 /* This is what we are setting in the kernel */
2493 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2494
2495 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2496
2497 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2498 errno = 0;
2499 long v = strtol(tmp, &end, 16);
2500 if (errno == 0) {
2501 wpa_msg(wpa_s, MSG_DEBUG,
2502 "htcap value[%i]: %ld end: %p tmp: %p",
2503 i, v, end, tmp);
2504 if (end == tmp)
2505 break;
2506
2507 htcaps->supported_mcs_set[i] = v;
2508 tmp = end;
2509 } else {
2510 wpa_msg(wpa_s, MSG_ERROR,
2511 "Failed to parse ht-mcs: %s, error: %s\n",
2512 ht_mcs, strerror(errno));
2513 return -1;
2514 }
2515 }
2516
2517 /*
2518 * If we were able to parse any values, then set mask for the MCS set.
2519 */
2520 if (i) {
2521 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2522 IEEE80211_HT_MCS_MASK_LEN - 1);
2523 /* skip the 3 reserved bits */
2524 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2525 0x1f;
2526 }
2527
2528 return 0;
2529}
2530
2531
2532static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2533 struct ieee80211_ht_capabilities *htcaps,
2534 struct ieee80211_ht_capabilities *htcaps_mask,
2535 int disabled)
2536{
2537 u16 msk;
2538
2539 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2540
2541 if (disabled == -1)
2542 return 0;
2543
2544 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2545 htcaps_mask->ht_capabilities_info |= msk;
2546 if (disabled)
2547 htcaps->ht_capabilities_info &= msk;
2548 else
2549 htcaps->ht_capabilities_info |= msk;
2550
2551 return 0;
2552}
2553
2554
2555static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2556 struct ieee80211_ht_capabilities *htcaps,
2557 struct ieee80211_ht_capabilities *htcaps_mask,
2558 int factor)
2559{
2560 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2561
2562 if (factor == -1)
2563 return 0;
2564
2565 if (factor < 0 || factor > 3) {
2566 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2567 "Must be 0-3 or -1", factor);
2568 return -EINVAL;
2569 }
2570
2571 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2572 htcaps->a_mpdu_params &= ~0x3;
2573 htcaps->a_mpdu_params |= factor & 0x3;
2574
2575 return 0;
2576}
2577
2578
2579static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2580 struct ieee80211_ht_capabilities *htcaps,
2581 struct ieee80211_ht_capabilities *htcaps_mask,
2582 int density)
2583{
2584 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2585
2586 if (density == -1)
2587 return 0;
2588
2589 if (density < 0 || density > 7) {
2590 wpa_msg(wpa_s, MSG_ERROR,
2591 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2592 density);
2593 return -EINVAL;
2594 }
2595
2596 htcaps_mask->a_mpdu_params |= 0x1C;
2597 htcaps->a_mpdu_params &= ~(0x1C);
2598 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2599
2600 return 0;
2601}
2602
2603
2604static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2605 struct ieee80211_ht_capabilities *htcaps,
2606 struct ieee80211_ht_capabilities *htcaps_mask,
2607 int disabled)
2608{
2609 /* Masking these out disables HT40 */
2610 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2611 HT_CAP_INFO_SHORT_GI40MHZ);
2612
2613 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2614
2615 if (disabled)
2616 htcaps->ht_capabilities_info &= ~msk;
2617 else
2618 htcaps->ht_capabilities_info |= msk;
2619
2620 htcaps_mask->ht_capabilities_info |= msk;
2621
2622 return 0;
2623}
2624
2625
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002626static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2627 struct ieee80211_ht_capabilities *htcaps,
2628 struct ieee80211_ht_capabilities *htcaps_mask,
2629 int disabled)
2630{
2631 /* Masking these out disables SGI */
2632 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2633 HT_CAP_INFO_SHORT_GI40MHZ);
2634
2635 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2636
2637 if (disabled)
2638 htcaps->ht_capabilities_info &= ~msk;
2639 else
2640 htcaps->ht_capabilities_info |= msk;
2641
2642 htcaps_mask->ht_capabilities_info |= msk;
2643
2644 return 0;
2645}
2646
2647
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002648void wpa_supplicant_apply_ht_overrides(
2649 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2650 struct wpa_driver_associate_params *params)
2651{
2652 struct ieee80211_ht_capabilities *htcaps;
2653 struct ieee80211_ht_capabilities *htcaps_mask;
2654
2655 if (!ssid)
2656 return;
2657
2658 params->disable_ht = ssid->disable_ht;
2659 if (!params->htcaps || !params->htcaps_mask)
2660 return;
2661
2662 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2663 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2664 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2665 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2666 ssid->disable_max_amsdu);
2667 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2668 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2669 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002670 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002671}
2672
2673#endif /* CONFIG_HT_OVERRIDES */
2674
2675
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002676#ifdef CONFIG_VHT_OVERRIDES
2677void wpa_supplicant_apply_vht_overrides(
2678 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2679 struct wpa_driver_associate_params *params)
2680{
2681 struct ieee80211_vht_capabilities *vhtcaps;
2682 struct ieee80211_vht_capabilities *vhtcaps_mask;
2683
2684 if (!ssid)
2685 return;
2686
2687 params->disable_vht = ssid->disable_vht;
2688
2689 vhtcaps = (void *) params->vhtcaps;
2690 vhtcaps_mask = (void *) params->vhtcaps_mask;
2691
2692 if (!vhtcaps || !vhtcaps_mask)
2693 return;
2694
2695 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2696 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2697
2698#define OVERRIDE_MCS(i) \
2699 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2700 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2701 3 << 2 * (i - 1); \
2702 vhtcaps->vht_supported_mcs_set.tx_map |= \
2703 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2704 } \
2705 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2706 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2707 3 << 2 * (i - 1); \
2708 vhtcaps->vht_supported_mcs_set.rx_map |= \
2709 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2710 }
2711
2712 OVERRIDE_MCS(1);
2713 OVERRIDE_MCS(2);
2714 OVERRIDE_MCS(3);
2715 OVERRIDE_MCS(4);
2716 OVERRIDE_MCS(5);
2717 OVERRIDE_MCS(6);
2718 OVERRIDE_MCS(7);
2719 OVERRIDE_MCS(8);
2720}
2721#endif /* CONFIG_VHT_OVERRIDES */
2722
2723
Dmitry Shmidt04949592012-07-19 12:16:46 -07002724static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2725{
2726#ifdef PCSC_FUNCS
2727 size_t len;
2728
2729 if (!wpa_s->conf->pcsc_reader)
2730 return 0;
2731
2732 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2733 if (!wpa_s->scard)
2734 return 1;
2735
2736 if (wpa_s->conf->pcsc_pin &&
2737 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2738 scard_deinit(wpa_s->scard);
2739 wpa_s->scard = NULL;
2740 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2741 return -1;
2742 }
2743
2744 len = sizeof(wpa_s->imsi) - 1;
2745 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2746 scard_deinit(wpa_s->scard);
2747 wpa_s->scard = NULL;
2748 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2749 return -1;
2750 }
2751 wpa_s->imsi[len] = '\0';
2752
2753 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2754
2755 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2756 wpa_s->imsi, wpa_s->mnc_len);
2757
2758 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2759 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2760#endif /* PCSC_FUNCS */
2761
2762 return 0;
2763}
2764
2765
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002766int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2767{
2768 char *val, *pos;
2769
2770 ext_password_deinit(wpa_s->ext_pw);
2771 wpa_s->ext_pw = NULL;
2772 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2773
2774 if (!wpa_s->conf->ext_password_backend)
2775 return 0;
2776
2777 val = os_strdup(wpa_s->conf->ext_password_backend);
2778 if (val == NULL)
2779 return -1;
2780 pos = os_strchr(val, ':');
2781 if (pos)
2782 *pos++ = '\0';
2783
2784 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2785
2786 wpa_s->ext_pw = ext_password_init(val, pos);
2787 os_free(val);
2788 if (wpa_s->ext_pw == NULL) {
2789 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2790 return -1;
2791 }
2792 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2793
2794 return 0;
2795}
2796
2797
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002798static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2799 struct wpa_interface *iface)
2800{
2801 const char *ifname, *driver;
2802 struct wpa_driver_capa capa;
2803
2804 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2805 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2806 iface->confname ? iface->confname : "N/A",
2807 iface->driver ? iface->driver : "default",
2808 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2809 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2810
2811 if (iface->confname) {
2812#ifdef CONFIG_BACKEND_FILE
2813 wpa_s->confname = os_rel2abs_path(iface->confname);
2814 if (wpa_s->confname == NULL) {
2815 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2816 "for configuration file '%s'.",
2817 iface->confname);
2818 return -1;
2819 }
2820 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2821 iface->confname, wpa_s->confname);
2822#else /* CONFIG_BACKEND_FILE */
2823 wpa_s->confname = os_strdup(iface->confname);
2824#endif /* CONFIG_BACKEND_FILE */
2825 wpa_s->conf = wpa_config_read(wpa_s->confname);
2826 if (wpa_s->conf == NULL) {
2827 wpa_printf(MSG_ERROR, "Failed to read or parse "
2828 "configuration '%s'.", wpa_s->confname);
2829 return -1;
2830 }
2831
2832 /*
2833 * Override ctrl_interface and driver_param if set on command
2834 * line.
2835 */
2836 if (iface->ctrl_interface) {
2837 os_free(wpa_s->conf->ctrl_interface);
2838 wpa_s->conf->ctrl_interface =
2839 os_strdup(iface->ctrl_interface);
2840 }
2841
2842 if (iface->driver_param) {
2843 os_free(wpa_s->conf->driver_param);
2844 wpa_s->conf->driver_param =
2845 os_strdup(iface->driver_param);
2846 }
2847 } else
2848 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2849 iface->driver_param);
2850
2851 if (wpa_s->conf == NULL) {
2852 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2853 return -1;
2854 }
2855
2856 if (iface->ifname == NULL) {
2857 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2858 return -1;
2859 }
2860 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2861 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2862 iface->ifname);
2863 return -1;
2864 }
2865 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2866
2867 if (iface->bridge_ifname) {
2868 if (os_strlen(iface->bridge_ifname) >=
2869 sizeof(wpa_s->bridge_ifname)) {
2870 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2871 "name '%s'.", iface->bridge_ifname);
2872 return -1;
2873 }
2874 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2875 sizeof(wpa_s->bridge_ifname));
2876 }
2877
2878 /* RSNA Supplicant Key Management - INITIALIZE */
2879 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2880 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2881
2882 /* Initialize driver interface and register driver event handler before
2883 * L2 receive handler so that association events are processed before
2884 * EAPOL-Key packets if both become available for the same select()
2885 * call. */
2886 driver = iface->driver;
2887next_driver:
2888 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2889 return -1;
2890
2891 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2892 if (wpa_s->drv_priv == NULL) {
2893 const char *pos;
2894 pos = driver ? os_strchr(driver, ',') : NULL;
2895 if (pos) {
2896 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2897 "driver interface - try next driver wrapper");
2898 driver = pos + 1;
2899 goto next_driver;
2900 }
2901 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2902 "interface");
2903 return -1;
2904 }
2905 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2906 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2907 "driver_param '%s'", wpa_s->conf->driver_param);
2908 return -1;
2909 }
2910
2911 ifname = wpa_drv_get_ifname(wpa_s);
2912 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2913 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2914 "interface name with '%s'", ifname);
2915 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2916 }
2917
2918 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2919 return -1;
2920
2921 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2922 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2923 NULL);
2924 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2925
2926 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2927 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2928 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2929 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2930 "dot11RSNAConfigPMKLifetime");
2931 return -1;
2932 }
2933
2934 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2935 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2936 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2937 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2938 "dot11RSNAConfigPMKReauthThreshold");
2939 return -1;
2940 }
2941
2942 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2943 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2944 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2945 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2946 "dot11RSNAConfigSATimeout");
2947 return -1;
2948 }
2949
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002950 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2951 &wpa_s->hw.num_modes,
2952 &wpa_s->hw.flags);
2953
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002954 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002955 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002956 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002957 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002958 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002959 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002960 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2961 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2962 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002963 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2964 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07002965 wpa_s->extended_capa = capa.extended_capa;
2966 wpa_s->extended_capa_mask = capa.extended_capa_mask;
2967 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002968 }
2969 if (wpa_s->max_remain_on_chan == 0)
2970 wpa_s->max_remain_on_chan = 1000;
2971
2972 if (wpa_supplicant_driver_init(wpa_s) < 0)
2973 return -1;
2974
2975#ifdef CONFIG_TDLS
2976 if (wpa_tdls_init(wpa_s->wpa))
2977 return -1;
2978#endif /* CONFIG_TDLS */
2979
2980 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2981 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2982 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2983 return -1;
2984 }
2985
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002986 if (wpas_wps_init(wpa_s))
2987 return -1;
2988
2989 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2990 return -1;
2991 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2992
2993 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2994 if (wpa_s->ctrl_iface == NULL) {
2995 wpa_printf(MSG_ERROR,
2996 "Failed to initialize control interface '%s'.\n"
2997 "You may have another wpa_supplicant process "
2998 "already running or the file was\n"
2999 "left by an unclean termination of wpa_supplicant "
3000 "in which case you will need\n"
3001 "to manually remove this file before starting "
3002 "wpa_supplicant again.\n",
3003 wpa_s->conf->ctrl_interface);
3004 return -1;
3005 }
3006
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003007 wpa_s->gas = gas_query_init(wpa_s);
3008 if (wpa_s->gas == NULL) {
3009 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3010 return -1;
3011 }
3012
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003013#ifdef CONFIG_P2P
3014 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
3015 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
3016 return -1;
3017 }
3018#endif /* CONFIG_P2P */
3019
3020 if (wpa_bss_init(wpa_s) < 0)
3021 return -1;
3022
Dmitry Shmidt04949592012-07-19 12:16:46 -07003023 if (pcsc_reader_init(wpa_s) < 0)
3024 return -1;
3025
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003026 if (wpas_init_ext_pw(wpa_s) < 0)
3027 return -1;
3028
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003029 return 0;
3030}
3031
3032
3033static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003034 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003035{
3036 if (wpa_s->drv_priv) {
3037 wpa_supplicant_deauthenticate(wpa_s,
3038 WLAN_REASON_DEAUTH_LEAVING);
3039
3040 wpa_drv_set_countermeasures(wpa_s, 0);
3041 wpa_clear_keys(wpa_s, NULL);
3042 }
3043
3044 wpa_supplicant_cleanup(wpa_s);
3045
Dmitry Shmidt04949592012-07-19 12:16:46 -07003046#ifdef CONFIG_P2P
3047 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3048 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3049 "the management interface is being removed");
3050 wpas_p2p_deinit_global(wpa_s->global);
3051 }
3052#endif /* CONFIG_P2P */
3053
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003054 if (wpa_s->drv_priv)
3055 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003056
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003057 if (notify)
3058 wpas_notify_iface_removed(wpa_s);
3059
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003060 if (terminate)
3061 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003062
3063 if (wpa_s->ctrl_iface) {
3064 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3065 wpa_s->ctrl_iface = NULL;
3066 }
3067
3068 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003069 wpa_config_free(wpa_s->conf);
3070 wpa_s->conf = NULL;
3071 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003072}
3073
3074
3075/**
3076 * wpa_supplicant_add_iface - Add a new network interface
3077 * @global: Pointer to global data from wpa_supplicant_init()
3078 * @iface: Interface configuration options
3079 * Returns: Pointer to the created interface or %NULL on failure
3080 *
3081 * This function is used to add new network interfaces for %wpa_supplicant.
3082 * This can be called before wpa_supplicant_run() to add interfaces before the
3083 * main event loop has been started. In addition, new interfaces can be added
3084 * dynamically while %wpa_supplicant is already running. This could happen,
3085 * e.g., when a hotplug network adapter is inserted.
3086 */
3087struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3088 struct wpa_interface *iface)
3089{
3090 struct wpa_supplicant *wpa_s;
3091 struct wpa_interface t_iface;
3092 struct wpa_ssid *ssid;
3093
3094 if (global == NULL || iface == NULL)
3095 return NULL;
3096
3097 wpa_s = wpa_supplicant_alloc();
3098 if (wpa_s == NULL)
3099 return NULL;
3100
3101 wpa_s->global = global;
3102
3103 t_iface = *iface;
3104 if (global->params.override_driver) {
3105 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3106 "('%s' -> '%s')",
3107 iface->driver, global->params.override_driver);
3108 t_iface.driver = global->params.override_driver;
3109 }
3110 if (global->params.override_ctrl_interface) {
3111 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3112 "ctrl_interface ('%s' -> '%s')",
3113 iface->ctrl_interface,
3114 global->params.override_ctrl_interface);
3115 t_iface.ctrl_interface =
3116 global->params.override_ctrl_interface;
3117 }
3118 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3119 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3120 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003121 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003122 os_free(wpa_s);
3123 return NULL;
3124 }
3125
3126 /* Notify the control interfaces about new iface */
3127 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003128 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003129 os_free(wpa_s);
3130 return NULL;
3131 }
3132
3133 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3134 wpas_notify_network_added(wpa_s, ssid);
3135
3136 wpa_s->next = global->ifaces;
3137 global->ifaces = wpa_s;
3138
3139 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003140 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003141
3142 return wpa_s;
3143}
3144
3145
3146/**
3147 * wpa_supplicant_remove_iface - Remove a network interface
3148 * @global: Pointer to global data from wpa_supplicant_init()
3149 * @wpa_s: Pointer to the network interface to be removed
3150 * Returns: 0 if interface was removed, -1 if interface was not found
3151 *
3152 * This function can be used to dynamically remove network interfaces from
3153 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3154 * addition, this function is used to remove all remaining interfaces when
3155 * %wpa_supplicant is terminated.
3156 */
3157int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003158 struct wpa_supplicant *wpa_s,
3159 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003160{
3161 struct wpa_supplicant *prev;
3162
3163 /* Remove interface from the global list of interfaces */
3164 prev = global->ifaces;
3165 if (prev == wpa_s) {
3166 global->ifaces = wpa_s->next;
3167 } else {
3168 while (prev && prev->next != wpa_s)
3169 prev = prev->next;
3170 if (prev == NULL)
3171 return -1;
3172 prev->next = wpa_s->next;
3173 }
3174
3175 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3176
3177 if (global->p2p_group_formation == wpa_s)
3178 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07003179 if (global->p2p_invite_group == wpa_s)
3180 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003181 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003182 os_free(wpa_s);
3183
3184 return 0;
3185}
3186
3187
3188/**
3189 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3190 * @wpa_s: Pointer to the network interface
3191 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3192 */
3193const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3194{
3195 const char *eapol_method;
3196
3197 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3198 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3199 return "NO-EAP";
3200 }
3201
3202 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3203 if (eapol_method == NULL)
3204 return "UNKNOWN-EAP";
3205
3206 return eapol_method;
3207}
3208
3209
3210/**
3211 * wpa_supplicant_get_iface - Get a new network interface
3212 * @global: Pointer to global data from wpa_supplicant_init()
3213 * @ifname: Interface name
3214 * Returns: Pointer to the interface or %NULL if not found
3215 */
3216struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3217 const char *ifname)
3218{
3219 struct wpa_supplicant *wpa_s;
3220
3221 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3222 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3223 return wpa_s;
3224 }
3225 return NULL;
3226}
3227
3228
3229#ifndef CONFIG_NO_WPA_MSG
3230static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3231{
3232 struct wpa_supplicant *wpa_s = ctx;
3233 if (wpa_s == NULL)
3234 return NULL;
3235 return wpa_s->ifname;
3236}
3237#endif /* CONFIG_NO_WPA_MSG */
3238
3239
3240/**
3241 * wpa_supplicant_init - Initialize %wpa_supplicant
3242 * @params: Parameters for %wpa_supplicant
3243 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3244 *
3245 * This function is used to initialize %wpa_supplicant. After successful
3246 * initialization, the returned data pointer can be used to add and remove
3247 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3248 */
3249struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3250{
3251 struct wpa_global *global;
3252 int ret, i;
3253
3254 if (params == NULL)
3255 return NULL;
3256
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003257#ifdef CONFIG_DRIVER_NDIS
3258 {
3259 void driver_ndis_init_ops(void);
3260 driver_ndis_init_ops();
3261 }
3262#endif /* CONFIG_DRIVER_NDIS */
3263
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003264#ifndef CONFIG_NO_WPA_MSG
3265 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3266#endif /* CONFIG_NO_WPA_MSG */
3267
3268 wpa_debug_open_file(params->wpa_debug_file_path);
3269 if (params->wpa_debug_syslog)
3270 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003271 if (params->wpa_debug_tracing) {
3272 ret = wpa_debug_open_linux_tracing();
3273 if (ret) {
3274 wpa_printf(MSG_ERROR,
3275 "Failed to enable trace logging");
3276 return NULL;
3277 }
3278 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003279
3280 ret = eap_register_methods();
3281 if (ret) {
3282 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3283 if (ret == -2)
3284 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3285 "the same EAP type.");
3286 return NULL;
3287 }
3288
3289 global = os_zalloc(sizeof(*global));
3290 if (global == NULL)
3291 return NULL;
3292 dl_list_init(&global->p2p_srv_bonjour);
3293 dl_list_init(&global->p2p_srv_upnp);
3294 global->params.daemonize = params->daemonize;
3295 global->params.wait_for_monitor = params->wait_for_monitor;
3296 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3297 if (params->pid_file)
3298 global->params.pid_file = os_strdup(params->pid_file);
3299 if (params->ctrl_interface)
3300 global->params.ctrl_interface =
3301 os_strdup(params->ctrl_interface);
3302 if (params->override_driver)
3303 global->params.override_driver =
3304 os_strdup(params->override_driver);
3305 if (params->override_ctrl_interface)
3306 global->params.override_ctrl_interface =
3307 os_strdup(params->override_ctrl_interface);
3308 wpa_debug_level = global->params.wpa_debug_level =
3309 params->wpa_debug_level;
3310 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3311 params->wpa_debug_show_keys;
3312 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3313 params->wpa_debug_timestamp;
3314
3315 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3316
3317 if (eloop_init()) {
3318 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3319 wpa_supplicant_deinit(global);
3320 return NULL;
3321 }
3322
Jouni Malinen75ecf522011-06-27 15:19:46 -07003323 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003324
3325 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3326 if (global->ctrl_iface == NULL) {
3327 wpa_supplicant_deinit(global);
3328 return NULL;
3329 }
3330
3331 if (wpas_notify_supplicant_initialized(global)) {
3332 wpa_supplicant_deinit(global);
3333 return NULL;
3334 }
3335
3336 for (i = 0; wpa_drivers[i]; i++)
3337 global->drv_count++;
3338 if (global->drv_count == 0) {
3339 wpa_printf(MSG_ERROR, "No drivers enabled");
3340 wpa_supplicant_deinit(global);
3341 return NULL;
3342 }
3343 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3344 if (global->drv_priv == NULL) {
3345 wpa_supplicant_deinit(global);
3346 return NULL;
3347 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003348
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003349#ifdef CONFIG_WIFI_DISPLAY
3350 if (wifi_display_init(global) < 0) {
3351 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3352 wpa_supplicant_deinit(global);
3353 return NULL;
3354 }
3355#endif /* CONFIG_WIFI_DISPLAY */
3356
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003357 return global;
3358}
3359
3360
3361/**
3362 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3363 * @global: Pointer to global data from wpa_supplicant_init()
3364 * Returns: 0 after successful event loop run, -1 on failure
3365 *
3366 * This function starts the main event loop and continues running as long as
3367 * there are any remaining events. In most cases, this function is running as
3368 * long as the %wpa_supplicant process in still in use.
3369 */
3370int wpa_supplicant_run(struct wpa_global *global)
3371{
3372 struct wpa_supplicant *wpa_s;
3373
3374 if (global->params.daemonize &&
3375 wpa_supplicant_daemon(global->params.pid_file))
3376 return -1;
3377
3378 if (global->params.wait_for_monitor) {
3379 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3380 if (wpa_s->ctrl_iface)
3381 wpa_supplicant_ctrl_iface_wait(
3382 wpa_s->ctrl_iface);
3383 }
3384
3385 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3386 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3387
3388 eloop_run();
3389
3390 return 0;
3391}
3392
3393
3394/**
3395 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3396 * @global: Pointer to global data from wpa_supplicant_init()
3397 *
3398 * This function is called to deinitialize %wpa_supplicant and to free all
3399 * allocated resources. Remaining network interfaces will also be removed.
3400 */
3401void wpa_supplicant_deinit(struct wpa_global *global)
3402{
3403 int i;
3404
3405 if (global == NULL)
3406 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003407
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003408#ifdef CONFIG_WIFI_DISPLAY
3409 wifi_display_deinit(global);
3410#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003411#ifdef CONFIG_P2P
3412 wpas_p2p_deinit_global(global);
3413#endif /* CONFIG_P2P */
3414
3415 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003416 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003417
3418 if (global->ctrl_iface)
3419 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3420
3421 wpas_notify_supplicant_deinitialized(global);
3422
3423 eap_peer_unregister_methods();
3424#ifdef CONFIG_AP
3425 eap_server_unregister_methods();
3426#endif /* CONFIG_AP */
3427
3428 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3429 if (!global->drv_priv[i])
3430 continue;
3431 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3432 }
3433 os_free(global->drv_priv);
3434
3435 random_deinit();
3436
3437 eloop_destroy();
3438
3439 if (global->params.pid_file) {
3440 os_daemonize_terminate(global->params.pid_file);
3441 os_free(global->params.pid_file);
3442 }
3443 os_free(global->params.ctrl_interface);
3444 os_free(global->params.override_driver);
3445 os_free(global->params.override_ctrl_interface);
3446
Dmitry Shmidt04949592012-07-19 12:16:46 -07003447 os_free(global->p2p_disallow_freq);
3448
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003449 os_free(global);
3450 wpa_debug_close_syslog();
3451 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003452 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003453}
3454
3455
3456void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3457{
3458 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3459 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3460 char country[3];
3461 country[0] = wpa_s->conf->country[0];
3462 country[1] = wpa_s->conf->country[1];
3463 country[2] = '\0';
3464 if (wpa_drv_set_country(wpa_s, country) < 0) {
3465 wpa_printf(MSG_ERROR, "Failed to set country code "
3466 "'%s'", country);
3467 }
3468 }
3469
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003470 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3471 wpas_init_ext_pw(wpa_s);
3472
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003473#ifdef CONFIG_WPS
3474 wpas_wps_update_config(wpa_s);
3475#endif /* CONFIG_WPS */
3476
3477#ifdef CONFIG_P2P
3478 wpas_p2p_update_config(wpa_s);
3479#endif /* CONFIG_P2P */
3480
3481 wpa_s->conf->changed_parameters = 0;
3482}
3483
3484
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003485static void add_freq(int *freqs, int *num_freqs, int freq)
3486{
3487 int i;
3488
3489 for (i = 0; i < *num_freqs; i++) {
3490 if (freqs[i] == freq)
3491 return;
3492 }
3493
3494 freqs[*num_freqs] = freq;
3495 (*num_freqs)++;
3496}
3497
3498
3499static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3500{
3501 struct wpa_bss *bss, *cbss;
3502 const int max_freqs = 10;
3503 int *freqs;
3504 int num_freqs = 0;
3505
3506 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3507 if (freqs == NULL)
3508 return NULL;
3509
3510 cbss = wpa_s->current_bss;
3511
3512 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3513 if (bss == cbss)
3514 continue;
3515 if (bss->ssid_len == cbss->ssid_len &&
3516 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3517 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3518 add_freq(freqs, &num_freqs, bss->freq);
3519 if (num_freqs == max_freqs)
3520 break;
3521 }
3522 }
3523
3524 if (num_freqs == 0) {
3525 os_free(freqs);
3526 freqs = NULL;
3527 }
3528
3529 return freqs;
3530}
3531
3532
3533void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3534{
3535 int timeout;
3536 int count;
3537 int *freqs = NULL;
3538
3539 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003540 * Remove possible authentication timeout since the connection failed.
3541 */
3542 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3543
3544 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003545 * Add the failed BSSID into the blacklist and speed up next scan
3546 * attempt if there could be other APs that could accept association.
3547 * The current blacklist count indicates how many times we have tried
3548 * connecting to this AP and multiple attempts mean that other APs are
3549 * either not available or has already been tried, so that we can start
3550 * increasing the delay here to avoid constant scanning.
3551 */
3552 count = wpa_blacklist_add(wpa_s, bssid);
3553 if (count == 1 && wpa_s->current_bss) {
3554 /*
3555 * This BSS was not in the blacklist before. If there is
3556 * another BSS available for the same ESS, we should try that
3557 * next. Otherwise, we may as well try this one once more
3558 * before allowing other, likely worse, ESSes to be considered.
3559 */
3560 freqs = get_bss_freqs_in_ess(wpa_s);
3561 if (freqs) {
3562 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3563 "has been seen; try it next");
3564 wpa_blacklist_add(wpa_s, bssid);
3565 /*
3566 * On the next scan, go through only the known channels
3567 * used in this ESS based on previous scans to speed up
3568 * common load balancing use case.
3569 */
3570 os_free(wpa_s->next_scan_freqs);
3571 wpa_s->next_scan_freqs = freqs;
3572 }
3573 }
3574
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003575 /*
3576 * Add previous failure count in case the temporary blacklist was
3577 * cleared due to no other BSSes being available.
3578 */
3579 count += wpa_s->extra_blacklist_count;
3580
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003581 switch (count) {
3582 case 1:
3583 timeout = 100;
3584 break;
3585 case 2:
3586 timeout = 500;
3587 break;
3588 case 3:
3589 timeout = 1000;
3590 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003591 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003592 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003593 break;
3594 default:
3595 timeout = 10000;
3596 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003597 }
3598
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003599 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3600 "ms", count, timeout);
3601
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003602 /*
3603 * TODO: if more than one possible AP is available in scan results,
3604 * could try the other ones before requesting a new scan.
3605 */
3606 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3607 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003608
Dmitry Shmidt37d4d6a2013-03-18 13:09:42 -07003609 wpas_p2p_continue_after_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003610}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003611
3612
3613int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3614{
3615 return wpa_s->conf->ap_scan == 2 ||
3616 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3617}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003618
Dmitry Shmidt04949592012-07-19 12:16:46 -07003619
3620#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3621int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3622 struct wpa_ssid *ssid,
3623 const char *field,
3624 const char *value)
3625{
3626#ifdef IEEE8021X_EAPOL
3627 struct eap_peer_config *eap = &ssid->eap;
3628
3629 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3630 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3631 (const u8 *) value, os_strlen(value));
3632
3633 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3634 case WPA_CTRL_REQ_EAP_IDENTITY:
3635 os_free(eap->identity);
3636 eap->identity = (u8 *) os_strdup(value);
3637 eap->identity_len = os_strlen(value);
3638 eap->pending_req_identity = 0;
3639 if (ssid == wpa_s->current_ssid)
3640 wpa_s->reassociate = 1;
3641 break;
3642 case WPA_CTRL_REQ_EAP_PASSWORD:
3643 os_free(eap->password);
3644 eap->password = (u8 *) os_strdup(value);
3645 eap->password_len = os_strlen(value);
3646 eap->pending_req_password = 0;
3647 if (ssid == wpa_s->current_ssid)
3648 wpa_s->reassociate = 1;
3649 break;
3650 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3651 os_free(eap->new_password);
3652 eap->new_password = (u8 *) os_strdup(value);
3653 eap->new_password_len = os_strlen(value);
3654 eap->pending_req_new_password = 0;
3655 if (ssid == wpa_s->current_ssid)
3656 wpa_s->reassociate = 1;
3657 break;
3658 case WPA_CTRL_REQ_EAP_PIN:
3659 os_free(eap->pin);
3660 eap->pin = os_strdup(value);
3661 eap->pending_req_pin = 0;
3662 if (ssid == wpa_s->current_ssid)
3663 wpa_s->reassociate = 1;
3664 break;
3665 case WPA_CTRL_REQ_EAP_OTP:
3666 os_free(eap->otp);
3667 eap->otp = (u8 *) os_strdup(value);
3668 eap->otp_len = os_strlen(value);
3669 os_free(eap->pending_req_otp);
3670 eap->pending_req_otp = NULL;
3671 eap->pending_req_otp_len = 0;
3672 break;
3673 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3674 os_free(eap->private_key_passwd);
3675 eap->private_key_passwd = (u8 *) os_strdup(value);
3676 eap->pending_req_passphrase = 0;
3677 if (ssid == wpa_s->current_ssid)
3678 wpa_s->reassociate = 1;
3679 break;
3680 default:
3681 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3682 return -1;
3683 }
3684
3685 return 0;
3686#else /* IEEE8021X_EAPOL */
3687 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3688 return -1;
3689#endif /* IEEE8021X_EAPOL */
3690}
3691#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3692
3693
3694int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3695{
3696 int i;
3697 unsigned int drv_enc;
3698
3699 if (ssid == NULL)
3700 return 1;
3701
3702 if (ssid->disabled)
3703 return 1;
3704
3705 if (wpa_s && wpa_s->drv_capa_known)
3706 drv_enc = wpa_s->drv_enc;
3707 else
3708 drv_enc = (unsigned int) -1;
3709
3710 for (i = 0; i < NUM_WEP_KEYS; i++) {
3711 size_t len = ssid->wep_key_len[i];
3712 if (len == 0)
3713 continue;
3714 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3715 continue;
3716 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3717 continue;
3718 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3719 continue;
3720 return 1; /* invalid WEP key */
3721 }
3722
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003723 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3724 !ssid->ext_psk)
3725 return 1;
3726
Dmitry Shmidt04949592012-07-19 12:16:46 -07003727 return 0;
3728}
3729
3730
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003731int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003732{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003733 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003734 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003735 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003736 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003737 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003738}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003739
3740
3741void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3742{
3743 struct wpa_ssid *ssid = wpa_s->current_ssid;
3744 int dur;
3745 struct os_time now;
3746
3747 if (ssid == NULL) {
3748 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3749 "SSID block");
3750 return;
3751 }
3752
3753 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3754 return;
3755
3756 ssid->auth_failures++;
3757 if (ssid->auth_failures > 50)
3758 dur = 300;
3759 else if (ssid->auth_failures > 20)
3760 dur = 120;
3761 else if (ssid->auth_failures > 10)
3762 dur = 60;
3763 else if (ssid->auth_failures > 5)
3764 dur = 30;
3765 else if (ssid->auth_failures > 1)
3766 dur = 20;
3767 else
3768 dur = 10;
3769
3770 os_get_time(&now);
3771 if (now.sec + dur <= ssid->disabled_until.sec)
3772 return;
3773
3774 ssid->disabled_until.sec = now.sec + dur;
3775
3776 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3777 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3778 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3779 ssid->auth_failures, dur);
3780}
3781
3782
3783void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3784 struct wpa_ssid *ssid, int clear_failures)
3785{
3786 if (ssid == NULL)
3787 return;
3788
3789 if (ssid->disabled_until.sec) {
3790 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3791 "id=%d ssid=\"%s\"",
3792 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3793 }
3794 ssid->disabled_until.sec = 0;
3795 ssid->disabled_until.usec = 0;
3796 if (clear_failures)
3797 ssid->auth_failures = 0;
3798}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003799
3800
3801int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3802{
3803 size_t i;
3804
3805 if (wpa_s->disallow_aps_bssid == NULL)
3806 return 0;
3807
3808 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3809 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3810 bssid, ETH_ALEN) == 0)
3811 return 1;
3812 }
3813
3814 return 0;
3815}
3816
3817
3818int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3819 size_t ssid_len)
3820{
3821 size_t i;
3822
3823 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3824 return 0;
3825
3826 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3827 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3828 if (ssid_len == s->ssid_len &&
3829 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3830 return 1;
3831 }
3832
3833 return 0;
3834}
3835
3836
3837/**
3838 * wpas_request_connection - Request a new connection
3839 * @wpa_s: Pointer to the network interface
3840 *
3841 * This function is used to request a new connection to be found. It will mark
3842 * the interface to allow reassociation and request a new scan to find a
3843 * suitable network to connect to.
3844 */
3845void wpas_request_connection(struct wpa_supplicant *wpa_s)
3846{
3847 wpa_s->normal_scans = 0;
3848 wpa_supplicant_reinit_autoscan(wpa_s);
3849 wpa_s->extra_blacklist_count = 0;
3850 wpa_s->disconnected = 0;
3851 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003852
3853 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3854 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003855}