18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Glue code to setup EAPOL and RSN modules 3807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet/l2_packet.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sme.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpas_glue.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 28c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#include "notify.h" 295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "wpas_kay.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_set_config_blob(void *ctx, 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_config_blob *blob) 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_blob(wpa_s->conf, blob); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->update_config) { 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to update config after " 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "blob set"); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const struct wpa_config_blob * 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_get_config_blob(void *ctx, const char *name) 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_config_get_blob(wpa_s->conf, name); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */ 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const void *data, u16 data_len, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *msg_len, void **data_pos) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg_len = sizeof(*hdr) + data_len; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = os_malloc(*msg_len); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr == NULL) 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version = wpa_s->conf->eapol_version; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type = type; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = host_to_be16(data_len); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hdr + 1, data, data_len); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(hdr + 1, 0, data_len); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_pos) 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *data_pos = hdr + 1; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (u8 *) hdr; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_ether_send - Send Ethernet frame 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @dest: Destination MAC address 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @proto: Ethertype in host byte order 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Frame payload starting from IEEE 802.1X header 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Frame payload length 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: >=0 on success, <0 on failure 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest, 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 proto, const u8 *buf, size_t len) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 1006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) { 1016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t hex_len = 2 * len + 1; 1026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *hex = os_malloc(hex_len); 1036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hex == NULL) 1056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 1066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_snprintf_hex(hex, hex_len, buf, len); 1076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "EAPOL-TX " MACSTR " %s", 1086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt MAC2STR(dest), hex); 1096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(hex); 1106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 1116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 1136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->l2) { 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return l2_packet_send(wpa_s->l2, dest, proto, buf, len); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pointer to wpa_supplicant data (wpa_s) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: EAPOL payload (after IEEE 802.1X header) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: EAPOL payload length 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: >=0 on success, <0 on failure 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the current Authenticator. 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf, 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg, *dst, bssid[ETH_ALEN]; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t msglen; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could add l2_packet_sendmsg that allows fragments to avoid 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * extra copy here */ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Current SSID is not using IEEE 802.1X/EAP, so drop possible 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL frames (mainly, EAPOL-Start) from EAPOL state 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machines. */ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X " 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mode (type=%d len=%lu)", type, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_get_current(wpa_s->wpa) && 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type == IEEE802_1X_TYPE_EAPOL_START) { 160661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* 161661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * We were trying to use PMKSA caching and sending EAPOL-Start 162661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * would abort that and trigger full EAPOL authentication. 163661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * However, we've already waited for the AP/Authenticator to 164661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * start 4-way handshake or EAP authentication, and apparently 165661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * it has not done so since the startWhen timer has reached zero 166661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * to get the state machine sending EAPOL-Start. This is not 167661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * really supposed to happen, but an interoperability issue with 168661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * a deployed AP has been identified where the connection fails 169661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * due to that AP failing to operate correctly if PMKID is 170661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * included in the Association Request frame. To work around 171661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * this, assume PMKSA caching failed and try to initiate full 172661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * EAP authentication. 173661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt */ 174661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!wpa_s->current_ssid || 175661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_s->current_ssid->eap_workaround) { 176661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, 177661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "RSN: Timeout on waiting for the AP to initiate 4-way handshake for PMKSA caching or EAP authentication - try to force it to start EAP authentication"); 178661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } else { 179661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, 180661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "RSN: PMKSA caching - do not send EAPOL-Start"); 181661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 182661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(wpa_s->bssid)) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an " 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL frame"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_get_bssid(wpa_s, bssid) == 0 && 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(bssid)) { 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = bssid; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " from the driver as the EAPOL destination", 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dst)); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = wpa_s->last_eapol_src; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Using the source address of the" 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " last received EAPOL frame " MACSTR " as " 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the EAPOL destination", 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dst)); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* BSSID was already set (from (Re)Assoc event, so use it as 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the EAPOL destination. */ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = wpa_s->bssid; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst)); 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_eapol_set_wep_key - set WEP key for the driver 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pointer to wpa_supplicant data (wpa_s) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @unicast: 1 = individual unicast key, 0 = broadcast key 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @keyidx: WEP key index (0..3) 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Pointer to key data 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @keylen: Key length in bytes 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success or < 0 on error. 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx, 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t keylen) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 : 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_CIPHER_WEP104; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (unicast) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pairwise_cipher = cipher; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->group_cipher = cipher; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_set_key(wpa_s, WPA_ALG_WEP, 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unicast ? wpa_s->bssid : NULL, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyidx, unicast, NULL, 0, key, keylen); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_aborted_cached(void *ctx) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_aborted_cached(wpa_s->wpa); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 253344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic const char * result_str(enum eapol_supp_result result) 254344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt{ 255344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt switch (result) { 256344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt case EAPOL_SUPP_RESULT_FAILURE: 257344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return "FAILURE"; 258344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt case EAPOL_SUPP_RESULT_SUCCESS: 259344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return "SUCCESS"; 260344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt case EAPOL_SUPP_RESULT_EXPECTED_FAILURE: 261344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return "EXPECTED_FAILURE"; 262344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 263344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return "?"; 264344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt} 265344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 266344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 267344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, 268344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt enum eapol_supp_result result, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, pmk_len; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pmk[PMK_LEN]; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 275344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s", 276344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result_str(result)); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_wps_eapol_cb(wpa_s) > 0) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 281344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->eap_expected_failure = result == 282344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt EAPOL_SUPP_RESULT_EXPECTED_FAILURE; 283344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 284344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (result != EAPOL_SUPP_RESULT_SUCCESS) { 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure we do not get stuck here waiting for long EAPOL 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout if the AP does not disconnect in case of 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication failure. 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_auth_timeout(wpa_s, 2, 0); 2915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 2925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 295344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (result != EAPOL_SUPP_RESULT_SUCCESS || 296344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way " 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake"); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk_len = PMK_LEN; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[2 * PMK_LEN]; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for " 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver-based 4-way hs and FT"); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pmk, buf + PMK_LEN, PMK_LEN); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(buf, 0, sizeof(buf)); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_IEEE80211R */ 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(eapol, pmk, PMK_LEN); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-LEAP is an exception from other EAP methods: it 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * uses only 16-byte PMK. 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(eapol, pmk, 16); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk_len = 16; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state " 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machines"); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way " 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake", pmk, pmk_len); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmk_len)) { 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_scan(wpa_s); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_auth_timeout(wpa_s); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_notify_eapol_done(void *ctx) 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete"); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_auth_timeout(wpa_s); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *curr = NULL, *bss; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0) 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL || 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((bss->ssid_len == ssid->ssid_len && 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) || 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len == 0)) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt curr = bss; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (curr) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_bss_get_ie(curr, WLAN_EID_RSN); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_get_beacon_ie(void *ctx) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_get_beacon_ie(wpa_s) == 0) { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No WPA/RSN IE found in the cached scan results. Try to get updated 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * scan results from the driver. */ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_update_scan_results(wpa_s) < 0) 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_get_beacon_ie(wpa_s); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const void *data, u16 data_len, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *msg_len, void **data_pos) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto, 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_ether_send(wpa_s, dest, proto, buf, len); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _wpa_supplicant_cancel_auth_timeout(void *wpa_s) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_auth_timeout(wpa_s); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state) 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, state); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_state - Get the connection state 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The current connection state (WPA_*) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s) 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s->wpa_state; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_states _wpa_supplicant_get_state(void *wpa_s) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_supplicant_get_state(wpa_s); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate(wpa_s, reason_code); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule a scan to make sure we continue looking for networks */ 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 5, 0); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * wpa_supplicant_get_network_ctx(void *wpa_s) 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_supplicant_get_ssid(wpa_s); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_get_bssid(void *ctx, u8 *bssid) 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_get_bssid(wpa_s, bssid); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg, 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, int key_idx, int set_tx, 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seq, size_t seq_len, 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t key_len) 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = _wpa_s; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the MIC error counter when setting a new PTK. */ 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->mic_errors_seen = 0; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 495b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt#ifdef CONFIG_TESTING_GET_GTK 496b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) && 497b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) { 498b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt os_memcpy(wpa_s->last_gtk, key, key_len); 499b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->last_gtk_len = key_len; 500b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt } 501b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt#endif /* CONFIG_TESTING_GET_GTK */ 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key, key_len); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int protection_type, 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_type) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type, 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_type); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_add_pmkid(void *wpa_s, 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, const u8 *pmkid) 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_add_pmkid(wpa_s, bssid, pmkid); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_remove_pmkid(void *wpa_s, 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, const u8 *pmkid) 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md, 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sme_update_ft_ies(wpa_s, md, ies, ies_len); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len); 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_send_ft_action(void *ctx, u8 action, 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *target_ap, 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 5466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int ret; 5476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 *data, *pos; 5486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t data_len; 5496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (action != 1) { 5516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, "Unsupported send_ft_action action %d", 5526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt action); 5536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 5546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 5576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Action frame payload: 5586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Category[1] = 6 (Fast BSS Transition) 5596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Action[1] = 1 (Fast BSS Transition Request) 5606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * STA Address 5616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Target AP Address 5626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * FT IEs 5636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 5646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data_len = 2 + 2 * ETH_ALEN + ies_len; 5666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data = os_malloc(data_len); 5676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (data == NULL) 5686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 5696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos = data; 5706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos++ = 0x06; /* FT Action category */ 5716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos++ = action; 5726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(pos, wpa_s->own_addr, ETH_ALEN); 5736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += ETH_ALEN; 5746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(pos, target_ap, ETH_ALEN); 5756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += ETH_ALEN; 5766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(pos, ies, ies_len); 5776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, 5796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid, 5806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data, data_len, 0); 5816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(data); 5826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 5836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return ret; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap) 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_auth_params params; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get_bssid(wpa_s, target_ap); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = target_ap; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq = bss->freq; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = bss->ssid; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = bss->ssid_len; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_FT; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.local_state_change = 1; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_authenticate(wpa_s, ¶ms); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported, 6126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int *tdls_ext_setup, 6136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int *tdls_chan_switch) 6141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 6151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 6161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *tdls_supported = 0; 6181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *tdls_ext_setup = 0; 6196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *tdls_chan_switch = 0; 6201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->drv_capa_known) 6221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) 6251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *tdls_supported = 1; 6261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP) 6281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *tdls_ext_setup = 1; 6291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH) 6316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *tdls_chan_switch = 1; 6326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 6341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst, 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 action_code, u8 dialog_token, 639df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt u16 status_code, u32 peer_capab, 6409ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt int initiator, const u8 *buf, 6419ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt size_t len) 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token, 6459ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt status_code, peer_capab, initiator, buf, 6469ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt len); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer) 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_tdls_oper(wpa_s, oper, peer); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_tdls_peer_addset( 65851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt void *ctx, const u8 *peer, int add, u16 aid, u16 capability, 659f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt const u8 *supp_rates, size_t supp_rates_len, 660f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt const struct ieee80211_ht_capabilities *ht_capab, 66133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt const struct ieee80211_vht_capabilities *vht_capab, 6629ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, 663344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt const u8 *supp_channels, size_t supp_channels_len, 664344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt const u8 *supp_oper_classes, size_t supp_oper_classes_len) 6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 6661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 6671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_sta_add_params params; 6681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 669f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 670f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 6711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.addr = peer; 67251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt params.aid = aid; 6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.capability = capability; 6741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED; 675f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 676f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 6779ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * Don't rely only on qosinfo for WMM capability. It may be 0 even when 6789ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * present. Allow the WMM IE to also indicate QoS support. 679f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 6809ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (wmm || qosinfo) 681f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt params.flags |= WPA_STA_WMM; 682f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 683f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt params.ht_capabilities = ht_capab; 68433e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt params.vht_capabilities = vht_capab; 685f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt params.qosinfo = qosinfo; 6861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.listen_interval = 0; 6871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.supp_rates = supp_rates; 6881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.supp_rates_len = supp_rates_len; 6891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.set = !add; 690f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt params.ext_capab = ext_capab; 691f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt params.ext_capab_len = ext_capab_len; 692344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.supp_channels = supp_channels; 693344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.supp_channels_len = supp_channels_len; 694344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.supp_oper_classes = supp_oper_classes; 695344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.supp_oper_classes_len = supp_oper_classes_len; 6961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_sta_add(wpa_s, ¶ms); 6981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpa_supplicant_tdls_enable_channel_switch( 7026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt void *ctx, const u8 *addr, u8 oper_class, 7036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const struct hostapd_freq_params *params) 7046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 7056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 7066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return wpa_drv_tdls_enable_channel_switch(wpa_s, addr, oper_class, 7086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params); 7096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 7106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpa_supplicant_tdls_disable_channel_switch(void *ctx, const u8 *addr) 7136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 7146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 7156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return wpa_drv_tdls_disable_channel_switch(wpa_s, addr); 7176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 7186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */ 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 72134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_NO_WPA */ 72234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtenum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field) 7251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 7261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_strcmp(field, "IDENTITY") == 0) 7271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_IDENTITY; 7281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strcmp(field, "PASSWORD") == 0) 7291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_PASSWORD; 7301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strcmp(field, "NEW_PASSWORD") == 0) 7311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_NEW_PASSWORD; 7321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strcmp(field, "PIN") == 0) 7331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_PIN; 7341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strcmp(field, "OTP") == 0) 7351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_OTP; 7361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strcmp(field, "PASSPHRASE") == 0) 7371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_EAP_PASSPHRASE; 738051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt else if (os_strcmp(field, "SIM") == 0) 739051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return WPA_CTRL_REQ_SIM; 740912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt else if (os_strcmp(field, "PSK_PASSPHRASE") == 0) 741912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt return WPA_CTRL_REQ_PSK_PASSPHRASE; 7421b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt else if (os_strcmp(field, "EXT_CERT_CHECK") == 0) 7431b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return WPA_CTRL_REQ_EXT_CERT_CHECK; 7441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WPA_CTRL_REQ_UNKNOWN; 7451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field, 7491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *default_txt, 7501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char **txt) 7511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 7521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *ret = NULL; 7531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = default_txt; 7551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (field) { 7571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_IDENTITY: 7581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = "Identity"; 7591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "IDENTITY"; 7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSWORD: 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = "Password"; 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "PASSWORD"; 7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = "New Password"; 7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "NEW_PASSWORD"; 7681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PIN: 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = "PIN"; 7711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "PIN"; 7721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_OTP: 7741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "OTP"; 7751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WPA_CTRL_REQ_EAP_PASSPHRASE: 7771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *txt = "Private key passphrase"; 7781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = "PASSPHRASE"; 7791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 780051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case WPA_CTRL_REQ_SIM: 781051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ret = "SIM"; 782051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 783912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt case WPA_CTRL_REQ_PSK_PASSPHRASE: 784912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt *txt = "PSK or passphrase"; 785912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt ret = "PSK_PASSPHRASE"; 786912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt break; 7871b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt case WPA_CTRL_REQ_EXT_CERT_CHECK: 7881b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt *txt = "External server certificate validation"; 7891b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt ret = "EXT_CERT_CHECK"; 7901b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt break; 7911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt default: 7921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* txt needs to be something */ 7961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (*txt == NULL) { 7971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_WARNING, "No message for request %d", field); 7981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = NULL; 7991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 8021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 8031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 804912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 805912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidtvoid wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 806912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt const char *field_name, const char *txt) 807912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt{ 808912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt char *buf; 809912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt size_t buflen; 810912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt int len; 811912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 812912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt buflen = 100 + os_strlen(txt) + ssid->ssid_len; 813912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt buf = os_malloc(buflen); 814912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (buf == NULL) 815912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt return; 816912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt len = os_snprintf(buf, buflen, "%s-%d:%s needed for SSID ", 817912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt field_name, ssid->id, txt); 818912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (os_snprintf_error(buflen, len)) { 819912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt os_free(buf); 820912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt return; 821912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 822912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (ssid->ssid && buflen > len + ssid->ssid_len) { 823912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt os_memcpy(buf + len, ssid->ssid, ssid->ssid_len); 824912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt len += ssid->ssid_len; 825912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt buf[len] = '\0'; 826912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 827912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt buf[buflen - 1] = '\0'; 828912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, WPA_CTRL_REQ "%s", buf); 829912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt os_free(buf); 830912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt} 831912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 832912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 8351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpa_supplicant_eap_param_needed(void *ctx, 8361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum wpa_ctrl_req_type field, 8371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *default_txt) 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 8411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *field_name, *txt = NULL; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8461b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (field == WPA_CTRL_REQ_EXT_CERT_CHECK) 8471b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt ssid->eap.pending_ext_cert_check = PENDING_CHECK; 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_network_request(wpa_s, ssid, field, default_txt); 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt, 8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &txt); 8521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (field_name == NULL) { 8531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed", 8541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt field); 8551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 858a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name); 859a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 860912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpas_send_ctrl_req(wpa_s, ssid, field_name, txt); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define wpa_supplicant_eap_param_needed NULL 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 867203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 868203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidtstatic void wpa_supplicant_eap_proxy_cb(void *ctx) 869203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt{ 870203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 871203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt size_t len; 872203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 873203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, 874203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_s->imsi, &len); 875203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (wpa_s->mnc_len > 0) { 876203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_s->imsi[len] = '\0'; 877203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)", 878203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_s->imsi, wpa_s->mnc_len); 879203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 880203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available"); 881203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 882203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt} 883203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 884203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 885203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_port_cb(void *ctx, int authorized) 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) { 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "AP mode active - skip EAPOL Supplicant " 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "port status: %s", 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authorized ? "Authorized" : "Unauthorized"); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */ 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s", 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authorized ? "Authorized" : "Unauthorized"); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_supp_port(wpa_s, authorized); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 901c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 902c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 903c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject, 9042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *altsubject[], int num_altsubject, 905c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const char *cert_hash, 906c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const struct wpabuf *cert) 907c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{ 908c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 909c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 9102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpas_notify_certification(wpa_s, depth, subject, altsubject, 9112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_altsubject, cert_hash, cert); 912c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt} 91304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 91404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 91504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_status_cb(void *ctx, const char *status, 91604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *parameter) 91704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 91804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 91904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 92004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_notify_eap_status(wpa_s, status, parameter); 92104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 9224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len) 9254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 9264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 9274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *str; 9284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int res; 9294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity", 9314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt id, len); 9324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (wpa_s->current_ssid == NULL) 9344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 9354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (id == NULL) { 9374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 9384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "NULL", 0) < 0) 9394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 9404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else { 9414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt str = os_malloc(len * 2 + 1); 9424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (str == NULL) 9434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 9444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_snprintf_hex(str, len * 2 + 1, id, len); 9454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 9464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt str, 0); 9474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(str); 9484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (res < 0) 9494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 9504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 9514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 9524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (wpa_s->conf->update_config) { 9534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt res = wpa_config_write(wpa_s->confname, wpa_s->conf); 9544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (res) { 9554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to update config after " 9564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "anonymous_id update"); 9574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 9584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 9594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_ctx *ctx; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) { 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context."); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->ctx = wpa_s; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->msg_ctx = wpa_s; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_send_ctx = wpa_s; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->preauth = 0; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_send = wpa_supplicant_eapol_send; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_wep_key = wpa_eapol_set_wep_key; 980700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_config_blob = wpa_supplicant_set_config_blob; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_config_blob = wpa_supplicant_get_config_blob; 983700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->aborted_cached = wpa_supplicant_aborted_cached; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 9886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->wps = wpa_s->wps; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eap_param_needed = wpa_supplicant_eap_param_needed; 991203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 992203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt ctx->eap_proxy_cb = wpa_supplicant_eap_proxy_cb; 993203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->port_cb = wpa_supplicant_port_cb; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cb = wpa_supplicant_eapol_cb; 996c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt ctx->cert_cb = wpa_supplicant_cert_cb; 9972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ctx->cert_in_cb = wpa_s->conf->cert_in_cb; 99804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ctx->status_cb = wpa_supplicant_status_cb; 9994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ctx->set_anon_id = wpa_supplicant_set_anon_id; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cb_ctx = wpa_s; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->eapol = eapol_sm_init(ctx); 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->eapol == NULL) { 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state " 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machines."); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1014a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifndef CONFIG_NO_WPA 1015807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidtstatic void wpa_supplicant_set_rekey_offload(void *ctx, 1016807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const u8 *kek, size_t kek_len, 1017807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt const u8 *kck, size_t kck_len, 10181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *replay_ctr) 10191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 10201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 10211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1022807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_drv_set_rekey_info(wpa_s, kek, kek_len, kck, kck_len, replay_ctr); 10231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 10241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk, 10276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t pmk_len) 10286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 10296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 10306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10311d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (wpa_s->conf->key_mgmt_offload && 10321d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) 10336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, 10346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt NULL, 0, pmk, pmk_len); 10356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 10366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 10376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1038d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif /* CONFIG_NO_WPA */ 10396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_sm_ctx *ctx; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to allocate WPA context."); 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->ctx = wpa_s; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->msg_ctx = wpa_s; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_state = _wpa_supplicant_set_state; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_state = _wpa_supplicant_get_state; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->deauthenticate = _wpa_supplicant_deauthenticate; 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_key = wpa_supplicant_set_key; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_network_ctx = wpa_supplicant_get_network_ctx; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_bssid = wpa_supplicant_get_bssid; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->ether_send = _wpa_ether_send; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->alloc_eapol = _wpa_alloc_eapol; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->add_pmkid = wpa_supplicant_add_pmkid; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->remove_pmkid = wpa_supplicant_remove_pmkid; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_config_blob = wpa_supplicant_set_config_blob; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_config_blob = wpa_supplicant_get_config_blob; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->update_ft_ies = wpa_supplicant_update_ft_ies; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->send_ft_action = wpa_supplicant_send_ft_action; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->mark_authenticated = wpa_supplicant_mark_authenticated; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS 10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ctx->tdls_get_capa = wpa_supplicant_tdls_get_capa; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->tdls_oper = wpa_supplicant_tdls_oper; 10791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ctx->tdls_peer_addset = wpa_supplicant_tdls_peer_addset; 10806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ctx->tdls_enable_channel_switch = 10816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_tdls_enable_channel_switch; 10826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ctx->tdls_disable_channel_switch = 10836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_tdls_disable_channel_switch; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */ 10851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload; 10866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wpa = wpa_sm_init(ctx); 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa == NULL) { 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "machine"); 1092ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(ctx); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_WPA */ 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid) 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_supp_config conf; 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&conf, 0, sizeof(conf)); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.network_ctx = ssid; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.peerkey_enabled = ssid->peerkey; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.allowed_pairwise_cipher = ssid->pairwise_cipher; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 1111d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt conf.proactive_key_caching = ssid->proactive_key_caching < 0 ? 1112d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->okc : ssid->proactive_key_caching; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_workaround = ssid->eap_workaround; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_conf_ctx = &ssid->eap; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.ssid = ssid->ssid; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.ssid_len = ssid->ssid_len; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey; 1119cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P 1120cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ssid->p2p_group && wpa_s->current_bss && 1121cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !wpa_s->p2p_disable_ip_addr_req) { 1122cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *p2p; 1123cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss, 1124cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt P2P_IE_VENDOR_TYPE); 1125cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p) { 1126cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 group_capab; 1127cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt group_capab = p2p_get_group_capab(p2p); 1128cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (group_capab & 1129cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION) 1130cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt conf.p2p = 1; 1131cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(p2p); 1132cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1133cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1134cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */ 1135d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf.wpa_rsc_relaxation = wpa_s->conf->wpa_rsc_relaxation; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1139