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