18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / IEEE 802.1X-2004 Authenticator 3c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Copyright (c) 2002-2012, 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 "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_wsc_common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_auth/eapol_auth_sm_i.h" 231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "p2p/p2p.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "preauth_auth.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pmksa_cache_auth.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 32fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#include "wps_hostapd.h" 33f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#include "hs20.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#ifdef CONFIG_HS20 38de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtstatic void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx); 39de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* CONFIG_HS20 */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_finished(struct hostapd_data *hapd, 41f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct sta_info *sta, int success, 42f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int remediation); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta, 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type, const u8 *data, size_t datalen) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *xhdr; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int encrypt = 0; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(*xhdr) + datalen; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(len); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "malloc() failed for " 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ieee802_1x_send(len=%lu)", 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xhdr = (struct ieee802_1x_hdr *) buf; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xhdr->version = hapd->conf->eapol_version; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xhdr->type = type; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xhdr->length = host_to_be16(datalen); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (datalen > 0 && data != NULL) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(xhdr + 1, data, datalen); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_pairwise_set(sta->wpa_sm)) 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt = 1; 726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hapd->ext_eapol_frame_io) { 746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t hex_len = 2 * len + 1; 756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *hex = os_malloc(hex_len); 766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hex) { 786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_snprintf_hex(hex, hex_len, buf, len); 796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, 806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "EAPOL-TX " MACSTR " %s", 816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt MAC2STR(sta->addr), hex); 826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(hex); 836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else 856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_PREAUTH) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_preauth_send(hapd, sta, buf, len); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 89a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hostapd_drv_hapd_send_eapol( 90a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd, sta->addr, buf, len, 91a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt encrypt, hostapd_sta_flags_to_drv(sta->flags)); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_set_sta_authorized(struct hostapd_data *hapd, 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, int authorized) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_PREAUTH) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authorized) { 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_set_authorized(hapd, sta, 1); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "authorizing port"); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 0); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_set_authorized(hapd, sta, 0); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "unauthorizing port"); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res && errno != ENOENT) { 1199657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not set station " MACSTR 1209657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt " flags for kernel driver (errno=%d).", 1219657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt MAC2STR(sta->addr), errno); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 124d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (authorized) { 12504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&sta->connected_time); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_start(hapd, sta); 127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 131d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_FIPS 132d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_NO_RC4 133d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_tx_key_one(struct hostapd_data *hapd, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int idx, int broadcast, 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key_data, size_t key_len) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, *ekey; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_eapol_key *key; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, ekey_len; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(*key) + key_len; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(sizeof(*hdr) + len); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) buf; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct ieee802_1x_eapol_key *) (hdr + 1); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type = EAPOL_KEY_TYPE_RC4; 15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_BE16(key->key_length, key_len); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_get_ntp_timestamp(key->replay_counter); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(key->key_iv, sizeof(key->key_iv))) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not get random numbers"); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index = idx | (broadcast ? 0 : BIT(7)); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->eapol_key_index_workaround) { 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* According to some information, WinXP Supplicant seems to 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interpret bit7 as an indication whether the key is to be 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * activated, so make it possible to enable workaround that 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sets this bit for all keys. */ 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index |= BIT(7); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Key is encrypted using "Key-IV + MSK[0..31]" as the RC4-key and 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MSK[32..63] is used to sign the message. */ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if->eapKeyData == NULL || sm->eap_if->eapKeyDataLen < 64) { 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "No eapKeyData available for encrypting " 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "and signing EAPOL-Key"); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy((u8 *) (key + 1), key_data, key_len); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ekey_len = sizeof(key->key_iv) + 32; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ekey = os_malloc(ekey_len); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ekey == NULL) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not encrypt key"); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey, key->key_iv, sizeof(key->key_iv)); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey + sizeof(key->key_iv), sm->eap_if->eapKeyData, 32); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ekey, ekey_len, 0, (u8 *) (key + 1), key_len); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ekey); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This header is needed here for HMAC-MD5, but it will be regenerated 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in ieee802_1x_send() */ 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version = hapd->conf->eapol_version; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = host_to_be16(len); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_md5(sm->eap_if->eapKeyData + 32, 32, buf, sizeof(*hdr) + len, 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_signature); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (%s index=%d)", MAC2STR(sm->addr), 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt broadcast ? "broadcast" : "unicast", idx); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAPOL_KEY, (u8 *) key, len); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthEapolFramesTx++; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 213d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_authenticator *eapol = hapd->eapol_auth; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || !sm->eap_if->eapKeyData) 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR, 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_VLAN 22557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (sta->vlan_id > 0) { 2265393a0f77c5281735888bd9dcf8d8abeb5961461Dmitry Shmidt wpa_printf(MSG_ERROR, "Using WEP with vlans is not supported."); 2275393a0f77c5281735888bd9dcf8d8abeb5961461Dmitry Shmidt return; 2285393a0f77c5281735888bd9dcf8d8abeb5961461Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_VLAN */ 2305393a0f77c5281735888bd9dcf8d8abeb5961461Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol->default_wep_key) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_tx_key_one(hapd, sta, eapol->default_wep_key_idx, 1, 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key, 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->default_wep_key_len); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->individual_wep_key_len > 0) { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ikey; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ikey = os_malloc(hapd->conf->individual_wep_key_len); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ikey == NULL || 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_get_bytes(ikey, hapd->conf->individual_wep_key_len)) 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not generate random " 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "individual WEP key."); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ikey); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "Individual WEP key", 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ikey, hapd->conf->individual_wep_key_len); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->individual_wep_key_len); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: set encryption in TX callback, i.e., only after STA 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has ACKed EAPOL-Key frame */ 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->addr, 0, 1, NULL, 0, ikey, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->individual_wep_key_len)) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set individual WEP " 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption."); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ikey); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 269d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FIPS */ 270d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *radius_mode_txt(struct hostapd_data *hapd) 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hapd->iface->conf->hw_mode) { 275a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt case HOSTAPD_MODE_IEEE80211AD: 276a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return "802.11ad"; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODE_IEEE80211A: 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "802.11a"; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODE_IEEE80211G: 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "802.11g"; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODE_IEEE80211B: 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "802.11b"; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rate = 0; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < sta->supported_rates_len; i++) 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->supported_rates[i] & 0x7f) > rate) 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rate = sta->supported_rates[i] & 0x7f; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rate; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_learn_identity(struct hostapd_data *hapd, 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm, 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eap, size_t len) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *identity; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len; 3086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const struct eap_hdr *hdr = (const struct eap_hdr *) eap; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len <= sizeof(struct eap_hdr) || 3116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (hdr->code == EAP_CODE_RESPONSE && 3126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap[sizeof(struct eap_hdr)] != EAP_TYPE_IDENTITY) || 3136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (hdr->code == EAP_CODE_INITIATE && 3146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap[sizeof(struct eap_hdr)] != EAP_ERP_TYPE_REAUTH) || 3156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (hdr->code != EAP_CODE_RESPONSE && 3166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hdr->code != EAP_CODE_INITIATE)) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = eap_get_identity(sm->eap, &identity_len); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity == NULL) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Save station identity for future RADIUS packets */ 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 3254b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt sm->identity = (u8 *) dup_binstr(identity, identity_len); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity == NULL) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity_len = 0; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity_len = identity_len; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X, 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "STA identity '%s'", sm->identity); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolRespIdFramesRx++; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidtstatic int add_common_radius_sta_attr_rsn(struct hostapd_data *hapd, 33903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt struct hostapd_radius_attr *req_attr, 34003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt struct sta_info *sta, 34103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt struct radius_msg *msg) 34203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt{ 34303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt u32 suite; 34403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt int ver, val; 34503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 34603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt ver = wpa_auth_sta_wpa_version(sta->wpa_sm); 34703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt val = wpa_auth_get_pairwise(sta->wpa_sm); 34803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite = wpa_cipher_to_suite(ver, val); 34903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (val != -1 && 35003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !hostapd_config_get_radius_attr(req_attr, 35103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt RADIUS_ATTR_WLAN_PAIRWISE_CIPHER) && 35203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_PAIRWISE_CIPHER, 35303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite)) { 35403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add WLAN-Pairwise-Cipher"); 35503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 35603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 35703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 3584171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt suite = wpa_cipher_to_suite(((hapd->conf->wpa & 0x2) || 3594171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt hapd->conf->osen) ? 36003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt WPA_PROTO_RSN : WPA_PROTO_WPA, 36103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt hapd->conf->wpa_group); 36203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 36303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt RADIUS_ATTR_WLAN_GROUP_CIPHER) && 36403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_GROUP_CIPHER, 36503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite)) { 36603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add WLAN-Group-Cipher"); 36703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 36803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 36903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 37003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt val = wpa_auth_sta_key_mgmt(sta->wpa_sm); 37103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite = wpa_akm_to_suite(val); 37203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (val != -1 && 37303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !hostapd_config_get_radius_attr(req_attr, 37403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt RADIUS_ATTR_WLAN_AKM_SUITE) && 37503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE, 37603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite)) { 37703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add WLAN-AKM-Suite"); 37803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 37903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 38003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 38103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#ifdef CONFIG_IEEE80211W 38203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 38303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt suite = wpa_cipher_to_suite(WPA_PROTO_RSN, 38403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt hapd->conf->group_mgmt_cipher); 38503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (!hostapd_config_get_radius_attr( 38603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt req_attr, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER) && 38703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr_int32( 38803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt msg, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER, suite)) { 38903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, 39003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt "Could not add WLAN-Group-Mgmt-Cipher"); 39103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 39203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 39303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 39403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 39503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 39603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return 0; 39703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt} 39803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 39903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 40061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int add_common_radius_sta_attr(struct hostapd_data *hapd, 40161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_radius_attr *req_attr, 40261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct sta_info *sta, 40361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct radius_msg *msg) 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 40857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt RADIUS_ATTR_SERVICE_TYPE) && 40957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_SERVICE_TYPE, 41057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt RADIUS_SERVICE_TYPE_FRAMED)) { 41157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Service-Type"); 41257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt return -1; 41357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt } 41457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 41557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 41661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_ATTR_NAS_PORT) && 41761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) { 41861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add NAS-Port"); 41961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 42061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 42361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt MAC2STR(sta->addr)); 42461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 42561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 42661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 42761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Calling-Station-Id"); 42861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 42961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sta->flags & WLAN_STA_PREAUTH) { 43261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlcpy(buf, "IEEE 802.11i Pre-Authentication", 43361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(buf)); 43461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s", 43661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt radius_sta_rate(hapd, sta) / 2, 43761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (radius_sta_rate(hapd, sta) & 1) ? ".5" : "", 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt radius_mode_txt(hapd)); 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 44261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_ATTR_CONNECT_INFO) && 44361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 44461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 44561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Connect-Info"); 44661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 449b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (sta->acct_session_id) { 45057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%016llX", 45157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) sta->acct_session_id); 452a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID, 453a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 454a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Acct-Session-Id"); 455a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 456a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 457a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 458a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 459b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if ((hapd->conf->wpa & 2) && 460b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt !hapd->conf->disable_pmksa_caching && 461b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sta->eapol_sm && sta->eapol_sm->acct_multi_session_id) { 46257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%016llX", 46357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) 464b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sta->eapol_sm->acct_multi_session_id); 465b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!radius_msg_add_attr( 466b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt msg, RADIUS_ATTR_ACCT_MULTI_SESSION_ID, 467b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt (u8 *) buf, os_strlen(buf))) { 468b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_INFO, 469b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt "Could not add Acct-Multi-Session-Id"); 470b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 471b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 472b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 473b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 47403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#ifdef CONFIG_IEEE80211R 47503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) && 47603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt sta->wpa_sm && 47703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm)) || 47803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt sta->auth_alg == WLAN_AUTH_FT) && 47903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !hostapd_config_get_radius_attr(req_attr, 48003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt RADIUS_ATTR_MOBILITY_DOMAIN_ID) && 48103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_MOBILITY_DOMAIN_ID, 48203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt WPA_GET_BE16( 48303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt hapd->conf->mobility_domain))) { 48403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Mobility-Domain-Id"); 48503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 48603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 48703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 48803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 4894171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if ((hapd->conf->wpa || hapd->conf->osen) && sta->wpa_sm && 49003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt add_common_radius_sta_attr_rsn(hapd, req_attr, sta, msg) < 0) 49103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 49203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint add_common_radius_attr(struct hostapd_data *hapd, 49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_radius_attr *req_attr, 49961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct sta_info *sta, 50061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct radius_msg *msg) 50161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 50261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char buf[128]; 50361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_radius_attr *attr; 504014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt int len; 50561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 50661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_NAS_IP_ADDRESS) && 50804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->conf->own_ip_addr.af == AF_INET && 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) { 51161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add NAS-IP-Address"); 51261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 51661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 51704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_NAS_IPV6_ADDRESS) && 51804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->conf->own_ip_addr.af == AF_INET6 && 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS, 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) { 52161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add NAS-IPv6-Address"); 52261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 52704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_NAS_IDENTIFIER) && 52804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->conf->nas_identifier && 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER, 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) hapd->conf->nas_identifier, 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(hapd->conf->nas_identifier))) { 53261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add NAS-Identifier"); 53361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 536014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt len = os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":", 537014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt MAC2STR(hapd->own_addr)); 538014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt os_memcpy(&buf[len], hapd->conf->ssid.ssid, 539014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt hapd->conf->ssid.ssid_len); 540014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt len += hapd->conf->ssid.ssid_len; 54161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 54204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_CALLED_STATION_ID) && 54304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID, 544014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt (u8 *) buf, len)) { 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add Called-Station-Id"); 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_ATTR_NAS_PORT_TYPE) && 55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 55261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 55361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add NAS-Port-Type"); 55461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 55661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 55703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#ifdef CONFIG_INTERWORKING 55803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (hapd->conf->interworking && 55903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !is_zero_ether_addr(hapd->conf->hessid)) { 56003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 56103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt MAC2STR(hapd->conf->hessid)); 56203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 56303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt if (!hostapd_config_get_radius_attr(req_attr, 56403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt RADIUS_ATTR_WLAN_HESSID) && 56503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_WLAN_HESSID, 56603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 56703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add WLAN-HESSID"); 56803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt return -1; 56903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 57003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt } 57103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 57203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 57361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sta && add_common_radius_sta_attr(hapd, req_attr, sta, msg) < 0) 57461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 57561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 57661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (attr = req_attr; attr; attr = attr->next) { 57761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, 57861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(attr->val), 57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(attr->val))) { 58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add RADIUS " 58161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "attribute"); 58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 58561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 59061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd, 59161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct sta_info *sta, 59261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *eap, size_t len) 59361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 59461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct radius_msg *msg; 59561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 59661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 59761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm == NULL) 59861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 59961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ieee802_1x_learn_identity(hapd, sm, eap, len); 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "packet"); 60461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->radius_identifier = radius_client_get_id(hapd->radius); 60661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 60761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->radius_identifier); 60861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg == NULL) { 609cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not create new RADIUS packet"); 61061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 61161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 61261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 613b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (radius_msg_make_authenticator(msg) < 0) { 614b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_INFO, "Could not make Request Authenticator"); 615b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt goto fail; 616b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 61761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 61861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->identity && 61961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->identity, sm->identity_len)) { 621cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not add User-Name"); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, sta, 62661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg) < 0) 62761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 62861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: should probably check MTU from driver config; 2304 is max for 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11, but use 1400 to avoid problems with too large packets 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 63204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr, 63304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_FRAMED_MTU) && 63404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 635cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not add Framed-MTU"); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6394171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (!radius_msg_add_eap(msg, eap, len)) { 640cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not add EAP-Message"); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* State attribute must be copied if and only if this packet is 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Access-Request reply to the previous Access-Challenge */ 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_recv_radius && 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(sm->last_recv_radius)->code == 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_CODE_ACCESS_CHALLENGE) { 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = radius_msg_copy_attr(msg, sm->last_recv_radius, 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ATTR_STATE); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 652cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not copy State attribute from previous Access-Challenge"); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res > 0) { 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Copied RADIUS State Attribute"); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->conf->radius_request_cui) { 66104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *cui; 66204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t cui_len; 66304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Add previously learned CUI or nul CUI to request CUI */ 66404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->radius_cui) { 66504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = wpabuf_head(sm->radius_cui); 66604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui_len = wpabuf_len(sm->radius_cui); 66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 66804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = (const u8 *) "\0"; 66904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui_len = 1; 67004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 67104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!radius_msg_add_attr(msg, 67204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, 67304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui, cui_len)) { 67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "Could not add CUI"); 67504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto fail; 67604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 67704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 67804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 679f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 680f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (hapd->conf->hs20) { 681f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 ver = 1; /* Release 2 */ 682f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 683f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, RADIUS_VENDOR_ATTR_WFA_HS20_AP_VERSION, 684f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt &ver, 1)) { 685f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add HS 2.0 AP " 686f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "version"); 687f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt goto fail; 688f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 689f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 690f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sta->hs20_ie && wpabuf_len(sta->hs20_ie) > 0) { 691f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt const u8 *pos; 692f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 buf[3]; 693f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u16 id; 694f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = wpabuf_head_u8(sta->hs20_ie); 695f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf[0] = (*pos) >> 4; 696f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (((*pos) & HS20_PPS_MO_ID_PRESENT) && 697f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_len(sta->hs20_ie) >= 3) 698f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt id = WPA_GET_LE16(pos + 1); 699f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else 700f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt id = 0; 701f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt WPA_PUT_BE16(buf + 1, id); 702f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 703f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, 704f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RADIUS_VENDOR_ATTR_WFA_HS20_STA_VERSION, 705f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf, sizeof(buf))) { 706f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add HS 2.0 " 707f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "STA version"); 708f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt goto fail; 709f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 710f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 711f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 712f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 713f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr) < 0) 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_eap_response(struct hostapd_data *hapd, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, struct eap_hdr *eap, 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type, *data; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = (u8 *) (eap + 1); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*eap) + 1) { 737cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_eap_response: too short response data"); 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_type_supp = type = data[0]; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X, 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d " 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "id=%d len=%d) from STA: EAP Response-%s (%d)", 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->code, eap->identifier, be_to_host16(eap->length), 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_get_name(0, type), type); 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolRespFramesRx++; 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if->eapRespData); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void handle_eap_initiate(struct hostapd_data *hapd, 7586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct sta_info *sta, struct eap_hdr *eap, 7596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t len) 7606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 7616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 7626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 type, *data; 7636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 7646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm == NULL) 7666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 7676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len < sizeof(*eap) + 1) { 7696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 7706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "handle_eap_initiate: too short response data"); 7716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 7726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 7736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data = (u8 *) (eap + 1); 7756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt type = data[0]; 7766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X, 7786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d " 7796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "id=%d len=%d) from STA: EAP Initiate type %u", 7806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap->code, eap->identifier, be_to_host16(eap->length), 7816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt type); 7826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(sm->eap_if->eapRespData); 7846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len); 7856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapolEap = TRUE; 7866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 7876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 7886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Process incoming EAP packet from Supplicant */ 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_eap(struct hostapd_data *hapd, struct sta_info *sta, 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len) 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *eap; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 eap_len; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*eap)) { 798cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, " too short EAP packet"); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = (struct eap_hdr *) buf; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_len = be_to_host16(eap->length); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d", 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->code, eap->identifier, eap_len); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_len < sizeof(*eap)) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " Invalid EAP length"); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (eap_len > len) { 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " Too short frame to contain this EAP " 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "packet"); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (eap_len < len) { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " Ignoring %lu extra bytes after EAP " 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "packet", (unsigned long) len - eap_len); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (eap->code) { 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_REQUEST: 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " (request)"); 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " (response)"); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_eap_response(hapd, sta, eap, eap_len); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_SUCCESS: 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " (success)"); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_FAILURE: 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " (failure)"); 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAP_CODE_INITIATE: 8346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, " (initiate)"); 8356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt handle_eap_initiate(hapd, sta, eap, eap_len); 8366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 8376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAP_CODE_FINISH: 8386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, " (finish)"); 8396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " (unknown code)"); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eapol_state_machine * 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta) 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags = 0; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_PREAUTH) 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAPOL_SM_PREAUTH; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm) { 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAPOL_SM_USES_WPA; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAPOL_SM_FROM_PMKSA_CACHE; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eapol_auth_alloc(hapd->eapol_auth, sta->addr, flags, 85961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->wps_ie, sta->p2p_ie, sta, 86061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->identity, sta->radius_cui); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86431a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidtstatic void ieee802_1x_save_eapol(struct sta_info *sta, const u8 *buf, 86531a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt size_t len) 86631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt{ 86731a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (sta->pending_eapol_rx) { 86831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt wpabuf_free(sta->pending_eapol_rx->buf); 86931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } else { 87031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt sta->pending_eapol_rx = 87131a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt os_malloc(sizeof(*sta->pending_eapol_rx)); 87231a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (!sta->pending_eapol_rx) 87331a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt return; 87431a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } 87531a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 87631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt sta->pending_eapol_rx->buf = wpabuf_alloc_copy(buf, len); 87731a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (!sta->pending_eapol_rx->buf) { 87831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt os_free(sta->pending_eapol_rx); 87931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt sta->pending_eapol_rx = NULL; 88031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt return; 88131a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } 88231a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 88331a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt os_get_reltime(&sta->pending_eapol_rx->rx_time); 88431a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt} 88531a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 88631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_1x_receive - Process the EAPOL frames from the Supplicant 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sa: Source address (sender of the EAPOL frame) 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: EAPOL frame 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of buf in octets 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called for each incoming EAPOL frame from the interface 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf, 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_eapol_key *key; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 datalen; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_pmksa_cache_entry *pmksa; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_mgmt; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 906f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen && 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !hapd->conf->wps_state) 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR, 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, MAC2STR(sa)); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, sa); 9131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!sta || (!(sta->flags & (WLAN_STA_ASSOC | WLAN_STA_PREAUTH)) && 9141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED))) { 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not " 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associated/Pre-authenticating STA"); 91731a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 91831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_AUTH)) { 91931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt wpa_printf(MSG_DEBUG, "Saving EAPOL frame from " MACSTR 92031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt " for later use", MAC2STR(sta->addr)); 92131a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt ieee802_1x_save_eapol(sta, buf, len); 92231a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } 92331a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*hdr)) { 928cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, " too short IEEE 802.1X packet"); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) buf; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datalen = be_to_host16(hdr->length); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " IEEE 802.1X: version=%d type=%d length=%d", 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version, hdr->type, datalen); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len - sizeof(*hdr) < datalen) { 938cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, " frame too short for this IEEE 802.1X packet"); 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm) 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len - sizeof(*hdr) > datalen) { 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " ignoring %lu extra octets after " 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IEEE 802.1X packet", 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len - sizeof(*hdr) - datalen); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm) { 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthEapolFramesRx++; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct ieee802_1x_eapol_key *) (hdr + 1); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (datalen >= sizeof(struct ieee802_1x_eapol_key) && 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type == IEEE802_1X_TYPE_EAPOL_KEY && 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (key->type == EAPOL_KEY_TYPE_WPA || 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type == EAPOL_KEY_TYPE_RSN)) { 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr, 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(*hdr) + datalen); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 964f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->osen && 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) { 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - " 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "802.1X not enabled and WPS not used"); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_mgmt != -1 && wpa_key_mgmt_wpa_psk(key_mgmt)) { 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore EAPOL message - " 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "STA is using PSK"); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta->eapol_sm) { 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta->eapol_sm) 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 984f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!hapd->conf->ieee802_1x && hapd->conf->wps_state) { 9851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u32 wflags = sta->flags & (WLAN_STA_WPS | 9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_STA_WPS2 | 9871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_STA_MAYBE_WPS); 9881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wflags == WLAN_STA_MAYBE_WPS || 9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wflags == (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) { 9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 9911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Delay EAPOL frame transmission until a 9921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * possible WPS STA initiates the handshake 9931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * with EAPOL-Start. Only allow the wait to be 9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * skipped if the STA is known to support WPS 9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 2.0. 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Do not start " 9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "EAPOL until EAPOL-Start is " 9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "received"); 10001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->eapol_sm->flags |= EAPOL_SM_WAIT_START; 10011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eap_if->portEnabled = TRUE; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* since we support version 1, we can ignore version field and proceed 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */ 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: actually, we are not version 1 anymore.. However, Version 2 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * does not change frame contents, so should be ok to process frames 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * more or less identically. Some changes might be needed for 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * verification of fields. */ 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->type) { 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAP_PACKET: 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_START: 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start " 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from STA"); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa) { 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "cached PMKSA " 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available - ignore it since " 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "STA sent EAPOL-Start"); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eapolStart = TRUE; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthEapolStartFramesRx++; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_clear_identity(sta->eapol_sm->eap); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_LOGOFF: 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff " 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from STA"); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_terminate_cause = 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_stop(hapd, sta); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eapolLogoff = TRUE; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_clear_identity(sta->eapol_sm->eap); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_KEY: 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " EAPOL-Key"); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ap_sta_is_authorized(sta)) { 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " Dropped key data from " 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unauthorized Supplicant"); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT: 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " EAPOL-Encapsulated-ASF-Alert"); 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: implement support for this; show data */ 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " unknown IEEE 802.1X packet type"); 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sta->eapol_sm); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_1x_new_station - Start IEEE 802.1X authentication 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sta: The station 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to start IEEE 802.1X authentication when a new 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * station completes IEEE 802.11 association. 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta) 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_pmksa_cache_entry *pmksa; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc = 1; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int force_1x = 0; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_mgmt; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 10916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hapd->conf->wps_state && 10926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ((hapd->conf->wpa && (sta->flags & WLAN_STA_MAYBE_WPS)) || 10936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (sta->flags & WLAN_STA_WPS))) { 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Need to enable IEEE 802.1X/EAPOL state machines for possible 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS handshake even if IEEE 802.1X/EAPOL is not used for 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication in this BSS. 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_1x = 1; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1103f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!force_1x && !hapd->conf->ieee802_1x && !hapd->conf->osen) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - " 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "802.1X not enabled or forced for WPS"); 110604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 110704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Clear any possible EAPOL authenticator state to support 110804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * reassociation change from WPS to PSK. 110904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 1110de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt ieee802_1x_free_station(hapd, sta); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_mgmt != -1 && wpa_key_mgmt_wpa_psk(key_mgmt)) { 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - using PSK"); 111704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 111804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Clear any possible EAPOL authenticator state to support 111904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * reassociation change from WPA-EAP to PSK. 112004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 1121de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt ieee802_1x_free_station(hapd, sta); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm == NULL) { 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "start authentication"); 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm == NULL) { 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE8021X, 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed to allocate state machine"); 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reassoc = 0; 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START; 1141f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!hapd->conf->ieee802_1x && hapd->conf->wps_state && 1142f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt !(sta->flags & WLAN_STA_WPS2)) { 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Delay EAPOL frame transmission until a possible WPS STA 11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * initiates the handshake with EAPOL-Start. Only allow the 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wait to be skipped if the STA is known to support WPS 2.0. 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Do not start EAPOL until " 11491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "EAPOL-Start is received"); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->flags |= EAPOL_SM_WAIT_START; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eap_if->portEnabled = TRUE; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg == WLAN_AUTH_FT) { 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PMK from FT - skip IEEE 802.1X/EAP"); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup EAPOL state machines to already authenticated state 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because of existing FT information from R0KH. */ 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->keyRun = TRUE; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eap_if->eapKeyAvailable = TRUE; 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->authSuccess = TRUE; 1168c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sta->eapol_sm->authFail = FALSE; 1169d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt sta->eapol_sm->portValid = TRUE; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm->eap) 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_notify_cached(sta->eapol_sm->eap); 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: get vlan_id from R0KH using RRB message */ 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa) { 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PMK from PMKSA cache - skip IEEE 802.1X/EAP"); 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup EAPOL state machines to already authenticated state 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because of existing PMKSA information in the cache. */ 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->keyRun = TRUE; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eap_if->eapKeyAvailable = TRUE; 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->authSuccess = TRUE; 1189c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sta->eapol_sm->authFail = FALSE; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm->eap) 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_notify_cached(sta->eapol_sm->eap); 119257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt pmksa_cache_to_eapol_data(hapd, pmksa, sta->eapol_sm); 11938347444e0bfb85e4550817fc99903f38ce8f5bccDmitry Shmidt ap_sta_bind_vlan(hapd, sta); 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Force EAPOL state machines to start 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication without having to wait for the 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Supplicant to send EAPOL-Start. 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->reAuthenticate = TRUE; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sta->eapol_sm); 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtvoid ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta) 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1212de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#ifdef CONFIG_HS20 1213de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta); 1214de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* CONFIG_HS20 */ 1215de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 121631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (sta->pending_eapol_rx) { 121731a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt wpabuf_free(sta->pending_eapol_rx->buf); 121831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt os_free(sta->pending_eapol_rx); 121931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt sta->pending_eapol_rx = NULL; 122031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } 122131a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm = NULL; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sm->last_recv_radius); 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_free_class(&sm->radius_class); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_free(sm); 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta) 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 124061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *eap; 124161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct eap_hdr *hdr; 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_type = -1; 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[64]; 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->last_recv_radius == NULL) { 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapNoReq = TRUE; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = sm->last_recv_radius; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 125561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap = radius_msg_get_eap(msg); 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) { 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3579, Chap. 2.6.3: 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * attribute */ 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, "could not extract " 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Message from RADIUS message"); 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapNoReq = TRUE; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 126761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_len(eap) < sizeof(*hdr)) { 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, "too short EAP packet " 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received from authentication server"); 127161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(eap); 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapNoReq = TRUE; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 127661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_len(eap) > sizeof(*hdr)) 127761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 127961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hdr = wpabuf_head(eap); 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_REQUEST: 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_type >= 0) 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_type_authsrv = eap_type; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 12852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt eap_server_get_name(0, eap_type), eap_type); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 12892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt eap_server_get_name(0, eap_type), eap_type); 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_SUCCESS: 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "EAP Success", sizeof(buf)); 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_FAILURE: 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "EAP Failure", sizeof(buf)); 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d " 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "id=%d len=%d) from RADIUS server: %s", 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code, hdr->identifier, be_to_host16(hdr->length), 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf); 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapReq = TRUE; 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if->aaaEapReqData); 131061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->eap_if->aaaEapReqData = eap; 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_get_keys(struct hostapd_data *hapd, 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, struct radius_msg *msg, 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *req, 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *shared_secret, 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t shared_secret_len) 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_ms_mppe_keys *keys; 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys = radius_msg_get_ms_keys(msg, req, shared_secret, 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_secret_len); 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys && keys->send && keys->recv) { 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = keys->send_len + keys->recv_len; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key", 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->send, keys->send_len); 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key", 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->recv, keys->recv_len); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if->aaaEapKeyData); 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapKeyData = os_malloc(len); 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if->aaaEapKeyData) { 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->eap_if->aaaEapKeyData, keys->recv, 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->recv_len); 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->eap_if->aaaEapKeyData + keys->recv_len, 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->send, keys->send_len); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapKeyDataLen = len; 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapKeyAvailable = TRUE; 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1345807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt } else { 1346807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_printf(MSG_DEBUG, 1347807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt "MS-MPPE: 1x_get_keys, could not get keys: %p send: %p recv: %p", 1348807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt keys, keys ? keys->send : NULL, 1349807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt keys ? keys->recv : NULL); 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys) { 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys->send); 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys->recv); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys); 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_store_radius_class(struct hostapd_data *hapd, 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg) 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13641d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt u8 *attr_class; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t class_len; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count, i; 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_attr_data *nclass; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t nclass_count; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hapd->conf->radius->acct_server || hapd->radius == NULL || 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm == NULL) 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_free_class(&sm->radius_class); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count <= 0) 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt nclass = os_calloc(count, sizeof(struct radius_attr_data)); 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nclass == NULL) 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nclass_count = 0; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13861d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt attr_class = NULL; 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < count; i++) { 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, 13901d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt &attr_class, &class_len, 13911d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt attr_class) < 0) { 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = count; 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (class_len < 1); 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nclass[nclass_count].data = os_malloc(class_len); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nclass[nclass_count].data == NULL) 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14011d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt os_memcpy(nclass[nclass_count].data, attr_class, class_len); 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nclass[nclass_count].len = class_len; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nclass_count++; 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->radius_class.attr = nclass; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->radius_class.count = nclass_count; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Stored %lu RADIUS Class " 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attributes for " MACSTR, 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) sm->radius_class.count, 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Update sta->identity based on User-Name attribute in Access-Accept */ 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_update_sta_identity(struct hostapd_data *hapd, 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg) 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, *identity; 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len, 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL) < 0) 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14314b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt identity = (u8 *) dup_binstr(buf, len); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity == NULL) 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with " 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "User-Name from Access-Accept '%s'", 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity ? (char *) sm->identity : "N/A", 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) identity); 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity = identity; 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity_len = len; 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 144704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/* Update CUI based on Chargeable-User-Identity attribute in Access-Accept */ 144804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void ieee802_1x_update_sta_cui(struct hostapd_data *hapd, 144904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta, 145004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_msg *msg) 145104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 145204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 145304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *cui; 145404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *buf; 145504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t len; 145604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 145704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm == NULL) 145804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 145904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 146004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, 146104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &buf, &len, NULL) < 0) 146204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 146304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 146404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = wpabuf_alloc_copy(buf, len); 146504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cui == NULL) 146604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 146704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 146804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(sm->radius_cui); 146904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->radius_cui = cui; 147004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 147104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 147204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1473f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 1474f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1475f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void ieee802_1x_hs20_sub_rem(struct sta_info *sta, u8 *pos, size_t len) 1476f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1477f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation = 1; 1478f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(sta->remediation_url); 1479f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (len > 2) { 1480f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_url = os_malloc(len); 1481f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!sta->remediation_url) 1482f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1483f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_method = pos[0]; 1484f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(sta->remediation_url, pos + 1, len - 1); 1485f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_url[len - 1] = '\0'; 1486f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Subscription remediation needed " 1487f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "for " MACSTR " - server method %u URL %s", 1488f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt MAC2STR(sta->addr), sta->remediation_method, 1489f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_url); 1490f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else { 1491f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_url = NULL; 1492f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Subscription remediation needed " 1493f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "for " MACSTR, MAC2STR(sta->addr)); 1494f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1495f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* TODO: assign the STA into remediation VLAN or add filtering */ 1496f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1497f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1498f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1499f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void ieee802_1x_hs20_deauth_req(struct hostapd_data *hapd, 1500f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct sta_info *sta, u8 *pos, 1501f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t len) 1502f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1503f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (len < 3) 1504f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; /* Malformed information */ 1505f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_deauth_requested = 1; 1506f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Deauthentication request - Code %u " 1507f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "Re-auth Delay %u", 1508f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt *pos, WPA_GET_LE16(pos + 1)); 1509f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_free(sta->hs20_deauth_req); 1510f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_deauth_req = wpabuf_alloc(len + 1); 1511f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sta->hs20_deauth_req) { 1512f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_data(sta->hs20_deauth_req, pos, 3); 1513f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_u8(sta->hs20_deauth_req, len - 3); 1514f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpabuf_put_data(sta->hs20_deauth_req, pos + 3, len - 3); 1515f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1516f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ap_sta_session_timeout(hapd, sta, hapd->conf->hs20_deauth_req_timeout); 1517f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1518f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1519f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1520f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void ieee802_1x_hs20_session_info(struct hostapd_data *hapd, 1521f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct sta_info *sta, u8 *pos, 1522f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t len, int session_timeout) 1523f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1524f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unsigned int swt; 1525f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int warning_time, beacon_int; 1526f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1527f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (len < 1) 1528f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; /* Malformed information */ 1529f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(sta->hs20_session_info_url); 1530f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_session_info_url = os_malloc(len); 1531f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sta->hs20_session_info_url == NULL) 1532f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1533f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt swt = pos[0]; 1534f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(sta->hs20_session_info_url, pos + 1, len - 1); 1535f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_session_info_url[len - 1] = '\0'; 1536f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Session Information URL='%s' SWT=%u " 1537f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "(session_timeout=%d)", 1538f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_session_info_url, swt, session_timeout); 1539f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (session_timeout < 0) { 1540f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: No Session-Timeout set - ignore session info URL"); 1541f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return; 1542f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1543f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (swt == 255) 1544f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt swt = 1; /* Use one minute as the AP selected value */ 1545f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1546f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((unsigned int) session_timeout < swt * 60) 1547f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt warning_time = 0; 1548f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else 1549f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt warning_time = session_timeout - swt * 60; 1550f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1551f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt beacon_int = hapd->iconf->beacon_int; 1552f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (beacon_int < 1) 1553f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt beacon_int = 100; /* best guess */ 1554f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_disassoc_timer = swt * 60 * 1000 / beacon_int * 125 / 128; 1555f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sta->hs20_disassoc_timer > 65535) 1556f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_disassoc_timer = 65535; 1557f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1558f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ap_sta_session_warning_timeout(hapd, sta, warning_time); 1559f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1560f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1561f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 1562f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1563f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1564f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtstatic void ieee802_1x_check_hs20(struct hostapd_data *hapd, 1565f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct sta_info *sta, 1566f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct radius_msg *msg, 1567f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int session_timeout) 1568f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt{ 1569f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 1570f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 *buf, *pos, *end, type, sublen; 1571f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t len; 1572f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1573f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf = NULL; 1574f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation = 0; 1575f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->hs20_deauth_requested = 0; 1576f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1577f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (;;) { 1578f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC, 1579f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt &buf, &len, buf) < 0) 1580f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1581f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (len < 6) 1582f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1583f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = buf; 1584f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt end = buf + len; 1585f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA) 1586f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 1587f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos += 4; 1588f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1589f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt type = *pos++; 1590f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sublen = *pos++; 1591f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (sublen < 2) 1592f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; /* invalid length */ 1593f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sublen -= 2; /* skip header */ 1594f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (pos + sublen > end) 1595f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; /* invalid WFA VSA */ 1596f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1597f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt switch (type) { 1598f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION: 1599f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ieee802_1x_hs20_sub_rem(sta, pos, sublen); 1600f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1601f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case RADIUS_VENDOR_ATTR_WFA_HS20_DEAUTH_REQ: 1602f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ieee802_1x_hs20_deauth_req(hapd, sta, pos, sublen); 1603f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1604f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case RADIUS_VENDOR_ATTR_WFA_HS20_SESSION_INFO_URL: 1605f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ieee802_1x_hs20_session_info(hapd, sta, pos, sublen, 1606f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt session_timeout); 1607f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1608f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1609f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1610f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 1611f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 1612f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1613f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct sta_id_search { 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 identifier; 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm; 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd, 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_id_search *id_search = ctx; 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->radius_identifier >= 0 && 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->radius_identifier == id_search->identifier) { 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id_search->sm = sm; 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eapol_state_machine * 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier) 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_id_search id_search; 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id_search.identifier = identifier; 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id_search.sm = NULL; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return id_search.sm; 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: RADIUS response message 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @req: RADIUS request message 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @shared_secret: RADIUS shared secret 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @shared_secret_len: Length of shared_secret in octets 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Context data (struct hostapd_data *) 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Processing status 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic RadiusRxResult 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *shared_secret, size_t shared_secret_len, 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *data) 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = data; 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 session_timeout = 0, termination_action, acct_interim_interval; 166457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt int session_timeout_set; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int override_eapReq = 0; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(msg); 166857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt struct vlan_description vlan_desc; 166957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#ifndef CONFIG_NO_VLAN 167057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt int *untagged, *tagged, *notempty; 167157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* CONFIG_NO_VLAN */ 167257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 167357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_memset(&vlan_desc, 0, sizeof(vlan_desc)); 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) { 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching " 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "station for this RADIUS message"); 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = sm->sta; 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * present when packet contains an EAP-Message attribute */ 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) < 0 && 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Allowing RADIUS Access-Reject without " 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Message-Authenticator since it does not include " 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Message"); 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req, 1)) { 1694cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have correct Message-Authenticator - dropped"); 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_INVALID_AUTHENTICATOR; 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code != RADIUS_CODE_ACCESS_REJECT && 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 1701cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Unknown RADIUS message code"); 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->radius_identifier = -1; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR, 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sm->last_recv_radius); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_recv_radius = msg; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session_timeout_set = 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &session_timeout); 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION, 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &termination_action)) 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt termination_action = RADIUS_TERMINATION_ACTION_DEFAULT; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->acct_interim_interval == 0 && 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &acct_interim_interval) == 0) { 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (acct_interim_interval < 60) { 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE8021X, 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignored too small " 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Acct-Interim-Interval %d", 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt acct_interim_interval); 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_interim_interval = acct_interim_interval; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_ACCEPT: 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_VLAN 173857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) { 173957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt notempty = &vlan_desc.notempty; 174057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt untagged = &vlan_desc.untagged; 174157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt tagged = vlan_desc.tagged; 174257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt *notempty = !!radius_msg_get_vlanid(msg, untagged, 174357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt MAX_NUM_TAGGED_VLAN, 174457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt tagged); 174557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt } 174657c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 174757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (vlan_desc.notempty && 174857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt !hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { 17498347444e0bfb85e4550817fc99903f38ce8f5bccDmitry Shmidt sta->eapol_sm->authFail = TRUE; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_RADIUS, 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 175357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt "Invalid VLAN %d%s received from RADIUS server", 175457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt vlan_desc.untagged, 175557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt vlan_desc.tagged[0] ? "+" : ""); 175657c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_memset(&vlan_desc, 0, sizeof(vlan_desc)); 175757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt ap_sta_set_vlan(hapd, sta, &vlan_desc); 17588347444e0bfb85e4550817fc99903f38ce8f5bccDmitry Shmidt break; 175957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt } 176057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 176157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED && 176257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt !vlan_desc.notempty) { 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->authFail = TRUE; 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE8021X, 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "authentication " 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server did not include required VLAN " 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID in Access-Accept"); 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_VLAN */ 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 177357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) 177457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt break; 177557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 177657c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#ifndef CONFIG_NO_VLAN 177757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt if (sta->vlan_id > 0) { 177857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt hostapd_logger(hapd, sta->addr, 177957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt HOSTAPD_MODULE_RADIUS, 178057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt HOSTAPD_LEVEL_INFO, 178157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt "VLAN ID %d", sta->vlan_id); 178257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt } 178357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* CONFIG_NO_VLAN */ 178457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 17858347444e0bfb85e4550817fc99903f38ce8f5bccDmitry Shmidt if ((sta->flags & WLAN_STA_ASSOC) && 17868347444e0bfb85e4550817fc99903f38ce8f5bccDmitry Shmidt ap_sta_bind_vlan(hapd, sta) < 0) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17899ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt sta->session_timeout_set = !!session_timeout_set; 17909ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt sta->session_timeout = session_timeout; 17919ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3580, Ch. 3.17 */ 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (session_timeout_set && termination_action == 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) { 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reAuthPeriod = session_timeout; 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (session_timeout_set) 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_session_timeout(hapd, sta, session_timeout); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaSuccess = TRUE; 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt override_eapReq = 1; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret, 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_secret_len); 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_store_radius_class(hapd, sta, msg); 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_update_sta_identity(hapd, sta, msg); 180504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ieee802_1x_update_sta_cui(hapd, sta, msg); 1806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ieee802_1x_check_hs20(hapd, sta, msg, 1807f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt session_timeout_set ? 1808f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt (int) session_timeout : -1); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_REJECT: 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaFail = TRUE; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt override_eapReq = 1; 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_CHALLENGE: 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapReq = TRUE; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (session_timeout_set) { 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */ 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaMethodTimeout = session_timeout; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sm->addr, 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE8021X, 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "using EAP timeout of %d seconds (from " 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RADIUS)", 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaMethodTimeout); 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use dynamic retransmission behavior per EAP 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * specification. 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaMethodTimeout = 0; 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_decapsulate_radius(hapd, sta); 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (override_eapReq) 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->aaaEapReq = FALSE; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sm); 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_QUEUED; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta) 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "aborting authentication"); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sm->last_recv_radius); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_recv_radius = NULL; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if->eapTimeout) { 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Disconnect the STA since it did not reply to the last EAP 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request and we cannot continue EAP processing (EAP-Failure 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * could only be sent if the EAP peer actually replied). 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "EAP Timeout, STA " MACSTR, 18671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sta->addr)); 18681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->portEnabled = FALSE; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_disconnect(hapd, sta, sta->addr, 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd) 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_authenticator *eapol = hapd->eapol_auth; 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->default_wep_key_len < 1) 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(eapol->default_wep_key); 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key = os_malloc(hapd->conf->default_wep_key_len); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol->default_wep_key == NULL || 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_get_bytes(eapol->default_wep_key, 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->default_wep_key_len)) { 1888cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Could not generate random WEP key"); 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(eapol->default_wep_key); 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key = NULL; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key", 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key, 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->default_wep_key_len); 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_1x_sta_key_available(struct hostapd_data *hapd, 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta, void *ctx) 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm) { 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm->eap_if->eapKeyAvailable = TRUE; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sta->eapol_sm); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx) 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = eloop_ctx; 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_authenticator *eapol = hapd->eapol_auth; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol->default_wep_key_idx >= 3) 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key_idx = 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->individual_wep_key_len > 0 ? 1 : 0; 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key_idx++; 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d", 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key_idx); 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_1x_rekey_broadcast(hapd)) { 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, "failed to generate a " 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "new broadcast key"); 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(eapol->default_wep_key); 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key = NULL; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: Could setup key for RX here, but change default TX keyid only 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after new broadcast key has been sent to all stations. */ 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt broadcast_ether_addr, 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key_idx, 1, NULL, 0, 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key, 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->default_wep_key_len)) { 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, "failed to configure a " 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "new broadcast key"); 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(eapol->default_wep_key); 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol->default_wep_key = NULL; 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL); 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wep_rekeying_period > 0) { 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(hapd->conf->wep_rekeying_period, 0, 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_rekey, hapd, NULL); 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type, 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t datalen) 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) == 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STA_MAYBE_WPS) { 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *identity; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = eap_get_identity(sm->eap, &identity_len); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity && 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((identity_len == WSC_ID_ENROLLEE_LEN && 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(identity, WSC_ID_ENROLLEE, 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WSC_ID_ENROLLEE_LEN) == 0) || 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (identity_len == WSC_ID_REGISTRAR_LEN && 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(identity, WSC_ID_REGISTRAR, 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WSC_ID_REGISTRAR_LEN) == 0))) { 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: WLAN_STA_MAYBE_WPS -> " 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WLAN_STA_WPS"); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_WPS; 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_send(ctx, sta_ctx, type, data, datalen); 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_aaa_send(void *ctx, void *sta_ctx, 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t datalen) 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_encapsulate_radius(hapd, sta, data, datalen); 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success, 2004f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int preauth, int remediation) 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (preauth) 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsn_preauth_finished(hapd, sta, success); 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2011f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ieee802_1x_finished(hapd, sta, success, remediation); 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_1x_get_eap_user(void *ctx, const u8 *identity, 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len, int phase2, 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_user *user) 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct hostapd_eap_user *eap_user; 20211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 2022912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt int rv = -1; 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2024d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt eap_user = hostapd_get_eap_user(hapd, identity, identity_len, phase2); 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user == NULL) 2026912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt goto out; 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(user, 0, sizeof(*user)); 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->phase2 = phase2; 20301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < EAP_MAX_METHODS; i++) { 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->methods[i].vendor = eap_user->methods[i].vendor; 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->methods[i].method = eap_user->methods[i].method; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user->password) { 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->password = os_malloc(eap_user->password_len); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (user->password == NULL) 2038912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt goto out; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(user->password, eap_user->password, 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_user->password_len); 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->password_len = eap_user->password_len; 20421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt user->password_hash = eap_user->password_hash; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->force_version = eap_user->force_version; 2045df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt user->macacl = eap_user->macacl; 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->ttls_auth = eap_user->ttls_auth; 2047f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt user->remediation = eap_user->remediation; 2048912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt rv = 0; 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2050912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidtout: 2051912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (rv) 2052912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__); 2053912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 2054912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt return rv; 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr) 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL || sta->eapol_sm == NULL) 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_logger(void *ctx, const u8 *addr, 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_logger_level level, const char *txt) 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_HOSTAPD_LOGGER 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int hlevel; 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (level) { 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_LOGGER_WARNING: 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlevel = HOSTAPD_LEVEL_WARNING; 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_LOGGER_INFO: 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlevel = HOSTAPD_LEVEL_INFO; 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_LOGGER_DEBUG: 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlevel = HOSTAPD_LEVEL_DEBUG; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s", 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_HOSTAPD_LOGGER */ 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_set_port_authorized(void *ctx, void *sta_ctx, 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int authorized) 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_set_sta_authorized(hapd, sta, authorized); 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx) 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_abort_auth(hapd, sta); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _ieee802_1x_tx_key(void *ctx, void *sta_ctx) 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_FIPS 2115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_NO_RC4 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_tx_key(hapd, sta); 2119d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 2120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FIPS */ 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_eapol_event(void *ctx, void *sta_ctx, 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum eapol_event type) 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* struct hostapd_data *hapd = ctx; */ 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = sta_ctx; 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_AUTH_SM_CHANGE: 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_notify(sta->wpa_sm); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_AUTH_REAUTHENTICATE: 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 21416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic struct eap_server_erp_key * 21436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtieee802_1x_erp_get_key(void *ctx, const char *keyname) 21446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 21456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct hostapd_data *hapd = ctx; 21466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_server_erp_key *erp; 21476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(erp, &hapd->erp_keys, struct eap_server_erp_key, 21496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt list) { 21506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(erp->keyname_nai, keyname) == 0) 21516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return erp; 21526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 21536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 21556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 21566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int ieee802_1x_erp_add_key(void *ctx, struct eap_server_erp_key *erp) 21596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 21606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct hostapd_data *hapd = ctx; 21616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_add(&hapd->erp_keys, &erp->list); 21636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 21646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 21656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 21676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_1x_init(struct hostapd_data *hapd) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_auth_config conf; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_auth_cb cb; 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_init(&hapd->erp_keys); 21766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&conf, 0, sizeof(conf)); 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.ctx = hapd; 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_reauth_period = hapd->conf->eap_reauth_period; 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.wpa = hapd->conf->wpa; 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.individual_wep_key_len = hapd->conf->individual_wep_key_len; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_server = hapd->conf->eap_server; 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.ssl_ctx = hapd->ssl_ctx; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.msg_ctx = hapd->msg_ctx; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_sim_db_priv = hapd->eap_sim_db_priv; 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_req_id_text = hapd->conf->eap_req_id_text; 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len; 21886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conf.erp_send_reauth_start = hapd->conf->erp_send_reauth_start; 21896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conf.erp_domain = hapd->conf->erp_domain; 21906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conf.erp = hapd->conf->eap_server_erp; 2191d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf.tls_session_lifetime = hapd->conf->tls_session_lifetime; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pac_opaque_encr_key = hapd->conf->pac_opaque_encr_key; 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_fast_a_id = hapd->conf->eap_fast_a_id; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len; 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_fast_a_id_info = hapd->conf->eap_fast_a_id_info; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_fast_prov = hapd->conf->eap_fast_prov; 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pac_key_lifetime = hapd->conf->pac_key_lifetime; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pac_key_refresh_time = hapd->conf->pac_key_refresh_time; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind; 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.tnc = hapd->conf->tnc; 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.wps = hapd->wps; 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.fragment_size = hapd->conf->fragment_size; 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pwd_group = hapd->conf->pwd_group; 220487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen conf.pbc_in_m1 = hapd->conf->pbc_in_m1; 220534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (hapd->conf->server_id) { 220634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conf.server_id = (const u8 *) hapd->conf->server_id; 220734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conf.server_id_len = os_strlen(hapd->conf->server_id); 220834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } else { 220934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conf.server_id = (const u8 *) "hostapd"; 221034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conf.server_id_len = 7; 221134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&cb, 0, sizeof(cb)); 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.eapol_send = ieee802_1x_eapol_send; 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.aaa_send = ieee802_1x_aaa_send; 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.finished = _ieee802_1x_finished; 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.get_eap_user = ieee802_1x_get_eap_user; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.sta_entry_alive = ieee802_1x_sta_entry_alive; 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.logger = ieee802_1x_logger; 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.set_port_authorized = ieee802_1x_set_port_authorized; 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.abort_auth = _ieee802_1x_abort_auth; 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.tx_key = _ieee802_1x_tx_key; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb.eapol_event = ieee802_1x_eapol_event; 22246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 22256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt cb.erp_get_key = ieee802_1x_erp_get_key; 22266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt cb.erp_add_key = ieee802_1x_erp_add_key; 22276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->eapol_auth = eapol_auth_init(&conf, &cb); 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->eapol_auth == NULL) 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->ieee802_1x || hapd->conf->wpa) && 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1)) 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_client_register(hapd->radius, RADIUS_AUTH, 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_receive_auth, hapd)) 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->default_wep_key_len) { 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(hapd->conf->iface, hapd, 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_ALG_NONE, NULL, i, 0, NULL, 0, 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0); 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_rekey(hapd, NULL); 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->eapol_auth->default_wep_key == NULL) 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid ieee802_1x_erp_flush(struct hostapd_data *hapd) 22606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 22616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_server_erp_key *erp; 22626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 22636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while ((erp = dl_list_first(&hapd->erp_keys, struct eap_server_erp_key, 22646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt list)) != NULL) { 22656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_del(&erp->list); 22666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(erp, sizeof(*erp)); 22676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 22686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 22696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 22706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_deinit(struct hostapd_data *hapd) 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL); 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (hapd->driver && hapd->drv_priv && 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (hapd->conf->ieee802_1x || hapd->conf->wpa)) 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_deinit(hapd->eapol_auth); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->eapol_auth = NULL; 22816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 22826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ieee802_1x_erp_flush(hapd); 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len, int ack) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_hdr *hdr; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char rfc1042_hdr[ETH_ALEN] = 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len < sizeof(*hdr) + sizeof(rfc1042_hdr) + 2) 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee80211_hdr *) buf; 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (hdr + 1); 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pos, rfc1042_hdr, sizeof(rfc1042_hdr)) != 0) 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += sizeof(rfc1042_hdr); 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(pos) != ETH_P_PAE) 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ieee802_1x_eapol_tx_status(hapd, sta, pos, buf + len - pos, 23091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ack); 23101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 23111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta, 23141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *buf, int len, int ack) 23151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 23161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct ieee802_1x_hdr *xhdr = 23171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (const struct ieee802_1x_hdr *) buf; 23181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *pos = buf + sizeof(*xhdr); 23191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct ieee802_1x_eapol_key *key; 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len < (int) sizeof(*xhdr)) 23221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR " TX status - version=%d " 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type=%d length=%d - ack=%d", 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr), xhdr->version, xhdr->type, 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt be_to_host16(xhdr->length), ack); 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (xhdr->type != IEEE802_1X_TYPE_EAPOL_KEY) 23291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 23301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + sizeof(struct wpa_eapol_key) <= buf + len) { 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_eapol_key *wpa; 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa = (const struct wpa_eapol_key *) pos; 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa->type == EAPOL_KEY_TYPE_RSN || 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa->type == EAPOL_KEY_TYPE_WPA) 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_eapol_key_tx_status(hapd->wpa_auth, 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wpa_sm, ack); 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * or Authenticator state machines, but EAPOL-Key packets are not 23421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * retransmitted in case of failure. Try to re-send failed EAPOL-Key 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets couple of times because otherwise STA keys become 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unsynchronized with AP. */ 23451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!ack && pos + sizeof(*key) <= buf + len) { 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct ieee802_1x_eapol_key *) pos; 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "did not Ack EAPOL-Key " 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame (%scast index=%d)", 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & BIT(7) ? "uni" : "broad", 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & ~BIT(7)); 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: re-send EAPOL-Key couple of times (with short delay 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * between them?). If all attempt fail, report error and 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deauthenticate STA so that it will get new keys when 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authenticating again (e.g., after returning in range). 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Separate limit/transmit state needed both for unicast and 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * broadcast keys(?) */ 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could move unicast key configuration from ieee802_1x_tx_key() 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to here and change the key only if the EAPOL-Key packet was Acked. 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len) 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->identity == NULL) 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->identity_len; 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->identity; 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int idx) 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->radius_class.attr == NULL || 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx >= (int) sm->radius_class.count) 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->radius_class.attr[idx].len; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->radius_class.attr[idx].data; 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstruct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm) 239004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 239104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm == NULL) 239204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return NULL; 239304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return sm->radius_cui; 239404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 239504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 239604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len) 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 239975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *len = 0; 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->eap_if->eapKeyDataLen; 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eap_if->eapKeyData; 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm, 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int enabled) 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if->portEnabled = enabled ? TRUE : FALSE; 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sm); 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_notify_port_valid(struct eapol_state_machine *sm, 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int valid) 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = valid ? TRUE : FALSE; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_auth_step(sm); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth) 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pre_auth) 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->flags |= EAPOL_SM_PREAUTH; 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->flags &= ~EAPOL_SM_PREAUTH; 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24391d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const char * bool_txt(Boolean val) 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24411d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return val ? "TRUE" : "FALSE"; 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len = 0, ret; 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_state_machine *sm = sta->eapol_sm; 2457fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime diff; 245896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt const char *name1; 245996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt const char *name2; 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xPaePortNumber=%d\n" 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xPaePortProtocolVersion=%d\n" 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xPaePortCapabilities=1\n" 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xPaePortInitialize=%d\n" 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xPaePortReauthenticate=FALSE\n", 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->aid, 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAPOL_VERSION, 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize); 24736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dot1xAuthConfigTable */ 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthPaeState=%d\n" 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendAuthState=%d\n" 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAdminControlledDirections=%d\n" 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthOperControlledDirections=%d\n" 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthControlledPortStatus=%d\n" 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthControlledPortControl=%d\n" 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthQuietPeriod=%u\n" 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthServerTimeout=%u\n" 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthReAuthPeriod=%u\n" 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthReAuthEnabled=%s\n" 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthKeyTxEnabled=%s\n", 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->auth_pae_state + 1, 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->be_auth_state + 1, 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->adminControlledDirections, 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->operControlledDirections, 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPortStatus, 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portControl, 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->quietPeriod, 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->serverTimeout, 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->reAuthPeriod, 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool_txt(sm->reAuthEnabled), 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool_txt(sm->keyTxEnabled)); 25016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dot1xAuthStatsTable */ 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolFramesRx=%u\n" 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolFramesTx=%u\n" 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolStartFramesRx=%u\n" 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolLogoffFramesRx=%u\n" 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolRespIdFramesRx=%u\n" 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolRespFramesRx=%u\n" 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolReqIdFramesTx=%u\n" 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapolReqFramesTx=%u\n" 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthInvalidEapolFramesRx=%u\n" 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapLengthErrorFramesRx=%u\n" 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthLastEapolFrameVersion=%u\n" 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthLastEapolFrameSource=" MACSTR "\n", 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolFramesRx, 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolFramesTx, 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolStartFramesRx, 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolLogoffFramesRx, 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolRespIdFramesRx, 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolRespFramesRx, 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolReqIdFramesTx, 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapolReqFramesTx, 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthInvalidEapolFramesRx, 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthEapLengthErrorFramesRx, 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xAuthLastEapolFrameVersion, 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sm->addr)); 25316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dot1xAuthDiagTable */ 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEntersConnecting=%u\n" 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEapLogoffsWhileConnecting=%u\n" 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthEntersAuthenticating=%u\n" 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n" 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n" 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthFailWhileAuthenticating=%u\n" 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n" 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n" 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthReauthsWhileAuthenticated=%u\n" 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n" 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n" 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendResponses=%u\n" 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendAccessChallenges=%u\n" 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendOtherRequestsToSupplicant=%u\n" 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendAuthSuccesses=%u\n" 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthBackendAuthFails=%u\n", 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authEntersConnecting, 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authEapLogoffsWhileConnecting, 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authEntersAuthenticating, 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthSuccessesWhileAuthenticating, 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthTimeoutsWhileAuthenticating, 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthFailWhileAuthenticating, 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthEapStartsWhileAuthenticating, 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthEapLogoffWhileAuthenticating, 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthReauthsWhileAuthenticated, 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthEapStartsWhileAuthenticated, 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authAuthEapLogoffWhileAuthenticated, 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backendResponses, 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backendAccessChallenges, 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backendOtherRequestsToSupplicant, 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backendAuthSuccesses, 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backendAuthFails); 25696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* dot1xAuthSessionStatsTable */ 2574fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_age(&sta->acct_session_start, &diff); 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot1xAuthSessionOctetsRx */ 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot1xAuthSessionOctetsTx */ 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot1xAuthSessionFramesRx */ 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: dot1xAuthSessionFramesTx */ 258057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt "dot1xAuthSessionId=%016llX\n" 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthSessionAuthenticMethod=%d\n" 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthSessionTime=%u\n" 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthSessionTerminateCause=999\n" 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xAuthSessionUserName=%s\n", 258557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) sta->acct_session_id, 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_key_mgmt_wpa_ieee8021x( 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_key_mgmt(sta->wpa_sm))) ? 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1 : 2, 2589fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt (unsigned int) diff.sec, 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity); 25916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2595b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (sm->acct_multi_session_id) { 25962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 259757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt "authMultiSessionId=%016llX\n", 259857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) 2599b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sm->acct_multi_session_id); 26002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 26012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return len; 26022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt len += ret; 26032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 26042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 260596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt name1 = eap_server_get_name(0, sm->eap_type_authsrv); 260696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt name2 = eap_server_get_name(0, sm->eap_type_supp); 2607fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 2608fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "last_eap_type_as=%d (%s)\n" 2609fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "last_eap_type_sta=%d (%s)\n", 26102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sm->eap_type_authsrv, name1, 26112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sm->eap_type_supp, name2); 26126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 2613fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return len; 2614fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len += ret; 2615fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2620de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#ifdef CONFIG_HS20 2621de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtstatic void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) 2622de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt{ 2623de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt struct hostapd_data *hapd = eloop_ctx; 2624de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt struct sta_info *sta = timeout_ctx; 2625de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 2626de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (sta->remediation) { 2627de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to " 2628de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MACSTR " to indicate Subscription Remediation", 2629de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MAC2STR(sta->addr)); 2630de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt hs20_send_wnm_notification(hapd, sta->addr, 2631de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt sta->remediation_method, 2632de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt sta->remediation_url); 2633de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_free(sta->remediation_url); 2634de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt sta->remediation_url = NULL; 2635de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt } 2636de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 2637de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (sta->hs20_deauth_req) { 2638de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to " 2639de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MACSTR " to indicate imminent deauthentication", 2640de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MAC2STR(sta->addr)); 2641de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt hs20_send_wnm_notification_deauth_req(hapd, sta->addr, 2642de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt sta->hs20_deauth_req); 2643de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt } 2644de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt} 2645de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* CONFIG_HS20 */ 2646de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 2647de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_finished(struct hostapd_data *hapd, 2649f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt struct sta_info *sta, int success, 2650f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int remediation) 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key; 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: get PMKLifetime from WPA parameters */ 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static const int dot11RSNAConfigPMKLifetime = 43200; 26569ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt unsigned int session_timeout; 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 2659f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (remediation && !sta->remediation) { 2660f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation = 1; 2661f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(sta->remediation_url); 2662f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_url = 2663f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_strdup(hapd->conf->subscr_remediation_url); 2664f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sta->remediation_method = 1; /* SOAP-XML SPP */ 2665f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 2666f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 2667de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (success && (sta->remediation || sta->hs20_deauth_req)) { 2668de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt wpa_printf(MSG_DEBUG, "HS 2.0: Schedule WNM-Notification to " 2669de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MACSTR " in 100 ms", MAC2STR(sta->addr)); 2670de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta); 2671de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt eloop_register_timeout(0, 100000, ieee802_1x_wnm_notif_send, 2672de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt hapd, sta); 2673f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 2674f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 2675f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = ieee802_1x_get_key(sta->eapol_sm, &len); 26779ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (sta->session_timeout_set) 26789ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt session_timeout = sta->session_timeout; 26799ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt else 26809ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt session_timeout = dot11RSNAConfigPMKLifetime; 2681f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (success && key && len >= PMK_LEN && !sta->remediation && 2682f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt !sta->hs20_deauth_requested && 2683d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_auth_pmksa_add(sta->wpa_sm, key, len, session_timeout, 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->eapol_sm) == 0) { 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Added PMKSA cache entry (IEEE 802.1X)"); 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!success) { 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many devices require deauthentication after WPS provisioning 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and some may not be be able to do that themselves, so 26941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * disconnect the client here. In addition, this may also 26951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * benefit IEEE 802.1X/EAPOL authentication cases, too since 26961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * the EAPOL PAE state machine would remain in HELD state for 26971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * considerable amount of time and some EAP methods, like 26981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * EAP-FAST with anonymous provisioning, may require another 26991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * EAPOL authentication to be started to complete connection. 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "IEEE 802.1X: Force " 27021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "disconnection after EAP-Failure"); 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add a small sleep to increase likelihood of previously 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requested EAP-Failure TX getting out before this should the 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * driver reorder operations. 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_sleep(0, 10000); 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_disconnect(hapd, sta, sta->addr, 27091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_REASON_IEEE_802_1X_AUTH_FAILED); 2710fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt hostapd_wps_eap_completed(hapd); 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2713