1*e28a4053SRui Paulo /* 2*e28a4053SRui Paulo * hostapd / IEEE 802.1X-2004 Authenticator 3*e28a4053SRui Paulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4*e28a4053SRui Paulo * 5*e28a4053SRui Paulo * This program is free software; you can redistribute it and/or modify 6*e28a4053SRui Paulo * it under the terms of the GNU General Public License version 2 as 7*e28a4053SRui Paulo * published by the Free Software Foundation. 8*e28a4053SRui Paulo * 9*e28a4053SRui Paulo * Alternatively, this software may be distributed under the terms of BSD 10*e28a4053SRui Paulo * license. 11*e28a4053SRui Paulo * 12*e28a4053SRui Paulo * See README and COPYING for more details. 13*e28a4053SRui Paulo */ 14*e28a4053SRui Paulo 15*e28a4053SRui Paulo #include "utils/includes.h" 16*e28a4053SRui Paulo 17*e28a4053SRui Paulo #include "utils/common.h" 18*e28a4053SRui Paulo #include "utils/eloop.h" 19*e28a4053SRui Paulo #include "crypto/md5.h" 20*e28a4053SRui Paulo #include "crypto/crypto.h" 21*e28a4053SRui Paulo #include "common/ieee802_11_defs.h" 22*e28a4053SRui Paulo #include "common/wpa_ctrl.h" 23*e28a4053SRui Paulo #include "radius/radius.h" 24*e28a4053SRui Paulo #include "radius/radius_client.h" 25*e28a4053SRui Paulo #include "eap_server/eap.h" 26*e28a4053SRui Paulo #include "eap_common/eap_wsc_common.h" 27*e28a4053SRui Paulo #include "eapol_auth/eapol_auth_sm.h" 28*e28a4053SRui Paulo #include "eapol_auth/eapol_auth_sm_i.h" 29*e28a4053SRui Paulo #include "hostapd.h" 30*e28a4053SRui Paulo #include "accounting.h" 31*e28a4053SRui Paulo #include "sta_info.h" 32*e28a4053SRui Paulo #include "wpa_auth.h" 33*e28a4053SRui Paulo #include "preauth_auth.h" 34*e28a4053SRui Paulo #include "pmksa_cache_auth.h" 35*e28a4053SRui Paulo #include "ap_config.h" 36*e28a4053SRui Paulo #include "ieee802_1x.h" 37*e28a4053SRui Paulo 38*e28a4053SRui Paulo 39*e28a4053SRui Paulo static void ieee802_1x_finished(struct hostapd_data *hapd, 40*e28a4053SRui Paulo struct sta_info *sta, int success); 41*e28a4053SRui Paulo 42*e28a4053SRui Paulo 43*e28a4053SRui Paulo static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta, 44*e28a4053SRui Paulo u8 type, const u8 *data, size_t datalen) 45*e28a4053SRui Paulo { 46*e28a4053SRui Paulo u8 *buf; 47*e28a4053SRui Paulo struct ieee802_1x_hdr *xhdr; 48*e28a4053SRui Paulo size_t len; 49*e28a4053SRui Paulo int encrypt = 0; 50*e28a4053SRui Paulo 51*e28a4053SRui Paulo len = sizeof(*xhdr) + datalen; 52*e28a4053SRui Paulo buf = os_zalloc(len); 53*e28a4053SRui Paulo if (buf == NULL) { 54*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "malloc() failed for " 55*e28a4053SRui Paulo "ieee802_1x_send(len=%lu)", 56*e28a4053SRui Paulo (unsigned long) len); 57*e28a4053SRui Paulo return; 58*e28a4053SRui Paulo } 59*e28a4053SRui Paulo 60*e28a4053SRui Paulo xhdr = (struct ieee802_1x_hdr *) buf; 61*e28a4053SRui Paulo xhdr->version = hapd->conf->eapol_version; 62*e28a4053SRui Paulo xhdr->type = type; 63*e28a4053SRui Paulo xhdr->length = host_to_be16(datalen); 64*e28a4053SRui Paulo 65*e28a4053SRui Paulo if (datalen > 0 && data != NULL) 66*e28a4053SRui Paulo os_memcpy(xhdr + 1, data, datalen); 67*e28a4053SRui Paulo 68*e28a4053SRui Paulo if (wpa_auth_pairwise_set(sta->wpa_sm)) 69*e28a4053SRui Paulo encrypt = 1; 70*e28a4053SRui Paulo if (sta->flags & WLAN_STA_PREAUTH) { 71*e28a4053SRui Paulo rsn_preauth_send(hapd, sta, buf, len); 72*e28a4053SRui Paulo } else { 73*e28a4053SRui Paulo hapd->drv.send_eapol(hapd, sta->addr, buf, len, encrypt); 74*e28a4053SRui Paulo } 75*e28a4053SRui Paulo 76*e28a4053SRui Paulo os_free(buf); 77*e28a4053SRui Paulo } 78*e28a4053SRui Paulo 79*e28a4053SRui Paulo 80*e28a4053SRui Paulo void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd, 81*e28a4053SRui Paulo struct sta_info *sta, int authorized) 82*e28a4053SRui Paulo { 83*e28a4053SRui Paulo int res; 84*e28a4053SRui Paulo 85*e28a4053SRui Paulo if (sta->flags & WLAN_STA_PREAUTH) 86*e28a4053SRui Paulo return; 87*e28a4053SRui Paulo 88*e28a4053SRui Paulo if (authorized) { 89*e28a4053SRui Paulo if (!(sta->flags & WLAN_STA_AUTHORIZED)) 90*e28a4053SRui Paulo wpa_msg(hapd->msg_ctx, MSG_INFO, 91*e28a4053SRui Paulo AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr)); 92*e28a4053SRui Paulo sta->flags |= WLAN_STA_AUTHORIZED; 93*e28a4053SRui Paulo res = hapd->drv.set_authorized(hapd, sta, 1); 94*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 95*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "authorizing port"); 96*e28a4053SRui Paulo } else { 97*e28a4053SRui Paulo if ((sta->flags & (WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC)) == 98*e28a4053SRui Paulo (WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC)) 99*e28a4053SRui Paulo wpa_msg(hapd->msg_ctx, MSG_INFO, 100*e28a4053SRui Paulo AP_STA_DISCONNECTED MACSTR, 101*e28a4053SRui Paulo MAC2STR(sta->addr)); 102*e28a4053SRui Paulo sta->flags &= ~WLAN_STA_AUTHORIZED; 103*e28a4053SRui Paulo res = hapd->drv.set_authorized(hapd, sta, 0); 104*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 105*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "unauthorizing port"); 106*e28a4053SRui Paulo } 107*e28a4053SRui Paulo 108*e28a4053SRui Paulo if (res && errno != ENOENT) { 109*e28a4053SRui Paulo printf("Could not set station " MACSTR " flags for kernel " 110*e28a4053SRui Paulo "driver (errno=%d).\n", MAC2STR(sta->addr), errno); 111*e28a4053SRui Paulo } 112*e28a4053SRui Paulo 113*e28a4053SRui Paulo if (authorized) 114*e28a4053SRui Paulo accounting_sta_start(hapd, sta); 115*e28a4053SRui Paulo } 116*e28a4053SRui Paulo 117*e28a4053SRui Paulo 118*e28a4053SRui Paulo static void ieee802_1x_tx_key_one(struct hostapd_data *hapd, 119*e28a4053SRui Paulo struct sta_info *sta, 120*e28a4053SRui Paulo int idx, int broadcast, 121*e28a4053SRui Paulo u8 *key_data, size_t key_len) 122*e28a4053SRui Paulo { 123*e28a4053SRui Paulo u8 *buf, *ekey; 124*e28a4053SRui Paulo struct ieee802_1x_hdr *hdr; 125*e28a4053SRui Paulo struct ieee802_1x_eapol_key *key; 126*e28a4053SRui Paulo size_t len, ekey_len; 127*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 128*e28a4053SRui Paulo 129*e28a4053SRui Paulo if (sm == NULL) 130*e28a4053SRui Paulo return; 131*e28a4053SRui Paulo 132*e28a4053SRui Paulo len = sizeof(*key) + key_len; 133*e28a4053SRui Paulo buf = os_zalloc(sizeof(*hdr) + len); 134*e28a4053SRui Paulo if (buf == NULL) 135*e28a4053SRui Paulo return; 136*e28a4053SRui Paulo 137*e28a4053SRui Paulo hdr = (struct ieee802_1x_hdr *) buf; 138*e28a4053SRui Paulo key = (struct ieee802_1x_eapol_key *) (hdr + 1); 139*e28a4053SRui Paulo key->type = EAPOL_KEY_TYPE_RC4; 140*e28a4053SRui Paulo key->key_length = htons(key_len); 141*e28a4053SRui Paulo wpa_get_ntp_timestamp(key->replay_counter); 142*e28a4053SRui Paulo 143*e28a4053SRui Paulo if (os_get_random(key->key_iv, sizeof(key->key_iv))) { 144*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Could not get random numbers"); 145*e28a4053SRui Paulo os_free(buf); 146*e28a4053SRui Paulo return; 147*e28a4053SRui Paulo } 148*e28a4053SRui Paulo 149*e28a4053SRui Paulo key->key_index = idx | (broadcast ? 0 : BIT(7)); 150*e28a4053SRui Paulo if (hapd->conf->eapol_key_index_workaround) { 151*e28a4053SRui Paulo /* According to some information, WinXP Supplicant seems to 152*e28a4053SRui Paulo * interpret bit7 as an indication whether the key is to be 153*e28a4053SRui Paulo * activated, so make it possible to enable workaround that 154*e28a4053SRui Paulo * sets this bit for all keys. */ 155*e28a4053SRui Paulo key->key_index |= BIT(7); 156*e28a4053SRui Paulo } 157*e28a4053SRui Paulo 158*e28a4053SRui Paulo /* Key is encrypted using "Key-IV + MSK[0..31]" as the RC4-key and 159*e28a4053SRui Paulo * MSK[32..63] is used to sign the message. */ 160*e28a4053SRui Paulo if (sm->eap_if->eapKeyData == NULL || sm->eap_if->eapKeyDataLen < 64) { 161*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "No eapKeyData available for encrypting " 162*e28a4053SRui Paulo "and signing EAPOL-Key"); 163*e28a4053SRui Paulo os_free(buf); 164*e28a4053SRui Paulo return; 165*e28a4053SRui Paulo } 166*e28a4053SRui Paulo os_memcpy((u8 *) (key + 1), key_data, key_len); 167*e28a4053SRui Paulo ekey_len = sizeof(key->key_iv) + 32; 168*e28a4053SRui Paulo ekey = os_malloc(ekey_len); 169*e28a4053SRui Paulo if (ekey == NULL) { 170*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Could not encrypt key"); 171*e28a4053SRui Paulo os_free(buf); 172*e28a4053SRui Paulo return; 173*e28a4053SRui Paulo } 174*e28a4053SRui Paulo os_memcpy(ekey, key->key_iv, sizeof(key->key_iv)); 175*e28a4053SRui Paulo os_memcpy(ekey + sizeof(key->key_iv), sm->eap_if->eapKeyData, 32); 176*e28a4053SRui Paulo rc4_skip(ekey, ekey_len, 0, (u8 *) (key + 1), key_len); 177*e28a4053SRui Paulo os_free(ekey); 178*e28a4053SRui Paulo 179*e28a4053SRui Paulo /* This header is needed here for HMAC-MD5, but it will be regenerated 180*e28a4053SRui Paulo * in ieee802_1x_send() */ 181*e28a4053SRui Paulo hdr->version = hapd->conf->eapol_version; 182*e28a4053SRui Paulo hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 183*e28a4053SRui Paulo hdr->length = host_to_be16(len); 184*e28a4053SRui Paulo hmac_md5(sm->eap_if->eapKeyData + 32, 32, buf, sizeof(*hdr) + len, 185*e28a4053SRui Paulo key->key_signature); 186*e28a4053SRui Paulo 187*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR 188*e28a4053SRui Paulo " (%s index=%d)", MAC2STR(sm->addr), 189*e28a4053SRui Paulo broadcast ? "broadcast" : "unicast", idx); 190*e28a4053SRui Paulo ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAPOL_KEY, (u8 *) key, len); 191*e28a4053SRui Paulo if (sta->eapol_sm) 192*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthEapolFramesTx++; 193*e28a4053SRui Paulo os_free(buf); 194*e28a4053SRui Paulo } 195*e28a4053SRui Paulo 196*e28a4053SRui Paulo 197*e28a4053SRui Paulo #ifndef CONFIG_NO_VLAN 198*e28a4053SRui Paulo static struct hostapd_wep_keys * 199*e28a4053SRui Paulo ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname) 200*e28a4053SRui Paulo { 201*e28a4053SRui Paulo struct hostapd_wep_keys *key; 202*e28a4053SRui Paulo 203*e28a4053SRui Paulo key = os_zalloc(sizeof(*key)); 204*e28a4053SRui Paulo if (key == NULL) 205*e28a4053SRui Paulo return NULL; 206*e28a4053SRui Paulo 207*e28a4053SRui Paulo key->default_len = hapd->conf->default_wep_key_len; 208*e28a4053SRui Paulo 209*e28a4053SRui Paulo if (key->idx >= hapd->conf->broadcast_key_idx_max || 210*e28a4053SRui Paulo key->idx < hapd->conf->broadcast_key_idx_min) 211*e28a4053SRui Paulo key->idx = hapd->conf->broadcast_key_idx_min; 212*e28a4053SRui Paulo else 213*e28a4053SRui Paulo key->idx++; 214*e28a4053SRui Paulo 215*e28a4053SRui Paulo if (!key->key[key->idx]) 216*e28a4053SRui Paulo key->key[key->idx] = os_malloc(key->default_len); 217*e28a4053SRui Paulo if (key->key[key->idx] == NULL || 218*e28a4053SRui Paulo os_get_random(key->key[key->idx], key->default_len)) { 219*e28a4053SRui Paulo printf("Could not generate random WEP key (dynamic VLAN).\n"); 220*e28a4053SRui Paulo os_free(key->key[key->idx]); 221*e28a4053SRui Paulo key->key[key->idx] = NULL; 222*e28a4053SRui Paulo os_free(key); 223*e28a4053SRui Paulo return NULL; 224*e28a4053SRui Paulo } 225*e28a4053SRui Paulo key->len[key->idx] = key->default_len; 226*e28a4053SRui Paulo 227*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "%s: Default WEP idx %d for dynamic VLAN\n", 228*e28a4053SRui Paulo ifname, key->idx); 229*e28a4053SRui Paulo wpa_hexdump_key(MSG_DEBUG, "Default WEP key (dynamic VLAN)", 230*e28a4053SRui Paulo key->key[key->idx], key->len[key->idx]); 231*e28a4053SRui Paulo 232*e28a4053SRui Paulo if (hapd->drv.set_key(ifname, hapd, WPA_ALG_WEP, NULL, key->idx, 1, 233*e28a4053SRui Paulo NULL, 0, key->key[key->idx], key->len[key->idx])) 234*e28a4053SRui Paulo printf("Could not set dynamic VLAN WEP encryption key.\n"); 235*e28a4053SRui Paulo 236*e28a4053SRui Paulo hapd->drv.set_drv_ieee8021x(hapd, ifname, 1); 237*e28a4053SRui Paulo 238*e28a4053SRui Paulo return key; 239*e28a4053SRui Paulo } 240*e28a4053SRui Paulo 241*e28a4053SRui Paulo 242*e28a4053SRui Paulo static struct hostapd_wep_keys * 243*e28a4053SRui Paulo ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid, 244*e28a4053SRui Paulo size_t vlan_id) 245*e28a4053SRui Paulo { 246*e28a4053SRui Paulo const char *ifname; 247*e28a4053SRui Paulo 248*e28a4053SRui Paulo if (vlan_id == 0) 249*e28a4053SRui Paulo return &ssid->wep; 250*e28a4053SRui Paulo 251*e28a4053SRui Paulo if (vlan_id <= ssid->max_dyn_vlan_keys && ssid->dyn_vlan_keys && 252*e28a4053SRui Paulo ssid->dyn_vlan_keys[vlan_id]) 253*e28a4053SRui Paulo return ssid->dyn_vlan_keys[vlan_id]; 254*e28a4053SRui Paulo 255*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Creating new group " 256*e28a4053SRui Paulo "state machine for VLAN ID %lu", 257*e28a4053SRui Paulo (unsigned long) vlan_id); 258*e28a4053SRui Paulo 259*e28a4053SRui Paulo ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id); 260*e28a4053SRui Paulo if (ifname == NULL) { 261*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Unknown VLAN ID %lu - " 262*e28a4053SRui Paulo "cannot create group key state machine", 263*e28a4053SRui Paulo (unsigned long) vlan_id); 264*e28a4053SRui Paulo return NULL; 265*e28a4053SRui Paulo } 266*e28a4053SRui Paulo 267*e28a4053SRui Paulo if (ssid->dyn_vlan_keys == NULL) { 268*e28a4053SRui Paulo int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]); 269*e28a4053SRui Paulo ssid->dyn_vlan_keys = os_zalloc(size); 270*e28a4053SRui Paulo if (ssid->dyn_vlan_keys == NULL) 271*e28a4053SRui Paulo return NULL; 272*e28a4053SRui Paulo ssid->max_dyn_vlan_keys = vlan_id; 273*e28a4053SRui Paulo } 274*e28a4053SRui Paulo 275*e28a4053SRui Paulo if (ssid->max_dyn_vlan_keys < vlan_id) { 276*e28a4053SRui Paulo struct hostapd_wep_keys **na; 277*e28a4053SRui Paulo int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]); 278*e28a4053SRui Paulo na = os_realloc(ssid->dyn_vlan_keys, size); 279*e28a4053SRui Paulo if (na == NULL) 280*e28a4053SRui Paulo return NULL; 281*e28a4053SRui Paulo ssid->dyn_vlan_keys = na; 282*e28a4053SRui Paulo os_memset(&ssid->dyn_vlan_keys[ssid->max_dyn_vlan_keys + 1], 0, 283*e28a4053SRui Paulo (vlan_id - ssid->max_dyn_vlan_keys) * 284*e28a4053SRui Paulo sizeof(ssid->dyn_vlan_keys[0])); 285*e28a4053SRui Paulo ssid->max_dyn_vlan_keys = vlan_id; 286*e28a4053SRui Paulo } 287*e28a4053SRui Paulo 288*e28a4053SRui Paulo ssid->dyn_vlan_keys[vlan_id] = ieee802_1x_group_alloc(hapd, ifname); 289*e28a4053SRui Paulo 290*e28a4053SRui Paulo return ssid->dyn_vlan_keys[vlan_id]; 291*e28a4053SRui Paulo } 292*e28a4053SRui Paulo #endif /* CONFIG_NO_VLAN */ 293*e28a4053SRui Paulo 294*e28a4053SRui Paulo 295*e28a4053SRui Paulo void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta) 296*e28a4053SRui Paulo { 297*e28a4053SRui Paulo struct eapol_authenticator *eapol = hapd->eapol_auth; 298*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 299*e28a4053SRui Paulo #ifndef CONFIG_NO_VLAN 300*e28a4053SRui Paulo struct hostapd_wep_keys *key = NULL; 301*e28a4053SRui Paulo int vlan_id; 302*e28a4053SRui Paulo #endif /* CONFIG_NO_VLAN */ 303*e28a4053SRui Paulo 304*e28a4053SRui Paulo if (sm == NULL || !sm->eap_if->eapKeyData) 305*e28a4053SRui Paulo return; 306*e28a4053SRui Paulo 307*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR, 308*e28a4053SRui Paulo MAC2STR(sta->addr)); 309*e28a4053SRui Paulo 310*e28a4053SRui Paulo #ifndef CONFIG_NO_VLAN 311*e28a4053SRui Paulo vlan_id = sta->vlan_id; 312*e28a4053SRui Paulo if (vlan_id < 0 || vlan_id > MAX_VLAN_ID) 313*e28a4053SRui Paulo vlan_id = 0; 314*e28a4053SRui Paulo 315*e28a4053SRui Paulo if (vlan_id) { 316*e28a4053SRui Paulo key = ieee802_1x_get_group(hapd, sta->ssid, vlan_id); 317*e28a4053SRui Paulo if (key && key->key[key->idx]) 318*e28a4053SRui Paulo ieee802_1x_tx_key_one(hapd, sta, key->idx, 1, 319*e28a4053SRui Paulo key->key[key->idx], 320*e28a4053SRui Paulo key->len[key->idx]); 321*e28a4053SRui Paulo } else 322*e28a4053SRui Paulo #endif /* CONFIG_NO_VLAN */ 323*e28a4053SRui Paulo if (eapol->default_wep_key) { 324*e28a4053SRui Paulo ieee802_1x_tx_key_one(hapd, sta, eapol->default_wep_key_idx, 1, 325*e28a4053SRui Paulo eapol->default_wep_key, 326*e28a4053SRui Paulo hapd->conf->default_wep_key_len); 327*e28a4053SRui Paulo } 328*e28a4053SRui Paulo 329*e28a4053SRui Paulo if (hapd->conf->individual_wep_key_len > 0) { 330*e28a4053SRui Paulo u8 *ikey; 331*e28a4053SRui Paulo ikey = os_malloc(hapd->conf->individual_wep_key_len); 332*e28a4053SRui Paulo if (ikey == NULL || 333*e28a4053SRui Paulo os_get_random(ikey, hapd->conf->individual_wep_key_len)) { 334*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Could not generate random " 335*e28a4053SRui Paulo "individual WEP key."); 336*e28a4053SRui Paulo os_free(ikey); 337*e28a4053SRui Paulo return; 338*e28a4053SRui Paulo } 339*e28a4053SRui Paulo 340*e28a4053SRui Paulo wpa_hexdump_key(MSG_DEBUG, "Individual WEP key", 341*e28a4053SRui Paulo ikey, hapd->conf->individual_wep_key_len); 342*e28a4053SRui Paulo 343*e28a4053SRui Paulo ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey, 344*e28a4053SRui Paulo hapd->conf->individual_wep_key_len); 345*e28a4053SRui Paulo 346*e28a4053SRui Paulo /* TODO: set encryption in TX callback, i.e., only after STA 347*e28a4053SRui Paulo * has ACKed EAPOL-Key frame */ 348*e28a4053SRui Paulo if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, 349*e28a4053SRui Paulo sta->addr, 0, 1, NULL, 0, ikey, 350*e28a4053SRui Paulo hapd->conf->individual_wep_key_len)) { 351*e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Could not set individual WEP " 352*e28a4053SRui Paulo "encryption."); 353*e28a4053SRui Paulo } 354*e28a4053SRui Paulo 355*e28a4053SRui Paulo os_free(ikey); 356*e28a4053SRui Paulo } 357*e28a4053SRui Paulo } 358*e28a4053SRui Paulo 359*e28a4053SRui Paulo 360*e28a4053SRui Paulo const char *radius_mode_txt(struct hostapd_data *hapd) 361*e28a4053SRui Paulo { 362*e28a4053SRui Paulo switch (hapd->iface->conf->hw_mode) { 363*e28a4053SRui Paulo case HOSTAPD_MODE_IEEE80211A: 364*e28a4053SRui Paulo return "802.11a"; 365*e28a4053SRui Paulo case HOSTAPD_MODE_IEEE80211G: 366*e28a4053SRui Paulo return "802.11g"; 367*e28a4053SRui Paulo case HOSTAPD_MODE_IEEE80211B: 368*e28a4053SRui Paulo default: 369*e28a4053SRui Paulo return "802.11b"; 370*e28a4053SRui Paulo } 371*e28a4053SRui Paulo } 372*e28a4053SRui Paulo 373*e28a4053SRui Paulo 374*e28a4053SRui Paulo int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta) 375*e28a4053SRui Paulo { 376*e28a4053SRui Paulo int i; 377*e28a4053SRui Paulo u8 rate = 0; 378*e28a4053SRui Paulo 379*e28a4053SRui Paulo for (i = 0; i < sta->supported_rates_len; i++) 380*e28a4053SRui Paulo if ((sta->supported_rates[i] & 0x7f) > rate) 381*e28a4053SRui Paulo rate = sta->supported_rates[i] & 0x7f; 382*e28a4053SRui Paulo 383*e28a4053SRui Paulo return rate; 384*e28a4053SRui Paulo } 385*e28a4053SRui Paulo 386*e28a4053SRui Paulo 387*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 388*e28a4053SRui Paulo static void ieee802_1x_learn_identity(struct hostapd_data *hapd, 389*e28a4053SRui Paulo struct eapol_state_machine *sm, 390*e28a4053SRui Paulo const u8 *eap, size_t len) 391*e28a4053SRui Paulo { 392*e28a4053SRui Paulo const u8 *identity; 393*e28a4053SRui Paulo size_t identity_len; 394*e28a4053SRui Paulo 395*e28a4053SRui Paulo if (len <= sizeof(struct eap_hdr) || 396*e28a4053SRui Paulo eap[sizeof(struct eap_hdr)] != EAP_TYPE_IDENTITY) 397*e28a4053SRui Paulo return; 398*e28a4053SRui Paulo 399*e28a4053SRui Paulo identity = eap_get_identity(sm->eap, &identity_len); 400*e28a4053SRui Paulo if (identity == NULL) 401*e28a4053SRui Paulo return; 402*e28a4053SRui Paulo 403*e28a4053SRui Paulo /* Save station identity for future RADIUS packets */ 404*e28a4053SRui Paulo os_free(sm->identity); 405*e28a4053SRui Paulo sm->identity = os_malloc(identity_len + 1); 406*e28a4053SRui Paulo if (sm->identity == NULL) { 407*e28a4053SRui Paulo sm->identity_len = 0; 408*e28a4053SRui Paulo return; 409*e28a4053SRui Paulo } 410*e28a4053SRui Paulo 411*e28a4053SRui Paulo os_memcpy(sm->identity, identity, identity_len); 412*e28a4053SRui Paulo sm->identity_len = identity_len; 413*e28a4053SRui Paulo sm->identity[identity_len] = '\0'; 414*e28a4053SRui Paulo hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X, 415*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "STA identity '%s'", sm->identity); 416*e28a4053SRui Paulo sm->dot1xAuthEapolRespIdFramesRx++; 417*e28a4053SRui Paulo } 418*e28a4053SRui Paulo 419*e28a4053SRui Paulo 420*e28a4053SRui Paulo static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd, 421*e28a4053SRui Paulo struct sta_info *sta, 422*e28a4053SRui Paulo const u8 *eap, size_t len) 423*e28a4053SRui Paulo { 424*e28a4053SRui Paulo struct radius_msg *msg; 425*e28a4053SRui Paulo char buf[128]; 426*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 427*e28a4053SRui Paulo 428*e28a4053SRui Paulo if (sm == NULL) 429*e28a4053SRui Paulo return; 430*e28a4053SRui Paulo 431*e28a4053SRui Paulo ieee802_1x_learn_identity(hapd, sm, eap, len); 432*e28a4053SRui Paulo 433*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 434*e28a4053SRui Paulo "packet"); 435*e28a4053SRui Paulo 436*e28a4053SRui Paulo sm->radius_identifier = radius_client_get_id(hapd->radius); 437*e28a4053SRui Paulo msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 438*e28a4053SRui Paulo sm->radius_identifier); 439*e28a4053SRui Paulo if (msg == NULL) { 440*e28a4053SRui Paulo printf("Could not create net RADIUS packet\n"); 441*e28a4053SRui Paulo return; 442*e28a4053SRui Paulo } 443*e28a4053SRui Paulo 444*e28a4053SRui Paulo radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta)); 445*e28a4053SRui Paulo 446*e28a4053SRui Paulo if (sm->identity && 447*e28a4053SRui Paulo !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 448*e28a4053SRui Paulo sm->identity, sm->identity_len)) { 449*e28a4053SRui Paulo printf("Could not add User-Name\n"); 450*e28a4053SRui Paulo goto fail; 451*e28a4053SRui Paulo } 452*e28a4053SRui Paulo 453*e28a4053SRui Paulo if (hapd->conf->own_ip_addr.af == AF_INET && 454*e28a4053SRui Paulo !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 455*e28a4053SRui Paulo (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) { 456*e28a4053SRui Paulo printf("Could not add NAS-IP-Address\n"); 457*e28a4053SRui Paulo goto fail; 458*e28a4053SRui Paulo } 459*e28a4053SRui Paulo 460*e28a4053SRui Paulo #ifdef CONFIG_IPV6 461*e28a4053SRui Paulo if (hapd->conf->own_ip_addr.af == AF_INET6 && 462*e28a4053SRui Paulo !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS, 463*e28a4053SRui Paulo (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) { 464*e28a4053SRui Paulo printf("Could not add NAS-IPv6-Address\n"); 465*e28a4053SRui Paulo goto fail; 466*e28a4053SRui Paulo } 467*e28a4053SRui Paulo #endif /* CONFIG_IPV6 */ 468*e28a4053SRui Paulo 469*e28a4053SRui Paulo if (hapd->conf->nas_identifier && 470*e28a4053SRui Paulo !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER, 471*e28a4053SRui Paulo (u8 *) hapd->conf->nas_identifier, 472*e28a4053SRui Paulo os_strlen(hapd->conf->nas_identifier))) { 473*e28a4053SRui Paulo printf("Could not add NAS-Identifier\n"); 474*e28a4053SRui Paulo goto fail; 475*e28a4053SRui Paulo } 476*e28a4053SRui Paulo 477*e28a4053SRui Paulo if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) { 478*e28a4053SRui Paulo printf("Could not add NAS-Port\n"); 479*e28a4053SRui Paulo goto fail; 480*e28a4053SRui Paulo } 481*e28a4053SRui Paulo 482*e28a4053SRui Paulo os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s", 483*e28a4053SRui Paulo MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid); 484*e28a4053SRui Paulo buf[sizeof(buf) - 1] = '\0'; 485*e28a4053SRui Paulo if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID, 486*e28a4053SRui Paulo (u8 *) buf, os_strlen(buf))) { 487*e28a4053SRui Paulo printf("Could not add Called-Station-Id\n"); 488*e28a4053SRui Paulo goto fail; 489*e28a4053SRui Paulo } 490*e28a4053SRui Paulo 491*e28a4053SRui Paulo os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 492*e28a4053SRui Paulo MAC2STR(sta->addr)); 493*e28a4053SRui Paulo buf[sizeof(buf) - 1] = '\0'; 494*e28a4053SRui Paulo if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 495*e28a4053SRui Paulo (u8 *) buf, os_strlen(buf))) { 496*e28a4053SRui Paulo printf("Could not add Calling-Station-Id\n"); 497*e28a4053SRui Paulo goto fail; 498*e28a4053SRui Paulo } 499*e28a4053SRui Paulo 500*e28a4053SRui Paulo /* TODO: should probably check MTU from driver config; 2304 is max for 501*e28a4053SRui Paulo * IEEE 802.11, but use 1400 to avoid problems with too large packets 502*e28a4053SRui Paulo */ 503*e28a4053SRui Paulo if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 504*e28a4053SRui Paulo printf("Could not add Framed-MTU\n"); 505*e28a4053SRui Paulo goto fail; 506*e28a4053SRui Paulo } 507*e28a4053SRui Paulo 508*e28a4053SRui Paulo if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 509*e28a4053SRui Paulo RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 510*e28a4053SRui Paulo printf("Could not add NAS-Port-Type\n"); 511*e28a4053SRui Paulo goto fail; 512*e28a4053SRui Paulo } 513*e28a4053SRui Paulo 514*e28a4053SRui Paulo if (sta->flags & WLAN_STA_PREAUTH) { 515*e28a4053SRui Paulo os_strlcpy(buf, "IEEE 802.11i Pre-Authentication", 516*e28a4053SRui Paulo sizeof(buf)); 517*e28a4053SRui Paulo } else { 518*e28a4053SRui Paulo os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s", 519*e28a4053SRui Paulo radius_sta_rate(hapd, sta) / 2, 520*e28a4053SRui Paulo (radius_sta_rate(hapd, sta) & 1) ? ".5" : "", 521*e28a4053SRui Paulo radius_mode_txt(hapd)); 522*e28a4053SRui Paulo buf[sizeof(buf) - 1] = '\0'; 523*e28a4053SRui Paulo } 524*e28a4053SRui Paulo if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 525*e28a4053SRui Paulo (u8 *) buf, os_strlen(buf))) { 526*e28a4053SRui Paulo printf("Could not add Connect-Info\n"); 527*e28a4053SRui Paulo goto fail; 528*e28a4053SRui Paulo } 529*e28a4053SRui Paulo 530*e28a4053SRui Paulo if (eap && !radius_msg_add_eap(msg, eap, len)) { 531*e28a4053SRui Paulo printf("Could not add EAP-Message\n"); 532*e28a4053SRui Paulo goto fail; 533*e28a4053SRui Paulo } 534*e28a4053SRui Paulo 535*e28a4053SRui Paulo /* State attribute must be copied if and only if this packet is 536*e28a4053SRui Paulo * Access-Request reply to the previous Access-Challenge */ 537*e28a4053SRui Paulo if (sm->last_recv_radius && 538*e28a4053SRui Paulo radius_msg_get_hdr(sm->last_recv_radius)->code == 539*e28a4053SRui Paulo RADIUS_CODE_ACCESS_CHALLENGE) { 540*e28a4053SRui Paulo int res = radius_msg_copy_attr(msg, sm->last_recv_radius, 541*e28a4053SRui Paulo RADIUS_ATTR_STATE); 542*e28a4053SRui Paulo if (res < 0) { 543*e28a4053SRui Paulo printf("Could not copy State attribute from previous " 544*e28a4053SRui Paulo "Access-Challenge\n"); 545*e28a4053SRui Paulo goto fail; 546*e28a4053SRui Paulo } 547*e28a4053SRui Paulo if (res > 0) { 548*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "Copied RADIUS State Attribute"); 549*e28a4053SRui Paulo } 550*e28a4053SRui Paulo } 551*e28a4053SRui Paulo 552*e28a4053SRui Paulo radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr); 553*e28a4053SRui Paulo return; 554*e28a4053SRui Paulo 555*e28a4053SRui Paulo fail: 556*e28a4053SRui Paulo radius_msg_free(msg); 557*e28a4053SRui Paulo } 558*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 559*e28a4053SRui Paulo 560*e28a4053SRui Paulo 561*e28a4053SRui Paulo static void handle_eap_response(struct hostapd_data *hapd, 562*e28a4053SRui Paulo struct sta_info *sta, struct eap_hdr *eap, 563*e28a4053SRui Paulo size_t len) 564*e28a4053SRui Paulo { 565*e28a4053SRui Paulo u8 type, *data; 566*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 567*e28a4053SRui Paulo if (sm == NULL) 568*e28a4053SRui Paulo return; 569*e28a4053SRui Paulo 570*e28a4053SRui Paulo data = (u8 *) (eap + 1); 571*e28a4053SRui Paulo 572*e28a4053SRui Paulo if (len < sizeof(*eap) + 1) { 573*e28a4053SRui Paulo printf("handle_eap_response: too short response data\n"); 574*e28a4053SRui Paulo return; 575*e28a4053SRui Paulo } 576*e28a4053SRui Paulo 577*e28a4053SRui Paulo sm->eap_type_supp = type = data[0]; 578*e28a4053SRui Paulo 579*e28a4053SRui Paulo hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X, 580*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d " 581*e28a4053SRui Paulo "id=%d len=%d) from STA: EAP Response-%s (%d)", 582*e28a4053SRui Paulo eap->code, eap->identifier, be_to_host16(eap->length), 583*e28a4053SRui Paulo eap_server_get_name(0, type), type); 584*e28a4053SRui Paulo 585*e28a4053SRui Paulo sm->dot1xAuthEapolRespFramesRx++; 586*e28a4053SRui Paulo 587*e28a4053SRui Paulo wpabuf_free(sm->eap_if->eapRespData); 588*e28a4053SRui Paulo sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len); 589*e28a4053SRui Paulo sm->eapolEap = TRUE; 590*e28a4053SRui Paulo } 591*e28a4053SRui Paulo 592*e28a4053SRui Paulo 593*e28a4053SRui Paulo /* Process incoming EAP packet from Supplicant */ 594*e28a4053SRui Paulo static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta, 595*e28a4053SRui Paulo u8 *buf, size_t len) 596*e28a4053SRui Paulo { 597*e28a4053SRui Paulo struct eap_hdr *eap; 598*e28a4053SRui Paulo u16 eap_len; 599*e28a4053SRui Paulo 600*e28a4053SRui Paulo if (len < sizeof(*eap)) { 601*e28a4053SRui Paulo printf(" too short EAP packet\n"); 602*e28a4053SRui Paulo return; 603*e28a4053SRui Paulo } 604*e28a4053SRui Paulo 605*e28a4053SRui Paulo eap = (struct eap_hdr *) buf; 606*e28a4053SRui Paulo 607*e28a4053SRui Paulo eap_len = be_to_host16(eap->length); 608*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d", 609*e28a4053SRui Paulo eap->code, eap->identifier, eap_len); 610*e28a4053SRui Paulo if (eap_len < sizeof(*eap)) { 611*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " Invalid EAP length"); 612*e28a4053SRui Paulo return; 613*e28a4053SRui Paulo } else if (eap_len > len) { 614*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " Too short frame to contain this EAP " 615*e28a4053SRui Paulo "packet"); 616*e28a4053SRui Paulo return; 617*e28a4053SRui Paulo } else if (eap_len < len) { 618*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " Ignoring %lu extra bytes after EAP " 619*e28a4053SRui Paulo "packet", (unsigned long) len - eap_len); 620*e28a4053SRui Paulo } 621*e28a4053SRui Paulo 622*e28a4053SRui Paulo switch (eap->code) { 623*e28a4053SRui Paulo case EAP_CODE_REQUEST: 624*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " (request)"); 625*e28a4053SRui Paulo return; 626*e28a4053SRui Paulo case EAP_CODE_RESPONSE: 627*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " (response)"); 628*e28a4053SRui Paulo handle_eap_response(hapd, sta, eap, eap_len); 629*e28a4053SRui Paulo break; 630*e28a4053SRui Paulo case EAP_CODE_SUCCESS: 631*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " (success)"); 632*e28a4053SRui Paulo return; 633*e28a4053SRui Paulo case EAP_CODE_FAILURE: 634*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " (failure)"); 635*e28a4053SRui Paulo return; 636*e28a4053SRui Paulo default: 637*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " (unknown code)"); 638*e28a4053SRui Paulo return; 639*e28a4053SRui Paulo } 640*e28a4053SRui Paulo } 641*e28a4053SRui Paulo 642*e28a4053SRui Paulo 643*e28a4053SRui Paulo static struct eapol_state_machine * 644*e28a4053SRui Paulo ieee802_1x_alloc_eapol_sm(struct hostapd_data *hapd, struct sta_info *sta) 645*e28a4053SRui Paulo { 646*e28a4053SRui Paulo int flags = 0; 647*e28a4053SRui Paulo if (sta->flags & WLAN_STA_PREAUTH) 648*e28a4053SRui Paulo flags |= EAPOL_SM_PREAUTH; 649*e28a4053SRui Paulo if (sta->wpa_sm) { 650*e28a4053SRui Paulo flags |= EAPOL_SM_USES_WPA; 651*e28a4053SRui Paulo if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) 652*e28a4053SRui Paulo flags |= EAPOL_SM_FROM_PMKSA_CACHE; 653*e28a4053SRui Paulo } 654*e28a4053SRui Paulo return eapol_auth_alloc(hapd->eapol_auth, sta->addr, flags, 655*e28a4053SRui Paulo sta->wps_ie, sta); 656*e28a4053SRui Paulo } 657*e28a4053SRui Paulo 658*e28a4053SRui Paulo 659*e28a4053SRui Paulo /** 660*e28a4053SRui Paulo * ieee802_1x_receive - Process the EAPOL frames from the Supplicant 661*e28a4053SRui Paulo * @hapd: hostapd BSS data 662*e28a4053SRui Paulo * @sa: Source address (sender of the EAPOL frame) 663*e28a4053SRui Paulo * @buf: EAPOL frame 664*e28a4053SRui Paulo * @len: Length of buf in octets 665*e28a4053SRui Paulo * 666*e28a4053SRui Paulo * This function is called for each incoming EAPOL frame from the interface 667*e28a4053SRui Paulo */ 668*e28a4053SRui Paulo void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf, 669*e28a4053SRui Paulo size_t len) 670*e28a4053SRui Paulo { 671*e28a4053SRui Paulo struct sta_info *sta; 672*e28a4053SRui Paulo struct ieee802_1x_hdr *hdr; 673*e28a4053SRui Paulo struct ieee802_1x_eapol_key *key; 674*e28a4053SRui Paulo u16 datalen; 675*e28a4053SRui Paulo struct rsn_pmksa_cache_entry *pmksa; 676*e28a4053SRui Paulo 677*e28a4053SRui Paulo if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && 678*e28a4053SRui Paulo !hapd->conf->wps_state) 679*e28a4053SRui Paulo return; 680*e28a4053SRui Paulo 681*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR, 682*e28a4053SRui Paulo (unsigned long) len, MAC2STR(sa)); 683*e28a4053SRui Paulo sta = ap_get_sta(hapd, sa); 684*e28a4053SRui Paulo if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { 685*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not " 686*e28a4053SRui Paulo "associated STA"); 687*e28a4053SRui Paulo return; 688*e28a4053SRui Paulo } 689*e28a4053SRui Paulo 690*e28a4053SRui Paulo if (len < sizeof(*hdr)) { 691*e28a4053SRui Paulo printf(" too short IEEE 802.1X packet\n"); 692*e28a4053SRui Paulo return; 693*e28a4053SRui Paulo } 694*e28a4053SRui Paulo 695*e28a4053SRui Paulo hdr = (struct ieee802_1x_hdr *) buf; 696*e28a4053SRui Paulo datalen = be_to_host16(hdr->length); 697*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " IEEE 802.1X: version=%d type=%d length=%d", 698*e28a4053SRui Paulo hdr->version, hdr->type, datalen); 699*e28a4053SRui Paulo 700*e28a4053SRui Paulo if (len - sizeof(*hdr) < datalen) { 701*e28a4053SRui Paulo printf(" frame too short for this IEEE 802.1X packet\n"); 702*e28a4053SRui Paulo if (sta->eapol_sm) 703*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++; 704*e28a4053SRui Paulo return; 705*e28a4053SRui Paulo } 706*e28a4053SRui Paulo if (len - sizeof(*hdr) > datalen) { 707*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " ignoring %lu extra octets after " 708*e28a4053SRui Paulo "IEEE 802.1X packet", 709*e28a4053SRui Paulo (unsigned long) len - sizeof(*hdr) - datalen); 710*e28a4053SRui Paulo } 711*e28a4053SRui Paulo 712*e28a4053SRui Paulo if (sta->eapol_sm) { 713*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version; 714*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthEapolFramesRx++; 715*e28a4053SRui Paulo } 716*e28a4053SRui Paulo 717*e28a4053SRui Paulo key = (struct ieee802_1x_eapol_key *) (hdr + 1); 718*e28a4053SRui Paulo if (datalen >= sizeof(struct ieee802_1x_eapol_key) && 719*e28a4053SRui Paulo hdr->type == IEEE802_1X_TYPE_EAPOL_KEY && 720*e28a4053SRui Paulo (key->type == EAPOL_KEY_TYPE_WPA || 721*e28a4053SRui Paulo key->type == EAPOL_KEY_TYPE_RSN)) { 722*e28a4053SRui Paulo wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr, 723*e28a4053SRui Paulo sizeof(*hdr) + datalen); 724*e28a4053SRui Paulo return; 725*e28a4053SRui Paulo } 726*e28a4053SRui Paulo 727*e28a4053SRui Paulo if ((!hapd->conf->ieee802_1x && 728*e28a4053SRui Paulo !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) || 729*e28a4053SRui Paulo wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm))) 730*e28a4053SRui Paulo return; 731*e28a4053SRui Paulo 732*e28a4053SRui Paulo if (!sta->eapol_sm) { 733*e28a4053SRui Paulo sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta); 734*e28a4053SRui Paulo if (!sta->eapol_sm) 735*e28a4053SRui Paulo return; 736*e28a4053SRui Paulo 737*e28a4053SRui Paulo #ifdef CONFIG_WPS 738*e28a4053SRui Paulo if (!hapd->conf->ieee802_1x && 739*e28a4053SRui Paulo ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) == 740*e28a4053SRui Paulo WLAN_STA_MAYBE_WPS)) { 741*e28a4053SRui Paulo /* 742*e28a4053SRui Paulo * Delay EAPOL frame transmission until a possible WPS 743*e28a4053SRui Paulo * STA initiates the handshake with EAPOL-Start. 744*e28a4053SRui Paulo */ 745*e28a4053SRui Paulo sta->eapol_sm->flags |= EAPOL_SM_WAIT_START; 746*e28a4053SRui Paulo } 747*e28a4053SRui Paulo #endif /* CONFIG_WPS */ 748*e28a4053SRui Paulo 749*e28a4053SRui Paulo sta->eapol_sm->eap_if->portEnabled = TRUE; 750*e28a4053SRui Paulo } 751*e28a4053SRui Paulo 752*e28a4053SRui Paulo /* since we support version 1, we can ignore version field and proceed 753*e28a4053SRui Paulo * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */ 754*e28a4053SRui Paulo /* TODO: actually, we are not version 1 anymore.. However, Version 2 755*e28a4053SRui Paulo * does not change frame contents, so should be ok to process frames 756*e28a4053SRui Paulo * more or less identically. Some changes might be needed for 757*e28a4053SRui Paulo * verification of fields. */ 758*e28a4053SRui Paulo 759*e28a4053SRui Paulo switch (hdr->type) { 760*e28a4053SRui Paulo case IEEE802_1X_TYPE_EAP_PACKET: 761*e28a4053SRui Paulo handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen); 762*e28a4053SRui Paulo break; 763*e28a4053SRui Paulo 764*e28a4053SRui Paulo case IEEE802_1X_TYPE_EAPOL_START: 765*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 766*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start " 767*e28a4053SRui Paulo "from STA"); 768*e28a4053SRui Paulo sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START; 769*e28a4053SRui Paulo pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm); 770*e28a4053SRui Paulo if (pmksa) { 771*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 772*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "cached PMKSA " 773*e28a4053SRui Paulo "available - ignore it since " 774*e28a4053SRui Paulo "STA sent EAPOL-Start"); 775*e28a4053SRui Paulo wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa); 776*e28a4053SRui Paulo } 777*e28a4053SRui Paulo sta->eapol_sm->eapolStart = TRUE; 778*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthEapolStartFramesRx++; 779*e28a4053SRui Paulo wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL); 780*e28a4053SRui Paulo break; 781*e28a4053SRui Paulo 782*e28a4053SRui Paulo case IEEE802_1X_TYPE_EAPOL_LOGOFF: 783*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 784*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff " 785*e28a4053SRui Paulo "from STA"); 786*e28a4053SRui Paulo sta->acct_terminate_cause = 787*e28a4053SRui Paulo RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 788*e28a4053SRui Paulo accounting_sta_stop(hapd, sta); 789*e28a4053SRui Paulo sta->eapol_sm->eapolLogoff = TRUE; 790*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++; 791*e28a4053SRui Paulo break; 792*e28a4053SRui Paulo 793*e28a4053SRui Paulo case IEEE802_1X_TYPE_EAPOL_KEY: 794*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " EAPOL-Key"); 795*e28a4053SRui Paulo if (!(sta->flags & WLAN_STA_AUTHORIZED)) { 796*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " Dropped key data from " 797*e28a4053SRui Paulo "unauthorized Supplicant"); 798*e28a4053SRui Paulo break; 799*e28a4053SRui Paulo } 800*e28a4053SRui Paulo break; 801*e28a4053SRui Paulo 802*e28a4053SRui Paulo case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT: 803*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " EAPOL-Encapsulated-ASF-Alert"); 804*e28a4053SRui Paulo /* TODO: implement support for this; show data */ 805*e28a4053SRui Paulo break; 806*e28a4053SRui Paulo 807*e28a4053SRui Paulo default: 808*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, " unknown IEEE 802.1X packet type"); 809*e28a4053SRui Paulo sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++; 810*e28a4053SRui Paulo break; 811*e28a4053SRui Paulo } 812*e28a4053SRui Paulo 813*e28a4053SRui Paulo eapol_auth_step(sta->eapol_sm); 814*e28a4053SRui Paulo } 815*e28a4053SRui Paulo 816*e28a4053SRui Paulo 817*e28a4053SRui Paulo /** 818*e28a4053SRui Paulo * ieee802_1x_new_station - Start IEEE 802.1X authentication 819*e28a4053SRui Paulo * @hapd: hostapd BSS data 820*e28a4053SRui Paulo * @sta: The station 821*e28a4053SRui Paulo * 822*e28a4053SRui Paulo * This function is called to start IEEE 802.1X authentication when a new 823*e28a4053SRui Paulo * station completes IEEE 802.11 association. 824*e28a4053SRui Paulo */ 825*e28a4053SRui Paulo void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta) 826*e28a4053SRui Paulo { 827*e28a4053SRui Paulo struct rsn_pmksa_cache_entry *pmksa; 828*e28a4053SRui Paulo int reassoc = 1; 829*e28a4053SRui Paulo int force_1x = 0; 830*e28a4053SRui Paulo 831*e28a4053SRui Paulo #ifdef CONFIG_WPS 832*e28a4053SRui Paulo if (hapd->conf->wps_state && hapd->conf->wpa && 833*e28a4053SRui Paulo (sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) { 834*e28a4053SRui Paulo /* 835*e28a4053SRui Paulo * Need to enable IEEE 802.1X/EAPOL state machines for possible 836*e28a4053SRui Paulo * WPS handshake even if IEEE 802.1X/EAPOL is not used for 837*e28a4053SRui Paulo * authentication in this BSS. 838*e28a4053SRui Paulo */ 839*e28a4053SRui Paulo force_1x = 1; 840*e28a4053SRui Paulo } 841*e28a4053SRui Paulo #endif /* CONFIG_WPS */ 842*e28a4053SRui Paulo 843*e28a4053SRui Paulo if ((!force_1x && !hapd->conf->ieee802_1x) || 844*e28a4053SRui Paulo wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm))) 845*e28a4053SRui Paulo return; 846*e28a4053SRui Paulo 847*e28a4053SRui Paulo if (sta->eapol_sm == NULL) { 848*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 849*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "start authentication"); 850*e28a4053SRui Paulo sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta); 851*e28a4053SRui Paulo if (sta->eapol_sm == NULL) { 852*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, 853*e28a4053SRui Paulo HOSTAPD_MODULE_IEEE8021X, 854*e28a4053SRui Paulo HOSTAPD_LEVEL_INFO, 855*e28a4053SRui Paulo "failed to allocate state machine"); 856*e28a4053SRui Paulo return; 857*e28a4053SRui Paulo } 858*e28a4053SRui Paulo reassoc = 0; 859*e28a4053SRui Paulo } 860*e28a4053SRui Paulo 861*e28a4053SRui Paulo #ifdef CONFIG_WPS 862*e28a4053SRui Paulo sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START; 863*e28a4053SRui Paulo if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) { 864*e28a4053SRui Paulo /* 865*e28a4053SRui Paulo * Delay EAPOL frame transmission until a possible WPS 866*e28a4053SRui Paulo * initiates the handshake with EAPOL-Start. 867*e28a4053SRui Paulo */ 868*e28a4053SRui Paulo sta->eapol_sm->flags |= EAPOL_SM_WAIT_START; 869*e28a4053SRui Paulo } 870*e28a4053SRui Paulo #endif /* CONFIG_WPS */ 871*e28a4053SRui Paulo 872*e28a4053SRui Paulo sta->eapol_sm->eap_if->portEnabled = TRUE; 873*e28a4053SRui Paulo 874*e28a4053SRui Paulo pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm); 875*e28a4053SRui Paulo if (pmksa) { 876*e28a4053SRui Paulo int old_vlanid; 877*e28a4053SRui Paulo 878*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 879*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, 880*e28a4053SRui Paulo "PMK from PMKSA cache - skip IEEE 802.1X/EAP"); 881*e28a4053SRui Paulo /* Setup EAPOL state machines to already authenticated state 882*e28a4053SRui Paulo * because of existing PMKSA information in the cache. */ 883*e28a4053SRui Paulo sta->eapol_sm->keyRun = TRUE; 884*e28a4053SRui Paulo sta->eapol_sm->eap_if->eapKeyAvailable = TRUE; 885*e28a4053SRui Paulo sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING; 886*e28a4053SRui Paulo sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS; 887*e28a4053SRui Paulo sta->eapol_sm->authSuccess = TRUE; 888*e28a4053SRui Paulo if (sta->eapol_sm->eap) 889*e28a4053SRui Paulo eap_sm_notify_cached(sta->eapol_sm->eap); 890*e28a4053SRui Paulo old_vlanid = sta->vlan_id; 891*e28a4053SRui Paulo pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm); 892*e28a4053SRui Paulo if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED) 893*e28a4053SRui Paulo sta->vlan_id = 0; 894*e28a4053SRui Paulo ap_sta_bind_vlan(hapd, sta, old_vlanid); 895*e28a4053SRui Paulo } else { 896*e28a4053SRui Paulo if (reassoc) { 897*e28a4053SRui Paulo /* 898*e28a4053SRui Paulo * Force EAPOL state machines to start 899*e28a4053SRui Paulo * re-authentication without having to wait for the 900*e28a4053SRui Paulo * Supplicant to send EAPOL-Start. 901*e28a4053SRui Paulo */ 902*e28a4053SRui Paulo sta->eapol_sm->reAuthenticate = TRUE; 903*e28a4053SRui Paulo } 904*e28a4053SRui Paulo eapol_auth_step(sta->eapol_sm); 905*e28a4053SRui Paulo } 906*e28a4053SRui Paulo } 907*e28a4053SRui Paulo 908*e28a4053SRui Paulo 909*e28a4053SRui Paulo void ieee802_1x_free_station(struct sta_info *sta) 910*e28a4053SRui Paulo { 911*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 912*e28a4053SRui Paulo 913*e28a4053SRui Paulo if (sm == NULL) 914*e28a4053SRui Paulo return; 915*e28a4053SRui Paulo 916*e28a4053SRui Paulo sta->eapol_sm = NULL; 917*e28a4053SRui Paulo 918*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 919*e28a4053SRui Paulo radius_msg_free(sm->last_recv_radius); 920*e28a4053SRui Paulo radius_free_class(&sm->radius_class); 921*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 922*e28a4053SRui Paulo 923*e28a4053SRui Paulo os_free(sm->identity); 924*e28a4053SRui Paulo eapol_auth_free(sm); 925*e28a4053SRui Paulo } 926*e28a4053SRui Paulo 927*e28a4053SRui Paulo 928*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 929*e28a4053SRui Paulo static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, 930*e28a4053SRui Paulo struct sta_info *sta) 931*e28a4053SRui Paulo { 932*e28a4053SRui Paulo u8 *eap; 933*e28a4053SRui Paulo size_t len; 934*e28a4053SRui Paulo struct eap_hdr *hdr; 935*e28a4053SRui Paulo int eap_type = -1; 936*e28a4053SRui Paulo char buf[64]; 937*e28a4053SRui Paulo struct radius_msg *msg; 938*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 939*e28a4053SRui Paulo 940*e28a4053SRui Paulo if (sm == NULL || sm->last_recv_radius == NULL) { 941*e28a4053SRui Paulo if (sm) 942*e28a4053SRui Paulo sm->eap_if->aaaEapNoReq = TRUE; 943*e28a4053SRui Paulo return; 944*e28a4053SRui Paulo } 945*e28a4053SRui Paulo 946*e28a4053SRui Paulo msg = sm->last_recv_radius; 947*e28a4053SRui Paulo 948*e28a4053SRui Paulo eap = radius_msg_get_eap(msg, &len); 949*e28a4053SRui Paulo if (eap == NULL) { 950*e28a4053SRui Paulo /* RFC 3579, Chap. 2.6.3: 951*e28a4053SRui Paulo * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 952*e28a4053SRui Paulo * attribute */ 953*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 954*e28a4053SRui Paulo HOSTAPD_LEVEL_WARNING, "could not extract " 955*e28a4053SRui Paulo "EAP-Message from RADIUS message"); 956*e28a4053SRui Paulo sm->eap_if->aaaEapNoReq = TRUE; 957*e28a4053SRui Paulo return; 958*e28a4053SRui Paulo } 959*e28a4053SRui Paulo 960*e28a4053SRui Paulo if (len < sizeof(*hdr)) { 961*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 962*e28a4053SRui Paulo HOSTAPD_LEVEL_WARNING, "too short EAP packet " 963*e28a4053SRui Paulo "received from authentication server"); 964*e28a4053SRui Paulo os_free(eap); 965*e28a4053SRui Paulo sm->eap_if->aaaEapNoReq = TRUE; 966*e28a4053SRui Paulo return; 967*e28a4053SRui Paulo } 968*e28a4053SRui Paulo 969*e28a4053SRui Paulo if (len > sizeof(*hdr)) 970*e28a4053SRui Paulo eap_type = eap[sizeof(*hdr)]; 971*e28a4053SRui Paulo 972*e28a4053SRui Paulo hdr = (struct eap_hdr *) eap; 973*e28a4053SRui Paulo switch (hdr->code) { 974*e28a4053SRui Paulo case EAP_CODE_REQUEST: 975*e28a4053SRui Paulo if (eap_type >= 0) 976*e28a4053SRui Paulo sm->eap_type_authsrv = eap_type; 977*e28a4053SRui Paulo os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 978*e28a4053SRui Paulo eap_type >= 0 ? eap_server_get_name(0, eap_type) : 979*e28a4053SRui Paulo "??", 980*e28a4053SRui Paulo eap_type); 981*e28a4053SRui Paulo break; 982*e28a4053SRui Paulo case EAP_CODE_RESPONSE: 983*e28a4053SRui Paulo os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 984*e28a4053SRui Paulo eap_type >= 0 ? eap_server_get_name(0, eap_type) : 985*e28a4053SRui Paulo "??", 986*e28a4053SRui Paulo eap_type); 987*e28a4053SRui Paulo break; 988*e28a4053SRui Paulo case EAP_CODE_SUCCESS: 989*e28a4053SRui Paulo os_strlcpy(buf, "EAP Success", sizeof(buf)); 990*e28a4053SRui Paulo break; 991*e28a4053SRui Paulo case EAP_CODE_FAILURE: 992*e28a4053SRui Paulo os_strlcpy(buf, "EAP Failure", sizeof(buf)); 993*e28a4053SRui Paulo break; 994*e28a4053SRui Paulo default: 995*e28a4053SRui Paulo os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 996*e28a4053SRui Paulo break; 997*e28a4053SRui Paulo } 998*e28a4053SRui Paulo buf[sizeof(buf) - 1] = '\0'; 999*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1000*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d " 1001*e28a4053SRui Paulo "id=%d len=%d) from RADIUS server: %s", 1002*e28a4053SRui Paulo hdr->code, hdr->identifier, be_to_host16(hdr->length), 1003*e28a4053SRui Paulo buf); 1004*e28a4053SRui Paulo sm->eap_if->aaaEapReq = TRUE; 1005*e28a4053SRui Paulo 1006*e28a4053SRui Paulo wpabuf_free(sm->eap_if->aaaEapReqData); 1007*e28a4053SRui Paulo sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len); 1008*e28a4053SRui Paulo } 1009*e28a4053SRui Paulo 1010*e28a4053SRui Paulo 1011*e28a4053SRui Paulo static void ieee802_1x_get_keys(struct hostapd_data *hapd, 1012*e28a4053SRui Paulo struct sta_info *sta, struct radius_msg *msg, 1013*e28a4053SRui Paulo struct radius_msg *req, 1014*e28a4053SRui Paulo const u8 *shared_secret, 1015*e28a4053SRui Paulo size_t shared_secret_len) 1016*e28a4053SRui Paulo { 1017*e28a4053SRui Paulo struct radius_ms_mppe_keys *keys; 1018*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1019*e28a4053SRui Paulo if (sm == NULL) 1020*e28a4053SRui Paulo return; 1021*e28a4053SRui Paulo 1022*e28a4053SRui Paulo keys = radius_msg_get_ms_keys(msg, req, shared_secret, 1023*e28a4053SRui Paulo shared_secret_len); 1024*e28a4053SRui Paulo 1025*e28a4053SRui Paulo if (keys && keys->send && keys->recv) { 1026*e28a4053SRui Paulo size_t len = keys->send_len + keys->recv_len; 1027*e28a4053SRui Paulo wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key", 1028*e28a4053SRui Paulo keys->send, keys->send_len); 1029*e28a4053SRui Paulo wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key", 1030*e28a4053SRui Paulo keys->recv, keys->recv_len); 1031*e28a4053SRui Paulo 1032*e28a4053SRui Paulo os_free(sm->eap_if->aaaEapKeyData); 1033*e28a4053SRui Paulo sm->eap_if->aaaEapKeyData = os_malloc(len); 1034*e28a4053SRui Paulo if (sm->eap_if->aaaEapKeyData) { 1035*e28a4053SRui Paulo os_memcpy(sm->eap_if->aaaEapKeyData, keys->recv, 1036*e28a4053SRui Paulo keys->recv_len); 1037*e28a4053SRui Paulo os_memcpy(sm->eap_if->aaaEapKeyData + keys->recv_len, 1038*e28a4053SRui Paulo keys->send, keys->send_len); 1039*e28a4053SRui Paulo sm->eap_if->aaaEapKeyDataLen = len; 1040*e28a4053SRui Paulo sm->eap_if->aaaEapKeyAvailable = TRUE; 1041*e28a4053SRui Paulo } 1042*e28a4053SRui Paulo } 1043*e28a4053SRui Paulo 1044*e28a4053SRui Paulo if (keys) { 1045*e28a4053SRui Paulo os_free(keys->send); 1046*e28a4053SRui Paulo os_free(keys->recv); 1047*e28a4053SRui Paulo os_free(keys); 1048*e28a4053SRui Paulo } 1049*e28a4053SRui Paulo } 1050*e28a4053SRui Paulo 1051*e28a4053SRui Paulo 1052*e28a4053SRui Paulo static void ieee802_1x_store_radius_class(struct hostapd_data *hapd, 1053*e28a4053SRui Paulo struct sta_info *sta, 1054*e28a4053SRui Paulo struct radius_msg *msg) 1055*e28a4053SRui Paulo { 1056*e28a4053SRui Paulo u8 *class; 1057*e28a4053SRui Paulo size_t class_len; 1058*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1059*e28a4053SRui Paulo int count, i; 1060*e28a4053SRui Paulo struct radius_attr_data *nclass; 1061*e28a4053SRui Paulo size_t nclass_count; 1062*e28a4053SRui Paulo 1063*e28a4053SRui Paulo if (!hapd->conf->radius->acct_server || hapd->radius == NULL || 1064*e28a4053SRui Paulo sm == NULL) 1065*e28a4053SRui Paulo return; 1066*e28a4053SRui Paulo 1067*e28a4053SRui Paulo radius_free_class(&sm->radius_class); 1068*e28a4053SRui Paulo count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1); 1069*e28a4053SRui Paulo if (count <= 0) 1070*e28a4053SRui Paulo return; 1071*e28a4053SRui Paulo 1072*e28a4053SRui Paulo nclass = os_zalloc(count * sizeof(struct radius_attr_data)); 1073*e28a4053SRui Paulo if (nclass == NULL) 1074*e28a4053SRui Paulo return; 1075*e28a4053SRui Paulo 1076*e28a4053SRui Paulo nclass_count = 0; 1077*e28a4053SRui Paulo 1078*e28a4053SRui Paulo class = NULL; 1079*e28a4053SRui Paulo for (i = 0; i < count; i++) { 1080*e28a4053SRui Paulo do { 1081*e28a4053SRui Paulo if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, 1082*e28a4053SRui Paulo &class, &class_len, 1083*e28a4053SRui Paulo class) < 0) { 1084*e28a4053SRui Paulo i = count; 1085*e28a4053SRui Paulo break; 1086*e28a4053SRui Paulo } 1087*e28a4053SRui Paulo } while (class_len < 1); 1088*e28a4053SRui Paulo 1089*e28a4053SRui Paulo nclass[nclass_count].data = os_malloc(class_len); 1090*e28a4053SRui Paulo if (nclass[nclass_count].data == NULL) 1091*e28a4053SRui Paulo break; 1092*e28a4053SRui Paulo 1093*e28a4053SRui Paulo os_memcpy(nclass[nclass_count].data, class, class_len); 1094*e28a4053SRui Paulo nclass[nclass_count].len = class_len; 1095*e28a4053SRui Paulo nclass_count++; 1096*e28a4053SRui Paulo } 1097*e28a4053SRui Paulo 1098*e28a4053SRui Paulo sm->radius_class.attr = nclass; 1099*e28a4053SRui Paulo sm->radius_class.count = nclass_count; 1100*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Stored %lu RADIUS Class " 1101*e28a4053SRui Paulo "attributes for " MACSTR, 1102*e28a4053SRui Paulo (unsigned long) sm->radius_class.count, 1103*e28a4053SRui Paulo MAC2STR(sta->addr)); 1104*e28a4053SRui Paulo } 1105*e28a4053SRui Paulo 1106*e28a4053SRui Paulo 1107*e28a4053SRui Paulo /* Update sta->identity based on User-Name attribute in Access-Accept */ 1108*e28a4053SRui Paulo static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd, 1109*e28a4053SRui Paulo struct sta_info *sta, 1110*e28a4053SRui Paulo struct radius_msg *msg) 1111*e28a4053SRui Paulo { 1112*e28a4053SRui Paulo u8 *buf, *identity; 1113*e28a4053SRui Paulo size_t len; 1114*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1115*e28a4053SRui Paulo 1116*e28a4053SRui Paulo if (sm == NULL) 1117*e28a4053SRui Paulo return; 1118*e28a4053SRui Paulo 1119*e28a4053SRui Paulo if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len, 1120*e28a4053SRui Paulo NULL) < 0) 1121*e28a4053SRui Paulo return; 1122*e28a4053SRui Paulo 1123*e28a4053SRui Paulo identity = os_malloc(len + 1); 1124*e28a4053SRui Paulo if (identity == NULL) 1125*e28a4053SRui Paulo return; 1126*e28a4053SRui Paulo 1127*e28a4053SRui Paulo os_memcpy(identity, buf, len); 1128*e28a4053SRui Paulo identity[len] = '\0'; 1129*e28a4053SRui Paulo 1130*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1131*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with " 1132*e28a4053SRui Paulo "User-Name from Access-Accept '%s'", 1133*e28a4053SRui Paulo sm->identity ? (char *) sm->identity : "N/A", 1134*e28a4053SRui Paulo (char *) identity); 1135*e28a4053SRui Paulo 1136*e28a4053SRui Paulo os_free(sm->identity); 1137*e28a4053SRui Paulo sm->identity = identity; 1138*e28a4053SRui Paulo sm->identity_len = len; 1139*e28a4053SRui Paulo } 1140*e28a4053SRui Paulo 1141*e28a4053SRui Paulo 1142*e28a4053SRui Paulo struct sta_id_search { 1143*e28a4053SRui Paulo u8 identifier; 1144*e28a4053SRui Paulo struct eapol_state_machine *sm; 1145*e28a4053SRui Paulo }; 1146*e28a4053SRui Paulo 1147*e28a4053SRui Paulo 1148*e28a4053SRui Paulo static int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd, 1149*e28a4053SRui Paulo struct sta_info *sta, 1150*e28a4053SRui Paulo void *ctx) 1151*e28a4053SRui Paulo { 1152*e28a4053SRui Paulo struct sta_id_search *id_search = ctx; 1153*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1154*e28a4053SRui Paulo 1155*e28a4053SRui Paulo if (sm && sm->radius_identifier >= 0 && 1156*e28a4053SRui Paulo sm->radius_identifier == id_search->identifier) { 1157*e28a4053SRui Paulo id_search->sm = sm; 1158*e28a4053SRui Paulo return 1; 1159*e28a4053SRui Paulo } 1160*e28a4053SRui Paulo return 0; 1161*e28a4053SRui Paulo } 1162*e28a4053SRui Paulo 1163*e28a4053SRui Paulo 1164*e28a4053SRui Paulo static struct eapol_state_machine * 1165*e28a4053SRui Paulo ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier) 1166*e28a4053SRui Paulo { 1167*e28a4053SRui Paulo struct sta_id_search id_search; 1168*e28a4053SRui Paulo id_search.identifier = identifier; 1169*e28a4053SRui Paulo id_search.sm = NULL; 1170*e28a4053SRui Paulo ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search); 1171*e28a4053SRui Paulo return id_search.sm; 1172*e28a4053SRui Paulo } 1173*e28a4053SRui Paulo 1174*e28a4053SRui Paulo 1175*e28a4053SRui Paulo /** 1176*e28a4053SRui Paulo * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server 1177*e28a4053SRui Paulo * @msg: RADIUS response message 1178*e28a4053SRui Paulo * @req: RADIUS request message 1179*e28a4053SRui Paulo * @shared_secret: RADIUS shared secret 1180*e28a4053SRui Paulo * @shared_secret_len: Length of shared_secret in octets 1181*e28a4053SRui Paulo * @data: Context data (struct hostapd_data *) 1182*e28a4053SRui Paulo * Returns: Processing status 1183*e28a4053SRui Paulo */ 1184*e28a4053SRui Paulo static RadiusRxResult 1185*e28a4053SRui Paulo ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 1186*e28a4053SRui Paulo const u8 *shared_secret, size_t shared_secret_len, 1187*e28a4053SRui Paulo void *data) 1188*e28a4053SRui Paulo { 1189*e28a4053SRui Paulo struct hostapd_data *hapd = data; 1190*e28a4053SRui Paulo struct sta_info *sta; 1191*e28a4053SRui Paulo u32 session_timeout = 0, termination_action, acct_interim_interval; 1192*e28a4053SRui Paulo int session_timeout_set, old_vlanid = 0; 1193*e28a4053SRui Paulo struct eapol_state_machine *sm; 1194*e28a4053SRui Paulo int override_eapReq = 0; 1195*e28a4053SRui Paulo struct radius_hdr *hdr = radius_msg_get_hdr(msg); 1196*e28a4053SRui Paulo 1197*e28a4053SRui Paulo sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier); 1198*e28a4053SRui Paulo if (sm == NULL) { 1199*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching " 1200*e28a4053SRui Paulo "station for this RADIUS message"); 1201*e28a4053SRui Paulo return RADIUS_RX_UNKNOWN; 1202*e28a4053SRui Paulo } 1203*e28a4053SRui Paulo sta = sm->sta; 1204*e28a4053SRui Paulo 1205*e28a4053SRui Paulo /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 1206*e28a4053SRui Paulo * present when packet contains an EAP-Message attribute */ 1207*e28a4053SRui Paulo if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 1208*e28a4053SRui Paulo radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 1209*e28a4053SRui Paulo 0) < 0 && 1210*e28a4053SRui Paulo radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 1211*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "Allowing RADIUS Access-Reject without " 1212*e28a4053SRui Paulo "Message-Authenticator since it does not include " 1213*e28a4053SRui Paulo "EAP-Message"); 1214*e28a4053SRui Paulo } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 1215*e28a4053SRui Paulo req, 1)) { 1216*e28a4053SRui Paulo printf("Incoming RADIUS packet did not have correct " 1217*e28a4053SRui Paulo "Message-Authenticator - dropped\n"); 1218*e28a4053SRui Paulo return RADIUS_RX_INVALID_AUTHENTICATOR; 1219*e28a4053SRui Paulo } 1220*e28a4053SRui Paulo 1221*e28a4053SRui Paulo if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 1222*e28a4053SRui Paulo hdr->code != RADIUS_CODE_ACCESS_REJECT && 1223*e28a4053SRui Paulo hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 1224*e28a4053SRui Paulo printf("Unknown RADIUS message code\n"); 1225*e28a4053SRui Paulo return RADIUS_RX_UNKNOWN; 1226*e28a4053SRui Paulo } 1227*e28a4053SRui Paulo 1228*e28a4053SRui Paulo sm->radius_identifier = -1; 1229*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR, 1230*e28a4053SRui Paulo MAC2STR(sta->addr)); 1231*e28a4053SRui Paulo 1232*e28a4053SRui Paulo radius_msg_free(sm->last_recv_radius); 1233*e28a4053SRui Paulo sm->last_recv_radius = msg; 1234*e28a4053SRui Paulo 1235*e28a4053SRui Paulo session_timeout_set = 1236*e28a4053SRui Paulo !radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, 1237*e28a4053SRui Paulo &session_timeout); 1238*e28a4053SRui Paulo if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION, 1239*e28a4053SRui Paulo &termination_action)) 1240*e28a4053SRui Paulo termination_action = RADIUS_TERMINATION_ACTION_DEFAULT; 1241*e28a4053SRui Paulo 1242*e28a4053SRui Paulo if (hapd->conf->acct_interim_interval == 0 && 1243*e28a4053SRui Paulo hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 1244*e28a4053SRui Paulo radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, 1245*e28a4053SRui Paulo &acct_interim_interval) == 0) { 1246*e28a4053SRui Paulo if (acct_interim_interval < 60) { 1247*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, 1248*e28a4053SRui Paulo HOSTAPD_MODULE_IEEE8021X, 1249*e28a4053SRui Paulo HOSTAPD_LEVEL_INFO, 1250*e28a4053SRui Paulo "ignored too small " 1251*e28a4053SRui Paulo "Acct-Interim-Interval %d", 1252*e28a4053SRui Paulo acct_interim_interval); 1253*e28a4053SRui Paulo } else 1254*e28a4053SRui Paulo sta->acct_interim_interval = acct_interim_interval; 1255*e28a4053SRui Paulo } 1256*e28a4053SRui Paulo 1257*e28a4053SRui Paulo 1258*e28a4053SRui Paulo switch (hdr->code) { 1259*e28a4053SRui Paulo case RADIUS_CODE_ACCESS_ACCEPT: 1260*e28a4053SRui Paulo if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED) 1261*e28a4053SRui Paulo sta->vlan_id = 0; 1262*e28a4053SRui Paulo #ifndef CONFIG_NO_VLAN 1263*e28a4053SRui Paulo else { 1264*e28a4053SRui Paulo old_vlanid = sta->vlan_id; 1265*e28a4053SRui Paulo sta->vlan_id = radius_msg_get_vlanid(msg); 1266*e28a4053SRui Paulo } 1267*e28a4053SRui Paulo if (sta->vlan_id > 0 && 1268*e28a4053SRui Paulo hostapd_get_vlan_id_ifname(hapd->conf->vlan, 1269*e28a4053SRui Paulo sta->vlan_id)) { 1270*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, 1271*e28a4053SRui Paulo HOSTAPD_MODULE_RADIUS, 1272*e28a4053SRui Paulo HOSTAPD_LEVEL_INFO, 1273*e28a4053SRui Paulo "VLAN ID %d", sta->vlan_id); 1274*e28a4053SRui Paulo } else if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_REQUIRED) { 1275*e28a4053SRui Paulo sta->eapol_sm->authFail = TRUE; 1276*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, 1277*e28a4053SRui Paulo HOSTAPD_MODULE_IEEE8021X, 1278*e28a4053SRui Paulo HOSTAPD_LEVEL_INFO, "authentication " 1279*e28a4053SRui Paulo "server did not include required VLAN " 1280*e28a4053SRui Paulo "ID in Access-Accept"); 1281*e28a4053SRui Paulo break; 1282*e28a4053SRui Paulo } 1283*e28a4053SRui Paulo #endif /* CONFIG_NO_VLAN */ 1284*e28a4053SRui Paulo 1285*e28a4053SRui Paulo if (ap_sta_bind_vlan(hapd, sta, old_vlanid) < 0) 1286*e28a4053SRui Paulo break; 1287*e28a4053SRui Paulo 1288*e28a4053SRui Paulo /* RFC 3580, Ch. 3.17 */ 1289*e28a4053SRui Paulo if (session_timeout_set && termination_action == 1290*e28a4053SRui Paulo RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) { 1291*e28a4053SRui Paulo sm->reAuthPeriod = session_timeout; 1292*e28a4053SRui Paulo } else if (session_timeout_set) 1293*e28a4053SRui Paulo ap_sta_session_timeout(hapd, sta, session_timeout); 1294*e28a4053SRui Paulo 1295*e28a4053SRui Paulo sm->eap_if->aaaSuccess = TRUE; 1296*e28a4053SRui Paulo override_eapReq = 1; 1297*e28a4053SRui Paulo ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret, 1298*e28a4053SRui Paulo shared_secret_len); 1299*e28a4053SRui Paulo ieee802_1x_store_radius_class(hapd, sta, msg); 1300*e28a4053SRui Paulo ieee802_1x_update_sta_identity(hapd, sta, msg); 1301*e28a4053SRui Paulo if (sm->eap_if->eapKeyAvailable && 1302*e28a4053SRui Paulo wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt, 1303*e28a4053SRui Paulo session_timeout_set ? 1304*e28a4053SRui Paulo (int) session_timeout : -1, sm) == 0) { 1305*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 1306*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, 1307*e28a4053SRui Paulo "Added PMKSA cache entry"); 1308*e28a4053SRui Paulo } 1309*e28a4053SRui Paulo break; 1310*e28a4053SRui Paulo case RADIUS_CODE_ACCESS_REJECT: 1311*e28a4053SRui Paulo sm->eap_if->aaaFail = TRUE; 1312*e28a4053SRui Paulo override_eapReq = 1; 1313*e28a4053SRui Paulo break; 1314*e28a4053SRui Paulo case RADIUS_CODE_ACCESS_CHALLENGE: 1315*e28a4053SRui Paulo sm->eap_if->aaaEapReq = TRUE; 1316*e28a4053SRui Paulo if (session_timeout_set) { 1317*e28a4053SRui Paulo /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */ 1318*e28a4053SRui Paulo sm->eap_if->aaaMethodTimeout = session_timeout; 1319*e28a4053SRui Paulo hostapd_logger(hapd, sm->addr, 1320*e28a4053SRui Paulo HOSTAPD_MODULE_IEEE8021X, 1321*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, 1322*e28a4053SRui Paulo "using EAP timeout of %d seconds (from " 1323*e28a4053SRui Paulo "RADIUS)", 1324*e28a4053SRui Paulo sm->eap_if->aaaMethodTimeout); 1325*e28a4053SRui Paulo } else { 1326*e28a4053SRui Paulo /* 1327*e28a4053SRui Paulo * Use dynamic retransmission behavior per EAP 1328*e28a4053SRui Paulo * specification. 1329*e28a4053SRui Paulo */ 1330*e28a4053SRui Paulo sm->eap_if->aaaMethodTimeout = 0; 1331*e28a4053SRui Paulo } 1332*e28a4053SRui Paulo break; 1333*e28a4053SRui Paulo } 1334*e28a4053SRui Paulo 1335*e28a4053SRui Paulo ieee802_1x_decapsulate_radius(hapd, sta); 1336*e28a4053SRui Paulo if (override_eapReq) 1337*e28a4053SRui Paulo sm->eap_if->aaaEapReq = FALSE; 1338*e28a4053SRui Paulo 1339*e28a4053SRui Paulo eapol_auth_step(sm); 1340*e28a4053SRui Paulo 1341*e28a4053SRui Paulo return RADIUS_RX_QUEUED; 1342*e28a4053SRui Paulo } 1343*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 1344*e28a4053SRui Paulo 1345*e28a4053SRui Paulo 1346*e28a4053SRui Paulo void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta) 1347*e28a4053SRui Paulo { 1348*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1349*e28a4053SRui Paulo if (sm == NULL) 1350*e28a4053SRui Paulo return; 1351*e28a4053SRui Paulo 1352*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1353*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "aborting authentication"); 1354*e28a4053SRui Paulo 1355*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 1356*e28a4053SRui Paulo radius_msg_free(sm->last_recv_radius); 1357*e28a4053SRui Paulo sm->last_recv_radius = NULL; 1358*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 1359*e28a4053SRui Paulo 1360*e28a4053SRui Paulo if (sm->eap_if->eapTimeout) { 1361*e28a4053SRui Paulo /* 1362*e28a4053SRui Paulo * Disconnect the STA since it did not reply to the last EAP 1363*e28a4053SRui Paulo * request and we cannot continue EAP processing (EAP-Failure 1364*e28a4053SRui Paulo * could only be sent if the EAP peer actually replied). 1365*e28a4053SRui Paulo */ 1366*e28a4053SRui Paulo sm->eap_if->portEnabled = FALSE; 1367*e28a4053SRui Paulo ap_sta_disconnect(hapd, sta, sta->addr, 1368*e28a4053SRui Paulo WLAN_REASON_PREV_AUTH_NOT_VALID); 1369*e28a4053SRui Paulo } 1370*e28a4053SRui Paulo } 1371*e28a4053SRui Paulo 1372*e28a4053SRui Paulo 1373*e28a4053SRui Paulo static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd) 1374*e28a4053SRui Paulo { 1375*e28a4053SRui Paulo struct eapol_authenticator *eapol = hapd->eapol_auth; 1376*e28a4053SRui Paulo 1377*e28a4053SRui Paulo if (hapd->conf->default_wep_key_len < 1) 1378*e28a4053SRui Paulo return 0; 1379*e28a4053SRui Paulo 1380*e28a4053SRui Paulo os_free(eapol->default_wep_key); 1381*e28a4053SRui Paulo eapol->default_wep_key = os_malloc(hapd->conf->default_wep_key_len); 1382*e28a4053SRui Paulo if (eapol->default_wep_key == NULL || 1383*e28a4053SRui Paulo os_get_random(eapol->default_wep_key, 1384*e28a4053SRui Paulo hapd->conf->default_wep_key_len)) { 1385*e28a4053SRui Paulo printf("Could not generate random WEP key.\n"); 1386*e28a4053SRui Paulo os_free(eapol->default_wep_key); 1387*e28a4053SRui Paulo eapol->default_wep_key = NULL; 1388*e28a4053SRui Paulo return -1; 1389*e28a4053SRui Paulo } 1390*e28a4053SRui Paulo 1391*e28a4053SRui Paulo wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key", 1392*e28a4053SRui Paulo eapol->default_wep_key, 1393*e28a4053SRui Paulo hapd->conf->default_wep_key_len); 1394*e28a4053SRui Paulo 1395*e28a4053SRui Paulo return 0; 1396*e28a4053SRui Paulo } 1397*e28a4053SRui Paulo 1398*e28a4053SRui Paulo 1399*e28a4053SRui Paulo static int ieee802_1x_sta_key_available(struct hostapd_data *hapd, 1400*e28a4053SRui Paulo struct sta_info *sta, void *ctx) 1401*e28a4053SRui Paulo { 1402*e28a4053SRui Paulo if (sta->eapol_sm) { 1403*e28a4053SRui Paulo sta->eapol_sm->eap_if->eapKeyAvailable = TRUE; 1404*e28a4053SRui Paulo eapol_auth_step(sta->eapol_sm); 1405*e28a4053SRui Paulo } 1406*e28a4053SRui Paulo return 0; 1407*e28a4053SRui Paulo } 1408*e28a4053SRui Paulo 1409*e28a4053SRui Paulo 1410*e28a4053SRui Paulo static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx) 1411*e28a4053SRui Paulo { 1412*e28a4053SRui Paulo struct hostapd_data *hapd = eloop_ctx; 1413*e28a4053SRui Paulo struct eapol_authenticator *eapol = hapd->eapol_auth; 1414*e28a4053SRui Paulo 1415*e28a4053SRui Paulo if (eapol->default_wep_key_idx >= 3) 1416*e28a4053SRui Paulo eapol->default_wep_key_idx = 1417*e28a4053SRui Paulo hapd->conf->individual_wep_key_len > 0 ? 1 : 0; 1418*e28a4053SRui Paulo else 1419*e28a4053SRui Paulo eapol->default_wep_key_idx++; 1420*e28a4053SRui Paulo 1421*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d", 1422*e28a4053SRui Paulo eapol->default_wep_key_idx); 1423*e28a4053SRui Paulo 1424*e28a4053SRui Paulo if (ieee802_1x_rekey_broadcast(hapd)) { 1425*e28a4053SRui Paulo hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, 1426*e28a4053SRui Paulo HOSTAPD_LEVEL_WARNING, "failed to generate a " 1427*e28a4053SRui Paulo "new broadcast key"); 1428*e28a4053SRui Paulo os_free(eapol->default_wep_key); 1429*e28a4053SRui Paulo eapol->default_wep_key = NULL; 1430*e28a4053SRui Paulo return; 1431*e28a4053SRui Paulo } 1432*e28a4053SRui Paulo 1433*e28a4053SRui Paulo /* TODO: Could setup key for RX here, but change default TX keyid only 1434*e28a4053SRui Paulo * after new broadcast key has been sent to all stations. */ 1435*e28a4053SRui Paulo if (hapd->drv.set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, NULL, 1436*e28a4053SRui Paulo eapol->default_wep_key_idx, 1, NULL, 0, 1437*e28a4053SRui Paulo eapol->default_wep_key, 1438*e28a4053SRui Paulo hapd->conf->default_wep_key_len)) { 1439*e28a4053SRui Paulo hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, 1440*e28a4053SRui Paulo HOSTAPD_LEVEL_WARNING, "failed to configure a " 1441*e28a4053SRui Paulo "new broadcast key"); 1442*e28a4053SRui Paulo os_free(eapol->default_wep_key); 1443*e28a4053SRui Paulo eapol->default_wep_key = NULL; 1444*e28a4053SRui Paulo return; 1445*e28a4053SRui Paulo } 1446*e28a4053SRui Paulo 1447*e28a4053SRui Paulo ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL); 1448*e28a4053SRui Paulo 1449*e28a4053SRui Paulo if (hapd->conf->wep_rekeying_period > 0) { 1450*e28a4053SRui Paulo eloop_register_timeout(hapd->conf->wep_rekeying_period, 0, 1451*e28a4053SRui Paulo ieee802_1x_rekey, hapd, NULL); 1452*e28a4053SRui Paulo } 1453*e28a4053SRui Paulo } 1454*e28a4053SRui Paulo 1455*e28a4053SRui Paulo 1456*e28a4053SRui Paulo static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type, 1457*e28a4053SRui Paulo const u8 *data, size_t datalen) 1458*e28a4053SRui Paulo { 1459*e28a4053SRui Paulo #ifdef CONFIG_WPS 1460*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1461*e28a4053SRui Paulo 1462*e28a4053SRui Paulo if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) == 1463*e28a4053SRui Paulo WLAN_STA_MAYBE_WPS) { 1464*e28a4053SRui Paulo const u8 *identity; 1465*e28a4053SRui Paulo size_t identity_len; 1466*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1467*e28a4053SRui Paulo 1468*e28a4053SRui Paulo identity = eap_get_identity(sm->eap, &identity_len); 1469*e28a4053SRui Paulo if (identity && 1470*e28a4053SRui Paulo ((identity_len == WSC_ID_ENROLLEE_LEN && 1471*e28a4053SRui Paulo os_memcmp(identity, WSC_ID_ENROLLEE, 1472*e28a4053SRui Paulo WSC_ID_ENROLLEE_LEN) == 0) || 1473*e28a4053SRui Paulo (identity_len == WSC_ID_REGISTRAR_LEN && 1474*e28a4053SRui Paulo os_memcmp(identity, WSC_ID_REGISTRAR, 1475*e28a4053SRui Paulo WSC_ID_REGISTRAR_LEN) == 0))) { 1476*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "WPS: WLAN_STA_MAYBE_WPS -> " 1477*e28a4053SRui Paulo "WLAN_STA_WPS"); 1478*e28a4053SRui Paulo sta->flags |= WLAN_STA_WPS; 1479*e28a4053SRui Paulo } 1480*e28a4053SRui Paulo } 1481*e28a4053SRui Paulo #endif /* CONFIG_WPS */ 1482*e28a4053SRui Paulo 1483*e28a4053SRui Paulo ieee802_1x_send(ctx, sta_ctx, type, data, datalen); 1484*e28a4053SRui Paulo } 1485*e28a4053SRui Paulo 1486*e28a4053SRui Paulo 1487*e28a4053SRui Paulo static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx, 1488*e28a4053SRui Paulo const u8 *data, size_t datalen) 1489*e28a4053SRui Paulo { 1490*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 1491*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1492*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1493*e28a4053SRui Paulo 1494*e28a4053SRui Paulo ieee802_1x_encapsulate_radius(hapd, sta, data, datalen); 1495*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 1496*e28a4053SRui Paulo } 1497*e28a4053SRui Paulo 1498*e28a4053SRui Paulo 1499*e28a4053SRui Paulo static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success, 1500*e28a4053SRui Paulo int preauth) 1501*e28a4053SRui Paulo { 1502*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1503*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1504*e28a4053SRui Paulo if (preauth) 1505*e28a4053SRui Paulo rsn_preauth_finished(hapd, sta, success); 1506*e28a4053SRui Paulo else 1507*e28a4053SRui Paulo ieee802_1x_finished(hapd, sta, success); 1508*e28a4053SRui Paulo } 1509*e28a4053SRui Paulo 1510*e28a4053SRui Paulo 1511*e28a4053SRui Paulo static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity, 1512*e28a4053SRui Paulo size_t identity_len, int phase2, 1513*e28a4053SRui Paulo struct eap_user *user) 1514*e28a4053SRui Paulo { 1515*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1516*e28a4053SRui Paulo const struct hostapd_eap_user *eap_user; 1517*e28a4053SRui Paulo int i, count; 1518*e28a4053SRui Paulo 1519*e28a4053SRui Paulo eap_user = hostapd_get_eap_user(hapd->conf, identity, 1520*e28a4053SRui Paulo identity_len, phase2); 1521*e28a4053SRui Paulo if (eap_user == NULL) 1522*e28a4053SRui Paulo return -1; 1523*e28a4053SRui Paulo 1524*e28a4053SRui Paulo os_memset(user, 0, sizeof(*user)); 1525*e28a4053SRui Paulo user->phase2 = phase2; 1526*e28a4053SRui Paulo count = EAP_USER_MAX_METHODS; 1527*e28a4053SRui Paulo if (count > EAP_MAX_METHODS) 1528*e28a4053SRui Paulo count = EAP_MAX_METHODS; 1529*e28a4053SRui Paulo for (i = 0; i < count; i++) { 1530*e28a4053SRui Paulo user->methods[i].vendor = eap_user->methods[i].vendor; 1531*e28a4053SRui Paulo user->methods[i].method = eap_user->methods[i].method; 1532*e28a4053SRui Paulo } 1533*e28a4053SRui Paulo 1534*e28a4053SRui Paulo if (eap_user->password) { 1535*e28a4053SRui Paulo user->password = os_malloc(eap_user->password_len); 1536*e28a4053SRui Paulo if (user->password == NULL) 1537*e28a4053SRui Paulo return -1; 1538*e28a4053SRui Paulo os_memcpy(user->password, eap_user->password, 1539*e28a4053SRui Paulo eap_user->password_len); 1540*e28a4053SRui Paulo user->password_len = eap_user->password_len; 1541*e28a4053SRui Paulo } 1542*e28a4053SRui Paulo user->force_version = eap_user->force_version; 1543*e28a4053SRui Paulo user->ttls_auth = eap_user->ttls_auth; 1544*e28a4053SRui Paulo 1545*e28a4053SRui Paulo return 0; 1546*e28a4053SRui Paulo } 1547*e28a4053SRui Paulo 1548*e28a4053SRui Paulo 1549*e28a4053SRui Paulo static int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr) 1550*e28a4053SRui Paulo { 1551*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1552*e28a4053SRui Paulo struct sta_info *sta; 1553*e28a4053SRui Paulo sta = ap_get_sta(hapd, addr); 1554*e28a4053SRui Paulo if (sta == NULL || sta->eapol_sm == NULL) 1555*e28a4053SRui Paulo return 0; 1556*e28a4053SRui Paulo return 1; 1557*e28a4053SRui Paulo } 1558*e28a4053SRui Paulo 1559*e28a4053SRui Paulo 1560*e28a4053SRui Paulo static void ieee802_1x_logger(void *ctx, const u8 *addr, 1561*e28a4053SRui Paulo eapol_logger_level level, const char *txt) 1562*e28a4053SRui Paulo { 1563*e28a4053SRui Paulo #ifndef CONFIG_NO_HOSTAPD_LOGGER 1564*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1565*e28a4053SRui Paulo int hlevel; 1566*e28a4053SRui Paulo 1567*e28a4053SRui Paulo switch (level) { 1568*e28a4053SRui Paulo case EAPOL_LOGGER_WARNING: 1569*e28a4053SRui Paulo hlevel = HOSTAPD_LEVEL_WARNING; 1570*e28a4053SRui Paulo break; 1571*e28a4053SRui Paulo case EAPOL_LOGGER_INFO: 1572*e28a4053SRui Paulo hlevel = HOSTAPD_LEVEL_INFO; 1573*e28a4053SRui Paulo break; 1574*e28a4053SRui Paulo case EAPOL_LOGGER_DEBUG: 1575*e28a4053SRui Paulo default: 1576*e28a4053SRui Paulo hlevel = HOSTAPD_LEVEL_DEBUG; 1577*e28a4053SRui Paulo break; 1578*e28a4053SRui Paulo } 1579*e28a4053SRui Paulo 1580*e28a4053SRui Paulo hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s", 1581*e28a4053SRui Paulo txt); 1582*e28a4053SRui Paulo #endif /* CONFIG_NO_HOSTAPD_LOGGER */ 1583*e28a4053SRui Paulo } 1584*e28a4053SRui Paulo 1585*e28a4053SRui Paulo 1586*e28a4053SRui Paulo static void ieee802_1x_set_port_authorized(void *ctx, void *sta_ctx, 1587*e28a4053SRui Paulo int authorized) 1588*e28a4053SRui Paulo { 1589*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1590*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1591*e28a4053SRui Paulo ieee802_1x_set_sta_authorized(hapd, sta, authorized); 1592*e28a4053SRui Paulo } 1593*e28a4053SRui Paulo 1594*e28a4053SRui Paulo 1595*e28a4053SRui Paulo static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx) 1596*e28a4053SRui Paulo { 1597*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1598*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1599*e28a4053SRui Paulo ieee802_1x_abort_auth(hapd, sta); 1600*e28a4053SRui Paulo } 1601*e28a4053SRui Paulo 1602*e28a4053SRui Paulo 1603*e28a4053SRui Paulo static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx) 1604*e28a4053SRui Paulo { 1605*e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 1606*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1607*e28a4053SRui Paulo ieee802_1x_tx_key(hapd, sta); 1608*e28a4053SRui Paulo } 1609*e28a4053SRui Paulo 1610*e28a4053SRui Paulo 1611*e28a4053SRui Paulo static void ieee802_1x_eapol_event(void *ctx, void *sta_ctx, 1612*e28a4053SRui Paulo enum eapol_event type) 1613*e28a4053SRui Paulo { 1614*e28a4053SRui Paulo /* struct hostapd_data *hapd = ctx; */ 1615*e28a4053SRui Paulo struct sta_info *sta = sta_ctx; 1616*e28a4053SRui Paulo switch (type) { 1617*e28a4053SRui Paulo case EAPOL_AUTH_SM_CHANGE: 1618*e28a4053SRui Paulo wpa_auth_sm_notify(sta->wpa_sm); 1619*e28a4053SRui Paulo break; 1620*e28a4053SRui Paulo case EAPOL_AUTH_REAUTHENTICATE: 1621*e28a4053SRui Paulo wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL); 1622*e28a4053SRui Paulo break; 1623*e28a4053SRui Paulo } 1624*e28a4053SRui Paulo } 1625*e28a4053SRui Paulo 1626*e28a4053SRui Paulo 1627*e28a4053SRui Paulo int ieee802_1x_init(struct hostapd_data *hapd) 1628*e28a4053SRui Paulo { 1629*e28a4053SRui Paulo int i; 1630*e28a4053SRui Paulo struct eapol_auth_config conf; 1631*e28a4053SRui Paulo struct eapol_auth_cb cb; 1632*e28a4053SRui Paulo 1633*e28a4053SRui Paulo os_memset(&conf, 0, sizeof(conf)); 1634*e28a4053SRui Paulo conf.ctx = hapd; 1635*e28a4053SRui Paulo conf.eap_reauth_period = hapd->conf->eap_reauth_period; 1636*e28a4053SRui Paulo conf.wpa = hapd->conf->wpa; 1637*e28a4053SRui Paulo conf.individual_wep_key_len = hapd->conf->individual_wep_key_len; 1638*e28a4053SRui Paulo conf.eap_server = hapd->conf->eap_server; 1639*e28a4053SRui Paulo conf.ssl_ctx = hapd->ssl_ctx; 1640*e28a4053SRui Paulo conf.msg_ctx = hapd->msg_ctx; 1641*e28a4053SRui Paulo conf.eap_sim_db_priv = hapd->eap_sim_db_priv; 1642*e28a4053SRui Paulo conf.eap_req_id_text = hapd->conf->eap_req_id_text; 1643*e28a4053SRui Paulo conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len; 1644*e28a4053SRui Paulo conf.pac_opaque_encr_key = hapd->conf->pac_opaque_encr_key; 1645*e28a4053SRui Paulo conf.eap_fast_a_id = hapd->conf->eap_fast_a_id; 1646*e28a4053SRui Paulo conf.eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len; 1647*e28a4053SRui Paulo conf.eap_fast_a_id_info = hapd->conf->eap_fast_a_id_info; 1648*e28a4053SRui Paulo conf.eap_fast_prov = hapd->conf->eap_fast_prov; 1649*e28a4053SRui Paulo conf.pac_key_lifetime = hapd->conf->pac_key_lifetime; 1650*e28a4053SRui Paulo conf.pac_key_refresh_time = hapd->conf->pac_key_refresh_time; 1651*e28a4053SRui Paulo conf.eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind; 1652*e28a4053SRui Paulo conf.tnc = hapd->conf->tnc; 1653*e28a4053SRui Paulo conf.wps = hapd->wps; 1654*e28a4053SRui Paulo 1655*e28a4053SRui Paulo os_memset(&cb, 0, sizeof(cb)); 1656*e28a4053SRui Paulo cb.eapol_send = ieee802_1x_eapol_send; 1657*e28a4053SRui Paulo cb.aaa_send = ieee802_1x_aaa_send; 1658*e28a4053SRui Paulo cb.finished = _ieee802_1x_finished; 1659*e28a4053SRui Paulo cb.get_eap_user = ieee802_1x_get_eap_user; 1660*e28a4053SRui Paulo cb.sta_entry_alive = ieee802_1x_sta_entry_alive; 1661*e28a4053SRui Paulo cb.logger = ieee802_1x_logger; 1662*e28a4053SRui Paulo cb.set_port_authorized = ieee802_1x_set_port_authorized; 1663*e28a4053SRui Paulo cb.abort_auth = _ieee802_1x_abort_auth; 1664*e28a4053SRui Paulo cb.tx_key = _ieee802_1x_tx_key; 1665*e28a4053SRui Paulo cb.eapol_event = ieee802_1x_eapol_event; 1666*e28a4053SRui Paulo 1667*e28a4053SRui Paulo hapd->eapol_auth = eapol_auth_init(&conf, &cb); 1668*e28a4053SRui Paulo if (hapd->eapol_auth == NULL) 1669*e28a4053SRui Paulo return -1; 1670*e28a4053SRui Paulo 1671*e28a4053SRui Paulo if ((hapd->conf->ieee802_1x || hapd->conf->wpa) && 1672*e28a4053SRui Paulo hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1)) 1673*e28a4053SRui Paulo return -1; 1674*e28a4053SRui Paulo 1675*e28a4053SRui Paulo #ifndef CONFIG_NO_RADIUS 1676*e28a4053SRui Paulo if (radius_client_register(hapd->radius, RADIUS_AUTH, 1677*e28a4053SRui Paulo ieee802_1x_receive_auth, hapd)) 1678*e28a4053SRui Paulo return -1; 1679*e28a4053SRui Paulo #endif /* CONFIG_NO_RADIUS */ 1680*e28a4053SRui Paulo 1681*e28a4053SRui Paulo if (hapd->conf->default_wep_key_len) { 1682*e28a4053SRui Paulo for (i = 0; i < 4; i++) 1683*e28a4053SRui Paulo hapd->drv.set_key(hapd->conf->iface, hapd, 1684*e28a4053SRui Paulo WPA_ALG_NONE, NULL, i, 0, NULL, 0, 1685*e28a4053SRui Paulo NULL, 0); 1686*e28a4053SRui Paulo 1687*e28a4053SRui Paulo ieee802_1x_rekey(hapd, NULL); 1688*e28a4053SRui Paulo 1689*e28a4053SRui Paulo if (hapd->eapol_auth->default_wep_key == NULL) 1690*e28a4053SRui Paulo return -1; 1691*e28a4053SRui Paulo } 1692*e28a4053SRui Paulo 1693*e28a4053SRui Paulo return 0; 1694*e28a4053SRui Paulo } 1695*e28a4053SRui Paulo 1696*e28a4053SRui Paulo 1697*e28a4053SRui Paulo void ieee802_1x_deinit(struct hostapd_data *hapd) 1698*e28a4053SRui Paulo { 1699*e28a4053SRui Paulo eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL); 1700*e28a4053SRui Paulo 1701*e28a4053SRui Paulo if (hapd->driver != NULL && 1702*e28a4053SRui Paulo (hapd->conf->ieee802_1x || hapd->conf->wpa)) 1703*e28a4053SRui Paulo hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 1704*e28a4053SRui Paulo 1705*e28a4053SRui Paulo eapol_auth_deinit(hapd->eapol_auth); 1706*e28a4053SRui Paulo hapd->eapol_auth = NULL; 1707*e28a4053SRui Paulo } 1708*e28a4053SRui Paulo 1709*e28a4053SRui Paulo 1710*e28a4053SRui Paulo int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, 1711*e28a4053SRui Paulo const u8 *buf, size_t len, int ack) 1712*e28a4053SRui Paulo { 1713*e28a4053SRui Paulo struct ieee80211_hdr *hdr; 1714*e28a4053SRui Paulo struct ieee802_1x_hdr *xhdr; 1715*e28a4053SRui Paulo struct ieee802_1x_eapol_key *key; 1716*e28a4053SRui Paulo u8 *pos; 1717*e28a4053SRui Paulo const unsigned char rfc1042_hdr[ETH_ALEN] = 1718*e28a4053SRui Paulo { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 1719*e28a4053SRui Paulo 1720*e28a4053SRui Paulo if (sta == NULL) 1721*e28a4053SRui Paulo return -1; 1722*e28a4053SRui Paulo if (len < sizeof(*hdr) + sizeof(rfc1042_hdr) + 2 + sizeof(*xhdr)) 1723*e28a4053SRui Paulo return 0; 1724*e28a4053SRui Paulo 1725*e28a4053SRui Paulo hdr = (struct ieee80211_hdr *) buf; 1726*e28a4053SRui Paulo pos = (u8 *) (hdr + 1); 1727*e28a4053SRui Paulo if (os_memcmp(pos, rfc1042_hdr, sizeof(rfc1042_hdr)) != 0) 1728*e28a4053SRui Paulo return 0; 1729*e28a4053SRui Paulo pos += sizeof(rfc1042_hdr); 1730*e28a4053SRui Paulo if (WPA_GET_BE16(pos) != ETH_P_PAE) 1731*e28a4053SRui Paulo return 0; 1732*e28a4053SRui Paulo pos += 2; 1733*e28a4053SRui Paulo 1734*e28a4053SRui Paulo xhdr = (struct ieee802_1x_hdr *) pos; 1735*e28a4053SRui Paulo pos += sizeof(*xhdr); 1736*e28a4053SRui Paulo 1737*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR " TX status - version=%d " 1738*e28a4053SRui Paulo "type=%d length=%d - ack=%d", 1739*e28a4053SRui Paulo MAC2STR(sta->addr), xhdr->version, xhdr->type, 1740*e28a4053SRui Paulo be_to_host16(xhdr->length), ack); 1741*e28a4053SRui Paulo 1742*e28a4053SRui Paulo /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant 1743*e28a4053SRui Paulo * or Authenticator state machines, but EAPOL-Key packets are not 1744*e28a4053SRui Paulo * retransmitted in case of failure. Try to re-sent failed EAPOL-Key 1745*e28a4053SRui Paulo * packets couple of times because otherwise STA keys become 1746*e28a4053SRui Paulo * unsynchronized with AP. */ 1747*e28a4053SRui Paulo if (xhdr->type == IEEE802_1X_TYPE_EAPOL_KEY && !ack && 1748*e28a4053SRui Paulo pos + sizeof(*key) <= buf + len) { 1749*e28a4053SRui Paulo key = (struct ieee802_1x_eapol_key *) pos; 1750*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, 1751*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, "did not Ack EAPOL-Key " 1752*e28a4053SRui Paulo "frame (%scast index=%d)", 1753*e28a4053SRui Paulo key->key_index & BIT(7) ? "uni" : "broad", 1754*e28a4053SRui Paulo key->key_index & ~BIT(7)); 1755*e28a4053SRui Paulo /* TODO: re-send EAPOL-Key couple of times (with short delay 1756*e28a4053SRui Paulo * between them?). If all attempt fail, report error and 1757*e28a4053SRui Paulo * deauthenticate STA so that it will get new keys when 1758*e28a4053SRui Paulo * authenticating again (e.g., after returning in range). 1759*e28a4053SRui Paulo * Separate limit/transmit state needed both for unicast and 1760*e28a4053SRui Paulo * broadcast keys(?) */ 1761*e28a4053SRui Paulo } 1762*e28a4053SRui Paulo /* TODO: could move unicast key configuration from ieee802_1x_tx_key() 1763*e28a4053SRui Paulo * to here and change the key only if the EAPOL-Key packet was Acked. 1764*e28a4053SRui Paulo */ 1765*e28a4053SRui Paulo 1766*e28a4053SRui Paulo return 1; 1767*e28a4053SRui Paulo } 1768*e28a4053SRui Paulo 1769*e28a4053SRui Paulo 1770*e28a4053SRui Paulo u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len) 1771*e28a4053SRui Paulo { 1772*e28a4053SRui Paulo if (sm == NULL || sm->identity == NULL) 1773*e28a4053SRui Paulo return NULL; 1774*e28a4053SRui Paulo 1775*e28a4053SRui Paulo *len = sm->identity_len; 1776*e28a4053SRui Paulo return sm->identity; 1777*e28a4053SRui Paulo } 1778*e28a4053SRui Paulo 1779*e28a4053SRui Paulo 1780*e28a4053SRui Paulo u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, 1781*e28a4053SRui Paulo int idx) 1782*e28a4053SRui Paulo { 1783*e28a4053SRui Paulo if (sm == NULL || sm->radius_class.attr == NULL || 1784*e28a4053SRui Paulo idx >= (int) sm->radius_class.count) 1785*e28a4053SRui Paulo return NULL; 1786*e28a4053SRui Paulo 1787*e28a4053SRui Paulo *len = sm->radius_class.attr[idx].len; 1788*e28a4053SRui Paulo return sm->radius_class.attr[idx].data; 1789*e28a4053SRui Paulo } 1790*e28a4053SRui Paulo 1791*e28a4053SRui Paulo 1792*e28a4053SRui Paulo const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len) 1793*e28a4053SRui Paulo { 1794*e28a4053SRui Paulo if (sm == NULL) 1795*e28a4053SRui Paulo return NULL; 1796*e28a4053SRui Paulo 1797*e28a4053SRui Paulo *len = sm->eap_if->eapKeyDataLen; 1798*e28a4053SRui Paulo return sm->eap_if->eapKeyData; 1799*e28a4053SRui Paulo } 1800*e28a4053SRui Paulo 1801*e28a4053SRui Paulo 1802*e28a4053SRui Paulo void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm, 1803*e28a4053SRui Paulo int enabled) 1804*e28a4053SRui Paulo { 1805*e28a4053SRui Paulo if (sm == NULL) 1806*e28a4053SRui Paulo return; 1807*e28a4053SRui Paulo sm->eap_if->portEnabled = enabled ? TRUE : FALSE; 1808*e28a4053SRui Paulo eapol_auth_step(sm); 1809*e28a4053SRui Paulo } 1810*e28a4053SRui Paulo 1811*e28a4053SRui Paulo 1812*e28a4053SRui Paulo void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm, 1813*e28a4053SRui Paulo int valid) 1814*e28a4053SRui Paulo { 1815*e28a4053SRui Paulo if (sm == NULL) 1816*e28a4053SRui Paulo return; 1817*e28a4053SRui Paulo sm->portValid = valid ? TRUE : FALSE; 1818*e28a4053SRui Paulo eapol_auth_step(sm); 1819*e28a4053SRui Paulo } 1820*e28a4053SRui Paulo 1821*e28a4053SRui Paulo 1822*e28a4053SRui Paulo void ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth) 1823*e28a4053SRui Paulo { 1824*e28a4053SRui Paulo if (sm == NULL) 1825*e28a4053SRui Paulo return; 1826*e28a4053SRui Paulo if (pre_auth) 1827*e28a4053SRui Paulo sm->flags |= EAPOL_SM_PREAUTH; 1828*e28a4053SRui Paulo else 1829*e28a4053SRui Paulo sm->flags &= ~EAPOL_SM_PREAUTH; 1830*e28a4053SRui Paulo } 1831*e28a4053SRui Paulo 1832*e28a4053SRui Paulo 1833*e28a4053SRui Paulo static const char * bool_txt(Boolean bool) 1834*e28a4053SRui Paulo { 1835*e28a4053SRui Paulo return bool ? "TRUE" : "FALSE"; 1836*e28a4053SRui Paulo } 1837*e28a4053SRui Paulo 1838*e28a4053SRui Paulo 1839*e28a4053SRui Paulo int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) 1840*e28a4053SRui Paulo { 1841*e28a4053SRui Paulo /* TODO */ 1842*e28a4053SRui Paulo return 0; 1843*e28a4053SRui Paulo } 1844*e28a4053SRui Paulo 1845*e28a4053SRui Paulo 1846*e28a4053SRui Paulo int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, 1847*e28a4053SRui Paulo char *buf, size_t buflen) 1848*e28a4053SRui Paulo { 1849*e28a4053SRui Paulo int len = 0, ret; 1850*e28a4053SRui Paulo struct eapol_state_machine *sm = sta->eapol_sm; 1851*e28a4053SRui Paulo 1852*e28a4053SRui Paulo if (sm == NULL) 1853*e28a4053SRui Paulo return 0; 1854*e28a4053SRui Paulo 1855*e28a4053SRui Paulo ret = os_snprintf(buf + len, buflen - len, 1856*e28a4053SRui Paulo "dot1xPaePortNumber=%d\n" 1857*e28a4053SRui Paulo "dot1xPaePortProtocolVersion=%d\n" 1858*e28a4053SRui Paulo "dot1xPaePortCapabilities=1\n" 1859*e28a4053SRui Paulo "dot1xPaePortInitialize=%d\n" 1860*e28a4053SRui Paulo "dot1xPaePortReauthenticate=FALSE\n", 1861*e28a4053SRui Paulo sta->aid, 1862*e28a4053SRui Paulo EAPOL_VERSION, 1863*e28a4053SRui Paulo sm->initialize); 1864*e28a4053SRui Paulo if (ret < 0 || (size_t) ret >= buflen - len) 1865*e28a4053SRui Paulo return len; 1866*e28a4053SRui Paulo len += ret; 1867*e28a4053SRui Paulo 1868*e28a4053SRui Paulo /* dot1xAuthConfigTable */ 1869*e28a4053SRui Paulo ret = os_snprintf(buf + len, buflen - len, 1870*e28a4053SRui Paulo "dot1xAuthPaeState=%d\n" 1871*e28a4053SRui Paulo "dot1xAuthBackendAuthState=%d\n" 1872*e28a4053SRui Paulo "dot1xAuthAdminControlledDirections=%d\n" 1873*e28a4053SRui Paulo "dot1xAuthOperControlledDirections=%d\n" 1874*e28a4053SRui Paulo "dot1xAuthAuthControlledPortStatus=%d\n" 1875*e28a4053SRui Paulo "dot1xAuthAuthControlledPortControl=%d\n" 1876*e28a4053SRui Paulo "dot1xAuthQuietPeriod=%u\n" 1877*e28a4053SRui Paulo "dot1xAuthServerTimeout=%u\n" 1878*e28a4053SRui Paulo "dot1xAuthReAuthPeriod=%u\n" 1879*e28a4053SRui Paulo "dot1xAuthReAuthEnabled=%s\n" 1880*e28a4053SRui Paulo "dot1xAuthKeyTxEnabled=%s\n", 1881*e28a4053SRui Paulo sm->auth_pae_state + 1, 1882*e28a4053SRui Paulo sm->be_auth_state + 1, 1883*e28a4053SRui Paulo sm->adminControlledDirections, 1884*e28a4053SRui Paulo sm->operControlledDirections, 1885*e28a4053SRui Paulo sm->authPortStatus, 1886*e28a4053SRui Paulo sm->portControl, 1887*e28a4053SRui Paulo sm->quietPeriod, 1888*e28a4053SRui Paulo sm->serverTimeout, 1889*e28a4053SRui Paulo sm->reAuthPeriod, 1890*e28a4053SRui Paulo bool_txt(sm->reAuthEnabled), 1891*e28a4053SRui Paulo bool_txt(sm->keyTxEnabled)); 1892*e28a4053SRui Paulo if (ret < 0 || (size_t) ret >= buflen - len) 1893*e28a4053SRui Paulo return len; 1894*e28a4053SRui Paulo len += ret; 1895*e28a4053SRui Paulo 1896*e28a4053SRui Paulo /* dot1xAuthStatsTable */ 1897*e28a4053SRui Paulo ret = os_snprintf(buf + len, buflen - len, 1898*e28a4053SRui Paulo "dot1xAuthEapolFramesRx=%u\n" 1899*e28a4053SRui Paulo "dot1xAuthEapolFramesTx=%u\n" 1900*e28a4053SRui Paulo "dot1xAuthEapolStartFramesRx=%u\n" 1901*e28a4053SRui Paulo "dot1xAuthEapolLogoffFramesRx=%u\n" 1902*e28a4053SRui Paulo "dot1xAuthEapolRespIdFramesRx=%u\n" 1903*e28a4053SRui Paulo "dot1xAuthEapolRespFramesRx=%u\n" 1904*e28a4053SRui Paulo "dot1xAuthEapolReqIdFramesTx=%u\n" 1905*e28a4053SRui Paulo "dot1xAuthEapolReqFramesTx=%u\n" 1906*e28a4053SRui Paulo "dot1xAuthInvalidEapolFramesRx=%u\n" 1907*e28a4053SRui Paulo "dot1xAuthEapLengthErrorFramesRx=%u\n" 1908*e28a4053SRui Paulo "dot1xAuthLastEapolFrameVersion=%u\n" 1909*e28a4053SRui Paulo "dot1xAuthLastEapolFrameSource=" MACSTR "\n", 1910*e28a4053SRui Paulo sm->dot1xAuthEapolFramesRx, 1911*e28a4053SRui Paulo sm->dot1xAuthEapolFramesTx, 1912*e28a4053SRui Paulo sm->dot1xAuthEapolStartFramesRx, 1913*e28a4053SRui Paulo sm->dot1xAuthEapolLogoffFramesRx, 1914*e28a4053SRui Paulo sm->dot1xAuthEapolRespIdFramesRx, 1915*e28a4053SRui Paulo sm->dot1xAuthEapolRespFramesRx, 1916*e28a4053SRui Paulo sm->dot1xAuthEapolReqIdFramesTx, 1917*e28a4053SRui Paulo sm->dot1xAuthEapolReqFramesTx, 1918*e28a4053SRui Paulo sm->dot1xAuthInvalidEapolFramesRx, 1919*e28a4053SRui Paulo sm->dot1xAuthEapLengthErrorFramesRx, 1920*e28a4053SRui Paulo sm->dot1xAuthLastEapolFrameVersion, 1921*e28a4053SRui Paulo MAC2STR(sm->addr)); 1922*e28a4053SRui Paulo if (ret < 0 || (size_t) ret >= buflen - len) 1923*e28a4053SRui Paulo return len; 1924*e28a4053SRui Paulo len += ret; 1925*e28a4053SRui Paulo 1926*e28a4053SRui Paulo /* dot1xAuthDiagTable */ 1927*e28a4053SRui Paulo ret = os_snprintf(buf + len, buflen - len, 1928*e28a4053SRui Paulo "dot1xAuthEntersConnecting=%u\n" 1929*e28a4053SRui Paulo "dot1xAuthEapLogoffsWhileConnecting=%u\n" 1930*e28a4053SRui Paulo "dot1xAuthEntersAuthenticating=%u\n" 1931*e28a4053SRui Paulo "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n" 1932*e28a4053SRui Paulo "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n" 1933*e28a4053SRui Paulo "dot1xAuthAuthFailWhileAuthenticating=%u\n" 1934*e28a4053SRui Paulo "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n" 1935*e28a4053SRui Paulo "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n" 1936*e28a4053SRui Paulo "dot1xAuthAuthReauthsWhileAuthenticated=%u\n" 1937*e28a4053SRui Paulo "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n" 1938*e28a4053SRui Paulo "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n" 1939*e28a4053SRui Paulo "dot1xAuthBackendResponses=%u\n" 1940*e28a4053SRui Paulo "dot1xAuthBackendAccessChallenges=%u\n" 1941*e28a4053SRui Paulo "dot1xAuthBackendOtherRequestsToSupplicant=%u\n" 1942*e28a4053SRui Paulo "dot1xAuthBackendAuthSuccesses=%u\n" 1943*e28a4053SRui Paulo "dot1xAuthBackendAuthFails=%u\n", 1944*e28a4053SRui Paulo sm->authEntersConnecting, 1945*e28a4053SRui Paulo sm->authEapLogoffsWhileConnecting, 1946*e28a4053SRui Paulo sm->authEntersAuthenticating, 1947*e28a4053SRui Paulo sm->authAuthSuccessesWhileAuthenticating, 1948*e28a4053SRui Paulo sm->authAuthTimeoutsWhileAuthenticating, 1949*e28a4053SRui Paulo sm->authAuthFailWhileAuthenticating, 1950*e28a4053SRui Paulo sm->authAuthEapStartsWhileAuthenticating, 1951*e28a4053SRui Paulo sm->authAuthEapLogoffWhileAuthenticating, 1952*e28a4053SRui Paulo sm->authAuthReauthsWhileAuthenticated, 1953*e28a4053SRui Paulo sm->authAuthEapStartsWhileAuthenticated, 1954*e28a4053SRui Paulo sm->authAuthEapLogoffWhileAuthenticated, 1955*e28a4053SRui Paulo sm->backendResponses, 1956*e28a4053SRui Paulo sm->backendAccessChallenges, 1957*e28a4053SRui Paulo sm->backendOtherRequestsToSupplicant, 1958*e28a4053SRui Paulo sm->backendAuthSuccesses, 1959*e28a4053SRui Paulo sm->backendAuthFails); 1960*e28a4053SRui Paulo if (ret < 0 || (size_t) ret >= buflen - len) 1961*e28a4053SRui Paulo return len; 1962*e28a4053SRui Paulo len += ret; 1963*e28a4053SRui Paulo 1964*e28a4053SRui Paulo /* dot1xAuthSessionStatsTable */ 1965*e28a4053SRui Paulo ret = os_snprintf(buf + len, buflen - len, 1966*e28a4053SRui Paulo /* TODO: dot1xAuthSessionOctetsRx */ 1967*e28a4053SRui Paulo /* TODO: dot1xAuthSessionOctetsTx */ 1968*e28a4053SRui Paulo /* TODO: dot1xAuthSessionFramesRx */ 1969*e28a4053SRui Paulo /* TODO: dot1xAuthSessionFramesTx */ 1970*e28a4053SRui Paulo "dot1xAuthSessionId=%08X-%08X\n" 1971*e28a4053SRui Paulo "dot1xAuthSessionAuthenticMethod=%d\n" 1972*e28a4053SRui Paulo "dot1xAuthSessionTime=%u\n" 1973*e28a4053SRui Paulo "dot1xAuthSessionTerminateCause=999\n" 1974*e28a4053SRui Paulo "dot1xAuthSessionUserName=%s\n", 1975*e28a4053SRui Paulo sta->acct_session_id_hi, sta->acct_session_id_lo, 1976*e28a4053SRui Paulo (wpa_key_mgmt_wpa_ieee8021x( 1977*e28a4053SRui Paulo wpa_auth_sta_key_mgmt(sta->wpa_sm))) ? 1978*e28a4053SRui Paulo 1 : 2, 1979*e28a4053SRui Paulo (unsigned int) (time(NULL) - 1980*e28a4053SRui Paulo sta->acct_session_start), 1981*e28a4053SRui Paulo sm->identity); 1982*e28a4053SRui Paulo if (ret < 0 || (size_t) ret >= buflen - len) 1983*e28a4053SRui Paulo return len; 1984*e28a4053SRui Paulo len += ret; 1985*e28a4053SRui Paulo 1986*e28a4053SRui Paulo return len; 1987*e28a4053SRui Paulo } 1988*e28a4053SRui Paulo 1989*e28a4053SRui Paulo 1990*e28a4053SRui Paulo static void ieee802_1x_finished(struct hostapd_data *hapd, 1991*e28a4053SRui Paulo struct sta_info *sta, int success) 1992*e28a4053SRui Paulo { 1993*e28a4053SRui Paulo const u8 *key; 1994*e28a4053SRui Paulo size_t len; 1995*e28a4053SRui Paulo /* TODO: get PMKLifetime from WPA parameters */ 1996*e28a4053SRui Paulo static const int dot11RSNAConfigPMKLifetime = 43200; 1997*e28a4053SRui Paulo 1998*e28a4053SRui Paulo key = ieee802_1x_get_key(sta->eapol_sm, &len); 1999*e28a4053SRui Paulo if (success && key && len >= PMK_LEN && 2000*e28a4053SRui Paulo wpa_auth_pmksa_add(sta->wpa_sm, key, dot11RSNAConfigPMKLifetime, 2001*e28a4053SRui Paulo sta->eapol_sm) == 0) { 2002*e28a4053SRui Paulo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 2003*e28a4053SRui Paulo HOSTAPD_LEVEL_DEBUG, 2004*e28a4053SRui Paulo "Added PMKSA cache entry (IEEE 802.1X)"); 2005*e28a4053SRui Paulo } 2006*e28a4053SRui Paulo 2007*e28a4053SRui Paulo #ifdef CONFIG_WPS 2008*e28a4053SRui Paulo if (!success && (sta->flags & WLAN_STA_WPS)) { 2009*e28a4053SRui Paulo /* 2010*e28a4053SRui Paulo * Many devices require deauthentication after WPS provisioning 2011*e28a4053SRui Paulo * and some may not be be able to do that themselves, so 2012*e28a4053SRui Paulo * disconnect the client here. 2013*e28a4053SRui Paulo */ 2014*e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "WPS: Force disconnection after " 2015*e28a4053SRui Paulo "EAP-Failure"); 2016*e28a4053SRui Paulo /* Add a small sleep to increase likelihood of previously 2017*e28a4053SRui Paulo * requested EAP-Failure TX getting out before this should the 2018*e28a4053SRui Paulo * driver reorder operations. 2019*e28a4053SRui Paulo */ 2020*e28a4053SRui Paulo os_sleep(0, 10000); 2021*e28a4053SRui Paulo ap_sta_disconnect(hapd, sta, sta->addr, 2022*e28a4053SRui Paulo WLAN_REASON_PREV_AUTH_NOT_VALID); 2023*e28a4053SRui Paulo } 2024*e28a4053SRui Paulo #endif /* CONFIG_WPS */ 2025*e28a4053SRui Paulo } 2026