$search
00001 /* 00002 * WPA Supplicant - Glue code to setup EAPOL and RSN modules 00003 * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "eapol_supp/eapol_supp_sm.h" 00019 #include "rsn_supp/wpa.h" 00020 #include "eloop.h" 00021 #include "config.h" 00022 #include "l2_packet/l2_packet.h" 00023 #include "common/wpa_common.h" 00024 #include "wpa_supplicant_i.h" 00025 #include "driver_i.h" 00026 #include "rsn_supp/pmksa_cache.h" 00027 #include "mlme.h" 00028 #include "sme.h" 00029 #include "common/ieee802_11_defs.h" 00030 #include "common/wpa_ctrl.h" 00031 #include "wpas_glue.h" 00032 #include "wps_supplicant.h" 00033 #include "bss.h" 00034 #include "scan.h" 00035 00036 00037 #ifndef CONFIG_NO_CONFIG_BLOBS 00038 #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) 00039 static void wpa_supplicant_set_config_blob(void *ctx, 00040 struct wpa_config_blob *blob) 00041 { 00042 struct wpa_supplicant *wpa_s = ctx; 00043 wpa_config_set_blob(wpa_s->conf, blob); 00044 if (wpa_s->conf->update_config) { 00045 int ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 00046 if (ret) { 00047 wpa_printf(MSG_DEBUG, "Failed to update config after " 00048 "blob set"); 00049 } 00050 } 00051 } 00052 00053 00054 static const struct wpa_config_blob * 00055 wpa_supplicant_get_config_blob(void *ctx, const char *name) 00056 { 00057 struct wpa_supplicant *wpa_s = ctx; 00058 return wpa_config_get_blob(wpa_s->conf, name); 00059 } 00060 #endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */ 00061 #endif /* CONFIG_NO_CONFIG_BLOBS */ 00062 00063 00064 #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) 00065 static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type, 00066 const void *data, u16 data_len, 00067 size_t *msg_len, void **data_pos) 00068 { 00069 struct ieee802_1x_hdr *hdr; 00070 00071 *msg_len = sizeof(*hdr) + data_len; 00072 hdr = os_malloc(*msg_len); 00073 if (hdr == NULL) 00074 return NULL; 00075 00076 hdr->version = wpa_s->conf->eapol_version; 00077 hdr->type = type; 00078 hdr->length = host_to_be16(data_len); 00079 00080 if (data) 00081 os_memcpy(hdr + 1, data, data_len); 00082 else 00083 os_memset(hdr + 1, 0, data_len); 00084 00085 if (data_pos) 00086 *data_pos = hdr + 1; 00087 00088 return (u8 *) hdr; 00089 } 00090 00091 00101 static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest, 00102 u16 proto, const u8 *buf, size_t len) 00103 { 00104 if (wpa_s->l2) { 00105 return l2_packet_send(wpa_s->l2, dest, proto, buf, len); 00106 } 00107 00108 return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len); 00109 } 00110 #endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */ 00111 00112 00113 #ifdef IEEE8021X_EAPOL 00114 00126 static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf, 00127 size_t len) 00128 { 00129 struct wpa_supplicant *wpa_s = ctx; 00130 u8 *msg, *dst, bssid[ETH_ALEN]; 00131 size_t msglen; 00132 int res; 00133 00134 /* TODO: could add l2_packet_sendmsg that allows fragments to avoid 00135 * extra copy here */ 00136 00137 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || 00138 wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { 00139 /* Current SSID is not using IEEE 802.1X/EAP, so drop possible 00140 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state 00141 * machines. */ 00142 wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X " 00143 "mode (type=%d len=%lu)", type, 00144 (unsigned long) len); 00145 return -1; 00146 } 00147 00148 if (pmksa_cache_get_current(wpa_s->wpa) && 00149 type == IEEE802_1X_TYPE_EAPOL_START) { 00150 /* Trying to use PMKSA caching - do not send EAPOL-Start frames 00151 * since they will trigger full EAPOL authentication. */ 00152 wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send " 00153 "EAPOL-Start"); 00154 return -1; 00155 } 00156 00157 if (is_zero_ether_addr(wpa_s->bssid)) { 00158 wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an " 00159 "EAPOL frame"); 00160 if (wpa_drv_get_bssid(wpa_s, bssid) == 0 && 00161 !is_zero_ether_addr(bssid)) { 00162 dst = bssid; 00163 wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR 00164 " from the driver as the EAPOL destination", 00165 MAC2STR(dst)); 00166 } else { 00167 dst = wpa_s->last_eapol_src; 00168 wpa_printf(MSG_DEBUG, "Using the source address of the" 00169 " last received EAPOL frame " MACSTR " as " 00170 "the EAPOL destination", 00171 MAC2STR(dst)); 00172 } 00173 } else { 00174 /* BSSID was already set (from (Re)Assoc event, so use it as 00175 * the EAPOL destination. */ 00176 dst = wpa_s->bssid; 00177 } 00178 00179 msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL); 00180 if (msg == NULL) 00181 return -1; 00182 00183 wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst)); 00184 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen); 00185 res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen); 00186 os_free(msg); 00187 return res; 00188 } 00189 00190 00200 static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx, 00201 const u8 *key, size_t keylen) 00202 { 00203 struct wpa_supplicant *wpa_s = ctx; 00204 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 00205 int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 : 00206 WPA_CIPHER_WEP104; 00207 if (unicast) 00208 wpa_s->pairwise_cipher = cipher; 00209 else 00210 wpa_s->group_cipher = cipher; 00211 } 00212 return wpa_drv_set_key(wpa_s, WPA_ALG_WEP, 00213 unicast ? wpa_s->bssid : 00214 (u8 *) "\xff\xff\xff\xff\xff\xff", 00215 keyidx, unicast, (u8 *) "", 0, key, keylen); 00216 } 00217 00218 00219 static void wpa_supplicant_aborted_cached(void *ctx) 00220 { 00221 struct wpa_supplicant *wpa_s = ctx; 00222 wpa_sm_aborted_cached(wpa_s->wpa); 00223 } 00224 00225 00226 static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success, 00227 void *ctx) 00228 { 00229 struct wpa_supplicant *wpa_s = ctx; 00230 int res, pmk_len; 00231 u8 pmk[PMK_LEN]; 00232 00233 wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully", 00234 success ? "" : "un"); 00235 00236 if (wpas_wps_eapol_cb(wpa_s) > 0) 00237 return; 00238 00239 if (!success) { 00240 /* 00241 * Make sure we do not get stuck here waiting for long EAPOL 00242 * timeout if the AP does not disconnect in case of 00243 * authentication failure. 00244 */ 00245 wpa_supplicant_req_auth_timeout(wpa_s, 2, 0); 00246 } 00247 00248 if (!success || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) 00249 return; 00250 00251 if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) 00252 return; 00253 00254 wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way " 00255 "handshake"); 00256 00257 pmk_len = PMK_LEN; 00258 res = eapol_sm_get_key(eapol, pmk, PMK_LEN); 00259 if (res) { 00260 /* 00261 * EAP-LEAP is an exception from other EAP methods: it 00262 * uses only 16-byte PMK. 00263 */ 00264 res = eapol_sm_get_key(eapol, pmk, 16); 00265 pmk_len = 16; 00266 } 00267 00268 if (res) { 00269 wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state " 00270 "machines"); 00271 return; 00272 } 00273 00274 if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, 00275 pmk_len)) { 00276 wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); 00277 } 00278 00279 wpa_supplicant_cancel_scan(wpa_s); 00280 wpa_supplicant_cancel_auth_timeout(wpa_s); 00281 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 00282 00283 } 00284 00285 00286 static void wpa_supplicant_notify_eapol_done(void *ctx) 00287 { 00288 struct wpa_supplicant *wpa_s = ctx; 00289 wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete"); 00290 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { 00291 wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE); 00292 } else { 00293 wpa_supplicant_cancel_auth_timeout(wpa_s); 00294 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 00295 } 00296 } 00297 00298 #endif /* IEEE8021X_EAPOL */ 00299 00300 00301 #ifndef CONFIG_NO_WPA 00302 00303 static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) 00304 { 00305 int ret = 0; 00306 struct wpa_bss *curr = NULL, *bss; 00307 struct wpa_ssid *ssid = wpa_s->current_ssid; 00308 const u8 *ie; 00309 00310 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 00311 if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0) 00312 continue; 00313 if (ssid == NULL || 00314 ((bss->ssid_len == ssid->ssid_len && 00315 os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) || 00316 ssid->ssid_len == 0)) { 00317 curr = bss; 00318 break; 00319 } 00320 } 00321 00322 if (curr) { 00323 ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); 00324 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) 00325 ret = -1; 00326 00327 ie = wpa_bss_get_ie(curr, WLAN_EID_RSN); 00328 if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) 00329 ret = -1; 00330 } else { 00331 ret = -1; 00332 } 00333 00334 return ret; 00335 } 00336 00337 00338 static int wpa_supplicant_get_beacon_ie(void *ctx) 00339 { 00340 struct wpa_supplicant *wpa_s = ctx; 00341 if (wpa_get_beacon_ie(wpa_s) == 0) { 00342 return 0; 00343 } 00344 00345 /* No WPA/RSN IE found in the cached scan results. Try to get updated 00346 * scan results from the driver. */ 00347 if (wpa_supplicant_update_scan_results(wpa_s) < 0) 00348 return -1; 00349 00350 return wpa_get_beacon_ie(wpa_s); 00351 } 00352 00353 00354 static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, 00355 const void *data, u16 data_len, 00356 size_t *msg_len, void **data_pos) 00357 { 00358 return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos); 00359 } 00360 00361 00362 static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto, 00363 const u8 *buf, size_t len) 00364 { 00365 return wpa_ether_send(wpa_s, dest, proto, buf, len); 00366 } 00367 00368 00369 static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s) 00370 { 00371 wpa_supplicant_cancel_auth_timeout(wpa_s); 00372 } 00373 00374 00375 static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state) 00376 { 00377 wpa_supplicant_set_state(wpa_s, state); 00378 } 00379 00380 00386 static enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s) 00387 { 00388 return wpa_s->wpa_state; 00389 } 00390 00391 00392 static enum wpa_states _wpa_supplicant_get_state(void *wpa_s) 00393 { 00394 return wpa_supplicant_get_state(wpa_s); 00395 } 00396 00397 00398 static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code) 00399 { 00400 wpa_supplicant_disassociate(wpa_s, reason_code); 00401 /* Schedule a scan to make sure we continue looking for networks */ 00402 wpa_supplicant_req_scan(wpa_s, 5, 0); 00403 } 00404 00405 00406 static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code) 00407 { 00408 wpa_supplicant_deauthenticate(wpa_s, reason_code); 00409 /* Schedule a scan to make sure we continue looking for networks */ 00410 wpa_supplicant_req_scan(wpa_s, 5, 0); 00411 } 00412 00413 00414 static void * wpa_supplicant_get_network_ctx(void *wpa_s) 00415 { 00416 return wpa_supplicant_get_ssid(wpa_s); 00417 } 00418 00419 00420 static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid) 00421 { 00422 struct wpa_supplicant *wpa_s = ctx; 00423 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { 00424 os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); 00425 return 0; 00426 } 00427 return wpa_drv_get_bssid(wpa_s, bssid); 00428 } 00429 00430 00431 static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg, 00432 const u8 *addr, int key_idx, int set_tx, 00433 const u8 *seq, size_t seq_len, 00434 const u8 *key, size_t key_len) 00435 { 00436 struct wpa_supplicant *wpa_s = _wpa_s; 00437 if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { 00438 /* Clear the MIC error counter when setting a new PTK. */ 00439 wpa_s->mic_errors_seen = 0; 00440 } 00441 return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, 00442 key, key_len); 00443 } 00444 00445 00446 static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr, 00447 int protection_type, 00448 int key_type) 00449 { 00450 return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type, 00451 key_type); 00452 } 00453 00454 00455 static int wpa_supplicant_add_pmkid(void *wpa_s, 00456 const u8 *bssid, const u8 *pmkid) 00457 { 00458 return wpa_drv_add_pmkid(wpa_s, bssid, pmkid); 00459 } 00460 00461 00462 static int wpa_supplicant_remove_pmkid(void *wpa_s, 00463 const u8 *bssid, const u8 *pmkid) 00464 { 00465 return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid); 00466 } 00467 00468 00469 #ifdef CONFIG_IEEE80211R 00470 static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md, 00471 const u8 *ies, size_t ies_len) 00472 { 00473 struct wpa_supplicant *wpa_s = ctx; 00474 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) 00475 return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len); 00476 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 00477 return sme_update_ft_ies(wpa_s, md, ies, ies_len); 00478 return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len); 00479 } 00480 00481 00482 static int wpa_supplicant_send_ft_action(void *ctx, u8 action, 00483 const u8 *target_ap, 00484 const u8 *ies, size_t ies_len) 00485 { 00486 struct wpa_supplicant *wpa_s = ctx; 00487 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) 00488 return ieee80211_sta_send_ft_action(wpa_s, action, target_ap, 00489 ies, ies_len); 00490 return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len); 00491 } 00492 00493 00494 static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap) 00495 { 00496 struct wpa_supplicant *wpa_s = ctx; 00497 struct wpa_driver_auth_params params; 00498 struct wpa_bss *bss; 00499 00500 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) 00501 return -1; 00502 00503 bss = wpa_bss_get_bssid(wpa_s, target_ap); 00504 if (bss == NULL) 00505 return -1; 00506 00507 os_memset(¶ms, 0, sizeof(params)); 00508 params.bssid = target_ap; 00509 params.freq = bss->freq; 00510 params.ssid = bss->ssid; 00511 params.ssid_len = bss->ssid_len; 00512 params.auth_alg = WPA_AUTH_ALG_FT; 00513 params.local_state_change = 1; 00514 return wpa_drv_authenticate(wpa_s, ¶ms); 00515 } 00516 #endif /* CONFIG_IEEE80211R */ 00517 00518 #endif /* CONFIG_NO_WPA */ 00519 00520 00521 #ifdef IEEE8021X_EAPOL 00522 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 00523 static void wpa_supplicant_eap_param_needed(void *ctx, const char *field, 00524 const char *txt) 00525 { 00526 struct wpa_supplicant *wpa_s = ctx; 00527 struct wpa_ssid *ssid = wpa_s->current_ssid; 00528 char *buf; 00529 size_t buflen; 00530 int len; 00531 00532 if (ssid == NULL) 00533 return; 00534 00535 buflen = 100 + os_strlen(txt) + ssid->ssid_len; 00536 buf = os_malloc(buflen); 00537 if (buf == NULL) 00538 return; 00539 len = os_snprintf(buf, buflen, 00540 WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 00541 field, ssid->id, txt); 00542 if (len < 0 || (size_t) len >= buflen) { 00543 os_free(buf); 00544 return; 00545 } 00546 if (ssid->ssid && buflen > len + ssid->ssid_len) { 00547 os_memcpy(buf + len, ssid->ssid, ssid->ssid_len); 00548 len += ssid->ssid_len; 00549 buf[len] = '\0'; 00550 } 00551 buf[buflen - 1] = '\0'; 00552 wpa_msg(wpa_s, MSG_INFO, "%s", buf); 00553 os_free(buf); 00554 } 00555 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 00556 #define wpa_supplicant_eap_param_needed NULL 00557 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 00558 00559 00560 static void wpa_supplicant_port_cb(void *ctx, int authorized) 00561 { 00562 struct wpa_supplicant *wpa_s = ctx; 00563 wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s", 00564 authorized ? "Authorized" : "Unauthorized"); 00565 wpa_drv_set_supp_port(wpa_s, authorized); 00566 } 00567 #endif /* IEEE8021X_EAPOL */ 00568 00569 00570 int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) 00571 { 00572 #ifdef IEEE8021X_EAPOL 00573 struct eapol_ctx *ctx; 00574 ctx = os_zalloc(sizeof(*ctx)); 00575 if (ctx == NULL) { 00576 wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context."); 00577 return -1; 00578 } 00579 00580 ctx->ctx = wpa_s; 00581 ctx->msg_ctx = wpa_s; 00582 ctx->eapol_send_ctx = wpa_s; 00583 ctx->preauth = 0; 00584 ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done; 00585 ctx->eapol_send = wpa_supplicant_eapol_send; 00586 ctx->set_wep_key = wpa_eapol_set_wep_key; 00587 ctx->set_config_blob = wpa_supplicant_set_config_blob; 00588 ctx->get_config_blob = wpa_supplicant_get_config_blob; 00589 ctx->aborted_cached = wpa_supplicant_aborted_cached; 00590 ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 00591 ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 00592 ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 00593 ctx->wps = wpa_s->wps; 00594 ctx->eap_param_needed = wpa_supplicant_eap_param_needed; 00595 ctx->port_cb = wpa_supplicant_port_cb; 00596 ctx->cb = wpa_supplicant_eapol_cb; 00597 ctx->cb_ctx = wpa_s; 00598 wpa_s->eapol = eapol_sm_init(ctx); 00599 if (wpa_s->eapol == NULL) { 00600 os_free(ctx); 00601 wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state " 00602 "machines."); 00603 return -1; 00604 } 00605 #endif /* IEEE8021X_EAPOL */ 00606 00607 return 0; 00608 } 00609 00610 00611 int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) 00612 { 00613 #ifndef CONFIG_NO_WPA 00614 struct wpa_sm_ctx *ctx; 00615 ctx = os_zalloc(sizeof(*ctx)); 00616 if (ctx == NULL) { 00617 wpa_printf(MSG_ERROR, "Failed to allocate WPA context."); 00618 return -1; 00619 } 00620 00621 ctx->ctx = wpa_s; 00622 ctx->msg_ctx = wpa_s; 00623 ctx->set_state = _wpa_supplicant_set_state; 00624 ctx->get_state = _wpa_supplicant_get_state; 00625 ctx->deauthenticate = _wpa_supplicant_deauthenticate; 00626 ctx->disassociate = _wpa_supplicant_disassociate; 00627 ctx->set_key = wpa_supplicant_set_key; 00628 ctx->get_network_ctx = wpa_supplicant_get_network_ctx; 00629 ctx->get_bssid = wpa_supplicant_get_bssid; 00630 ctx->ether_send = _wpa_ether_send; 00631 ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; 00632 ctx->alloc_eapol = _wpa_alloc_eapol; 00633 ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; 00634 ctx->add_pmkid = wpa_supplicant_add_pmkid; 00635 ctx->remove_pmkid = wpa_supplicant_remove_pmkid; 00636 #ifndef CONFIG_NO_CONFIG_BLOBS 00637 ctx->set_config_blob = wpa_supplicant_set_config_blob; 00638 ctx->get_config_blob = wpa_supplicant_get_config_blob; 00639 #endif /* CONFIG_NO_CONFIG_BLOBS */ 00640 ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection; 00641 #ifdef CONFIG_IEEE80211R 00642 ctx->update_ft_ies = wpa_supplicant_update_ft_ies; 00643 ctx->send_ft_action = wpa_supplicant_send_ft_action; 00644 ctx->mark_authenticated = wpa_supplicant_mark_authenticated; 00645 #endif /* CONFIG_IEEE80211R */ 00646 00647 wpa_s->wpa = wpa_sm_init(ctx); 00648 if (wpa_s->wpa == NULL) { 00649 wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 00650 "machine"); 00651 return -1; 00652 } 00653 #endif /* CONFIG_NO_WPA */ 00654 00655 return 0; 00656 } 00657 00658 00659 void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, 00660 struct wpa_ssid *ssid) 00661 { 00662 struct rsn_supp_config conf; 00663 if (ssid) { 00664 os_memset(&conf, 0, sizeof(conf)); 00665 conf.network_ctx = ssid; 00666 conf.peerkey_enabled = ssid->peerkey; 00667 conf.allowed_pairwise_cipher = ssid->pairwise_cipher; 00668 #ifdef IEEE8021X_EAPOL 00669 conf.eap_workaround = ssid->eap_workaround; 00670 conf.eap_conf_ctx = &ssid->eap; 00671 #endif /* IEEE8021X_EAPOL */ 00672 conf.ssid = ssid->ssid; 00673 conf.ssid_len = ssid->ssid_len; 00674 conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey; 00675 } 00676 wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL); 00677 }