blob: 284a91d9084345fae052ae6604e65bf996c5783e [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 Shmidtc5ec7f52012-03-06 16:33:24 -080055"Copyright (c) 2003-2012, 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);
193 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
194 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
203 if (wpa_s->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
204 wpa_s->global->p2p != NULL) {
205 wpa_s->p2p_cb_on_scan_complete = 0;
206 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
473 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700474
475 ext_password_deinit(wpa_s->ext_pw);
476 wpa_s->ext_pw = NULL;
477
478 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700479}
480
481
482/**
483 * wpa_clear_keys - Clear keys configured for the driver
484 * @wpa_s: Pointer to wpa_supplicant data
485 * @addr: Previously used BSSID or %NULL if not available
486 *
487 * This function clears the encryption keys that has been previously configured
488 * for the driver.
489 */
490void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
491{
492 if (wpa_s->keys_cleared) {
493 /* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
494 * timing issues with keys being cleared just before new keys
495 * are set or just after association or something similar. This
496 * shows up in group key handshake failing often because of the
497 * client not receiving the first encrypted packets correctly.
498 * Skipping some of the extra key clearing steps seems to help
499 * in completing group key handshake more reliably. */
500 wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
501 "skip key clearing");
502 return;
503 }
504
505 /* MLME-DELETEKEYS.request */
506 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
507 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
508 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
509 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
510#ifdef CONFIG_IEEE80211W
511 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
512 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
513#endif /* CONFIG_IEEE80211W */
514 if (addr) {
515 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
516 0);
517 /* MLME-SETPROTECTION.request(None) */
518 wpa_drv_mlme_setprotection(
519 wpa_s, addr,
520 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
521 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
522 }
523 wpa_s->keys_cleared = 1;
524}
525
526
527/**
528 * wpa_supplicant_state_txt - Get the connection state name as a text string
529 * @state: State (wpa_state; WPA_*)
530 * Returns: The state name as a printable text string
531 */
532const char * wpa_supplicant_state_txt(enum wpa_states state)
533{
534 switch (state) {
535 case WPA_DISCONNECTED:
536 return "DISCONNECTED";
537 case WPA_INACTIVE:
538 return "INACTIVE";
539 case WPA_INTERFACE_DISABLED:
540 return "INTERFACE_DISABLED";
541 case WPA_SCANNING:
542 return "SCANNING";
543 case WPA_AUTHENTICATING:
544 return "AUTHENTICATING";
545 case WPA_ASSOCIATING:
546 return "ASSOCIATING";
547 case WPA_ASSOCIATED:
548 return "ASSOCIATED";
549 case WPA_4WAY_HANDSHAKE:
550 return "4WAY_HANDSHAKE";
551 case WPA_GROUP_HANDSHAKE:
552 return "GROUP_HANDSHAKE";
553 case WPA_COMPLETED:
554 return "COMPLETED";
555 default:
556 return "UNKNOWN";
557 }
558}
559
560
561#ifdef CONFIG_BGSCAN
562
563static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
564{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800565 if (wpas_driver_bss_selection(wpa_s))
566 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700567 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
568 return;
569
570 bgscan_deinit(wpa_s);
571 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
572 if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
573 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
574 "bgscan");
575 /*
576 * Live without bgscan; it is only used as a roaming
577 * optimization, so the initial connection is not
578 * affected.
579 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700580 } else {
581 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700582 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700583 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
584 0);
585 if (scan_res) {
586 bgscan_notify_scan(wpa_s, scan_res);
587 wpa_scan_results_free(scan_res);
588 }
589 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700590 } else
591 wpa_s->bgscan_ssid = NULL;
592}
593
594
595static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
596{
597 if (wpa_s->bgscan_ssid != NULL) {
598 bgscan_deinit(wpa_s);
599 wpa_s->bgscan_ssid = NULL;
600 }
601}
602
603#endif /* CONFIG_BGSCAN */
604
605
Dmitry Shmidt04949592012-07-19 12:16:46 -0700606static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
607{
608 if (autoscan_init(wpa_s, 0))
609 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
610}
611
612
613static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
614{
615 autoscan_deinit(wpa_s);
616}
617
618
619void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
620{
621 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
622 wpa_s->wpa_state == WPA_SCANNING) {
623 autoscan_deinit(wpa_s);
624 wpa_supplicant_start_autoscan(wpa_s);
625 }
626}
627
628
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700629/**
630 * wpa_supplicant_set_state - Set current connection state
631 * @wpa_s: Pointer to wpa_supplicant data
632 * @state: The new connection state
633 *
634 * This function is called whenever the connection state changes, e.g.,
635 * association is completed for WPA/WPA2 4-Way Handshake is started.
636 */
637void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
638 enum wpa_states state)
639{
640 enum wpa_states old_state = wpa_s->wpa_state;
641
642 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
643 wpa_supplicant_state_txt(wpa_s->wpa_state),
644 wpa_supplicant_state_txt(state));
645
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700646#ifdef ANDROID_P2P
Irfan Sheriff7db4ef72012-06-18 09:39:07 -0700647 if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
648 wpa_s->current_ssid->assoc_retry = 0;
649 }
Dmitry Shmidt98f9e762012-05-30 11:18:46 -0700650#endif /* ANDROID_P2P */
651
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700652 if (state != WPA_SCANNING)
653 wpa_supplicant_notify_scanning(wpa_s, 0);
654
655 if (state == WPA_COMPLETED && wpa_s->new_connection) {
656#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
657 struct wpa_ssid *ssid = wpa_s->current_ssid;
658 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
659 MACSTR " completed %s [id=%d id_str=%s]",
660 MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ?
661 "(reauth)" : "(auth)",
662 ssid ? ssid->id : -1,
663 ssid && ssid->id_str ? ssid->id_str : "");
664#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700665 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700666 wpa_s->new_connection = 0;
667 wpa_s->reassociated_connection = 1;
668 wpa_drv_set_operstate(wpa_s, 1);
669#ifndef IEEE8021X_EAPOL
670 wpa_drv_set_supp_port(wpa_s, 1);
671#endif /* IEEE8021X_EAPOL */
672 wpa_s->after_wps = 0;
673#ifdef CONFIG_P2P
674 wpas_p2p_completed(wpa_s);
675#endif /* CONFIG_P2P */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700676
677 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700678 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
679 state == WPA_ASSOCIATED) {
680 wpa_s->new_connection = 1;
681 wpa_drv_set_operstate(wpa_s, 0);
682#ifndef IEEE8021X_EAPOL
683 wpa_drv_set_supp_port(wpa_s, 0);
684#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700685 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700686 }
687 wpa_s->wpa_state = state;
688
689#ifdef CONFIG_BGSCAN
690 if (state == WPA_COMPLETED)
691 wpa_supplicant_start_bgscan(wpa_s);
692 else
693 wpa_supplicant_stop_bgscan(wpa_s);
694#endif /* CONFIG_BGSCAN */
695
Dmitry Shmidt04949592012-07-19 12:16:46 -0700696 if (state == WPA_AUTHENTICATING)
697 wpa_supplicant_stop_autoscan(wpa_s);
698
699 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
700 wpa_supplicant_start_autoscan(wpa_s);
701
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700702 if (wpa_s->wpa_state != old_state) {
703 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
704
705 if (wpa_s->wpa_state == WPA_COMPLETED ||
706 old_state == WPA_COMPLETED)
707 wpas_notify_auth_changed(wpa_s);
708 }
709}
710
711
712void wpa_supplicant_terminate_proc(struct wpa_global *global)
713{
714 int pending = 0;
715#ifdef CONFIG_WPS
716 struct wpa_supplicant *wpa_s = global->ifaces;
717 while (wpa_s) {
718 if (wpas_wps_terminate_pending(wpa_s) == 1)
719 pending = 1;
720 wpa_s = wpa_s->next;
721 }
722#endif /* CONFIG_WPS */
723 if (pending)
724 return;
725 eloop_terminate();
726}
727
728
729static void wpa_supplicant_terminate(int sig, void *signal_ctx)
730{
731 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700732 wpa_supplicant_terminate_proc(global);
733}
734
735
736void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
737{
738 enum wpa_states old_state = wpa_s->wpa_state;
739
740 wpa_s->pairwise_cipher = 0;
741 wpa_s->group_cipher = 0;
742 wpa_s->mgmt_group_cipher = 0;
743 wpa_s->key_mgmt = 0;
744 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700745 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700746
747 if (wpa_s->wpa_state != old_state)
748 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
749}
750
751
752/**
753 * wpa_supplicant_reload_configuration - Reload configuration data
754 * @wpa_s: Pointer to wpa_supplicant data
755 * Returns: 0 on success or -1 if configuration parsing failed
756 *
757 * This function can be used to request that the configuration data is reloaded
758 * (e.g., after configuration file change). This function is reloading
759 * configuration only for one interface, so this may need to be called multiple
760 * times if %wpa_supplicant is controlling multiple interfaces and all
761 * interfaces need reconfiguration.
762 */
763int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
764{
765 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700766 int reconf_ctrl;
767 int old_ap_scan;
768
769 if (wpa_s->confname == NULL)
770 return -1;
771 conf = wpa_config_read(wpa_s->confname);
772 if (conf == NULL) {
773 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
774 "file '%s' - exiting", wpa_s->confname);
775 return -1;
776 }
777 conf->changed_parameters = (unsigned int) -1;
778
779 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
780 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
781 os_strcmp(conf->ctrl_interface,
782 wpa_s->conf->ctrl_interface) != 0);
783
784 if (reconf_ctrl && wpa_s->ctrl_iface) {
785 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
786 wpa_s->ctrl_iface = NULL;
787 }
788
789 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800790 if (wpa_s->current_ssid) {
791 wpa_supplicant_deauthenticate(wpa_s,
792 WLAN_REASON_DEAUTH_LEAVING);
793 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700794
795 /*
796 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
797 * pkcs11_engine_path, pkcs11_module_path.
798 */
799 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
800 /*
801 * Clear forced success to clear EAP state for next
802 * authentication.
803 */
804 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
805 }
806 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
807 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800808 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700809 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
810 rsn_preauth_deinit(wpa_s->wpa);
811
812 old_ap_scan = wpa_s->conf->ap_scan;
813 wpa_config_free(wpa_s->conf);
814 wpa_s->conf = conf;
815 if (old_ap_scan != wpa_s->conf->ap_scan)
816 wpas_notify_ap_scan_changed(wpa_s);
817
818 if (reconf_ctrl)
819 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
820
821 wpa_supplicant_update_config(wpa_s);
822
823 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700824 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700825 wpa_s->reassociate = 1;
826 wpa_supplicant_req_scan(wpa_s, 0, 0);
827 }
828 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
829 return 0;
830}
831
832
833static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
834{
835 struct wpa_global *global = signal_ctx;
836 struct wpa_supplicant *wpa_s;
837 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
838 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
839 sig);
840 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
841 wpa_supplicant_terminate_proc(global);
842 }
843 }
844}
845
846
847enum wpa_cipher cipher_suite2driver(int cipher)
848{
849 switch (cipher) {
850 case WPA_CIPHER_NONE:
851 return CIPHER_NONE;
852 case WPA_CIPHER_WEP40:
853 return CIPHER_WEP40;
854 case WPA_CIPHER_WEP104:
855 return CIPHER_WEP104;
856 case WPA_CIPHER_CCMP:
857 return CIPHER_CCMP;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700858 case WPA_CIPHER_GCMP:
859 return CIPHER_GCMP;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700860 case WPA_CIPHER_TKIP:
861 default:
862 return CIPHER_TKIP;
863 }
864}
865
866
867enum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
868{
869 switch (key_mgmt) {
870 case WPA_KEY_MGMT_NONE:
871 return KEY_MGMT_NONE;
872 case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
873 return KEY_MGMT_802_1X_NO_WPA;
874 case WPA_KEY_MGMT_IEEE8021X:
875 return KEY_MGMT_802_1X;
876 case WPA_KEY_MGMT_WPA_NONE:
877 return KEY_MGMT_WPA_NONE;
878 case WPA_KEY_MGMT_FT_IEEE8021X:
879 return KEY_MGMT_FT_802_1X;
880 case WPA_KEY_MGMT_FT_PSK:
881 return KEY_MGMT_FT_PSK;
882 case WPA_KEY_MGMT_IEEE8021X_SHA256:
883 return KEY_MGMT_802_1X_SHA256;
884 case WPA_KEY_MGMT_PSK_SHA256:
885 return KEY_MGMT_PSK_SHA256;
886 case WPA_KEY_MGMT_WPS:
887 return KEY_MGMT_WPS;
888 case WPA_KEY_MGMT_PSK:
889 default:
890 return KEY_MGMT_PSK;
891 }
892}
893
894
895static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
896 struct wpa_ssid *ssid,
897 struct wpa_ie_data *ie)
898{
899 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
900 if (ret) {
901 if (ret == -2) {
902 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
903 "from association info");
904 }
905 return -1;
906 }
907
908 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
909 "cipher suites");
910 if (!(ie->group_cipher & ssid->group_cipher)) {
911 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
912 "cipher 0x%x (mask 0x%x) - reject",
913 ie->group_cipher, ssid->group_cipher);
914 return -1;
915 }
916 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
917 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
918 "cipher 0x%x (mask 0x%x) - reject",
919 ie->pairwise_cipher, ssid->pairwise_cipher);
920 return -1;
921 }
922 if (!(ie->key_mgmt & ssid->key_mgmt)) {
923 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
924 "management 0x%x (mask 0x%x) - reject",
925 ie->key_mgmt, ssid->key_mgmt);
926 return -1;
927 }
928
929#ifdef CONFIG_IEEE80211W
930 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
931 ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
932 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
933 "that does not support management frame protection - "
934 "reject");
935 return -1;
936 }
937#endif /* CONFIG_IEEE80211W */
938
939 return 0;
940}
941
942
943/**
944 * wpa_supplicant_set_suites - Set authentication and encryption parameters
945 * @wpa_s: Pointer to wpa_supplicant data
946 * @bss: Scan results for the selected BSS, or %NULL if not available
947 * @ssid: Configuration data for the selected network
948 * @wpa_ie: Buffer for the WPA/RSN IE
949 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
950 * used buffer length in case the functions returns success.
951 * Returns: 0 on success or -1 on failure
952 *
953 * This function is used to configure authentication and encryption parameters
954 * based on the network configuration and scan result for the selected BSS (if
955 * available).
956 */
957int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
958 struct wpa_bss *bss, struct wpa_ssid *ssid,
959 u8 *wpa_ie, size_t *wpa_ie_len)
960{
961 struct wpa_ie_data ie;
962 int sel, proto;
963 const u8 *bss_wpa, *bss_rsn;
964
965 if (bss) {
966 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
967 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
968 } else
969 bss_wpa = bss_rsn = NULL;
970
971 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
972 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
973 (ie.group_cipher & ssid->group_cipher) &&
974 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
975 (ie.key_mgmt & ssid->key_mgmt)) {
976 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
977 proto = WPA_PROTO_RSN;
978 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
979 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
980 (ie.group_cipher & ssid->group_cipher) &&
981 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
982 (ie.key_mgmt & ssid->key_mgmt)) {
983 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
984 proto = WPA_PROTO_WPA;
985 } else if (bss) {
986 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
987 return -1;
988 } else {
989 if (ssid->proto & WPA_PROTO_RSN)
990 proto = WPA_PROTO_RSN;
991 else
992 proto = WPA_PROTO_WPA;
993 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
994 os_memset(&ie, 0, sizeof(ie));
995 ie.group_cipher = ssid->group_cipher;
996 ie.pairwise_cipher = ssid->pairwise_cipher;
997 ie.key_mgmt = ssid->key_mgmt;
998#ifdef CONFIG_IEEE80211W
999 ie.mgmt_group_cipher =
1000 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
1001 WPA_CIPHER_AES_128_CMAC : 0;
1002#endif /* CONFIG_IEEE80211W */
1003 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1004 "based on configuration");
1005 } else
1006 proto = ie.proto;
1007 }
1008
1009 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1010 "pairwise %d key_mgmt %d proto %d",
1011 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
1012#ifdef CONFIG_IEEE80211W
1013 if (ssid->ieee80211w) {
1014 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1015 ie.mgmt_group_cipher);
1016 }
1017#endif /* CONFIG_IEEE80211W */
1018
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001019 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001020 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1021 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
1022 !!(ssid->proto & WPA_PROTO_RSN));
1023
1024 if (bss || !wpa_s->ap_ies_from_associnfo) {
1025 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1026 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1027 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1028 bss_rsn ? 2 + bss_rsn[1] : 0))
1029 return -1;
1030 }
1031
1032 sel = ie.group_cipher & ssid->group_cipher;
1033 if (sel & WPA_CIPHER_CCMP) {
1034 wpa_s->group_cipher = WPA_CIPHER_CCMP;
1035 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK CCMP");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001036 } else if (sel & WPA_CIPHER_GCMP) {
1037 wpa_s->group_cipher = WPA_CIPHER_GCMP;
1038 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK GCMP");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001039 } else if (sel & WPA_CIPHER_TKIP) {
1040 wpa_s->group_cipher = WPA_CIPHER_TKIP;
1041 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK TKIP");
1042 } else if (sel & WPA_CIPHER_WEP104) {
1043 wpa_s->group_cipher = WPA_CIPHER_WEP104;
1044 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP104");
1045 } else if (sel & WPA_CIPHER_WEP40) {
1046 wpa_s->group_cipher = WPA_CIPHER_WEP40;
1047 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP40");
1048 } else {
1049 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1050 "cipher");
1051 return -1;
1052 }
1053
1054 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
1055 if (sel & WPA_CIPHER_CCMP) {
1056 wpa_s->pairwise_cipher = WPA_CIPHER_CCMP;
1057 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK CCMP");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001058 } else if (sel & WPA_CIPHER_GCMP) {
1059 wpa_s->pairwise_cipher = WPA_CIPHER_GCMP;
1060 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK GCMP");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001061 } else if (sel & WPA_CIPHER_TKIP) {
1062 wpa_s->pairwise_cipher = WPA_CIPHER_TKIP;
1063 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK TKIP");
1064 } else if (sel & WPA_CIPHER_NONE) {
1065 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
1066 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK NONE");
1067 } else {
1068 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1069 "cipher");
1070 return -1;
1071 }
1072
1073 sel = ie.key_mgmt & ssid->key_mgmt;
1074 if (0) {
1075#ifdef CONFIG_IEEE80211R
1076 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1077 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1078 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1079 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1080 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1081 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1082#endif /* CONFIG_IEEE80211R */
1083#ifdef CONFIG_IEEE80211W
1084 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1085 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1086 wpa_dbg(wpa_s, MSG_DEBUG,
1087 "WPA: using KEY_MGMT 802.1X with SHA256");
1088 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1089 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1090 wpa_dbg(wpa_s, MSG_DEBUG,
1091 "WPA: using KEY_MGMT PSK with SHA256");
1092#endif /* CONFIG_IEEE80211W */
1093 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1094 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1095 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1096 } else if (sel & WPA_KEY_MGMT_PSK) {
1097 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1098 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1099 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1100 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1101 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
1102 } else {
1103 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1104 "authenticated key management type");
1105 return -1;
1106 }
1107
1108 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1109 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1110 wpa_s->pairwise_cipher);
1111 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1112
1113#ifdef CONFIG_IEEE80211W
1114 sel = ie.mgmt_group_cipher;
1115 if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION ||
1116 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1117 sel = 0;
1118 if (sel & WPA_CIPHER_AES_128_CMAC) {
1119 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1120 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1121 "AES-128-CMAC");
1122 } else {
1123 wpa_s->mgmt_group_cipher = 0;
1124 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1125 }
1126 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1127 wpa_s->mgmt_group_cipher);
1128 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, ssid->ieee80211w);
1129#endif /* CONFIG_IEEE80211W */
1130
1131 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1132 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1133 return -1;
1134 }
1135
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001136 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001137 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001138#ifndef CONFIG_NO_PBKDF2
1139 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1140 ssid->passphrase) {
1141 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001142 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1143 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001144 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1145 psk, PMK_LEN);
1146 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1147 }
1148#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001149#ifdef CONFIG_EXT_PASSWORD
1150 if (ssid->ext_psk) {
1151 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1152 ssid->ext_psk);
1153 char pw_str[64 + 1];
1154 u8 psk[PMK_LEN];
1155
1156 if (pw == NULL) {
1157 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1158 "found from external storage");
1159 return -1;
1160 }
1161
1162 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1163 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1164 "PSK length %d in external storage",
1165 (int) wpabuf_len(pw));
1166 ext_password_free(pw);
1167 return -1;
1168 }
1169
1170 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1171 pw_str[wpabuf_len(pw)] = '\0';
1172
1173#ifndef CONFIG_NO_PBKDF2
1174 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1175 {
1176 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1177 4096, psk, PMK_LEN);
1178 os_memset(pw_str, 0, sizeof(pw_str));
1179 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1180 "external passphrase)",
1181 psk, PMK_LEN);
1182 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1183 } else
1184#endif /* CONFIG_NO_PBKDF2 */
1185 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1186 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1187 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1188 "Invalid PSK hex string");
1189 os_memset(pw_str, 0, sizeof(pw_str));
1190 ext_password_free(pw);
1191 return -1;
1192 }
1193 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1194 } else {
1195 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1196 "PSK available");
1197 os_memset(pw_str, 0, sizeof(pw_str));
1198 ext_password_free(pw);
1199 return -1;
1200 }
1201
1202 os_memset(pw_str, 0, sizeof(pw_str));
1203 ext_password_free(pw);
1204 }
1205#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001206 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001207 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1208
1209 return 0;
1210}
1211
1212
1213/**
1214 * wpa_supplicant_associate - Request association
1215 * @wpa_s: Pointer to wpa_supplicant data
1216 * @bss: Scan results for the selected BSS, or %NULL if not available
1217 * @ssid: Configuration data for the selected network
1218 *
1219 * This function is used to request %wpa_supplicant to associate with a BSS.
1220 */
1221void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1222 struct wpa_bss *bss, struct wpa_ssid *ssid)
1223{
1224 u8 wpa_ie[200];
1225 size_t wpa_ie_len;
1226 int use_crypt, ret, i, bssid_changed;
1227 int algs = WPA_AUTH_ALG_OPEN;
1228 enum wpa_cipher cipher_pairwise, cipher_group;
1229 struct wpa_driver_associate_params params;
1230 int wep_keys_set = 0;
1231 struct wpa_driver_capa capa;
1232 int assoc_failed = 0;
1233 struct wpa_ssid *old_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001234#ifdef CONFIG_HT_OVERRIDES
1235 struct ieee80211_ht_capabilities htcaps;
1236 struct ieee80211_ht_capabilities htcaps_mask;
1237#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001238
1239#ifdef CONFIG_IBSS_RSN
1240 ibss_rsn_deinit(wpa_s->ibss_rsn);
1241 wpa_s->ibss_rsn = NULL;
1242#endif /* CONFIG_IBSS_RSN */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001243#ifdef ANDROID_P2P
1244 int freq = 0;
1245#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001246
1247 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1248 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1249#ifdef CONFIG_AP
1250 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1251 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1252 "mode");
1253 return;
1254 }
1255 wpa_supplicant_create_ap(wpa_s, ssid);
1256 wpa_s->current_bss = bss;
1257#else /* CONFIG_AP */
1258 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1259 "the build");
1260#endif /* CONFIG_AP */
1261 return;
1262 }
1263
1264#ifdef CONFIG_TDLS
1265 if (bss)
1266 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1267 bss->ie_len);
1268#endif /* CONFIG_TDLS */
1269
1270 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1271 ssid->mode == IEEE80211_MODE_INFRA) {
1272 sme_authenticate(wpa_s, bss, ssid);
1273 return;
1274 }
1275
1276 os_memset(&params, 0, sizeof(params));
1277 wpa_s->reassociate = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001278 if (bss && !wpas_driver_bss_selection(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001279#ifdef CONFIG_IEEE80211R
1280 const u8 *ie, *md = NULL;
1281#endif /* CONFIG_IEEE80211R */
1282 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1283 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
1284 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
1285 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1286 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1287 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1288 if (bssid_changed)
1289 wpas_notify_bssid_changed(wpa_s);
1290#ifdef CONFIG_IEEE80211R
1291 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
1292 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1293 md = ie + 2;
1294 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
1295 if (md) {
1296 /* Prepare for the next transition */
1297 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
1298 }
1299#endif /* CONFIG_IEEE80211R */
1300#ifdef CONFIG_WPS
1301 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1302 wpa_s->conf->ap_scan == 2 &&
1303 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1304 /* Use ap_scan==1 style network selection to find the network
1305 */
1306 wpa_s->scan_req = 2;
1307 wpa_s->reassociate = 1;
1308 wpa_supplicant_req_scan(wpa_s, 0, 0);
1309 return;
1310#endif /* CONFIG_WPS */
1311 } else {
1312 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1313 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1314 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1315 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001316 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001317 wpa_supplicant_cancel_scan(wpa_s);
1318
1319 /* Starting new association, so clear the possibly used WPA IE from the
1320 * previous association. */
1321 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1322
1323#ifdef IEEE8021X_EAPOL
1324 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1325 if (ssid->leap) {
1326 if (ssid->non_leap == 0)
1327 algs = WPA_AUTH_ALG_LEAP;
1328 else
1329 algs |= WPA_AUTH_ALG_LEAP;
1330 }
1331 }
1332#endif /* IEEE8021X_EAPOL */
1333 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
1334 if (ssid->auth_alg) {
1335 algs = ssid->auth_alg;
1336 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1337 "0x%x", algs);
1338 }
1339
1340 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1341 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001342 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001343 int try_opportunistic;
1344 try_opportunistic = ssid->proactive_key_caching &&
1345 (ssid->proto & WPA_PROTO_RSN);
1346 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
1347 wpa_s->current_ssid,
1348 try_opportunistic) == 0)
1349 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1350 wpa_ie_len = sizeof(wpa_ie);
1351 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1352 wpa_ie, &wpa_ie_len)) {
1353 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1354 "key management and encryption suites");
1355 return;
1356 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001357 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1358 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1359 /*
1360 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1361 * use non-WPA since the scan results did not indicate that the
1362 * AP is using WPA or WPA2.
1363 */
1364 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1365 wpa_ie_len = 0;
1366 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001367 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001368 wpa_ie_len = sizeof(wpa_ie);
1369 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1370 wpa_ie, &wpa_ie_len)) {
1371 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1372 "key management and encryption suites (no "
1373 "scan results)");
1374 return;
1375 }
1376#ifdef CONFIG_WPS
1377 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1378 struct wpabuf *wps_ie;
1379 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
1380 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1381 wpa_ie_len = wpabuf_len(wps_ie);
1382 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
1383 } else
1384 wpa_ie_len = 0;
1385 wpabuf_free(wps_ie);
1386 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1387 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1388 params.wps = WPS_MODE_PRIVACY;
1389 else
1390 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001391 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001392#endif /* CONFIG_WPS */
1393 } else {
1394 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1395 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001396 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001397 }
1398
1399#ifdef CONFIG_P2P
1400 if (wpa_s->global->p2p) {
1401 u8 *pos;
1402 size_t len;
1403 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001404 pos = wpa_ie + wpa_ie_len;
1405 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001406 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1407 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001408 if (res >= 0)
1409 wpa_ie_len += res;
1410 }
1411
1412 wpa_s->cross_connect_disallowed = 0;
1413 if (bss) {
1414 struct wpabuf *p2p;
1415 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1416 if (p2p) {
1417 wpa_s->cross_connect_disallowed =
1418 p2p_get_cross_connect_disallowed(p2p);
1419 wpabuf_free(p2p);
1420 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1421 "connection",
1422 wpa_s->cross_connect_disallowed ?
1423 "disallows" : "allows");
1424 }
1425 }
1426#endif /* CONFIG_P2P */
1427
Dmitry Shmidt04949592012-07-19 12:16:46 -07001428#ifdef CONFIG_HS20
1429 if (wpa_s->conf->hs20) {
1430 struct wpabuf *hs20;
1431 hs20 = wpabuf_alloc(20);
1432 if (hs20) {
1433 wpas_hs20_add_indication(hs20);
1434 os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
1435 wpabuf_len(hs20));
1436 wpa_ie_len += wpabuf_len(hs20);
1437 wpabuf_free(hs20);
1438 }
1439 }
1440#endif /* CONFIG_HS20 */
1441
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001442#ifdef CONFIG_INTERWORKING
1443 if (wpa_s->conf->interworking) {
1444 u8 *pos = wpa_ie;
1445 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1446 pos += 2 + pos[1];
1447 os_memmove(pos + 6, pos, wpa_ie_len - (pos - wpa_ie));
1448 wpa_ie_len += 6;
1449 *pos++ = WLAN_EID_EXT_CAPAB;
1450 *pos++ = 4;
1451 *pos++ = 0x00;
1452 *pos++ = 0x00;
1453 *pos++ = 0x00;
1454 *pos++ = 0x80; /* Bit 31 - Interworking */
1455 }
1456#endif /* CONFIG_INTERWORKING */
1457
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001458 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1459 use_crypt = 1;
1460 cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher);
1461 cipher_group = cipher_suite2driver(wpa_s->group_cipher);
1462 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1463 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1464 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1465 use_crypt = 0;
1466 if (wpa_set_wep_keys(wpa_s, ssid)) {
1467 use_crypt = 1;
1468 wep_keys_set = 1;
1469 }
1470 }
1471 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1472 use_crypt = 0;
1473
1474#ifdef IEEE8021X_EAPOL
1475 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1476 if ((ssid->eapol_flags &
1477 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1478 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1479 !wep_keys_set) {
1480 use_crypt = 0;
1481 } else {
1482 /* Assume that dynamic WEP-104 keys will be used and
1483 * set cipher suites in order for drivers to expect
1484 * encryption. */
1485 cipher_pairwise = cipher_group = CIPHER_WEP104;
1486 }
1487 }
1488#endif /* IEEE8021X_EAPOL */
1489
1490 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1491 /* Set the key before (and later after) association */
1492 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1493 }
1494
1495 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1496 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001497 params.ssid = bss->ssid;
1498 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001499 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1500 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1501 MACSTR " freq=%u MHz based on scan results "
1502 "(bssid_set=%d)",
1503 MAC2STR(bss->bssid), bss->freq,
1504 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001505 params.bssid = bss->bssid;
1506 params.freq = bss->freq;
1507 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001508 } else {
1509 params.ssid = ssid->ssid;
1510 params.ssid_len = ssid->ssid_len;
1511 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001512
1513 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1514 wpa_s->conf->ap_scan == 2) {
1515 params.bssid = ssid->bssid;
1516 params.fixed_bssid = 1;
1517 }
1518
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001519 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1520 params.freq == 0)
1521 params.freq = ssid->frequency; /* Initial channel for IBSS */
1522 params.wpa_ie = wpa_ie;
1523 params.wpa_ie_len = wpa_ie_len;
1524 params.pairwise_suite = cipher_pairwise;
1525 params.group_suite = cipher_group;
1526 params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001527 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001528 params.auth_alg = algs;
1529 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001530 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001531 for (i = 0; i < NUM_WEP_KEYS; i++) {
1532 if (ssid->wep_key_len[i])
1533 params.wep_key[i] = ssid->wep_key[i];
1534 params.wep_key_len[i] = ssid->wep_key_len[i];
1535 }
1536 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1537
1538 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
1539 (params.key_mgmt_suite == KEY_MGMT_PSK ||
1540 params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
1541 params.passphrase = ssid->passphrase;
1542 if (ssid->psk_set)
1543 params.psk = ssid->psk;
1544 }
1545
1546 params.drop_unencrypted = use_crypt;
1547
1548#ifdef CONFIG_IEEE80211W
1549 params.mgmt_frame_protection = ssid->ieee80211w;
1550 if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) {
1551 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1552 struct wpa_ie_data ie;
1553 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1554 ie.capabilities &
1555 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
1556 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1557 "MFP: require MFP");
1558 params.mgmt_frame_protection =
1559 MGMT_FRAME_PROTECTION_REQUIRED;
1560 }
1561 }
1562#endif /* CONFIG_IEEE80211W */
1563
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001564 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001565
1566 if (wpa_s->parent->set_sta_uapsd)
1567 params.uapsd = wpa_s->parent->sta_uapsd;
1568 else
1569 params.uapsd = -1;
1570
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001571#ifdef CONFIG_HT_OVERRIDES
1572 os_memset(&htcaps, 0, sizeof(htcaps));
1573 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1574 params.htcaps = (u8 *) &htcaps;
1575 params.htcaps_mask = (u8 *) &htcaps_mask;
1576 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1577#endif /* CONFIG_HT_OVERRIDES */
1578
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001579#ifdef ANDROID_P2P
1580 /* If multichannel concurrency is not supported, check for any frequency
1581 * conflict and take appropriate action.
1582 */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001583 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1584 ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1585 wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001586 , freq, params.freq);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001587 if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq) < 0) {
1588 /* Handling conflicts failed. Disable the current connect req and
1589 * notify the userspace to take appropriate action */
1590 wpa_printf(MSG_DEBUG, "proiritize is not set. Notifying user space to handle the case");
1591 wpa_supplicant_disable_network(wpa_s, ssid);
1592 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_FREQ_CONFLICT
1593 " id=%d", ssid->id);
1594 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
Dmitry Shmidt687922c2012-03-26 14:02:32 -07001595 return;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001596 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001597 }
1598#endif
1599 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001600 if (ret < 0) {
1601 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1602 "failed");
1603 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1604 /*
1605 * The driver is known to mean what is saying, so we
1606 * can stop right here; the association will not
1607 * succeed.
1608 */
1609 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001610 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001611 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1612 return;
1613 }
1614 /* try to continue anyway; new association will be tried again
1615 * after timeout */
1616 assoc_failed = 1;
1617 }
1618
1619 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1620 /* Set the key after the association just in case association
1621 * cleared the previously configured key. */
1622 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1623 /* No need to timeout authentication since there is no key
1624 * management. */
1625 wpa_supplicant_cancel_auth_timeout(wpa_s);
1626 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
1627#ifdef CONFIG_IBSS_RSN
1628 } else if (ssid->mode == WPAS_MODE_IBSS &&
1629 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1630 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1631 /*
1632 * RSN IBSS authentication is per-STA and we can disable the
1633 * per-BSSID authentication.
1634 */
1635 wpa_supplicant_cancel_auth_timeout(wpa_s);
1636#endif /* CONFIG_IBSS_RSN */
1637 } else {
1638 /* Timeout for IEEE 802.11 authentication and association */
1639 int timeout = 60;
1640
1641 if (assoc_failed) {
1642 /* give IBSS a bit more time */
1643 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1644 } else if (wpa_s->conf->ap_scan == 1) {
1645 /* give IBSS a bit more time */
1646 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1647 }
1648 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1649 }
1650
1651 if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1652 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
1653 /* Set static WEP keys again */
1654 wpa_set_wep_keys(wpa_s, ssid);
1655 }
1656
1657 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1658 /*
1659 * Do not allow EAP session resumption between different
1660 * network configurations.
1661 */
1662 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1663 }
1664 old_ssid = wpa_s->current_ssid;
1665 wpa_s->current_ssid = ssid;
1666 wpa_s->current_bss = bss;
1667 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1668 wpa_supplicant_initiate_eapol(wpa_s);
1669 if (old_ssid != wpa_s->current_ssid)
1670 wpas_notify_network_changed(wpa_s);
1671}
1672
1673
1674static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1675 const u8 *addr)
1676{
1677 struct wpa_ssid *old_ssid;
1678
1679 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001680 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001681 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001682 wpa_sm_set_config(wpa_s->wpa, NULL);
1683 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1684 if (old_ssid != wpa_s->current_ssid)
1685 wpas_notify_network_changed(wpa_s);
1686 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1687}
1688
1689
1690/**
1691 * wpa_supplicant_disassociate - Disassociate the current connection
1692 * @wpa_s: Pointer to wpa_supplicant data
1693 * @reason_code: IEEE 802.11 reason code for the disassociate frame
1694 *
1695 * This function is used to request %wpa_supplicant to disassociate with the
1696 * current AP.
1697 */
1698void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
1699 int reason_code)
1700{
1701 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001702 union wpa_event_data event;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001703
1704 if (!is_zero_ether_addr(wpa_s->bssid)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001705 wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001706 addr = wpa_s->bssid;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001707 os_memset(&event, 0, sizeof(event));
1708 event.disassoc_info.reason_code = (u16) reason_code;
1709 event.disassoc_info.locally_generated = 1;
1710 wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001711 }
1712
1713 wpa_supplicant_clear_connection(wpa_s, addr);
1714}
1715
1716
1717/**
1718 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1719 * @wpa_s: Pointer to wpa_supplicant data
1720 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1721 *
1722 * This function is used to request %wpa_supplicant to deauthenticate from the
1723 * current AP.
1724 */
1725void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1726 int reason_code)
1727{
1728 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001729 union wpa_event_data event;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001730
1731 if (!is_zero_ether_addr(wpa_s->bssid)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001732 wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001733 addr = wpa_s->bssid;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001734 os_memset(&event, 0, sizeof(event));
1735 event.deauth_info.reason_code = (u16) reason_code;
1736 event.deauth_info.locally_generated = 1;
1737 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001738 }
1739
1740 wpa_supplicant_clear_connection(wpa_s, addr);
1741}
1742
1743
1744/**
1745 * wpa_supplicant_enable_network - Mark a configured network as enabled
1746 * @wpa_s: wpa_supplicant structure for a network interface
1747 * @ssid: wpa_ssid structure for a configured network or %NULL
1748 *
1749 * Enables the specified network or all networks if no network specified.
1750 */
1751void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
1752 struct wpa_ssid *ssid)
1753{
1754 struct wpa_ssid *other_ssid;
1755 int was_disabled;
1756
1757 if (ssid == NULL) {
1758 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1759 other_ssid = other_ssid->next) {
1760 if (other_ssid->disabled == 2)
1761 continue; /* do not change persistent P2P group
1762 * data */
1763 if (other_ssid == wpa_s->current_ssid &&
1764 other_ssid->disabled)
1765 wpa_s->reassociate = 1;
1766
1767 was_disabled = other_ssid->disabled;
1768
1769 other_ssid->disabled = 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001770 if (was_disabled)
1771 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001772
1773 if (was_disabled != other_ssid->disabled)
1774 wpas_notify_network_enabled_changed(
1775 wpa_s, other_ssid);
1776 }
1777 if (wpa_s->reassociate)
1778 wpa_supplicant_req_scan(wpa_s, 0, 0);
1779 } else if (ssid->disabled && ssid->disabled != 2) {
1780 if (wpa_s->current_ssid == NULL) {
1781 /*
1782 * Try to reassociate since there is no current
1783 * configuration and a new network was made available.
1784 */
1785 wpa_s->reassociate = 1;
1786 wpa_supplicant_req_scan(wpa_s, 0, 0);
1787 }
1788
1789 was_disabled = ssid->disabled;
1790
1791 ssid->disabled = 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001792 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001793
1794 if (was_disabled != ssid->disabled)
1795 wpas_notify_network_enabled_changed(wpa_s, ssid);
1796 }
1797}
1798
1799
1800/**
1801 * wpa_supplicant_disable_network - Mark a configured network as disabled
1802 * @wpa_s: wpa_supplicant structure for a network interface
1803 * @ssid: wpa_ssid structure for a configured network or %NULL
1804 *
1805 * Disables the specified network or all networks if no network specified.
1806 */
1807void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
1808 struct wpa_ssid *ssid)
1809{
1810 struct wpa_ssid *other_ssid;
1811 int was_disabled;
1812
1813 if (ssid == NULL) {
1814 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1815 other_ssid = other_ssid->next) {
1816 was_disabled = other_ssid->disabled;
1817 if (was_disabled == 2)
1818 continue; /* do not change persistent P2P group
1819 * data */
1820
1821 other_ssid->disabled = 1;
1822
1823 if (was_disabled != other_ssid->disabled)
1824 wpas_notify_network_enabled_changed(
1825 wpa_s, other_ssid);
1826 }
1827 if (wpa_s->current_ssid)
1828 wpa_supplicant_disassociate(
1829 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1830 } else if (ssid->disabled != 2) {
1831 if (ssid == wpa_s->current_ssid)
1832 wpa_supplicant_disassociate(
1833 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1834
1835 was_disabled = ssid->disabled;
1836
1837 ssid->disabled = 1;
1838
1839 if (was_disabled != ssid->disabled)
1840 wpas_notify_network_enabled_changed(wpa_s, ssid);
1841 }
1842}
1843
1844
1845/**
1846 * wpa_supplicant_select_network - Attempt association with a network
1847 * @wpa_s: wpa_supplicant structure for a network interface
1848 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
1849 */
1850void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
1851 struct wpa_ssid *ssid)
1852{
1853
1854 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001855 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001856
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001857 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001858 wpa_supplicant_disassociate(
1859 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001860 disconnected = 1;
1861 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001862
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001863 if (ssid)
1864 wpas_clear_temp_disabled(wpa_s, ssid, 1);
1865
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001866 /*
1867 * Mark all other networks disabled or mark all networks enabled if no
1868 * network specified.
1869 */
1870 for (other_ssid = wpa_s->conf->ssid; other_ssid;
1871 other_ssid = other_ssid->next) {
1872 int was_disabled = other_ssid->disabled;
1873 if (was_disabled == 2)
1874 continue; /* do not change persistent P2P group data */
1875
1876 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001877 if (was_disabled && !other_ssid->disabled)
1878 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001879
1880 if (was_disabled != other_ssid->disabled)
1881 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
1882 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001883
1884 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
1885 /* We are already associated with the selected network */
1886 wpa_printf(MSG_DEBUG, "Already associated with the "
1887 "selected network - do nothing");
1888 return;
1889 }
1890
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001891 if (ssid)
1892 wpa_s->current_ssid = ssid;
Jouni Malinen75ecf522011-06-27 15:19:46 -07001893 wpa_s->connect_without_scan = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001894 wpa_s->disconnected = 0;
1895 wpa_s->reassociate = 1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08001896 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001897
1898 if (ssid)
1899 wpas_notify_network_selected(wpa_s, ssid);
1900}
1901
1902
1903/**
1904 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
1905 * @wpa_s: wpa_supplicant structure for a network interface
1906 * @ap_scan: AP scan mode
1907 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
1908 *
1909 */
1910int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
1911{
1912
1913 int old_ap_scan;
1914
1915 if (ap_scan < 0 || ap_scan > 2)
1916 return -1;
1917
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001918#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001919 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
1920 wpa_s->wpa_state >= WPA_ASSOCIATING &&
1921 wpa_s->wpa_state < WPA_COMPLETED) {
1922 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
1923 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001924 return 0;
1925 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001926#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07001927
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001928 old_ap_scan = wpa_s->conf->ap_scan;
1929 wpa_s->conf->ap_scan = ap_scan;
1930
1931 if (old_ap_scan != wpa_s->conf->ap_scan)
1932 wpas_notify_ap_scan_changed(wpa_s);
1933
1934 return 0;
1935}
1936
1937
1938/**
1939 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
1940 * @wpa_s: wpa_supplicant structure for a network interface
1941 * @expire_age: Expiration age in seconds
1942 * Returns: 0 if succeed or -1 if expire_age has an invalid value
1943 *
1944 */
1945int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
1946 unsigned int bss_expire_age)
1947{
1948 if (bss_expire_age < 10) {
1949 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
1950 bss_expire_age);
1951 return -1;
1952 }
1953 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
1954 bss_expire_age);
1955 wpa_s->conf->bss_expiration_age = bss_expire_age;
1956
1957 return 0;
1958}
1959
1960
1961/**
1962 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
1963 * @wpa_s: wpa_supplicant structure for a network interface
1964 * @expire_count: number of scans after which an unseen BSS is reclaimed
1965 * Returns: 0 if succeed or -1 if expire_count has an invalid value
1966 *
1967 */
1968int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
1969 unsigned int bss_expire_count)
1970{
1971 if (bss_expire_count < 1) {
1972 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
1973 bss_expire_count);
1974 return -1;
1975 }
1976 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
1977 bss_expire_count);
1978 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
1979
1980 return 0;
1981}
1982
1983
1984/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07001985 * wpa_supplicant_set_scan_interval - Set scan interval
1986 * @wpa_s: wpa_supplicant structure for a network interface
1987 * @scan_interval: scan interval in seconds
1988 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
1989 *
1990 */
1991int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
1992 int scan_interval)
1993{
1994 if (scan_interval < 0) {
1995 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
1996 scan_interval);
1997 return -1;
1998 }
1999 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2000 scan_interval);
2001 wpa_s->scan_interval = scan_interval;
2002
2003 return 0;
2004}
2005
2006
2007/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002008 * wpa_supplicant_set_debug_params - Set global debug params
2009 * @global: wpa_global structure
2010 * @debug_level: debug level
2011 * @debug_timestamp: determines if show timestamp in debug data
2012 * @debug_show_keys: determines if show keys in debug data
2013 * Returns: 0 if succeed or -1 if debug_level has wrong value
2014 */
2015int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2016 int debug_timestamp, int debug_show_keys)
2017{
2018
2019 int old_level, old_timestamp, old_show_keys;
2020
2021 /* check for allowed debuglevels */
2022 if (debug_level != MSG_EXCESSIVE &&
2023 debug_level != MSG_MSGDUMP &&
2024 debug_level != MSG_DEBUG &&
2025 debug_level != MSG_INFO &&
2026 debug_level != MSG_WARNING &&
2027 debug_level != MSG_ERROR)
2028 return -1;
2029
2030 old_level = wpa_debug_level;
2031 old_timestamp = wpa_debug_timestamp;
2032 old_show_keys = wpa_debug_show_keys;
2033
2034 wpa_debug_level = debug_level;
2035 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2036 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2037
2038 if (wpa_debug_level != old_level)
2039 wpas_notify_debug_level_changed(global);
2040 if (wpa_debug_timestamp != old_timestamp)
2041 wpas_notify_debug_timestamp_changed(global);
2042 if (wpa_debug_show_keys != old_show_keys)
2043 wpas_notify_debug_show_keys_changed(global);
2044
2045 return 0;
2046}
2047
2048
2049/**
2050 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2051 * @wpa_s: Pointer to wpa_supplicant data
2052 * Returns: A pointer to the current network structure or %NULL on failure
2053 */
2054struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2055{
2056 struct wpa_ssid *entry;
2057 u8 ssid[MAX_SSID_LEN];
2058 int res;
2059 size_t ssid_len;
2060 u8 bssid[ETH_ALEN];
2061 int wired;
2062
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002063 res = wpa_drv_get_ssid(wpa_s, ssid);
2064 if (res < 0) {
2065 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2066 "driver");
2067 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002068 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002069 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002070
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002071 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002072 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2073 "driver");
2074 return NULL;
2075 }
2076
2077 wired = wpa_s->conf->ap_scan == 0 &&
2078 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
2079
2080 entry = wpa_s->conf->ssid;
2081 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002082 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002083 ((ssid_len == entry->ssid_len &&
2084 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2085 (!entry->bssid_set ||
2086 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2087 return entry;
2088#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07002089 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002090 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2091 (entry->ssid == NULL || entry->ssid_len == 0) &&
2092 (!entry->bssid_set ||
2093 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2094 return entry;
2095#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002096
Dmitry Shmidt04949592012-07-19 12:16:46 -07002097 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002098 entry->ssid_len == 0 &&
2099 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2100 return entry;
2101
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002102 entry = entry->next;
2103 }
2104
2105 return NULL;
2106}
2107
2108
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002109static int select_driver(struct wpa_supplicant *wpa_s, int i)
2110{
2111 struct wpa_global *global = wpa_s->global;
2112
2113 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2114 global->drv_priv[i] = wpa_drivers[i]->global_init();
2115 if (global->drv_priv[i] == NULL) {
2116 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2117 "'%s'", wpa_drivers[i]->name);
2118 return -1;
2119 }
2120 }
2121
2122 wpa_s->driver = wpa_drivers[i];
2123 wpa_s->global_drv_priv = global->drv_priv[i];
2124
2125 return 0;
2126}
2127
2128
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002129static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2130 const char *name)
2131{
2132 int i;
2133 size_t len;
2134 const char *pos, *driver = name;
2135
2136 if (wpa_s == NULL)
2137 return -1;
2138
2139 if (wpa_drivers[0] == NULL) {
2140 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2141 "wpa_supplicant");
2142 return -1;
2143 }
2144
2145 if (name == NULL) {
2146 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002147 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002148 }
2149
2150 do {
2151 pos = os_strchr(driver, ',');
2152 if (pos)
2153 len = pos - driver;
2154 else
2155 len = os_strlen(driver);
2156
2157 for (i = 0; wpa_drivers[i]; i++) {
2158 if (os_strlen(wpa_drivers[i]->name) == len &&
2159 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002160 0) {
2161 /* First driver that succeeds wins */
2162 if (select_driver(wpa_s, i) == 0)
2163 return 0;
2164 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002165 }
2166
2167 driver = pos + 1;
2168 } while (pos);
2169
2170 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
2171 return -1;
2172}
2173
2174
2175/**
2176 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2177 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2178 * with struct wpa_driver_ops::init()
2179 * @src_addr: Source address of the EAPOL frame
2180 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2181 * @len: Length of the EAPOL data
2182 *
2183 * This function is called for each received EAPOL frame. Most driver
2184 * interfaces rely on more generic OS mechanism for receiving frames through
2185 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2186 * take care of received EAPOL frames and deliver them to the core supplicant
2187 * code by calling this function.
2188 */
2189void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2190 const u8 *buf, size_t len)
2191{
2192 struct wpa_supplicant *wpa_s = ctx;
2193
2194 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
2195 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2196
2197 if (wpa_s->wpa_state < WPA_ASSOCIATED) {
2198 /*
2199 * There is possible race condition between receiving the
2200 * association event and the EAPOL frame since they are coming
2201 * through different paths from the driver. In order to avoid
2202 * issues in trying to process the EAPOL frame before receiving
2203 * association information, lets queue it for processing until
2204 * the association event is received.
2205 */
2206 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
2207 "of received EAPOL frame");
2208 wpabuf_free(wpa_s->pending_eapol_rx);
2209 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2210 if (wpa_s->pending_eapol_rx) {
2211 os_get_time(&wpa_s->pending_eapol_rx_time);
2212 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2213 ETH_ALEN);
2214 }
2215 return;
2216 }
2217
2218#ifdef CONFIG_AP
2219 if (wpa_s->ap_iface) {
2220 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2221 return;
2222 }
2223#endif /* CONFIG_AP */
2224
2225 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
2226 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2227 "no key management is configured");
2228 return;
2229 }
2230
2231 if (wpa_s->eapol_received == 0 &&
2232 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
2233 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
2234 wpa_s->wpa_state != WPA_COMPLETED) &&
2235 (wpa_s->current_ssid == NULL ||
2236 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
2237 /* Timeout for completing IEEE 802.1X and WPA authentication */
2238 wpa_supplicant_req_auth_timeout(
2239 wpa_s,
2240 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2241 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2242 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
2243 70 : 10, 0);
2244 }
2245 wpa_s->eapol_received++;
2246
2247 if (wpa_s->countermeasures) {
2248 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2249 "EAPOL packet");
2250 return;
2251 }
2252
2253#ifdef CONFIG_IBSS_RSN
2254 if (wpa_s->current_ssid &&
2255 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
2256 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2257 return;
2258 }
2259#endif /* CONFIG_IBSS_RSN */
2260
2261 /* Source address of the incoming EAPOL frame could be compared to the
2262 * current BSSID. However, it is possible that a centralized
2263 * Authenticator could be using another MAC address than the BSSID of
2264 * an AP, so just allow any address to be used for now. The replies are
2265 * still sent to the current BSSID (if available), though. */
2266
2267 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
2268 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
2269 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2270 return;
2271 wpa_drv_poll(wpa_s);
2272 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
2273 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
2274 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
2275 /*
2276 * Set portValid = TRUE here since we are going to skip 4-way
2277 * handshake processing which would normally set portValid. We
2278 * need this to allow the EAPOL state machines to be completed
2279 * without going through EAPOL-Key handshake.
2280 */
2281 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2282 }
2283}
2284
2285
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002286int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002287{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002288 if (wpa_s->driver->send_eapol) {
2289 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2290 if (addr)
2291 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2292 } else if (!(wpa_s->drv_flags &
2293 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002294 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002295 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2296 wpa_drv_get_mac_addr(wpa_s),
2297 ETH_P_EAPOL,
2298 wpa_supplicant_rx_eapol, wpa_s, 0);
2299 if (wpa_s->l2 == NULL)
2300 return -1;
2301 } else {
2302 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2303 if (addr)
2304 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
2305 }
2306
2307 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
2308 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
2309 return -1;
2310 }
2311
2312 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2313 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002314 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2315
2316 return 0;
2317}
2318
2319
Dmitry Shmidt04949592012-07-19 12:16:46 -07002320static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2321 const u8 *buf, size_t len)
2322{
2323 struct wpa_supplicant *wpa_s = ctx;
2324 const struct l2_ethhdr *eth;
2325
2326 if (len < sizeof(*eth))
2327 return;
2328 eth = (const struct l2_ethhdr *) buf;
2329
2330 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2331 !(eth->h_dest[0] & 0x01)) {
2332 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2333 " (bridge - not for this interface - ignore)",
2334 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2335 return;
2336 }
2337
2338 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2339 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2340 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2341 len - sizeof(*eth));
2342}
2343
2344
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002345/**
2346 * wpa_supplicant_driver_init - Initialize driver interface parameters
2347 * @wpa_s: Pointer to wpa_supplicant data
2348 * Returns: 0 on success, -1 on failure
2349 *
2350 * This function is called to initialize driver interface parameters.
2351 * wpa_drv_init() must have been called before this function to initialize the
2352 * driver interface.
2353 */
2354int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2355{
2356 static int interface_count = 0;
2357
2358 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2359 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002360
2361 if (wpa_s->bridge_ifname[0]) {
2362 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2363 "interface '%s'", wpa_s->bridge_ifname);
2364 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2365 wpa_s->own_addr,
2366 ETH_P_EAPOL,
Dmitry Shmidt04949592012-07-19 12:16:46 -07002367 wpa_supplicant_rx_eapol_bridge,
2368 wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002369 if (wpa_s->l2_br == NULL) {
2370 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2371 "connection for the bridge interface '%s'",
2372 wpa_s->bridge_ifname);
2373 return -1;
2374 }
2375 }
2376
2377 wpa_clear_keys(wpa_s, NULL);
2378
2379 /* Make sure that TKIP countermeasures are not left enabled (could
2380 * happen if wpa_supplicant is killed during countermeasures. */
2381 wpa_drv_set_countermeasures(wpa_s, 0);
2382
2383 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
2384 wpa_drv_flush_pmkid(wpa_s);
2385
2386 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002387 wpa_s->prev_scan_wildcard = 0;
2388
Dmitry Shmidt04949592012-07-19 12:16:46 -07002389 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002390 if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
2391 100000))
2392 wpa_supplicant_req_scan(wpa_s, interface_count,
2393 100000);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002394 interface_count++;
2395 } else
2396 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
2397
2398 return 0;
2399}
2400
2401
2402static int wpa_supplicant_daemon(const char *pid_file)
2403{
2404 wpa_printf(MSG_DEBUG, "Daemonize..");
2405 return os_daemonize(pid_file);
2406}
2407
2408
2409static struct wpa_supplicant * wpa_supplicant_alloc(void)
2410{
2411 struct wpa_supplicant *wpa_s;
2412
2413 wpa_s = os_zalloc(sizeof(*wpa_s));
2414 if (wpa_s == NULL)
2415 return NULL;
2416 wpa_s->scan_req = 1;
2417 wpa_s->scan_interval = 5;
2418 wpa_s->new_connection = 1;
2419 wpa_s->parent = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002420 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002421
2422 return wpa_s;
2423}
2424
2425
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002426#ifdef CONFIG_HT_OVERRIDES
2427
2428static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2429 struct ieee80211_ht_capabilities *htcaps,
2430 struct ieee80211_ht_capabilities *htcaps_mask,
2431 const char *ht_mcs)
2432{
2433 /* parse ht_mcs into hex array */
2434 int i;
2435 const char *tmp = ht_mcs;
2436 char *end = NULL;
2437
2438 /* If ht_mcs is null, do not set anything */
2439 if (!ht_mcs)
2440 return 0;
2441
2442 /* This is what we are setting in the kernel */
2443 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2444
2445 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2446
2447 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2448 errno = 0;
2449 long v = strtol(tmp, &end, 16);
2450 if (errno == 0) {
2451 wpa_msg(wpa_s, MSG_DEBUG,
2452 "htcap value[%i]: %ld end: %p tmp: %p",
2453 i, v, end, tmp);
2454 if (end == tmp)
2455 break;
2456
2457 htcaps->supported_mcs_set[i] = v;
2458 tmp = end;
2459 } else {
2460 wpa_msg(wpa_s, MSG_ERROR,
2461 "Failed to parse ht-mcs: %s, error: %s\n",
2462 ht_mcs, strerror(errno));
2463 return -1;
2464 }
2465 }
2466
2467 /*
2468 * If we were able to parse any values, then set mask for the MCS set.
2469 */
2470 if (i) {
2471 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2472 IEEE80211_HT_MCS_MASK_LEN - 1);
2473 /* skip the 3 reserved bits */
2474 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2475 0x1f;
2476 }
2477
2478 return 0;
2479}
2480
2481
2482static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2483 struct ieee80211_ht_capabilities *htcaps,
2484 struct ieee80211_ht_capabilities *htcaps_mask,
2485 int disabled)
2486{
2487 u16 msk;
2488
2489 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2490
2491 if (disabled == -1)
2492 return 0;
2493
2494 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2495 htcaps_mask->ht_capabilities_info |= msk;
2496 if (disabled)
2497 htcaps->ht_capabilities_info &= msk;
2498 else
2499 htcaps->ht_capabilities_info |= msk;
2500
2501 return 0;
2502}
2503
2504
2505static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2506 struct ieee80211_ht_capabilities *htcaps,
2507 struct ieee80211_ht_capabilities *htcaps_mask,
2508 int factor)
2509{
2510 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2511
2512 if (factor == -1)
2513 return 0;
2514
2515 if (factor < 0 || factor > 3) {
2516 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2517 "Must be 0-3 or -1", factor);
2518 return -EINVAL;
2519 }
2520
2521 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2522 htcaps->a_mpdu_params &= ~0x3;
2523 htcaps->a_mpdu_params |= factor & 0x3;
2524
2525 return 0;
2526}
2527
2528
2529static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2530 struct ieee80211_ht_capabilities *htcaps,
2531 struct ieee80211_ht_capabilities *htcaps_mask,
2532 int density)
2533{
2534 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2535
2536 if (density == -1)
2537 return 0;
2538
2539 if (density < 0 || density > 7) {
2540 wpa_msg(wpa_s, MSG_ERROR,
2541 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2542 density);
2543 return -EINVAL;
2544 }
2545
2546 htcaps_mask->a_mpdu_params |= 0x1C;
2547 htcaps->a_mpdu_params &= ~(0x1C);
2548 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2549
2550 return 0;
2551}
2552
2553
2554static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2555 struct ieee80211_ht_capabilities *htcaps,
2556 struct ieee80211_ht_capabilities *htcaps_mask,
2557 int disabled)
2558{
2559 /* Masking these out disables HT40 */
2560 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2561 HT_CAP_INFO_SHORT_GI40MHZ);
2562
2563 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2564
2565 if (disabled)
2566 htcaps->ht_capabilities_info &= ~msk;
2567 else
2568 htcaps->ht_capabilities_info |= msk;
2569
2570 htcaps_mask->ht_capabilities_info |= msk;
2571
2572 return 0;
2573}
2574
2575
2576void wpa_supplicant_apply_ht_overrides(
2577 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2578 struct wpa_driver_associate_params *params)
2579{
2580 struct ieee80211_ht_capabilities *htcaps;
2581 struct ieee80211_ht_capabilities *htcaps_mask;
2582
2583 if (!ssid)
2584 return;
2585
2586 params->disable_ht = ssid->disable_ht;
2587 if (!params->htcaps || !params->htcaps_mask)
2588 return;
2589
2590 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2591 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2592 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2593 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2594 ssid->disable_max_amsdu);
2595 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2596 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2597 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
2598}
2599
2600#endif /* CONFIG_HT_OVERRIDES */
2601
2602
Dmitry Shmidt04949592012-07-19 12:16:46 -07002603static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
2604{
2605#ifdef PCSC_FUNCS
2606 size_t len;
2607
2608 if (!wpa_s->conf->pcsc_reader)
2609 return 0;
2610
2611 wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
2612 if (!wpa_s->scard)
2613 return 1;
2614
2615 if (wpa_s->conf->pcsc_pin &&
2616 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
2617 scard_deinit(wpa_s->scard);
2618 wpa_s->scard = NULL;
2619 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
2620 return -1;
2621 }
2622
2623 len = sizeof(wpa_s->imsi) - 1;
2624 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
2625 scard_deinit(wpa_s->scard);
2626 wpa_s->scard = NULL;
2627 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
2628 return -1;
2629 }
2630 wpa_s->imsi[len] = '\0';
2631
2632 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
2633
2634 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
2635 wpa_s->imsi, wpa_s->mnc_len);
2636
2637 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
2638 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
2639#endif /* PCSC_FUNCS */
2640
2641 return 0;
2642}
2643
2644
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002645int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
2646{
2647 char *val, *pos;
2648
2649 ext_password_deinit(wpa_s->ext_pw);
2650 wpa_s->ext_pw = NULL;
2651 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
2652
2653 if (!wpa_s->conf->ext_password_backend)
2654 return 0;
2655
2656 val = os_strdup(wpa_s->conf->ext_password_backend);
2657 if (val == NULL)
2658 return -1;
2659 pos = os_strchr(val, ':');
2660 if (pos)
2661 *pos++ = '\0';
2662
2663 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
2664
2665 wpa_s->ext_pw = ext_password_init(val, pos);
2666 os_free(val);
2667 if (wpa_s->ext_pw == NULL) {
2668 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
2669 return -1;
2670 }
2671 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
2672
2673 return 0;
2674}
2675
2676
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002677static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
2678 struct wpa_interface *iface)
2679{
2680 const char *ifname, *driver;
2681 struct wpa_driver_capa capa;
2682
2683 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
2684 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
2685 iface->confname ? iface->confname : "N/A",
2686 iface->driver ? iface->driver : "default",
2687 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
2688 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
2689
2690 if (iface->confname) {
2691#ifdef CONFIG_BACKEND_FILE
2692 wpa_s->confname = os_rel2abs_path(iface->confname);
2693 if (wpa_s->confname == NULL) {
2694 wpa_printf(MSG_ERROR, "Failed to get absolute path "
2695 "for configuration file '%s'.",
2696 iface->confname);
2697 return -1;
2698 }
2699 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
2700 iface->confname, wpa_s->confname);
2701#else /* CONFIG_BACKEND_FILE */
2702 wpa_s->confname = os_strdup(iface->confname);
2703#endif /* CONFIG_BACKEND_FILE */
2704 wpa_s->conf = wpa_config_read(wpa_s->confname);
2705 if (wpa_s->conf == NULL) {
2706 wpa_printf(MSG_ERROR, "Failed to read or parse "
2707 "configuration '%s'.", wpa_s->confname);
2708 return -1;
2709 }
2710
2711 /*
2712 * Override ctrl_interface and driver_param if set on command
2713 * line.
2714 */
2715 if (iface->ctrl_interface) {
2716 os_free(wpa_s->conf->ctrl_interface);
2717 wpa_s->conf->ctrl_interface =
2718 os_strdup(iface->ctrl_interface);
2719 }
2720
2721 if (iface->driver_param) {
2722 os_free(wpa_s->conf->driver_param);
2723 wpa_s->conf->driver_param =
2724 os_strdup(iface->driver_param);
2725 }
2726 } else
2727 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
2728 iface->driver_param);
2729
2730 if (wpa_s->conf == NULL) {
2731 wpa_printf(MSG_ERROR, "\nNo configuration found.");
2732 return -1;
2733 }
2734
2735 if (iface->ifname == NULL) {
2736 wpa_printf(MSG_ERROR, "\nInterface name is required.");
2737 return -1;
2738 }
2739 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
2740 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
2741 iface->ifname);
2742 return -1;
2743 }
2744 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
2745
2746 if (iface->bridge_ifname) {
2747 if (os_strlen(iface->bridge_ifname) >=
2748 sizeof(wpa_s->bridge_ifname)) {
2749 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
2750 "name '%s'.", iface->bridge_ifname);
2751 return -1;
2752 }
2753 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
2754 sizeof(wpa_s->bridge_ifname));
2755 }
2756
2757 /* RSNA Supplicant Key Management - INITIALIZE */
2758 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2759 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2760
2761 /* Initialize driver interface and register driver event handler before
2762 * L2 receive handler so that association events are processed before
2763 * EAPOL-Key packets if both become available for the same select()
2764 * call. */
2765 driver = iface->driver;
2766next_driver:
2767 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
2768 return -1;
2769
2770 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
2771 if (wpa_s->drv_priv == NULL) {
2772 const char *pos;
2773 pos = driver ? os_strchr(driver, ',') : NULL;
2774 if (pos) {
2775 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
2776 "driver interface - try next driver wrapper");
2777 driver = pos + 1;
2778 goto next_driver;
2779 }
2780 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
2781 "interface");
2782 return -1;
2783 }
2784 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
2785 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
2786 "driver_param '%s'", wpa_s->conf->driver_param);
2787 return -1;
2788 }
2789
2790 ifname = wpa_drv_get_ifname(wpa_s);
2791 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
2792 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
2793 "interface name with '%s'", ifname);
2794 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
2795 }
2796
2797 if (wpa_supplicant_init_wpa(wpa_s) < 0)
2798 return -1;
2799
2800 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
2801 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
2802 NULL);
2803 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
2804
2805 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
2806 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
2807 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
2808 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2809 "dot11RSNAConfigPMKLifetime");
2810 return -1;
2811 }
2812
2813 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
2814 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
2815 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
2816 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2817 "dot11RSNAConfigPMKReauthThreshold");
2818 return -1;
2819 }
2820
2821 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
2822 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
2823 wpa_s->conf->dot11RSNAConfigSATimeout)) {
2824 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
2825 "dot11RSNAConfigSATimeout");
2826 return -1;
2827 }
2828
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002829 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
2830 &wpa_s->hw.num_modes,
2831 &wpa_s->hw.flags);
2832
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002833 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002834 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002835 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002836 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002837 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002838 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002839 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
2840 wpa_s->sched_scan_supported = capa.sched_scan_supported;
2841 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002842 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
2843 wpa_s->max_stations = capa.max_stations;
2844 }
2845 if (wpa_s->max_remain_on_chan == 0)
2846 wpa_s->max_remain_on_chan = 1000;
2847
2848 if (wpa_supplicant_driver_init(wpa_s) < 0)
2849 return -1;
2850
2851#ifdef CONFIG_TDLS
2852 if (wpa_tdls_init(wpa_s->wpa))
2853 return -1;
2854#endif /* CONFIG_TDLS */
2855
2856 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
2857 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
2858 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
2859 return -1;
2860 }
2861
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002862 if (wpas_wps_init(wpa_s))
2863 return -1;
2864
2865 if (wpa_supplicant_init_eapol(wpa_s) < 0)
2866 return -1;
2867 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2868
2869 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
2870 if (wpa_s->ctrl_iface == NULL) {
2871 wpa_printf(MSG_ERROR,
2872 "Failed to initialize control interface '%s'.\n"
2873 "You may have another wpa_supplicant process "
2874 "already running or the file was\n"
2875 "left by an unclean termination of wpa_supplicant "
2876 "in which case you will need\n"
2877 "to manually remove this file before starting "
2878 "wpa_supplicant again.\n",
2879 wpa_s->conf->ctrl_interface);
2880 return -1;
2881 }
2882
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002883 wpa_s->gas = gas_query_init(wpa_s);
2884 if (wpa_s->gas == NULL) {
2885 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
2886 return -1;
2887 }
2888
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002889#ifdef CONFIG_P2P
2890 if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
2891 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
2892 return -1;
2893 }
2894#endif /* CONFIG_P2P */
2895
2896 if (wpa_bss_init(wpa_s) < 0)
2897 return -1;
2898
Dmitry Shmidt04949592012-07-19 12:16:46 -07002899 if (pcsc_reader_init(wpa_s) < 0)
2900 return -1;
2901
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002902 if (wpas_init_ext_pw(wpa_s) < 0)
2903 return -1;
2904
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002905 return 0;
2906}
2907
2908
2909static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07002910 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002911{
2912 if (wpa_s->drv_priv) {
2913 wpa_supplicant_deauthenticate(wpa_s,
2914 WLAN_REASON_DEAUTH_LEAVING);
2915
2916 wpa_drv_set_countermeasures(wpa_s, 0);
2917 wpa_clear_keys(wpa_s, NULL);
2918 }
2919
2920 wpa_supplicant_cleanup(wpa_s);
2921
Dmitry Shmidt04949592012-07-19 12:16:46 -07002922#ifdef CONFIG_P2P
2923 if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
2924 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
2925 "the management interface is being removed");
2926 wpas_p2p_deinit_global(wpa_s->global);
2927 }
2928#endif /* CONFIG_P2P */
2929
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002930 if (wpa_s->drv_priv)
2931 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07002932
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07002933 if (notify)
2934 wpas_notify_iface_removed(wpa_s);
2935
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07002936 if (terminate)
2937 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07002938
2939 if (wpa_s->ctrl_iface) {
2940 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
2941 wpa_s->ctrl_iface = NULL;
2942 }
2943
2944 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07002945 wpa_config_free(wpa_s->conf);
2946 wpa_s->conf = NULL;
2947 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002948}
2949
2950
2951/**
2952 * wpa_supplicant_add_iface - Add a new network interface
2953 * @global: Pointer to global data from wpa_supplicant_init()
2954 * @iface: Interface configuration options
2955 * Returns: Pointer to the created interface or %NULL on failure
2956 *
2957 * This function is used to add new network interfaces for %wpa_supplicant.
2958 * This can be called before wpa_supplicant_run() to add interfaces before the
2959 * main event loop has been started. In addition, new interfaces can be added
2960 * dynamically while %wpa_supplicant is already running. This could happen,
2961 * e.g., when a hotplug network adapter is inserted.
2962 */
2963struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
2964 struct wpa_interface *iface)
2965{
2966 struct wpa_supplicant *wpa_s;
2967 struct wpa_interface t_iface;
2968 struct wpa_ssid *ssid;
2969
2970 if (global == NULL || iface == NULL)
2971 return NULL;
2972
2973 wpa_s = wpa_supplicant_alloc();
2974 if (wpa_s == NULL)
2975 return NULL;
2976
2977 wpa_s->global = global;
2978
2979 t_iface = *iface;
2980 if (global->params.override_driver) {
2981 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
2982 "('%s' -> '%s')",
2983 iface->driver, global->params.override_driver);
2984 t_iface.driver = global->params.override_driver;
2985 }
2986 if (global->params.override_ctrl_interface) {
2987 wpa_printf(MSG_DEBUG, "Override interface parameter: "
2988 "ctrl_interface ('%s' -> '%s')",
2989 iface->ctrl_interface,
2990 global->params.override_ctrl_interface);
2991 t_iface.ctrl_interface =
2992 global->params.override_ctrl_interface;
2993 }
2994 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
2995 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
2996 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07002997 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002998 os_free(wpa_s);
2999 return NULL;
3000 }
3001
3002 /* Notify the control interfaces about new iface */
3003 if (wpas_notify_iface_added(wpa_s)) {
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003004 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003005 os_free(wpa_s);
3006 return NULL;
3007 }
3008
3009 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3010 wpas_notify_network_added(wpa_s, ssid);
3011
3012 wpa_s->next = global->ifaces;
3013 global->ifaces = wpa_s;
3014
3015 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003016 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003017
3018 return wpa_s;
3019}
3020
3021
3022/**
3023 * wpa_supplicant_remove_iface - Remove a network interface
3024 * @global: Pointer to global data from wpa_supplicant_init()
3025 * @wpa_s: Pointer to the network interface to be removed
3026 * Returns: 0 if interface was removed, -1 if interface was not found
3027 *
3028 * This function can be used to dynamically remove network interfaces from
3029 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3030 * addition, this function is used to remove all remaining interfaces when
3031 * %wpa_supplicant is terminated.
3032 */
3033int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003034 struct wpa_supplicant *wpa_s,
3035 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003036{
3037 struct wpa_supplicant *prev;
3038
3039 /* Remove interface from the global list of interfaces */
3040 prev = global->ifaces;
3041 if (prev == wpa_s) {
3042 global->ifaces = wpa_s->next;
3043 } else {
3044 while (prev && prev->next != wpa_s)
3045 prev = prev->next;
3046 if (prev == NULL)
3047 return -1;
3048 prev->next = wpa_s->next;
3049 }
3050
3051 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
3052
3053 if (global->p2p_group_formation == wpa_s)
3054 global->p2p_group_formation = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003055 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003056 os_free(wpa_s);
3057
3058 return 0;
3059}
3060
3061
3062/**
3063 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3064 * @wpa_s: Pointer to the network interface
3065 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3066 */
3067const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3068{
3069 const char *eapol_method;
3070
3071 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3072 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3073 return "NO-EAP";
3074 }
3075
3076 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3077 if (eapol_method == NULL)
3078 return "UNKNOWN-EAP";
3079
3080 return eapol_method;
3081}
3082
3083
3084/**
3085 * wpa_supplicant_get_iface - Get a new network interface
3086 * @global: Pointer to global data from wpa_supplicant_init()
3087 * @ifname: Interface name
3088 * Returns: Pointer to the interface or %NULL if not found
3089 */
3090struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3091 const char *ifname)
3092{
3093 struct wpa_supplicant *wpa_s;
3094
3095 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3096 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3097 return wpa_s;
3098 }
3099 return NULL;
3100}
3101
3102
3103#ifndef CONFIG_NO_WPA_MSG
3104static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3105{
3106 struct wpa_supplicant *wpa_s = ctx;
3107 if (wpa_s == NULL)
3108 return NULL;
3109 return wpa_s->ifname;
3110}
3111#endif /* CONFIG_NO_WPA_MSG */
3112
3113
3114/**
3115 * wpa_supplicant_init - Initialize %wpa_supplicant
3116 * @params: Parameters for %wpa_supplicant
3117 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3118 *
3119 * This function is used to initialize %wpa_supplicant. After successful
3120 * initialization, the returned data pointer can be used to add and remove
3121 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3122 */
3123struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3124{
3125 struct wpa_global *global;
3126 int ret, i;
3127
3128 if (params == NULL)
3129 return NULL;
3130
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003131#ifdef CONFIG_DRIVER_NDIS
3132 {
3133 void driver_ndis_init_ops(void);
3134 driver_ndis_init_ops();
3135 }
3136#endif /* CONFIG_DRIVER_NDIS */
3137
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003138#ifndef CONFIG_NO_WPA_MSG
3139 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
3140#endif /* CONFIG_NO_WPA_MSG */
3141
3142 wpa_debug_open_file(params->wpa_debug_file_path);
3143 if (params->wpa_debug_syslog)
3144 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003145 if (params->wpa_debug_tracing) {
3146 ret = wpa_debug_open_linux_tracing();
3147 if (ret) {
3148 wpa_printf(MSG_ERROR,
3149 "Failed to enable trace logging");
3150 return NULL;
3151 }
3152 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003153
3154 ret = eap_register_methods();
3155 if (ret) {
3156 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3157 if (ret == -2)
3158 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
3159 "the same EAP type.");
3160 return NULL;
3161 }
3162
3163 global = os_zalloc(sizeof(*global));
3164 if (global == NULL)
3165 return NULL;
3166 dl_list_init(&global->p2p_srv_bonjour);
3167 dl_list_init(&global->p2p_srv_upnp);
3168 global->params.daemonize = params->daemonize;
3169 global->params.wait_for_monitor = params->wait_for_monitor;
3170 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
3171 if (params->pid_file)
3172 global->params.pid_file = os_strdup(params->pid_file);
3173 if (params->ctrl_interface)
3174 global->params.ctrl_interface =
3175 os_strdup(params->ctrl_interface);
3176 if (params->override_driver)
3177 global->params.override_driver =
3178 os_strdup(params->override_driver);
3179 if (params->override_ctrl_interface)
3180 global->params.override_ctrl_interface =
3181 os_strdup(params->override_ctrl_interface);
3182 wpa_debug_level = global->params.wpa_debug_level =
3183 params->wpa_debug_level;
3184 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
3185 params->wpa_debug_show_keys;
3186 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
3187 params->wpa_debug_timestamp;
3188
3189 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
3190
3191 if (eloop_init()) {
3192 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3193 wpa_supplicant_deinit(global);
3194 return NULL;
3195 }
3196
Jouni Malinen75ecf522011-06-27 15:19:46 -07003197 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003198
3199 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
3200 if (global->ctrl_iface == NULL) {
3201 wpa_supplicant_deinit(global);
3202 return NULL;
3203 }
3204
3205 if (wpas_notify_supplicant_initialized(global)) {
3206 wpa_supplicant_deinit(global);
3207 return NULL;
3208 }
3209
3210 for (i = 0; wpa_drivers[i]; i++)
3211 global->drv_count++;
3212 if (global->drv_count == 0) {
3213 wpa_printf(MSG_ERROR, "No drivers enabled");
3214 wpa_supplicant_deinit(global);
3215 return NULL;
3216 }
3217 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
3218 if (global->drv_priv == NULL) {
3219 wpa_supplicant_deinit(global);
3220 return NULL;
3221 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003222
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003223#ifdef CONFIG_WIFI_DISPLAY
3224 if (wifi_display_init(global) < 0) {
3225 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
3226 wpa_supplicant_deinit(global);
3227 return NULL;
3228 }
3229#endif /* CONFIG_WIFI_DISPLAY */
3230
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003231 return global;
3232}
3233
3234
3235/**
3236 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
3237 * @global: Pointer to global data from wpa_supplicant_init()
3238 * Returns: 0 after successful event loop run, -1 on failure
3239 *
3240 * This function starts the main event loop and continues running as long as
3241 * there are any remaining events. In most cases, this function is running as
3242 * long as the %wpa_supplicant process in still in use.
3243 */
3244int wpa_supplicant_run(struct wpa_global *global)
3245{
3246 struct wpa_supplicant *wpa_s;
3247
3248 if (global->params.daemonize &&
3249 wpa_supplicant_daemon(global->params.pid_file))
3250 return -1;
3251
3252 if (global->params.wait_for_monitor) {
3253 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
3254 if (wpa_s->ctrl_iface)
3255 wpa_supplicant_ctrl_iface_wait(
3256 wpa_s->ctrl_iface);
3257 }
3258
3259 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
3260 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
3261
3262 eloop_run();
3263
3264 return 0;
3265}
3266
3267
3268/**
3269 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
3270 * @global: Pointer to global data from wpa_supplicant_init()
3271 *
3272 * This function is called to deinitialize %wpa_supplicant and to free all
3273 * allocated resources. Remaining network interfaces will also be removed.
3274 */
3275void wpa_supplicant_deinit(struct wpa_global *global)
3276{
3277 int i;
3278
3279 if (global == NULL)
3280 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003281
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003282#ifdef CONFIG_WIFI_DISPLAY
3283 wifi_display_deinit(global);
3284#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003285#ifdef CONFIG_P2P
3286 wpas_p2p_deinit_global(global);
3287#endif /* CONFIG_P2P */
3288
3289 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07003290 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003291
3292 if (global->ctrl_iface)
3293 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
3294
3295 wpas_notify_supplicant_deinitialized(global);
3296
3297 eap_peer_unregister_methods();
3298#ifdef CONFIG_AP
3299 eap_server_unregister_methods();
3300#endif /* CONFIG_AP */
3301
3302 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
3303 if (!global->drv_priv[i])
3304 continue;
3305 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
3306 }
3307 os_free(global->drv_priv);
3308
3309 random_deinit();
3310
3311 eloop_destroy();
3312
3313 if (global->params.pid_file) {
3314 os_daemonize_terminate(global->params.pid_file);
3315 os_free(global->params.pid_file);
3316 }
3317 os_free(global->params.ctrl_interface);
3318 os_free(global->params.override_driver);
3319 os_free(global->params.override_ctrl_interface);
3320
Dmitry Shmidt04949592012-07-19 12:16:46 -07003321 os_free(global->p2p_disallow_freq);
3322
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003323 os_free(global);
3324 wpa_debug_close_syslog();
3325 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07003326 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003327}
3328
3329
3330void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
3331{
3332 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
3333 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
3334 char country[3];
3335 country[0] = wpa_s->conf->country[0];
3336 country[1] = wpa_s->conf->country[1];
3337 country[2] = '\0';
3338 if (wpa_drv_set_country(wpa_s, country) < 0) {
3339 wpa_printf(MSG_ERROR, "Failed to set country code "
3340 "'%s'", country);
3341 }
3342 }
3343
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003344 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
3345 wpas_init_ext_pw(wpa_s);
3346
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003347#ifdef CONFIG_WPS
3348 wpas_wps_update_config(wpa_s);
3349#endif /* CONFIG_WPS */
3350
3351#ifdef CONFIG_P2P
3352 wpas_p2p_update_config(wpa_s);
3353#endif /* CONFIG_P2P */
3354
3355 wpa_s->conf->changed_parameters = 0;
3356}
3357
3358
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003359static void add_freq(int *freqs, int *num_freqs, int freq)
3360{
3361 int i;
3362
3363 for (i = 0; i < *num_freqs; i++) {
3364 if (freqs[i] == freq)
3365 return;
3366 }
3367
3368 freqs[*num_freqs] = freq;
3369 (*num_freqs)++;
3370}
3371
3372
3373static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
3374{
3375 struct wpa_bss *bss, *cbss;
3376 const int max_freqs = 10;
3377 int *freqs;
3378 int num_freqs = 0;
3379
3380 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
3381 if (freqs == NULL)
3382 return NULL;
3383
3384 cbss = wpa_s->current_bss;
3385
3386 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
3387 if (bss == cbss)
3388 continue;
3389 if (bss->ssid_len == cbss->ssid_len &&
3390 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
3391 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
3392 add_freq(freqs, &num_freqs, bss->freq);
3393 if (num_freqs == max_freqs)
3394 break;
3395 }
3396 }
3397
3398 if (num_freqs == 0) {
3399 os_free(freqs);
3400 freqs = NULL;
3401 }
3402
3403 return freqs;
3404}
3405
3406
3407void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
3408{
3409 int timeout;
3410 int count;
3411 int *freqs = NULL;
3412
3413 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003414 * Remove possible authentication timeout since the connection failed.
3415 */
3416 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3417
3418 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003419 * Add the failed BSSID into the blacklist and speed up next scan
3420 * attempt if there could be other APs that could accept association.
3421 * The current blacklist count indicates how many times we have tried
3422 * connecting to this AP and multiple attempts mean that other APs are
3423 * either not available or has already been tried, so that we can start
3424 * increasing the delay here to avoid constant scanning.
3425 */
3426 count = wpa_blacklist_add(wpa_s, bssid);
3427 if (count == 1 && wpa_s->current_bss) {
3428 /*
3429 * This BSS was not in the blacklist before. If there is
3430 * another BSS available for the same ESS, we should try that
3431 * next. Otherwise, we may as well try this one once more
3432 * before allowing other, likely worse, ESSes to be considered.
3433 */
3434 freqs = get_bss_freqs_in_ess(wpa_s);
3435 if (freqs) {
3436 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
3437 "has been seen; try it next");
3438 wpa_blacklist_add(wpa_s, bssid);
3439 /*
3440 * On the next scan, go through only the known channels
3441 * used in this ESS based on previous scans to speed up
3442 * common load balancing use case.
3443 */
3444 os_free(wpa_s->next_scan_freqs);
3445 wpa_s->next_scan_freqs = freqs;
3446 }
3447 }
3448
3449 switch (count) {
3450 case 1:
3451 timeout = 100;
3452 break;
3453 case 2:
3454 timeout = 500;
3455 break;
3456 case 3:
3457 timeout = 1000;
3458 break;
3459 default:
3460 timeout = 5000;
3461 }
3462
3463 /*
3464 * TODO: if more than one possible AP is available in scan results,
3465 * could try the other ones before requesting a new scan.
3466 */
3467 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
3468 1000 * (timeout % 1000));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003469
3470#ifdef CONFIG_P2P
3471 if (wpa_s->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
3472 wpa_s->global->p2p != NULL) {
3473 wpa_s->p2p_cb_on_scan_complete = 0;
3474 if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
3475 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
3476 "continued after failed association");
3477 }
3478 }
3479#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003480}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003481
3482
3483int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
3484{
3485 return wpa_s->conf->ap_scan == 2 ||
3486 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
3487}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003488
Dmitry Shmidt04949592012-07-19 12:16:46 -07003489
3490#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
3491int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
3492 struct wpa_ssid *ssid,
3493 const char *field,
3494 const char *value)
3495{
3496#ifdef IEEE8021X_EAPOL
3497 struct eap_peer_config *eap = &ssid->eap;
3498
3499 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
3500 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
3501 (const u8 *) value, os_strlen(value));
3502
3503 switch (wpa_supplicant_ctrl_req_from_string(field)) {
3504 case WPA_CTRL_REQ_EAP_IDENTITY:
3505 os_free(eap->identity);
3506 eap->identity = (u8 *) os_strdup(value);
3507 eap->identity_len = os_strlen(value);
3508 eap->pending_req_identity = 0;
3509 if (ssid == wpa_s->current_ssid)
3510 wpa_s->reassociate = 1;
3511 break;
3512 case WPA_CTRL_REQ_EAP_PASSWORD:
3513 os_free(eap->password);
3514 eap->password = (u8 *) os_strdup(value);
3515 eap->password_len = os_strlen(value);
3516 eap->pending_req_password = 0;
3517 if (ssid == wpa_s->current_ssid)
3518 wpa_s->reassociate = 1;
3519 break;
3520 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
3521 os_free(eap->new_password);
3522 eap->new_password = (u8 *) os_strdup(value);
3523 eap->new_password_len = os_strlen(value);
3524 eap->pending_req_new_password = 0;
3525 if (ssid == wpa_s->current_ssid)
3526 wpa_s->reassociate = 1;
3527 break;
3528 case WPA_CTRL_REQ_EAP_PIN:
3529 os_free(eap->pin);
3530 eap->pin = os_strdup(value);
3531 eap->pending_req_pin = 0;
3532 if (ssid == wpa_s->current_ssid)
3533 wpa_s->reassociate = 1;
3534 break;
3535 case WPA_CTRL_REQ_EAP_OTP:
3536 os_free(eap->otp);
3537 eap->otp = (u8 *) os_strdup(value);
3538 eap->otp_len = os_strlen(value);
3539 os_free(eap->pending_req_otp);
3540 eap->pending_req_otp = NULL;
3541 eap->pending_req_otp_len = 0;
3542 break;
3543 case WPA_CTRL_REQ_EAP_PASSPHRASE:
3544 os_free(eap->private_key_passwd);
3545 eap->private_key_passwd = (u8 *) os_strdup(value);
3546 eap->pending_req_passphrase = 0;
3547 if (ssid == wpa_s->current_ssid)
3548 wpa_s->reassociate = 1;
3549 break;
3550 default:
3551 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
3552 return -1;
3553 }
3554
3555 return 0;
3556#else /* IEEE8021X_EAPOL */
3557 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
3558 return -1;
3559#endif /* IEEE8021X_EAPOL */
3560}
3561#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
3562
3563
3564int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
3565{
3566 int i;
3567 unsigned int drv_enc;
3568
3569 if (ssid == NULL)
3570 return 1;
3571
3572 if (ssid->disabled)
3573 return 1;
3574
3575 if (wpa_s && wpa_s->drv_capa_known)
3576 drv_enc = wpa_s->drv_enc;
3577 else
3578 drv_enc = (unsigned int) -1;
3579
3580 for (i = 0; i < NUM_WEP_KEYS; i++) {
3581 size_t len = ssid->wep_key_len[i];
3582 if (len == 0)
3583 continue;
3584 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
3585 continue;
3586 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
3587 continue;
3588 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
3589 continue;
3590 return 1; /* invalid WEP key */
3591 }
3592
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003593 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
3594 !ssid->ext_psk)
3595 return 1;
3596
Dmitry Shmidt04949592012-07-19 12:16:46 -07003597 return 0;
3598}
3599
3600
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003601int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003602{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003603 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003604 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07003605 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003606 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07003607 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003608}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003609
3610
3611void wpas_auth_failed(struct wpa_supplicant *wpa_s)
3612{
3613 struct wpa_ssid *ssid = wpa_s->current_ssid;
3614 int dur;
3615 struct os_time now;
3616
3617 if (ssid == NULL) {
3618 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
3619 "SSID block");
3620 return;
3621 }
3622
3623 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
3624 return;
3625
3626 ssid->auth_failures++;
3627 if (ssid->auth_failures > 50)
3628 dur = 300;
3629 else if (ssid->auth_failures > 20)
3630 dur = 120;
3631 else if (ssid->auth_failures > 10)
3632 dur = 60;
3633 else if (ssid->auth_failures > 5)
3634 dur = 30;
3635 else if (ssid->auth_failures > 1)
3636 dur = 20;
3637 else
3638 dur = 10;
3639
3640 os_get_time(&now);
3641 if (now.sec + dur <= ssid->disabled_until.sec)
3642 return;
3643
3644 ssid->disabled_until.sec = now.sec + dur;
3645
3646 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
3647 "id=%d ssid=\"%s\" auth_failures=%u duration=%d",
3648 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
3649 ssid->auth_failures, dur);
3650}
3651
3652
3653void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
3654 struct wpa_ssid *ssid, int clear_failures)
3655{
3656 if (ssid == NULL)
3657 return;
3658
3659 if (ssid->disabled_until.sec) {
3660 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
3661 "id=%d ssid=\"%s\"",
3662 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
3663 }
3664 ssid->disabled_until.sec = 0;
3665 ssid->disabled_until.usec = 0;
3666 if (clear_failures)
3667 ssid->auth_failures = 0;
3668}