1 /* 2 * wpa_supplicant - SME 3 * Copyright (c) 2009-2010, 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 "utils/eloop.h" 19 #include "common/ieee802_11_defs.h" 20 #include "common/ieee802_11_common.h" 21 #include "eapol_supp/eapol_supp_sm.h" 22 #include "common/wpa_common.h" 23 #include "rsn_supp/wpa.h" 24 #include "rsn_supp/pmksa_cache.h" 25 #include "config.h" 26 #include "wpa_supplicant_i.h" 27 #include "driver_i.h" 28 #include "wpas_glue.h" 29 #include "wps_supplicant.h" 30 #include "p2p_supplicant.h" 31 #include "notify.h" 32 #include "blacklist.h" 33 #include "bss.h" 34 #include "scan.h" 35 #include "sme.h" 36 37 #define SME_AUTH_TIMEOUT 5 38 #define SME_ASSOC_TIMEOUT 5 39 40 static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx); 41 static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx); 42 #ifdef CONFIG_IEEE80211W 43 static void sme_stop_sa_query(struct wpa_supplicant *wpa_s); 44 #endif /* CONFIG_IEEE80211W */ 45 46 47 void sme_authenticate(struct wpa_supplicant *wpa_s, 48 struct wpa_bss *bss, struct wpa_ssid *ssid) 49 { 50 struct wpa_driver_auth_params params; 51 struct wpa_ssid *old_ssid; 52 #ifdef CONFIG_IEEE80211R 53 const u8 *ie; 54 #endif /* CONFIG_IEEE80211R */ 55 #ifdef CONFIG_IEEE80211R 56 const u8 *md = NULL; 57 #endif /* CONFIG_IEEE80211R */ 58 int i, bssid_changed; 59 60 if (bss == NULL) { 61 wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for " 62 "the network"); 63 return; 64 } 65 66 wpa_s->current_bss = bss; 67 68 os_memset(¶ms, 0, sizeof(params)); 69 wpa_s->reassociate = 0; 70 71 params.freq = bss->freq; 72 params.bssid = bss->bssid; 73 params.ssid = bss->ssid; 74 params.ssid_len = bss->ssid_len; 75 params.p2p = ssid->p2p_group; 76 77 if (wpa_s->sme.ssid_len != params.ssid_len || 78 os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0) 79 wpa_s->sme.prev_bssid_set = 0; 80 81 wpa_s->sme.freq = params.freq; 82 os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len); 83 wpa_s->sme.ssid_len = params.ssid_len; 84 85 params.auth_alg = WPA_AUTH_ALG_OPEN; 86 #ifdef IEEE8021X_EAPOL 87 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 88 if (ssid->leap) { 89 if (ssid->non_leap == 0) 90 params.auth_alg = WPA_AUTH_ALG_LEAP; 91 else 92 params.auth_alg |= WPA_AUTH_ALG_LEAP; 93 } 94 } 95 #endif /* IEEE8021X_EAPOL */ 96 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", 97 params.auth_alg); 98 if (ssid->auth_alg) { 99 params.auth_alg = ssid->auth_alg; 100 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: " 101 "0x%x", params.auth_alg); 102 } 103 104 for (i = 0; i < NUM_WEP_KEYS; i++) { 105 if (ssid->wep_key_len[i]) 106 params.wep_key[i] = ssid->wep_key[i]; 107 params.wep_key_len[i] = ssid->wep_key_len[i]; 108 } 109 params.wep_tx_keyidx = ssid->wep_tx_keyidx; 110 111 bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 112 os_memset(wpa_s->bssid, 0, ETH_ALEN); 113 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); 114 if (bssid_changed) 115 wpas_notify_bssid_changed(wpa_s); 116 117 if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || 118 wpa_bss_get_ie(bss, WLAN_EID_RSN)) && 119 (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | 120 WPA_KEY_MGMT_FT_IEEE8021X | 121 WPA_KEY_MGMT_FT_PSK | 122 WPA_KEY_MGMT_IEEE8021X_SHA256 | 123 WPA_KEY_MGMT_PSK_SHA256))) { 124 int try_opportunistic; 125 try_opportunistic = ssid->proactive_key_caching && 126 (ssid->proto & WPA_PROTO_RSN); 127 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, 128 wpa_s->current_ssid, 129 try_opportunistic) == 0) 130 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); 131 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 132 if (wpa_supplicant_set_suites(wpa_s, bss, ssid, 133 wpa_s->sme.assoc_req_ie, 134 &wpa_s->sme.assoc_req_ie_len)) { 135 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 136 "key management and encryption suites"); 137 return; 138 } 139 } else if (ssid->key_mgmt & 140 (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X | 141 WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK | 142 WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 | 143 WPA_KEY_MGMT_IEEE8021X_SHA256)) { 144 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 145 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, 146 wpa_s->sme.assoc_req_ie, 147 &wpa_s->sme.assoc_req_ie_len)) { 148 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 149 "key management and encryption suites (no " 150 "scan results)"); 151 return; 152 } 153 #ifdef CONFIG_WPS 154 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 155 struct wpabuf *wps_ie; 156 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid)); 157 if (wps_ie && wpabuf_len(wps_ie) <= 158 sizeof(wpa_s->sme.assoc_req_ie)) { 159 wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie); 160 os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie), 161 wpa_s->sme.assoc_req_ie_len); 162 } else 163 wpa_s->sme.assoc_req_ie_len = 0; 164 wpabuf_free(wps_ie); 165 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 166 #endif /* CONFIG_WPS */ 167 } else { 168 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 169 wpa_s->sme.assoc_req_ie_len = 0; 170 } 171 172 #ifdef CONFIG_IEEE80211R 173 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 174 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) 175 md = ie + 2; 176 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); 177 if (md) { 178 /* Prepare for the next transition */ 179 wpa_ft_prepare_auth_request(wpa_s->wpa, ie); 180 } 181 182 if (md && ssid->key_mgmt & (WPA_KEY_MGMT_FT_PSK | 183 WPA_KEY_MGMT_FT_IEEE8021X)) { 184 if (wpa_s->sme.assoc_req_ie_len + 5 < 185 sizeof(wpa_s->sme.assoc_req_ie)) { 186 struct rsn_mdie *mdie; 187 u8 *pos = wpa_s->sme.assoc_req_ie + 188 wpa_s->sme.assoc_req_ie_len; 189 *pos++ = WLAN_EID_MOBILITY_DOMAIN; 190 *pos++ = sizeof(*mdie); 191 mdie = (struct rsn_mdie *) pos; 192 os_memcpy(mdie->mobility_domain, md, 193 MOBILITY_DOMAIN_ID_LEN); 194 mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN]; 195 wpa_s->sme.assoc_req_ie_len += 5; 196 } 197 198 if (wpa_s->sme.ft_used && 199 os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && 200 wpa_sm_has_ptk(wpa_s->wpa)) { 201 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT " 202 "over-the-air"); 203 params.auth_alg = WPA_AUTH_ALG_FT; 204 params.ie = wpa_s->sme.ft_ies; 205 params.ie_len = wpa_s->sme.ft_ies_len; 206 } 207 } 208 #endif /* CONFIG_IEEE80211R */ 209 210 #ifdef CONFIG_IEEE80211W 211 wpa_s->sme.mfp = ssid->ieee80211w; 212 if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 213 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 214 struct wpa_ie_data _ie; 215 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 && 216 _ie.capabilities & 217 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) { 218 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports " 219 "MFP: require MFP"); 220 wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED; 221 } 222 } 223 #endif /* CONFIG_IEEE80211W */ 224 225 #ifdef CONFIG_P2P 226 if (wpa_s->global->p2p) { 227 u8 *pos; 228 size_t len; 229 int res; 230 pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; 231 len = sizeof(wpa_s->sme.assoc_req_ie) - 232 wpa_s->sme.assoc_req_ie_len; 233 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, 234 ssid->p2p_group); 235 if (res >= 0) 236 wpa_s->sme.assoc_req_ie_len += res; 237 } 238 #endif /* CONFIG_P2P */ 239 240 #ifdef CONFIG_INTERWORKING 241 if (wpa_s->conf->interworking) { 242 u8 *pos = wpa_s->sme.assoc_req_ie; 243 if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) 244 pos += 2 + pos[1]; 245 os_memmove(pos + 6, pos, 246 wpa_s->sme.assoc_req_ie_len - 247 (pos - wpa_s->sme.assoc_req_ie)); 248 wpa_s->sme.assoc_req_ie_len += 6; 249 *pos++ = WLAN_EID_EXT_CAPAB; 250 *pos++ = 4; 251 *pos++ = 0x00; 252 *pos++ = 0x00; 253 *pos++ = 0x00; 254 *pos++ = 0x80; /* Bit 31 - Interworking */ 255 } 256 #endif /* CONFIG_INTERWORKING */ 257 258 wpa_supplicant_cancel_sched_scan(wpa_s); 259 wpa_supplicant_cancel_scan(wpa_s); 260 261 wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR 262 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 263 wpa_ssid_txt(params.ssid, params.ssid_len), params.freq); 264 265 wpa_clear_keys(wpa_s, bss->bssid); 266 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 267 old_ssid = wpa_s->current_ssid; 268 wpa_s->current_ssid = ssid; 269 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 270 wpa_supplicant_initiate_eapol(wpa_s); 271 if (old_ssid != wpa_s->current_ssid) 272 wpas_notify_network_changed(wpa_s); 273 274 wpa_s->sme.auth_alg = params.auth_alg; 275 if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) { 276 wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the " 277 "driver failed"); 278 wpas_connection_failed(wpa_s, bss->bssid); 279 wpa_supplicant_mark_disassoc(wpa_s); 280 return; 281 } 282 283 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 284 NULL); 285 286 /* 287 * Association will be started based on the authentication event from 288 * the driver. 289 */ 290 } 291 292 293 void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) 294 { 295 struct wpa_ssid *ssid = wpa_s->current_ssid; 296 297 if (ssid == NULL) { 298 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 299 "when network is not selected"); 300 return; 301 } 302 303 if (wpa_s->wpa_state != WPA_AUTHENTICATING) { 304 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 305 "when not in authenticating state"); 306 return; 307 } 308 309 if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) { 310 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with " 311 "unexpected peer " MACSTR, 312 MAC2STR(data->auth.peer)); 313 return; 314 } 315 316 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR 317 " auth_type=%d status_code=%d", 318 MAC2STR(data->auth.peer), data->auth.auth_type, 319 data->auth.status_code); 320 wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs", 321 data->auth.ies, data->auth.ies_len); 322 323 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 324 325 if (data->auth.status_code != WLAN_STATUS_SUCCESS) { 326 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status " 327 "code %d)", data->auth.status_code); 328 329 if (data->auth.status_code != 330 WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG || 331 wpa_s->sme.auth_alg == data->auth.auth_type || 332 wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) { 333 wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 334 return; 335 } 336 337 switch (data->auth.auth_type) { 338 case WLAN_AUTH_OPEN: 339 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED; 340 341 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth"); 342 wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 343 wpa_s->current_ssid); 344 return; 345 346 case WLAN_AUTH_SHARED_KEY: 347 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP; 348 349 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth"); 350 wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 351 wpa_s->current_ssid); 352 return; 353 354 default: 355 return; 356 } 357 } 358 359 #ifdef CONFIG_IEEE80211R 360 if (data->auth.auth_type == WLAN_AUTH_FT) { 361 union wpa_event_data edata; 362 os_memset(&edata, 0, sizeof(edata)); 363 edata.ft_ies.ies = data->auth.ies; 364 edata.ft_ies.ies_len = data->auth.ies_len; 365 os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN); 366 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata); 367 } 368 #endif /* CONFIG_IEEE80211R */ 369 370 sme_associate(wpa_s, ssid->mode, data->auth.peer, 371 data->auth.auth_type); 372 } 373 374 375 void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, 376 const u8 *bssid, u16 auth_type) 377 { 378 struct wpa_driver_associate_params params; 379 struct ieee802_11_elems elems; 380 381 os_memset(¶ms, 0, sizeof(params)); 382 params.bssid = bssid; 383 params.ssid = wpa_s->sme.ssid; 384 params.ssid_len = wpa_s->sme.ssid_len; 385 params.freq = wpa_s->sme.freq; 386 params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? 387 wpa_s->sme.assoc_req_ie : NULL; 388 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; 389 params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher); 390 params.group_suite = cipher_suite2driver(wpa_s->group_cipher); 391 #ifdef CONFIG_IEEE80211R 392 if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { 393 params.wpa_ie = wpa_s->sme.ft_ies; 394 params.wpa_ie_len = wpa_s->sme.ft_ies_len; 395 } 396 #endif /* CONFIG_IEEE80211R */ 397 params.mode = mode; 398 params.mgmt_frame_protection = wpa_s->sme.mfp; 399 if (wpa_s->sme.prev_bssid_set) 400 params.prev_bssid = wpa_s->sme.prev_bssid; 401 402 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR 403 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 404 params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", 405 params.freq); 406 407 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); 408 409 if (params.wpa_ie == NULL || 410 ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) 411 < 0) { 412 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!"); 413 os_memset(&elems, 0, sizeof(elems)); 414 } 415 if (elems.rsn_ie) { 416 params.wpa_proto = WPA_PROTO_RSN; 417 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, 418 elems.rsn_ie_len + 2); 419 } else if (elems.wpa_ie) { 420 params.wpa_proto = WPA_PROTO_WPA; 421 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, 422 elems.wpa_ie_len + 2); 423 } else 424 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); 425 if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group) 426 params.p2p = 1; 427 428 if (wpa_s->parent->set_sta_uapsd) 429 params.uapsd = wpa_s->parent->sta_uapsd; 430 else 431 params.uapsd = -1; 432 433 if (wpa_drv_associate(wpa_s, ¶ms) < 0) { 434 wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the " 435 "driver failed"); 436 wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 437 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 438 return; 439 } 440 441 eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s, 442 NULL); 443 } 444 445 446 int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 447 const u8 *ies, size_t ies_len) 448 { 449 if (md == NULL || ies == NULL) { 450 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain"); 451 os_free(wpa_s->sme.ft_ies); 452 wpa_s->sme.ft_ies = NULL; 453 wpa_s->sme.ft_ies_len = 0; 454 wpa_s->sme.ft_used = 0; 455 return 0; 456 } 457 458 os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN); 459 wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len); 460 os_free(wpa_s->sme.ft_ies); 461 wpa_s->sme.ft_ies = os_malloc(ies_len); 462 if (wpa_s->sme.ft_ies == NULL) 463 return -1; 464 os_memcpy(wpa_s->sme.ft_ies, ies, ies_len); 465 wpa_s->sme.ft_ies_len = ies_len; 466 return 0; 467 } 468 469 470 static void sme_deauth(struct wpa_supplicant *wpa_s) 471 { 472 int bssid_changed; 473 474 bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 475 476 if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, 477 WLAN_REASON_DEAUTH_LEAVING) < 0) { 478 wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver " 479 "failed"); 480 } 481 wpa_s->sme.prev_bssid_set = 0; 482 483 wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 484 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 485 os_memset(wpa_s->bssid, 0, ETH_ALEN); 486 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 487 if (bssid_changed) 488 wpas_notify_bssid_changed(wpa_s); 489 } 490 491 492 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, 493 union wpa_event_data *data) 494 { 495 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: " 496 "status code %d", MAC2STR(wpa_s->pending_bssid), 497 data->assoc_reject.status_code); 498 499 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 500 501 /* 502 * For now, unconditionally terminate the previous authentication. In 503 * theory, this should not be needed, but mac80211 gets quite confused 504 * if the authentication is left pending.. Some roaming cases might 505 * benefit from using the previous authentication, so this could be 506 * optimized in the future. 507 */ 508 sme_deauth(wpa_s); 509 } 510 511 512 void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, 513 union wpa_event_data *data) 514 { 515 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out"); 516 wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 517 wpa_supplicant_mark_disassoc(wpa_s); 518 } 519 520 521 void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, 522 union wpa_event_data *data) 523 { 524 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out"); 525 wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 526 wpa_supplicant_mark_disassoc(wpa_s); 527 } 528 529 530 void sme_event_disassoc(struct wpa_supplicant *wpa_s, 531 union wpa_event_data *data) 532 { 533 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received"); 534 if (wpa_s->sme.prev_bssid_set) { 535 /* 536 * cfg80211/mac80211 can get into somewhat confused state if 537 * the AP only disassociates us and leaves us in authenticated 538 * state. For now, force the state to be cleared to avoid 539 * confusing errors if we try to associate with the AP again. 540 */ 541 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear " 542 "driver state"); 543 wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, 544 WLAN_REASON_DEAUTH_LEAVING); 545 } 546 } 547 548 549 static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx) 550 { 551 struct wpa_supplicant *wpa_s = eloop_ctx; 552 if (wpa_s->wpa_state == WPA_AUTHENTICATING) { 553 wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout"); 554 sme_deauth(wpa_s); 555 } 556 } 557 558 559 static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx) 560 { 561 struct wpa_supplicant *wpa_s = eloop_ctx; 562 if (wpa_s->wpa_state == WPA_ASSOCIATING) { 563 wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout"); 564 sme_deauth(wpa_s); 565 } 566 } 567 568 569 void sme_state_changed(struct wpa_supplicant *wpa_s) 570 { 571 /* Make sure timers are cleaned up appropriately. */ 572 if (wpa_s->wpa_state != WPA_ASSOCIATING) 573 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 574 if (wpa_s->wpa_state != WPA_AUTHENTICATING) 575 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 576 } 577 578 579 void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, 580 const u8 *prev_pending_bssid) 581 { 582 /* 583 * mac80211-workaround to force deauth on failed auth cmd, 584 * requires us to remain in authenticating state to allow the 585 * second authentication attempt to be continued properly. 586 */ 587 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication " 588 "to proceed after disconnection event"); 589 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 590 os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); 591 592 /* 593 * Re-arm authentication timer in case auth fails for whatever reason. 594 */ 595 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 596 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 597 NULL); 598 } 599 600 601 void sme_deinit(struct wpa_supplicant *wpa_s) 602 { 603 os_free(wpa_s->sme.ft_ies); 604 wpa_s->sme.ft_ies = NULL; 605 wpa_s->sme.ft_ies_len = 0; 606 #ifdef CONFIG_IEEE80211W 607 sme_stop_sa_query(wpa_s); 608 #endif /* CONFIG_IEEE80211W */ 609 610 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 611 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 612 } 613 614 615 #ifdef CONFIG_IEEE80211W 616 617 static const unsigned int sa_query_max_timeout = 1000; 618 static const unsigned int sa_query_retry_timeout = 201; 619 620 static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) 621 { 622 u32 tu; 623 struct os_time now, passed; 624 os_get_time(&now); 625 os_time_sub(&now, &wpa_s->sme.sa_query_start, &passed); 626 tu = (passed.sec * 1000000 + passed.usec) / 1024; 627 if (sa_query_max_timeout < tu) { 628 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out"); 629 sme_stop_sa_query(wpa_s); 630 wpa_supplicant_deauthenticate( 631 wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID); 632 return 1; 633 } 634 635 return 0; 636 } 637 638 639 static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, 640 const u8 *trans_id) 641 { 642 u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN]; 643 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to " 644 MACSTR, MAC2STR(wpa_s->bssid)); 645 wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID", 646 trans_id, WLAN_SA_QUERY_TR_ID_LEN); 647 req[0] = WLAN_ACTION_SA_QUERY; 648 req[1] = WLAN_SA_QUERY_REQUEST; 649 os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); 650 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 651 wpa_s->own_addr, wpa_s->bssid, 652 req, sizeof(req), 0) < 0) 653 wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " 654 "Request"); 655 } 656 657 658 static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 659 { 660 struct wpa_supplicant *wpa_s = eloop_ctx; 661 unsigned int timeout, sec, usec; 662 u8 *trans_id, *nbuf; 663 664 if (wpa_s->sme.sa_query_count > 0 && 665 sme_check_sa_query_timeout(wpa_s)) 666 return; 667 668 nbuf = os_realloc(wpa_s->sme.sa_query_trans_id, 669 (wpa_s->sme.sa_query_count + 1) * 670 WLAN_SA_QUERY_TR_ID_LEN); 671 if (nbuf == NULL) 672 return; 673 if (wpa_s->sme.sa_query_count == 0) { 674 /* Starting a new SA Query procedure */ 675 os_get_time(&wpa_s->sme.sa_query_start); 676 } 677 trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 678 wpa_s->sme.sa_query_trans_id = nbuf; 679 wpa_s->sme.sa_query_count++; 680 681 os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); 682 683 timeout = sa_query_retry_timeout; 684 sec = ((timeout / 1000) * 1024) / 1000; 685 usec = (timeout % 1000) * 1024; 686 eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL); 687 688 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d", 689 wpa_s->sme.sa_query_count); 690 691 sme_send_sa_query_req(wpa_s, trans_id); 692 } 693 694 695 static void sme_start_sa_query(struct wpa_supplicant *wpa_s) 696 { 697 sme_sa_query_timer(wpa_s, NULL); 698 } 699 700 701 void sme_stop_sa_query(struct wpa_supplicant *wpa_s) 702 { 703 eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL); 704 os_free(wpa_s->sme.sa_query_trans_id); 705 wpa_s->sme.sa_query_trans_id = NULL; 706 wpa_s->sme.sa_query_count = 0; 707 } 708 709 710 void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, 711 const u8 *da, u16 reason_code) 712 { 713 struct wpa_ssid *ssid; 714 715 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) 716 return; 717 if (wpa_s->wpa_state != WPA_COMPLETED) 718 return; 719 ssid = wpa_s->current_ssid; 720 if (ssid == NULL || ssid->ieee80211w == 0) 721 return; 722 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 723 return; 724 if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && 725 reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) 726 return; 727 if (wpa_s->sme.sa_query_count > 0) 728 return; 729 730 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - " 731 "possible AP/STA state mismatch - trigger SA Query"); 732 sme_start_sa_query(wpa_s); 733 } 734 735 736 void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, 737 const u8 *data, size_t len) 738 { 739 int i; 740 741 if (wpa_s->sme.sa_query_trans_id == NULL || 742 len < 1 + WLAN_SA_QUERY_TR_ID_LEN || 743 data[0] != WLAN_SA_QUERY_RESPONSE) 744 return; 745 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from " 746 MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); 747 748 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 749 return; 750 751 for (i = 0; i < wpa_s->sme.sa_query_count; i++) { 752 if (os_memcmp(wpa_s->sme.sa_query_trans_id + 753 i * WLAN_SA_QUERY_TR_ID_LEN, 754 data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0) 755 break; 756 } 757 758 if (i >= wpa_s->sme.sa_query_count) { 759 wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query " 760 "transaction identifier found"); 761 return; 762 } 763 764 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received " 765 "from " MACSTR, MAC2STR(sa)); 766 sme_stop_sa_query(wpa_s); 767 } 768 769 #endif /* CONFIG_IEEE80211W */ 770