00001
00016 #include "includes.h"
00017
00018 #include "hostapd.h"
00019 #include "ieee802_1x.h"
00020 #include "accounting.h"
00021 #include "radius/radius.h"
00022 #include "radius/radius_client.h"
00023 #include "eapol_sm.h"
00024 #include "md5.h"
00025 #include "crypto.h"
00026 #include "eloop.h"
00027 #include "sta_info.h"
00028 #include "wpa.h"
00029 #include "preauth.h"
00030 #include "pmksa_cache.h"
00031 #include "driver_i.h"
00032 #include "hw_features.h"
00033 #include "eap_server/eap.h"
00034 #include "ieee802_11_defs.h"
00035 #include "wpa_ctrl.h"
00036
00037
00038 static void ieee802_1x_finished(struct hostapd_data *hapd,
00039 struct sta_info *sta, int success);
00040
00041
00042 static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
00043 u8 type, const u8 *data, size_t datalen)
00044 {
00045 u8 *buf;
00046 struct ieee802_1x_hdr *xhdr;
00047 size_t len;
00048 int encrypt = 0;
00049
00050 len = sizeof(*xhdr) + datalen;
00051 buf = os_zalloc(len);
00052 if (buf == NULL) {
00053 wpa_printf(MSG_ERROR, "malloc() failed for "
00054 "ieee802_1x_send(len=%lu)",
00055 (unsigned long) len);
00056 return;
00057 }
00058
00059 xhdr = (struct ieee802_1x_hdr *) buf;
00060 xhdr->version = hapd->conf->eapol_version;
00061 xhdr->type = type;
00062 xhdr->length = host_to_be16(datalen);
00063
00064 if (datalen > 0 && data != NULL)
00065 os_memcpy(xhdr + 1, data, datalen);
00066
00067 if (wpa_auth_pairwise_set(sta->wpa_sm))
00068 encrypt = 1;
00069 if (sta->flags & WLAN_STA_PREAUTH) {
00070 rsn_preauth_send(hapd, sta, buf, len);
00071 } else {
00072 hostapd_send_eapol(hapd, sta->addr, buf, len, encrypt);
00073 }
00074
00075 os_free(buf);
00076 }
00077
00078
00079 void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
00080 struct sta_info *sta, int authorized)
00081 {
00082 int res;
00083
00084 if (sta->flags & WLAN_STA_PREAUTH)
00085 return;
00086
00087 if (authorized) {
00088 if (!(sta->flags & WLAN_STA_AUTHORIZED))
00089 wpa_msg(hapd->msg_ctx, MSG_INFO,
00090 AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
00091 sta->flags |= WLAN_STA_AUTHORIZED;
00092 res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
00093 WLAN_STA_AUTHORIZED, ~0);
00094 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00095 HOSTAPD_LEVEL_DEBUG, "authorizing port");
00096 } else {
00097 if ((sta->flags & (WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC)) ==
00098 (WLAN_STA_AUTHORIZED | WLAN_STA_ASSOC))
00099 wpa_msg(hapd->msg_ctx, MSG_INFO,
00100 AP_STA_DISCONNECTED MACSTR,
00101 MAC2STR(sta->addr));
00102 sta->flags &= ~WLAN_STA_AUTHORIZED;
00103 res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
00104 0, ~WLAN_STA_AUTHORIZED);
00105 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00106 HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
00107 }
00108
00109 if (res && errno != ENOENT) {
00110 printf("Could not set station " MACSTR " flags for kernel "
00111 "driver (errno=%d).\n", MAC2STR(sta->addr), errno);
00112 }
00113
00114 if (authorized)
00115 accounting_sta_start(hapd, sta);
00116 }
00117
00118
00119 static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
00120 struct sta_info *sta,
00121 int idx, int broadcast,
00122 u8 *key_data, size_t key_len)
00123 {
00124 u8 *buf, *ekey;
00125 struct ieee802_1x_hdr *hdr;
00126 struct ieee802_1x_eapol_key *key;
00127 size_t len, ekey_len;
00128 struct eapol_state_machine *sm = sta->eapol_sm;
00129
00130 if (sm == NULL)
00131 return;
00132
00133 len = sizeof(*key) + key_len;
00134 buf = os_zalloc(sizeof(*hdr) + len);
00135 if (buf == NULL)
00136 return;
00137
00138 hdr = (struct ieee802_1x_hdr *) buf;
00139 key = (struct ieee802_1x_eapol_key *) (hdr + 1);
00140 key->type = EAPOL_KEY_TYPE_RC4;
00141 key->key_length = htons(key_len);
00142 wpa_get_ntp_timestamp(key->replay_counter);
00143
00144 if (os_get_random(key->key_iv, sizeof(key->key_iv))) {
00145 wpa_printf(MSG_ERROR, "Could not get random numbers");
00146 os_free(buf);
00147 return;
00148 }
00149
00150 key->key_index = idx | (broadcast ? 0 : BIT(7));
00151 if (hapd->conf->eapol_key_index_workaround) {
00152
00153
00154
00155
00156 key->key_index |= BIT(7);
00157 }
00158
00159
00160
00161 if (sm->eap_if->eapKeyData == NULL || sm->eap_if->eapKeyDataLen < 64) {
00162 wpa_printf(MSG_ERROR, "No eapKeyData available for encrypting "
00163 "and signing EAPOL-Key");
00164 os_free(buf);
00165 return;
00166 }
00167 os_memcpy((u8 *) (key + 1), key_data, key_len);
00168 ekey_len = sizeof(key->key_iv) + 32;
00169 ekey = os_malloc(ekey_len);
00170 if (ekey == NULL) {
00171 wpa_printf(MSG_ERROR, "Could not encrypt key");
00172 os_free(buf);
00173 return;
00174 }
00175 os_memcpy(ekey, key->key_iv, sizeof(key->key_iv));
00176 os_memcpy(ekey + sizeof(key->key_iv), sm->eap_if->eapKeyData, 32);
00177 rc4_skip(ekey, ekey_len, 0, (u8 *) (key + 1), key_len);
00178 os_free(ekey);
00179
00180
00181
00182 hdr->version = hapd->conf->eapol_version;
00183 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
00184 hdr->length = host_to_be16(len);
00185 hmac_md5(sm->eap_if->eapKeyData + 32, 32, buf, sizeof(*hdr) + len,
00186 key->key_signature);
00187
00188 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR
00189 " (%s index=%d)", MAC2STR(sm->addr),
00190 broadcast ? "broadcast" : "unicast", idx);
00191 ieee802_1x_send(hapd, sta, IEEE802_1X_TYPE_EAPOL_KEY, (u8 *) key, len);
00192 if (sta->eapol_sm)
00193 sta->eapol_sm->dot1xAuthEapolFramesTx++;
00194 os_free(buf);
00195 }
00196
00197
00198 #ifndef CONFIG_NO_VLAN
00199 static struct hostapd_wep_keys *
00200 ieee802_1x_group_alloc(struct hostapd_data *hapd, const char *ifname)
00201 {
00202 struct hostapd_wep_keys *key;
00203
00204 key = os_zalloc(sizeof(*key));
00205 if (key == NULL)
00206 return NULL;
00207
00208 key->default_len = hapd->conf->default_wep_key_len;
00209
00210 if (key->idx >= hapd->conf->broadcast_key_idx_max ||
00211 key->idx < hapd->conf->broadcast_key_idx_min)
00212 key->idx = hapd->conf->broadcast_key_idx_min;
00213 else
00214 key->idx++;
00215
00216 if (!key->key[key->idx])
00217 key->key[key->idx] = os_malloc(key->default_len);
00218 if (key->key[key->idx] == NULL ||
00219 os_get_random(key->key[key->idx], key->default_len)) {
00220 printf("Could not generate random WEP key (dynamic VLAN).\n");
00221 os_free(key->key[key->idx]);
00222 key->key[key->idx] = NULL;
00223 os_free(key);
00224 return NULL;
00225 }
00226 key->len[key->idx] = key->default_len;
00227
00228 wpa_printf(MSG_DEBUG, "%s: Default WEP idx %d for dynamic VLAN\n",
00229 ifname, key->idx);
00230 wpa_hexdump_key(MSG_DEBUG, "Default WEP key (dynamic VLAN)",
00231 key->key[key->idx], key->len[key->idx]);
00232
00233 if (hostapd_set_key(ifname, hapd, WPA_ALG_WEP, NULL, key->idx, 1,
00234 NULL, 0, key->key[key->idx], key->len[key->idx]))
00235 printf("Could not set dynamic VLAN WEP encryption key.\n");
00236
00237 hostapd_set_ieee8021x(ifname, hapd, 1);
00238
00239 return key;
00240 }
00241
00242
00243 static struct hostapd_wep_keys *
00244 ieee802_1x_get_group(struct hostapd_data *hapd, struct hostapd_ssid *ssid,
00245 size_t vlan_id)
00246 {
00247 const char *ifname;
00248
00249 if (vlan_id == 0)
00250 return &ssid->wep;
00251
00252 if (vlan_id <= ssid->max_dyn_vlan_keys && ssid->dyn_vlan_keys &&
00253 ssid->dyn_vlan_keys[vlan_id])
00254 return ssid->dyn_vlan_keys[vlan_id];
00255
00256 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Creating new group "
00257 "state machine for VLAN ID %lu",
00258 (unsigned long) vlan_id);
00259
00260 ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
00261 if (ifname == NULL) {
00262 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Unknown VLAN ID %lu - "
00263 "cannot create group key state machine",
00264 (unsigned long) vlan_id);
00265 return NULL;
00266 }
00267
00268 if (ssid->dyn_vlan_keys == NULL) {
00269 int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
00270 ssid->dyn_vlan_keys = os_zalloc(size);
00271 if (ssid->dyn_vlan_keys == NULL)
00272 return NULL;
00273 ssid->max_dyn_vlan_keys = vlan_id;
00274 }
00275
00276 if (ssid->max_dyn_vlan_keys < vlan_id) {
00277 struct hostapd_wep_keys **na;
00278 int size = (vlan_id + 1) * sizeof(ssid->dyn_vlan_keys[0]);
00279 na = os_realloc(ssid->dyn_vlan_keys, size);
00280 if (na == NULL)
00281 return NULL;
00282 ssid->dyn_vlan_keys = na;
00283 os_memset(&ssid->dyn_vlan_keys[ssid->max_dyn_vlan_keys + 1], 0,
00284 (vlan_id - ssid->max_dyn_vlan_keys) *
00285 sizeof(ssid->dyn_vlan_keys[0]));
00286 ssid->max_dyn_vlan_keys = vlan_id;
00287 }
00288
00289 ssid->dyn_vlan_keys[vlan_id] = ieee802_1x_group_alloc(hapd, ifname);
00290
00291 return ssid->dyn_vlan_keys[vlan_id];
00292 }
00293 #endif
00294
00295
00296 void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
00297 {
00298 struct eapol_authenticator *eapol = hapd->eapol_auth;
00299 struct eapol_state_machine *sm = sta->eapol_sm;
00300 #ifndef CONFIG_NO_VLAN
00301 struct hostapd_wep_keys *key = NULL;
00302 int vlan_id;
00303 #endif
00304
00305 if (sm == NULL || !sm->eap_if->eapKeyData)
00306 return;
00307
00308 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR,
00309 MAC2STR(sta->addr));
00310
00311 #ifndef CONFIG_NO_VLAN
00312 vlan_id = sta->vlan_id;
00313 if (vlan_id < 0 || vlan_id > MAX_VLAN_ID)
00314 vlan_id = 0;
00315
00316 if (vlan_id) {
00317 key = ieee802_1x_get_group(hapd, sta->ssid, vlan_id);
00318 if (key && key->key[key->idx])
00319 ieee802_1x_tx_key_one(hapd, sta, key->idx, 1,
00320 key->key[key->idx],
00321 key->len[key->idx]);
00322 } else
00323 #endif
00324 if (eapol->default_wep_key) {
00325 ieee802_1x_tx_key_one(hapd, sta, eapol->default_wep_key_idx, 1,
00326 eapol->default_wep_key,
00327 hapd->conf->default_wep_key_len);
00328 }
00329
00330 if (hapd->conf->individual_wep_key_len > 0) {
00331 u8 *ikey;
00332 ikey = os_malloc(hapd->conf->individual_wep_key_len);
00333 if (ikey == NULL ||
00334 os_get_random(ikey, hapd->conf->individual_wep_key_len)) {
00335 wpa_printf(MSG_ERROR, "Could not generate random "
00336 "individual WEP key.");
00337 os_free(ikey);
00338 return;
00339 }
00340
00341 wpa_hexdump_key(MSG_DEBUG, "Individual WEP key",
00342 ikey, hapd->conf->individual_wep_key_len);
00343
00344 ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey,
00345 hapd->conf->individual_wep_key_len);
00346
00347
00348
00349 if (hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
00350 sta->addr, 0, 1, NULL, 0, ikey,
00351 hapd->conf->individual_wep_key_len)) {
00352 wpa_printf(MSG_ERROR, "Could not set individual WEP "
00353 "encryption.");
00354 }
00355
00356 os_free(ikey);
00357 }
00358 }
00359
00360
00361 const char *radius_mode_txt(struct hostapd_data *hapd)
00362 {
00363 if (hapd->iface->current_mode == NULL)
00364 return "802.11";
00365
00366 switch (hapd->iface->current_mode->mode) {
00367 case HOSTAPD_MODE_IEEE80211A:
00368 return "802.11a";
00369 case HOSTAPD_MODE_IEEE80211G:
00370 return "802.11g";
00371 case HOSTAPD_MODE_IEEE80211B:
00372 default:
00373 return "802.11b";
00374 }
00375 }
00376
00377
00378 int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta)
00379 {
00380 int i;
00381 u8 rate = 0;
00382
00383 for (i = 0; i < sta->supported_rates_len; i++)
00384 if ((sta->supported_rates[i] & 0x7f) > rate)
00385 rate = sta->supported_rates[i] & 0x7f;
00386
00387 return rate;
00388 }
00389
00390
00391 #ifndef CONFIG_NO_RADIUS
00392 static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
00393 struct eapol_state_machine *sm,
00394 const u8 *eap, size_t len)
00395 {
00396 const u8 *identity;
00397 size_t identity_len;
00398
00399 if (len <= sizeof(struct eap_hdr) ||
00400 eap[sizeof(struct eap_hdr)] != EAP_TYPE_IDENTITY)
00401 return;
00402
00403 identity = eap_get_identity(sm->eap, &identity_len);
00404 if (identity == NULL)
00405 return;
00406
00407
00408 os_free(sm->identity);
00409 sm->identity = os_malloc(identity_len + 1);
00410 if (sm->identity == NULL) {
00411 sm->identity_len = 0;
00412 return;
00413 }
00414
00415 os_memcpy(sm->identity, identity, identity_len);
00416 sm->identity_len = identity_len;
00417 sm->identity[identity_len] = '\0';
00418 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
00419 HOSTAPD_LEVEL_DEBUG, "STA identity '%s'", sm->identity);
00420 sm->dot1xAuthEapolRespIdFramesRx++;
00421 }
00422
00423
00424 static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
00425 struct sta_info *sta,
00426 const u8 *eap, size_t len)
00427 {
00428 struct radius_msg *msg;
00429 char buf[128];
00430 struct eapol_state_machine *sm = sta->eapol_sm;
00431
00432 if (sm == NULL)
00433 return;
00434
00435 ieee802_1x_learn_identity(hapd, sm, eap, len);
00436
00437 wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
00438 "packet");
00439
00440 sm->radius_identifier = radius_client_get_id(hapd->radius);
00441 msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
00442 sm->radius_identifier);
00443 if (msg == NULL) {
00444 printf("Could not create net RADIUS packet\n");
00445 return;
00446 }
00447
00448 radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
00449
00450 if (sm->identity &&
00451 !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
00452 sm->identity, sm->identity_len)) {
00453 printf("Could not add User-Name\n");
00454 goto fail;
00455 }
00456
00457 if (hapd->conf->own_ip_addr.af == AF_INET &&
00458 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
00459 (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
00460 printf("Could not add NAS-IP-Address\n");
00461 goto fail;
00462 }
00463
00464 #ifdef CONFIG_IPV6
00465 if (hapd->conf->own_ip_addr.af == AF_INET6 &&
00466 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
00467 (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
00468 printf("Could not add NAS-IPv6-Address\n");
00469 goto fail;
00470 }
00471 #endif
00472
00473 if (hapd->conf->nas_identifier &&
00474 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
00475 (u8 *) hapd->conf->nas_identifier,
00476 os_strlen(hapd->conf->nas_identifier))) {
00477 printf("Could not add NAS-Identifier\n");
00478 goto fail;
00479 }
00480
00481 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
00482 printf("Could not add NAS-Port\n");
00483 goto fail;
00484 }
00485
00486 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
00487 MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
00488 buf[sizeof(buf) - 1] = '\0';
00489 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
00490 (u8 *) buf, os_strlen(buf))) {
00491 printf("Could not add Called-Station-Id\n");
00492 goto fail;
00493 }
00494
00495 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
00496 MAC2STR(sta->addr));
00497 buf[sizeof(buf) - 1] = '\0';
00498 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
00499 (u8 *) buf, os_strlen(buf))) {
00500 printf("Could not add Calling-Station-Id\n");
00501 goto fail;
00502 }
00503
00504
00505
00506
00507 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
00508 printf("Could not add Framed-MTU\n");
00509 goto fail;
00510 }
00511
00512 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
00513 RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
00514 printf("Could not add NAS-Port-Type\n");
00515 goto fail;
00516 }
00517
00518 if (sta->flags & WLAN_STA_PREAUTH) {
00519 os_strlcpy(buf, "IEEE 802.11i Pre-Authentication",
00520 sizeof(buf));
00521 } else {
00522 os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
00523 radius_sta_rate(hapd, sta) / 2,
00524 (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
00525 radius_mode_txt(hapd));
00526 buf[sizeof(buf) - 1] = '\0';
00527 }
00528 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
00529 (u8 *) buf, os_strlen(buf))) {
00530 printf("Could not add Connect-Info\n");
00531 goto fail;
00532 }
00533
00534 if (eap && !radius_msg_add_eap(msg, eap, len)) {
00535 printf("Could not add EAP-Message\n");
00536 goto fail;
00537 }
00538
00539
00540
00541 if (sm->last_recv_radius && sm->last_recv_radius->hdr->code ==
00542 RADIUS_CODE_ACCESS_CHALLENGE) {
00543 int res = radius_msg_copy_attr(msg, sm->last_recv_radius,
00544 RADIUS_ATTR_STATE);
00545 if (res < 0) {
00546 printf("Could not copy State attribute from previous "
00547 "Access-Challenge\n");
00548 goto fail;
00549 }
00550 if (res > 0) {
00551 wpa_printf(MSG_DEBUG, "Copied RADIUS State Attribute");
00552 }
00553 }
00554
00555 radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr);
00556 return;
00557
00558 fail:
00559 radius_msg_free(msg);
00560 os_free(msg);
00561 }
00562 #endif
00563
00564
00565 char *eap_type_text(u8 type)
00566 {
00567 switch (type) {
00568 case EAP_TYPE_IDENTITY: return "Identity";
00569 case EAP_TYPE_NOTIFICATION: return "Notification";
00570 case EAP_TYPE_NAK: return "Nak";
00571 case EAP_TYPE_MD5: return "MD5-Challenge";
00572 case EAP_TYPE_OTP: return "One-Time Password";
00573 case EAP_TYPE_GTC: return "Generic Token Card";
00574 case EAP_TYPE_TLS: return "TLS";
00575 case EAP_TYPE_TTLS: return "TTLS";
00576 case EAP_TYPE_PEAP: return "PEAP";
00577 case EAP_TYPE_SIM: return "SIM";
00578 case EAP_TYPE_FAST: return "FAST";
00579 case EAP_TYPE_SAKE: return "SAKE";
00580 case EAP_TYPE_PSK: return "PSK";
00581 case EAP_TYPE_PAX: return "PAX";
00582 default: return "Unknown";
00583 }
00584 }
00585
00586
00587 static void handle_eap_response(struct hostapd_data *hapd,
00588 struct sta_info *sta, struct eap_hdr *eap,
00589 size_t len)
00590 {
00591 u8 type, *data;
00592 struct eapol_state_machine *sm = sta->eapol_sm;
00593 if (sm == NULL)
00594 return;
00595
00596 data = (u8 *) (eap + 1);
00597
00598 if (len < sizeof(*eap) + 1) {
00599 printf("handle_eap_response: too short response data\n");
00600 return;
00601 }
00602
00603 sm->eap_type_supp = type = data[0];
00604
00605 hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
00606 HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
00607 "id=%d len=%d) from STA: EAP Response-%s (%d)",
00608 eap->code, eap->identifier, be_to_host16(eap->length),
00609 eap_type_text(type), type);
00610
00611 sm->dot1xAuthEapolRespFramesRx++;
00612
00613 wpabuf_free(sm->eap_if->eapRespData);
00614 sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);
00615 sm->eapolEap = TRUE;
00616 }
00617
00618
00619
00620 static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,
00621 u8 *buf, size_t len)
00622 {
00623 struct eap_hdr *eap;
00624 u16 eap_len;
00625
00626 if (len < sizeof(*eap)) {
00627 printf(" too short EAP packet\n");
00628 return;
00629 }
00630
00631 eap = (struct eap_hdr *) buf;
00632
00633 eap_len = be_to_host16(eap->length);
00634 wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d",
00635 eap->code, eap->identifier, eap_len);
00636 if (eap_len < sizeof(*eap)) {
00637 wpa_printf(MSG_DEBUG, " Invalid EAP length");
00638 return;
00639 } else if (eap_len > len) {
00640 wpa_printf(MSG_DEBUG, " Too short frame to contain this EAP "
00641 "packet");
00642 return;
00643 } else if (eap_len < len) {
00644 wpa_printf(MSG_DEBUG, " Ignoring %lu extra bytes after EAP "
00645 "packet", (unsigned long) len - eap_len);
00646 }
00647
00648 switch (eap->code) {
00649 case EAP_CODE_REQUEST:
00650 wpa_printf(MSG_DEBUG, " (request)");
00651 return;
00652 case EAP_CODE_RESPONSE:
00653 wpa_printf(MSG_DEBUG, " (response)");
00654 handle_eap_response(hapd, sta, eap, eap_len);
00655 break;
00656 case EAP_CODE_SUCCESS:
00657 wpa_printf(MSG_DEBUG, " (success)");
00658 return;
00659 case EAP_CODE_FAILURE:
00660 wpa_printf(MSG_DEBUG, " (failure)");
00661 return;
00662 default:
00663 wpa_printf(MSG_DEBUG, " (unknown code)");
00664 return;
00665 }
00666 }
00667
00668
00679 void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
00680 size_t len)
00681 {
00682 struct sta_info *sta;
00683 struct ieee802_1x_hdr *hdr;
00684 struct ieee802_1x_eapol_key *key;
00685 u16 datalen;
00686 struct rsn_pmksa_cache_entry *pmksa;
00687
00688 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
00689 !hapd->conf->wps_state)
00690 return;
00691
00692 wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,
00693 (unsigned long) len, MAC2STR(sa));
00694 sta = ap_get_sta(hapd, sa);
00695 if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
00696 wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
00697 "associated STA");
00698 return;
00699 }
00700
00701 if (len < sizeof(*hdr)) {
00702 printf(" too short IEEE 802.1X packet\n");
00703 return;
00704 }
00705
00706 hdr = (struct ieee802_1x_hdr *) buf;
00707 datalen = be_to_host16(hdr->length);
00708 wpa_printf(MSG_DEBUG, " IEEE 802.1X: version=%d type=%d length=%d",
00709 hdr->version, hdr->type, datalen);
00710
00711 if (len - sizeof(*hdr) < datalen) {
00712 printf(" frame too short for this IEEE 802.1X packet\n");
00713 if (sta->eapol_sm)
00714 sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++;
00715 return;
00716 }
00717 if (len - sizeof(*hdr) > datalen) {
00718 wpa_printf(MSG_DEBUG, " ignoring %lu extra octets after "
00719 "IEEE 802.1X packet",
00720 (unsigned long) len - sizeof(*hdr) - datalen);
00721 }
00722
00723 if (sta->eapol_sm) {
00724 sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version;
00725 sta->eapol_sm->dot1xAuthEapolFramesRx++;
00726 }
00727
00728 key = (struct ieee802_1x_eapol_key *) (hdr + 1);
00729 if (datalen >= sizeof(struct ieee802_1x_eapol_key) &&
00730 hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&
00731 (key->type == EAPOL_KEY_TYPE_WPA ||
00732 key->type == EAPOL_KEY_TYPE_RSN)) {
00733 wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr,
00734 sizeof(*hdr) + datalen);
00735 return;
00736 }
00737
00738 if ((!hapd->conf->ieee802_1x &&
00739 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) ||
00740 wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))
00741 return;
00742
00743 if (!sta->eapol_sm) {
00744 sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,
00745 sta->flags & WLAN_STA_PREAUTH,
00746 sta);
00747 if (!sta->eapol_sm)
00748 return;
00749
00750 #ifdef CONFIG_WPS
00751 if (!hapd->conf->ieee802_1x &&
00752 ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==
00753 WLAN_STA_MAYBE_WPS)) {
00754
00755
00756
00757
00758 sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;
00759 }
00760 #endif
00761
00762 sta->eapol_sm->eap_if->portEnabled = TRUE;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772 switch (hdr->type) {
00773 case IEEE802_1X_TYPE_EAP_PACKET:
00774 handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);
00775 break;
00776
00777 case IEEE802_1X_TYPE_EAPOL_START:
00778 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00779 HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start "
00780 "from STA");
00781 sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
00782 pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
00783 if (pmksa) {
00784 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
00785 HOSTAPD_LEVEL_DEBUG, "cached PMKSA "
00786 "available - ignore it since "
00787 "STA sent EAPOL-Start");
00788 wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa);
00789 }
00790 sta->eapol_sm->eapolStart = TRUE;
00791 sta->eapol_sm->dot1xAuthEapolStartFramesRx++;
00792 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);
00793 break;
00794
00795 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
00796 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00797 HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff "
00798 "from STA");
00799 sta->acct_terminate_cause =
00800 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
00801 accounting_sta_stop(hapd, sta);
00802 sta->eapol_sm->eapolLogoff = TRUE;
00803 sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++;
00804 break;
00805
00806 case IEEE802_1X_TYPE_EAPOL_KEY:
00807 wpa_printf(MSG_DEBUG, " EAPOL-Key");
00808 if (!(sta->flags & WLAN_STA_AUTHORIZED)) {
00809 wpa_printf(MSG_DEBUG, " Dropped key data from "
00810 "unauthorized Supplicant");
00811 break;
00812 }
00813 break;
00814
00815 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
00816 wpa_printf(MSG_DEBUG, " EAPOL-Encapsulated-ASF-Alert");
00817
00818 break;
00819
00820 default:
00821 wpa_printf(MSG_DEBUG, " unknown IEEE 802.1X packet type");
00822 sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++;
00823 break;
00824 }
00825
00826 eapol_auth_step(sta->eapol_sm);
00827 }
00828
00829
00839 void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
00840 {
00841 struct rsn_pmksa_cache_entry *pmksa;
00842 int reassoc = 1;
00843 int force_1x = 0;
00844
00845 #ifdef CONFIG_WPS
00846 if (hapd->conf->wps_state && hapd->conf->wpa &&
00847 (sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
00848
00849
00850
00851
00852
00853 force_1x = 1;
00854 }
00855 #endif
00856
00857 if ((!force_1x && !hapd->conf->ieee802_1x) ||
00858 wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))
00859 return;
00860
00861 if (sta->eapol_sm == NULL) {
00862 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00863 HOSTAPD_LEVEL_DEBUG, "start authentication");
00864 sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,
00865 sta->flags & WLAN_STA_PREAUTH,
00866 sta);
00867 if (sta->eapol_sm == NULL) {
00868 hostapd_logger(hapd, sta->addr,
00869 HOSTAPD_MODULE_IEEE8021X,
00870 HOSTAPD_LEVEL_INFO,
00871 "failed to allocate state machine");
00872 return;
00873 }
00874 reassoc = 0;
00875 }
00876
00877 #ifdef CONFIG_WPS
00878 sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
00879 if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) {
00880
00881
00882
00883
00884 sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;
00885 }
00886 #endif
00887
00888 sta->eapol_sm->eap_if->portEnabled = TRUE;
00889
00890 pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
00891 if (pmksa) {
00892 int old_vlanid;
00893
00894 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00895 HOSTAPD_LEVEL_DEBUG,
00896 "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
00897
00898
00899 sta->eapol_sm->keyRun = TRUE;
00900 sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;
00901 sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
00902 sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
00903 sta->eapol_sm->authSuccess = TRUE;
00904 if (sta->eapol_sm->eap)
00905 eap_sm_notify_cached(sta->eapol_sm->eap);
00906 old_vlanid = sta->vlan_id;
00907 pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm);
00908 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
00909 sta->vlan_id = 0;
00910 ap_sta_bind_vlan(hapd, sta, old_vlanid);
00911 } else {
00912 if (reassoc) {
00913
00914
00915
00916
00917
00918 sta->eapol_sm->reAuthenticate = TRUE;
00919 }
00920 eapol_auth_step(sta->eapol_sm);
00921 }
00922 }
00923
00924
00925 void ieee802_1x_free_station(struct sta_info *sta)
00926 {
00927 struct eapol_state_machine *sm = sta->eapol_sm;
00928
00929 if (sm == NULL)
00930 return;
00931
00932 sta->eapol_sm = NULL;
00933
00934 #ifndef CONFIG_NO_RADIUS
00935 if (sm->last_recv_radius) {
00936 radius_msg_free(sm->last_recv_radius);
00937 os_free(sm->last_recv_radius);
00938 }
00939 radius_free_class(&sm->radius_class);
00940 #endif
00941
00942 os_free(sm->identity);
00943 eapol_auth_free(sm);
00944 }
00945
00946
00947 #ifndef CONFIG_NO_RADIUS
00948 static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
00949 struct sta_info *sta)
00950 {
00951 u8 *eap;
00952 size_t len;
00953 struct eap_hdr *hdr;
00954 int eap_type = -1;
00955 char buf[64];
00956 struct radius_msg *msg;
00957 struct eapol_state_machine *sm = sta->eapol_sm;
00958
00959 if (sm == NULL || sm->last_recv_radius == NULL) {
00960 if (sm)
00961 sm->eap_if->aaaEapNoReq = TRUE;
00962 return;
00963 }
00964
00965 msg = sm->last_recv_radius;
00966
00967 eap = radius_msg_get_eap(msg, &len);
00968 if (eap == NULL) {
00969
00970
00971
00972 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00973 HOSTAPD_LEVEL_WARNING, "could not extract "
00974 "EAP-Message from RADIUS message");
00975 sm->eap_if->aaaEapNoReq = TRUE;
00976 return;
00977 }
00978
00979 if (len < sizeof(*hdr)) {
00980 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
00981 HOSTAPD_LEVEL_WARNING, "too short EAP packet "
00982 "received from authentication server");
00983 os_free(eap);
00984 sm->eap_if->aaaEapNoReq = TRUE;
00985 return;
00986 }
00987
00988 if (len > sizeof(*hdr))
00989 eap_type = eap[sizeof(*hdr)];
00990
00991 hdr = (struct eap_hdr *) eap;
00992 switch (hdr->code) {
00993 case EAP_CODE_REQUEST:
00994 if (eap_type >= 0)
00995 sm->eap_type_authsrv = eap_type;
00996 os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
00997 eap_type >= 0 ? eap_type_text(eap_type) : "??",
00998 eap_type);
00999 break;
01000 case EAP_CODE_RESPONSE:
01001 os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
01002 eap_type >= 0 ? eap_type_text(eap_type) : "??",
01003 eap_type);
01004 break;
01005 case EAP_CODE_SUCCESS:
01006 os_strlcpy(buf, "EAP Success", sizeof(buf));
01007 break;
01008 case EAP_CODE_FAILURE:
01009 os_strlcpy(buf, "EAP Failure", sizeof(buf));
01010 break;
01011 default:
01012 os_strlcpy(buf, "unknown EAP code", sizeof(buf));
01013 break;
01014 }
01015 buf[sizeof(buf) - 1] = '\0';
01016 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
01017 HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d "
01018 "id=%d len=%d) from RADIUS server: %s",
01019 hdr->code, hdr->identifier, be_to_host16(hdr->length),
01020 buf);
01021 sm->eap_if->aaaEapReq = TRUE;
01022
01023 wpabuf_free(sm->eap_if->aaaEapReqData);
01024 sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len);
01025 }
01026
01027
01028 static void ieee802_1x_get_keys(struct hostapd_data *hapd,
01029 struct sta_info *sta, struct radius_msg *msg,
01030 struct radius_msg *req,
01031 const u8 *shared_secret,
01032 size_t shared_secret_len)
01033 {
01034 struct radius_ms_mppe_keys *keys;
01035 struct eapol_state_machine *sm = sta->eapol_sm;
01036 if (sm == NULL)
01037 return;
01038
01039 keys = radius_msg_get_ms_keys(msg, req, shared_secret,
01040 shared_secret_len);
01041
01042 if (keys && keys->send && keys->recv) {
01043 size_t len = keys->send_len + keys->recv_len;
01044 wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key",
01045 keys->send, keys->send_len);
01046 wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key",
01047 keys->recv, keys->recv_len);
01048
01049 os_free(sm->eap_if->aaaEapKeyData);
01050 sm->eap_if->aaaEapKeyData = os_malloc(len);
01051 if (sm->eap_if->aaaEapKeyData) {
01052 os_memcpy(sm->eap_if->aaaEapKeyData, keys->recv,
01053 keys->recv_len);
01054 os_memcpy(sm->eap_if->aaaEapKeyData + keys->recv_len,
01055 keys->send, keys->send_len);
01056 sm->eap_if->aaaEapKeyDataLen = len;
01057 sm->eap_if->aaaEapKeyAvailable = TRUE;
01058 }
01059 }
01060
01061 if (keys) {
01062 os_free(keys->send);
01063 os_free(keys->recv);
01064 os_free(keys);
01065 }
01066 }
01067
01068
01069 static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,
01070 struct sta_info *sta,
01071 struct radius_msg *msg)
01072 {
01073 u8 *class;
01074 size_t class_len;
01075 struct eapol_state_machine *sm = sta->eapol_sm;
01076 int count, i;
01077 struct radius_attr_data *nclass;
01078 size_t nclass_count;
01079
01080 if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
01081 sm == NULL)
01082 return;
01083
01084 radius_free_class(&sm->radius_class);
01085 count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
01086 if (count <= 0)
01087 return;
01088
01089 nclass = os_zalloc(count * sizeof(struct radius_attr_data));
01090 if (nclass == NULL)
01091 return;
01092
01093 nclass_count = 0;
01094
01095 class = NULL;
01096 for (i = 0; i < count; i++) {
01097 do {
01098 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS,
01099 &class, &class_len,
01100 class) < 0) {
01101 i = count;
01102 break;
01103 }
01104 } while (class_len < 1);
01105
01106 nclass[nclass_count].data = os_malloc(class_len);
01107 if (nclass[nclass_count].data == NULL)
01108 break;
01109
01110 os_memcpy(nclass[nclass_count].data, class, class_len);
01111 nclass[nclass_count].len = class_len;
01112 nclass_count++;
01113 }
01114
01115 sm->radius_class.attr = nclass;
01116 sm->radius_class.count = nclass_count;
01117 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Stored %lu RADIUS Class "
01118 "attributes for " MACSTR,
01119 (unsigned long) sm->radius_class.count,
01120 MAC2STR(sta->addr));
01121 }
01122
01123
01124
01125 static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,
01126 struct sta_info *sta,
01127 struct radius_msg *msg)
01128 {
01129 u8 *buf, *identity;
01130 size_t len;
01131 struct eapol_state_machine *sm = sta->eapol_sm;
01132
01133 if (sm == NULL)
01134 return;
01135
01136 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len,
01137 NULL) < 0)
01138 return;
01139
01140 identity = os_malloc(len + 1);
01141 if (identity == NULL)
01142 return;
01143
01144 os_memcpy(identity, buf, len);
01145 identity[len] = '\0';
01146
01147 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
01148 HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "
01149 "User-Name from Access-Accept '%s'",
01150 sm->identity ? (char *) sm->identity : "N/A",
01151 (char *) identity);
01152
01153 os_free(sm->identity);
01154 sm->identity = identity;
01155 sm->identity_len = len;
01156 }
01157
01158
01159 struct sta_id_search {
01160 u8 identifier;
01161 struct eapol_state_machine *sm;
01162 };
01163
01164
01165 static int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd,
01166 struct sta_info *sta,
01167 void *ctx)
01168 {
01169 struct sta_id_search *id_search = ctx;
01170 struct eapol_state_machine *sm = sta->eapol_sm;
01171
01172 if (sm && sm->radius_identifier >= 0 &&
01173 sm->radius_identifier == id_search->identifier) {
01174 id_search->sm = sm;
01175 return 1;
01176 }
01177 return 0;
01178 }
01179
01180
01181 static struct eapol_state_machine *
01182 ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier)
01183 {
01184 struct sta_id_search id_search;
01185 id_search.identifier = identifier;
01186 id_search.sm = NULL;
01187 ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search);
01188 return id_search.sm;
01189 }
01190
01191
01202 static RadiusRxResult
01203 ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
01204 const u8 *shared_secret, size_t shared_secret_len,
01205 void *data)
01206 {
01207 struct hostapd_data *hapd = data;
01208 struct sta_info *sta;
01209 u32 session_timeout = 0, termination_action, acct_interim_interval;
01210 int session_timeout_set, old_vlanid = 0;
01211 struct eapol_state_machine *sm;
01212 int override_eapReq = 0;
01213
01214 sm = ieee802_1x_search_radius_identifier(hapd, msg->hdr->identifier);
01215 if (sm == NULL) {
01216 wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching "
01217 "station for this RADIUS message");
01218 return RADIUS_RX_UNKNOWN;
01219 }
01220 sta = sm->sta;
01221
01222
01223
01224 if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
01225 radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
01226 0) < 0 &&
01227 radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
01228 wpa_printf(MSG_DEBUG, "Allowing RADIUS Access-Reject without "
01229 "Message-Authenticator since it does not include "
01230 "EAP-Message");
01231 } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
01232 req, 1)) {
01233 printf("Incoming RADIUS packet did not have correct "
01234 "Message-Authenticator - dropped\n");
01235 return RADIUS_RX_INVALID_AUTHENTICATOR;
01236 }
01237
01238 if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
01239 msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
01240 msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
01241 printf("Unknown RADIUS message code\n");
01242 return RADIUS_RX_UNKNOWN;
01243 }
01244
01245 sm->radius_identifier = -1;
01246 wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR,
01247 MAC2STR(sta->addr));
01248
01249 if (sm->last_recv_radius) {
01250 radius_msg_free(sm->last_recv_radius);
01251 os_free(sm->last_recv_radius);
01252 }
01253
01254 sm->last_recv_radius = msg;
01255
01256 session_timeout_set =
01257 !radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
01258 &session_timeout);
01259 if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION,
01260 &termination_action))
01261 termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
01262
01263 if (hapd->conf->radius->acct_interim_interval == 0 &&
01264 msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
01265 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
01266 &acct_interim_interval) == 0) {
01267 if (acct_interim_interval < 60) {
01268 hostapd_logger(hapd, sta->addr,
01269 HOSTAPD_MODULE_IEEE8021X,
01270 HOSTAPD_LEVEL_INFO,
01271 "ignored too small "
01272 "Acct-Interim-Interval %d",
01273 acct_interim_interval);
01274 } else
01275 sta->acct_interim_interval = acct_interim_interval;
01276 }
01277
01278
01279 switch (msg->hdr->code) {
01280 case RADIUS_CODE_ACCESS_ACCEPT:
01281 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
01282 sta->vlan_id = 0;
01283 #ifndef CONFIG_NO_VLAN
01284 else {
01285 old_vlanid = sta->vlan_id;
01286 sta->vlan_id = radius_msg_get_vlanid(msg);
01287 }
01288 if (sta->vlan_id > 0 &&
01289 hostapd_get_vlan_id_ifname(hapd->conf->vlan,
01290 sta->vlan_id)) {
01291 hostapd_logger(hapd, sta->addr,
01292 HOSTAPD_MODULE_RADIUS,
01293 HOSTAPD_LEVEL_INFO,
01294 "VLAN ID %d", sta->vlan_id);
01295 } else if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_REQUIRED) {
01296 sta->eapol_sm->authFail = TRUE;
01297 hostapd_logger(hapd, sta->addr,
01298 HOSTAPD_MODULE_IEEE8021X,
01299 HOSTAPD_LEVEL_INFO, "authentication "
01300 "server did not include required VLAN "
01301 "ID in Access-Accept");
01302 break;
01303 }
01304 #endif
01305
01306 ap_sta_bind_vlan(hapd, sta, old_vlanid);
01307
01308
01309 if (session_timeout_set && termination_action ==
01310 RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
01311 sm->reAuthPeriod = session_timeout;
01312 } else if (session_timeout_set)
01313 ap_sta_session_timeout(hapd, sta, session_timeout);
01314
01315 sm->eap_if->aaaSuccess = TRUE;
01316 override_eapReq = 1;
01317 ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,
01318 shared_secret_len);
01319 ieee802_1x_store_radius_class(hapd, sta, msg);
01320 ieee802_1x_update_sta_identity(hapd, sta, msg);
01321 if (sm->eap_if->eapKeyAvailable &&
01322 wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt,
01323 session_timeout_set ?
01324 (int) session_timeout : -1, sm) == 0) {
01325 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
01326 HOSTAPD_LEVEL_DEBUG,
01327 "Added PMKSA cache entry");
01328 }
01329 break;
01330 case RADIUS_CODE_ACCESS_REJECT:
01331 sm->eap_if->aaaFail = TRUE;
01332 override_eapReq = 1;
01333 break;
01334 case RADIUS_CODE_ACCESS_CHALLENGE:
01335 sm->eap_if->aaaEapReq = TRUE;
01336 if (session_timeout_set) {
01337
01338 sm->eap_if->aaaMethodTimeout = session_timeout;
01339 hostapd_logger(hapd, sm->addr,
01340 HOSTAPD_MODULE_IEEE8021X,
01341 HOSTAPD_LEVEL_DEBUG,
01342 "using EAP timeout of %d seconds (from "
01343 "RADIUS)",
01344 sm->eap_if->aaaMethodTimeout);
01345 } else {
01346
01347
01348
01349
01350 sm->eap_if->aaaMethodTimeout = 0;
01351 }
01352 break;
01353 }
01354
01355 ieee802_1x_decapsulate_radius(hapd, sta);
01356 if (override_eapReq)
01357 sm->eap_if->aaaEapReq = FALSE;
01358
01359 eapol_auth_step(sm);
01360
01361 return RADIUS_RX_QUEUED;
01362 }
01363 #endif
01364
01365
01366 void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
01367 {
01368 struct eapol_state_machine *sm = sta->eapol_sm;
01369 if (sm == NULL)
01370 return;
01371
01372 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
01373 HOSTAPD_LEVEL_DEBUG, "aborting authentication");
01374
01375 #ifndef CONFIG_NO_RADIUS
01376 if (sm->last_recv_radius) {
01377 radius_msg_free(sm->last_recv_radius);
01378 os_free(sm->last_recv_radius);
01379 sm->last_recv_radius = NULL;
01380 }
01381 #endif
01382
01383 if (sm->eap_if->eapTimeout) {
01384
01385
01386
01387
01388
01389 sm->eap_if->portEnabled = FALSE;
01390 hostapd_sta_deauth(hapd, sta->addr,
01391 WLAN_REASON_PREV_AUTH_NOT_VALID);
01392 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
01393 WLAN_STA_AUTHORIZED);
01394 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
01395 eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
01396 sta->timeout_next = STA_REMOVE;
01397 }
01398 }
01399
01400
01401 #ifdef HOSTAPD_DUMP_STATE
01402 static void fprint_char(FILE *f, char c)
01403 {
01404 if (c >= 32 && c < 127)
01405 fprintf(f, "%c", c);
01406 else
01407 fprintf(f, "<%02x>", c);
01408 }
01409
01410
01411 void ieee802_1x_dump_state(FILE *f, const char *prefix, struct sta_info *sta)
01412 {
01413 struct eapol_state_machine *sm = sta->eapol_sm;
01414 if (sm == NULL)
01415 return;
01416
01417 fprintf(f, "%sIEEE 802.1X:\n", prefix);
01418
01419 if (sm->identity) {
01420 size_t i;
01421 fprintf(f, "%sidentity=", prefix);
01422 for (i = 0; i < sm->identity_len; i++)
01423 fprint_char(f, sm->identity[i]);
01424 fprintf(f, "\n");
01425 }
01426
01427 fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "
01428 "Supplicant: %d (%s)\n", prefix,
01429 sm->eap_type_authsrv, eap_type_text(sm->eap_type_authsrv),
01430 sm->eap_type_supp, eap_type_text(sm->eap_type_supp));
01431
01432 fprintf(f, "%scached_packets=%s\n", prefix,
01433 sm->last_recv_radius ? "[RX RADIUS]" : "");
01434
01435 eapol_auth_dump_state(f, prefix, sm);
01436 }
01437 #endif
01438
01439
01440 static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd)
01441 {
01442 struct eapol_authenticator *eapol = hapd->eapol_auth;
01443
01444 if (hapd->conf->default_wep_key_len < 1)
01445 return 0;
01446
01447 os_free(eapol->default_wep_key);
01448 eapol->default_wep_key = os_malloc(hapd->conf->default_wep_key_len);
01449 if (eapol->default_wep_key == NULL ||
01450 os_get_random(eapol->default_wep_key,
01451 hapd->conf->default_wep_key_len)) {
01452 printf("Could not generate random WEP key.\n");
01453 os_free(eapol->default_wep_key);
01454 eapol->default_wep_key = NULL;
01455 return -1;
01456 }
01457
01458 wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key",
01459 eapol->default_wep_key,
01460 hapd->conf->default_wep_key_len);
01461
01462 return 0;
01463 }
01464
01465
01466 static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,
01467 struct sta_info *sta, void *ctx)
01468 {
01469 if (sta->eapol_sm) {
01470 sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;
01471 eapol_auth_step(sta->eapol_sm);
01472 }
01473 return 0;
01474 }
01475
01476
01477 static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
01478 {
01479 struct hostapd_data *hapd = eloop_ctx;
01480 struct eapol_authenticator *eapol = hapd->eapol_auth;
01481
01482 if (eapol->default_wep_key_idx >= 3)
01483 eapol->default_wep_key_idx =
01484 hapd->conf->individual_wep_key_len > 0 ? 1 : 0;
01485 else
01486 eapol->default_wep_key_idx++;
01487
01488 wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d",
01489 eapol->default_wep_key_idx);
01490
01491 if (ieee802_1x_rekey_broadcast(hapd)) {
01492 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
01493 HOSTAPD_LEVEL_WARNING, "failed to generate a "
01494 "new broadcast key");
01495 os_free(eapol->default_wep_key);
01496 eapol->default_wep_key = NULL;
01497 return;
01498 }
01499
01500
01501
01502 if (hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, NULL,
01503 eapol->default_wep_key_idx, 1, NULL, 0,
01504 eapol->default_wep_key,
01505 hapd->conf->default_wep_key_len)) {
01506 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
01507 HOSTAPD_LEVEL_WARNING, "failed to configure a "
01508 "new broadcast key");
01509 os_free(eapol->default_wep_key);
01510 eapol->default_wep_key = NULL;
01511 return;
01512 }
01513
01514 ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL);
01515
01516 if (hapd->conf->wep_rekeying_period > 0) {
01517 eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,
01518 ieee802_1x_rekey, hapd, NULL);
01519 }
01520 }
01521
01522
01523 static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
01524 const u8 *data, size_t datalen)
01525 {
01526 ieee802_1x_send(ctx, sta_ctx, type, data, datalen);
01527 }
01528
01529
01530 static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
01531 const u8 *data, size_t datalen)
01532 {
01533 #ifndef CONFIG_NO_RADIUS
01534 struct hostapd_data *hapd = ctx;
01535 struct sta_info *sta = sta_ctx;
01536
01537 ieee802_1x_encapsulate_radius(hapd, sta, data, datalen);
01538 #endif
01539 }
01540
01541
01542 static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
01543 int preauth)
01544 {
01545 struct hostapd_data *hapd = ctx;
01546 struct sta_info *sta = sta_ctx;
01547 if (preauth)
01548 rsn_preauth_finished(hapd, sta, success);
01549 else
01550 ieee802_1x_finished(hapd, sta, success);
01551 }
01552
01553
01554 static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
01555 size_t identity_len, int phase2,
01556 struct eap_user *user)
01557 {
01558 struct hostapd_data *hapd = ctx;
01559 const struct hostapd_eap_user *eap_user;
01560 int i, count;
01561
01562 eap_user = hostapd_get_eap_user(hapd->conf, identity,
01563 identity_len, phase2);
01564 if (eap_user == NULL)
01565 return -1;
01566
01567 os_memset(user, 0, sizeof(*user));
01568 user->phase2 = phase2;
01569 count = EAP_USER_MAX_METHODS;
01570 if (count > EAP_MAX_METHODS)
01571 count = EAP_MAX_METHODS;
01572 for (i = 0; i < count; i++) {
01573 user->methods[i].vendor = eap_user->methods[i].vendor;
01574 user->methods[i].method = eap_user->methods[i].method;
01575 }
01576
01577 if (eap_user->password) {
01578 user->password = os_malloc(eap_user->password_len);
01579 if (user->password == NULL)
01580 return -1;
01581 os_memcpy(user->password, eap_user->password,
01582 eap_user->password_len);
01583 user->password_len = eap_user->password_len;
01584 }
01585 user->force_version = eap_user->force_version;
01586 user->ttls_auth = eap_user->ttls_auth;
01587
01588 return 0;
01589 }
01590
01591
01592 static int ieee802_1x_sta_entry_alive(void *ctx, const u8 *addr)
01593 {
01594 struct hostapd_data *hapd = ctx;
01595 struct sta_info *sta;
01596 sta = ap_get_sta(hapd, addr);
01597 if (sta == NULL || sta->eapol_sm == NULL)
01598 return 0;
01599 return 1;
01600 }
01601
01602
01603 static void ieee802_1x_logger(void *ctx, const u8 *addr,
01604 eapol_logger_level level, const char *txt)
01605 {
01606 #ifndef CONFIG_NO_HOSTAPD_LOGGER
01607 struct hostapd_data *hapd = ctx;
01608 int hlevel;
01609
01610 switch (level) {
01611 case EAPOL_LOGGER_WARNING:
01612 hlevel = HOSTAPD_LEVEL_WARNING;
01613 break;
01614 case EAPOL_LOGGER_INFO:
01615 hlevel = HOSTAPD_LEVEL_INFO;
01616 break;
01617 case EAPOL_LOGGER_DEBUG:
01618 default:
01619 hlevel = HOSTAPD_LEVEL_DEBUG;
01620 break;
01621 }
01622
01623 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE8021X, hlevel, "%s",
01624 txt);
01625 #endif
01626 }
01627
01628
01629 static void ieee802_1x_set_port_authorized(void *ctx, void *sta_ctx,
01630 int authorized)
01631 {
01632 struct hostapd_data *hapd = ctx;
01633 struct sta_info *sta = sta_ctx;
01634 ieee802_1x_set_sta_authorized(hapd, sta, authorized);
01635 }
01636
01637
01638 static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx)
01639 {
01640 struct hostapd_data *hapd = ctx;
01641 struct sta_info *sta = sta_ctx;
01642 ieee802_1x_abort_auth(hapd, sta);
01643 }
01644
01645
01646 static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
01647 {
01648 struct hostapd_data *hapd = ctx;
01649 struct sta_info *sta = sta_ctx;
01650 ieee802_1x_tx_key(hapd, sta);
01651 }
01652
01653
01654 int ieee802_1x_init(struct hostapd_data *hapd)
01655 {
01656 int i;
01657 struct eapol_auth_config conf;
01658 struct eapol_auth_cb cb;
01659
01660 os_memset(&conf, 0, sizeof(conf));
01661 conf.hapd = hapd;
01662 conf.eap_reauth_period = hapd->conf->eap_reauth_period;
01663 conf.wpa = hapd->conf->wpa;
01664 conf.individual_wep_key_len = hapd->conf->individual_wep_key_len;
01665 conf.eap_server = hapd->conf->eap_server;
01666 conf.ssl_ctx = hapd->ssl_ctx;
01667 conf.eap_sim_db_priv = hapd->eap_sim_db_priv;
01668 conf.eap_req_id_text = hapd->conf->eap_req_id_text;
01669 conf.eap_req_id_text_len = hapd->conf->eap_req_id_text_len;
01670 conf.pac_opaque_encr_key = hapd->conf->pac_opaque_encr_key;
01671 conf.eap_fast_a_id = hapd->conf->eap_fast_a_id;
01672 conf.eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len;
01673 conf.eap_fast_a_id_info = hapd->conf->eap_fast_a_id_info;
01674 conf.eap_fast_prov = hapd->conf->eap_fast_prov;
01675 conf.pac_key_lifetime = hapd->conf->pac_key_lifetime;
01676 conf.pac_key_refresh_time = hapd->conf->pac_key_refresh_time;
01677 conf.eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
01678 conf.tnc = hapd->conf->tnc;
01679 conf.wps = hapd->wps;
01680
01681 os_memset(&cb, 0, sizeof(cb));
01682 cb.eapol_send = ieee802_1x_eapol_send;
01683 cb.aaa_send = ieee802_1x_aaa_send;
01684 cb.finished = _ieee802_1x_finished;
01685 cb.get_eap_user = ieee802_1x_get_eap_user;
01686 cb.sta_entry_alive = ieee802_1x_sta_entry_alive;
01687 cb.logger = ieee802_1x_logger;
01688 cb.set_port_authorized = ieee802_1x_set_port_authorized;
01689 cb.abort_auth = _ieee802_1x_abort_auth;
01690 cb.tx_key = _ieee802_1x_tx_key;
01691
01692 hapd->eapol_auth = eapol_auth_init(&conf, &cb);
01693 if (hapd->eapol_auth == NULL)
01694 return -1;
01695
01696 if ((hapd->conf->ieee802_1x || hapd->conf->wpa) &&
01697 hostapd_set_ieee8021x(hapd->conf->iface, hapd, 1))
01698 return -1;
01699
01700 #ifndef CONFIG_NO_RADIUS
01701 if (radius_client_register(hapd->radius, RADIUS_AUTH,
01702 ieee802_1x_receive_auth, hapd))
01703 return -1;
01704 #endif
01705
01706 if (hapd->conf->default_wep_key_len) {
01707 hostapd_set_privacy(hapd, 1);
01708
01709 for (i = 0; i < 4; i++)
01710 hostapd_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
01711 NULL, i, 0, NULL, 0, NULL, 0);
01712
01713 ieee802_1x_rekey(hapd, NULL);
01714
01715 if (hapd->eapol_auth->default_wep_key == NULL)
01716 return -1;
01717 }
01718
01719 return 0;
01720 }
01721
01722
01723 void ieee802_1x_deinit(struct hostapd_data *hapd)
01724 {
01725 eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
01726
01727 if (hapd->driver != NULL &&
01728 (hapd->conf->ieee802_1x || hapd->conf->wpa))
01729 hostapd_set_ieee8021x(hapd->conf->iface, hapd, 0);
01730
01731 eapol_auth_deinit(hapd->eapol_auth);
01732 hapd->eapol_auth = NULL;
01733 }
01734
01735
01736 int ieee802_1x_reconfig(struct hostapd_data *hapd,
01737 struct hostapd_config *oldconf,
01738 struct hostapd_bss_config *oldbss)
01739 {
01740 ieee802_1x_deinit(hapd);
01741 return ieee802_1x_init(hapd);
01742 }
01743
01744
01745 int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
01746 const u8 *buf, size_t len, int ack)
01747 {
01748 struct ieee80211_hdr *hdr;
01749 struct ieee802_1x_hdr *xhdr;
01750 struct ieee802_1x_eapol_key *key;
01751 u8 *pos;
01752 const unsigned char rfc1042_hdr[ETH_ALEN] =
01753 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
01754
01755 if (sta == NULL)
01756 return -1;
01757 if (len < sizeof(*hdr) + sizeof(rfc1042_hdr) + 2 + sizeof(*xhdr))
01758 return 0;
01759
01760 hdr = (struct ieee80211_hdr *) buf;
01761 pos = (u8 *) (hdr + 1);
01762 if (os_memcmp(pos, rfc1042_hdr, sizeof(rfc1042_hdr)) != 0)
01763 return 0;
01764 pos += sizeof(rfc1042_hdr);
01765 if (WPA_GET_BE16(pos) != ETH_P_PAE)
01766 return 0;
01767 pos += 2;
01768
01769 xhdr = (struct ieee802_1x_hdr *) pos;
01770 pos += sizeof(*xhdr);
01771
01772 wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR " TX status - version=%d "
01773 "type=%d length=%d - ack=%d",
01774 MAC2STR(sta->addr), xhdr->version, xhdr->type,
01775 be_to_host16(xhdr->length), ack);
01776
01777
01778
01779
01780
01781
01782 if (xhdr->type == IEEE802_1X_TYPE_EAPOL_KEY && !ack &&
01783 pos + sizeof(*key) <= buf + len) {
01784 key = (struct ieee802_1x_eapol_key *) pos;
01785 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
01786 HOSTAPD_LEVEL_DEBUG, "did not Ack EAPOL-Key "
01787 "frame (%scast index=%d)",
01788 key->key_index & BIT(7) ? "uni" : "broad",
01789 key->key_index & ~BIT(7));
01790
01791
01792
01793
01794
01795
01796 }
01797
01798
01799
01800
01801 return 1;
01802 }
01803
01804
01805 u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len)
01806 {
01807 if (sm == NULL || sm->identity == NULL)
01808 return NULL;
01809
01810 *len = sm->identity_len;
01811 return sm->identity;
01812 }
01813
01814
01815 u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
01816 int idx)
01817 {
01818 if (sm == NULL || sm->radius_class.attr == NULL ||
01819 idx >= (int) sm->radius_class.count)
01820 return NULL;
01821
01822 *len = sm->radius_class.attr[idx].len;
01823 return sm->radius_class.attr[idx].data;
01824 }
01825
01826
01827 const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len)
01828 {
01829 if (sm == NULL)
01830 return NULL;
01831
01832 *len = sm->eap_if->eapKeyDataLen;
01833 return sm->eap_if->eapKeyData;
01834 }
01835
01836
01837 void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
01838 int enabled)
01839 {
01840 if (sm == NULL)
01841 return;
01842 sm->eap_if->portEnabled = enabled ? TRUE : FALSE;
01843 eapol_auth_step(sm);
01844 }
01845
01846
01847 void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm,
01848 int valid)
01849 {
01850 if (sm == NULL)
01851 return;
01852 sm->portValid = valid ? TRUE : FALSE;
01853 eapol_auth_step(sm);
01854 }
01855
01856
01857 void ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth)
01858 {
01859 if (sm == NULL)
01860 return;
01861 if (pre_auth)
01862 sm->flags |= EAPOL_SM_PREAUTH;
01863 else
01864 sm->flags &= ~EAPOL_SM_PREAUTH;
01865 }
01866
01867
01868 static const char * bool_txt(Boolean bool)
01869 {
01870 return bool ? "TRUE" : "FALSE";
01871 }
01872
01873
01874 int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
01875 {
01876
01877 return 0;
01878 }
01879
01880
01881 int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
01882 char *buf, size_t buflen)
01883 {
01884 int len = 0, ret;
01885 struct eapol_state_machine *sm = sta->eapol_sm;
01886
01887 if (sm == NULL)
01888 return 0;
01889
01890 ret = os_snprintf(buf + len, buflen - len,
01891 "dot1xPaePortNumber=%d\n"
01892 "dot1xPaePortProtocolVersion=%d\n"
01893 "dot1xPaePortCapabilities=1\n"
01894 "dot1xPaePortInitialize=%d\n"
01895 "dot1xPaePortReauthenticate=FALSE\n",
01896 sta->aid,
01897 EAPOL_VERSION,
01898 sm->initialize);
01899 if (ret < 0 || (size_t) ret >= buflen - len)
01900 return len;
01901 len += ret;
01902
01903
01904 ret = os_snprintf(buf + len, buflen - len,
01905 "dot1xAuthPaeState=%d\n"
01906 "dot1xAuthBackendAuthState=%d\n"
01907 "dot1xAuthAdminControlledDirections=%d\n"
01908 "dot1xAuthOperControlledDirections=%d\n"
01909 "dot1xAuthAuthControlledPortStatus=%d\n"
01910 "dot1xAuthAuthControlledPortControl=%d\n"
01911 "dot1xAuthQuietPeriod=%u\n"
01912 "dot1xAuthServerTimeout=%u\n"
01913 "dot1xAuthReAuthPeriod=%u\n"
01914 "dot1xAuthReAuthEnabled=%s\n"
01915 "dot1xAuthKeyTxEnabled=%s\n",
01916 sm->auth_pae_state + 1,
01917 sm->be_auth_state + 1,
01918 sm->adminControlledDirections,
01919 sm->operControlledDirections,
01920 sm->authPortStatus,
01921 sm->portControl,
01922 sm->quietPeriod,
01923 sm->serverTimeout,
01924 sm->reAuthPeriod,
01925 bool_txt(sm->reAuthEnabled),
01926 bool_txt(sm->keyTxEnabled));
01927 if (ret < 0 || (size_t) ret >= buflen - len)
01928 return len;
01929 len += ret;
01930
01931
01932 ret = os_snprintf(buf + len, buflen - len,
01933 "dot1xAuthEapolFramesRx=%u\n"
01934 "dot1xAuthEapolFramesTx=%u\n"
01935 "dot1xAuthEapolStartFramesRx=%u\n"
01936 "dot1xAuthEapolLogoffFramesRx=%u\n"
01937 "dot1xAuthEapolRespIdFramesRx=%u\n"
01938 "dot1xAuthEapolRespFramesRx=%u\n"
01939 "dot1xAuthEapolReqIdFramesTx=%u\n"
01940 "dot1xAuthEapolReqFramesTx=%u\n"
01941 "dot1xAuthInvalidEapolFramesRx=%u\n"
01942 "dot1xAuthEapLengthErrorFramesRx=%u\n"
01943 "dot1xAuthLastEapolFrameVersion=%u\n"
01944 "dot1xAuthLastEapolFrameSource=" MACSTR "\n",
01945 sm->dot1xAuthEapolFramesRx,
01946 sm->dot1xAuthEapolFramesTx,
01947 sm->dot1xAuthEapolStartFramesRx,
01948 sm->dot1xAuthEapolLogoffFramesRx,
01949 sm->dot1xAuthEapolRespIdFramesRx,
01950 sm->dot1xAuthEapolRespFramesRx,
01951 sm->dot1xAuthEapolReqIdFramesTx,
01952 sm->dot1xAuthEapolReqFramesTx,
01953 sm->dot1xAuthInvalidEapolFramesRx,
01954 sm->dot1xAuthEapLengthErrorFramesRx,
01955 sm->dot1xAuthLastEapolFrameVersion,
01956 MAC2STR(sm->addr));
01957 if (ret < 0 || (size_t) ret >= buflen - len)
01958 return len;
01959 len += ret;
01960
01961
01962 ret = os_snprintf(buf + len, buflen - len,
01963 "dot1xAuthEntersConnecting=%u\n"
01964 "dot1xAuthEapLogoffsWhileConnecting=%u\n"
01965 "dot1xAuthEntersAuthenticating=%u\n"
01966 "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n"
01967 "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n"
01968 "dot1xAuthAuthFailWhileAuthenticating=%u\n"
01969 "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n"
01970 "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n"
01971 "dot1xAuthAuthReauthsWhileAuthenticated=%u\n"
01972 "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n"
01973 "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n"
01974 "dot1xAuthBackendResponses=%u\n"
01975 "dot1xAuthBackendAccessChallenges=%u\n"
01976 "dot1xAuthBackendOtherRequestsToSupplicant=%u\n"
01977 "dot1xAuthBackendAuthSuccesses=%u\n"
01978 "dot1xAuthBackendAuthFails=%u\n",
01979 sm->authEntersConnecting,
01980 sm->authEapLogoffsWhileConnecting,
01981 sm->authEntersAuthenticating,
01982 sm->authAuthSuccessesWhileAuthenticating,
01983 sm->authAuthTimeoutsWhileAuthenticating,
01984 sm->authAuthFailWhileAuthenticating,
01985 sm->authAuthEapStartsWhileAuthenticating,
01986 sm->authAuthEapLogoffWhileAuthenticating,
01987 sm->authAuthReauthsWhileAuthenticated,
01988 sm->authAuthEapStartsWhileAuthenticated,
01989 sm->authAuthEapLogoffWhileAuthenticated,
01990 sm->backendResponses,
01991 sm->backendAccessChallenges,
01992 sm->backendOtherRequestsToSupplicant,
01993 sm->backendAuthSuccesses,
01994 sm->backendAuthFails);
01995 if (ret < 0 || (size_t) ret >= buflen - len)
01996 return len;
01997 len += ret;
01998
01999
02000 ret = os_snprintf(buf + len, buflen - len,
02001
02002
02003
02004
02005 "dot1xAuthSessionId=%08X-%08X\n"
02006 "dot1xAuthSessionAuthenticMethod=%d\n"
02007 "dot1xAuthSessionTime=%u\n"
02008 "dot1xAuthSessionTerminateCause=999\n"
02009 "dot1xAuthSessionUserName=%s\n",
02010 sta->acct_session_id_hi, sta->acct_session_id_lo,
02011 (wpa_key_mgmt_wpa_ieee8021x(
02012 wpa_auth_sta_key_mgmt(sta->wpa_sm))) ?
02013 1 : 2,
02014 (unsigned int) (time(NULL) -
02015 sta->acct_session_start),
02016 sm->identity);
02017 if (ret < 0 || (size_t) ret >= buflen - len)
02018 return len;
02019 len += ret;
02020
02021 return len;
02022 }
02023
02024
02025 static void ieee802_1x_finished(struct hostapd_data *hapd,
02026 struct sta_info *sta, int success)
02027 {
02028 const u8 *key;
02029 size_t len;
02030
02031 static const int dot11RSNAConfigPMKLifetime = 43200;
02032
02033 key = ieee802_1x_get_key(sta->eapol_sm, &len);
02034 if (success && key && len >= PMK_LEN &&
02035 wpa_auth_pmksa_add(sta->wpa_sm, key, dot11RSNAConfigPMKLifetime,
02036 sta->eapol_sm) == 0) {
02037 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
02038 HOSTAPD_LEVEL_DEBUG,
02039 "Added PMKSA cache entry (IEEE 802.1X)");
02040 }
02041 }
02042