blob: 7a93716a60ade72c8addf4b2eb5456adcb8a4e86 [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) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700664 struct wpa_ssid *ssid = wpa_s->current_ssid;
Dmitry Shmidt700a1372013-03-15 14:14:44 -0700665#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700666 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,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07001364 ssid, try_opportunistic) == 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001365 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1366 wpa_ie_len = sizeof(wpa_ie);
1367 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1368 wpa_ie, &wpa_ie_len)) {
1369 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1370 "key management and encryption suites");
1371 return;
1372 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001373 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1374 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1375 /*
1376 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1377 * use non-WPA since the scan results did not indicate that the
1378 * AP is using WPA or WPA2.
1379 */
1380 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1381 wpa_ie_len = 0;
1382 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001383 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001384 wpa_ie_len = sizeof(wpa_ie);
1385 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1386 wpa_ie, &wpa_ie_len)) {
1387 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1388 "key management and encryption suites (no "
1389 "scan results)");
1390 return;
1391 }
1392#ifdef CONFIG_WPS
1393 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1394 struct wpabuf *wps_ie;
1395 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1396 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1397 wpa_ie_len = wpabuf_len(wps_ie);
1398 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1399 } else
1400 wpa_ie_len = 0;
1401 wpabuf_free(wps_ie);
1402 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1403 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1404 params.wps = WPS_MODE_PRIVACY;
1405 else
1406 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001407 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001408#endif /* CONFIG_WPS */
1409 } else {
1410 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1411 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001412 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001413 }
1414
1415#ifdef CONFIG_P2P
1416 if (wpa_s->global->p2p) {
1417 u8 *pos;
1418 size_t len;
1419 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001420 pos = wpa_ie + wpa_ie_len;
1421 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001422 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1423 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001424 if (res >= 0)
1425 wpa_ie_len += res;
1426 }
1427
1428 wpa_s->cross_connect_disallowed = 0;
1429 if (bss) {
1430 struct wpabuf *p2p;
1431 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1432 if (p2p) {
1433 wpa_s->cross_connect_disallowed =
1434 p2p_get_cross_connect_disallowed(p2p);
1435 wpabuf_free(p2p);
1436 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1437 "connection",
1438 wpa_s->cross_connect_disallowed ?
1439 "disallows" : "allows");
1440 }
1441 }
1442#endif /* CONFIG_P2P */
1443
Dmitry Shmidt04949592012-07-19 12:16:46 -07001444#ifdef CONFIG_HS20
1445 if (wpa_s->conf->hs20) {
1446 struct wpabuf *hs20;
1447 hs20 = wpabuf_alloc(20);
1448 if (hs20) {
1449 wpas_hs20_add_indication(hs20);
1450 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1451 wpabuf_len(hs20));
1452 wpa_ie_len += wpabuf_len(hs20);
1453 wpabuf_free(hs20);
1454 }
1455 }
1456#endif /* CONFIG_HS20 */
1457
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001458 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1459 if (ext_capab_len > 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001460 u8 *pos = wpa_ie;
1461 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1462 pos += 2 + pos[1];
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001463 os_memmove(pos + ext_capab_len, pos,
1464 wpa_ie_len - (pos - wpa_ie));
1465 wpa_ie_len += ext_capab_len;
1466 os_memcpy(pos, ext_capab, ext_capab_len);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001467 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001468
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001469 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1470 use_crypt = 1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001471 cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1472 cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001473 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1474 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1475 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1476 use_crypt = 0;
1477 if (wpa_set_wep_keys(wpa_s, ssid)) {
1478 use_crypt = 1;
1479 wep_keys_set = 1;
1480 }
1481 }
1482 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1483 use_crypt = 0;
1484
1485#ifdef IEEE8021X_EAPOL
1486 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1487 if ((ssid->eapol_flags &
1488 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1489 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1490 !wep_keys_set) {
1491 use_crypt = 0;
1492 } else {
1493 /* Assume that dynamic WEP-104 keys will be used and
1494 * set cipher suites in order for drivers to expect
1495 * encryption. */
1496 cipher_pairwise = cipher_group = CIPHER_WEP104;
1497 }
1498 }
1499#endif /* IEEE8021X_EAPOL */
1500
1501 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1502 /* Set the key before (and later after) association */
1503 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1504 }
1505
1506 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1507 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001508 params.ssid = bss->ssid;
1509 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001510 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1511 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1512 MACSTR " freq=%u MHz based on scan results "
1513 "(bssid_set=%d)",
1514 MAC2STR(bss->bssid), bss->freq,
1515 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001516 params.bssid = bss->bssid;
1517 params.freq = bss->freq;
1518 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001519 } else {
1520 params.ssid = ssid->ssid;
1521 params.ssid_len = ssid->ssid_len;
1522 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001523
1524 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1525 wpa_s->conf->ap_scan == 2) {
1526 params.bssid = ssid->bssid;
1527 params.fixed_bssid = 1;
1528 }
1529
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001530 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1531 params.freq == 0)
1532 params.freq = ssid->frequency; /* Initial channel for IBSS */
1533 params.wpa_ie = wpa_ie;
1534 params.wpa_ie_len = wpa_ie_len;
1535 params.pairwise_suite = cipher_pairwise;
1536 params.group_suite = cipher_group;
1537 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001538 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001539 params.auth_alg = algs;
1540 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001541 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001542 for (i = 0; i < NUM_WEP_KEYS; i++) {
1543 if (ssid->wep_key_len[i])
1544 params.wep_key[i] = ssid->wep_key[i];
1545 params.wep_key_len[i] = ssid->wep_key_len[i];
1546 }
1547 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1548
1549 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1550 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1551 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1552 params.passphrase = ssid->passphrase;
1553 if (ssid->psk_set)
1554 params.psk = ssid->psk;
1555 }
1556
1557 params.drop_unencrypted = use_crypt;
1558
1559#ifdef CONFIG_IEEE80211W
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001560 params.mgmt_frame_protection =
1561 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1562 wpa_s->conf->pmf : ssid->ieee80211w;
1563 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001564 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1565 struct wpa_ie_data ie;
1566 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1567 ie.capabilities &
1568 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1569 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1570 "MFP: require MFP");
1571 params.mgmt_frame_protection =
1572 MGMT_FRAME_PROTECTION_REQUIRED;
1573 }
1574 }
1575#endif /* CONFIG_IEEE80211W */
1576
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001577 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001578
1579 if (wpa_s->parent->set_sta_uapsd)
1580 params.uapsd = wpa_s->parent->sta_uapsd;
1581 else
1582 params.uapsd = -1;
1583
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001584#ifdef CONFIG_HT_OVERRIDES
1585 os_memset(&htcaps, 0, sizeof(htcaps));
1586 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1587 params.htcaps = (u8 *) &htcaps;
1588 params.htcaps_mask = (u8 *) &htcaps_mask;
1589 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1590#endif /* CONFIG_HT_OVERRIDES */
1591
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001592#ifdef ANDROID_P2P
1593 /* If multichannel concurrency is not supported, check for any frequency
1594 * conflict and take appropriate action.
1595 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001596 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1597 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1598 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001599 , freq, params.freq);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001600 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001601 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001602 }
1603#endif
1604 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001605 if (ret < 0) {
1606 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1607 "failed");
1608 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1609 /*
1610 * The driver is known to mean what is saying, so we
1611 * can stop right here; the association will not
1612 * succeed.
1613 */
1614 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001615 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001616 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1617 return;
1618 }
1619 /* try to continue anyway; new association will be tried again
1620 * after timeout */
1621 assoc_failed = 1;
1622 }
1623
1624 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1625 /* Set the key after the association just in case association
1626 * cleared the previously configured key. */
1627 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1628 /* No need to timeout authentication since there is no key
1629 * management. */
1630 wpa_supplicant_cancel_auth_timeout(wpa_s);
1631 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1632#ifdef CONFIG_IBSS_RSN
1633 } else if (ssid->mode == WPAS_MODE_IBSS &&
1634 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1635 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1636 /*
1637 * RSN IBSS authentication is per-STA and we can disable the
1638 * per-BSSID authentication.
1639 */
1640 wpa_supplicant_cancel_auth_timeout(wpa_s);
1641#endif /* CONFIG_IBSS_RSN */
1642 } else {
1643 /* Timeout for IEEE 802.11 authentication and association */
1644 int timeout = 60;
1645
1646 if (assoc_failed) {
1647 /* give IBSS a bit more time */
1648 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1649 } else if (wpa_s->conf->ap_scan == 1) {
1650 /* give IBSS a bit more time */
1651 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1652 }
1653 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1654 }
1655
1656 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1657 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1658 /* Set static WEP keys again */
1659 wpa_set_wep_keys(wpa_s, ssid);
1660 }
1661
1662 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1663 /*
1664 * Do not allow EAP session resumption between different
1665 * network configurations.
1666 */
1667 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1668 }
1669 old_ssid = wpa_s->current_ssid;
1670 wpa_s->current_ssid = ssid;
1671 wpa_s->current_bss = bss;
1672 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1673 wpa_supplicant_initiate_eapol(wpa_s);
1674 if (old_ssid != wpa_s->current_ssid)
1675 wpas_notify_network_changed(wpa_s);
1676}
1677
1678
1679static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1680 const u8 *addr)
1681{
1682 struct wpa_ssid *old_ssid;
1683
1684 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001685 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001686 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001687 wpa_sm_set_config(wpa_s->wpa, NULL);
1688 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1689 if (old_ssid != wpa_s->current_ssid)
1690 wpas_notify_network_changed(wpa_s);
1691 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1692}
1693
1694
1695/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001696 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1697 * @wpa_s: Pointer to wpa_supplicant data
1698 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1699 *
1700 * This function is used to request %wpa_supplicant to deauthenticate from the
1701 * current AP.
1702 */
1703void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1704 int reason_code)
1705{
1706 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001707 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001708 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001709
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001710 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1711 " pending_bssid=" MACSTR " reason=%d state=%s",
1712 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1713 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1714
1715 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001716 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001717 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1718 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1719 wpa_s->wpa_state == WPA_ASSOCIATING))
1720 addr = wpa_s->pending_bssid;
1721 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1722 /*
1723 * When using driver-based BSS selection, we may not know the
1724 * BSSID with which we are currently trying to associate. We
1725 * need to notify the driver of this disconnection even in such
1726 * a case, so use the all zeros address here.
1727 */
1728 addr = wpa_s->bssid;
1729 zero_addr = 1;
1730 }
1731
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001732#ifdef CONFIG_TDLS
1733 wpa_tdls_teardown_peers(wpa_s->wpa);
1734#endif /* CONFIG_TDLS */
1735
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001736 if (addr) {
1737 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001738 os_memset(&event, 0, sizeof(event));
1739 event.deauth_info.reason_code = (u16) reason_code;
1740 event.deauth_info.locally_generated = 1;
1741 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001742 if (zero_addr)
1743 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001744 }
1745
1746 wpa_supplicant_clear_connection(wpa_s, addr);
1747}
1748
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001749static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
1750 struct wpa_ssid *ssid)
1751{
1752 if (!ssid || !ssid->disabled || ssid->disabled == 2)
1753 return;
1754
1755 ssid->disabled = 0;
1756 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1757 wpas_notify_network_enabled_changed(wpa_s, ssid);
1758
1759 /*
1760 * Try to reassociate since there is no current configuration and a new
1761 * network was made available.
1762 */
1763 if (!wpa_s->current_ssid)
1764 wpa_s->reassociate = 1;
1765}
1766
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001767
1768/**
1769 * wpa_supplicant_enable_network - Mark a configured network as enabled
1770 * @wpa_s: wpa_supplicant structure for a network interface
1771 * @ssid: wpa_ssid structure for a configured network or %NULL
1772 *
1773 * Enables the specified network or all networks if no network specified.
1774 */
1775void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1776 struct wpa_ssid *ssid)
1777{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001778 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001779 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
1780 wpa_supplicant_enable_one_network(wpa_s, ssid);
1781 } else
1782 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001783
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001784 if (wpa_s->reassociate) {
1785 if (wpa_s->sched_scanning) {
1786 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
1787 "new network to scan filters");
1788 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001789 }
1790
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001791 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001792 }
1793}
1794
1795
1796/**
1797 * wpa_supplicant_disable_network - Mark a configured network as disabled
1798 * @wpa_s: wpa_supplicant structure for a network interface
1799 * @ssid: wpa_ssid structure for a configured network or %NULL
1800 *
1801 * Disables the specified network or all networks if no network specified.
1802 */
1803void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1804 struct wpa_ssid *ssid)
1805{
1806 struct wpa_ssid *other_ssid;
1807 int was_disabled;
1808
1809 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001810 if (wpa_s->sched_scanning)
1811 wpa_supplicant_cancel_sched_scan(wpa_s);
1812
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001813 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1814 other_ssid = other_ssid->next) {
1815 was_disabled = other_ssid->disabled;
1816 if (was_disabled == 2)
1817 continue; /* do not change persistent P2P group
1818 * data */
1819
1820 other_ssid->disabled = 1;
1821
1822 if (was_disabled != other_ssid->disabled)
1823 wpas_notify_network_enabled_changed(
1824 wpa_s, other_ssid);
1825 }
1826 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001827 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001828 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1829 } else if (ssid->disabled != 2) {
1830 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001831 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001832 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1833
1834 was_disabled = ssid->disabled;
1835
1836 ssid->disabled = 1;
1837
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001838 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001839 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07001840 if (wpa_s->sched_scanning) {
1841 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
1842 "to remove network from filters");
1843 wpa_supplicant_cancel_sched_scan(wpa_s);
1844 wpa_supplicant_req_scan(wpa_s, 0, 0);
1845 }
1846 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001847 }
1848}
1849
1850
1851/**
1852 * wpa_supplicant_select_network - Attempt association with a network
1853 * @wpa_s: wpa_supplicant structure for a network interface
1854 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1855 */
1856void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1857 struct wpa_ssid *ssid)
1858{
1859
1860 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001861 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001862
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001863 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001864 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001865 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001866 disconnected = 1;
1867 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001868
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001869 if (ssid)
1870 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1871
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001872 /*
1873 * Mark all other networks disabled or mark all networks enabled if no
1874 * network specified.
1875 */
1876 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1877 other_ssid = other_ssid->next) {
1878 int was_disabled = other_ssid->disabled;
1879 if (was_disabled == 2)
1880 continue; /* do not change persistent P2P group data */
1881
1882 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001883 if (was_disabled && !other_ssid->disabled)
1884 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001885
1886 if (was_disabled != other_ssid->disabled)
1887 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1888 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001889
1890 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1891 /* We are already associated with the selected network */
1892 wpa_printf(MSG_DEBUG, "Already associated with the "
1893 "selected network - do nothing");
1894 return;
1895 }
1896
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001897 if (ssid)
1898 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001899 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001900 wpa_s->disconnected = 0;
1901 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08001902
1903 if (wpa_supplicant_fast_associate(wpa_s) != 1)
1904 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001905
1906 if (ssid)
1907 wpas_notify_network_selected(wpa_s, ssid);
1908}
1909
1910
1911/**
1912 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1913 * @wpa_s: wpa_supplicant structure for a network interface
1914 * @ap_scan: AP scan mode
1915 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1916 *
1917 */
1918int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1919{
1920
1921 int old_ap_scan;
1922
1923 if (ap_scan < 0 || ap_scan > 2)
1924 return -1;
1925
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001926#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001927 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1928 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1929 wpa_s->wpa_state < WPA_COMPLETED) {
1930 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1931 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001932 return 0;
1933 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001934#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001935
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001936 old_ap_scan = wpa_s->conf->ap_scan;
1937 wpa_s->conf->ap_scan = ap_scan;
1938
1939 if (old_ap_scan != wpa_s->conf->ap_scan)
1940 wpas_notify_ap_scan_changed(wpa_s);
1941
1942 return 0;
1943}
1944
1945
1946/**
1947 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1948 * @wpa_s: wpa_supplicant structure for a network interface
1949 * @expire_age: Expiration age in seconds
1950 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1951 *
1952 */
1953int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1954 unsigned int bss_expire_age)
1955{
1956 if (bss_expire_age < 10) {
1957 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1958 bss_expire_age);
1959 return -1;
1960 }
1961 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1962 bss_expire_age);
1963 wpa_s->conf->bss_expiration_age = bss_expire_age;
1964
1965 return 0;
1966}
1967
1968
1969/**
1970 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
1971 * @wpa_s: wpa_supplicant structure for a network interface
1972 * @expire_count: number of scans after which an unseen BSS is reclaimed
1973 * Returns: 0 if succeed or -1 if expire_count has an invalid value
1974 *
1975 */
1976int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
1977 unsigned int bss_expire_count)
1978{
1979 if (bss_expire_count < 1) {
1980 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
1981 bss_expire_count);
1982 return -1;
1983 }
1984 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
1985 bss_expire_count);
1986 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
1987
1988 return 0;
1989}
1990
1991
1992/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07001993 * wpa_supplicant_set_scan_interval - Set scan interval
1994 * @wpa_s: wpa_supplicant structure for a network interface
1995 * @scan_interval: scan interval in seconds
1996 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
1997 *
1998 */
1999int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2000 int scan_interval)
2001{
2002 if (scan_interval < 0) {
2003 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2004 scan_interval);
2005 return -1;
2006 }
2007 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2008 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002009 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002010
2011 return 0;
2012}
2013
2014
2015/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002016 * wpa_supplicant_set_debug_params - Set global debug params
2017 * @global: wpa_global structure
2018 * @debug_level: debug level
2019 * @debug_timestamp: determines if show timestamp in debug data
2020 * @debug_show_keys: determines if show keys in debug data
2021 * Returns: 0 if succeed or -1 if debug_level has wrong value
2022 */
2023int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2024 int debug_timestamp, int debug_show_keys)
2025{
2026
2027 int old_level, old_timestamp, old_show_keys;
2028
2029 /* check for allowed debuglevels */
2030 if (debug_level != MSG_EXCESSIVE &&
2031 debug_level != MSG_MSGDUMP &&
2032 debug_level != MSG_DEBUG &&
2033 debug_level != MSG_INFO &&
2034 debug_level != MSG_WARNING &&
2035 debug_level != MSG_ERROR)
2036 return -1;
2037
2038 old_level = wpa_debug_level;
2039 old_timestamp = wpa_debug_timestamp;
2040 old_show_keys = wpa_debug_show_keys;
2041
2042 wpa_debug_level = debug_level;
2043 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2044 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2045
2046 if (wpa_debug_level != old_level)
2047 wpas_notify_debug_level_changed(global);
2048 if (wpa_debug_timestamp != old_timestamp)
2049 wpas_notify_debug_timestamp_changed(global);
2050 if (wpa_debug_show_keys != old_show_keys)
2051 wpas_notify_debug_show_keys_changed(global);
2052
2053 return 0;
2054}
2055
2056
2057/**
2058 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2059 * @wpa_s: Pointer to wpa_supplicant data
2060 * Returns: A pointer to the current network structure or %NULL on failure
2061 */
2062struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2063{
2064 struct wpa_ssid *entry;
2065 u8 ssid[MAX_SSID_LEN];
2066 int res;
2067 size_t ssid_len;
2068 u8 bssid[ETH_ALEN];
2069 int wired;
2070
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002071 res = wpa_drv_get_ssid(wpa_s, ssid);
2072 if (res < 0) {
2073 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2074 "driver");
2075 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002076 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002077 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002078
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002079 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002080 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2081 "driver");
2082 return NULL;
2083 }
2084
2085 wired = wpa_s->conf->ap_scan == 0 &&
2086 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2087
2088 entry = wpa_s->conf->ssid;
2089 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002090 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002091 ((ssid_len == entry->ssid_len &&
2092 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2093 (!entry->bssid_set ||
2094 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2095 return entry;
2096#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002097 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002098 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2099 (entry->ssid == NULL || entry->ssid_len == 0) &&
2100 (!entry->bssid_set ||
2101 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2102 return entry;
2103#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002104
Dmitry Shmidt04949592012-07-19 12:16:46 -07002105 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002106 entry->ssid_len == 0 &&
2107 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2108 return entry;
2109
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002110 entry = entry->next;
2111 }
2112
2113 return NULL;
2114}
2115
2116
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002117static int select_driver(struct wpa_supplicant *wpa_s, int i)
2118{
2119 struct wpa_global *global = wpa_s->global;
2120
2121 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2122 global->drv_priv[i] = wpa_drivers[i]->global_init();
2123 if (global->drv_priv[i] == NULL) {
2124 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2125 "'%s'", wpa_drivers[i]->name);
2126 return -1;
2127 }
2128 }
2129
2130 wpa_s->driver = wpa_drivers[i];
2131 wpa_s->global_drv_priv = global->drv_priv[i];
2132
2133 return 0;
2134}
2135
2136
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002137static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2138 const char *name)
2139{
2140 int i;
2141 size_t len;
2142 const char *pos, *driver = name;
2143
2144 if (wpa_s == NULL)
2145 return -1;
2146
2147 if (wpa_drivers[0] == NULL) {
2148 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2149 "wpa_supplicant");
2150 return -1;
2151 }
2152
2153 if (name == NULL) {
2154 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002155 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002156 }
2157
2158 do {
2159 pos = os_strchr(driver, ',');
2160 if (pos)
2161 len = pos - driver;
2162 else
2163 len = os_strlen(driver);
2164
2165 for (i = 0; wpa_drivers[i]; i++) {
2166 if (os_strlen(wpa_drivers[i]->name) == len &&
2167 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002168 0) {
2169 /* First driver that succeeds wins */
2170 if (select_driver(wpa_s, i) == 0)
2171 return 0;
2172 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002173 }
2174
2175 driver = pos + 1;
2176 } while (pos);
2177
2178 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2179 return -1;
2180}
2181
2182
2183/**
2184 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2185 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2186 * with struct wpa_driver_ops::init()
2187 * @src_addr: Source address of the EAPOL frame
2188 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2189 * @len: Length of the EAPOL data
2190 *
2191 * This function is called for each received EAPOL frame. Most driver
2192 * interfaces rely on more generic OS mechanism for receiving frames through
2193 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2194 * take care of received EAPOL frames and deliver them to the core supplicant
2195 * code by calling this function.
2196 */
2197void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2198 const u8 *buf, size_t len)
2199{
2200 struct wpa_supplicant *wpa_s = ctx;
2201
2202 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2203 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2204
Jouni Malinena05074c2012-12-21 21:35:35 +02002205 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2206 (wpa_s->last_eapol_matches_bssid &&
2207#ifdef CONFIG_AP
2208 !wpa_s->ap_iface &&
2209#endif /* CONFIG_AP */
2210 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002211 /*
2212 * There is possible race condition between receiving the
2213 * association event and the EAPOL frame since they are coming
2214 * through different paths from the driver. In order to avoid
2215 * issues in trying to process the EAPOL frame before receiving
2216 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02002217 * the association event is received. This may also be needed in
2218 * driver-based roaming case, so also use src_addr != BSSID as a
2219 * trigger if we have previously confirmed that the
2220 * Authenticator uses BSSID as the src_addr (which is not the
2221 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002222 */
2223 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02002224 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2225 wpa_supplicant_state_txt(wpa_s->wpa_state),
2226 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002227 wpabuf_free(wpa_s->pending_eapol_rx);
2228 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2229 if (wpa_s->pending_eapol_rx) {
2230 os_get_time(&wpa_s->pending_eapol_rx_time);
2231 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2232 ETH_ALEN);
2233 }
2234 return;
2235 }
2236
Jouni Malinena05074c2012-12-21 21:35:35 +02002237 wpa_s->last_eapol_matches_bssid =
2238 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2239
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002240#ifdef CONFIG_AP
2241 if (wpa_s->ap_iface) {
2242 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2243 return;
2244 }
2245#endif /* CONFIG_AP */
2246
2247 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2248 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2249 "no key management is configured");
2250 return;
2251 }
2252
2253 if (wpa_s->eapol_received == 0 &&
2254 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2255 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2256 wpa_s->wpa_state != WPA_COMPLETED) &&
2257 (wpa_s->current_ssid == NULL ||
2258 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2259 /* Timeout for completing IEEE 802.1X and WPA authentication */
2260 wpa_supplicant_req_auth_timeout(
2261 wpa_s,
2262 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2263 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2264 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2265 70 : 10, 0);
2266 }
2267 wpa_s->eapol_received++;
2268
2269 if (wpa_s->countermeasures) {
2270 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2271 "EAPOL packet");
2272 return;
2273 }
2274
2275#ifdef CONFIG_IBSS_RSN
2276 if (wpa_s->current_ssid &&
2277 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2278 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2279 return;
2280 }
2281#endif /* CONFIG_IBSS_RSN */
2282
2283 /* Source address of the incoming EAPOL frame could be compared to the
2284 * current BSSID. However, it is possible that a centralized
2285 * Authenticator could be using another MAC address than the BSSID of
2286 * an AP, so just allow any address to be used for now. The replies are
2287 * still sent to the current BSSID (if available), though. */
2288
2289 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2290 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2291 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2292 return;
2293 wpa_drv_poll(wpa_s);
2294 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2295 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2296 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2297 /*
2298 * Set portValid = TRUE here since we are going to skip 4-way
2299 * handshake processing which would normally set portValid. We
2300 * need this to allow the EAPOL state machines to be completed
2301 * without going through EAPOL-Key handshake.
2302 */
2303 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2304 }
2305}
2306
2307
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002308int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002309{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002310 if (wpa_s->driver->send_eapol) {
2311 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2312 if (addr)
2313 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2314 } else if (!(wpa_s->drv_flags &
2315 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002316 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002317 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2318 wpa_drv_get_mac_addr(wpa_s),
2319 ETH_P_EAPOL,
2320 wpa_supplicant_rx_eapol, wpa_s, 0);
2321 if (wpa_s->l2 == NULL)
2322 return -1;
2323 } else {
2324 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2325 if (addr)
2326 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2327 }
2328
2329 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2330 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2331 return -1;
2332 }
2333
2334 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2335 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002336 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2337
2338 return 0;
2339}
2340
2341
Dmitry Shmidt04949592012-07-19 12:16:46 -07002342static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2343 const u8 *buf, size_t len)
2344{
2345 struct wpa_supplicant *wpa_s = ctx;
2346 const struct l2_ethhdr *eth;
2347
2348 if (len < sizeof(*eth))
2349 return;
2350 eth = (const struct l2_ethhdr *) buf;
2351
2352 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2353 !(eth->h_dest[0] & 0x01)) {
2354 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2355 " (bridge - not for this interface - ignore)",
2356 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2357 return;
2358 }
2359
2360 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2361 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2362 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2363 len - sizeof(*eth));
2364}
2365
2366
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002367/**
2368 * wpa_supplicant_driver_init - Initialize driver interface parameters
2369 * @wpa_s: Pointer to wpa_supplicant data
2370 * Returns: 0 on success, -1 on failure
2371 *
2372 * This function is called to initialize driver interface parameters.
2373 * wpa_drv_init() must have been called before this function to initialize the
2374 * driver interface.
2375 */
2376int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2377{
2378 static int interface_count = 0;
2379
2380 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2381 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002382
2383 if (wpa_s->bridge_ifname[0]) {
2384 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2385 "interface '%s'", wpa_s->bridge_ifname);
2386 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2387 wpa_s->own_addr,
2388 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002389 wpa_supplicant_rx_eapol_bridge,
2390 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002391 if (wpa_s->l2_br == NULL) {
2392 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2393 "connection for the bridge interface '%s'",
2394 wpa_s->bridge_ifname);
2395 return -1;
2396 }
2397 }
2398
2399 wpa_clear_keys(wpa_s, NULL);
2400
2401 /* Make sure that TKIP countermeasures are not left enabled (could
2402 * happen if wpa_supplicant is killed during countermeasures. */
2403 wpa_drv_set_countermeasures(wpa_s, 0);
2404
2405 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2406 wpa_drv_flush_pmkid(wpa_s);
2407
2408 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002409 wpa_s->prev_scan_wildcard = 0;
2410
Dmitry Shmidt04949592012-07-19 12:16:46 -07002411 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002412 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2413 100000))
2414 wpa_supplicant_req_scan(wpa_s, interface_count,
2415 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002416 interface_count++;
2417 } else
2418 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2419
2420 return 0;
2421}
2422
2423
2424static int wpa_supplicant_daemon(const char *pid_file)
2425{
2426 wpa_printf(MSG_DEBUG, "Daemonize..");
2427 return os_daemonize(pid_file);
2428}
2429
2430
2431static struct wpa_supplicant * wpa_supplicant_alloc(void)
2432{
2433 struct wpa_supplicant *wpa_s;
2434
2435 wpa_s = os_zalloc(sizeof(*wpa_s));
2436 if (wpa_s == NULL)
2437 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002438 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002439 wpa_s->scan_interval = 5;
2440 wpa_s->new_connection = 1;
2441 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002442 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002443
2444 return wpa_s;
2445}
2446
2447
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002448#ifdef CONFIG_HT_OVERRIDES
2449
2450static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2451 struct ieee80211_ht_capabilities *htcaps,
2452 struct ieee80211_ht_capabilities *htcaps_mask,
2453 const char *ht_mcs)
2454{
2455 /* parse ht_mcs into hex array */
2456 int i;
2457 const char *tmp = ht_mcs;
2458 char *end = NULL;
2459
2460 /* If ht_mcs is null, do not set anything */
2461 if (!ht_mcs)
2462 return 0;
2463
2464 /* This is what we are setting in the kernel */
2465 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2466
2467 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2468
2469 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2470 errno = 0;
2471 long v = strtol(tmp, &end, 16);
2472 if (errno == 0) {
2473 wpa_msg(wpa_s, MSG_DEBUG,
2474 "htcap value[%i]: %ld end: %p tmp: %p",
2475 i, v, end, tmp);
2476 if (end == tmp)
2477 break;
2478
2479 htcaps->supported_mcs_set[i] = v;
2480 tmp = end;
2481 } else {
2482 wpa_msg(wpa_s, MSG_ERROR,
2483 "Failed to parse ht-mcs: %s, error: %s\n",
2484 ht_mcs, strerror(errno));
2485 return -1;
2486 }
2487 }
2488
2489 /*
2490 * If we were able to parse any values, then set mask for the MCS set.
2491 */
2492 if (i) {
2493 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2494 IEEE80211_HT_MCS_MASK_LEN - 1);
2495 /* skip the 3 reserved bits */
2496 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2497 0x1f;
2498 }
2499
2500 return 0;
2501}
2502
2503
2504static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2505 struct ieee80211_ht_capabilities *htcaps,
2506 struct ieee80211_ht_capabilities *htcaps_mask,
2507 int disabled)
2508{
2509 u16 msk;
2510
2511 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2512
2513 if (disabled == -1)
2514 return 0;
2515
2516 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2517 htcaps_mask->ht_capabilities_info |= msk;
2518 if (disabled)
2519 htcaps->ht_capabilities_info &= msk;
2520 else
2521 htcaps->ht_capabilities_info |= msk;
2522
2523 return 0;
2524}
2525
2526
2527static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2528 struct ieee80211_ht_capabilities *htcaps,
2529 struct ieee80211_ht_capabilities *htcaps_mask,
2530 int factor)
2531{
2532 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2533
2534 if (factor == -1)
2535 return 0;
2536
2537 if (factor < 0 || factor > 3) {
2538 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2539 "Must be 0-3 or -1", factor);
2540 return -EINVAL;
2541 }
2542
2543 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2544 htcaps->a_mpdu_params &= ~0x3;
2545 htcaps->a_mpdu_params |= factor & 0x3;
2546
2547 return 0;
2548}
2549
2550
2551static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2552 struct ieee80211_ht_capabilities *htcaps,
2553 struct ieee80211_ht_capabilities *htcaps_mask,
2554 int density)
2555{
2556 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2557
2558 if (density == -1)
2559 return 0;
2560
2561 if (density < 0 || density > 7) {
2562 wpa_msg(wpa_s, MSG_ERROR,
2563 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2564 density);
2565 return -EINVAL;
2566 }
2567
2568 htcaps_mask->a_mpdu_params |= 0x1C;
2569 htcaps->a_mpdu_params &= ~(0x1C);
2570 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2571
2572 return 0;
2573}
2574
2575
2576static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2577 struct ieee80211_ht_capabilities *htcaps,
2578 struct ieee80211_ht_capabilities *htcaps_mask,
2579 int disabled)
2580{
2581 /* Masking these out disables HT40 */
2582 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2583 HT_CAP_INFO_SHORT_GI40MHZ);
2584
2585 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2586
2587 if (disabled)
2588 htcaps->ht_capabilities_info &= ~msk;
2589 else
2590 htcaps->ht_capabilities_info |= msk;
2591
2592 htcaps_mask->ht_capabilities_info |= msk;
2593
2594 return 0;
2595}
2596
2597
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002598static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2599 struct ieee80211_ht_capabilities *htcaps,
2600 struct ieee80211_ht_capabilities *htcaps_mask,
2601 int disabled)
2602{
2603 /* Masking these out disables SGI */
2604 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2605 HT_CAP_INFO_SHORT_GI40MHZ);
2606
2607 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2608
2609 if (disabled)
2610 htcaps->ht_capabilities_info &= ~msk;
2611 else
2612 htcaps->ht_capabilities_info |= msk;
2613
2614 htcaps_mask->ht_capabilities_info |= msk;
2615
2616 return 0;
2617}
2618
2619
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002620void wpa_supplicant_apply_ht_overrides(
2621 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2622 struct wpa_driver_associate_params *params)
2623{
2624 struct ieee80211_ht_capabilities *htcaps;
2625 struct ieee80211_ht_capabilities *htcaps_mask;
2626
2627 if (!ssid)
2628 return;
2629
2630 params->disable_ht = ssid->disable_ht;
2631 if (!params->htcaps || !params->htcaps_mask)
2632 return;
2633
2634 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2635 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2636 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2637 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2638 ssid->disable_max_amsdu);
2639 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2640 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2641 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002642 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002643}
2644
2645#endif /* CONFIG_HT_OVERRIDES */
2646
2647
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002648#ifdef CONFIG_VHT_OVERRIDES
2649void wpa_supplicant_apply_vht_overrides(
2650 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2651 struct wpa_driver_associate_params *params)
2652{
2653 struct ieee80211_vht_capabilities *vhtcaps;
2654 struct ieee80211_vht_capabilities *vhtcaps_mask;
2655
2656 if (!ssid)
2657 return;
2658
2659 params->disable_vht = ssid->disable_vht;
2660
2661 vhtcaps = (void *) params->vhtcaps;
2662 vhtcaps_mask = (void *) params->vhtcaps_mask;
2663
2664 if (!vhtcaps || !vhtcaps_mask)
2665 return;
2666
2667 vhtcaps->vht_capabilities_info = ssid->vht_capa;
2668 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
2669
2670#define OVERRIDE_MCS(i) \
2671 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
2672 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
2673 3 << 2 * (i - 1); \
2674 vhtcaps->vht_supported_mcs_set.tx_map |= \
2675 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
2676 } \
2677 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
2678 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
2679 3 << 2 * (i - 1); \
2680 vhtcaps->vht_supported_mcs_set.rx_map |= \
2681 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
2682 }
2683
2684 OVERRIDE_MCS(1);
2685 OVERRIDE_MCS(2);
2686 OVERRIDE_MCS(3);
2687 OVERRIDE_MCS(4);
2688 OVERRIDE_MCS(5);
2689 OVERRIDE_MCS(6);
2690 OVERRIDE_MCS(7);
2691 OVERRIDE_MCS(8);
2692}
2693#endif /* CONFIG_VHT_OVERRIDES */
2694
2695
Dmitry Shmidt04949592012-07-19 12:16:46 -07002696static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2697{
2698#ifdef PCSC_FUNCS
2699 size_t len;
2700
2701 if (!wpa_s->conf->pcsc_reader)
2702 return 0;
2703
2704 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2705 if (!wpa_s->scard)
2706 return 1;
2707
2708 if (wpa_s->conf->pcsc_pin &&
2709 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2710 scard_deinit(wpa_s->scard);
2711 wpa_s->scard = NULL;
2712 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2713 return -1;
2714 }
2715
2716 len = sizeof(wpa_s->imsi) - 1;
2717 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2718 scard_deinit(wpa_s->scard);
2719 wpa_s->scard = NULL;
2720 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2721 return -1;
2722 }
2723 wpa_s->imsi[len] = '\0';
2724
2725 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2726
2727 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2728 wpa_s->imsi, wpa_s->mnc_len);
2729
2730 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2731 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2732#endif /* PCSC_FUNCS */
2733
2734 return 0;
2735}
2736
2737
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002738int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2739{
2740 char *val, *pos;
2741
2742 ext_password_deinit(wpa_s->ext_pw);
2743 wpa_s->ext_pw = NULL;
2744 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2745
2746 if (!wpa_s->conf->ext_password_backend)
2747 return 0;
2748
2749 val = os_strdup(wpa_s->conf->ext_password_backend);
2750 if (val == NULL)
2751 return -1;
2752 pos = os_strchr(val, ':');
2753 if (pos)
2754 *pos++ = '\0';
2755
2756 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2757
2758 wpa_s->ext_pw = ext_password_init(val, pos);
2759 os_free(val);
2760 if (wpa_s->ext_pw == NULL) {
2761 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2762 return -1;
2763 }
2764 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2765
2766 return 0;
2767}
2768
2769
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002770static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2771 struct wpa_interface *iface)
2772{
2773 const char *ifname, *driver;
2774 struct wpa_driver_capa capa;
2775
2776 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2777 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2778 iface->confname ? iface->confname : "N/A",
2779 iface->driver ? iface->driver : "default",
2780 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2781 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2782
2783 if (iface->confname) {
2784#ifdef CONFIG_BACKEND_FILE
2785 wpa_s->confname = os_rel2abs_path(iface->confname);
2786 if (wpa_s->confname == NULL) {
2787 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2788 "for configuration file '%s'.",
2789 iface->confname);
2790 return -1;
2791 }
2792 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2793 iface->confname, wpa_s->confname);
2794#else /* CONFIG_BACKEND_FILE */
2795 wpa_s->confname = os_strdup(iface->confname);
2796#endif /* CONFIG_BACKEND_FILE */
2797 wpa_s->conf = wpa_config_read(wpa_s->confname);
2798 if (wpa_s->conf == NULL) {
2799 wpa_printf(MSG_ERROR, "Failed to read or parse "
2800 "configuration '%s'.", wpa_s->confname);
2801 return -1;
2802 }
2803
2804 /*
2805 * Override ctrl_interface and driver_param if set on command
2806 * line.
2807 */
2808 if (iface->ctrl_interface) {
2809 os_free(wpa_s->conf->ctrl_interface);
2810 wpa_s->conf->ctrl_interface =
2811 os_strdup(iface->ctrl_interface);
2812 }
2813
2814 if (iface->driver_param) {
2815 os_free(wpa_s->conf->driver_param);
2816 wpa_s->conf->driver_param =
2817 os_strdup(iface->driver_param);
2818 }
2819 } else
2820 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2821 iface->driver_param);
2822
2823 if (wpa_s->conf == NULL) {
2824 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2825 return -1;
2826 }
2827
2828 if (iface->ifname == NULL) {
2829 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2830 return -1;
2831 }
2832 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2833 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2834 iface->ifname);
2835 return -1;
2836 }
2837 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2838
2839 if (iface->bridge_ifname) {
2840 if (os_strlen(iface->bridge_ifname) >=
2841 sizeof(wpa_s->bridge_ifname)) {
2842 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2843 "name '%s'.", iface->bridge_ifname);
2844 return -1;
2845 }
2846 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2847 sizeof(wpa_s->bridge_ifname));
2848 }
2849
2850 /* RSNA Supplicant Key Management - INITIALIZE */
2851 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2852 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2853
2854 /* Initialize driver interface and register driver event handler before
2855 * L2 receive handler so that association events are processed before
2856 * EAPOL-Key packets if both become available for the same select()
2857 * call. */
2858 driver = iface->driver;
2859next_driver:
2860 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2861 return -1;
2862
2863 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2864 if (wpa_s->drv_priv == NULL) {
2865 const char *pos;
2866 pos = driver ? os_strchr(driver, ',') : NULL;
2867 if (pos) {
2868 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2869 "driver interface - try next driver wrapper");
2870 driver = pos + 1;
2871 goto next_driver;
2872 }
2873 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2874 "interface");
2875 return -1;
2876 }
2877 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2878 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2879 "driver_param '%s'", wpa_s->conf->driver_param);
2880 return -1;
2881 }
2882
2883 ifname = wpa_drv_get_ifname(wpa_s);
2884 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2885 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2886 "interface name with '%s'", ifname);
2887 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2888 }
2889
2890 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2891 return -1;
2892
2893 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2894 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2895 NULL);
2896 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2897
2898 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2899 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2900 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2901 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2902 "dot11RSNAConfigPMKLifetime");
2903 return -1;
2904 }
2905
2906 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2907 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2908 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2909 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2910 "dot11RSNAConfigPMKReauthThreshold");
2911 return -1;
2912 }
2913
2914 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2915 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2916 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2917 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2918 "dot11RSNAConfigSATimeout");
2919 return -1;
2920 }
2921
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002922 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2923 &wpa_s->hw.num_modes,
2924 &wpa_s->hw.flags);
2925
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002926 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002927 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002928 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002929 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002930 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002931 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002932 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2933 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2934 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002935 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2936 wpa_s->max_stations = capa.max_stations;
2937 }
2938 if (wpa_s->max_remain_on_chan == 0)
2939 wpa_s->max_remain_on_chan = 1000;
2940
2941 if (wpa_supplicant_driver_init(wpa_s) < 0)
2942 return -1;
2943
2944#ifdef CONFIG_TDLS
2945 if (wpa_tdls_init(wpa_s->wpa))
2946 return -1;
2947#endif /* CONFIG_TDLS */
2948
2949 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2950 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2951 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2952 return -1;
2953 }
2954
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002955 if (wpas_wps_init(wpa_s))
2956 return -1;
2957
2958 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2959 return -1;
2960 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2961
2962 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2963 if (wpa_s->ctrl_iface == NULL) {
2964 wpa_printf(MSG_ERROR,
2965 "Failed to initialize control interface '%s'.\n"
2966 "You may have another wpa_supplicant process "
2967 "already running or the file was\n"
2968 "left by an unclean termination of wpa_supplicant "
2969 "in which case you will need\n"
2970 "to manually remove this file before starting "
2971 "wpa_supplicant again.\n",
2972 wpa_s->conf->ctrl_interface);
2973 return -1;
2974 }
2975
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002976 wpa_s->gas = gas_query_init(wpa_s);
2977 if (wpa_s->gas == NULL) {
2978 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
2979 return -1;
2980 }
2981
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002982#ifdef CONFIG_P2P
2983 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
2984 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
2985 return -1;
2986 }
2987#endif /* CONFIG_P2P */
2988
2989 if (wpa_bss_init(wpa_s) < 0)
2990 return -1;
2991
Dmitry Shmidt04949592012-07-19 12:16:46 -07002992 if (pcsc_reader_init(wpa_s) < 0)
2993 return -1;
2994
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002995 if (wpas_init_ext_pw(wpa_s) < 0)
2996 return -1;
2997
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002998 return 0;
2999}
3000
3001
3002static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003003 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003004{
3005 if (wpa_s->drv_priv) {
3006 wpa_supplicant_deauthenticate(wpa_s,
3007 WLAN_REASON_DEAUTH_LEAVING);
3008
3009 wpa_drv_set_countermeasures(wpa_s, 0);
3010 wpa_clear_keys(wpa_s, NULL);
3011 }
3012
3013 wpa_supplicant_cleanup(wpa_s);
3014
Dmitry Shmidt04949592012-07-19 12:16:46 -07003015#ifdef CONFIG_P2P
3016 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
3017 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
3018 "the management interface is being removed");
3019 wpas_p2p_deinit_global(wpa_s->global);
3020 }
3021#endif /* CONFIG_P2P */
3022
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003023 if (wpa_s->drv_priv)
3024 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003025
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003026 if (notify)
3027 wpas_notify_iface_removed(wpa_s);
3028
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003029 if (terminate)
3030 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003031
3032 if (wpa_s->ctrl_iface) {
3033 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3034 wpa_s->ctrl_iface = NULL;
3035 }
3036
3037 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07003038 wpa_config_free(wpa_s->conf);
3039 wpa_s->conf = NULL;
3040 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003041}
3042
3043
3044/**
3045 * wpa_supplicant_add_iface - Add a new network interface
3046 * @global: Pointer to global data from wpa_supplicant_init()
3047 * @iface: Interface configuration options
3048 * Returns: Pointer to the created interface or %NULL on failure
3049 *
3050 * This function is used to add new network interfaces for %wpa_supplicant.
3051 * This can be called before wpa_supplicant_run() to add interfaces before the
3052 * main event loop has been started. In addition, new interfaces can be added
3053 * dynamically while %wpa_supplicant is already running. This could happen,
3054 * e.g., when a hotplug network adapter is inserted.
3055 */
3056struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3057 struct wpa_interface *iface)
3058{
3059 struct wpa_supplicant *wpa_s;
3060 struct wpa_interface t_iface;
3061 struct wpa_ssid *ssid;
3062
3063 if (global == NULL || iface == NULL)
3064 return NULL;
3065
3066 wpa_s = wpa_supplicant_alloc();
3067 if (wpa_s == NULL)
3068 return NULL;
3069
3070 wpa_s->global = global;
3071
3072 t_iface = *iface;
3073 if (global->params.override_driver) {
3074 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3075 "('%s' -> '%s')",
3076 iface->driver, global->params.override_driver);
3077 t_iface.driver = global->params.override_driver;
3078 }
3079 if (global->params.override_ctrl_interface) {
3080 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3081 "ctrl_interface ('%s' -> '%s')",
3082 iface->ctrl_interface,
3083 global->params.override_ctrl_interface);
3084 t_iface.ctrl_interface =
3085 global->params.override_ctrl_interface;
3086 }
3087 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
3088 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3089 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003090 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003091 os_free(wpa_s);
3092 return NULL;
3093 }
3094
3095 /* Notify the control interfaces about new iface */
3096 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003097 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003098 os_free(wpa_s);
3099 return NULL;
3100 }
3101
3102 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3103 wpas_notify_network_added(wpa_s, ssid);
3104
3105 wpa_s->next = global->ifaces;
3106 global->ifaces = wpa_s;
3107
3108 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003109 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003110
3111 return wpa_s;
3112}
3113
3114
3115/**
3116 * wpa_supplicant_remove_iface - Remove a network interface
3117 * @global: Pointer to global data from wpa_supplicant_init()
3118 * @wpa_s: Pointer to the network interface to be removed
3119 * Returns: 0 if interface was removed, -1 if interface was not found
3120 *
3121 * This function can be used to dynamically remove network interfaces from
3122 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3123 * addition, this function is used to remove all remaining interfaces when
3124 * %wpa_supplicant is terminated.
3125 */
3126int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003127 struct wpa_supplicant *wpa_s,
3128 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003129{
3130 struct wpa_supplicant *prev;
3131
3132 /* Remove interface from the global list of interfaces */
3133 prev = global->ifaces;
3134 if (prev == wpa_s) {
3135 global->ifaces = wpa_s->next;
3136 } else {
3137 while (prev && prev->next != wpa_s)
3138 prev = prev->next;
3139 if (prev == NULL)
3140 return -1;
3141 prev->next = wpa_s->next;
3142 }
3143
3144 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3145
3146 if (global->p2p_group_formation == wpa_s)
3147 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07003148 if (global->p2p_invite_group == wpa_s)
3149 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003150 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003151 os_free(wpa_s);
3152
3153 return 0;
3154}
3155
3156
3157/**
3158 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3159 * @wpa_s: Pointer to the network interface
3160 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3161 */
3162const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3163{
3164 const char *eapol_method;
3165
3166 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3167 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3168 return "NO-EAP";
3169 }
3170
3171 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3172 if (eapol_method == NULL)
3173 return "UNKNOWN-EAP";
3174
3175 return eapol_method;
3176}
3177
3178
3179/**
3180 * wpa_supplicant_get_iface - Get a new network interface
3181 * @global: Pointer to global data from wpa_supplicant_init()
3182 * @ifname: Interface name
3183 * Returns: Pointer to the interface or %NULL if not found
3184 */
3185struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3186 const char *ifname)
3187{
3188 struct wpa_supplicant *wpa_s;
3189
3190 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3191 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3192 return wpa_s;
3193 }
3194 return NULL;
3195}
3196
3197
3198#ifndef CONFIG_NO_WPA_MSG
3199static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3200{
3201 struct wpa_supplicant *wpa_s = ctx;
3202 if (wpa_s == NULL)
3203 return NULL;
3204 return wpa_s->ifname;
3205}
3206#endif /* CONFIG_NO_WPA_MSG */
3207
3208
3209/**
3210 * wpa_supplicant_init - Initialize %wpa_supplicant
3211 * @params: Parameters for %wpa_supplicant
3212 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3213 *
3214 * This function is used to initialize %wpa_supplicant. After successful
3215 * initialization, the returned data pointer can be used to add and remove
3216 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3217 */
3218struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3219{
3220 struct wpa_global *global;
3221 int ret, i;
3222
3223 if (params == NULL)
3224 return NULL;
3225
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003226#ifdef CONFIG_DRIVER_NDIS
3227 {
3228 void driver_ndis_init_ops(void);
3229 driver_ndis_init_ops();
3230 }
3231#endif /* CONFIG_DRIVER_NDIS */
3232
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003233#ifndef CONFIG_NO_WPA_MSG
3234 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3235#endif /* CONFIG_NO_WPA_MSG */
3236
3237 wpa_debug_open_file(params->wpa_debug_file_path);
3238 if (params->wpa_debug_syslog)
3239 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003240 if (params->wpa_debug_tracing) {
3241 ret = wpa_debug_open_linux_tracing();
3242 if (ret) {
3243 wpa_printf(MSG_ERROR,
3244 "Failed to enable trace logging");
3245 return NULL;
3246 }
3247 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003248
3249 ret = eap_register_methods();
3250 if (ret) {
3251 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3252 if (ret == -2)
3253 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3254 "the same EAP type.");
3255 return NULL;
3256 }
3257
3258 global = os_zalloc(sizeof(*global));
3259 if (global == NULL)
3260 return NULL;
3261 dl_list_init(&global->p2p_srv_bonjour);
3262 dl_list_init(&global->p2p_srv_upnp);
3263 global->params.daemonize = params->daemonize;
3264 global->params.wait_for_monitor = params->wait_for_monitor;
3265 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3266 if (params->pid_file)
3267 global->params.pid_file = os_strdup(params->pid_file);
3268 if (params->ctrl_interface)
3269 global->params.ctrl_interface =
3270 os_strdup(params->ctrl_interface);
3271 if (params->override_driver)
3272 global->params.override_driver =
3273 os_strdup(params->override_driver);
3274 if (params->override_ctrl_interface)
3275 global->params.override_ctrl_interface =
3276 os_strdup(params->override_ctrl_interface);
3277 wpa_debug_level = global->params.wpa_debug_level =
3278 params->wpa_debug_level;
3279 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3280 params->wpa_debug_show_keys;
3281 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3282 params->wpa_debug_timestamp;
3283
3284 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3285
3286 if (eloop_init()) {
3287 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3288 wpa_supplicant_deinit(global);
3289 return NULL;
3290 }
3291
Jouni Malinen75ecf522011-06-27 15:19:46 -07003292 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003293
3294 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3295 if (global->ctrl_iface == NULL) {
3296 wpa_supplicant_deinit(global);
3297 return NULL;
3298 }
3299
3300 if (wpas_notify_supplicant_initialized(global)) {
3301 wpa_supplicant_deinit(global);
3302 return NULL;
3303 }
3304
3305 for (i = 0; wpa_drivers[i]; i++)
3306 global->drv_count++;
3307 if (global->drv_count == 0) {
3308 wpa_printf(MSG_ERROR, "No drivers enabled");
3309 wpa_supplicant_deinit(global);
3310 return NULL;
3311 }
3312 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3313 if (global->drv_priv == NULL) {
3314 wpa_supplicant_deinit(global);
3315 return NULL;
3316 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003317
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003318#ifdef CONFIG_WIFI_DISPLAY
3319 if (wifi_display_init(global) < 0) {
3320 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3321 wpa_supplicant_deinit(global);
3322 return NULL;
3323 }
3324#endif /* CONFIG_WIFI_DISPLAY */
3325
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003326 return global;
3327}
3328
3329
3330/**
3331 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3332 * @global: Pointer to global data from wpa_supplicant_init()
3333 * Returns: 0 after successful event loop run, -1 on failure
3334 *
3335 * This function starts the main event loop and continues running as long as
3336 * there are any remaining events. In most cases, this function is running as
3337 * long as the %wpa_supplicant process in still in use.
3338 */
3339int wpa_supplicant_run(struct wpa_global *global)
3340{
3341 struct wpa_supplicant *wpa_s;
3342
3343 if (global->params.daemonize &&
3344 wpa_supplicant_daemon(global->params.pid_file))
3345 return -1;
3346
3347 if (global->params.wait_for_monitor) {
3348 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3349 if (wpa_s->ctrl_iface)
3350 wpa_supplicant_ctrl_iface_wait(
3351 wpa_s->ctrl_iface);
3352 }
3353
3354 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3355 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3356
3357 eloop_run();
3358
3359 return 0;
3360}
3361
3362
3363/**
3364 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3365 * @global: Pointer to global data from wpa_supplicant_init()
3366 *
3367 * This function is called to deinitialize %wpa_supplicant and to free all
3368 * allocated resources. Remaining network interfaces will also be removed.
3369 */
3370void wpa_supplicant_deinit(struct wpa_global *global)
3371{
3372 int i;
3373
3374 if (global == NULL)
3375 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003376
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003377#ifdef CONFIG_WIFI_DISPLAY
3378 wifi_display_deinit(global);
3379#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003380#ifdef CONFIG_P2P
3381 wpas_p2p_deinit_global(global);
3382#endif /* CONFIG_P2P */
3383
3384 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003385 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003386
3387 if (global->ctrl_iface)
3388 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3389
3390 wpas_notify_supplicant_deinitialized(global);
3391
3392 eap_peer_unregister_methods();
3393#ifdef CONFIG_AP
3394 eap_server_unregister_methods();
3395#endif /* CONFIG_AP */
3396
3397 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3398 if (!global->drv_priv[i])
3399 continue;
3400 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3401 }
3402 os_free(global->drv_priv);
3403
3404 random_deinit();
3405
3406 eloop_destroy();
3407
3408 if (global->params.pid_file) {
3409 os_daemonize_terminate(global->params.pid_file);
3410 os_free(global->params.pid_file);
3411 }
3412 os_free(global->params.ctrl_interface);
3413 os_free(global->params.override_driver);
3414 os_free(global->params.override_ctrl_interface);
3415
Dmitry Shmidt04949592012-07-19 12:16:46 -07003416 os_free(global->p2p_disallow_freq);
3417
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003418 os_free(global);
3419 wpa_debug_close_syslog();
3420 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003421 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003422}
3423
3424
3425void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3426{
3427 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3428 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3429 char country[3];
3430 country[0] = wpa_s->conf->country[0];
3431 country[1] = wpa_s->conf->country[1];
3432 country[2] = '\0';
3433 if (wpa_drv_set_country(wpa_s, country) < 0) {
3434 wpa_printf(MSG_ERROR, "Failed to set country code "
3435 "'%s'", country);
3436 }
3437 }
3438
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003439 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3440 wpas_init_ext_pw(wpa_s);
3441
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003442#ifdef CONFIG_WPS
3443 wpas_wps_update_config(wpa_s);
3444#endif /* CONFIG_WPS */
3445
3446#ifdef CONFIG_P2P
3447 wpas_p2p_update_config(wpa_s);
3448#endif /* CONFIG_P2P */
3449
3450 wpa_s->conf->changed_parameters = 0;
3451}
3452
3453
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003454static void add_freq(int *freqs, int *num_freqs, int freq)
3455{
3456 int i;
3457
3458 for (i = 0; i < *num_freqs; i++) {
3459 if (freqs[i] == freq)
3460 return;
3461 }
3462
3463 freqs[*num_freqs] = freq;
3464 (*num_freqs)++;
3465}
3466
3467
3468static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3469{
3470 struct wpa_bss *bss, *cbss;
3471 const int max_freqs = 10;
3472 int *freqs;
3473 int num_freqs = 0;
3474
3475 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3476 if (freqs == NULL)
3477 return NULL;
3478
3479 cbss = wpa_s->current_bss;
3480
3481 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3482 if (bss == cbss)
3483 continue;
3484 if (bss->ssid_len == cbss->ssid_len &&
3485 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3486 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3487 add_freq(freqs, &num_freqs, bss->freq);
3488 if (num_freqs == max_freqs)
3489 break;
3490 }
3491 }
3492
3493 if (num_freqs == 0) {
3494 os_free(freqs);
3495 freqs = NULL;
3496 }
3497
3498 return freqs;
3499}
3500
3501
3502void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3503{
3504 int timeout;
3505 int count;
3506 int *freqs = NULL;
3507
3508 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003509 * Remove possible authentication timeout since the connection failed.
3510 */
3511 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3512
3513 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003514 * Add the failed BSSID into the blacklist and speed up next scan
3515 * attempt if there could be other APs that could accept association.
3516 * The current blacklist count indicates how many times we have tried
3517 * connecting to this AP and multiple attempts mean that other APs are
3518 * either not available or has already been tried, so that we can start
3519 * increasing the delay here to avoid constant scanning.
3520 */
3521 count = wpa_blacklist_add(wpa_s, bssid);
3522 if (count == 1 && wpa_s->current_bss) {
3523 /*
3524 * This BSS was not in the blacklist before. If there is
3525 * another BSS available for the same ESS, we should try that
3526 * next. Otherwise, we may as well try this one once more
3527 * before allowing other, likely worse, ESSes to be considered.
3528 */
3529 freqs = get_bss_freqs_in_ess(wpa_s);
3530 if (freqs) {
3531 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3532 "has been seen; try it next");
3533 wpa_blacklist_add(wpa_s, bssid);
3534 /*
3535 * On the next scan, go through only the known channels
3536 * used in this ESS based on previous scans to speed up
3537 * common load balancing use case.
3538 */
3539 os_free(wpa_s->next_scan_freqs);
3540 wpa_s->next_scan_freqs = freqs;
3541 }
3542 }
3543
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003544 /*
3545 * Add previous failure count in case the temporary blacklist was
3546 * cleared due to no other BSSes being available.
3547 */
3548 count += wpa_s->extra_blacklist_count;
3549
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003550 switch (count) {
3551 case 1:
3552 timeout = 100;
3553 break;
3554 case 2:
3555 timeout = 500;
3556 break;
3557 case 3:
3558 timeout = 1000;
3559 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003560 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003561 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003562 break;
3563 default:
3564 timeout = 10000;
3565 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003566 }
3567
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003568 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3569 "ms", count, timeout);
3570
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003571 /*
3572 * TODO: if more than one possible AP is available in scan results,
3573 * could try the other ones before requesting a new scan.
3574 */
3575 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3576 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003577
3578#ifdef CONFIG_P2P
Jouni Malinendc7b7132012-09-14 12:53:47 -07003579 if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003580 wpa_s->global->p2p != NULL) {
Jouni Malinendc7b7132012-09-14 12:53:47 -07003581 wpa_s->global->p2p_cb_on_scan_complete = 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003582 if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
3583 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
3584 "continued after failed association");
3585 }
3586 }
3587#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003588}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003589
3590
3591int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3592{
3593 return wpa_s->conf->ap_scan == 2 ||
3594 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3595}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003596
Dmitry Shmidt04949592012-07-19 12:16:46 -07003597
3598#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3599int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3600 struct wpa_ssid *ssid,
3601 const char *field,
3602 const char *value)
3603{
3604#ifdef IEEE8021X_EAPOL
3605 struct eap_peer_config *eap = &ssid->eap;
3606
3607 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3608 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3609 (const u8 *) value, os_strlen(value));
3610
3611 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3612 case WPA_CTRL_REQ_EAP_IDENTITY:
3613 os_free(eap->identity);
3614 eap->identity = (u8 *) os_strdup(value);
3615 eap->identity_len = os_strlen(value);
3616 eap->pending_req_identity = 0;
3617 if (ssid == wpa_s->current_ssid)
3618 wpa_s->reassociate = 1;
3619 break;
3620 case WPA_CTRL_REQ_EAP_PASSWORD:
3621 os_free(eap->password);
3622 eap->password = (u8 *) os_strdup(value);
3623 eap->password_len = os_strlen(value);
3624 eap->pending_req_password = 0;
3625 if (ssid == wpa_s->current_ssid)
3626 wpa_s->reassociate = 1;
3627 break;
3628 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3629 os_free(eap->new_password);
3630 eap->new_password = (u8 *) os_strdup(value);
3631 eap->new_password_len = os_strlen(value);
3632 eap->pending_req_new_password = 0;
3633 if (ssid == wpa_s->current_ssid)
3634 wpa_s->reassociate = 1;
3635 break;
3636 case WPA_CTRL_REQ_EAP_PIN:
3637 os_free(eap->pin);
3638 eap->pin = os_strdup(value);
3639 eap->pending_req_pin = 0;
3640 if (ssid == wpa_s->current_ssid)
3641 wpa_s->reassociate = 1;
3642 break;
3643 case WPA_CTRL_REQ_EAP_OTP:
3644 os_free(eap->otp);
3645 eap->otp = (u8 *) os_strdup(value);
3646 eap->otp_len = os_strlen(value);
3647 os_free(eap->pending_req_otp);
3648 eap->pending_req_otp = NULL;
3649 eap->pending_req_otp_len = 0;
3650 break;
3651 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3652 os_free(eap->private_key_passwd);
3653 eap->private_key_passwd = (u8 *) os_strdup(value);
3654 eap->pending_req_passphrase = 0;
3655 if (ssid == wpa_s->current_ssid)
3656 wpa_s->reassociate = 1;
3657 break;
3658 default:
3659 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3660 return -1;
3661 }
3662
3663 return 0;
3664#else /* IEEE8021X_EAPOL */
3665 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3666 return -1;
3667#endif /* IEEE8021X_EAPOL */
3668}
3669#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3670
3671
3672int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3673{
3674 int i;
3675 unsigned int drv_enc;
3676
3677 if (ssid == NULL)
3678 return 1;
3679
3680 if (ssid->disabled)
3681 return 1;
3682
3683 if (wpa_s && wpa_s->drv_capa_known)
3684 drv_enc = wpa_s->drv_enc;
3685 else
3686 drv_enc = (unsigned int) -1;
3687
3688 for (i = 0; i < NUM_WEP_KEYS; i++) {
3689 size_t len = ssid->wep_key_len[i];
3690 if (len == 0)
3691 continue;
3692 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3693 continue;
3694 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3695 continue;
3696 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3697 continue;
3698 return 1; /* invalid WEP key */
3699 }
3700
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003701 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3702 !ssid->ext_psk)
3703 return 1;
3704
Dmitry Shmidt04949592012-07-19 12:16:46 -07003705 return 0;
3706}
3707
3708
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003709int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003710{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003711 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003712 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003713 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003714 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003715 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003716}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003717
3718
3719void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3720{
3721 struct wpa_ssid *ssid = wpa_s->current_ssid;
3722 int dur;
3723 struct os_time now;
3724
3725 if (ssid == NULL) {
3726 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3727 "SSID block");
3728 return;
3729 }
3730
3731 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3732 return;
3733
3734 ssid->auth_failures++;
3735 if (ssid->auth_failures > 50)
3736 dur = 300;
3737 else if (ssid->auth_failures > 20)
3738 dur = 120;
3739 else if (ssid->auth_failures > 10)
3740 dur = 60;
3741 else if (ssid->auth_failures > 5)
3742 dur = 30;
3743 else if (ssid->auth_failures > 1)
3744 dur = 20;
3745 else
3746 dur = 10;
3747
3748 os_get_time(&now);
3749 if (now.sec + dur <= ssid->disabled_until.sec)
3750 return;
3751
3752 ssid->disabled_until.sec = now.sec + dur;
3753
3754 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3755 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3756 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3757 ssid->auth_failures, dur);
3758}
3759
3760
3761void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3762 struct wpa_ssid *ssid, int clear_failures)
3763{
3764 if (ssid == NULL)
3765 return;
3766
3767 if (ssid->disabled_until.sec) {
3768 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3769 "id=%d ssid=\"%s\"",
3770 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3771 }
3772 ssid->disabled_until.sec = 0;
3773 ssid->disabled_until.usec = 0;
3774 if (clear_failures)
3775 ssid->auth_failures = 0;
3776}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003777
3778
3779int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3780{
3781 size_t i;
3782
3783 if (wpa_s->disallow_aps_bssid == NULL)
3784 return 0;
3785
3786 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3787 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3788 bssid, ETH_ALEN) == 0)
3789 return 1;
3790 }
3791
3792 return 0;
3793}
3794
3795
3796int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3797 size_t ssid_len)
3798{
3799 size_t i;
3800
3801 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3802 return 0;
3803
3804 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3805 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3806 if (ssid_len == s->ssid_len &&
3807 os_memcmp(ssid, s->ssid, ssid_len) == 0)
3808 return 1;
3809 }
3810
3811 return 0;
3812}
3813
3814
3815/**
3816 * wpas_request_connection - Request a new connection
3817 * @wpa_s: Pointer to the network interface
3818 *
3819 * This function is used to request a new connection to be found. It will mark
3820 * the interface to allow reassociation and request a new scan to find a
3821 * suitable network to connect to.
3822 */
3823void wpas_request_connection(struct wpa_supplicant *wpa_s)
3824{
3825 wpa_s->normal_scans = 0;
3826 wpa_supplicant_reinit_autoscan(wpa_s);
3827 wpa_s->extra_blacklist_count = 0;
3828 wpa_s->disconnected = 0;
3829 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08003830
3831 if (wpa_supplicant_fast_associate(wpa_s) != 1)
3832 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003833}