2 * hostapd / IEEE 802.1X-2004 Authenticator
3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "crypto/md5.h"
20 #include "crypto/crypto.h"
21 #include "common/ieee802_11_defs.h"
22 #include "common/wpa_ctrl.h"
23 #include "radius/radius.h"
24 #include "radius/radius_client.h"
25 #include "eap_server/eap.h"
26 #include "eapol_auth/eapol_auth_sm.h"
27 #include "eapol_auth/eapol_auth_sm_i.h"
29 #include "accounting.h"
32 #include "preauth_auth.h"
33 #include "pmksa_cache_auth.h"
34 #include "ap_config.h"
35 #include "ieee802_1x.h"
38 static void ieee802_1x_finished(struct hostapd_data
*hapd
,
39 struct sta_info
*sta
, int success
);
42 static void ieee802_1x_send(struct hostapd_data
*hapd
, struct sta_info
*sta
,
43 u8 type
, const u8
*data
, size_t datalen
)
46 struct ieee802_1x_hdr
*xhdr
;
50 len
= sizeof(*xhdr
) + datalen
;
53 wpa_printf(MSG_ERROR
, "malloc() failed for "
54 "ieee802_1x_send(len=%lu)",
59 xhdr
= (struct ieee802_1x_hdr
*) buf
;
60 xhdr
->version
= hapd
->conf
->eapol_version
;
62 xhdr
->length
= host_to_be16(datalen
);
64 if (datalen
> 0 && data
!= NULL
)
65 os_memcpy(xhdr
+ 1, data
, datalen
);
67 if (wpa_auth_pairwise_set(sta
->wpa_sm
))
69 if (sta
->flags
& WLAN_STA_PREAUTH
) {
70 rsn_preauth_send(hapd
, sta
, buf
, len
);
72 hapd
->drv
.send_eapol(hapd
, sta
->addr
, buf
, len
, encrypt
);
79 void ieee802_1x_set_sta_authorized(struct hostapd_data
*hapd
,
80 struct sta_info
*sta
, int authorized
)
84 if (sta
->flags
& WLAN_STA_PREAUTH
)
88 if (!(sta
->flags
& WLAN_STA_AUTHORIZED
))
89 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
90 AP_STA_CONNECTED MACSTR
, MAC2STR(sta
->addr
));
91 sta
->flags
|= WLAN_STA_AUTHORIZED
;
92 res
= hapd
->drv
.set_authorized(hapd
, sta
, 1);
93 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
94 HOSTAPD_LEVEL_DEBUG
, "authorizing port");
96 if ((sta
->flags
& (WLAN_STA_AUTHORIZED
| WLAN_STA_ASSOC
)) ==
97 (WLAN_STA_AUTHORIZED
| WLAN_STA_ASSOC
))
98 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
99 AP_STA_DISCONNECTED MACSTR
,
101 sta
->flags
&= ~WLAN_STA_AUTHORIZED
;
102 res
= hapd
->drv
.set_authorized(hapd
, sta
, 0);
103 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
104 HOSTAPD_LEVEL_DEBUG
, "unauthorizing port");
107 if (res
&& errno
!= ENOENT
) {
108 printf("Could not set station " MACSTR
" flags for kernel "
109 "driver (errno=%d).\n", MAC2STR(sta
->addr
), errno
);
113 accounting_sta_start(hapd
, sta
);
117 static void ieee802_1x_tx_key_one(struct hostapd_data
*hapd
,
118 struct sta_info
*sta
,
119 int idx
, int broadcast
,
120 u8
*key_data
, size_t key_len
)
123 struct ieee802_1x_hdr
*hdr
;
124 struct ieee802_1x_eapol_key
*key
;
125 size_t len
, ekey_len
;
126 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
131 len
= sizeof(*key
) + key_len
;
132 buf
= os_zalloc(sizeof(*hdr
) + len
);
136 hdr
= (struct ieee802_1x_hdr
*) buf
;
137 key
= (struct ieee802_1x_eapol_key
*) (hdr
+ 1);
138 key
->type
= EAPOL_KEY_TYPE_RC4
;
139 key
->key_length
= htons(key_len
);
140 wpa_get_ntp_timestamp(key
->replay_counter
);
142 if (os_get_random(key
->key_iv
, sizeof(key
->key_iv
))) {
143 wpa_printf(MSG_ERROR
, "Could not get random numbers");
148 key
->key_index
= idx
| (broadcast
? 0 : BIT(7));
149 if (hapd
->conf
->eapol_key_index_workaround
) {
150 /* According to some information, WinXP Supplicant seems to
151 * interpret bit7 as an indication whether the key is to be
152 * activated, so make it possible to enable workaround that
153 * sets this bit for all keys. */
154 key
->key_index
|= BIT(7);
157 /* Key is encrypted using "Key-IV + MSK[0..31]" as the RC4-key and
158 * MSK[32..63] is used to sign the message. */
159 if (sm
->eap_if
->eapKeyData
== NULL
|| sm
->eap_if
->eapKeyDataLen
< 64) {
160 wpa_printf(MSG_ERROR
, "No eapKeyData available for encrypting "
161 "and signing EAPOL-Key");
165 os_memcpy((u8
*) (key
+ 1), key_data
, key_len
);
166 ekey_len
= sizeof(key
->key_iv
) + 32;
167 ekey
= os_malloc(ekey_len
);
169 wpa_printf(MSG_ERROR
, "Could not encrypt key");
173 os_memcpy(ekey
, key
->key_iv
, sizeof(key
->key_iv
));
174 os_memcpy(ekey
+ sizeof(key
->key_iv
), sm
->eap_if
->eapKeyData
, 32);
175 rc4_skip(ekey
, ekey_len
, 0, (u8
*) (key
+ 1), key_len
);
178 /* This header is needed here for HMAC-MD5, but it will be regenerated
179 * in ieee802_1x_send() */
180 hdr
->version
= hapd
->conf
->eapol_version
;
181 hdr
->type
= IEEE802_1X_TYPE_EAPOL_KEY
;
182 hdr
->length
= host_to_be16(len
);
183 hmac_md5(sm
->eap_if
->eapKeyData
+ 32, 32, buf
, sizeof(*hdr
) + len
,
186 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR
187 " (%s index=%d)", MAC2STR(sm
->addr
),
188 broadcast
? "broadcast" : "unicast", idx
);
189 ieee802_1x_send(hapd
, sta
, IEEE802_1X_TYPE_EAPOL_KEY
, (u8
*) key
, len
);
191 sta
->eapol_sm
->dot1xAuthEapolFramesTx
++;
196 #ifndef CONFIG_NO_VLAN
197 static struct hostapd_wep_keys
*
198 ieee802_1x_group_alloc(struct hostapd_data
*hapd
, const char *ifname
)
200 struct hostapd_wep_keys
*key
;
202 key
= os_zalloc(sizeof(*key
));
206 key
->default_len
= hapd
->conf
->default_wep_key_len
;
208 if (key
->idx
>= hapd
->conf
->broadcast_key_idx_max
||
209 key
->idx
< hapd
->conf
->broadcast_key_idx_min
)
210 key
->idx
= hapd
->conf
->broadcast_key_idx_min
;
214 if (!key
->key
[key
->idx
])
215 key
->key
[key
->idx
] = os_malloc(key
->default_len
);
216 if (key
->key
[key
->idx
] == NULL
||
217 os_get_random(key
->key
[key
->idx
], key
->default_len
)) {
218 printf("Could not generate random WEP key (dynamic VLAN).\n");
219 os_free(key
->key
[key
->idx
]);
220 key
->key
[key
->idx
] = NULL
;
224 key
->len
[key
->idx
] = key
->default_len
;
226 wpa_printf(MSG_DEBUG
, "%s: Default WEP idx %d for dynamic VLAN\n",
228 wpa_hexdump_key(MSG_DEBUG
, "Default WEP key (dynamic VLAN)",
229 key
->key
[key
->idx
], key
->len
[key
->idx
]);
231 if (hapd
->drv
.set_key(ifname
, hapd
, WPA_ALG_WEP
, NULL
, key
->idx
, 1,
232 NULL
, 0, key
->key
[key
->idx
], key
->len
[key
->idx
]))
233 printf("Could not set dynamic VLAN WEP encryption key.\n");
235 hapd
->drv
.set_drv_ieee8021x(hapd
, ifname
, 1);
241 static struct hostapd_wep_keys
*
242 ieee802_1x_get_group(struct hostapd_data
*hapd
, struct hostapd_ssid
*ssid
,
250 if (vlan_id
<= ssid
->max_dyn_vlan_keys
&& ssid
->dyn_vlan_keys
&&
251 ssid
->dyn_vlan_keys
[vlan_id
])
252 return ssid
->dyn_vlan_keys
[vlan_id
];
254 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Creating new group "
255 "state machine for VLAN ID %lu",
256 (unsigned long) vlan_id
);
258 ifname
= hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
, vlan_id
);
259 if (ifname
== NULL
) {
260 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Unknown VLAN ID %lu - "
261 "cannot create group key state machine",
262 (unsigned long) vlan_id
);
266 if (ssid
->dyn_vlan_keys
== NULL
) {
267 int size
= (vlan_id
+ 1) * sizeof(ssid
->dyn_vlan_keys
[0]);
268 ssid
->dyn_vlan_keys
= os_zalloc(size
);
269 if (ssid
->dyn_vlan_keys
== NULL
)
271 ssid
->max_dyn_vlan_keys
= vlan_id
;
274 if (ssid
->max_dyn_vlan_keys
< vlan_id
) {
275 struct hostapd_wep_keys
**na
;
276 int size
= (vlan_id
+ 1) * sizeof(ssid
->dyn_vlan_keys
[0]);
277 na
= os_realloc(ssid
->dyn_vlan_keys
, size
);
280 ssid
->dyn_vlan_keys
= na
;
281 os_memset(&ssid
->dyn_vlan_keys
[ssid
->max_dyn_vlan_keys
+ 1], 0,
282 (vlan_id
- ssid
->max_dyn_vlan_keys
) *
283 sizeof(ssid
->dyn_vlan_keys
[0]));
284 ssid
->max_dyn_vlan_keys
= vlan_id
;
287 ssid
->dyn_vlan_keys
[vlan_id
] = ieee802_1x_group_alloc(hapd
, ifname
);
289 return ssid
->dyn_vlan_keys
[vlan_id
];
291 #endif /* CONFIG_NO_VLAN */
294 void ieee802_1x_tx_key(struct hostapd_data
*hapd
, struct sta_info
*sta
)
296 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
297 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
298 #ifndef CONFIG_NO_VLAN
299 struct hostapd_wep_keys
*key
= NULL
;
301 #endif /* CONFIG_NO_VLAN */
303 if (sm
== NULL
|| !sm
->eap_if
->eapKeyData
)
306 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR
,
309 #ifndef CONFIG_NO_VLAN
310 vlan_id
= sta
->vlan_id
;
311 if (vlan_id
< 0 || vlan_id
> MAX_VLAN_ID
)
315 key
= ieee802_1x_get_group(hapd
, sta
->ssid
, vlan_id
);
316 if (key
&& key
->key
[key
->idx
])
317 ieee802_1x_tx_key_one(hapd
, sta
, key
->idx
, 1,
321 #endif /* CONFIG_NO_VLAN */
322 if (eapol
->default_wep_key
) {
323 ieee802_1x_tx_key_one(hapd
, sta
, eapol
->default_wep_key_idx
, 1,
324 eapol
->default_wep_key
,
325 hapd
->conf
->default_wep_key_len
);
328 if (hapd
->conf
->individual_wep_key_len
> 0) {
330 ikey
= os_malloc(hapd
->conf
->individual_wep_key_len
);
332 os_get_random(ikey
, hapd
->conf
->individual_wep_key_len
)) {
333 wpa_printf(MSG_ERROR
, "Could not generate random "
334 "individual WEP key.");
339 wpa_hexdump_key(MSG_DEBUG
, "Individual WEP key",
340 ikey
, hapd
->conf
->individual_wep_key_len
);
342 ieee802_1x_tx_key_one(hapd
, sta
, 0, 0, ikey
,
343 hapd
->conf
->individual_wep_key_len
);
345 /* TODO: set encryption in TX callback, i.e., only after STA
346 * has ACKed EAPOL-Key frame */
347 if (hapd
->drv
.set_key(hapd
->conf
->iface
, hapd
, WPA_ALG_WEP
,
348 sta
->addr
, 0, 1, NULL
, 0, ikey
,
349 hapd
->conf
->individual_wep_key_len
)) {
350 wpa_printf(MSG_ERROR
, "Could not set individual WEP "
359 const char *radius_mode_txt(struct hostapd_data
*hapd
)
361 switch (hapd
->iface
->conf
->hw_mode
) {
362 case HOSTAPD_MODE_IEEE80211A
:
364 case HOSTAPD_MODE_IEEE80211G
:
366 case HOSTAPD_MODE_IEEE80211B
:
373 int radius_sta_rate(struct hostapd_data
*hapd
, struct sta_info
*sta
)
378 for (i
= 0; i
< sta
->supported_rates_len
; i
++)
379 if ((sta
->supported_rates
[i
] & 0x7f) > rate
)
380 rate
= sta
->supported_rates
[i
] & 0x7f;
386 #ifndef CONFIG_NO_RADIUS
387 static void ieee802_1x_learn_identity(struct hostapd_data
*hapd
,
388 struct eapol_state_machine
*sm
,
389 const u8
*eap
, size_t len
)
394 if (len
<= sizeof(struct eap_hdr
) ||
395 eap
[sizeof(struct eap_hdr
)] != EAP_TYPE_IDENTITY
)
398 identity
= eap_get_identity(sm
->eap
, &identity_len
);
399 if (identity
== NULL
)
402 /* Save station identity for future RADIUS packets */
403 os_free(sm
->identity
);
404 sm
->identity
= os_malloc(identity_len
+ 1);
405 if (sm
->identity
== NULL
) {
406 sm
->identity_len
= 0;
410 os_memcpy(sm
->identity
, identity
, identity_len
);
411 sm
->identity_len
= identity_len
;
412 sm
->identity
[identity_len
] = '\0';
413 hostapd_logger(hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
414 HOSTAPD_LEVEL_DEBUG
, "STA identity '%s'", sm
->identity
);
415 sm
->dot1xAuthEapolRespIdFramesRx
++;
419 static void ieee802_1x_encapsulate_radius(struct hostapd_data
*hapd
,
420 struct sta_info
*sta
,
421 const u8
*eap
, size_t len
)
423 struct radius_msg
*msg
;
425 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
430 ieee802_1x_learn_identity(hapd
, sm
, eap
, len
);
432 wpa_printf(MSG_DEBUG
, "Encapsulating EAP message into a RADIUS "
435 sm
->radius_identifier
= radius_client_get_id(hapd
->radius
);
436 msg
= radius_msg_new(RADIUS_CODE_ACCESS_REQUEST
,
437 sm
->radius_identifier
);
439 printf("Could not create net RADIUS packet\n");
443 radius_msg_make_authenticator(msg
, (u8
*) sta
, sizeof(*sta
));
446 !radius_msg_add_attr(msg
, RADIUS_ATTR_USER_NAME
,
447 sm
->identity
, sm
->identity_len
)) {
448 printf("Could not add User-Name\n");
452 if (hapd
->conf
->own_ip_addr
.af
== AF_INET
&&
453 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IP_ADDRESS
,
454 (u8
*) &hapd
->conf
->own_ip_addr
.u
.v4
, 4)) {
455 printf("Could not add NAS-IP-Address\n");
460 if (hapd
->conf
->own_ip_addr
.af
== AF_INET6
&&
461 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IPV6_ADDRESS
,
462 (u8
*) &hapd
->conf
->own_ip_addr
.u
.v6
, 16)) {
463 printf("Could not add NAS-IPv6-Address\n");
466 #endif /* CONFIG_IPV6 */
468 if (hapd
->conf
->nas_identifier
&&
469 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IDENTIFIER
,
470 (u8
*) hapd
->conf
->nas_identifier
,
471 os_strlen(hapd
->conf
->nas_identifier
))) {
472 printf("Could not add NAS-Identifier\n");
476 if (!radius_msg_add_attr_int32(msg
, RADIUS_ATTR_NAS_PORT
, sta
->aid
)) {
477 printf("Could not add NAS-Port\n");
481 os_snprintf(buf
, sizeof(buf
), RADIUS_802_1X_ADDR_FORMAT
":%s",
482 MAC2STR(hapd
->own_addr
), hapd
->conf
->ssid
.ssid
);
483 buf
[sizeof(buf
) - 1] = '\0';
484 if (!radius_msg_add_attr(msg
, RADIUS_ATTR_CALLED_STATION_ID
,
485 (u8
*) buf
, os_strlen(buf
))) {
486 printf("Could not add Called-Station-Id\n");
490 os_snprintf(buf
, sizeof(buf
), RADIUS_802_1X_ADDR_FORMAT
,
492 buf
[sizeof(buf
) - 1] = '\0';
493 if (!radius_msg_add_attr(msg
, RADIUS_ATTR_CALLING_STATION_ID
,
494 (u8
*) buf
, os_strlen(buf
))) {
495 printf("Could not add Calling-Station-Id\n");
499 /* TODO: should probably check MTU from driver config; 2304 is max for
500 * IEEE 802.11, but use 1400 to avoid problems with too large packets
502 if (!radius_msg_add_attr_int32(msg
, RADIUS_ATTR_FRAMED_MTU
, 1400)) {
503 printf("Could not add Framed-MTU\n");
507 if (!radius_msg_add_attr_int32(msg
, RADIUS_ATTR_NAS_PORT_TYPE
,
508 RADIUS_NAS_PORT_TYPE_IEEE_802_11
)) {
509 printf("Could not add NAS-Port-Type\n");
513 if (sta
->flags
& WLAN_STA_PREAUTH
) {
514 os_strlcpy(buf
, "IEEE 802.11i Pre-Authentication",
517 os_snprintf(buf
, sizeof(buf
), "CONNECT %d%sMbps %s",
518 radius_sta_rate(hapd
, sta
) / 2,
519 (radius_sta_rate(hapd
, sta
) & 1) ? ".5" : "",
520 radius_mode_txt(hapd
));
521 buf
[sizeof(buf
) - 1] = '\0';
523 if (!radius_msg_add_attr(msg
, RADIUS_ATTR_CONNECT_INFO
,
524 (u8
*) buf
, os_strlen(buf
))) {
525 printf("Could not add Connect-Info\n");
529 if (eap
&& !radius_msg_add_eap(msg
, eap
, len
)) {
530 printf("Could not add EAP-Message\n");
534 /* State attribute must be copied if and only if this packet is
535 * Access-Request reply to the previous Access-Challenge */
536 if (sm
->last_recv_radius
&&
537 radius_msg_get_hdr(sm
->last_recv_radius
)->code
==
538 RADIUS_CODE_ACCESS_CHALLENGE
) {
539 int res
= radius_msg_copy_attr(msg
, sm
->last_recv_radius
,
542 printf("Could not copy State attribute from previous "
543 "Access-Challenge\n");
547 wpa_printf(MSG_DEBUG
, "Copied RADIUS State Attribute");
551 radius_client_send(hapd
->radius
, msg
, RADIUS_AUTH
, sta
->addr
);
555 radius_msg_free(msg
);
557 #endif /* CONFIG_NO_RADIUS */
560 static void handle_eap_response(struct hostapd_data
*hapd
,
561 struct sta_info
*sta
, struct eap_hdr
*eap
,
565 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
569 data
= (u8
*) (eap
+ 1);
571 if (len
< sizeof(*eap
) + 1) {
572 printf("handle_eap_response: too short response data\n");
576 sm
->eap_type_supp
= type
= data
[0];
578 hostapd_logger(hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
579 HOSTAPD_LEVEL_DEBUG
, "received EAP packet (code=%d "
580 "id=%d len=%d) from STA: EAP Response-%s (%d)",
581 eap
->code
, eap
->identifier
, be_to_host16(eap
->length
),
582 eap_server_get_name(0, type
), type
);
584 sm
->dot1xAuthEapolRespFramesRx
++;
586 wpabuf_free(sm
->eap_if
->eapRespData
);
587 sm
->eap_if
->eapRespData
= wpabuf_alloc_copy(eap
, len
);
592 /* Process incoming EAP packet from Supplicant */
593 static void handle_eap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
599 if (len
< sizeof(*eap
)) {
600 printf(" too short EAP packet\n");
604 eap
= (struct eap_hdr
*) buf
;
606 eap_len
= be_to_host16(eap
->length
);
607 wpa_printf(MSG_DEBUG
, "EAP: code=%d identifier=%d length=%d",
608 eap
->code
, eap
->identifier
, eap_len
);
609 if (eap_len
< sizeof(*eap
)) {
610 wpa_printf(MSG_DEBUG
, " Invalid EAP length");
612 } else if (eap_len
> len
) {
613 wpa_printf(MSG_DEBUG
, " Too short frame to contain this EAP "
616 } else if (eap_len
< len
) {
617 wpa_printf(MSG_DEBUG
, " Ignoring %lu extra bytes after EAP "
618 "packet", (unsigned long) len
- eap_len
);
622 case EAP_CODE_REQUEST
:
623 wpa_printf(MSG_DEBUG
, " (request)");
625 case EAP_CODE_RESPONSE
:
626 wpa_printf(MSG_DEBUG
, " (response)");
627 handle_eap_response(hapd
, sta
, eap
, eap_len
);
629 case EAP_CODE_SUCCESS
:
630 wpa_printf(MSG_DEBUG
, " (success)");
632 case EAP_CODE_FAILURE
:
633 wpa_printf(MSG_DEBUG
, " (failure)");
636 wpa_printf(MSG_DEBUG
, " (unknown code)");
642 static struct eapol_state_machine
*
643 ieee802_1x_alloc_eapol_sm(struct hostapd_data
*hapd
, struct sta_info
*sta
)
646 if (sta
->flags
& WLAN_STA_PREAUTH
)
647 flags
|= EAPOL_SM_PREAUTH
;
649 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
))
650 flags
|= EAPOL_SM_USES_WPA
;
651 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
))
652 flags
|= EAPOL_SM_FROM_PMKSA_CACHE
;
654 return eapol_auth_alloc(hapd
->eapol_auth
, sta
->addr
, flags
,
660 * ieee802_1x_receive - Process the EAPOL frames from the Supplicant
661 * @hapd: hostapd BSS data
662 * @sa: Source address (sender of the EAPOL frame)
664 * @len: Length of buf in octets
666 * This function is called for each incoming EAPOL frame from the interface
668 void ieee802_1x_receive(struct hostapd_data
*hapd
, const u8
*sa
, const u8
*buf
,
671 struct sta_info
*sta
;
672 struct ieee802_1x_hdr
*hdr
;
673 struct ieee802_1x_eapol_key
*key
;
675 struct rsn_pmksa_cache_entry
*pmksa
;
677 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
678 !hapd
->conf
->wps_state
)
681 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: %lu bytes from " MACSTR
,
682 (unsigned long) len
, MAC2STR(sa
));
683 sta
= ap_get_sta(hapd
, sa
);
684 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
685 wpa_printf(MSG_DEBUG
, "IEEE 802.1X data frame from not "
690 if (len
< sizeof(*hdr
)) {
691 printf(" too short IEEE 802.1X packet\n");
695 hdr
= (struct ieee802_1x_hdr
*) buf
;
696 datalen
= be_to_host16(hdr
->length
);
697 wpa_printf(MSG_DEBUG
, " IEEE 802.1X: version=%d type=%d length=%d",
698 hdr
->version
, hdr
->type
, datalen
);
700 if (len
- sizeof(*hdr
) < datalen
) {
701 printf(" frame too short for this IEEE 802.1X packet\n");
703 sta
->eapol_sm
->dot1xAuthEapLengthErrorFramesRx
++;
706 if (len
- sizeof(*hdr
) > datalen
) {
707 wpa_printf(MSG_DEBUG
, " ignoring %lu extra octets after "
708 "IEEE 802.1X packet",
709 (unsigned long) len
- sizeof(*hdr
) - datalen
);
713 sta
->eapol_sm
->dot1xAuthLastEapolFrameVersion
= hdr
->version
;
714 sta
->eapol_sm
->dot1xAuthEapolFramesRx
++;
717 key
= (struct ieee802_1x_eapol_key
*) (hdr
+ 1);
718 if (datalen
>= sizeof(struct ieee802_1x_eapol_key
) &&
719 hdr
->type
== IEEE802_1X_TYPE_EAPOL_KEY
&&
720 (key
->type
== EAPOL_KEY_TYPE_WPA
||
721 key
->type
== EAPOL_KEY_TYPE_RSN
)) {
722 wpa_receive(hapd
->wpa_auth
, sta
->wpa_sm
, (u8
*) hdr
,
723 sizeof(*hdr
) + datalen
);
727 if ((!hapd
->conf
->ieee802_1x
&&
728 !(sta
->flags
& (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
))) ||
729 wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
)))
732 if (!sta
->eapol_sm
) {
733 sta
->eapol_sm
= ieee802_1x_alloc_eapol_sm(hapd
, sta
);
738 if (!hapd
->conf
->ieee802_1x
&&
739 ((sta
->flags
& (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
)) ==
740 WLAN_STA_MAYBE_WPS
)) {
742 * Delay EAPOL frame transmission until a possible WPS
743 * STA initiates the handshake with EAPOL-Start.
745 sta
->eapol_sm
->flags
|= EAPOL_SM_WAIT_START
;
747 #endif /* CONFIG_WPS */
749 sta
->eapol_sm
->eap_if
->portEnabled
= TRUE
;
752 /* since we support version 1, we can ignore version field and proceed
753 * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */
754 /* TODO: actually, we are not version 1 anymore.. However, Version 2
755 * does not change frame contents, so should be ok to process frames
756 * more or less identically. Some changes might be needed for
757 * verification of fields. */
760 case IEEE802_1X_TYPE_EAP_PACKET
:
761 handle_eap(hapd
, sta
, (u8
*) (hdr
+ 1), datalen
);
764 case IEEE802_1X_TYPE_EAPOL_START
:
765 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
766 HOSTAPD_LEVEL_DEBUG
, "received EAPOL-Start "
768 sta
->eapol_sm
->flags
&= ~EAPOL_SM_WAIT_START
;
769 pmksa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
771 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
772 HOSTAPD_LEVEL_DEBUG
, "cached PMKSA "
773 "available - ignore it since "
774 "STA sent EAPOL-Start");
775 wpa_auth_sta_clear_pmksa(sta
->wpa_sm
, pmksa
);
777 sta
->eapol_sm
->eapolStart
= TRUE
;
778 sta
->eapol_sm
->dot1xAuthEapolStartFramesRx
++;
779 wpa_auth_sm_event(sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
782 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
783 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
784 HOSTAPD_LEVEL_DEBUG
, "received EAPOL-Logoff "
786 sta
->acct_terminate_cause
=
787 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
788 accounting_sta_stop(hapd
, sta
);
789 sta
->eapol_sm
->eapolLogoff
= TRUE
;
790 sta
->eapol_sm
->dot1xAuthEapolLogoffFramesRx
++;
793 case IEEE802_1X_TYPE_EAPOL_KEY
:
794 wpa_printf(MSG_DEBUG
, " EAPOL-Key");
795 if (!(sta
->flags
& WLAN_STA_AUTHORIZED
)) {
796 wpa_printf(MSG_DEBUG
, " Dropped key data from "
797 "unauthorized Supplicant");
802 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
803 wpa_printf(MSG_DEBUG
, " EAPOL-Encapsulated-ASF-Alert");
804 /* TODO: implement support for this; show data */
808 wpa_printf(MSG_DEBUG
, " unknown IEEE 802.1X packet type");
809 sta
->eapol_sm
->dot1xAuthInvalidEapolFramesRx
++;
813 eapol_auth_step(sta
->eapol_sm
);
818 * ieee802_1x_new_station - Start IEEE 802.1X authentication
819 * @hapd: hostapd BSS data
822 * This function is called to start IEEE 802.1X authentication when a new
823 * station completes IEEE 802.11 association.
825 void ieee802_1x_new_station(struct hostapd_data
*hapd
, struct sta_info
*sta
)
827 struct rsn_pmksa_cache_entry
*pmksa
;
832 if (hapd
->conf
->wps_state
&& hapd
->conf
->wpa
&&
833 (sta
->flags
& (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
))) {
835 * Need to enable IEEE 802.1X/EAPOL state machines for possible
836 * WPS handshake even if IEEE 802.1X/EAPOL is not used for
837 * authentication in this BSS.
841 #endif /* CONFIG_WPS */
843 if ((!force_1x
&& !hapd
->conf
->ieee802_1x
) ||
844 wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
)))
847 if (sta
->eapol_sm
== NULL
) {
848 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
849 HOSTAPD_LEVEL_DEBUG
, "start authentication");
850 sta
->eapol_sm
= ieee802_1x_alloc_eapol_sm(hapd
, sta
);
851 if (sta
->eapol_sm
== NULL
) {
852 hostapd_logger(hapd
, sta
->addr
,
853 HOSTAPD_MODULE_IEEE8021X
,
855 "failed to allocate state machine");
862 sta
->eapol_sm
->flags
&= ~EAPOL_SM_WAIT_START
;
863 if (!hapd
->conf
->ieee802_1x
&& !(sta
->flags
& WLAN_STA_WPS
)) {
865 * Delay EAPOL frame transmission until a possible WPS
866 * initiates the handshake with EAPOL-Start.
868 sta
->eapol_sm
->flags
|= EAPOL_SM_WAIT_START
;
870 #endif /* CONFIG_WPS */
872 sta
->eapol_sm
->eap_if
->portEnabled
= TRUE
;
874 pmksa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
878 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
880 "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
881 /* Setup EAPOL state machines to already authenticated state
882 * because of existing PMKSA information in the cache. */
883 sta
->eapol_sm
->keyRun
= TRUE
;
884 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
885 sta
->eapol_sm
->auth_pae_state
= AUTH_PAE_AUTHENTICATING
;
886 sta
->eapol_sm
->be_auth_state
= BE_AUTH_SUCCESS
;
887 sta
->eapol_sm
->authSuccess
= TRUE
;
888 if (sta
->eapol_sm
->eap
)
889 eap_sm_notify_cached(sta
->eapol_sm
->eap
);
890 old_vlanid
= sta
->vlan_id
;
891 pmksa_cache_to_eapol_data(pmksa
, sta
->eapol_sm
);
892 if (sta
->ssid
->dynamic_vlan
== DYNAMIC_VLAN_DISABLED
)
894 ap_sta_bind_vlan(hapd
, sta
, old_vlanid
);
898 * Force EAPOL state machines to start
899 * re-authentication without having to wait for the
900 * Supplicant to send EAPOL-Start.
902 sta
->eapol_sm
->reAuthenticate
= TRUE
;
904 eapol_auth_step(sta
->eapol_sm
);
909 void ieee802_1x_free_station(struct sta_info
*sta
)
911 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
916 sta
->eapol_sm
= NULL
;
918 #ifndef CONFIG_NO_RADIUS
919 radius_msg_free(sm
->last_recv_radius
);
920 radius_free_class(&sm
->radius_class
);
921 #endif /* CONFIG_NO_RADIUS */
923 os_free(sm
->identity
);
928 #ifndef CONFIG_NO_RADIUS
929 static void ieee802_1x_decapsulate_radius(struct hostapd_data
*hapd
,
930 struct sta_info
*sta
)
937 struct radius_msg
*msg
;
938 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
940 if (sm
== NULL
|| sm
->last_recv_radius
== NULL
) {
942 sm
->eap_if
->aaaEapNoReq
= TRUE
;
946 msg
= sm
->last_recv_radius
;
948 eap
= radius_msg_get_eap(msg
, &len
);
950 /* RFC 3579, Chap. 2.6.3:
951 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
953 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
954 HOSTAPD_LEVEL_WARNING
, "could not extract "
955 "EAP-Message from RADIUS message");
956 sm
->eap_if
->aaaEapNoReq
= TRUE
;
960 if (len
< sizeof(*hdr
)) {
961 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
962 HOSTAPD_LEVEL_WARNING
, "too short EAP packet "
963 "received from authentication server");
965 sm
->eap_if
->aaaEapNoReq
= TRUE
;
969 if (len
> sizeof(*hdr
))
970 eap_type
= eap
[sizeof(*hdr
)];
972 hdr
= (struct eap_hdr
*) eap
;
974 case EAP_CODE_REQUEST
:
976 sm
->eap_type_authsrv
= eap_type
;
977 os_snprintf(buf
, sizeof(buf
), "EAP-Request-%s (%d)",
978 eap_type
>= 0 ? eap_server_get_name(0, eap_type
) :
982 case EAP_CODE_RESPONSE
:
983 os_snprintf(buf
, sizeof(buf
), "EAP Response-%s (%d)",
984 eap_type
>= 0 ? eap_server_get_name(0, eap_type
) :
988 case EAP_CODE_SUCCESS
:
989 os_strlcpy(buf
, "EAP Success", sizeof(buf
));
991 case EAP_CODE_FAILURE
:
992 os_strlcpy(buf
, "EAP Failure", sizeof(buf
));
995 os_strlcpy(buf
, "unknown EAP code", sizeof(buf
));
998 buf
[sizeof(buf
) - 1] = '\0';
999 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1000 HOSTAPD_LEVEL_DEBUG
, "decapsulated EAP packet (code=%d "
1001 "id=%d len=%d) from RADIUS server: %s",
1002 hdr
->code
, hdr
->identifier
, be_to_host16(hdr
->length
),
1004 sm
->eap_if
->aaaEapReq
= TRUE
;
1006 wpabuf_free(sm
->eap_if
->aaaEapReqData
);
1007 sm
->eap_if
->aaaEapReqData
= wpabuf_alloc_ext_data(eap
, len
);
1011 static void ieee802_1x_get_keys(struct hostapd_data
*hapd
,
1012 struct sta_info
*sta
, struct radius_msg
*msg
,
1013 struct radius_msg
*req
,
1014 const u8
*shared_secret
,
1015 size_t shared_secret_len
)
1017 struct radius_ms_mppe_keys
*keys
;
1018 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1022 keys
= radius_msg_get_ms_keys(msg
, req
, shared_secret
,
1025 if (keys
&& keys
->send
&& keys
->recv
) {
1026 size_t len
= keys
->send_len
+ keys
->recv_len
;
1027 wpa_hexdump_key(MSG_DEBUG
, "MS-MPPE-Send-Key",
1028 keys
->send
, keys
->send_len
);
1029 wpa_hexdump_key(MSG_DEBUG
, "MS-MPPE-Recv-Key",
1030 keys
->recv
, keys
->recv_len
);
1032 os_free(sm
->eap_if
->aaaEapKeyData
);
1033 sm
->eap_if
->aaaEapKeyData
= os_malloc(len
);
1034 if (sm
->eap_if
->aaaEapKeyData
) {
1035 os_memcpy(sm
->eap_if
->aaaEapKeyData
, keys
->recv
,
1037 os_memcpy(sm
->eap_if
->aaaEapKeyData
+ keys
->recv_len
,
1038 keys
->send
, keys
->send_len
);
1039 sm
->eap_if
->aaaEapKeyDataLen
= len
;
1040 sm
->eap_if
->aaaEapKeyAvailable
= TRUE
;
1045 os_free(keys
->send
);
1046 os_free(keys
->recv
);
1052 static void ieee802_1x_store_radius_class(struct hostapd_data
*hapd
,
1053 struct sta_info
*sta
,
1054 struct radius_msg
*msg
)
1058 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1060 struct radius_attr_data
*nclass
;
1061 size_t nclass_count
;
1063 if (!hapd
->conf
->radius
->acct_server
|| hapd
->radius
== NULL
||
1067 radius_free_class(&sm
->radius_class
);
1068 count
= radius_msg_count_attr(msg
, RADIUS_ATTR_CLASS
, 1);
1072 nclass
= os_zalloc(count
* sizeof(struct radius_attr_data
));
1079 for (i
= 0; i
< count
; i
++) {
1081 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_CLASS
,
1087 } while (class_len
< 1);
1089 nclass
[nclass_count
].data
= os_malloc(class_len
);
1090 if (nclass
[nclass_count
].data
== NULL
)
1093 os_memcpy(nclass
[nclass_count
].data
, class, class_len
);
1094 nclass
[nclass_count
].len
= class_len
;
1098 sm
->radius_class
.attr
= nclass
;
1099 sm
->radius_class
.count
= nclass_count
;
1100 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Stored %lu RADIUS Class "
1101 "attributes for " MACSTR
,
1102 (unsigned long) sm
->radius_class
.count
,
1103 MAC2STR(sta
->addr
));
1107 /* Update sta->identity based on User-Name attribute in Access-Accept */
1108 static void ieee802_1x_update_sta_identity(struct hostapd_data
*hapd
,
1109 struct sta_info
*sta
,
1110 struct radius_msg
*msg
)
1114 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1119 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_USER_NAME
, &buf
, &len
,
1123 identity
= os_malloc(len
+ 1);
1124 if (identity
== NULL
)
1127 os_memcpy(identity
, buf
, len
);
1128 identity
[len
] = '\0';
1130 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1131 HOSTAPD_LEVEL_DEBUG
, "old identity '%s' updated with "
1132 "User-Name from Access-Accept '%s'",
1133 sm
->identity
? (char *) sm
->identity
: "N/A",
1136 os_free(sm
->identity
);
1137 sm
->identity
= identity
;
1138 sm
->identity_len
= len
;
1142 struct sta_id_search
{
1144 struct eapol_state_machine
*sm
;
1148 static int ieee802_1x_select_radius_identifier(struct hostapd_data
*hapd
,
1149 struct sta_info
*sta
,
1152 struct sta_id_search
*id_search
= ctx
;
1153 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1155 if (sm
&& sm
->radius_identifier
>= 0 &&
1156 sm
->radius_identifier
== id_search
->identifier
) {
1164 static struct eapol_state_machine
*
1165 ieee802_1x_search_radius_identifier(struct hostapd_data
*hapd
, u8 identifier
)
1167 struct sta_id_search id_search
;
1168 id_search
.identifier
= identifier
;
1169 id_search
.sm
= NULL
;
1170 ap_for_each_sta(hapd
, ieee802_1x_select_radius_identifier
, &id_search
);
1171 return id_search
.sm
;
1176 * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server
1177 * @msg: RADIUS response message
1178 * @req: RADIUS request message
1179 * @shared_secret: RADIUS shared secret
1180 * @shared_secret_len: Length of shared_secret in octets
1181 * @data: Context data (struct hostapd_data *)
1182 * Returns: Processing status
1184 static RadiusRxResult
1185 ieee802_1x_receive_auth(struct radius_msg
*msg
, struct radius_msg
*req
,
1186 const u8
*shared_secret
, size_t shared_secret_len
,
1189 struct hostapd_data
*hapd
= data
;
1190 struct sta_info
*sta
;
1191 u32 session_timeout
= 0, termination_action
, acct_interim_interval
;
1192 int session_timeout_set
, old_vlanid
= 0;
1193 struct eapol_state_machine
*sm
;
1194 int override_eapReq
= 0;
1195 struct radius_hdr
*hdr
= radius_msg_get_hdr(msg
);
1197 sm
= ieee802_1x_search_radius_identifier(hapd
, hdr
->identifier
);
1199 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Could not find matching "
1200 "station for this RADIUS message");
1201 return RADIUS_RX_UNKNOWN
;
1205 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
1206 * present when packet contains an EAP-Message attribute */
1207 if (hdr
->code
== RADIUS_CODE_ACCESS_REJECT
&&
1208 radius_msg_get_attr(msg
, RADIUS_ATTR_MESSAGE_AUTHENTICATOR
, NULL
,
1210 radius_msg_get_attr(msg
, RADIUS_ATTR_EAP_MESSAGE
, NULL
, 0) < 0) {
1211 wpa_printf(MSG_DEBUG
, "Allowing RADIUS Access-Reject without "
1212 "Message-Authenticator since it does not include "
1214 } else if (radius_msg_verify(msg
, shared_secret
, shared_secret_len
,
1216 printf("Incoming RADIUS packet did not have correct "
1217 "Message-Authenticator - dropped\n");
1218 return RADIUS_RX_INVALID_AUTHENTICATOR
;
1221 if (hdr
->code
!= RADIUS_CODE_ACCESS_ACCEPT
&&
1222 hdr
->code
!= RADIUS_CODE_ACCESS_REJECT
&&
1223 hdr
->code
!= RADIUS_CODE_ACCESS_CHALLENGE
) {
1224 printf("Unknown RADIUS message code\n");
1225 return RADIUS_RX_UNKNOWN
;
1228 sm
->radius_identifier
= -1;
1229 wpa_printf(MSG_DEBUG
, "RADIUS packet matching with station " MACSTR
,
1230 MAC2STR(sta
->addr
));
1232 radius_msg_free(sm
->last_recv_radius
);
1233 sm
->last_recv_radius
= msg
;
1235 session_timeout_set
=
1236 !radius_msg_get_attr_int32(msg
, RADIUS_ATTR_SESSION_TIMEOUT
,
1238 if (radius_msg_get_attr_int32(msg
, RADIUS_ATTR_TERMINATION_ACTION
,
1239 &termination_action
))
1240 termination_action
= RADIUS_TERMINATION_ACTION_DEFAULT
;
1242 if (hapd
->conf
->acct_interim_interval
== 0 &&
1243 hdr
->code
== RADIUS_CODE_ACCESS_ACCEPT
&&
1244 radius_msg_get_attr_int32(msg
, RADIUS_ATTR_ACCT_INTERIM_INTERVAL
,
1245 &acct_interim_interval
) == 0) {
1246 if (acct_interim_interval
< 60) {
1247 hostapd_logger(hapd
, sta
->addr
,
1248 HOSTAPD_MODULE_IEEE8021X
,
1250 "ignored too small "
1251 "Acct-Interim-Interval %d",
1252 acct_interim_interval
);
1254 sta
->acct_interim_interval
= acct_interim_interval
;
1258 switch (hdr
->code
) {
1259 case RADIUS_CODE_ACCESS_ACCEPT
:
1260 if (sta
->ssid
->dynamic_vlan
== DYNAMIC_VLAN_DISABLED
)
1262 #ifndef CONFIG_NO_VLAN
1264 old_vlanid
= sta
->vlan_id
;
1265 sta
->vlan_id
= radius_msg_get_vlanid(msg
);
1267 if (sta
->vlan_id
> 0 &&
1268 hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
1270 hostapd_logger(hapd
, sta
->addr
,
1271 HOSTAPD_MODULE_RADIUS
,
1273 "VLAN ID %d", sta
->vlan_id
);
1274 } else if (sta
->ssid
->dynamic_vlan
== DYNAMIC_VLAN_REQUIRED
) {
1275 sta
->eapol_sm
->authFail
= TRUE
;
1276 hostapd_logger(hapd
, sta
->addr
,
1277 HOSTAPD_MODULE_IEEE8021X
,
1278 HOSTAPD_LEVEL_INFO
, "authentication "
1279 "server did not include required VLAN "
1280 "ID in Access-Accept");
1283 #endif /* CONFIG_NO_VLAN */
1285 ap_sta_bind_vlan(hapd
, sta
, old_vlanid
);
1287 /* RFC 3580, Ch. 3.17 */
1288 if (session_timeout_set
&& termination_action
==
1289 RADIUS_TERMINATION_ACTION_RADIUS_REQUEST
) {
1290 sm
->reAuthPeriod
= session_timeout
;
1291 } else if (session_timeout_set
)
1292 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
1294 sm
->eap_if
->aaaSuccess
= TRUE
;
1295 override_eapReq
= 1;
1296 ieee802_1x_get_keys(hapd
, sta
, msg
, req
, shared_secret
,
1298 ieee802_1x_store_radius_class(hapd
, sta
, msg
);
1299 ieee802_1x_update_sta_identity(hapd
, sta
, msg
);
1300 if (sm
->eap_if
->eapKeyAvailable
&&
1301 wpa_auth_pmksa_add(sta
->wpa_sm
, sm
->eapol_key_crypt
,
1302 session_timeout_set
?
1303 (int) session_timeout
: -1, sm
) == 0) {
1304 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
1305 HOSTAPD_LEVEL_DEBUG
,
1306 "Added PMKSA cache entry");
1309 case RADIUS_CODE_ACCESS_REJECT
:
1310 sm
->eap_if
->aaaFail
= TRUE
;
1311 override_eapReq
= 1;
1313 case RADIUS_CODE_ACCESS_CHALLENGE
:
1314 sm
->eap_if
->aaaEapReq
= TRUE
;
1315 if (session_timeout_set
) {
1316 /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */
1317 sm
->eap_if
->aaaMethodTimeout
= session_timeout
;
1318 hostapd_logger(hapd
, sm
->addr
,
1319 HOSTAPD_MODULE_IEEE8021X
,
1320 HOSTAPD_LEVEL_DEBUG
,
1321 "using EAP timeout of %d seconds (from "
1323 sm
->eap_if
->aaaMethodTimeout
);
1326 * Use dynamic retransmission behavior per EAP
1329 sm
->eap_if
->aaaMethodTimeout
= 0;
1334 ieee802_1x_decapsulate_radius(hapd
, sta
);
1335 if (override_eapReq
)
1336 sm
->eap_if
->aaaEapReq
= FALSE
;
1338 eapol_auth_step(sm
);
1340 return RADIUS_RX_QUEUED
;
1342 #endif /* CONFIG_NO_RADIUS */
1345 void ieee802_1x_abort_auth(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1347 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1351 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1352 HOSTAPD_LEVEL_DEBUG
, "aborting authentication");
1354 #ifndef CONFIG_NO_RADIUS
1355 radius_msg_free(sm
->last_recv_radius
);
1356 sm
->last_recv_radius
= NULL
;
1357 #endif /* CONFIG_NO_RADIUS */
1359 if (sm
->eap_if
->eapTimeout
) {
1361 * Disconnect the STA since it did not reply to the last EAP
1362 * request and we cannot continue EAP processing (EAP-Failure
1363 * could only be sent if the EAP peer actually replied).
1365 sm
->eap_if
->portEnabled
= FALSE
;
1366 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
1367 WLAN_REASON_PREV_AUTH_NOT_VALID
);
1372 static int ieee802_1x_rekey_broadcast(struct hostapd_data
*hapd
)
1374 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
1376 if (hapd
->conf
->default_wep_key_len
< 1)
1379 os_free(eapol
->default_wep_key
);
1380 eapol
->default_wep_key
= os_malloc(hapd
->conf
->default_wep_key_len
);
1381 if (eapol
->default_wep_key
== NULL
||
1382 os_get_random(eapol
->default_wep_key
,
1383 hapd
->conf
->default_wep_key_len
)) {
1384 printf("Could not generate random WEP key.\n");
1385 os_free(eapol
->default_wep_key
);
1386 eapol
->default_wep_key
= NULL
;
1390 wpa_hexdump_key(MSG_DEBUG
, "IEEE 802.1X: New default WEP key",
1391 eapol
->default_wep_key
,
1392 hapd
->conf
->default_wep_key_len
);
1398 static int ieee802_1x_sta_key_available(struct hostapd_data
*hapd
,
1399 struct sta_info
*sta
, void *ctx
)
1401 if (sta
->eapol_sm
) {
1402 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
1403 eapol_auth_step(sta
->eapol_sm
);
1409 static void ieee802_1x_rekey(void *eloop_ctx
, void *timeout_ctx
)
1411 struct hostapd_data
*hapd
= eloop_ctx
;
1412 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
1414 if (eapol
->default_wep_key_idx
>= 3)
1415 eapol
->default_wep_key_idx
=
1416 hapd
->conf
->individual_wep_key_len
> 0 ? 1 : 0;
1418 eapol
->default_wep_key_idx
++;
1420 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: New default WEP key index %d",
1421 eapol
->default_wep_key_idx
);
1423 if (ieee802_1x_rekey_broadcast(hapd
)) {
1424 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE8021X
,
1425 HOSTAPD_LEVEL_WARNING
, "failed to generate a "
1426 "new broadcast key");
1427 os_free(eapol
->default_wep_key
);
1428 eapol
->default_wep_key
= NULL
;
1432 /* TODO: Could setup key for RX here, but change default TX keyid only
1433 * after new broadcast key has been sent to all stations. */
1434 if (hapd
->drv
.set_key(hapd
->conf
->iface
, hapd
, WPA_ALG_WEP
, NULL
,
1435 eapol
->default_wep_key_idx
, 1, NULL
, 0,
1436 eapol
->default_wep_key
,
1437 hapd
->conf
->default_wep_key_len
)) {
1438 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE8021X
,
1439 HOSTAPD_LEVEL_WARNING
, "failed to configure a "
1440 "new broadcast key");
1441 os_free(eapol
->default_wep_key
);
1442 eapol
->default_wep_key
= NULL
;
1446 ap_for_each_sta(hapd
, ieee802_1x_sta_key_available
, NULL
);
1448 if (hapd
->conf
->wep_rekeying_period
> 0) {
1449 eloop_register_timeout(hapd
->conf
->wep_rekeying_period
, 0,
1450 ieee802_1x_rekey
, hapd
, NULL
);
1455 static void ieee802_1x_eapol_send(void *ctx
, void *sta_ctx
, u8 type
,
1456 const u8
*data
, size_t datalen
)
1458 ieee802_1x_send(ctx
, sta_ctx
, type
, data
, datalen
);
1462 static void ieee802_1x_aaa_send(void *ctx
, void *sta_ctx
,
1463 const u8
*data
, size_t datalen
)
1465 #ifndef CONFIG_NO_RADIUS
1466 struct hostapd_data
*hapd
= ctx
;
1467 struct sta_info
*sta
= sta_ctx
;
1469 ieee802_1x_encapsulate_radius(hapd
, sta
, data
, datalen
);
1470 #endif /* CONFIG_NO_RADIUS */
1474 static void _ieee802_1x_finished(void *ctx
, void *sta_ctx
, int success
,
1477 struct hostapd_data
*hapd
= ctx
;
1478 struct sta_info
*sta
= sta_ctx
;
1480 rsn_preauth_finished(hapd
, sta
, success
);
1482 ieee802_1x_finished(hapd
, sta
, success
);
1486 static int ieee802_1x_get_eap_user(void *ctx
, const u8
*identity
,
1487 size_t identity_len
, int phase2
,
1488 struct eap_user
*user
)
1490 struct hostapd_data
*hapd
= ctx
;
1491 const struct hostapd_eap_user
*eap_user
;
1494 eap_user
= hostapd_get_eap_user(hapd
->conf
, identity
,
1495 identity_len
, phase2
);
1496 if (eap_user
== NULL
)
1499 os_memset(user
, 0, sizeof(*user
));
1500 user
->phase2
= phase2
;
1501 count
= EAP_USER_MAX_METHODS
;
1502 if (count
> EAP_MAX_METHODS
)
1503 count
= EAP_MAX_METHODS
;
1504 for (i
= 0; i
< count
; i
++) {
1505 user
->methods
[i
].vendor
= eap_user
->methods
[i
].vendor
;
1506 user
->methods
[i
].method
= eap_user
->methods
[i
].method
;
1509 if (eap_user
->password
) {
1510 user
->password
= os_malloc(eap_user
->password_len
);
1511 if (user
->password
== NULL
)
1513 os_memcpy(user
->password
, eap_user
->password
,
1514 eap_user
->password_len
);
1515 user
->password_len
= eap_user
->password_len
;
1517 user
->force_version
= eap_user
->force_version
;
1518 user
->ttls_auth
= eap_user
->ttls_auth
;
1524 static int ieee802_1x_sta_entry_alive(void *ctx
, const u8
*addr
)
1526 struct hostapd_data
*hapd
= ctx
;
1527 struct sta_info
*sta
;
1528 sta
= ap_get_sta(hapd
, addr
);
1529 if (sta
== NULL
|| sta
->eapol_sm
== NULL
)
1535 static void ieee802_1x_logger(void *ctx
, const u8
*addr
,
1536 eapol_logger_level level
, const char *txt
)
1538 #ifndef CONFIG_NO_HOSTAPD_LOGGER
1539 struct hostapd_data
*hapd
= ctx
;
1543 case EAPOL_LOGGER_WARNING
:
1544 hlevel
= HOSTAPD_LEVEL_WARNING
;
1546 case EAPOL_LOGGER_INFO
:
1547 hlevel
= HOSTAPD_LEVEL_INFO
;
1549 case EAPOL_LOGGER_DEBUG
:
1551 hlevel
= HOSTAPD_LEVEL_DEBUG
;
1555 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE8021X
, hlevel
, "%s",
1557 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
1561 static void ieee802_1x_set_port_authorized(void *ctx
, void *sta_ctx
,
1564 struct hostapd_data
*hapd
= ctx
;
1565 struct sta_info
*sta
= sta_ctx
;
1566 ieee802_1x_set_sta_authorized(hapd
, sta
, authorized
);
1570 static void _ieee802_1x_abort_auth(void *ctx
, void *sta_ctx
)
1572 struct hostapd_data
*hapd
= ctx
;
1573 struct sta_info
*sta
= sta_ctx
;
1574 ieee802_1x_abort_auth(hapd
, sta
);
1578 static void _ieee802_1x_tx_key(void *ctx
, void *sta_ctx
)
1580 struct hostapd_data
*hapd
= ctx
;
1581 struct sta_info
*sta
= sta_ctx
;
1582 ieee802_1x_tx_key(hapd
, sta
);
1586 static void ieee802_1x_eapol_event(void *ctx
, void *sta_ctx
,
1587 enum eapol_event type
)
1589 /* struct hostapd_data *hapd = ctx; */
1590 struct sta_info
*sta
= sta_ctx
;
1592 case EAPOL_AUTH_SM_CHANGE
:
1593 wpa_auth_sm_notify(sta
->wpa_sm
);
1595 case EAPOL_AUTH_REAUTHENTICATE
:
1596 wpa_auth_sm_event(sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
1602 int ieee802_1x_init(struct hostapd_data
*hapd
)
1605 struct eapol_auth_config conf
;
1606 struct eapol_auth_cb cb
;
1608 os_memset(&conf
, 0, sizeof(conf
));
1610 conf
.eap_reauth_period
= hapd
->conf
->eap_reauth_period
;
1611 conf
.wpa
= hapd
->conf
->wpa
;
1612 conf
.individual_wep_key_len
= hapd
->conf
->individual_wep_key_len
;
1613 conf
.eap_server
= hapd
->conf
->eap_server
;
1614 conf
.ssl_ctx
= hapd
->ssl_ctx
;
1615 conf
.eap_sim_db_priv
= hapd
->eap_sim_db_priv
;
1616 conf
.eap_req_id_text
= hapd
->conf
->eap_req_id_text
;
1617 conf
.eap_req_id_text_len
= hapd
->conf
->eap_req_id_text_len
;
1618 conf
.pac_opaque_encr_key
= hapd
->conf
->pac_opaque_encr_key
;
1619 conf
.eap_fast_a_id
= hapd
->conf
->eap_fast_a_id
;
1620 conf
.eap_fast_a_id_len
= hapd
->conf
->eap_fast_a_id_len
;
1621 conf
.eap_fast_a_id_info
= hapd
->conf
->eap_fast_a_id_info
;
1622 conf
.eap_fast_prov
= hapd
->conf
->eap_fast_prov
;
1623 conf
.pac_key_lifetime
= hapd
->conf
->pac_key_lifetime
;
1624 conf
.pac_key_refresh_time
= hapd
->conf
->pac_key_refresh_time
;
1625 conf
.eap_sim_aka_result_ind
= hapd
->conf
->eap_sim_aka_result_ind
;
1626 conf
.tnc
= hapd
->conf
->tnc
;
1627 conf
.wps
= hapd
->wps
;
1629 os_memset(&cb
, 0, sizeof(cb
));
1630 cb
.eapol_send
= ieee802_1x_eapol_send
;
1631 cb
.aaa_send
= ieee802_1x_aaa_send
;
1632 cb
.finished
= _ieee802_1x_finished
;
1633 cb
.get_eap_user
= ieee802_1x_get_eap_user
;
1634 cb
.sta_entry_alive
= ieee802_1x_sta_entry_alive
;
1635 cb
.logger
= ieee802_1x_logger
;
1636 cb
.set_port_authorized
= ieee802_1x_set_port_authorized
;
1637 cb
.abort_auth
= _ieee802_1x_abort_auth
;
1638 cb
.tx_key
= _ieee802_1x_tx_key
;
1639 cb
.eapol_event
= ieee802_1x_eapol_event
;
1641 hapd
->eapol_auth
= eapol_auth_init(&conf
, &cb
);
1642 if (hapd
->eapol_auth
== NULL
)
1645 if ((hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
) &&
1646 hapd
->drv
.set_drv_ieee8021x(hapd
, hapd
->conf
->iface
, 1))
1649 #ifndef CONFIG_NO_RADIUS
1650 if (radius_client_register(hapd
->radius
, RADIUS_AUTH
,
1651 ieee802_1x_receive_auth
, hapd
))
1653 #endif /* CONFIG_NO_RADIUS */
1655 if (hapd
->conf
->default_wep_key_len
) {
1656 for (i
= 0; i
< 4; i
++)
1657 hapd
->drv
.set_key(hapd
->conf
->iface
, hapd
,
1658 WPA_ALG_NONE
, NULL
, i
, 0, NULL
, 0,
1661 ieee802_1x_rekey(hapd
, NULL
);
1663 if (hapd
->eapol_auth
->default_wep_key
== NULL
)
1671 void ieee802_1x_deinit(struct hostapd_data
*hapd
)
1673 eloop_cancel_timeout(ieee802_1x_rekey
, hapd
, NULL
);
1675 if (hapd
->driver
!= NULL
&&
1676 (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
))
1677 hapd
->drv
.set_drv_ieee8021x(hapd
, hapd
->conf
->iface
, 0);
1679 eapol_auth_deinit(hapd
->eapol_auth
);
1680 hapd
->eapol_auth
= NULL
;
1684 int ieee802_1x_tx_status(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1685 const u8
*buf
, size_t len
, int ack
)
1687 struct ieee80211_hdr
*hdr
;
1688 struct ieee802_1x_hdr
*xhdr
;
1689 struct ieee802_1x_eapol_key
*key
;
1691 const unsigned char rfc1042_hdr
[ETH_ALEN
] =
1692 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
1696 if (len
< sizeof(*hdr
) + sizeof(rfc1042_hdr
) + 2 + sizeof(*xhdr
))
1699 hdr
= (struct ieee80211_hdr
*) buf
;
1700 pos
= (u8
*) (hdr
+ 1);
1701 if (os_memcmp(pos
, rfc1042_hdr
, sizeof(rfc1042_hdr
)) != 0)
1703 pos
+= sizeof(rfc1042_hdr
);
1704 if (WPA_GET_BE16(pos
) != ETH_P_PAE
)
1708 xhdr
= (struct ieee802_1x_hdr
*) pos
;
1709 pos
+= sizeof(*xhdr
);
1711 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
" TX status - version=%d "
1712 "type=%d length=%d - ack=%d",
1713 MAC2STR(sta
->addr
), xhdr
->version
, xhdr
->type
,
1714 be_to_host16(xhdr
->length
), ack
);
1716 /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant
1717 * or Authenticator state machines, but EAPOL-Key packets are not
1718 * retransmitted in case of failure. Try to re-sent failed EAPOL-Key
1719 * packets couple of times because otherwise STA keys become
1720 * unsynchronized with AP. */
1721 if (xhdr
->type
== IEEE802_1X_TYPE_EAPOL_KEY
&& !ack
&&
1722 pos
+ sizeof(*key
) <= buf
+ len
) {
1723 key
= (struct ieee802_1x_eapol_key
*) pos
;
1724 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1725 HOSTAPD_LEVEL_DEBUG
, "did not Ack EAPOL-Key "
1726 "frame (%scast index=%d)",
1727 key
->key_index
& BIT(7) ? "uni" : "broad",
1728 key
->key_index
& ~BIT(7));
1729 /* TODO: re-send EAPOL-Key couple of times (with short delay
1730 * between them?). If all attempt fail, report error and
1731 * deauthenticate STA so that it will get new keys when
1732 * authenticating again (e.g., after returning in range).
1733 * Separate limit/transmit state needed both for unicast and
1734 * broadcast keys(?) */
1736 /* TODO: could move unicast key configuration from ieee802_1x_tx_key()
1737 * to here and change the key only if the EAPOL-Key packet was Acked.
1744 u8
* ieee802_1x_get_identity(struct eapol_state_machine
*sm
, size_t *len
)
1746 if (sm
== NULL
|| sm
->identity
== NULL
)
1749 *len
= sm
->identity_len
;
1750 return sm
->identity
;
1754 u8
* ieee802_1x_get_radius_class(struct eapol_state_machine
*sm
, size_t *len
,
1757 if (sm
== NULL
|| sm
->radius_class
.attr
== NULL
||
1758 idx
>= (int) sm
->radius_class
.count
)
1761 *len
= sm
->radius_class
.attr
[idx
].len
;
1762 return sm
->radius_class
.attr
[idx
].data
;
1766 const u8
* ieee802_1x_get_key(struct eapol_state_machine
*sm
, size_t *len
)
1771 *len
= sm
->eap_if
->eapKeyDataLen
;
1772 return sm
->eap_if
->eapKeyData
;
1776 void ieee802_1x_notify_port_enabled(struct eapol_state_machine
*sm
,
1781 sm
->eap_if
->portEnabled
= enabled
? TRUE
: FALSE
;
1782 eapol_auth_step(sm
);
1786 void ieee802_1x_notify_port_valid(struct eapol_state_machine
*sm
,
1791 sm
->portValid
= valid
? TRUE
: FALSE
;
1792 eapol_auth_step(sm
);
1796 void ieee802_1x_notify_pre_auth(struct eapol_state_machine
*sm
, int pre_auth
)
1801 sm
->flags
|= EAPOL_SM_PREAUTH
;
1803 sm
->flags
&= ~EAPOL_SM_PREAUTH
;
1807 static const char * bool_txt(Boolean
bool)
1809 return bool ? "TRUE" : "FALSE";
1813 int ieee802_1x_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1820 int ieee802_1x_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1821 char *buf
, size_t buflen
)
1824 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1829 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1830 "dot1xPaePortNumber=%d\n"
1831 "dot1xPaePortProtocolVersion=%d\n"
1832 "dot1xPaePortCapabilities=1\n"
1833 "dot1xPaePortInitialize=%d\n"
1834 "dot1xPaePortReauthenticate=FALSE\n",
1838 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1842 /* dot1xAuthConfigTable */
1843 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1844 "dot1xAuthPaeState=%d\n"
1845 "dot1xAuthBackendAuthState=%d\n"
1846 "dot1xAuthAdminControlledDirections=%d\n"
1847 "dot1xAuthOperControlledDirections=%d\n"
1848 "dot1xAuthAuthControlledPortStatus=%d\n"
1849 "dot1xAuthAuthControlledPortControl=%d\n"
1850 "dot1xAuthQuietPeriod=%u\n"
1851 "dot1xAuthServerTimeout=%u\n"
1852 "dot1xAuthReAuthPeriod=%u\n"
1853 "dot1xAuthReAuthEnabled=%s\n"
1854 "dot1xAuthKeyTxEnabled=%s\n",
1855 sm
->auth_pae_state
+ 1,
1856 sm
->be_auth_state
+ 1,
1857 sm
->adminControlledDirections
,
1858 sm
->operControlledDirections
,
1864 bool_txt(sm
->reAuthEnabled
),
1865 bool_txt(sm
->keyTxEnabled
));
1866 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1870 /* dot1xAuthStatsTable */
1871 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1872 "dot1xAuthEapolFramesRx=%u\n"
1873 "dot1xAuthEapolFramesTx=%u\n"
1874 "dot1xAuthEapolStartFramesRx=%u\n"
1875 "dot1xAuthEapolLogoffFramesRx=%u\n"
1876 "dot1xAuthEapolRespIdFramesRx=%u\n"
1877 "dot1xAuthEapolRespFramesRx=%u\n"
1878 "dot1xAuthEapolReqIdFramesTx=%u\n"
1879 "dot1xAuthEapolReqFramesTx=%u\n"
1880 "dot1xAuthInvalidEapolFramesRx=%u\n"
1881 "dot1xAuthEapLengthErrorFramesRx=%u\n"
1882 "dot1xAuthLastEapolFrameVersion=%u\n"
1883 "dot1xAuthLastEapolFrameSource=" MACSTR
"\n",
1884 sm
->dot1xAuthEapolFramesRx
,
1885 sm
->dot1xAuthEapolFramesTx
,
1886 sm
->dot1xAuthEapolStartFramesRx
,
1887 sm
->dot1xAuthEapolLogoffFramesRx
,
1888 sm
->dot1xAuthEapolRespIdFramesRx
,
1889 sm
->dot1xAuthEapolRespFramesRx
,
1890 sm
->dot1xAuthEapolReqIdFramesTx
,
1891 sm
->dot1xAuthEapolReqFramesTx
,
1892 sm
->dot1xAuthInvalidEapolFramesRx
,
1893 sm
->dot1xAuthEapLengthErrorFramesRx
,
1894 sm
->dot1xAuthLastEapolFrameVersion
,
1896 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1900 /* dot1xAuthDiagTable */
1901 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1902 "dot1xAuthEntersConnecting=%u\n"
1903 "dot1xAuthEapLogoffsWhileConnecting=%u\n"
1904 "dot1xAuthEntersAuthenticating=%u\n"
1905 "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n"
1906 "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n"
1907 "dot1xAuthAuthFailWhileAuthenticating=%u\n"
1908 "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n"
1909 "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n"
1910 "dot1xAuthAuthReauthsWhileAuthenticated=%u\n"
1911 "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n"
1912 "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n"
1913 "dot1xAuthBackendResponses=%u\n"
1914 "dot1xAuthBackendAccessChallenges=%u\n"
1915 "dot1xAuthBackendOtherRequestsToSupplicant=%u\n"
1916 "dot1xAuthBackendAuthSuccesses=%u\n"
1917 "dot1xAuthBackendAuthFails=%u\n",
1918 sm
->authEntersConnecting
,
1919 sm
->authEapLogoffsWhileConnecting
,
1920 sm
->authEntersAuthenticating
,
1921 sm
->authAuthSuccessesWhileAuthenticating
,
1922 sm
->authAuthTimeoutsWhileAuthenticating
,
1923 sm
->authAuthFailWhileAuthenticating
,
1924 sm
->authAuthEapStartsWhileAuthenticating
,
1925 sm
->authAuthEapLogoffWhileAuthenticating
,
1926 sm
->authAuthReauthsWhileAuthenticated
,
1927 sm
->authAuthEapStartsWhileAuthenticated
,
1928 sm
->authAuthEapLogoffWhileAuthenticated
,
1929 sm
->backendResponses
,
1930 sm
->backendAccessChallenges
,
1931 sm
->backendOtherRequestsToSupplicant
,
1932 sm
->backendAuthSuccesses
,
1933 sm
->backendAuthFails
);
1934 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1938 /* dot1xAuthSessionStatsTable */
1939 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1940 /* TODO: dot1xAuthSessionOctetsRx */
1941 /* TODO: dot1xAuthSessionOctetsTx */
1942 /* TODO: dot1xAuthSessionFramesRx */
1943 /* TODO: dot1xAuthSessionFramesTx */
1944 "dot1xAuthSessionId=%08X-%08X\n"
1945 "dot1xAuthSessionAuthenticMethod=%d\n"
1946 "dot1xAuthSessionTime=%u\n"
1947 "dot1xAuthSessionTerminateCause=999\n"
1948 "dot1xAuthSessionUserName=%s\n",
1949 sta
->acct_session_id_hi
, sta
->acct_session_id_lo
,
1950 (wpa_key_mgmt_wpa_ieee8021x(
1951 wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) ?
1953 (unsigned int) (time(NULL
) -
1954 sta
->acct_session_start
),
1956 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1964 static void ieee802_1x_finished(struct hostapd_data
*hapd
,
1965 struct sta_info
*sta
, int success
)
1969 /* TODO: get PMKLifetime from WPA parameters */
1970 static const int dot11RSNAConfigPMKLifetime
= 43200;
1972 key
= ieee802_1x_get_key(sta
->eapol_sm
, &len
);
1973 if (success
&& key
&& len
>= PMK_LEN
&&
1974 wpa_auth_pmksa_add(sta
->wpa_sm
, key
, dot11RSNAConfigPMKLifetime
,
1975 sta
->eapol_sm
) == 0) {
1976 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
1977 HOSTAPD_LEVEL_DEBUG
,
1978 "Added PMKSA cache entry (IEEE 802.1X)");