blob: 7d50e4d077c33f0fd964b8697c394970419b1f09 [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
202#ifdef CONFIG_P2P
Jouni Malinendc7b7132012-09-14 12:53:47 -0700203 if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700204 wpa_s->global->p2p != NULL) {
Jouni Malinendc7b7132012-09-14 12:53:47 -0700205 wpa_s->global->p2p_cb_on_scan_complete = 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700206 if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
207 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
208 "continued after timed out authentication");
209 }
210 }
211#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700212}
213
214
215/**
216 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
217 * @wpa_s: Pointer to wpa_supplicant data
218 * @sec: Number of seconds after which to time out authentication
219 * @usec: Number of microseconds after which to time out authentication
220 *
221 * This function is used to schedule a timeout for the current authentication
222 * attempt.
223 */
224void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
225 int sec, int usec)
226{
227 if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
228 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
229 return;
230
231 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
232 "%d usec", sec, usec);
233 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
234 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
235}
236
237
238/**
239 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
240 * @wpa_s: Pointer to wpa_supplicant data
241 *
242 * This function is used to cancel authentication timeout scheduled with
243 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
244 * been completed.
245 */
246void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
247{
248 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
249 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
250 wpa_blacklist_del(wpa_s, wpa_s->bssid);
251}
252
253
254/**
255 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
256 * @wpa_s: Pointer to wpa_supplicant data
257 *
258 * This function is used to configure EAPOL state machine based on the selected
259 * authentication mode.
260 */
261void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
262{
263#ifdef IEEE8021X_EAPOL
264 struct eapol_config eapol_conf;
265 struct wpa_ssid *ssid = wpa_s->current_ssid;
266
267#ifdef CONFIG_IBSS_RSN
268 if (ssid->mode == WPAS_MODE_IBSS &&
269 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
270 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
271 /*
272 * RSN IBSS authentication is per-STA and we can disable the
273 * per-BSSID EAPOL authentication.
274 */
275 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
276 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
277 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
278 return;
279 }
280#endif /* CONFIG_IBSS_RSN */
281
282 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
283 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
284
285 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
286 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
287 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
288 else
289 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
290
291 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
292 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
293 eapol_conf.accept_802_1x_keys = 1;
294 eapol_conf.required_keys = 0;
295 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
296 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
297 }
298 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
299 eapol_conf.required_keys |=
300 EAPOL_REQUIRE_KEY_BROADCAST;
301 }
302
303 if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
304 eapol_conf.required_keys = 0;
305 }
306 if (wpa_s->conf)
307 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
308 eapol_conf.workaround = ssid->eap_workaround;
309 eapol_conf.eap_disabled =
310 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
311 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
312 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
313 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
314#endif /* IEEE8021X_EAPOL */
315}
316
317
318/**
319 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
320 * @wpa_s: Pointer to wpa_supplicant data
321 * @ssid: Configuration data for the network
322 *
323 * This function is used to configure WPA state machine and related parameters
324 * to a mode where WPA is not enabled. This is called as part of the
325 * authentication configuration when the selected network does not use WPA.
326 */
327void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
328 struct wpa_ssid *ssid)
329{
330 int i;
331
332 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
333 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
334 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
335 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
336 else
337 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
338 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
339 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
340 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
341 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
342 wpa_s->group_cipher = WPA_CIPHER_NONE;
343 wpa_s->mgmt_group_cipher = 0;
344
345 for (i = 0; i < NUM_WEP_KEYS; i++) {
346 if (ssid->wep_key_len[i] > 5) {
347 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
348 wpa_s->group_cipher = WPA_CIPHER_WEP104;
349 break;
350 } else if (ssid->wep_key_len[i] > 0) {
351 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
352 wpa_s->group_cipher = WPA_CIPHER_WEP40;
353 break;
354 }
355 }
356
357 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
358 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
359 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
360 wpa_s->pairwise_cipher);
361 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
362#ifdef CONFIG_IEEE80211W
363 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
364 wpa_s->mgmt_group_cipher);
365#endif /* CONFIG_IEEE80211W */
366
367 pmksa_cache_clear_current(wpa_s->wpa);
368}
369
370
Dmitry Shmidt04949592012-07-19 12:16:46 -0700371void free_hw_features(struct wpa_supplicant *wpa_s)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800372{
373 int i;
374 if (wpa_s->hw.modes == NULL)
375 return;
376
377 for (i = 0; i < wpa_s->hw.num_modes; i++) {
378 os_free(wpa_s->hw.modes[i].channels);
379 os_free(wpa_s->hw.modes[i].rates);
380 }
381
382 os_free(wpa_s->hw.modes);
383 wpa_s->hw.modes = NULL;
384}
385
386
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700387static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
388{
389 bgscan_deinit(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700390 autoscan_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700391 scard_deinit(wpa_s->scard);
392 wpa_s->scard = NULL;
393 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
394 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
395 l2_packet_deinit(wpa_s->l2);
396 wpa_s->l2 = NULL;
397 if (wpa_s->l2_br) {
398 l2_packet_deinit(wpa_s->l2_br);
399 wpa_s->l2_br = NULL;
400 }
401
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700402 if (wpa_s->conf != NULL) {
403 struct wpa_ssid *ssid;
404 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
405 wpas_notify_network_removed(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700406 }
407
408 os_free(wpa_s->confname);
409 wpa_s->confname = NULL;
410
411 wpa_sm_set_eapol(wpa_s->wpa, NULL);
412 eapol_sm_deinit(wpa_s->eapol);
413 wpa_s->eapol = NULL;
414
415 rsn_preauth_deinit(wpa_s->wpa);
416
417#ifdef CONFIG_TDLS
418 wpa_tdls_deinit(wpa_s->wpa);
419#endif /* CONFIG_TDLS */
420
421 pmksa_candidate_free(wpa_s->wpa);
422 wpa_sm_deinit(wpa_s->wpa);
423 wpa_s->wpa = NULL;
424 wpa_blacklist_clear(wpa_s);
425
426 wpa_bss_deinit(wpa_s);
427
428 wpa_supplicant_cancel_scan(wpa_s);
429 wpa_supplicant_cancel_auth_timeout(wpa_s);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800430 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
431#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
432 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
433 wpa_s, NULL);
434#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700435
436 wpas_wps_deinit(wpa_s);
437
438 wpabuf_free(wpa_s->pending_eapol_rx);
439 wpa_s->pending_eapol_rx = NULL;
440
441#ifdef CONFIG_IBSS_RSN
442 ibss_rsn_deinit(wpa_s->ibss_rsn);
443 wpa_s->ibss_rsn = NULL;
444#endif /* CONFIG_IBSS_RSN */
445
446 sme_deinit(wpa_s);
447
448#ifdef CONFIG_AP
449 wpa_supplicant_ap_deinit(wpa_s);
450#endif /* CONFIG_AP */
451
452#ifdef CONFIG_P2P
453 wpas_p2p_deinit(wpa_s);
454#endif /* CONFIG_P2P */
455
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800456#ifdef CONFIG_OFFCHANNEL
457 offchannel_deinit(wpa_s);
458#endif /* CONFIG_OFFCHANNEL */
459
460 wpa_supplicant_cancel_sched_scan(wpa_s);
461
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 os_free(wpa_s->next_scan_freqs);
463 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800464
465 gas_query_deinit(wpa_s->gas);
466 wpa_s->gas = NULL;
467
468 free_hw_features(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700469
470 os_free(wpa_s->bssid_filter);
471 wpa_s->bssid_filter = NULL;
472
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800473 os_free(wpa_s->disallow_aps_bssid);
474 wpa_s->disallow_aps_bssid = NULL;
475 os_free(wpa_s->disallow_aps_ssid);
476 wpa_s->disallow_aps_ssid = NULL;
477
Dmitry Shmidt04949592012-07-19 12:16:46 -0700478 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700479
480 ext_password_deinit(wpa_s->ext_pw);
481 wpa_s->ext_pw = NULL;
482
483 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidt9bce59c2012-09-11 15:06:38 -0700484
485 os_free(wpa_s->last_scan_res);
486 wpa_s->last_scan_res = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700487}
488
489
490/**
491 * wpa_clear_keys - Clear keys configured for the driver
492 * @wpa_s: Pointer to wpa_supplicant data
493 * @addr: Previously used BSSID or %NULL if not available
494 *
495 * This function clears the encryption keys that has been previously configured
496 * for the driver.
497 */
498void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
499{
500 if (wpa_s->keys_cleared) {
501 /* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
502 * timing issues with keys being cleared just before new keys
503 * are set or just after association or something similar. This
504 * shows up in group key handshake failing often because of the
505 * client not receiving the first encrypted packets correctly.
506 * Skipping some of the extra key clearing steps seems to help
507 * in completing group key handshake more reliably. */
508 wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
509 "skip key clearing");
510 return;
511 }
512
513 /* MLME-DELETEKEYS.request */
514 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
515 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
516 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
517 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
518#ifdef CONFIG_IEEE80211W
519 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
520 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
521#endif /* CONFIG_IEEE80211W */
522 if (addr) {
523 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
524 0);
525 /* MLME-SETPROTECTION.request(None) */
526 wpa_drv_mlme_setprotection(
527 wpa_s, addr,
528 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
529 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
530 }
531 wpa_s->keys_cleared = 1;
532}
533
534
535/**
536 * wpa_supplicant_state_txt - Get the connection state name as a text string
537 * @state: State (wpa_state; WPA_*)
538 * Returns: The state name as a printable text string
539 */
540const char * wpa_supplicant_state_txt(enum wpa_states state)
541{
542 switch (state) {
543 case WPA_DISCONNECTED:
544 return "DISCONNECTED";
545 case WPA_INACTIVE:
546 return "INACTIVE";
547 case WPA_INTERFACE_DISABLED:
548 return "INTERFACE_DISABLED";
549 case WPA_SCANNING:
550 return "SCANNING";
551 case WPA_AUTHENTICATING:
552 return "AUTHENTICATING";
553 case WPA_ASSOCIATING:
554 return "ASSOCIATING";
555 case WPA_ASSOCIATED:
556 return "ASSOCIATED";
557 case WPA_4WAY_HANDSHAKE:
558 return "4WAY_HANDSHAKE";
559 case WPA_GROUP_HANDSHAKE:
560 return "GROUP_HANDSHAKE";
561 case WPA_COMPLETED:
562 return "COMPLETED";
563 default:
564 return "UNKNOWN";
565 }
566}
567
568
569#ifdef CONFIG_BGSCAN
570
571static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
572{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800573 if (wpas_driver_bss_selection(wpa_s))
574 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700575 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
576 return;
577
578 bgscan_deinit(wpa_s);
579 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
580 if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
581 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
582 "bgscan");
583 /*
584 * Live without bgscan; it is only used as a roaming
585 * optimization, so the initial connection is not
586 * affected.
587 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700588 } else {
589 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700590 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700591 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
592 0);
593 if (scan_res) {
594 bgscan_notify_scan(wpa_s, scan_res);
595 wpa_scan_results_free(scan_res);
596 }
597 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700598 } else
599 wpa_s->bgscan_ssid = NULL;
600}
601
602
603static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
604{
605 if (wpa_s->bgscan_ssid != NULL) {
606 bgscan_deinit(wpa_s);
607 wpa_s->bgscan_ssid = NULL;
608 }
609}
610
611#endif /* CONFIG_BGSCAN */
612
613
Dmitry Shmidt04949592012-07-19 12:16:46 -0700614static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
615{
616 if (autoscan_init(wpa_s, 0))
617 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
618}
619
620
621static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
622{
623 autoscan_deinit(wpa_s);
624}
625
626
627void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
628{
629 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
630 wpa_s->wpa_state == WPA_SCANNING) {
631 autoscan_deinit(wpa_s);
632 wpa_supplicant_start_autoscan(wpa_s);
633 }
634}
635
636
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700637/**
638 * wpa_supplicant_set_state - Set current connection state
639 * @wpa_s: Pointer to wpa_supplicant data
640 * @state: The new connection state
641 *
642 * This function is called whenever the connection state changes, e.g.,
643 * association is completed for WPA/WPA2 4-Way Handshake is started.
644 */
645void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
646 enum wpa_states state)
647{
648 enum wpa_states old_state = wpa_s->wpa_state;
649
650 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
651 wpa_supplicant_state_txt(wpa_s->wpa_state),
652 wpa_supplicant_state_txt(state));
653
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700654#ifdef ANDROID_P2P
Irfan Sheriff7db4ef72012-06-18 09:39:07 -0700655 if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
656 wpa_s->current_ssid->assoc_retry = 0;
657 }
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700658#endif /* ANDROID_P2P */
659
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700660 if (state != WPA_SCANNING)
661 wpa_supplicant_notify_scanning(wpa_s, 0);
662
663 if (state == WPA_COMPLETED && wpa_s->new_connection) {
664#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
665 struct wpa_ssid *ssid = wpa_s->current_ssid;
666 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800667 MACSTR " completed (auth) [id=%d id_str=%s]",
668 MAC2STR(wpa_s->bssid),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700669 ssid ? ssid->id : -1,
670 ssid && ssid->id_str ? ssid->id_str : "");
671#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700672 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800673 wpa_s->extra_blacklist_count = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700674 wpa_s->new_connection = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700675 wpa_drv_set_operstate(wpa_s, 1);
676#ifndef IEEE8021X_EAPOL
677 wpa_drv_set_supp_port(wpa_s, 1);
678#endif /* IEEE8021X_EAPOL */
679 wpa_s->after_wps = 0;
680#ifdef CONFIG_P2P
681 wpas_p2p_completed(wpa_s);
682#endif /* CONFIG_P2P */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700683
684 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700685 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
686 state == WPA_ASSOCIATED) {
687 wpa_s->new_connection = 1;
688 wpa_drv_set_operstate(wpa_s, 0);
689#ifndef IEEE8021X_EAPOL
690 wpa_drv_set_supp_port(wpa_s, 0);
691#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700692 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700693 }
694 wpa_s->wpa_state = state;
695
696#ifdef CONFIG_BGSCAN
697 if (state == WPA_COMPLETED)
698 wpa_supplicant_start_bgscan(wpa_s);
699 else
700 wpa_supplicant_stop_bgscan(wpa_s);
701#endif /* CONFIG_BGSCAN */
702
Dmitry Shmidt04949592012-07-19 12:16:46 -0700703 if (state == WPA_AUTHENTICATING)
704 wpa_supplicant_stop_autoscan(wpa_s);
705
706 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
707 wpa_supplicant_start_autoscan(wpa_s);
708
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700709 if (wpa_s->wpa_state != old_state) {
710 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
711
712 if (wpa_s->wpa_state == WPA_COMPLETED ||
713 old_state == WPA_COMPLETED)
714 wpas_notify_auth_changed(wpa_s);
715 }
716}
717
718
719void wpa_supplicant_terminate_proc(struct wpa_global *global)
720{
721 int pending = 0;
722#ifdef CONFIG_WPS
723 struct wpa_supplicant *wpa_s = global->ifaces;
724 while (wpa_s) {
725 if (wpas_wps_terminate_pending(wpa_s) == 1)
726 pending = 1;
727 wpa_s = wpa_s->next;
728 }
729#endif /* CONFIG_WPS */
730 if (pending)
731 return;
732 eloop_terminate();
733}
734
735
736static void wpa_supplicant_terminate(int sig, void *signal_ctx)
737{
738 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700739 wpa_supplicant_terminate_proc(global);
740}
741
742
743void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
744{
745 enum wpa_states old_state = wpa_s->wpa_state;
746
747 wpa_s->pairwise_cipher = 0;
748 wpa_s->group_cipher = 0;
749 wpa_s->mgmt_group_cipher = 0;
750 wpa_s->key_mgmt = 0;
751 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700752 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700753
754 if (wpa_s->wpa_state != old_state)
755 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
756}
757
758
759/**
760 * wpa_supplicant_reload_configuration - Reload configuration data
761 * @wpa_s: Pointer to wpa_supplicant data
762 * Returns: 0 on success or -1 if configuration parsing failed
763 *
764 * This function can be used to request that the configuration data is reloaded
765 * (e.g., after configuration file change). This function is reloading
766 * configuration only for one interface, so this may need to be called multiple
767 * times if %wpa_supplicant is controlling multiple interfaces and all
768 * interfaces need reconfiguration.
769 */
770int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
771{
772 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700773 int reconf_ctrl;
774 int old_ap_scan;
775
776 if (wpa_s->confname == NULL)
777 return -1;
778 conf = wpa_config_read(wpa_s->confname);
779 if (conf == NULL) {
780 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
781 "file '%s' - exiting", wpa_s->confname);
782 return -1;
783 }
784 conf->changed_parameters = (unsigned int) -1;
785
786 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
787 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
788 os_strcmp(conf->ctrl_interface,
789 wpa_s->conf->ctrl_interface) != 0);
790
791 if (reconf_ctrl && wpa_s->ctrl_iface) {
792 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
793 wpa_s->ctrl_iface = NULL;
794 }
795
796 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800797 if (wpa_s->current_ssid) {
798 wpa_supplicant_deauthenticate(wpa_s,
799 WLAN_REASON_DEAUTH_LEAVING);
800 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700801
802 /*
803 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
804 * pkcs11_engine_path, pkcs11_module_path.
805 */
806 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
807 /*
808 * Clear forced success to clear EAP state for next
809 * authentication.
810 */
811 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
812 }
813 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
814 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800815 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700816 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
817 rsn_preauth_deinit(wpa_s->wpa);
818
819 old_ap_scan = wpa_s->conf->ap_scan;
820 wpa_config_free(wpa_s->conf);
821 wpa_s->conf = conf;
822 if (old_ap_scan != wpa_s->conf->ap_scan)
823 wpas_notify_ap_scan_changed(wpa_s);
824
825 if (reconf_ctrl)
826 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
827
828 wpa_supplicant_update_config(wpa_s);
829
830 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700831 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700832 wpa_s->reassociate = 1;
833 wpa_supplicant_req_scan(wpa_s, 0, 0);
834 }
835 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
836 return 0;
837}
838
839
840static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
841{
842 struct wpa_global *global = signal_ctx;
843 struct wpa_supplicant *wpa_s;
844 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
845 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
846 sig);
847 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
848 wpa_supplicant_terminate_proc(global);
849 }
850 }
851}
852
853
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700854enum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
855{
856 switch (key_mgmt) {
857 case WPA_KEY_MGMT_NONE:
858 return KEY_MGMT_NONE;
859 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
860 return KEY_MGMT_802_1X_NO_WPA;
861 case WPA_KEY_MGMT_IEEE8021X:
862 return KEY_MGMT_802_1X;
863 case WPA_KEY_MGMT_WPA_NONE:
864 return KEY_MGMT_WPA_NONE;
865 case WPA_KEY_MGMT_FT_IEEE8021X:
866 return KEY_MGMT_FT_802_1X;
867 case WPA_KEY_MGMT_FT_PSK:
868 return KEY_MGMT_FT_PSK;
869 case WPA_KEY_MGMT_IEEE8021X_SHA256:
870 return KEY_MGMT_802_1X_SHA256;
871 case WPA_KEY_MGMT_PSK_SHA256:
872 return KEY_MGMT_PSK_SHA256;
873 case WPA_KEY_MGMT_WPS:
874 return KEY_MGMT_WPS;
875 case WPA_KEY_MGMT_PSK:
876 default:
877 return KEY_MGMT_PSK;
878 }
879}
880
881
882static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
883 struct wpa_ssid *ssid,
884 struct wpa_ie_data *ie)
885{
886 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
887 if (ret) {
888 if (ret == -2) {
889 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
890 "from association info");
891 }
892 return -1;
893 }
894
895 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
896 "cipher suites");
897 if (!(ie->group_cipher & ssid->group_cipher)) {
898 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
899 "cipher 0x%x (mask 0x%x) - reject",
900 ie->group_cipher, ssid->group_cipher);
901 return -1;
902 }
903 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
904 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
905 "cipher 0x%x (mask 0x%x) - reject",
906 ie->pairwise_cipher, ssid->pairwise_cipher);
907 return -1;
908 }
909 if (!(ie->key_mgmt & ssid->key_mgmt)) {
910 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
911 "management 0x%x (mask 0x%x) - reject",
912 ie->key_mgmt, ssid->key_mgmt);
913 return -1;
914 }
915
916#ifdef CONFIG_IEEE80211W
917 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800918 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
919 wpa_s->conf->pmf : ssid->ieee80211w) ==
920 MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700921 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
922 "that does not support management frame protection - "
923 "reject");
924 return -1;
925 }
926#endif /* CONFIG_IEEE80211W */
927
928 return 0;
929}
930
931
932/**
933 * wpa_supplicant_set_suites - Set authentication and encryption parameters
934 * @wpa_s: Pointer to wpa_supplicant data
935 * @bss: Scan results for the selected BSS, or %NULL if not available
936 * @ssid: Configuration data for the selected network
937 * @wpa_ie: Buffer for the WPA/RSN IE
938 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
939 * used buffer length in case the functions returns success.
940 * Returns: 0 on success or -1 on failure
941 *
942 * This function is used to configure authentication and encryption parameters
943 * based on the network configuration and scan result for the selected BSS (if
944 * available).
945 */
946int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
947 struct wpa_bss *bss, struct wpa_ssid *ssid,
948 u8 *wpa_ie, size_t *wpa_ie_len)
949{
950 struct wpa_ie_data ie;
951 int sel, proto;
952 const u8 *bss_wpa, *bss_rsn;
953
954 if (bss) {
955 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
956 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
957 } else
958 bss_wpa = bss_rsn = NULL;
959
960 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
961 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
962 (ie.group_cipher & ssid->group_cipher) &&
963 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
964 (ie.key_mgmt & ssid->key_mgmt)) {
965 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
966 proto = WPA_PROTO_RSN;
967 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
968 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
969 (ie.group_cipher & ssid->group_cipher) &&
970 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
971 (ie.key_mgmt & ssid->key_mgmt)) {
972 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
973 proto = WPA_PROTO_WPA;
974 } else if (bss) {
975 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
976 return -1;
977 } else {
978 if (ssid->proto & WPA_PROTO_RSN)
979 proto = WPA_PROTO_RSN;
980 else
981 proto = WPA_PROTO_WPA;
982 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
983 os_memset(&ie, 0, sizeof(ie));
984 ie.group_cipher = ssid->group_cipher;
985 ie.pairwise_cipher = ssid->pairwise_cipher;
986 ie.key_mgmt = ssid->key_mgmt;
987#ifdef CONFIG_IEEE80211W
988 ie.mgmt_group_cipher =
989 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
990 WPA_CIPHER_AES_128_CMAC : 0;
991#endif /* CONFIG_IEEE80211W */
992 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
993 "based on configuration");
994 } else
995 proto = ie.proto;
996 }
997
998 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
999 "pairwise %d key_mgmt %d proto %d",
1000 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
1001#ifdef CONFIG_IEEE80211W
1002 if (ssid->ieee80211w) {
1003 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1004 ie.mgmt_group_cipher);
1005 }
1006#endif /* CONFIG_IEEE80211W */
1007
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001008 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001009 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1010 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1011 !!(ssid->proto & WPA_PROTO_RSN));
1012
1013 if (bss || !wpa_s->ap_ies_from_associnfo) {
1014 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1015 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1016 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1017 bss_rsn ? 2 + bss_rsn[1] : 0))
1018 return -1;
1019 }
1020
1021 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001022 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1023 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001024 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1025 "cipher");
1026 return -1;
1027 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001028 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1029 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001030
1031 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001032 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1033 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001034 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1035 "cipher");
1036 return -1;
1037 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001038 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1039 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001040
1041 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001042#ifdef CONFIG_SAE
1043 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1044 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1045#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001046 if (0) {
1047#ifdef CONFIG_IEEE80211R
1048 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1049 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1050 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1051 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1052 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1053 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1054#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001055#ifdef CONFIG_SAE
1056 } else if (sel & WPA_KEY_MGMT_SAE) {
1057 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1058 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1059 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1060 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1061 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1062#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001063#ifdef CONFIG_IEEE80211W
1064 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1065 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1066 wpa_dbg(wpa_s, MSG_DEBUG,
1067 "WPA: using KEY_MGMT 802.1X with SHA256");
1068 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1069 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1070 wpa_dbg(wpa_s, MSG_DEBUG,
1071 "WPA: using KEY_MGMT PSK with SHA256");
1072#endif /* CONFIG_IEEE80211W */
1073 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1074 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1075 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1076 } else if (sel & WPA_KEY_MGMT_PSK) {
1077 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1078 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1079 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1080 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1081 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1082 } else {
1083 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1084 "authenticated key management type");
1085 return -1;
1086 }
1087
1088 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1089 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1090 wpa_s->pairwise_cipher);
1091 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1092
1093#ifdef CONFIG_IEEE80211W
1094 sel = ie.mgmt_group_cipher;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001095 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1096 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001097 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1098 sel = 0;
1099 if (sel & WPA_CIPHER_AES_128_CMAC) {
1100 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1101 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1102 "AES-128-CMAC");
1103 } else {
1104 wpa_s->mgmt_group_cipher = 0;
1105 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1106 }
1107 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1108 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001109 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1110 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1111 wpa_s->conf->pmf : ssid->ieee80211w));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001112#endif /* CONFIG_IEEE80211W */
1113
1114 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1115 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1116 return -1;
1117 }
1118
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001119 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001120 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001121#ifndef CONFIG_NO_PBKDF2
1122 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1123 ssid->passphrase) {
1124 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001125 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1126 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001127 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1128 psk, PMK_LEN);
1129 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1130 }
1131#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001132#ifdef CONFIG_EXT_PASSWORD
1133 if (ssid->ext_psk) {
1134 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1135 ssid->ext_psk);
1136 char pw_str[64 + 1];
1137 u8 psk[PMK_LEN];
1138
1139 if (pw == NULL) {
1140 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1141 "found from external storage");
1142 return -1;
1143 }
1144
1145 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1146 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1147 "PSK length %d in external storage",
1148 (int) wpabuf_len(pw));
1149 ext_password_free(pw);
1150 return -1;
1151 }
1152
1153 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1154 pw_str[wpabuf_len(pw)] = '\0';
1155
1156#ifndef CONFIG_NO_PBKDF2
1157 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1158 {
1159 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1160 4096, psk, PMK_LEN);
1161 os_memset(pw_str, 0, sizeof(pw_str));
1162 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1163 "external passphrase)",
1164 psk, PMK_LEN);
1165 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1166 } else
1167#endif /* CONFIG_NO_PBKDF2 */
1168 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1169 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1170 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1171 "Invalid PSK hex string");
1172 os_memset(pw_str, 0, sizeof(pw_str));
1173 ext_password_free(pw);
1174 return -1;
1175 }
1176 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1177 } else {
1178 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1179 "PSK available");
1180 os_memset(pw_str, 0, sizeof(pw_str));
1181 ext_password_free(pw);
1182 return -1;
1183 }
1184
1185 os_memset(pw_str, 0, sizeof(pw_str));
1186 ext_password_free(pw);
1187 }
1188#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001189 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001190 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1191
1192 return 0;
1193}
1194
1195
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001196int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1197{
1198 u32 ext_capab = 0;
1199 u8 *pos = buf;
1200
1201#ifdef CONFIG_INTERWORKING
1202 if (wpa_s->conf->interworking)
1203 ext_capab |= BIT(31); /* Interworking */
1204#endif /* CONFIG_INTERWORKING */
1205
1206#ifdef CONFIG_WNM
1207 ext_capab |= BIT(17); /* WNM-Sleep Mode */
1208 ext_capab |= BIT(19); /* BSS Transition */
1209#endif /* CONFIG_WNM */
1210
1211 if (!ext_capab)
1212 return 0;
1213
1214 *pos++ = WLAN_EID_EXT_CAPAB;
1215 *pos++ = 4;
1216 WPA_PUT_LE32(pos, ext_capab);
1217 pos += 4;
1218
1219 return pos - buf;
1220}
1221
1222
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001223/**
1224 * wpa_supplicant_associate - Request association
1225 * @wpa_s: Pointer to wpa_supplicant data
1226 * @bss: Scan results for the selected BSS, or %NULL if not available
1227 * @ssid: Configuration data for the selected network
1228 *
1229 * This function is used to request %wpa_supplicant to associate with a BSS.
1230 */
1231void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1232 struct wpa_bss *bss, struct wpa_ssid *ssid)
1233{
1234 u8 wpa_ie[200];
1235 size_t wpa_ie_len;
1236 int use_crypt, ret, i, bssid_changed;
1237 int algs = WPA_AUTH_ALG_OPEN;
1238 enum wpa_cipher cipher_pairwise, cipher_group;
1239 struct wpa_driver_associate_params params;
1240 int wep_keys_set = 0;
1241 struct wpa_driver_capa capa;
1242 int assoc_failed = 0;
1243 struct wpa_ssid *old_ssid;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001244 u8 ext_capab[10];
1245 int ext_capab_len;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001246#ifdef CONFIG_HT_OVERRIDES
1247 struct ieee80211_ht_capabilities htcaps;
1248 struct ieee80211_ht_capabilities htcaps_mask;
1249#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001250
1251#ifdef CONFIG_IBSS_RSN
1252 ibss_rsn_deinit(wpa_s->ibss_rsn);
1253 wpa_s->ibss_rsn = NULL;
1254#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001255#ifdef ANDROID_P2P
1256 int freq = 0;
1257#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001258
1259 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1260 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1261#ifdef CONFIG_AP
1262 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1263 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1264 "mode");
1265 return;
1266 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001267 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1268 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1269 return;
1270 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001271 wpa_s->current_bss = bss;
1272#else /* CONFIG_AP */
1273 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1274 "the build");
1275#endif /* CONFIG_AP */
1276 return;
1277 }
1278
1279#ifdef CONFIG_TDLS
1280 if (bss)
1281 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1282 bss->ie_len);
1283#endif /* CONFIG_TDLS */
1284
1285 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1286 ssid->mode == IEEE80211_MODE_INFRA) {
1287 sme_authenticate(wpa_s, bss, ssid);
1288 return;
1289 }
1290
1291 os_memset(&params, 0, sizeof(params));
1292 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001293 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001294#ifdef CONFIG_IEEE80211R
1295 const u8 *ie, *md = NULL;
1296#endif /* CONFIG_IEEE80211R */
1297 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1298 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1299 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1300 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1301 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1302 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1303 if (bssid_changed)
1304 wpas_notify_bssid_changed(wpa_s);
1305#ifdef CONFIG_IEEE80211R
1306 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1307 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1308 md = ie + 2;
1309 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1310 if (md) {
1311 /* Prepare for the next transition */
1312 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1313 }
1314#endif /* CONFIG_IEEE80211R */
1315#ifdef CONFIG_WPS
1316 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1317 wpa_s->conf->ap_scan == 2 &&
1318 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1319 /* Use ap_scan==1 style network selection to find the network
1320 */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001321 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001322 wpa_s->reassociate = 1;
1323 wpa_supplicant_req_scan(wpa_s, 0, 0);
1324 return;
1325#endif /* CONFIG_WPS */
1326 } else {
1327 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1328 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1329 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1330 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001331 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001332 wpa_supplicant_cancel_scan(wpa_s);
1333
1334 /* Starting new association, so clear the possibly used WPA IE from the
1335 * previous association. */
1336 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1337
1338#ifdef IEEE8021X_EAPOL
1339 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1340 if (ssid->leap) {
1341 if (ssid->non_leap == 0)
1342 algs = WPA_AUTH_ALG_LEAP;
1343 else
1344 algs |= WPA_AUTH_ALG_LEAP;
1345 }
1346 }
1347#endif /* IEEE8021X_EAPOL */
1348 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1349 if (ssid->auth_alg) {
1350 algs = ssid->auth_alg;
1351 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1352 "0x%x", algs);
1353 }
1354
1355 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1356 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001357 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001358 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001359 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1360 wpa_s->conf->okc :
1361 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001362 (ssid->proto & WPA_PROTO_RSN);
1363 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
1364 wpa_s->current_ssid,
1365 try_opportunistic) == 0)
1366 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1367 wpa_ie_len = sizeof(wpa_ie);
1368 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1369 wpa_ie, &wpa_ie_len)) {
1370 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1371 "key management and encryption suites");
1372 return;
1373 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001374 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1375 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1376 /*
1377 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1378 * use non-WPA since the scan results did not indicate that the
1379 * AP is using WPA or WPA2.
1380 */
1381 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1382 wpa_ie_len = 0;
1383 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001384 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001385 wpa_ie_len = sizeof(wpa_ie);
1386 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1387 wpa_ie, &wpa_ie_len)) {
1388 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1389 "key management and encryption suites (no "
1390 "scan results)");
1391 return;
1392 }
1393#ifdef CONFIG_WPS
1394 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1395 struct wpabuf *wps_ie;
1396 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1397 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1398 wpa_ie_len = wpabuf_len(wps_ie);
1399 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1400 } else
1401 wpa_ie_len = 0;
1402 wpabuf_free(wps_ie);
1403 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1404 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1405 params.wps = WPS_MODE_PRIVACY;
1406 else
1407 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001408 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001409#endif /* CONFIG_WPS */
1410 } else {
1411 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1412 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001413 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001414 }
1415
1416#ifdef CONFIG_P2P
1417 if (wpa_s->global->p2p) {
1418 u8 *pos;
1419 size_t len;
1420 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001421 pos = wpa_ie + wpa_ie_len;
1422 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001423 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1424 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001425 if (res >= 0)
1426 wpa_ie_len += res;
1427 }
1428
1429 wpa_s->cross_connect_disallowed = 0;
1430 if (bss) {
1431 struct wpabuf *p2p;
1432 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1433 if (p2p) {
1434 wpa_s->cross_connect_disallowed =
1435 p2p_get_cross_connect_disallowed(p2p);
1436 wpabuf_free(p2p);
1437 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1438 "connection",
1439 wpa_s->cross_connect_disallowed ?
1440 "disallows" : "allows");
1441 }
1442 }
1443#endif /* CONFIG_P2P */
1444
Dmitry Shmidt04949592012-07-19 12:16:46 -07001445#ifdef CONFIG_HS20
1446 if (wpa_s->conf->hs20) {
1447 struct wpabuf *hs20;
1448 hs20 = wpabuf_alloc(20);
1449 if (hs20) {
1450 wpas_hs20_add_indication(hs20);
1451 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1452 wpabuf_len(hs20));
1453 wpa_ie_len += wpabuf_len(hs20);
1454 wpabuf_free(hs20);
1455 }
1456 }
1457#endif /* CONFIG_HS20 */
1458
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001459 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1460 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001461 u8 *pos = wpa_ie;
1462 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1463 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001464 os_memmove(pos + ext_capab_len, pos,
1465 wpa_ie_len - (pos - wpa_ie));
1466 wpa_ie_len += ext_capab_len;
1467 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001468 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001469
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001470 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1471 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001472 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1473 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001474 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1475 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1476 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1477 use_crypt = 0;
1478 if (wpa_set_wep_keys(wpa_s, ssid)) {
1479 use_crypt = 1;
1480 wep_keys_set = 1;
1481 }
1482 }
1483 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1484 use_crypt = 0;
1485
1486#ifdef IEEE8021X_EAPOL
1487 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1488 if ((ssid->eapol_flags &
1489 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1490 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1491 !wep_keys_set) {
1492 use_crypt = 0;
1493 } else {
1494 /* Assume that dynamic WEP-104 keys will be used and
1495 * set cipher suites in order for drivers to expect
1496 * encryption. */
1497 cipher_pairwise = cipher_group = CIPHER_WEP104;
1498 }
1499 }
1500#endif /* IEEE8021X_EAPOL */
1501
1502 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1503 /* Set the key before (and later after) association */
1504 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1505 }
1506
1507 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1508 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001509 params.ssid = bss->ssid;
1510 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001511 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1512 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1513 MACSTR " freq=%u MHz based on scan results "
1514 "(bssid_set=%d)",
1515 MAC2STR(bss->bssid), bss->freq,
1516 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001517 params.bssid = bss->bssid;
1518 params.freq = bss->freq;
1519 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001520 } else {
1521 params.ssid = ssid->ssid;
1522 params.ssid_len = ssid->ssid_len;
1523 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001524
1525 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1526 wpa_s->conf->ap_scan == 2) {
1527 params.bssid = ssid->bssid;
1528 params.fixed_bssid = 1;
1529 }
1530
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001531 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1532 params.freq == 0)
1533 params.freq = ssid->frequency; /* Initial channel for IBSS */
1534 params.wpa_ie = wpa_ie;
1535 params.wpa_ie_len = wpa_ie_len;
1536 params.pairwise_suite = cipher_pairwise;
1537 params.group_suite = cipher_group;
1538 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001539 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001540 params.auth_alg = algs;
1541 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001542 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001543 for (i = 0; i < NUM_WEP_KEYS; i++) {
1544 if (ssid->wep_key_len[i])
1545 params.wep_key[i] = ssid->wep_key[i];
1546 params.wep_key_len[i] = ssid->wep_key_len[i];
1547 }
1548 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1549
1550 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1551 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1552 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1553 params.passphrase = ssid->passphrase;
1554 if (ssid->psk_set)
1555 params.psk = ssid->psk;
1556 }
1557
1558 params.drop_unencrypted = use_crypt;
1559
1560#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001561 params.mgmt_frame_protection =
1562 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1563 wpa_s->conf->pmf : ssid->ieee80211w;
1564 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001565 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1566 struct wpa_ie_data ie;
1567 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1568 ie.capabilities &
1569 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1570 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1571 "MFP: require MFP");
1572 params.mgmt_frame_protection =
1573 MGMT_FRAME_PROTECTION_REQUIRED;
1574 }
1575 }
1576#endif /* CONFIG_IEEE80211W */
1577
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001578 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001579
1580 if (wpa_s->parent->set_sta_uapsd)
1581 params.uapsd = wpa_s->parent->sta_uapsd;
1582 else
1583 params.uapsd = -1;
1584
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001585#ifdef CONFIG_HT_OVERRIDES
1586 os_memset(&htcaps, 0, sizeof(htcaps));
1587 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1588 params.htcaps = (u8 *) &htcaps;
1589 params.htcaps_mask = (u8 *) &htcaps_mask;
1590 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1591#endif /* CONFIG_HT_OVERRIDES */
1592
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001593#ifdef ANDROID_P2P
1594 /* If multichannel concurrency is not supported, check for any frequency
1595 * conflict and take appropriate action.
1596 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001597 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1598 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1599 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001600 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001601 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001602 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001603 }
1604#endif
1605 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001606 if (ret < 0) {
1607 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1608 "failed");
1609 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1610 /*
1611 * The driver is known to mean what is saying, so we
1612 * can stop right here; the association will not
1613 * succeed.
1614 */
1615 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001616 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001617 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1618 return;
1619 }
1620 /* try to continue anyway; new association will be tried again
1621 * after timeout */
1622 assoc_failed = 1;
1623 }
1624
1625 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1626 /* Set the key after the association just in case association
1627 * cleared the previously configured key. */
1628 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1629 /* No need to timeout authentication since there is no key
1630 * management. */
1631 wpa_supplicant_cancel_auth_timeout(wpa_s);
1632 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1633#ifdef CONFIG_IBSS_RSN
1634 } else if (ssid->mode == WPAS_MODE_IBSS &&
1635 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1636 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1637 /*
1638 * RSN IBSS authentication is per-STA and we can disable the
1639 * per-BSSID authentication.
1640 */
1641 wpa_supplicant_cancel_auth_timeout(wpa_s);
1642#endif /* CONFIG_IBSS_RSN */
1643 } else {
1644 /* Timeout for IEEE 802.11 authentication and association */
1645 int timeout = 60;
1646
1647 if (assoc_failed) {
1648 /* give IBSS a bit more time */
1649 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1650 } else if (wpa_s->conf->ap_scan == 1) {
1651 /* give IBSS a bit more time */
1652 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1653 }
1654 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1655 }
1656
1657 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1658 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1659 /* Set static WEP keys again */
1660 wpa_set_wep_keys(wpa_s, ssid);
1661 }
1662
1663 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1664 /*
1665 * Do not allow EAP session resumption between different
1666 * network configurations.
1667 */
1668 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1669 }
1670 old_ssid = wpa_s->current_ssid;
1671 wpa_s->current_ssid = ssid;
1672 wpa_s->current_bss = bss;
1673 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1674 wpa_supplicant_initiate_eapol(wpa_s);
1675 if (old_ssid != wpa_s->current_ssid)
1676 wpas_notify_network_changed(wpa_s);
1677}
1678
1679
1680static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1681 const u8 *addr)
1682{
1683 struct wpa_ssid *old_ssid;
1684
1685 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001686 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001687 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001688 wpa_sm_set_config(wpa_s->wpa, NULL);
1689 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1690 if (old_ssid != wpa_s->current_ssid)
1691 wpas_notify_network_changed(wpa_s);
1692 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1693}
1694
1695
1696/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001697 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1698 * @wpa_s: Pointer to wpa_supplicant data
1699 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1700 *
1701 * This function is used to request %wpa_supplicant to deauthenticate from the
1702 * current AP.
1703 */
1704void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1705 int reason_code)
1706{
1707 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001708 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001709 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001710
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001711 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1712 " pending_bssid=" MACSTR " reason=%d state=%s",
1713 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1714 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1715
1716 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001717 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001718 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1719 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1720 wpa_s->wpa_state == WPA_ASSOCIATING))
1721 addr = wpa_s->pending_bssid;
1722 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1723 /*
1724 * When using driver-based BSS selection, we may not know the
1725 * BSSID with which we are currently trying to associate. We
1726 * need to notify the driver of this disconnection even in such
1727 * a case, so use the all zeros address here.
1728 */
1729 addr = wpa_s->bssid;
1730 zero_addr = 1;
1731 }
1732
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001733#ifdef CONFIG_TDLS
1734 wpa_tdls_teardown_peers(wpa_s->wpa);
1735#endif /* CONFIG_TDLS */
1736
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001737 if (addr) {
1738 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001739 os_memset(&event, 0, sizeof(event));
1740 event.deauth_info.reason_code = (u16) reason_code;
1741 event.deauth_info.locally_generated = 1;
1742 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001743 if (zero_addr)
1744 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001745 }
1746
1747 wpa_supplicant_clear_connection(wpa_s, addr);
1748}
1749
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001750static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1751 struct wpa_ssid *ssid)
1752{
1753 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1754 return;
1755
1756 ssid->disabled = 0;
1757 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1758 wpas_notify_network_enabled_changed(wpa_s, ssid);
1759
1760 /*
1761 * Try to reassociate since there is no current configuration and a new
1762 * network was made available.
1763 */
1764 if (!wpa_s->current_ssid)
1765 wpa_s->reassociate = 1;
1766}
1767
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001768
1769/**
1770 * wpa_supplicant_enable_network - Mark a configured network as enabled
1771 * @wpa_s: wpa_supplicant structure for a network interface
1772 * @ssid: wpa_ssid structure for a configured network or %NULL
1773 *
1774 * Enables the specified network or all networks if no network specified.
1775 */
1776void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1777 struct wpa_ssid *ssid)
1778{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001779 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001780 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1781 wpa_supplicant_enable_one_network(wpa_s, ssid);
1782 } else
1783 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001784
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001785 if (wpa_s->reassociate) {
1786 if (wpa_s->sched_scanning) {
1787 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1788 "new network to scan filters");
1789 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001790 }
1791
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001792 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001793 }
1794}
1795
1796
1797/**
1798 * wpa_supplicant_disable_network - Mark a configured network as disabled
1799 * @wpa_s: wpa_supplicant structure for a network interface
1800 * @ssid: wpa_ssid structure for a configured network or %NULL
1801 *
1802 * Disables the specified network or all networks if no network specified.
1803 */
1804void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1805 struct wpa_ssid *ssid)
1806{
1807 struct wpa_ssid *other_ssid;
1808 int was_disabled;
1809
1810 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001811 if (wpa_s->sched_scanning)
1812 wpa_supplicant_cancel_sched_scan(wpa_s);
1813
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001814 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1815 other_ssid = other_ssid->next) {
1816 was_disabled = other_ssid->disabled;
1817 if (was_disabled == 2)
1818 continue; /* do not change persistent P2P group
1819 * data */
1820
1821 other_ssid->disabled = 1;
1822
1823 if (was_disabled != other_ssid->disabled)
1824 wpas_notify_network_enabled_changed(
1825 wpa_s, other_ssid);
1826 }
1827 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001828 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001829 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1830 } else if (ssid->disabled != 2) {
1831 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001832 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001833 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1834
1835 was_disabled = ssid->disabled;
1836
1837 ssid->disabled = 1;
1838
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001839 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001840 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001841 if (wpa_s->sched_scanning) {
1842 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1843 "to remove network from filters");
1844 wpa_supplicant_cancel_sched_scan(wpa_s);
1845 wpa_supplicant_req_scan(wpa_s, 0, 0);
1846 }
1847 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001848 }
1849}
1850
1851
1852/**
1853 * wpa_supplicant_select_network - Attempt association with a network
1854 * @wpa_s: wpa_supplicant structure for a network interface
1855 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1856 */
1857void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1858 struct wpa_ssid *ssid)
1859{
1860
1861 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001862 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001863
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001864 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001865 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001866 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001867 disconnected = 1;
1868 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001869
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001870 if (ssid)
1871 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1872
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001873 /*
1874 * Mark all other networks disabled or mark all networks enabled if no
1875 * network specified.
1876 */
1877 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1878 other_ssid = other_ssid->next) {
1879 int was_disabled = other_ssid->disabled;
1880 if (was_disabled == 2)
1881 continue; /* do not change persistent P2P group data */
1882
1883 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001884 if (was_disabled && !other_ssid->disabled)
1885 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001886
1887 if (was_disabled != other_ssid->disabled)
1888 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1889 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001890
1891 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1892 /* We are already associated with the selected network */
1893 wpa_printf(MSG_DEBUG, "Already associated with the "
1894 "selected network - do nothing");
1895 return;
1896 }
1897
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001898 if (ssid)
1899 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001900 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001901 wpa_s->disconnected = 0;
1902 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001903
1904 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1905 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001906
1907 if (ssid)
1908 wpas_notify_network_selected(wpa_s, ssid);
1909}
1910
1911
1912/**
1913 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1914 * @wpa_s: wpa_supplicant structure for a network interface
1915 * @ap_scan: AP scan mode
1916 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1917 *
1918 */
1919int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1920{
1921
1922 int old_ap_scan;
1923
1924 if (ap_scan < 0 || ap_scan > 2)
1925 return -1;
1926
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001927#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001928 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1929 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1930 wpa_s->wpa_state < WPA_COMPLETED) {
1931 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1932 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001933 return 0;
1934 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001935#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001936
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001937 old_ap_scan = wpa_s->conf->ap_scan;
1938 wpa_s->conf->ap_scan = ap_scan;
1939
1940 if (old_ap_scan != wpa_s->conf->ap_scan)
1941 wpas_notify_ap_scan_changed(wpa_s);
1942
1943 return 0;
1944}
1945
1946
1947/**
1948 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1949 * @wpa_s: wpa_supplicant structure for a network interface
1950 * @expire_age: Expiration age in seconds
1951 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1952 *
1953 */
1954int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1955 unsigned int bss_expire_age)
1956{
1957 if (bss_expire_age < 10) {
1958 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1959 bss_expire_age);
1960 return -1;
1961 }
1962 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1963 bss_expire_age);
1964 wpa_s->conf->bss_expiration_age = bss_expire_age;
1965
1966 return 0;
1967}
1968
1969
1970/**
1971 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
1972 * @wpa_s: wpa_supplicant structure for a network interface
1973 * @expire_count: number of scans after which an unseen BSS is reclaimed
1974 * Returns: 0 if succeed or -1 if expire_count has an invalid value
1975 *
1976 */
1977int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
1978 unsigned int bss_expire_count)
1979{
1980 if (bss_expire_count < 1) {
1981 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
1982 bss_expire_count);
1983 return -1;
1984 }
1985 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
1986 bss_expire_count);
1987 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
1988
1989 return 0;
1990}
1991
1992
1993/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07001994 * wpa_supplicant_set_scan_interval - Set scan interval
1995 * @wpa_s: wpa_supplicant structure for a network interface
1996 * @scan_interval: scan interval in seconds
1997 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
1998 *
1999 */
2000int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2001 int scan_interval)
2002{
2003 if (scan_interval < 0) {
2004 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2005 scan_interval);
2006 return -1;
2007 }
2008 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2009 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002010 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002011
2012 return 0;
2013}
2014
2015
2016/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002017 * wpa_supplicant_set_debug_params - Set global debug params
2018 * @global: wpa_global structure
2019 * @debug_level: debug level
2020 * @debug_timestamp: determines if show timestamp in debug data
2021 * @debug_show_keys: determines if show keys in debug data
2022 * Returns: 0 if succeed or -1 if debug_level has wrong value
2023 */
2024int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2025 int debug_timestamp, int debug_show_keys)
2026{
2027
2028 int old_level, old_timestamp, old_show_keys;
2029
2030 /* check for allowed debuglevels */
2031 if (debug_level != MSG_EXCESSIVE &&
2032 debug_level != MSG_MSGDUMP &&
2033 debug_level != MSG_DEBUG &&
2034 debug_level != MSG_INFO &&
2035 debug_level != MSG_WARNING &&
2036 debug_level != MSG_ERROR)
2037 return -1;
2038
2039 old_level = wpa_debug_level;
2040 old_timestamp = wpa_debug_timestamp;
2041 old_show_keys = wpa_debug_show_keys;
2042
2043 wpa_debug_level = debug_level;
2044 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2045 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2046
2047 if (wpa_debug_level != old_level)
2048 wpas_notify_debug_level_changed(global);
2049 if (wpa_debug_timestamp != old_timestamp)
2050 wpas_notify_debug_timestamp_changed(global);
2051 if (wpa_debug_show_keys != old_show_keys)
2052 wpas_notify_debug_show_keys_changed(global);
2053
2054 return 0;
2055}
2056
2057
2058/**
2059 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2060 * @wpa_s: Pointer to wpa_supplicant data
2061 * Returns: A pointer to the current network structure or %NULL on failure
2062 */
2063struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2064{
2065 struct wpa_ssid *entry;
2066 u8 ssid[MAX_SSID_LEN];
2067 int res;
2068 size_t ssid_len;
2069 u8 bssid[ETH_ALEN];
2070 int wired;
2071
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002072 res = wpa_drv_get_ssid(wpa_s, ssid);
2073 if (res < 0) {
2074 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2075 "driver");
2076 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002077 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002078 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002079
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002080 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002081 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2082 "driver");
2083 return NULL;
2084 }
2085
2086 wired = wpa_s->conf->ap_scan == 0 &&
2087 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2088
2089 entry = wpa_s->conf->ssid;
2090 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002091 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002092 ((ssid_len == entry->ssid_len &&
2093 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2094 (!entry->bssid_set ||
2095 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2096 return entry;
2097#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002098 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002099 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2100 (entry->ssid == NULL || entry->ssid_len == 0) &&
2101 (!entry->bssid_set ||
2102 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2103 return entry;
2104#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002105
Dmitry Shmidt04949592012-07-19 12:16:46 -07002106 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002107 entry->ssid_len == 0 &&
2108 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2109 return entry;
2110
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002111 entry = entry->next;
2112 }
2113
2114 return NULL;
2115}
2116
2117
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002118static int select_driver(struct wpa_supplicant *wpa_s, int i)
2119{
2120 struct wpa_global *global = wpa_s->global;
2121
2122 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2123 global->drv_priv[i] = wpa_drivers[i]->global_init();
2124 if (global->drv_priv[i] == NULL) {
2125 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2126 "'%s'", wpa_drivers[i]->name);
2127 return -1;
2128 }
2129 }
2130
2131 wpa_s->driver = wpa_drivers[i];
2132 wpa_s->global_drv_priv = global->drv_priv[i];
2133
2134 return 0;
2135}
2136
2137
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002138static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2139 const char *name)
2140{
2141 int i;
2142 size_t len;
2143 const char *pos, *driver = name;
2144
2145 if (wpa_s == NULL)
2146 return -1;
2147
2148 if (wpa_drivers[0] == NULL) {
2149 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2150 "wpa_supplicant");
2151 return -1;
2152 }
2153
2154 if (name == NULL) {
2155 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002156 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002157 }
2158
2159 do {
2160 pos = os_strchr(driver, ',');
2161 if (pos)
2162 len = pos - driver;
2163 else
2164 len = os_strlen(driver);
2165
2166 for (i = 0; wpa_drivers[i]; i++) {
2167 if (os_strlen(wpa_drivers[i]->name) == len &&
2168 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002169 0) {
2170 /* First driver that succeeds wins */
2171 if (select_driver(wpa_s, i) == 0)
2172 return 0;
2173 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002174 }
2175
2176 driver = pos + 1;
2177 } while (pos);
2178
2179 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2180 return -1;
2181}
2182
2183
2184/**
2185 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2186 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2187 * with struct wpa_driver_ops::init()
2188 * @src_addr: Source address of the EAPOL frame
2189 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2190 * @len: Length of the EAPOL data
2191 *
2192 * This function is called for each received EAPOL frame. Most driver
2193 * interfaces rely on more generic OS mechanism for receiving frames through
2194 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2195 * take care of received EAPOL frames and deliver them to the core supplicant
2196 * code by calling this function.
2197 */
2198void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2199 const u8 *buf, size_t len)
2200{
2201 struct wpa_supplicant *wpa_s = ctx;
2202
2203 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2204 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2205
Jouni Malinena05074c2012-12-21 21:35:35 +02002206 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2207 (wpa_s->last_eapol_matches_bssid &&
2208#ifdef CONFIG_AP
2209 !wpa_s->ap_iface &&
2210#endif /* CONFIG_AP */
2211 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002212 /*
2213 * There is possible race condition between receiving the
2214 * association event and the EAPOL frame since they are coming
2215 * through different paths from the driver. In order to avoid
2216 * issues in trying to process the EAPOL frame before receiving
2217 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002218 * the association event is received. This may also be needed in
2219 * driver-based roaming case, so also use src_addr != BSSID as a
2220 * trigger if we have previously confirmed that the
2221 * Authenticator uses BSSID as the src_addr (which is not the
2222 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002223 */
2224 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002225 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2226 wpa_supplicant_state_txt(wpa_s->wpa_state),
2227 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002228 wpabuf_free(wpa_s->pending_eapol_rx);
2229 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2230 if (wpa_s->pending_eapol_rx) {
2231 os_get_time(&wpa_s->pending_eapol_rx_time);
2232 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2233 ETH_ALEN);
2234 }
2235 return;
2236 }
2237
Jouni Malinena05074c2012-12-21 21:35:35 +02002238 wpa_s->last_eapol_matches_bssid =
2239 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2240
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002241#ifdef CONFIG_AP
2242 if (wpa_s->ap_iface) {
2243 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2244 return;
2245 }
2246#endif /* CONFIG_AP */
2247
2248 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2249 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2250 "no key management is configured");
2251 return;
2252 }
2253
2254 if (wpa_s->eapol_received == 0 &&
2255 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2256 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2257 wpa_s->wpa_state != WPA_COMPLETED) &&
2258 (wpa_s->current_ssid == NULL ||
2259 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2260 /* Timeout for completing IEEE 802.1X and WPA authentication */
2261 wpa_supplicant_req_auth_timeout(
2262 wpa_s,
2263 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2264 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2265 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2266 70 : 10, 0);
2267 }
2268 wpa_s->eapol_received++;
2269
2270 if (wpa_s->countermeasures) {
2271 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2272 "EAPOL packet");
2273 return;
2274 }
2275
2276#ifdef CONFIG_IBSS_RSN
2277 if (wpa_s->current_ssid &&
2278 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2279 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2280 return;
2281 }
2282#endif /* CONFIG_IBSS_RSN */
2283
2284 /* Source address of the incoming EAPOL frame could be compared to the
2285 * current BSSID. However, it is possible that a centralized
2286 * Authenticator could be using another MAC address than the BSSID of
2287 * an AP, so just allow any address to be used for now. The replies are
2288 * still sent to the current BSSID (if available), though. */
2289
2290 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2291 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2292 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2293 return;
2294 wpa_drv_poll(wpa_s);
2295 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2296 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2297 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2298 /*
2299 * Set portValid = TRUE here since we are going to skip 4-way
2300 * handshake processing which would normally set portValid. We
2301 * need this to allow the EAPOL state machines to be completed
2302 * without going through EAPOL-Key handshake.
2303 */
2304 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2305 }
2306}
2307
2308
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002309int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002310{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002311 if (wpa_s->driver->send_eapol) {
2312 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2313 if (addr)
2314 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2315 } else if (!(wpa_s->drv_flags &
2316 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002317 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002318 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2319 wpa_drv_get_mac_addr(wpa_s),
2320 ETH_P_EAPOL,
2321 wpa_supplicant_rx_eapol, wpa_s, 0);
2322 if (wpa_s->l2 == NULL)
2323 return -1;
2324 } else {
2325 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2326 if (addr)
2327 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2328 }
2329
2330 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2331 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2332 return -1;
2333 }
2334
2335 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2336 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002337 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2338
2339 return 0;
2340}
2341
2342
Dmitry Shmidt04949592012-07-19 12:16:46 -07002343static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2344 const u8 *buf, size_t len)
2345{
2346 struct wpa_supplicant *wpa_s = ctx;
2347 const struct l2_ethhdr *eth;
2348
2349 if (len < sizeof(*eth))
2350 return;
2351 eth = (const struct l2_ethhdr *) buf;
2352
2353 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2354 !(eth->h_dest[0] & 0x01)) {
2355 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2356 " (bridge - not for this interface - ignore)",
2357 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2358 return;
2359 }
2360
2361 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2362 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2363 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2364 len - sizeof(*eth));
2365}
2366
2367
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002368/**
2369 * wpa_supplicant_driver_init - Initialize driver interface parameters
2370 * @wpa_s: Pointer to wpa_supplicant data
2371 * Returns: 0 on success, -1 on failure
2372 *
2373 * This function is called to initialize driver interface parameters.
2374 * wpa_drv_init() must have been called before this function to initialize the
2375 * driver interface.
2376 */
2377int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2378{
2379 static int interface_count = 0;
2380
2381 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2382 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002383
2384 if (wpa_s->bridge_ifname[0]) {
2385 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2386 "interface '%s'", wpa_s->bridge_ifname);
2387 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2388 wpa_s->own_addr,
2389 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002390 wpa_supplicant_rx_eapol_bridge,
2391 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002392 if (wpa_s->l2_br == NULL) {
2393 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2394 "connection for the bridge interface '%s'",
2395 wpa_s->bridge_ifname);
2396 return -1;
2397 }
2398 }
2399
2400 wpa_clear_keys(wpa_s, NULL);
2401
2402 /* Make sure that TKIP countermeasures are not left enabled (could
2403 * happen if wpa_supplicant is killed during countermeasures. */
2404 wpa_drv_set_countermeasures(wpa_s, 0);
2405
2406 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2407 wpa_drv_flush_pmkid(wpa_s);
2408
2409 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002410 wpa_s->prev_scan_wildcard = 0;
2411
Dmitry Shmidt04949592012-07-19 12:16:46 -07002412 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002413 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2414 100000))
2415 wpa_supplicant_req_scan(wpa_s, interface_count,
2416 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002417 interface_count++;
2418 } else
2419 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2420
2421 return 0;
2422}
2423
2424
2425static int wpa_supplicant_daemon(const char *pid_file)
2426{
2427 wpa_printf(MSG_DEBUG, "Daemonize..");
2428 return os_daemonize(pid_file);
2429}
2430
2431
2432static struct wpa_supplicant * wpa_supplicant_alloc(void)
2433{
2434 struct wpa_supplicant *wpa_s;
2435
2436 wpa_s = os_zalloc(sizeof(*wpa_s));
2437 if (wpa_s == NULL)
2438 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002439 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002440 wpa_s->scan_interval = 5;
2441 wpa_s->new_connection = 1;
2442 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002443 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002444
2445 return wpa_s;
2446}
2447
2448
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002449#ifdef CONFIG_HT_OVERRIDES
2450
2451static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2452 struct ieee80211_ht_capabilities *htcaps,
2453 struct ieee80211_ht_capabilities *htcaps_mask,
2454 const char *ht_mcs)
2455{
2456 /* parse ht_mcs into hex array */
2457 int i;
2458 const char *tmp = ht_mcs;
2459 char *end = NULL;
2460
2461 /* If ht_mcs is null, do not set anything */
2462 if (!ht_mcs)
2463 return 0;
2464
2465 /* This is what we are setting in the kernel */
2466 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2467
2468 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2469
2470 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2471 errno = 0;
2472 long v = strtol(tmp, &end, 16);
2473 if (errno == 0) {
2474 wpa_msg(wpa_s, MSG_DEBUG,
2475 "htcap value[%i]: %ld end: %p tmp: %p",
2476 i, v, end, tmp);
2477 if (end == tmp)
2478 break;
2479
2480 htcaps->supported_mcs_set[i] = v;
2481 tmp = end;
2482 } else {
2483 wpa_msg(wpa_s, MSG_ERROR,
2484 "Failed to parse ht-mcs: %s, error: %s\n",
2485 ht_mcs, strerror(errno));
2486 return -1;
2487 }
2488 }
2489
2490 /*
2491 * If we were able to parse any values, then set mask for the MCS set.
2492 */
2493 if (i) {
2494 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2495 IEEE80211_HT_MCS_MASK_LEN - 1);
2496 /* skip the 3 reserved bits */
2497 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2498 0x1f;
2499 }
2500
2501 return 0;
2502}
2503
2504
2505static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2506 struct ieee80211_ht_capabilities *htcaps,
2507 struct ieee80211_ht_capabilities *htcaps_mask,
2508 int disabled)
2509{
2510 u16 msk;
2511
2512 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2513
2514 if (disabled == -1)
2515 return 0;
2516
2517 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2518 htcaps_mask->ht_capabilities_info |= msk;
2519 if (disabled)
2520 htcaps->ht_capabilities_info &= msk;
2521 else
2522 htcaps->ht_capabilities_info |= msk;
2523
2524 return 0;
2525}
2526
2527
2528static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2529 struct ieee80211_ht_capabilities *htcaps,
2530 struct ieee80211_ht_capabilities *htcaps_mask,
2531 int factor)
2532{
2533 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2534
2535 if (factor == -1)
2536 return 0;
2537
2538 if (factor < 0 || factor > 3) {
2539 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2540 "Must be 0-3 or -1", factor);
2541 return -EINVAL;
2542 }
2543
2544 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2545 htcaps->a_mpdu_params &= ~0x3;
2546 htcaps->a_mpdu_params |= factor & 0x3;
2547
2548 return 0;
2549}
2550
2551
2552static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2553 struct ieee80211_ht_capabilities *htcaps,
2554 struct ieee80211_ht_capabilities *htcaps_mask,
2555 int density)
2556{
2557 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2558
2559 if (density == -1)
2560 return 0;
2561
2562 if (density < 0 || density > 7) {
2563 wpa_msg(wpa_s, MSG_ERROR,
2564 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2565 density);
2566 return -EINVAL;
2567 }
2568
2569 htcaps_mask->a_mpdu_params |= 0x1C;
2570 htcaps->a_mpdu_params &= ~(0x1C);
2571 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2572
2573 return 0;
2574}
2575
2576
2577static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2578 struct ieee80211_ht_capabilities *htcaps,
2579 struct ieee80211_ht_capabilities *htcaps_mask,
2580 int disabled)
2581{
2582 /* Masking these out disables HT40 */
2583 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2584 HT_CAP_INFO_SHORT_GI40MHZ);
2585
2586 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2587
2588 if (disabled)
2589 htcaps->ht_capabilities_info &= ~msk;
2590 else
2591 htcaps->ht_capabilities_info |= msk;
2592
2593 htcaps_mask->ht_capabilities_info |= msk;
2594
2595 return 0;
2596}
2597
2598
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002599static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2600 struct ieee80211_ht_capabilities *htcaps,
2601 struct ieee80211_ht_capabilities *htcaps_mask,
2602 int disabled)
2603{
2604 /* Masking these out disables SGI */
2605 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2606 HT_CAP_INFO_SHORT_GI40MHZ);
2607
2608 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2609
2610 if (disabled)
2611 htcaps->ht_capabilities_info &= ~msk;
2612 else
2613 htcaps->ht_capabilities_info |= msk;
2614
2615 htcaps_mask->ht_capabilities_info |= msk;
2616
2617 return 0;
2618}
2619
2620
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002621void wpa_supplicant_apply_ht_overrides(
2622 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2623 struct wpa_driver_associate_params *params)
2624{
2625 struct ieee80211_ht_capabilities *htcaps;
2626 struct ieee80211_ht_capabilities *htcaps_mask;
2627
2628 if (!ssid)
2629 return;
2630
2631 params->disable_ht = ssid->disable_ht;
2632 if (!params->htcaps || !params->htcaps_mask)
2633 return;
2634
2635 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2636 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2637 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2638 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2639 ssid->disable_max_amsdu);
2640 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2641 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2642 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002643 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002644}
2645
2646#endif /* CONFIG_HT_OVERRIDES */
2647
2648
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002649#ifdef CONFIG_VHT_OVERRIDES
2650void wpa_supplicant_apply_vht_overrides(
2651 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2652 struct wpa_driver_associate_params *params)
2653{
2654 struct ieee80211_vht_capabilities *vhtcaps;
2655 struct ieee80211_vht_capabilities *vhtcaps_mask;
2656
2657 if (!ssid)
2658 return;
2659
2660 params->disable_vht = ssid->disable_vht;
2661
2662 vhtcaps = (void *) params->vhtcaps;
2663 vhtcaps_mask = (void *) params->vhtcaps_mask;
2664
2665 if (!vhtcaps || !vhtcaps_mask)
2666 return;
2667
2668 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2669 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2670
2671#define OVERRIDE_MCS(i) \
2672 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2673 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2674 3 << 2 * (i - 1); \
2675 vhtcaps->vht_supported_mcs_set.tx_map |= \
2676 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2677 } \
2678 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2679 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2680 3 << 2 * (i - 1); \
2681 vhtcaps->vht_supported_mcs_set.rx_map |= \
2682 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2683 }
2684
2685 OVERRIDE_MCS(1);
2686 OVERRIDE_MCS(2);
2687 OVERRIDE_MCS(3);
2688 OVERRIDE_MCS(4);
2689 OVERRIDE_MCS(5);
2690 OVERRIDE_MCS(6);
2691 OVERRIDE_MCS(7);
2692 OVERRIDE_MCS(8);
2693}
2694#endif /* CONFIG_VHT_OVERRIDES */
2695
2696
Dmitry Shmidt04949592012-07-19 12:16:46 -07002697static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2698{
2699#ifdef PCSC_FUNCS
2700 size_t len;
2701
2702 if (!wpa_s->conf->pcsc_reader)
2703 return 0;
2704
2705 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2706 if (!wpa_s->scard)
2707 return 1;
2708
2709 if (wpa_s->conf->pcsc_pin &&
2710 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2711 scard_deinit(wpa_s->scard);
2712 wpa_s->scard = NULL;
2713 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2714 return -1;
2715 }
2716
2717 len = sizeof(wpa_s->imsi) - 1;
2718 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2719 scard_deinit(wpa_s->scard);
2720 wpa_s->scard = NULL;
2721 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2722 return -1;
2723 }
2724 wpa_s->imsi[len] = '\0';
2725
2726 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2727
2728 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2729 wpa_s->imsi, wpa_s->mnc_len);
2730
2731 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2732 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2733#endif /* PCSC_FUNCS */
2734
2735 return 0;
2736}
2737
2738
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002739int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2740{
2741 char *val, *pos;
2742
2743 ext_password_deinit(wpa_s->ext_pw);
2744 wpa_s->ext_pw = NULL;
2745 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2746
2747 if (!wpa_s->conf->ext_password_backend)
2748 return 0;
2749
2750 val = os_strdup(wpa_s->conf->ext_password_backend);
2751 if (val == NULL)
2752 return -1;
2753 pos = os_strchr(val, ':');
2754 if (pos)
2755 *pos++ = '\0';
2756
2757 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2758
2759 wpa_s->ext_pw = ext_password_init(val, pos);
2760 os_free(val);
2761 if (wpa_s->ext_pw == NULL) {
2762 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2763 return -1;
2764 }
2765 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2766
2767 return 0;
2768}
2769
2770
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002771static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2772 struct wpa_interface *iface)
2773{
2774 const char *ifname, *driver;
2775 struct wpa_driver_capa capa;
2776
2777 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2778 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2779 iface->confname ? iface->confname : "N/A",
2780 iface->driver ? iface->driver : "default",
2781 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2782 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2783
2784 if (iface->confname) {
2785#ifdef CONFIG_BACKEND_FILE
2786 wpa_s->confname = os_rel2abs_path(iface->confname);
2787 if (wpa_s->confname == NULL) {
2788 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2789 "for configuration file '%s'.",
2790 iface->confname);
2791 return -1;
2792 }
2793 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2794 iface->confname, wpa_s->confname);
2795#else /* CONFIG_BACKEND_FILE */
2796 wpa_s->confname = os_strdup(iface->confname);
2797#endif /* CONFIG_BACKEND_FILE */
2798 wpa_s->conf = wpa_config_read(wpa_s->confname);
2799 if (wpa_s->conf == NULL) {
2800 wpa_printf(MSG_ERROR, "Failed to read or parse "
2801 "configuration '%s'.", wpa_s->confname);
2802 return -1;
2803 }
2804
2805 /*
2806 * Override ctrl_interface and driver_param if set on command
2807 * line.
2808 */
2809 if (iface->ctrl_interface) {
2810 os_free(wpa_s->conf->ctrl_interface);
2811 wpa_s->conf->ctrl_interface =
2812 os_strdup(iface->ctrl_interface);
2813 }
2814
2815 if (iface->driver_param) {
2816 os_free(wpa_s->conf->driver_param);
2817 wpa_s->conf->driver_param =
2818 os_strdup(iface->driver_param);
2819 }
2820 } else
2821 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2822 iface->driver_param);
2823
2824 if (wpa_s->conf == NULL) {
2825 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2826 return -1;
2827 }
2828
2829 if (iface->ifname == NULL) {
2830 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2831 return -1;
2832 }
2833 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2834 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2835 iface->ifname);
2836 return -1;
2837 }
2838 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2839
2840 if (iface->bridge_ifname) {
2841 if (os_strlen(iface->bridge_ifname) >=
2842 sizeof(wpa_s->bridge_ifname)) {
2843 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2844 "name '%s'.", iface->bridge_ifname);
2845 return -1;
2846 }
2847 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2848 sizeof(wpa_s->bridge_ifname));
2849 }
2850
2851 /* RSNA Supplicant Key Management - INITIALIZE */
2852 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2853 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2854
2855 /* Initialize driver interface and register driver event handler before
2856 * L2 receive handler so that association events are processed before
2857 * EAPOL-Key packets if both become available for the same select()
2858 * call. */
2859 driver = iface->driver;
2860next_driver:
2861 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2862 return -1;
2863
2864 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2865 if (wpa_s->drv_priv == NULL) {
2866 const char *pos;
2867 pos = driver ? os_strchr(driver, ',') : NULL;
2868 if (pos) {
2869 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2870 "driver interface - try next driver wrapper");
2871 driver = pos + 1;
2872 goto next_driver;
2873 }
2874 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2875 "interface");
2876 return -1;
2877 }
2878 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2879 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2880 "driver_param '%s'", wpa_s->conf->driver_param);
2881 return -1;
2882 }
2883
2884 ifname = wpa_drv_get_ifname(wpa_s);
2885 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2886 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2887 "interface name with '%s'", ifname);
2888 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2889 }
2890
2891 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2892 return -1;
2893
2894 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2895 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2896 NULL);
2897 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2898
2899 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2900 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2901 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2902 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2903 "dot11RSNAConfigPMKLifetime");
2904 return -1;
2905 }
2906
2907 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2908 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2909 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2910 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2911 "dot11RSNAConfigPMKReauthThreshold");
2912 return -1;
2913 }
2914
2915 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2916 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2917 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2918 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2919 "dot11RSNAConfigSATimeout");
2920 return -1;
2921 }
2922
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002923 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2924 &wpa_s->hw.num_modes,
2925 &wpa_s->hw.flags);
2926
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002927 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002928 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002929 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002930 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002931 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002932 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002933 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2934 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2935 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002936 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2937 wpa_s->max_stations = capa.max_stations;
2938 }
2939 if (wpa_s->max_remain_on_chan == 0)
2940 wpa_s->max_remain_on_chan = 1000;
2941
2942 if (wpa_supplicant_driver_init(wpa_s) < 0)
2943 return -1;
2944
2945#ifdef CONFIG_TDLS
2946 if (wpa_tdls_init(wpa_s->wpa))
2947 return -1;
2948#endif /* CONFIG_TDLS */
2949
2950 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2951 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2952 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2953 return -1;
2954 }
2955
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002956 if (wpas_wps_init(wpa_s))
2957 return -1;
2958
2959 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2960 return -1;
2961 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2962
2963 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2964 if (wpa_s->ctrl_iface == NULL) {
2965 wpa_printf(MSG_ERROR,
2966 "Failed to initialize control interface '%s'.\n"
2967 "You may have another wpa_supplicant process "
2968 "already running or the file was\n"
2969 "left by an unclean termination of wpa_supplicant "
2970 "in which case you will need\n"
2971 "to manually remove this file before starting "
2972 "wpa_supplicant again.\n",
2973 wpa_s->conf->ctrl_interface);
2974 return -1;
2975 }
2976
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002977 wpa_s->gas = gas_query_init(wpa_s);
2978 if (wpa_s->gas == NULL) {
2979 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
2980 return -1;
2981 }
2982
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002983#ifdef CONFIG_P2P
2984 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
2985 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
2986 return -1;
2987 }
2988#endif /* CONFIG_P2P */
2989
2990 if (wpa_bss_init(wpa_s) < 0)
2991 return -1;
2992
Dmitry Shmidt04949592012-07-19 12:16:46 -07002993 if (pcsc_reader_init(wpa_s) < 0)
2994 return -1;
2995
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002996 if (wpas_init_ext_pw(wpa_s) < 0)
2997 return -1;
2998
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002999 return 0;
3000}
3001
3002
3003static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003004 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003005{
3006 if (wpa_s->drv_priv) {
3007 wpa_supplicant_deauthenticate(wpa_s,
3008 WLAN_REASON_DEAUTH_LEAVING);
3009
3010 wpa_drv_set_countermeasures(wpa_s, 0);
3011 wpa_clear_keys(wpa_s, NULL);
3012 }
3013
3014 wpa_supplicant_cleanup(wpa_s);
3015
Dmitry Shmidt04949592012-07-19 12:16:46 -07003016#ifdef CONFIG_P2P
3017 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3018 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3019 "the management interface is being removed");
3020 wpas_p2p_deinit_global(wpa_s->global);
3021 }
3022#endif /* CONFIG_P2P */
3023
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003024 if (wpa_s->drv_priv)
3025 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003026
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003027 if (notify)
3028 wpas_notify_iface_removed(wpa_s);
3029
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003030 if (terminate)
3031 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003032
3033 if (wpa_s->ctrl_iface) {
3034 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3035 wpa_s->ctrl_iface = NULL;
3036 }
3037
3038 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003039 wpa_config_free(wpa_s->conf);
3040 wpa_s->conf = NULL;
3041 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003042}
3043
3044
3045/**
3046 * wpa_supplicant_add_iface - Add a new network interface
3047 * @global: Pointer to global data from wpa_supplicant_init()
3048 * @iface: Interface configuration options
3049 * Returns: Pointer to the created interface or %NULL on failure
3050 *
3051 * This function is used to add new network interfaces for %wpa_supplicant.
3052 * This can be called before wpa_supplicant_run() to add interfaces before the
3053 * main event loop has been started. In addition, new interfaces can be added
3054 * dynamically while %wpa_supplicant is already running. This could happen,
3055 * e.g., when a hotplug network adapter is inserted.
3056 */
3057struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3058 struct wpa_interface *iface)
3059{
3060 struct wpa_supplicant *wpa_s;
3061 struct wpa_interface t_iface;
3062 struct wpa_ssid *ssid;
3063
3064 if (global == NULL || iface == NULL)
3065 return NULL;
3066
3067 wpa_s = wpa_supplicant_alloc();
3068 if (wpa_s == NULL)
3069 return NULL;
3070
3071 wpa_s->global = global;
3072
3073 t_iface = *iface;
3074 if (global->params.override_driver) {
3075 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3076 "('%s' -> '%s')",
3077 iface->driver, global->params.override_driver);
3078 t_iface.driver = global->params.override_driver;
3079 }
3080 if (global->params.override_ctrl_interface) {
3081 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3082 "ctrl_interface ('%s' -> '%s')",
3083 iface->ctrl_interface,
3084 global->params.override_ctrl_interface);
3085 t_iface.ctrl_interface =
3086 global->params.override_ctrl_interface;
3087 }
3088 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3089 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3090 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003091 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003092 os_free(wpa_s);
3093 return NULL;
3094 }
3095
3096 /* Notify the control interfaces about new iface */
3097 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003098 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003099 os_free(wpa_s);
3100 return NULL;
3101 }
3102
3103 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3104 wpas_notify_network_added(wpa_s, ssid);
3105
3106 wpa_s->next = global->ifaces;
3107 global->ifaces = wpa_s;
3108
3109 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003110 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003111
3112 return wpa_s;
3113}
3114
3115
3116/**
3117 * wpa_supplicant_remove_iface - Remove a network interface
3118 * @global: Pointer to global data from wpa_supplicant_init()
3119 * @wpa_s: Pointer to the network interface to be removed
3120 * Returns: 0 if interface was removed, -1 if interface was not found
3121 *
3122 * This function can be used to dynamically remove network interfaces from
3123 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3124 * addition, this function is used to remove all remaining interfaces when
3125 * %wpa_supplicant is terminated.
3126 */
3127int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003128 struct wpa_supplicant *wpa_s,
3129 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003130{
3131 struct wpa_supplicant *prev;
3132
3133 /* Remove interface from the global list of interfaces */
3134 prev = global->ifaces;
3135 if (prev == wpa_s) {
3136 global->ifaces = wpa_s->next;
3137 } else {
3138 while (prev && prev->next != wpa_s)
3139 prev = prev->next;
3140 if (prev == NULL)
3141 return -1;
3142 prev->next = wpa_s->next;
3143 }
3144
3145 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3146
3147 if (global->p2p_group_formation == wpa_s)
3148 global->p2p_group_formation = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003149 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003150 os_free(wpa_s);
3151
3152 return 0;
3153}
3154
3155
3156/**
3157 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3158 * @wpa_s: Pointer to the network interface
3159 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3160 */
3161const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3162{
3163 const char *eapol_method;
3164
3165 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3166 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3167 return "NO-EAP";
3168 }
3169
3170 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3171 if (eapol_method == NULL)
3172 return "UNKNOWN-EAP";
3173
3174 return eapol_method;
3175}
3176
3177
3178/**
3179 * wpa_supplicant_get_iface - Get a new network interface
3180 * @global: Pointer to global data from wpa_supplicant_init()
3181 * @ifname: Interface name
3182 * Returns: Pointer to the interface or %NULL if not found
3183 */
3184struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3185 const char *ifname)
3186{
3187 struct wpa_supplicant *wpa_s;
3188
3189 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3190 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3191 return wpa_s;
3192 }
3193 return NULL;
3194}
3195
3196
3197#ifndef CONFIG_NO_WPA_MSG
3198static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3199{
3200 struct wpa_supplicant *wpa_s = ctx;
3201 if (wpa_s == NULL)
3202 return NULL;
3203 return wpa_s->ifname;
3204}
3205#endif /* CONFIG_NO_WPA_MSG */
3206
3207
3208/**
3209 * wpa_supplicant_init - Initialize %wpa_supplicant
3210 * @params: Parameters for %wpa_supplicant
3211 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3212 *
3213 * This function is used to initialize %wpa_supplicant. After successful
3214 * initialization, the returned data pointer can be used to add and remove
3215 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3216 */
3217struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3218{
3219 struct wpa_global *global;
3220 int ret, i;
3221
3222 if (params == NULL)
3223 return NULL;
3224
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003225#ifdef CONFIG_DRIVER_NDIS
3226 {
3227 void driver_ndis_init_ops(void);
3228 driver_ndis_init_ops();
3229 }
3230#endif /* CONFIG_DRIVER_NDIS */
3231
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003232#ifndef CONFIG_NO_WPA_MSG
3233 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3234#endif /* CONFIG_NO_WPA_MSG */
3235
3236 wpa_debug_open_file(params->wpa_debug_file_path);
3237 if (params->wpa_debug_syslog)
3238 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003239 if (params->wpa_debug_tracing) {
3240 ret = wpa_debug_open_linux_tracing();
3241 if (ret) {
3242 wpa_printf(MSG_ERROR,
3243 "Failed to enable trace logging");
3244 return NULL;
3245 }
3246 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003247
3248 ret = eap_register_methods();
3249 if (ret) {
3250 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3251 if (ret == -2)
3252 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3253 "the same EAP type.");
3254 return NULL;
3255 }
3256
3257 global = os_zalloc(sizeof(*global));
3258 if (global == NULL)
3259 return NULL;
3260 dl_list_init(&global->p2p_srv_bonjour);
3261 dl_list_init(&global->p2p_srv_upnp);
3262 global->params.daemonize = params->daemonize;
3263 global->params.wait_for_monitor = params->wait_for_monitor;
3264 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3265 if (params->pid_file)
3266 global->params.pid_file = os_strdup(params->pid_file);
3267 if (params->ctrl_interface)
3268 global->params.ctrl_interface =
3269 os_strdup(params->ctrl_interface);
3270 if (params->override_driver)
3271 global->params.override_driver =
3272 os_strdup(params->override_driver);
3273 if (params->override_ctrl_interface)
3274 global->params.override_ctrl_interface =
3275 os_strdup(params->override_ctrl_interface);
3276 wpa_debug_level = global->params.wpa_debug_level =
3277 params->wpa_debug_level;
3278 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3279 params->wpa_debug_show_keys;
3280 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3281 params->wpa_debug_timestamp;
3282
3283 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3284
3285 if (eloop_init()) {
3286 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3287 wpa_supplicant_deinit(global);
3288 return NULL;
3289 }
3290
Jouni Malinen75ecf522011-06-27 15:19:46 -07003291 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003292
3293 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3294 if (global->ctrl_iface == NULL) {
3295 wpa_supplicant_deinit(global);
3296 return NULL;
3297 }
3298
3299 if (wpas_notify_supplicant_initialized(global)) {
3300 wpa_supplicant_deinit(global);
3301 return NULL;
3302 }
3303
3304 for (i = 0; wpa_drivers[i]; i++)
3305 global->drv_count++;
3306 if (global->drv_count == 0) {
3307 wpa_printf(MSG_ERROR, "No drivers enabled");
3308 wpa_supplicant_deinit(global);
3309 return NULL;
3310 }
3311 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3312 if (global->drv_priv == NULL) {
3313 wpa_supplicant_deinit(global);
3314 return NULL;
3315 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003316
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003317#ifdef CONFIG_WIFI_DISPLAY
3318 if (wifi_display_init(global) < 0) {
3319 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3320 wpa_supplicant_deinit(global);
3321 return NULL;
3322 }
3323#endif /* CONFIG_WIFI_DISPLAY */
3324
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003325 return global;
3326}
3327
3328
3329/**
3330 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3331 * @global: Pointer to global data from wpa_supplicant_init()
3332 * Returns: 0 after successful event loop run, -1 on failure
3333 *
3334 * This function starts the main event loop and continues running as long as
3335 * there are any remaining events. In most cases, this function is running as
3336 * long as the %wpa_supplicant process in still in use.
3337 */
3338int wpa_supplicant_run(struct wpa_global *global)
3339{
3340 struct wpa_supplicant *wpa_s;
3341
3342 if (global->params.daemonize &&
3343 wpa_supplicant_daemon(global->params.pid_file))
3344 return -1;
3345
3346 if (global->params.wait_for_monitor) {
3347 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3348 if (wpa_s->ctrl_iface)
3349 wpa_supplicant_ctrl_iface_wait(
3350 wpa_s->ctrl_iface);
3351 }
3352
3353 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3354 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3355
3356 eloop_run();
3357
3358 return 0;
3359}
3360
3361
3362/**
3363 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3364 * @global: Pointer to global data from wpa_supplicant_init()
3365 *
3366 * This function is called to deinitialize %wpa_supplicant and to free all
3367 * allocated resources. Remaining network interfaces will also be removed.
3368 */
3369void wpa_supplicant_deinit(struct wpa_global *global)
3370{
3371 int i;
3372
3373 if (global == NULL)
3374 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003375
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003376#ifdef CONFIG_WIFI_DISPLAY
3377 wifi_display_deinit(global);
3378#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003379#ifdef CONFIG_P2P
3380 wpas_p2p_deinit_global(global);
3381#endif /* CONFIG_P2P */
3382
3383 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003384 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003385
3386 if (global->ctrl_iface)
3387 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3388
3389 wpas_notify_supplicant_deinitialized(global);
3390
3391 eap_peer_unregister_methods();
3392#ifdef CONFIG_AP
3393 eap_server_unregister_methods();
3394#endif /* CONFIG_AP */
3395
3396 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3397 if (!global->drv_priv[i])
3398 continue;
3399 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3400 }
3401 os_free(global->drv_priv);
3402
3403 random_deinit();
3404
3405 eloop_destroy();
3406
3407 if (global->params.pid_file) {
3408 os_daemonize_terminate(global->params.pid_file);
3409 os_free(global->params.pid_file);
3410 }
3411 os_free(global->params.ctrl_interface);
3412 os_free(global->params.override_driver);
3413 os_free(global->params.override_ctrl_interface);
3414
Dmitry Shmidt04949592012-07-19 12:16:46 -07003415 os_free(global->p2p_disallow_freq);
3416
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003417 os_free(global);
3418 wpa_debug_close_syslog();
3419 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003420 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003421}
3422
3423
3424void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3425{
3426 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3427 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3428 char country[3];
3429 country[0] = wpa_s->conf->country[0];
3430 country[1] = wpa_s->conf->country[1];
3431 country[2] = '\0';
3432 if (wpa_drv_set_country(wpa_s, country) < 0) {
3433 wpa_printf(MSG_ERROR, "Failed to set country code "
3434 "'%s'", country);
3435 }
3436 }
3437
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003438 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3439 wpas_init_ext_pw(wpa_s);
3440
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003441#ifdef CONFIG_WPS
3442 wpas_wps_update_config(wpa_s);
3443#endif /* CONFIG_WPS */
3444
3445#ifdef CONFIG_P2P
3446 wpas_p2p_update_config(wpa_s);
3447#endif /* CONFIG_P2P */
3448
3449 wpa_s->conf->changed_parameters = 0;
3450}
3451
3452
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003453static void add_freq(int *freqs, int *num_freqs, int freq)
3454{
3455 int i;
3456
3457 for (i = 0; i < *num_freqs; i++) {
3458 if (freqs[i] == freq)
3459 return;
3460 }
3461
3462 freqs[*num_freqs] = freq;
3463 (*num_freqs)++;
3464}
3465
3466
3467static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3468{
3469 struct wpa_bss *bss, *cbss;
3470 const int max_freqs = 10;
3471 int *freqs;
3472 int num_freqs = 0;
3473
3474 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3475 if (freqs == NULL)
3476 return NULL;
3477
3478 cbss = wpa_s->current_bss;
3479
3480 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3481 if (bss == cbss)
3482 continue;
3483 if (bss->ssid_len == cbss->ssid_len &&
3484 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3485 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3486 add_freq(freqs, &num_freqs, bss->freq);
3487 if (num_freqs == max_freqs)
3488 break;
3489 }
3490 }
3491
3492 if (num_freqs == 0) {
3493 os_free(freqs);
3494 freqs = NULL;
3495 }
3496
3497 return freqs;
3498}
3499
3500
3501void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3502{
3503 int timeout;
3504 int count;
3505 int *freqs = NULL;
3506
3507 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003508 * Remove possible authentication timeout since the connection failed.
3509 */
3510 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3511
3512 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003513 * Add the failed BSSID into the blacklist and speed up next scan
3514 * attempt if there could be other APs that could accept association.
3515 * The current blacklist count indicates how many times we have tried
3516 * connecting to this AP and multiple attempts mean that other APs are
3517 * either not available or has already been tried, so that we can start
3518 * increasing the delay here to avoid constant scanning.
3519 */
3520 count = wpa_blacklist_add(wpa_s, bssid);
3521 if (count == 1 && wpa_s->current_bss) {
3522 /*
3523 * This BSS was not in the blacklist before. If there is
3524 * another BSS available for the same ESS, we should try that
3525 * next. Otherwise, we may as well try this one once more
3526 * before allowing other, likely worse, ESSes to be considered.
3527 */
3528 freqs = get_bss_freqs_in_ess(wpa_s);
3529 if (freqs) {
3530 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3531 "has been seen; try it next");
3532 wpa_blacklist_add(wpa_s, bssid);
3533 /*
3534 * On the next scan, go through only the known channels
3535 * used in this ESS based on previous scans to speed up
3536 * common load balancing use case.
3537 */
3538 os_free(wpa_s->next_scan_freqs);
3539 wpa_s->next_scan_freqs = freqs;
3540 }
3541 }
3542
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003543 /*
3544 * Add previous failure count in case the temporary blacklist was
3545 * cleared due to no other BSSes being available.
3546 */
3547 count += wpa_s->extra_blacklist_count;
3548
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003549 switch (count) {
3550 case 1:
3551 timeout = 100;
3552 break;
3553 case 2:
3554 timeout = 500;
3555 break;
3556 case 3:
3557 timeout = 1000;
3558 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003559 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003560 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003561 break;
3562 default:
3563 timeout = 10000;
3564 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003565 }
3566
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003567 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3568 "ms", count, timeout);
3569
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003570 /*
3571 * TODO: if more than one possible AP is available in scan results,
3572 * could try the other ones before requesting a new scan.
3573 */
3574 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3575 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003576
3577#ifdef CONFIG_P2P
Jouni Malinendc7b7132012-09-14 12:53:47 -07003578 if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003579 wpa_s->global->p2p != NULL) {
Jouni Malinendc7b7132012-09-14 12:53:47 -07003580 wpa_s->global->p2p_cb_on_scan_complete = 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003581 if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
3582 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
3583 "continued after failed association");
3584 }
3585 }
3586#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003587}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003588
3589
3590int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3591{
3592 return wpa_s->conf->ap_scan == 2 ||
3593 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3594}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003595
Dmitry Shmidt04949592012-07-19 12:16:46 -07003596
3597#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3598int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3599 struct wpa_ssid *ssid,
3600 const char *field,
3601 const char *value)
3602{
3603#ifdef IEEE8021X_EAPOL
3604 struct eap_peer_config *eap = &ssid->eap;
3605
3606 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3607 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3608 (const u8 *) value, os_strlen(value));
3609
3610 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3611 case WPA_CTRL_REQ_EAP_IDENTITY:
3612 os_free(eap->identity);
3613 eap->identity = (u8 *) os_strdup(value);
3614 eap->identity_len = os_strlen(value);
3615 eap->pending_req_identity = 0;
3616 if (ssid == wpa_s->current_ssid)
3617 wpa_s->reassociate = 1;
3618 break;
3619 case WPA_CTRL_REQ_EAP_PASSWORD:
3620 os_free(eap->password);
3621 eap->password = (u8 *) os_strdup(value);
3622 eap->password_len = os_strlen(value);
3623 eap->pending_req_password = 0;
3624 if (ssid == wpa_s->current_ssid)
3625 wpa_s->reassociate = 1;
3626 break;
3627 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3628 os_free(eap->new_password);
3629 eap->new_password = (u8 *) os_strdup(value);
3630 eap->new_password_len = os_strlen(value);
3631 eap->pending_req_new_password = 0;
3632 if (ssid == wpa_s->current_ssid)
3633 wpa_s->reassociate = 1;
3634 break;
3635 case WPA_CTRL_REQ_EAP_PIN:
3636 os_free(eap->pin);
3637 eap->pin = os_strdup(value);
3638 eap->pending_req_pin = 0;
3639 if (ssid == wpa_s->current_ssid)
3640 wpa_s->reassociate = 1;
3641 break;
3642 case WPA_CTRL_REQ_EAP_OTP:
3643 os_free(eap->otp);
3644 eap->otp = (u8 *) os_strdup(value);
3645 eap->otp_len = os_strlen(value);
3646 os_free(eap->pending_req_otp);
3647 eap->pending_req_otp = NULL;
3648 eap->pending_req_otp_len = 0;
3649 break;
3650 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3651 os_free(eap->private_key_passwd);
3652 eap->private_key_passwd = (u8 *) os_strdup(value);
3653 eap->pending_req_passphrase = 0;
3654 if (ssid == wpa_s->current_ssid)
3655 wpa_s->reassociate = 1;
3656 break;
3657 default:
3658 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3659 return -1;
3660 }
3661
3662 return 0;
3663#else /* IEEE8021X_EAPOL */
3664 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3665 return -1;
3666#endif /* IEEE8021X_EAPOL */
3667}
3668#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3669
3670
3671int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3672{
3673 int i;
3674 unsigned int drv_enc;
3675
3676 if (ssid == NULL)
3677 return 1;
3678
3679 if (ssid->disabled)
3680 return 1;
3681
3682 if (wpa_s && wpa_s->drv_capa_known)
3683 drv_enc = wpa_s->drv_enc;
3684 else
3685 drv_enc = (unsigned int) -1;
3686
3687 for (i = 0; i < NUM_WEP_KEYS; i++) {
3688 size_t len = ssid->wep_key_len[i];
3689 if (len == 0)
3690 continue;
3691 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3692 continue;
3693 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3694 continue;
3695 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3696 continue;
3697 return 1; /* invalid WEP key */
3698 }
3699
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003700 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3701 !ssid->ext_psk)
3702 return 1;
3703
Dmitry Shmidt04949592012-07-19 12:16:46 -07003704 return 0;
3705}
3706
3707
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003708int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003709{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003710 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003711 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003712 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003713 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003714 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003715}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003716
3717
3718void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3719{
3720 struct wpa_ssid *ssid = wpa_s->current_ssid;
3721 int dur;
3722 struct os_time now;
3723
3724 if (ssid == NULL) {
3725 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3726 "SSID block");
3727 return;
3728 }
3729
3730 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3731 return;
3732
3733 ssid->auth_failures++;
3734 if (ssid->auth_failures > 50)
3735 dur = 300;
3736 else if (ssid->auth_failures > 20)
3737 dur = 120;
3738 else if (ssid->auth_failures > 10)
3739 dur = 60;
3740 else if (ssid->auth_failures > 5)
3741 dur = 30;
3742 else if (ssid->auth_failures > 1)
3743 dur = 20;
3744 else
3745 dur = 10;
3746
3747 os_get_time(&now);
3748 if (now.sec + dur <= ssid->disabled_until.sec)
3749 return;
3750
3751 ssid->disabled_until.sec = now.sec + dur;
3752
3753 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3754 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3755 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3756 ssid->auth_failures, dur);
3757}
3758
3759
3760void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3761 struct wpa_ssid *ssid, int clear_failures)
3762{
3763 if (ssid == NULL)
3764 return;
3765
3766 if (ssid->disabled_until.sec) {
3767 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3768 "id=%d ssid=\"%s\"",
3769 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3770 }
3771 ssid->disabled_until.sec = 0;
3772 ssid->disabled_until.usec = 0;
3773 if (clear_failures)
3774 ssid->auth_failures = 0;
3775}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003776
3777
3778int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3779{
3780 size_t i;
3781
3782 if (wpa_s->disallow_aps_bssid == NULL)
3783 return 0;
3784
3785 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3786 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3787 bssid, ETH_ALEN) == 0)
3788 return 1;
3789 }
3790
3791 return 0;
3792}
3793
3794
3795int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3796 size_t ssid_len)
3797{
3798 size_t i;
3799
3800 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3801 return 0;
3802
3803 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3804 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3805 if (ssid_len == s->ssid_len &&
3806 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3807 return 1;
3808 }
3809
3810 return 0;
3811}
3812
3813
3814/**
3815 * wpas_request_connection - Request a new connection
3816 * @wpa_s: Pointer to the network interface
3817 *
3818 * This function is used to request a new connection to be found. It will mark
3819 * the interface to allow reassociation and request a new scan to find a
3820 * suitable network to connect to.
3821 */
3822void wpas_request_connection(struct wpa_supplicant *wpa_s)
3823{
3824 wpa_s->normal_scans = 0;
3825 wpa_supplicant_reinit_autoscan(wpa_s);
3826 wpa_s->extra_blacklist_count = 0;
3827 wpa_s->disconnected = 0;
3828 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003829
3830 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3831 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003832}