Added preliminary Wi-Fi Protected Setup (WPS) implementation
[mech_eap.orig] / wpa_supplicant / events.c
1 /*
2  * WPA Supplicant - Driver event processing
3  * Copyright (c) 2003-2008, 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_supp/eapol_supp_sm.h"
19 #include "wpa.h"
20 #include "eloop.h"
21 #include "drivers/driver.h"
22 #include "config.h"
23 #include "l2_packet/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_peer/eap.h"
30 #include "ctrl_iface_dbus.h"
31 #include "ieee802_11_defs.h"
32 #include "blacklist.h"
33 #include "wpas_glue.h"
34 #include "wps/wps.h"
35
36
37 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
38 {
39         struct wpa_ssid *ssid;
40
41         if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid)
42                 return 0;
43
44         wpa_printf(MSG_DEBUG, "Select network based on association "
45                    "information");
46         ssid = wpa_supplicant_get_ssid(wpa_s);
47         if (ssid == NULL) {
48                 wpa_printf(MSG_INFO, "No network configuration found for the "
49                            "current AP");
50                 return -1;
51         }
52
53         if (ssid->disabled) {
54                 wpa_printf(MSG_DEBUG, "Selected network is disabled");
55                 return -1;
56         }
57
58         wpa_printf(MSG_DEBUG, "Network configuration found for the current "
59                    "AP");
60         if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
61                               WPA_KEY_MGMT_WPA_NONE |
62                               WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X |
63                               WPA_KEY_MGMT_PSK_SHA256 |
64                               WPA_KEY_MGMT_IEEE8021X_SHA256)) {
65                 u8 wpa_ie[80];
66                 size_t wpa_ie_len = sizeof(wpa_ie);
67                 wpa_supplicant_set_suites(wpa_s, NULL, ssid,
68                                           wpa_ie, &wpa_ie_len);
69         } else {
70                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
71         }
72
73         if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
74                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
75         wpa_s->current_ssid = ssid;
76         wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
77         wpa_supplicant_initiate_eapol(wpa_s);
78
79         return 0;
80 }
81
82
83 static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
84                                                 void *sock_ctx)
85 {
86         struct wpa_supplicant *wpa_s = eloop_ctx;
87
88         if (wpa_s->countermeasures) {
89                 wpa_s->countermeasures = 0;
90                 wpa_drv_set_countermeasures(wpa_s, 0);
91                 wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
92                 wpa_supplicant_req_scan(wpa_s, 0, 0);
93         }
94 }
95
96
97 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
98 {
99         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
100         os_memset(wpa_s->bssid, 0, ETH_ALEN);
101         os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
102         eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
103         eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
104         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
105                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
106         wpa_s->ap_ies_from_associnfo = 0;
107 }
108
109
110 static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
111 {
112         struct wpa_ie_data ie;
113         int pmksa_set = -1;
114         size_t i;
115
116         if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
117             ie.pmkid == NULL)
118                 return;
119
120         for (i = 0; i < ie.num_pmkid; i++) {
121                 pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
122                                                     ie.pmkid + i * PMKID_LEN,
123                                                     NULL, NULL, 0);
124                 if (pmksa_set == 0) {
125                         eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
126                         break;
127                 }
128         }
129
130         wpa_printf(MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from PMKSA "
131                    "cache", pmksa_set == 0 ? "" : "not ");
132 }
133
134
135 static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
136                                                  union wpa_event_data *data)
137 {
138         if (data == NULL) {
139                 wpa_printf(MSG_DEBUG, "RSN: No data in PMKID candidate event");
140                 return;
141         }
142         wpa_printf(MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
143                    " index=%d preauth=%d",
144                    MAC2STR(data->pmkid_candidate.bssid),
145                    data->pmkid_candidate.index,
146                    data->pmkid_candidate.preauth);
147
148         pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
149                             data->pmkid_candidate.index,
150                             data->pmkid_candidate.preauth);
151 }
152
153
154 static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
155 {
156         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
157             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
158                 return 0;
159
160 #ifdef IEEE8021X_EAPOL
161         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
162             wpa_s->current_ssid &&
163             !(wpa_s->current_ssid->eapol_flags &
164               (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
165                EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
166                 /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
167                  * plaintext or static WEP keys). */
168                 return 0;
169         }
170 #endif /* IEEE8021X_EAPOL */
171
172         return 1;
173 }
174
175
176 /**
177  * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
178  * @wpa_s: pointer to wpa_supplicant data
179  * @ssid: Configuration data for the network
180  * Returns: 0 on success, -1 on failure
181  *
182  * This function is called when starting authentication with a network that is
183  * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
184  */
185 int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
186                               struct wpa_ssid *ssid)
187 {
188 #ifdef IEEE8021X_EAPOL
189         int aka = 0, sim = 0, type;
190
191         if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
192                 return 0;
193
194         if (ssid->eap.eap_methods == NULL) {
195                 sim = 1;
196                 aka = 1;
197         } else {
198                 struct eap_method_type *eap = ssid->eap.eap_methods;
199                 while (eap->vendor != EAP_VENDOR_IETF ||
200                        eap->method != EAP_TYPE_NONE) {
201                         if (eap->vendor == EAP_VENDOR_IETF) {
202                                 if (eap->method == EAP_TYPE_SIM)
203                                         sim = 1;
204                                 else if (eap->method == EAP_TYPE_AKA)
205                                         aka = 1;
206                         }
207                         eap++;
208                 }
209         }
210
211         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
212                 sim = 0;
213         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL)
214                 aka = 0;
215
216         if (!sim && !aka) {
217                 wpa_printf(MSG_DEBUG, "Selected network is configured to use "
218                            "SIM, but neither EAP-SIM nor EAP-AKA are enabled");
219                 return 0;
220         }
221
222         wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM "
223                    "(sim=%d aka=%d) - initialize PCSC", sim, aka);
224         if (sim && aka)
225                 type = SCARD_TRY_BOTH;
226         else if (aka)
227                 type = SCARD_USIM_ONLY;
228         else
229                 type = SCARD_GSM_SIM_ONLY;
230
231         wpa_s->scard = scard_init(type);
232         if (wpa_s->scard == NULL) {
233                 wpa_printf(MSG_WARNING, "Failed to initialize SIM "
234                            "(pcsc-lite)");
235                 return -1;
236         }
237         wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
238         eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
239 #endif /* IEEE8021X_EAPOL */
240
241         return 0;
242 }
243
244
245 #ifndef CONFIG_NO_SCAN_PROCESSING
246 static int wpa_supplicant_match_privacy(struct wpa_scan_res *bss,
247                                         struct wpa_ssid *ssid)
248 {
249         int i, privacy = 0;
250
251         if (ssid->mixed_cell)
252                 return 1;
253
254         for (i = 0; i < NUM_WEP_KEYS; i++) {
255                 if (ssid->wep_key_len[i]) {
256                         privacy = 1;
257                         break;
258                 }
259         }
260 #ifdef IEEE8021X_EAPOL
261         if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
262             ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
263                                  EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
264                 privacy = 1;
265 #endif /* IEEE8021X_EAPOL */
266
267         if (bss->caps & IEEE80211_CAP_PRIVACY)
268                 return privacy;
269         return !privacy;
270 }
271
272
273 static int wpa_supplicant_ssid_bss_match(struct wpa_ssid *ssid,
274                                          struct wpa_scan_res *bss)
275 {
276         struct wpa_ie_data ie;
277         int proto_match = 0;
278         const u8 *rsn_ie, *wpa_ie;
279
280 #ifdef CONFIG_WPS
281         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
282                 const u8 *wps_ie;
283                 wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
284                 if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
285                         if (!wps_ie) {
286                                 wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
287                                 return 0;
288                         }
289
290                         if (!wps_is_selected_pbc_registrar(wps_ie + 6,
291                                                            wps_ie[1] - 4)) {
292                                 wpa_printf(MSG_DEBUG, "   skip - WPS AP "
293                                            "without active PBC Registrar");
294                                 return 0;
295                         }
296
297                         /* TODO: overlap detection */
298                         wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
299                                    "(Active PBC)");
300                         return 1;
301                 }
302
303                 if (eap_is_wps_pin_enrollee(&ssid->eap)) {
304                         if (!wps_ie) {
305                                 wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
306                                 return 0;
307                         }
308
309                         if (!wps_is_selected_pin_registrar(wps_ie + 6,
310                                                            wps_ie[1] - 4)) {
311                                 wpa_printf(MSG_DEBUG, "   skip - WPS AP "
312                                            "without active PIN Registrar");
313                                 return 0;
314                         }
315                         wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
316                                    "(Active PIN)");
317                         return 1;
318                 }
319
320                 if (wps_ie) {
321                         wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
322                         return 1;
323                 }
324         }
325 #endif /* CONFIG_WPS */
326
327         rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
328         while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
329                 proto_match++;
330
331                 if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
332                         wpa_printf(MSG_DEBUG, "   skip RSN IE - parse failed");
333                         break;
334                 }
335                 if (!(ie.proto & ssid->proto)) {
336                         wpa_printf(MSG_DEBUG, "   skip RSN IE - proto "
337                                    "mismatch");
338                         break;
339                 }
340
341                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
342                         wpa_printf(MSG_DEBUG, "   skip RSN IE - PTK cipher "
343                                    "mismatch");
344                         break;
345                 }
346
347                 if (!(ie.group_cipher & ssid->group_cipher)) {
348                         wpa_printf(MSG_DEBUG, "   skip RSN IE - GTK cipher "
349                                    "mismatch");
350                         break;
351                 }
352
353                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
354                         wpa_printf(MSG_DEBUG, "   skip RSN IE - key mgmt "
355                                    "mismatch");
356                         break;
357                 }
358
359 #ifdef CONFIG_IEEE80211W
360                 if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
361                     ssid->ieee80211w == IEEE80211W_REQUIRED) {
362                         wpa_printf(MSG_DEBUG, "   skip RSN IE - no mgmt frame "
363                                    "protection");
364                         break;
365                 }
366 #endif /* CONFIG_IEEE80211W */
367
368                 wpa_printf(MSG_DEBUG, "   selected based on RSN IE");
369                 return 1;
370         }
371
372         wpa_ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
373         while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
374                 proto_match++;
375
376                 if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
377                         wpa_printf(MSG_DEBUG, "   skip WPA IE - parse failed");
378                         break;
379                 }
380                 if (!(ie.proto & ssid->proto)) {
381                         wpa_printf(MSG_DEBUG, "   skip WPA IE - proto "
382                                    "mismatch");
383                         break;
384                 }
385
386                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
387                         wpa_printf(MSG_DEBUG, "   skip WPA IE - PTK cipher "
388                                    "mismatch");
389                         break;
390                 }
391
392                 if (!(ie.group_cipher & ssid->group_cipher)) {
393                         wpa_printf(MSG_DEBUG, "   skip WPA IE - GTK cipher "
394                                    "mismatch");
395                         break;
396                 }
397
398                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
399                         wpa_printf(MSG_DEBUG, "   skip WPA IE - key mgmt "
400                                    "mismatch");
401                         break;
402                 }
403
404                 wpa_printf(MSG_DEBUG, "   selected based on WPA IE");
405                 return 1;
406         }
407
408         if (proto_match == 0)
409                 wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN proto match");
410
411         return 0;
412 }
413
414
415 #ifdef CONFIG_WPS
416 static int wps_ssid_wildcard_ok(struct wpa_ssid *ssid,
417                                 struct wpa_scan_res *bss)
418 {
419         const u8 *wps_ie;
420
421         if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
422                 wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
423                 if (wps_ie &&
424                     wps_is_selected_pbc_registrar(wps_ie + 6, wps_ie[1] - 4)) {
425                         /* allow wildcard SSID for WPS PBC */
426                         return 1;
427                 }
428         }
429
430         if (eap_is_wps_pin_enrollee(&ssid->eap)) {
431                 wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
432                 if (wps_ie &&
433                     wps_is_selected_pin_registrar(wps_ie + 6, wps_ie[1] - 4)) {
434                         /* allow wildcard SSID for WPS PIN */
435                         return 1;
436                 }
437         }
438
439         return 0;
440 }
441 #endif /* CONFIG_WPS */
442
443 static struct wpa_scan_res *
444 wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
445                               struct wpa_ssid *group,
446                               struct wpa_ssid **selected_ssid)
447 {
448         struct wpa_ssid *ssid;
449         struct wpa_scan_res *bss;
450         size_t i;
451         struct wpa_blacklist *e;
452         const u8 *ie;
453
454         wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
455         for (i = 0; i < wpa_s->scan_res->num; i++) {
456                 const u8 *ssid_;
457                 u8 wpa_ie_len, rsn_ie_len, ssid_len;
458                 bss = wpa_s->scan_res->res[i];
459
460                 ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
461                 ssid_ = ie ? ie + 2 : (u8 *) "";
462                 ssid_len = ie ? ie[1] : 0;
463
464                 ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
465                 wpa_ie_len = ie ? ie[1] : 0;
466
467                 ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
468                 rsn_ie_len = ie ? ie[1] : 0;
469
470                 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
471                            "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
472                            (int) i, MAC2STR(bss->bssid),
473                            wpa_ssid_txt(ssid_, ssid_len),
474                            wpa_ie_len, rsn_ie_len, bss->caps);
475
476                 e = wpa_blacklist_get(wpa_s, bss->bssid);
477                 if (e && e->count > 1) {
478                         wpa_printf(MSG_DEBUG, "   skip - blacklisted");
479                         continue;
480                 }
481
482                 if (wpa_ie_len == 0 && rsn_ie_len == 0) {
483                         wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN IE");
484                         continue;
485                 }
486
487                 for (ssid = group; ssid; ssid = ssid->pnext) {
488                         int check_ssid = 1;
489
490                         if (ssid->disabled) {
491                                 wpa_printf(MSG_DEBUG, "   skip - disabled");
492                                 continue;
493                         }
494
495 #ifdef CONFIG_WPS
496                         if (ssid->ssid_len == 0 &&
497                             wps_ssid_wildcard_ok(ssid, bss))
498                                 check_ssid = 0;
499 #endif /* CONFIG_WPS */
500
501                         if (check_ssid &&
502                             (ssid_len != ssid->ssid_len ||
503                              os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
504                                 wpa_printf(MSG_DEBUG, "   skip - "
505                                            "SSID mismatch");
506                                 continue;
507                         }
508
509                         if (ssid->bssid_set &&
510                             os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
511                         {
512                                 wpa_printf(MSG_DEBUG, "   skip - "
513                                            "BSSID mismatch");
514                                 continue;
515                         }
516
517                         if (!wpa_supplicant_ssid_bss_match(ssid, bss))
518                                 continue;
519
520                         wpa_printf(MSG_DEBUG, "   selected WPA AP "
521                                    MACSTR " ssid='%s'",
522                                    MAC2STR(bss->bssid),
523                                    wpa_ssid_txt(ssid_, ssid_len));
524                         *selected_ssid = ssid;
525                         return bss;
526                 }
527         }
528
529         return NULL;
530 }
531
532
533 static struct wpa_scan_res *
534 wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
535                                   struct wpa_ssid *group,
536                                   struct wpa_ssid **selected_ssid)
537 {
538         struct wpa_ssid *ssid;
539         struct wpa_scan_res *bss;
540         size_t i;
541         struct wpa_blacklist *e;
542         const u8 *ie;
543
544         wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
545         for (i = 0; i < wpa_s->scan_res->num; i++) {
546                 const u8 *ssid_;
547                 u8 wpa_ie_len, rsn_ie_len, ssid_len;
548                 bss = wpa_s->scan_res->res[i];
549
550                 ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
551                 ssid_ = ie ? ie + 2 : (u8 *) "";
552                 ssid_len = ie ? ie[1] : 0;
553
554                 ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
555                 wpa_ie_len = ie ? ie[1] : 0;
556
557                 ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
558                 rsn_ie_len = ie ? ie[1] : 0;
559
560                 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
561                            "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
562                            (int) i, MAC2STR(bss->bssid),
563                            wpa_ssid_txt(ssid_, ssid_len),
564                            wpa_ie_len, rsn_ie_len, bss->caps);
565
566                 e = wpa_blacklist_get(wpa_s, bss->bssid);
567                 if (e && e->count > 1) {
568                         wpa_printf(MSG_DEBUG, "   skip - blacklisted");
569                         continue;
570                 }
571
572                 for (ssid = group; ssid; ssid = ssid->pnext) {
573                         int check_ssid = ssid->ssid_len != 0;
574
575                         if (ssid->disabled) {
576                                 wpa_printf(MSG_DEBUG, "   skip - disabled");
577                                 continue;
578                         }
579
580 #ifdef CONFIG_WPS
581                         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
582                                 /* Only allow wildcard SSID match if an AP
583                                  * advertises active WPS operation that matches
584                                  * with our mode. */
585                                 check_ssid = 1;
586                                 if (ssid->ssid_len == 0 &&
587                                     wps_ssid_wildcard_ok(ssid, bss))
588                                         check_ssid = 0;
589                         }
590 #endif /* CONFIG_WPS */
591
592                         if (check_ssid &&
593                             (ssid_len != ssid->ssid_len ||
594                              os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
595                                 wpa_printf(MSG_DEBUG, "   skip - "
596                                            "SSID mismatch");
597                                 continue;
598                         }
599
600                         if (ssid->bssid_set &&
601                             os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
602                         {
603                                 wpa_printf(MSG_DEBUG, "   skip - "
604                                            "BSSID mismatch");
605                                 continue;
606                         }
607                         
608                         if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
609                             !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
610                             !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
611                         {
612                                 wpa_printf(MSG_DEBUG, "   skip - "
613                                            "non-WPA network not allowed");
614                                 continue;
615                         }
616
617                         if ((ssid->key_mgmt & 
618                              (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
619                               WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK |
620                               WPA_KEY_MGMT_IEEE8021X_SHA256 |
621                               WPA_KEY_MGMT_PSK_SHA256)) &&
622                             (wpa_ie_len != 0 || rsn_ie_len != 0)) {
623                                 wpa_printf(MSG_DEBUG, "   skip - "
624                                            "WPA network");
625                                 continue;
626                         }
627
628                         if (!wpa_supplicant_match_privacy(bss, ssid)) {
629                                 wpa_printf(MSG_DEBUG, "   skip - "
630                                            "privacy mismatch");
631                                 continue;
632                         }
633
634                         if (bss->caps & IEEE80211_CAP_IBSS) {
635                                 wpa_printf(MSG_DEBUG, "   skip - "
636                                            "IBSS (adhoc) network");
637                                 continue;
638                         }
639
640                         wpa_printf(MSG_DEBUG, "   selected non-WPA AP "
641                                    MACSTR " ssid='%s'",
642                                    MAC2STR(bss->bssid),
643                                    wpa_ssid_txt(ssid_, ssid_len));
644                         *selected_ssid = ssid;
645                         return bss;
646                 }
647         }
648
649         return NULL;
650 }
651
652
653 static struct wpa_scan_res *
654 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
655                           struct wpa_ssid **selected_ssid)
656 {
657         struct wpa_scan_res *selected;
658
659         wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
660                    group->priority);
661
662         /* First, try to find WPA-enabled AP */
663         selected = wpa_supplicant_select_bss_wpa(wpa_s, group, selected_ssid);
664         if (selected)
665                 return selected;
666
667         /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
668          * allows this. */
669         return wpa_supplicant_select_bss_non_wpa(wpa_s, group, selected_ssid);
670 }
671
672
673 #ifdef CONFIG_WPS
674
675 static int wpa_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
676                                 struct wpa_scan_res *selected,
677                                 struct wpa_ssid *ssid)
678 {
679         const u8 *sel_uuid, *uuid;
680         size_t i;
681         const u8 *wps_ie;
682
683         if (!eap_is_wps_pbc_enrollee(&ssid->eap))
684                 return 0;
685
686         /* Make sure that only one AP is in active PBC mode */
687         wps_ie = wpa_scan_get_vendor_ie(selected, WPS_IE_VENDOR_TYPE);
688         if (wps_ie)
689                 sel_uuid = wps_get_uuid_e(wps_ie + 6, wps_ie[1] - 4);
690         else
691                 sel_uuid = NULL;
692         if (!sel_uuid) {
693                 wpa_printf(MSG_DEBUG, "WPS: UUID-E not "
694                            "available for PBC overlap "
695                            "detection");
696                 return 1;
697         }
698
699         for (i = 0; i < wpa_s->scan_res->num; i++) {
700                 struct wpa_scan_res *bss = wpa_s->scan_res->res[i];
701                 if (bss == selected)
702                         continue;
703                 wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
704                 if (!wps_ie)
705                         continue;
706                 if (!wps_is_selected_pbc_registrar(wps_ie + 6,
707                                                    wps_ie[1] - 4))
708                         continue;
709                 uuid = wps_get_uuid_e(wps_ie + 6, wps_ie[1] - 4);
710                 if (uuid == NULL) {
711                         wpa_printf(MSG_DEBUG, "WPS: UUID-E not "
712                                    "available for PBC overlap "
713                                    "detection (other BSS)");
714                         return 1;
715                 }
716                 if (os_memcmp(sel_uuid, uuid, 16) != 0)
717                         return 1; /* PBC overlap */
718
719                 /* TODO: verify that this is reasonable dual-band situation */
720         }
721
722         return 0;
723 }
724
725 #else /* CONFIG_WPS */
726
727 #define wpa_scan_pbc_overlap(w, s, i) 0
728
729 #endif /* CONFIG_WPS */
730
731
732 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
733 {
734         int prio, timeout;
735         struct wpa_scan_res *selected = NULL;
736         struct wpa_ssid *ssid = NULL;
737
738         if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
739                 if (wpa_s->conf->ap_scan == 2)
740                         return;
741                 wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
742                            "scanning again");
743                 timeout = 1;
744                 goto req_scan;
745         }
746
747         /*
748          * Don't post the results if this was the initial cached
749          * and there were no results.
750          */
751         if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
752             wpa_s->scan_res->num == 0) {
753                 wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
754                         "empty - not posting");
755         } else {
756                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
757                 wpa_supplicant_dbus_notify_scan_results(wpa_s);
758         }
759
760         if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
761                 return;
762
763         while (selected == NULL) {
764                 for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
765                         selected = wpa_supplicant_select_bss(
766                                 wpa_s, wpa_s->conf->pssid[prio], &ssid);
767                         if (selected)
768                                 break;
769                 }
770
771                 if (selected == NULL && wpa_s->blacklist) {
772                         wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
773                                    "and try again");
774                         wpa_blacklist_clear(wpa_s);
775                 } else if (selected == NULL) {
776                         break;
777                 }
778         }
779
780         if (selected) {
781                 if (wpa_scan_pbc_overlap(wpa_s, selected, ssid)) {
782                         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
783                                 "PBC session overlap");
784                         timeout = 10;
785                         goto req_scan;
786                 }
787
788                 /* Do not trigger new association unless the BSSID has changed
789                  * or if reassociation is requested. If we are in process of
790                  * associating with the selected BSSID, do not trigger new
791                  * attempt. */
792                 if (wpa_s->reassociate ||
793                     (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
794                      (wpa_s->wpa_state != WPA_ASSOCIATING ||
795                       os_memcmp(selected->bssid, wpa_s->pending_bssid,
796                                 ETH_ALEN) != 0))) {
797                         if (wpa_supplicant_scard_init(wpa_s, ssid)) {
798                                 wpa_supplicant_req_scan(wpa_s, 10, 0);
799                                 return;
800                         }
801                         wpa_supplicant_associate(wpa_s, selected, ssid);
802                 } else {
803                         wpa_printf(MSG_DEBUG, "Already associated with the "
804                                    "selected AP.");
805                 }
806                 rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res);
807         } else {
808                 wpa_printf(MSG_DEBUG, "No suitable AP found.");
809                 timeout = 5;
810                 goto req_scan;
811         }
812
813         return;
814
815 req_scan:
816         if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
817                 /*
818                  * Quick recovery if the initial scan results were not
819                  * complete when fetched before the first scan request.
820                  */
821                 wpa_s->scan_res_tried++;
822                 timeout = 0;
823         }
824         wpa_supplicant_req_scan(wpa_s, timeout, 0);
825 }
826 #endif /* CONFIG_NO_SCAN_PROCESSING */
827
828
829 static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
830                                            union wpa_event_data *data)
831 {
832         int l, len, found = 0, wpa_found, rsn_found;
833         u8 *p;
834
835         wpa_printf(MSG_DEBUG, "Association info event");
836         if (data->assoc_info.req_ies)
837                 wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
838                             data->assoc_info.req_ies_len);
839         if (data->assoc_info.resp_ies)
840                 wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
841                             data->assoc_info.resp_ies_len);
842         if (data->assoc_info.beacon_ies)
843                 wpa_hexdump(MSG_DEBUG, "beacon_ies",
844                             data->assoc_info.beacon_ies,
845                             data->assoc_info.beacon_ies_len);
846
847         p = data->assoc_info.req_ies;
848         l = data->assoc_info.req_ies_len;
849
850         /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
851         while (p && l >= 2) {
852                 len = p[1] + 2;
853                 if (len > l) {
854                         wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
855                                     p, l);
856                         break;
857                 }
858                 if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
859                      (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
860                     (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
861                         if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
862                                 break;
863                         found = 1;
864                         wpa_find_assoc_pmkid(wpa_s);
865                         break;
866                 }
867                 l -= len;
868                 p += len;
869         }
870         if (!found && data->assoc_info.req_ies)
871                 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
872
873         /* WPA/RSN IE from Beacon/ProbeResp */
874         p = data->assoc_info.beacon_ies;
875         l = data->assoc_info.beacon_ies_len;
876
877         /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
878          */
879         wpa_found = rsn_found = 0;
880         while (p && l >= 2) {
881                 len = p[1] + 2;
882                 if (len > l) {
883                         wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
884                                     p, l);
885                         break;
886                 }
887                 if (!wpa_found &&
888                     p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
889                     os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
890                         wpa_found = 1;
891                         wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
892                 }
893
894                 if (!rsn_found &&
895                     p[0] == WLAN_EID_RSN && p[1] >= 2) {
896                         rsn_found = 1;
897                         wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
898                 }
899
900                 l -= len;
901                 p += len;
902         }
903
904         if (!wpa_found && data->assoc_info.beacon_ies)
905                 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
906         if (!rsn_found && data->assoc_info.beacon_ies)
907                 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
908         if (wpa_found || rsn_found)
909                 wpa_s->ap_ies_from_associnfo = 1;
910 }
911
912
913 static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
914                                        union wpa_event_data *data)
915 {
916         u8 bssid[ETH_ALEN];
917         int ft_completed = wpa_ft_is_completed(wpa_s->wpa);
918
919         if (data)
920                 wpa_supplicant_event_associnfo(wpa_s, data);
921
922         wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
923         if (wpa_s->use_client_mlme)
924                 os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
925         if (wpa_s->use_client_mlme ||
926             (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
927              os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
928                 wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
929                         MACSTR, MAC2STR(bssid));
930                 os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
931                 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
932                 if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
933                         wpa_clear_keys(wpa_s, bssid);
934                 }
935                 if (wpa_supplicant_select_config(wpa_s) < 0) {
936                         wpa_supplicant_disassociate(
937                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
938                         return;
939                 }
940         }
941
942         wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
943         if (wpa_s->current_ssid) {
944                 /* When using scanning (ap_scan=1), SIM PC/SC interface can be
945                  * initialized before association, but for other modes,
946                  * initialize PC/SC here, if the current configuration needs
947                  * smartcard or SIM/USIM. */
948                 wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
949         }
950         wpa_sm_notify_assoc(wpa_s->wpa, bssid);
951         l2_packet_notify_auth_start(wpa_s->l2);
952
953         /*
954          * Set portEnabled first to FALSE in order to get EAP state machine out
955          * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
956          * state machine may transit to AUTHENTICATING state based on obsolete
957          * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
958          * AUTHENTICATED without ever giving chance to EAP state machine to
959          * reset the state.
960          */
961         if (!ft_completed) {
962                 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
963                 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
964         }
965         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
966                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
967         /* 802.1X::portControl = Auto */
968         eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
969         wpa_s->eapol_received = 0;
970         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
971             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
972                 wpa_supplicant_cancel_auth_timeout(wpa_s);
973                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
974         } else if (!ft_completed) {
975                 /* Timeout for receiving the first EAPOL packet */
976                 wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
977         }
978         wpa_supplicant_cancel_scan(wpa_s);
979
980         if (wpa_s->driver_4way_handshake &&
981             wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
982                 /*
983                  * We are done; the driver will take care of RSN 4-way
984                  * handshake.
985                  */
986                 wpa_supplicant_cancel_auth_timeout(wpa_s);
987                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
988                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
989                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
990         }
991 }
992
993
994 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
995 {
996         const u8 *bssid;
997
998         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
999                 /*
1000                  * At least Host AP driver and a Prism3 card seemed to be
1001                  * generating streams of disconnected events when configuring
1002                  * IBSS for WPA-None. Ignore them for now.
1003                  */
1004                 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
1005                            "IBSS/WPA-None mode");
1006                 return;
1007         }
1008
1009         if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
1010             wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
1011                 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
1012                         "pre-shared key may be incorrect");
1013         }
1014         if (wpa_s->wpa_state >= WPA_ASSOCIATED)
1015                 wpa_supplicant_req_scan(wpa_s, 0, 100000);
1016         bssid = wpa_s->bssid;
1017         if (is_zero_ether_addr(bssid))
1018                 bssid = wpa_s->pending_bssid;
1019         wpa_blacklist_add(wpa_s, bssid);
1020         wpa_sm_notify_disassoc(wpa_s->wpa);
1021         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
1022                 "remove keys");
1023         if (wpa_supplicant_dynamic_keys(wpa_s)) {
1024                 wpa_s->keys_cleared = 0;
1025                 wpa_clear_keys(wpa_s, wpa_s->bssid);
1026         }
1027         wpa_supplicant_mark_disassoc(wpa_s);
1028 }
1029
1030
1031 #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
1032 static void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx,
1033                                                     void *sock_ctx)
1034 {
1035         struct wpa_supplicant *wpa_s = eloop_ctx;
1036
1037         if (!wpa_s->pending_mic_error_report)
1038                 return;
1039
1040         wpa_printf(MSG_DEBUG, "WPA: Sending pending MIC error report");
1041         wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
1042         wpa_s->pending_mic_error_report = 0;
1043 }
1044 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
1045
1046
1047 static void
1048 wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
1049                                          union wpa_event_data *data)
1050 {
1051         int pairwise;
1052         struct os_time t;
1053
1054         wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
1055         pairwise = (data && data->michael_mic_failure.unicast);
1056         os_get_time(&t);
1057         if ((wpa_s->last_michael_mic_error &&
1058              t.sec - wpa_s->last_michael_mic_error <= 60) ||
1059             wpa_s->pending_mic_error_report) {
1060                 if (wpa_s->pending_mic_error_report) {
1061                         /*
1062                          * Send the pending MIC error report immediately since
1063                          * we are going to start countermeasures and AP better
1064                          * do the same.
1065                          */
1066                         wpa_sm_key_request(wpa_s->wpa, 1,
1067                                            wpa_s->pending_mic_error_pairwise);
1068                 }
1069
1070                 /* Send the new MIC error report immediately since we are going
1071                  * to start countermeasures and AP better do the same.
1072                  */
1073                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
1074
1075                 /* initialize countermeasures */
1076                 wpa_s->countermeasures = 1;
1077                 wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
1078
1079                 /*
1080                  * Need to wait for completion of request frame. We do not get
1081                  * any callback for the message completion, so just wait a
1082                  * short while and hope for the best. */
1083                 os_sleep(0, 10000);
1084
1085                 wpa_drv_set_countermeasures(wpa_s, 1);
1086                 wpa_supplicant_deauthenticate(wpa_s,
1087                                               WLAN_REASON_MICHAEL_MIC_FAILURE);
1088                 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
1089                                      wpa_s, NULL);
1090                 eloop_register_timeout(60, 0,
1091                                        wpa_supplicant_stop_countermeasures,
1092                                        wpa_s, NULL);
1093                 /* TODO: mark the AP rejected for 60 second. STA is
1094                  * allowed to associate with another AP.. */
1095         } else {
1096 #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
1097                 if (wpa_s->mic_errors_seen) {
1098                         /*
1099                          * Reduce the effectiveness of Michael MIC error
1100                          * reports as a means for attacking against TKIP if
1101                          * more than one MIC failure is noticed with the same
1102                          * PTK. We delay the transmission of the reports by a
1103                          * random time between 0 and 60 seconds in order to
1104                          * force the attacker wait 60 seconds before getting
1105                          * the information on whether a frame resulted in a MIC
1106                          * failure.
1107                          */
1108                         u8 rval[4];
1109                         int sec;
1110
1111                         if (os_get_random(rval, sizeof(rval)) < 0)
1112                                 sec = os_random() % 60;
1113                         else
1114                                 sec = WPA_GET_BE32(rval) % 60;
1115                         wpa_printf(MSG_DEBUG, "WPA: Delay MIC error report %d "
1116                                    "seconds", sec);
1117                         wpa_s->pending_mic_error_report = 1;
1118                         wpa_s->pending_mic_error_pairwise = pairwise;
1119                         eloop_cancel_timeout(
1120                                 wpa_supplicant_delayed_mic_error_report,
1121                                 wpa_s, NULL);
1122                         eloop_register_timeout(
1123                                 sec, os_random() % 1000000,
1124                                 wpa_supplicant_delayed_mic_error_report,
1125                                 wpa_s, NULL);
1126                 } else {
1127                         wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
1128                 }
1129 #else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
1130                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
1131 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
1132         }
1133         wpa_s->last_michael_mic_error = t.sec;
1134         wpa_s->mic_errors_seen++;
1135 }
1136
1137
1138 static void
1139 wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
1140                                       union wpa_event_data *data)
1141 {
1142         if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
1143                 return;
1144
1145         switch (data->interface_status.ievent) {
1146         case EVENT_INTERFACE_ADDED:
1147                 if (!wpa_s->interface_removed)
1148                         break;
1149                 wpa_s->interface_removed = 0;
1150                 wpa_printf(MSG_DEBUG, "Configured interface was added.");
1151                 if (wpa_supplicant_driver_init(wpa_s) < 0) {
1152                         wpa_printf(MSG_INFO, "Failed to initialize the driver "
1153                                    "after interface was added.");
1154                 }
1155                 break;
1156         case EVENT_INTERFACE_REMOVED:
1157                 wpa_printf(MSG_DEBUG, "Configured interface was removed.");
1158                 wpa_s->interface_removed = 1;
1159                 wpa_supplicant_mark_disassoc(wpa_s);
1160                 l2_packet_deinit(wpa_s->l2);
1161                 wpa_s->l2 = NULL;
1162                 break;
1163         }
1164 }
1165
1166
1167 #ifdef CONFIG_PEERKEY
1168 static void
1169 wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
1170                               union wpa_event_data *data)
1171 {
1172         if (data == NULL)
1173                 return;
1174         wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
1175 }
1176 #endif /* CONFIG_PEERKEY */
1177
1178
1179 #ifdef CONFIG_IEEE80211R
1180 static void
1181 wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
1182                                  union wpa_event_data *data)
1183 {
1184         if (data == NULL)
1185                 return;
1186
1187         if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
1188                                     data->ft_ies.ies_len,
1189                                     data->ft_ies.ft_action,
1190                                     data->ft_ies.target_ap) < 0) {
1191                 /* TODO: prevent MLME/driver from trying to associate? */
1192         }
1193 }
1194 #endif /* CONFIG_IEEE80211R */
1195
1196
1197 void wpa_supplicant_event(void *ctx, wpa_event_type event,
1198                           union wpa_event_data *data)
1199 {
1200         struct wpa_supplicant *wpa_s = ctx;
1201
1202         switch (event) {
1203         case EVENT_ASSOC:
1204                 wpa_supplicant_event_assoc(wpa_s, data);
1205                 break;
1206         case EVENT_DISASSOC:
1207                 wpa_supplicant_event_disassoc(wpa_s);
1208                 break;
1209         case EVENT_MICHAEL_MIC_FAILURE:
1210                 wpa_supplicant_event_michael_mic_failure(wpa_s, data);
1211                 break;
1212 #ifndef CONFIG_NO_SCAN_PROCESSING
1213         case EVENT_SCAN_RESULTS:
1214                 wpa_supplicant_event_scan_results(wpa_s);
1215                 break;
1216 #endif /* CONFIG_NO_SCAN_PROCESSING */
1217         case EVENT_ASSOCINFO:
1218                 wpa_supplicant_event_associnfo(wpa_s, data);
1219                 break;
1220         case EVENT_INTERFACE_STATUS:
1221                 wpa_supplicant_event_interface_status(wpa_s, data);
1222                 break;
1223         case EVENT_PMKID_CANDIDATE:
1224                 wpa_supplicant_event_pmkid_candidate(wpa_s, data);
1225                 break;
1226 #ifdef CONFIG_PEERKEY
1227         case EVENT_STKSTART:
1228                 wpa_supplicant_event_stkstart(wpa_s, data);
1229                 break;
1230 #endif /* CONFIG_PEERKEY */
1231 #ifdef CONFIG_IEEE80211R
1232         case EVENT_FT_RESPONSE:
1233                 wpa_supplicant_event_ft_response(wpa_s, data);
1234                 break;
1235 #endif /* CONFIG_IEEE80211R */
1236         default:
1237                 wpa_printf(MSG_INFO, "Unknown event %d", event);
1238                 break;
1239         }
1240 }