00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "common/ieee802_11_defs.h"
00019 #include "common/ieee802_11_common.h"
00020 #include "eapol_supp/eapol_supp_sm.h"
00021 #include "common/wpa_common.h"
00022 #include "rsn_supp/wpa.h"
00023 #include "rsn_supp/pmksa_cache.h"
00024 #include "config.h"
00025 #include "wpa_supplicant_i.h"
00026 #include "driver_i.h"
00027 #include "wpas_glue.h"
00028 #include "wps_supplicant.h"
00029 #include "notify.h"
00030 #include "blacklist.h"
00031 #include "bss.h"
00032 #include "scan.h"
00033 #include "sme.h"
00034
00035 #include "../../src/nodes/wpa_supplicant_node.h"
00036
00037 void sme_authenticate(struct wpa_supplicant *wpa_s,
00038 struct wpa_bss *bss, struct wpa_ssid *ssid)
00039 {
00040 struct wpa_driver_auth_params params;
00041 struct wpa_ssid *old_ssid;
00042 #ifdef CONFIG_IEEE80211R
00043 const u8 *ie;
00044 #endif
00045 #ifdef CONFIG_IEEE80211R
00046 const u8 *md = NULL;
00047 #endif
00048 int i, bssid_changed;
00049
00050 if (bss == NULL) {
00051 wpa_printf(MSG_ERROR, "SME: No scan result available for the "
00052 "network");
00053 return;
00054 }
00055
00056 wpa_s->current_bss = bss;
00057
00058 os_memset(¶ms, 0, sizeof(params));
00059 wpa_s->reassociate = 0;
00060
00061 params.freq = bss->freq;
00062 params.bssid = bss->bssid;
00063 params.ssid = bss->ssid;
00064 params.ssid_len = bss->ssid_len;
00065
00066 if (wpa_s->sme.ssid_len != params.ssid_len ||
00067 os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
00068 wpa_s->sme.prev_bssid_set = 0;
00069
00070 wpa_s->sme.freq = params.freq;
00071 os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
00072 wpa_s->sme.ssid_len = params.ssid_len;
00073
00074 params.auth_alg = WPA_AUTH_ALG_OPEN;
00075 #ifdef IEEE8021X_EAPOL
00076 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
00077 if (ssid->leap) {
00078 if (ssid->non_leap == 0)
00079 params.auth_alg = WPA_AUTH_ALG_LEAP;
00080 else
00081 params.auth_alg |= WPA_AUTH_ALG_LEAP;
00082 }
00083 }
00084 #endif
00085 wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
00086 params.auth_alg);
00087 if (ssid->auth_alg) {
00088 params.auth_alg = ssid->auth_alg;
00089 wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x",
00090 params.auth_alg);
00091 }
00092
00093 for (i = 0; i < NUM_WEP_KEYS; i++) {
00094 if (ssid->wep_key_len[i])
00095 params.wep_key[i] = ssid->wep_key[i];
00096 params.wep_key_len[i] = ssid->wep_key_len[i];
00097 }
00098 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
00099
00100 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
00101 os_memset(wpa_s->bssid, 0, ETH_ALEN);
00102 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
00103 if (bssid_changed)
00104 wpas_notify_bssid_changed(wpa_s);
00105
00106 if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
00107 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
00108 (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
00109 WPA_KEY_MGMT_FT_IEEE8021X |
00110 WPA_KEY_MGMT_FT_PSK |
00111 WPA_KEY_MGMT_IEEE8021X_SHA256 |
00112 WPA_KEY_MGMT_PSK_SHA256))) {
00113 int try_opportunistic;
00114 try_opportunistic = ssid->proactive_key_caching &&
00115 (ssid->proto & WPA_PROTO_RSN);
00116 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
00117 wpa_s->current_ssid,
00118 try_opportunistic) == 0)
00119 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
00120 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
00121 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
00122 wpa_s->sme.assoc_req_ie,
00123 &wpa_s->sme.assoc_req_ie_len)) {
00124 wpa_printf(MSG_WARNING, "SME: Failed to set WPA key "
00125 "management and encryption suites");
00126 return;
00127 }
00128 } else if (ssid->key_mgmt &
00129 (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
00130 WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK |
00131 WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 |
00132 WPA_KEY_MGMT_IEEE8021X_SHA256)) {
00133 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
00134 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
00135 wpa_s->sme.assoc_req_ie,
00136 &wpa_s->sme.assoc_req_ie_len)) {
00137 wpa_printf(MSG_WARNING, "SME: Failed to set WPA key "
00138 "management and encryption suites (no scan "
00139 "results)");
00140 return;
00141 }
00142 #ifdef CONFIG_WPS
00143 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
00144 struct wpabuf *wps_ie;
00145 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
00146 if (wps_ie && wpabuf_len(wps_ie) <=
00147 sizeof(wpa_s->sme.assoc_req_ie)) {
00148 wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie);
00149 os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie),
00150 wpa_s->sme.assoc_req_ie_len);
00151 } else
00152 wpa_s->sme.assoc_req_ie_len = 0;
00153 wpabuf_free(wps_ie);
00154 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
00155 #endif
00156 } else {
00157 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
00158 wpa_s->sme.assoc_req_ie_len = 0;
00159 }
00160
00161 #ifdef CONFIG_IEEE80211R
00162 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
00163 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
00164 md = ie + 2;
00165 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
00166 if (md) {
00167
00168 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
00169 }
00170
00171 if (md && ssid->key_mgmt & (WPA_KEY_MGMT_FT_PSK |
00172 WPA_KEY_MGMT_FT_IEEE8021X)) {
00173 if (wpa_s->sme.assoc_req_ie_len + 5 <
00174 sizeof(wpa_s->sme.assoc_req_ie)) {
00175 struct rsn_mdie *mdie;
00176 u8 *pos = wpa_s->sme.assoc_req_ie +
00177 wpa_s->sme.assoc_req_ie_len;
00178 *pos++ = WLAN_EID_MOBILITY_DOMAIN;
00179 *pos++ = sizeof(*mdie);
00180 mdie = (struct rsn_mdie *) pos;
00181 os_memcpy(mdie->mobility_domain, md,
00182 MOBILITY_DOMAIN_ID_LEN);
00183 mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN];
00184 wpa_s->sme.assoc_req_ie_len += 5;
00185 }
00186
00187 if (wpa_s->sme.ft_used &&
00188 os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 &&
00189 wpa_sm_has_ptk(wpa_s->wpa)) {
00190 wpa_printf(MSG_DEBUG, "SME: Trying to use FT "
00191 "over-the-air");
00192 params.auth_alg = WPA_AUTH_ALG_FT;
00193 params.ie = wpa_s->sme.ft_ies;
00194 params.ie_len = wpa_s->sme.ft_ies_len;
00195 }
00196 }
00197 #endif
00198
00199 #ifdef CONFIG_IEEE80211W
00200 wpa_s->sme.mfp = ssid->ieee80211w;
00201 if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
00202 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
00203 struct wpa_ie_data _ie;
00204 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
00205 _ie.capabilities &
00206 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
00207 wpa_printf(MSG_DEBUG, "WPA: Selected AP supports MFP: "
00208 "require MFP");
00209 wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
00210 }
00211 }
00212 #endif
00213
00214 wpa_supplicant_cancel_scan(wpa_s);
00215
00216 wpa_msg(wpa_s, MSG_INFO, "Trying to authenticate with " MACSTR
00217 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
00218 wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
00219
00220 wpa_clear_keys(wpa_s, bss->bssid);
00221 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
00222 old_ssid = wpa_s->current_ssid;
00223 wpa_s->current_ssid = ssid;
00224 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
00225 wpa_supplicant_initiate_eapol(wpa_s);
00226 if (old_ssid != wpa_s->current_ssid)
00227 wpas_notify_network_changed(wpa_s);
00228
00229 wpa_s->sme.auth_alg = params.auth_alg;
00230 if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) {
00231 wpa_msg(wpa_s, MSG_INFO, "Authentication request to the "
00232 "driver failed");
00233
00234 ros_assoc_failed(wpa_s, bss->bssid, "Driver request to authenticate failed");
00235 return;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 }
00245
00246
00247 void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
00248 {
00249 struct wpa_ssid *ssid = wpa_s->current_ssid;
00250
00251 if (ssid == NULL) {
00252 wpa_printf(MSG_DEBUG, "SME: Ignore authentication event when "
00253 "network is not selected");
00254 return;
00255 }
00256
00257 if (wpa_s->wpa_state != WPA_AUTHENTICATING) {
00258 wpa_printf(MSG_DEBUG, "SME: Ignore authentication event when "
00259 "not in authenticating state");
00260 return;
00261 }
00262
00263 if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) {
00264 wpa_printf(MSG_DEBUG, "SME: Ignore authentication with "
00265 "unexpected peer " MACSTR,
00266 MAC2STR(data->auth.peer));
00267 return;
00268 }
00269
00270 wpa_printf(MSG_DEBUG, "SME: Authentication response: peer=" MACSTR
00271 " auth_type=%d status_code=%d",
00272 MAC2STR(data->auth.peer), data->auth.auth_type,
00273 data->auth.status_code);
00274 wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
00275 data->auth.ies, data->auth.ies_len);
00276
00277 if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
00278 wpa_printf(MSG_DEBUG, "SME: Authentication failed (status "
00279 "code %d)", data->auth.status_code);
00280 ros_assoc_failed(wpa_s, data->auth.peer, "Authentication failed");
00281 return;
00282 }
00283
00284 #ifdef CONFIG_IEEE80211R
00285 if (data->auth.auth_type == WLAN_AUTH_FT) {
00286 union wpa_event_data edata;
00287 os_memset(&edata, 0, sizeof(edata));
00288 edata.ft_ies.ies = data->auth.ies;
00289 edata.ft_ies.ies_len = data->auth.ies_len;
00290 os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN);
00291 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata);
00292 }
00293 #endif
00294
00295 sme_associate(wpa_s, ssid->mode, data->auth.peer,
00296 data->auth.auth_type);
00297 }
00298
00299
00300 void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
00301 const u8 *bssid, u16 auth_type)
00302 {
00303 struct wpa_driver_associate_params params;
00304 struct ieee802_11_elems elems;
00305
00306 os_memset(¶ms, 0, sizeof(params));
00307 params.bssid = bssid;
00308 params.ssid = wpa_s->sme.ssid;
00309 params.ssid_len = wpa_s->sme.ssid_len;
00310 params.freq = wpa_s->sme.freq;
00311 params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
00312 wpa_s->sme.assoc_req_ie : NULL;
00313 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
00314 #ifdef CONFIG_IEEE80211R
00315 if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
00316 params.wpa_ie = wpa_s->sme.ft_ies;
00317 params.wpa_ie_len = wpa_s->sme.ft_ies_len;
00318 }
00319 #endif
00320 params.mode = mode;
00321 params.mgmt_frame_protection = wpa_s->sme.mfp;
00322 if (wpa_s->sme.prev_bssid_set)
00323 params.prev_bssid = wpa_s->sme.prev_bssid;
00324
00325 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
00326 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
00327 params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
00328 params.freq);
00329
00330 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
00331
00332 if (params.wpa_ie == NULL ||
00333 ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
00334 < 0) {
00335 wpa_printf(MSG_DEBUG, "SME: Could not parse own IEs?!");
00336 os_memset(&elems, 0, sizeof(elems));
00337 }
00338 if (elems.rsn_ie)
00339 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
00340 elems.rsn_ie_len + 2);
00341 else if (elems.wpa_ie)
00342 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
00343 elems.wpa_ie_len + 2);
00344 else
00345 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
00346
00347 if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
00348 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
00349 "failed");
00350
00351 ros_assoc_failed(wpa_s, bssid, "Driver request to associate failed");
00352 return;
00353 }
00354
00355
00356 }
00357
00358
00359 int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
00360 const u8 *ies, size_t ies_len)
00361 {
00362 if (md == NULL || ies == NULL) {
00363 wpa_printf(MSG_DEBUG, "SME: Remove mobility domain");
00364 os_free(wpa_s->sme.ft_ies);
00365 wpa_s->sme.ft_ies = NULL;
00366 wpa_s->sme.ft_ies_len = 0;
00367 wpa_s->sme.ft_used = 0;
00368 return 0;
00369 }
00370
00371 os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN);
00372 wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len);
00373 os_free(wpa_s->sme.ft_ies);
00374 wpa_s->sme.ft_ies = os_malloc(ies_len);
00375 if (wpa_s->sme.ft_ies == NULL)
00376 return -1;
00377 os_memcpy(wpa_s->sme.ft_ies, ies, ies_len);
00378 wpa_s->sme.ft_ies_len = ies_len;
00379 return 0;
00380 }
00381
00382
00383 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
00384 union wpa_event_data *data)
00385 {
00386 int bssid_changed;
00387 int timeout = 5000;
00388
00389 wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: "
00390 "status code %d", MAC2STR(wpa_s->pending_bssid),
00391 data->assoc_reject.status_code);
00392
00393 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
00394
00395
00396
00397
00398
00399
00400
00401
00402 if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
00403 WLAN_REASON_DEAUTH_LEAVING) < 0) {
00404 wpa_msg(wpa_s, MSG_INFO,
00405 "Deauth request to the driver failed");
00406 }
00407 wpa_s->sme.prev_bssid_set = 0;
00408
00409 if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) {
00410 struct wpa_blacklist *b;
00411 b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid);
00412 if (b && b->count < 3) {
00413
00414
00415
00416
00417 timeout = 100;
00418 }
00419 }
00420 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
00421 os_memset(wpa_s->bssid, 0, ETH_ALEN);
00422 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
00423 if (bssid_changed)
00424 wpas_notify_bssid_changed(wpa_s);
00425
00426
00427
00428
00429
00430 ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Association rejected");
00431
00432
00433 }
00434
00435
00436 void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
00437 union wpa_event_data *data)
00438 {
00439 int timeout = 5000;
00440
00441 wpa_printf(MSG_DEBUG, "SME: Authentication timed out");
00442
00443 if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) {
00444 struct wpa_blacklist *b;
00445 b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid);
00446 if (b && b->count < 3) {
00447
00448
00449
00450
00451 timeout = 100;
00452 }
00453 }
00454 ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Authentication timed out");
00455
00456
00457 }
00458
00459
00460 void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
00461 union wpa_event_data *data)
00462 {
00463 wpa_printf(MSG_DEBUG, "SME: Association timed out");
00464 wpa_supplicant_mark_disassoc(wpa_s);
00465 ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Association timed out");
00466
00467 }
00468
00469
00470 void sme_event_disassoc(struct wpa_supplicant *wpa_s,
00471 union wpa_event_data *data)
00472 {
00473 wpa_printf(MSG_DEBUG, "SME: Disassociation event received");
00474 if (!is_zero_ether_addr(wpa_s->bssid) &&
00475 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) {
00476
00477
00478
00479
00480
00481
00482 wpa_printf(MSG_DEBUG, "SME: Deauthenticate to clear driver "
00483 "state");
00484 wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
00485 WLAN_REASON_DEAUTH_LEAVING);
00486 }
00487 }