wpas_glue.c
Go to the documentation of this file.
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(&params, 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, &params);
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 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36