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