Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 888 lines (773 sloc) 23.975 kb
845e012 auto import from //depot/cupcake/@135843
The Android Open Source Project authored
1 /*
2 * WPA Supplicant - Driver event processing
3 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "eapol_sm.h"
19 #include "wpa.h"
20 #include "eloop.h"
21 #include "wpa_supplicant.h"
22 #include "config.h"
23 #include "l2_packet.h"
24 #include "wpa_supplicant_i.h"
25 #include "pcsc_funcs.h"
26 #include "preauth.h"
27 #include "pmksa_cache.h"
28 #include "wpa_ctrl.h"
29 #include "eap.h"
30 #include "ctrl_iface_dbus.h"
31
32
33 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
34 {
35 struct wpa_ssid *ssid;
36
37 if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid)
38 return 0;
39
40 ssid = wpa_supplicant_get_ssid(wpa_s);
41 if (ssid == NULL) {
42 wpa_printf(MSG_INFO, "No network configuration found for the "
43 "current AP");
44 return -1;
45 }
46
47 if (ssid->disabled) {
48 wpa_printf(MSG_DEBUG, "Selected network is disabled");
49 return -1;
50 }
51
52 wpa_printf(MSG_DEBUG, "Network configuration found for the current "
53 "AP");
54 if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
55 WPA_KEY_MGMT_WPA_NONE)) {
56 u8 wpa_ie[80];
57 size_t wpa_ie_len = sizeof(wpa_ie);
58 wpa_supplicant_set_suites(wpa_s, NULL, ssid,
59 wpa_ie, &wpa_ie_len);
60 } else {
61 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
62 }
63
64 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
65 eapol_sm_invalidate_cached_session(wpa_s->eapol);
66 wpa_s->current_ssid = ssid;
67 wpa_sm_set_config(wpa_s->wpa, wpa_s->current_ssid);
68 wpa_supplicant_initiate_eapol(wpa_s);
69
70 return 0;
71 }
72
73
74 static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
75 void *sock_ctx)
76 {
77 struct wpa_supplicant *wpa_s = eloop_ctx;
78
79 if (wpa_s->countermeasures) {
80 wpa_s->countermeasures = 0;
81 wpa_drv_set_countermeasures(wpa_s, 0);
82 wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
83 wpa_supplicant_req_scan(wpa_s, 0, 0);
84 }
85 }
86
87
88 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
89 {
90 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
91 os_memset(wpa_s->bssid, 0, ETH_ALEN);
92 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
93 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
94 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
95 if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK)
96 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
97 }
98
99
100 static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
101 {
102 struct wpa_ie_data ie;
103 int i, pmksa_set = -1;
104
105 if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
106 ie.pmkid == NULL)
107 return;
108
109 for (i = 0; i < ie.num_pmkid; i++) {
110 pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
111 ie.pmkid + i * PMKID_LEN,
112 NULL, NULL, 0);
113 if (pmksa_set == 0) {
114 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
115 break;
116 }
117 }
118
119 wpa_printf(MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from PMKSA "
120 "cache", pmksa_set == 0 ? "" : "not ");
121 }
122
123
124 static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
125 union wpa_event_data *data)
126 {
127 if (data == NULL) {
128 wpa_printf(MSG_DEBUG, "RSN: No data in PMKID candidate event");
129 return;
130 }
131 wpa_printf(MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
132 " index=%d preauth=%d",
133 MAC2STR(data->pmkid_candidate.bssid),
134 data->pmkid_candidate.index,
135 data->pmkid_candidate.preauth);
136
137 pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
138 data->pmkid_candidate.index,
139 data->pmkid_candidate.preauth);
140 }
141
142
143 static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
144 {
145 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
146 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
147 return 0;
148
149 #ifdef IEEE8021X_EAPOL
150 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
151 wpa_s->current_ssid &&
152 !(wpa_s->current_ssid->eapol_flags &
153 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
154 EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
155 /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
156 * plaintext or static WEP keys). */
157 return 0;
158 }
159 #endif /* IEEE8021X_EAPOL */
160
161 return 1;
162 }
163
164
165 /**
166 * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
167 * @wpa_s: pointer to wpa_supplicant data
168 * @ssid: Configuration data for the network
169 * Returns: 0 on success, -1 on failure
170 *
171 * This function is called when starting authentication with a network that is
172 * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
173 */
174 int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
175 struct wpa_ssid *ssid)
176 {
177 #ifdef IEEE8021X_EAPOL
178 int aka = 0, sim = 0, type;
179
180 if (ssid->pcsc == NULL || wpa_s->scard != NULL)
181 return 0;
182
183 if (ssid->eap_methods == NULL) {
184 sim = 1;
185 aka = 1;
186 } else {
187 struct eap_method_type *eap = ssid->eap_methods;
188 while (eap->vendor != EAP_VENDOR_IETF ||
189 eap->method != EAP_TYPE_NONE) {
190 if (eap->vendor == EAP_VENDOR_IETF) {
191 if (eap->method == EAP_TYPE_SIM)
192 sim = 1;
193 else if (eap->method == EAP_TYPE_AKA)
194 aka = 1;
195 }
196 eap++;
197 }
198 }
199
200 if (eap_sm_get_eap_methods(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
201 sim = 0;
202 if (eap_sm_get_eap_methods(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL)
203 aka = 0;
204
205 if (!sim && !aka) {
206 wpa_printf(MSG_DEBUG, "Selected network is configured to use "
207 "SIM, but neither EAP-SIM nor EAP-AKA are enabled");
208 return 0;
209 }
210
211 wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM "
212 "(sim=%d aka=%d) - initialize PCSC", sim, aka);
213 if (sim && aka)
214 type = SCARD_TRY_BOTH;
215 else if (aka)
216 type = SCARD_USIM_ONLY;
217 else
218 type = SCARD_GSM_SIM_ONLY;
219
220 wpa_s->scard = scard_init(type);
221 if (wpa_s->scard == NULL) {
222 wpa_printf(MSG_WARNING, "Failed to initialize SIM "
223 "(pcsc-lite)");
224 return -1;
225 }
226 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
227 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
228 #endif /* IEEE8021X_EAPOL */
229
230 return 0;
231 }
232
233
234 static int wpa_supplicant_match_privacy(struct wpa_scan_result *bss,
235 struct wpa_ssid *ssid)
236 {
237 int i, privacy = 0;
238
239 if (ssid->mixed_cell)
240 return 1;
241
242 for (i = 0; i < NUM_WEP_KEYS; i++) {
243 if (ssid->wep_key_len[i]) {
244 privacy = 1;
245 break;
246 }
247 }
248 #ifdef IEEE8021X_EAPOL
249 if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
250 ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
251 EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
252 privacy = 1;
253 #endif /* IEEE8021X_EAPOL */
254
255 if (bss->caps & IEEE80211_CAP_PRIVACY)
256 return privacy;
257 return !privacy;
258 }
259
260
261 static int wpa_supplicant_ssid_bss_match(struct wpa_ssid *ssid,
262 struct wpa_scan_result *bss)
263 {
264 struct wpa_ie_data ie;
265 int proto_match = 0;
266
267 while ((ssid->proto & WPA_PROTO_RSN) && bss->rsn_ie_len > 0) {
268 proto_match++;
269
270 if (wpa_parse_wpa_ie(bss->rsn_ie, bss->rsn_ie_len, &ie)) {
271 wpa_printf(MSG_DEBUG, " skip RSN IE - parse failed");
272 break;
273 }
274 if (!(ie.proto & ssid->proto)) {
275 wpa_printf(MSG_DEBUG, " skip RSN IE - proto "
276 "mismatch");
277 break;
278 }
279
280 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
281 wpa_printf(MSG_DEBUG, " skip RSN IE - PTK cipher "
282 "mismatch");
283 break;
284 }
285
286 if (!(ie.group_cipher & ssid->group_cipher)) {
287 wpa_printf(MSG_DEBUG, " skip RSN IE - GTK cipher "
288 "mismatch");
289 break;
290 }
291
292 if (!(ie.key_mgmt & ssid->key_mgmt)) {
293 wpa_printf(MSG_DEBUG, " skip RSN IE - key mgmt "
294 "mismatch");
295 break;
296 }
297
298 #ifdef CONFIG_IEEE80211W
299 if (!(ie.capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION)
300 && ssid->ieee80211w == IEEE80211W_REQUIRED) {
301 wpa_printf(MSG_DEBUG, " skip RSN IE - no mgmt frame "
302 "protection");
303 break;
304 }
305 #endif /* CONFIG_IEEE80211W */
306
307 wpa_printf(MSG_DEBUG, " selected based on RSN IE");
308 return 1;
309 }
310
311 while ((ssid->proto & WPA_PROTO_WPA) && bss->wpa_ie_len > 0) {
312 proto_match++;
313
314 if (wpa_parse_wpa_ie(bss->wpa_ie, bss->wpa_ie_len, &ie)) {
315 wpa_printf(MSG_DEBUG, " skip WPA IE - parse failed");
316 break;
317 }
318 if (!(ie.proto & ssid->proto)) {
319 wpa_printf(MSG_DEBUG, " skip WPA IE - proto "
320 "mismatch");
321 break;
322 }
323
324 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
325 wpa_printf(MSG_DEBUG, " skip WPA IE - PTK cipher "
326 "mismatch");
327 break;
328 }
329
330 if (!(ie.group_cipher & ssid->group_cipher)) {
331 wpa_printf(MSG_DEBUG, " skip WPA IE - GTK cipher "
332 "mismatch");
333 break;
334 }
335
336 if (!(ie.key_mgmt & ssid->key_mgmt)) {
337 wpa_printf(MSG_DEBUG, " skip WPA IE - key mgmt "
338 "mismatch");
339 break;
340 }
341
342 wpa_printf(MSG_DEBUG, " selected based on WPA IE");
343 return 1;
344 }
345
346 if (proto_match == 0)
347 wpa_printf(MSG_DEBUG, " skip - no WPA/RSN proto match");
348
349 return 0;
350 }
351
352
353 static struct wpa_scan_result *
354 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
355 struct wpa_scan_result *results, int num,
356 struct wpa_ssid **selected_ssid)
357 {
358 struct wpa_ssid *ssid;
359 struct wpa_scan_result *bss, *selected = NULL;
360 int i;
361 struct wpa_blacklist *e;
362
363 wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
364 group->priority);
365
366 bss = NULL;
367 ssid = NULL;
368 /* First, try to find WPA-enabled AP */
369 wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
370 for (i = 0; i < num && !selected; i++) {
371 bss = &results[i];
372 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
373 "wpa_ie_len=%lu rsn_ie_len=%lu caps=0x%x",
374 i, MAC2STR(bss->bssid),
375 wpa_ssid_txt(bss->ssid, bss->ssid_len),
376 (unsigned long) bss->wpa_ie_len,
377 (unsigned long) bss->rsn_ie_len, bss->caps);
378 e = wpa_blacklist_get(wpa_s, bss->bssid);
379 if (e && e->count > 1) {
380 wpa_printf(MSG_DEBUG, " skip - blacklisted");
381 continue;
382 }
383
384 if (bss->wpa_ie_len == 0 && bss->rsn_ie_len == 0) {
385 wpa_printf(MSG_DEBUG, " skip - no WPA/RSN IE");
386 continue;
387 }
388
389 for (ssid = group; ssid; ssid = ssid->pnext) {
390 if (ssid->disabled) {
391 wpa_printf(MSG_DEBUG, " skip - disabled");
392 continue;
393 }
394 if (bss->ssid_len != ssid->ssid_len ||
395 os_memcmp(bss->ssid, ssid->ssid,
396 bss->ssid_len) != 0) {
397 wpa_printf(MSG_DEBUG, " skip - "
398 "SSID mismatch");
399 continue;
400 }
401 if (ssid->bssid_set &&
402 os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
403 {
404 wpa_printf(MSG_DEBUG, " skip - "
405 "BSSID mismatch");
406 continue;
407 }
408 if (wpa_supplicant_ssid_bss_match(ssid, bss)) {
409 selected = bss;
410 *selected_ssid = ssid;
411 wpa_printf(MSG_DEBUG, " selected WPA AP "
412 MACSTR " ssid='%s'",
413 MAC2STR(bss->bssid),
414 wpa_ssid_txt(bss->ssid,
415 bss->ssid_len));
416 break;
417 }
418 }
419 }
420
421 /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
422 * allows this. */
423 wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
424 for (i = 0; i < num && !selected; i++) {
425 bss = &results[i];
426 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
427 "wpa_ie_len=%lu rsn_ie_len=%lu caps=0x%x",
428 i, MAC2STR(bss->bssid),
429 wpa_ssid_txt(bss->ssid, bss->ssid_len),
430 (unsigned long) bss->wpa_ie_len,
431 (unsigned long) bss->rsn_ie_len, bss->caps);
432 e = wpa_blacklist_get(wpa_s, bss->bssid);
433 if (e && e->count > 1) {
434 wpa_printf(MSG_DEBUG, " skip - blacklisted");
435 continue;
436 }
437 for (ssid = group; ssid; ssid = ssid->pnext) {
438 if (ssid->disabled) {
439 wpa_printf(MSG_DEBUG, " skip - disabled");
440 continue;
441 }
442 if (ssid->ssid_len != 0 &&
443 (bss->ssid_len != ssid->ssid_len ||
444 os_memcmp(bss->ssid, ssid->ssid,
445 bss->ssid_len) != 0)) {
446 wpa_printf(MSG_DEBUG, " skip - "
447 "SSID mismatch");
448 continue;
449 }
450
451 if (ssid->bssid_set &&
452 os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
453 {
454 wpa_printf(MSG_DEBUG, " skip - "
455 "BSSID mismatch");
456 continue;
457 }
458
459 if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
460 !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
461 {
462 wpa_printf(MSG_DEBUG, " skip - "
463 "non-WPA network not allowed");
464 continue;
465 }
466
467 if ((ssid->key_mgmt &
468 (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK)) &&
469 (bss->wpa_ie_len != 0 || bss->rsn_ie_len != 0)) {
470 wpa_printf(MSG_DEBUG, " skip - "
471 "WPA network");
472 continue;
473 }
474
475 if (!wpa_supplicant_match_privacy(bss, ssid)) {
476 wpa_printf(MSG_DEBUG, " skip - "
477 "privacy mismatch");
478 continue;
479 }
480
481 if (bss->caps & IEEE80211_CAP_IBSS) {
482 wpa_printf(MSG_DEBUG, " skip - "
483 "IBSS (adhoc) network");
484 continue;
485 }
486
487 selected = bss;
488 *selected_ssid = ssid;
489 wpa_printf(MSG_DEBUG, " selected non-WPA AP "
490 MACSTR " ssid='%s'",
491 MAC2STR(bss->bssid),
492 wpa_ssid_txt(bss->ssid, bss->ssid_len));
493 break;
494 }
495 }
496
497 return selected;
498 }
499
500
501 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
502 {
503 int num, prio, timeout;
504 struct wpa_scan_result *selected = NULL;
505 struct wpa_ssid *ssid = NULL;
506 struct wpa_scan_result *results;
507
692ddb2 Fix possible scan conflict if two scan commands are issued at same time
Dmitry Shmidt authored
508 wpa_s->scan_ongoing = 0;
845e012 auto import from //depot/cupcake/@135843
The Android Open Source Project authored
509 if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
510 if (wpa_s->conf->ap_scan == 2)
511 return;
512 wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
513 "scanning again");
514 timeout = 1;
515 goto req_scan;
516 }
517
518 wpa_supplicant_dbus_notify_scan_results(wpa_s);
692ddb2 Fix possible scan conflict if two scan commands are issued at same time
Dmitry Shmidt authored
519 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS " Ready");
845e012 auto import from //depot/cupcake/@135843
The Android Open Source Project authored
520
521 if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
522 return;
523 results = wpa_s->scan_results;
524 num = wpa_s->num_scan_results;
525
526 while (selected == NULL) {
527 for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
528 selected = wpa_supplicant_select_bss(
529 wpa_s, wpa_s->conf->pssid[prio], results, num,
530 &ssid);
531 if (selected)
532 break;
533 }
534
535 if (selected == NULL && wpa_s->blacklist) {
536 wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
537 "and try again");
538 wpa_blacklist_clear(wpa_s);
539 } else if (selected == NULL) {
540 break;
541 }
542 }
543
544 if (selected) {
545 /* Do not trigger new association unless the BSSID has changed
546 * or if reassociation is requested. If we are in process of
547 * associating with the selected BSSID, do not trigger new
548 * attempt. */
549 if (wpa_s->reassociate ||
550 (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
551 (wpa_s->wpa_state != WPA_ASSOCIATING ||
552 os_memcmp(selected->bssid, wpa_s->pending_bssid,
553 ETH_ALEN) != 0))) {
554 if (wpa_supplicant_scard_init(wpa_s, ssid)) {
555 wpa_supplicant_req_scan(wpa_s, 10, 0);
556 return;
557 }
558 wpa_supplicant_associate(wpa_s, selected, ssid);
559 } else {
560 wpa_printf(MSG_DEBUG, "Already associated with the "
561 "selected AP.");
562 }
563 rsn_preauth_scan_results(wpa_s->wpa, results, num);
564 } else {
565 wpa_printf(MSG_DEBUG, "No suitable AP found.");
566 #ifdef ANDROID
567 timeout = wpa_s->scan_interval;
568 #else
569 timeout = 5;
570 #endif
571 goto req_scan;
572 }
573
574 return;
575
576 req_scan:
577 if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
578 /*
579 * Quick recovery if the initial scan results were not
580 * complete when fetched before the first scan request.
581 */
582 wpa_s->scan_res_tried++;
583 timeout = 0;
584 }
585 wpa_supplicant_req_scan(wpa_s, timeout, 0);
586 }
587
588
589 static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
590 union wpa_event_data *data)
591 {
592 int l, len, found = 0, wpa_found, rsn_found;
593 u8 *p;
594
595 wpa_printf(MSG_DEBUG, "Association info event");
596 if (data->assoc_info.req_ies)
597 wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
598 data->assoc_info.req_ies_len);
599 if (data->assoc_info.resp_ies)
600 wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
601 data->assoc_info.resp_ies_len);
602 if (data->assoc_info.beacon_ies)
603 wpa_hexdump(MSG_DEBUG, "beacon_ies",
604 data->assoc_info.beacon_ies,
605 data->assoc_info.beacon_ies_len);
606
607 p = data->assoc_info.req_ies;
608 l = data->assoc_info.req_ies_len;
609
610 /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
611 while (p && l >= 2) {
612 len = p[1] + 2;
613 if (len > l) {
614 wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
615 p, l);
616 break;
617 }
618 if ((p[0] == GENERIC_INFO_ELEM && p[1] >= 6 &&
619 (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
620 (p[0] == RSN_INFO_ELEM && p[1] >= 2)) {
621 if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
622 break;
623 found = 1;
624 wpa_find_assoc_pmkid(wpa_s);
625 break;
626 }
627 l -= len;
628 p += len;
629 }
630 if (!found && data->assoc_info.req_ies)
631 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
632
633 /* WPA/RSN IE from Beacon/ProbeResp */
634 p = data->assoc_info.beacon_ies;
635 l = data->assoc_info.beacon_ies_len;
636
637 /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
638 */
639 wpa_found = rsn_found = 0;
640 while (p && l >= 2) {
641 len = p[1] + 2;
642 if (len > l) {
643 wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
644 p, l);
645 break;
646 }
647 if (!wpa_found &&
648 p[0] == GENERIC_INFO_ELEM && p[1] >= 6 &&
649 os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
650 wpa_found = 1;
651 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
652 }
653
654 if (!rsn_found &&
655 p[0] == RSN_INFO_ELEM && p[1] >= 2) {
656 rsn_found = 1;
657 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
658 }
659
660 l -= len;
661 p += len;
662 }
663
c5a0c70 Fix 5.5.2 PMK Caching issue
Dmitry Shmidt authored
664 if (!wpa_found)
845e012 auto import from //depot/cupcake/@135843
The Android Open Source Project authored
665 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
c5a0c70 Fix 5.5.2 PMK Caching issue
Dmitry Shmidt authored
666 if (!rsn_found)
845e012 auto import from //depot/cupcake/@135843
The Android Open Source Project authored
667 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
668 }
669
670
671 static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
672 union wpa_event_data *data)
673 {
674 u8 bssid[ETH_ALEN];
675
676 if (data)
677 wpa_supplicant_event_associnfo(wpa_s, data);
678
679 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
680 if (wpa_s->use_client_mlme)
681 os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
682 if (wpa_s->use_client_mlme ||
683 (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
684 os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
685 wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
686 MACSTR, MAC2STR(bssid));
687 os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
688 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
689 if (wpa_supplicant_dynamic_keys(wpa_s)) {
690 wpa_clear_keys(wpa_s, bssid);
691 }
692 if (wpa_supplicant_select_config(wpa_s) < 0) {
693 wpa_supplicant_disassociate(wpa_s,
694 REASON_DEAUTH_LEAVING);
695 return;
696 }
697 }
698
699 wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
700 if (wpa_s->current_ssid) {
701 /* When using scanning (ap_scan=1), SIM PC/SC interface can be
702 * initialized before association, but for other modes,
703 * initialize PC/SC here, if the current configuration needs
704 * smartcard or SIM/USIM. */
705 wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
706 }
707 wpa_sm_notify_assoc(wpa_s->wpa, bssid);
708 l2_packet_notify_auth_start(wpa_s->l2);
709
710 /*
711 * Set portEnabled first to FALSE in order to get EAP state machine out
712 * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
713 * state machine may transit to AUTHENTICATING state based on obsolete
714 * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
715 * AUTHENTICATED without ever giving chance to EAP state machine to
716 * reset the state.
717 */
718 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
719 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
720 if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK)
721 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
722 /* 802.1X::portControl = Auto */
723 eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
724 wpa_s->eapol_received = 0;
725 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
726 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
727 wpa_supplicant_cancel_auth_timeout(wpa_s);
728 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
729 } else {
730 /* Timeout for receiving the first EAPOL packet */
731 wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
732 }
733 wpa_supplicant_cancel_scan(wpa_s);
734 }
735
736
737 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
738 {
739 const u8 *bssid;
740
741 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
742 /*
743 * At least Host AP driver and a Prism3 card seemed to be
744 * generating streams of disconnected events when configuring
745 * IBSS for WPA-None. Ignore them for now.
746 */
747 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
748 "IBSS/WPA-None mode");
749 return;
750 }
751
752 if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
753 wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
754 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
755 "pre-shared key may be incorrect");
756 }
757 if (wpa_s->wpa_state >= WPA_ASSOCIATED)
758 wpa_supplicant_req_scan(wpa_s, 0, 100000);
759 bssid = wpa_s->bssid;
760 if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
761 bssid = wpa_s->pending_bssid;
762 wpa_blacklist_add(wpa_s, bssid);
763 wpa_sm_notify_disassoc(wpa_s->wpa);
764 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
765 "remove keys");
766 if (wpa_supplicant_dynamic_keys(wpa_s)) {
767 wpa_s->keys_cleared = 0;
768 wpa_clear_keys(wpa_s, wpa_s->bssid);
769 }
770 wpa_supplicant_mark_disassoc(wpa_s);
771 }
772
773
774 static void
775 wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
776 union wpa_event_data *data)
777 {
778 int pairwise;
779 struct os_time t;
780
781 wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
782 pairwise = (data && data->michael_mic_failure.unicast);
783 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
784 os_get_time(&t);
785 if (wpa_s->last_michael_mic_error &&
786 t.sec - wpa_s->last_michael_mic_error <= 60) {
787 /* initialize countermeasures */
788 wpa_s->countermeasures = 1;
789 wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
790
791 /*
792 * Need to wait for completion of request frame. We do not get
793 * any callback for the message completion, so just wait a
794 * short while and hope for the best. */
795 os_sleep(0, 10000);
796
797 wpa_drv_set_countermeasures(wpa_s, 1);
798 wpa_supplicant_deauthenticate(wpa_s,
799 REASON_MICHAEL_MIC_FAILURE);
800 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
801 wpa_s, NULL);
802 eloop_register_timeout(60, 0,
803 wpa_supplicant_stop_countermeasures,
804 wpa_s, NULL);
805 /* TODO: mark the AP rejected for 60 second. STA is
806 * allowed to associate with another AP.. */
807 }
808 wpa_s->last_michael_mic_error = t.sec;
809 }
810
811
812 static void
813 wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
814 union wpa_event_data *data)
815 {
816 if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
817 return;
818
819 switch (data->interface_status.ievent) {
820 case EVENT_INTERFACE_ADDED:
821 if (!wpa_s->interface_removed)
822 break;
823 wpa_s->interface_removed = 0;
824 wpa_printf(MSG_DEBUG, "Configured interface was added.");
825 if (wpa_supplicant_driver_init(wpa_s, 1) < 0) {
826 wpa_printf(MSG_INFO, "Failed to initialize the driver "
827 "after interface was added.");
828 }
829 break;
830 case EVENT_INTERFACE_REMOVED:
831 wpa_printf(MSG_DEBUG, "Configured interface was removed.");
832 wpa_s->interface_removed = 1;
833 wpa_supplicant_mark_disassoc(wpa_s);
834 l2_packet_deinit(wpa_s->l2);
835 wpa_s->l2 = NULL;
836 break;
837 }
838 }
839
840
841 #ifdef CONFIG_PEERKEY
842 static void
843 wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
844 union wpa_event_data *data)
845 {
846 if (data == NULL)
847 return;
848 wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
849 }
850 #endif /* CONFIG_PEERKEY */
851
852
853 void wpa_supplicant_event(struct wpa_supplicant *wpa_s, wpa_event_type event,
854 union wpa_event_data *data)
855 {
856 switch (event) {
857 case EVENT_ASSOC:
858 wpa_supplicant_event_assoc(wpa_s, data);
859 break;
860 case EVENT_DISASSOC:
861 wpa_supplicant_event_disassoc(wpa_s);
862 break;
863 case EVENT_MICHAEL_MIC_FAILURE:
864 wpa_supplicant_event_michael_mic_failure(wpa_s, data);
865 break;
866 case EVENT_SCAN_RESULTS:
867 wpa_supplicant_event_scan_results(wpa_s);
868 break;
869 case EVENT_ASSOCINFO:
870 wpa_supplicant_event_associnfo(wpa_s, data);
871 break;
872 case EVENT_INTERFACE_STATUS:
873 wpa_supplicant_event_interface_status(wpa_s, data);
874 break;
875 case EVENT_PMKID_CANDIDATE:
876 wpa_supplicant_event_pmkid_candidate(wpa_s, data);
877 break;
878 #ifdef CONFIG_PEERKEY
879 case EVENT_STKSTART:
880 wpa_supplicant_event_stkstart(wpa_s, data);
881 break;
882 #endif /* CONFIG_PEERKEY */
883 default:
884 wpa_printf(MSG_INFO, "Unknown event %d", event);
885 break;
886 }
887 }
Something went wrong with that request. Please try again.