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