2 * hostapd / IEEE 802.1X-2004 Authenticator
3 * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
12 #endif /* CONFIG_SQLITE */
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "crypto/md5.h"
17 #include "crypto/crypto.h"
18 #include "crypto/random.h"
19 #include "common/ieee802_11_defs.h"
20 #include "radius/radius.h"
21 #include "radius/radius_client.h"
22 #include "eap_server/eap.h"
23 #include "eap_common/eap_wsc_common.h"
24 #include "eapol_auth/eapol_auth_sm.h"
25 #include "eapol_auth/eapol_auth_sm_i.h"
28 #include "accounting.h"
31 #include "preauth_auth.h"
32 #include "pmksa_cache_auth.h"
33 #include "ap_config.h"
34 #include "ap_drv_ops.h"
35 #include "wps_hostapd.h"
37 /* FIX: Not really a good thing to require ieee802_11.h here.. (FILS) */
38 #include "ieee802_11.h"
39 #include "ieee802_1x.h"
40 #include "wpa_auth_kay.h"
44 static void ieee802_1x_wnm_notif_send(void *eloop_ctx
, void *timeout_ctx
);
45 #endif /* CONFIG_HS20 */
46 static void ieee802_1x_finished(struct hostapd_data
*hapd
,
47 struct sta_info
*sta
, int success
,
51 static void ieee802_1x_send(struct hostapd_data
*hapd
, struct sta_info
*sta
,
52 u8 type
, const u8
*data
, size_t datalen
)
55 struct ieee802_1x_hdr
*xhdr
;
59 len
= sizeof(*xhdr
) + datalen
;
62 wpa_printf(MSG_ERROR
, "malloc() failed for "
63 "ieee802_1x_send(len=%lu)",
68 xhdr
= (struct ieee802_1x_hdr
*) buf
;
69 xhdr
->version
= hapd
->conf
->eapol_version
;
71 if (xhdr
->version
> 2 && hapd
->conf
->macsec_policy
== 0)
73 #endif /* CONFIG_MACSEC */
75 xhdr
->length
= host_to_be16(datalen
);
77 if (datalen
> 0 && data
!= NULL
)
78 os_memcpy(xhdr
+ 1, data
, datalen
);
80 if (wpa_auth_pairwise_set(sta
->wpa_sm
))
82 #ifdef CONFIG_TESTING_OPTIONS
83 if (hapd
->ext_eapol_frame_io
) {
84 size_t hex_len
= 2 * len
+ 1;
85 char *hex
= os_malloc(hex_len
);
88 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
89 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
90 "EAPOL-TX " MACSTR
" %s",
91 MAC2STR(sta
->addr
), hex
);
95 #endif /* CONFIG_TESTING_OPTIONS */
96 if (sta
->flags
& WLAN_STA_PREAUTH
) {
97 rsn_preauth_send(hapd
, sta
, buf
, len
);
99 hostapd_drv_hapd_send_eapol(
100 hapd
, sta
->addr
, buf
, len
,
101 encrypt
, hostapd_sta_flags_to_drv(sta
->flags
));
108 void ieee802_1x_set_sta_authorized(struct hostapd_data
*hapd
,
109 struct sta_info
*sta
, int authorized
)
113 if (sta
->flags
& WLAN_STA_PREAUTH
)
117 ap_sta_set_authorized(hapd
, sta
, 1);
118 res
= hostapd_set_authorized(hapd
, sta
, 1);
119 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
120 HOSTAPD_LEVEL_DEBUG
, "authorizing port");
122 ap_sta_set_authorized(hapd
, sta
, 0);
123 res
= hostapd_set_authorized(hapd
, sta
, 0);
124 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
125 HOSTAPD_LEVEL_DEBUG
, "unauthorizing port");
128 if (res
&& errno
!= ENOENT
) {
129 wpa_printf(MSG_DEBUG
, "Could not set station " MACSTR
130 " flags for kernel driver (errno=%d).",
131 MAC2STR(sta
->addr
), errno
);
135 os_get_reltime(&sta
->connected_time
);
136 accounting_sta_start(hapd
, sta
);
142 #ifndef CONFIG_NO_RC4
144 static void ieee802_1x_tx_key_one(struct hostapd_data
*hapd
,
145 struct sta_info
*sta
,
146 int idx
, int broadcast
,
147 u8
*key_data
, size_t key_len
)
150 struct ieee802_1x_hdr
*hdr
;
151 struct ieee802_1x_eapol_key
*key
;
152 size_t len
, ekey_len
;
153 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
158 len
= sizeof(*key
) + key_len
;
159 buf
= os_zalloc(sizeof(*hdr
) + len
);
163 hdr
= (struct ieee802_1x_hdr
*) buf
;
164 key
= (struct ieee802_1x_eapol_key
*) (hdr
+ 1);
165 key
->type
= EAPOL_KEY_TYPE_RC4
;
166 WPA_PUT_BE16(key
->key_length
, key_len
);
167 wpa_get_ntp_timestamp(key
->replay_counter
);
168 if (os_memcmp(key
->replay_counter
,
169 hapd
->last_1x_eapol_key_replay_counter
,
170 IEEE8021X_REPLAY_COUNTER_LEN
) <= 0) {
171 /* NTP timestamp did not increment from last EAPOL-Key frame;
172 * use previously used value + 1 instead. */
173 inc_byte_array(hapd
->last_1x_eapol_key_replay_counter
,
174 IEEE8021X_REPLAY_COUNTER_LEN
);
175 os_memcpy(key
->replay_counter
,
176 hapd
->last_1x_eapol_key_replay_counter
,
177 IEEE8021X_REPLAY_COUNTER_LEN
);
179 os_memcpy(hapd
->last_1x_eapol_key_replay_counter
,
181 IEEE8021X_REPLAY_COUNTER_LEN
);
184 if (random_get_bytes(key
->key_iv
, sizeof(key
->key_iv
))) {
185 wpa_printf(MSG_ERROR
, "Could not get random numbers");
190 key
->key_index
= idx
| (broadcast
? 0 : BIT(7));
191 if (hapd
->conf
->eapol_key_index_workaround
) {
192 /* According to some information, WinXP Supplicant seems to
193 * interpret bit7 as an indication whether the key is to be
194 * activated, so make it possible to enable workaround that
195 * sets this bit for all keys. */
196 key
->key_index
|= BIT(7);
199 /* Key is encrypted using "Key-IV + MSK[0..31]" as the RC4-key and
200 * MSK[32..63] is used to sign the message. */
201 if (sm
->eap_if
->eapKeyData
== NULL
|| sm
->eap_if
->eapKeyDataLen
< 64) {
202 wpa_printf(MSG_ERROR
, "No eapKeyData available for encrypting "
203 "and signing EAPOL-Key");
207 os_memcpy((u8
*) (key
+ 1), key_data
, key_len
);
208 ekey_len
= sizeof(key
->key_iv
) + 32;
209 ekey
= os_malloc(ekey_len
);
211 wpa_printf(MSG_ERROR
, "Could not encrypt key");
215 os_memcpy(ekey
, key
->key_iv
, sizeof(key
->key_iv
));
216 os_memcpy(ekey
+ sizeof(key
->key_iv
), sm
->eap_if
->eapKeyData
, 32);
217 rc4_skip(ekey
, ekey_len
, 0, (u8
*) (key
+ 1), key_len
);
220 /* This header is needed here for HMAC-MD5, but it will be regenerated
221 * in ieee802_1x_send() */
222 hdr
->version
= hapd
->conf
->eapol_version
;
224 if (hdr
->version
> 2)
226 #endif /* CONFIG_MACSEC */
227 hdr
->type
= IEEE802_1X_TYPE_EAPOL_KEY
;
228 hdr
->length
= host_to_be16(len
);
229 hmac_md5(sm
->eap_if
->eapKeyData
+ 32, 32, buf
, sizeof(*hdr
) + len
,
232 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Sending EAPOL-Key to " MACSTR
233 " (%s index=%d)", MAC2STR(sm
->addr
),
234 broadcast
? "broadcast" : "unicast", idx
);
235 ieee802_1x_send(hapd
, sta
, IEEE802_1X_TYPE_EAPOL_KEY
, (u8
*) key
, len
);
237 sta
->eapol_sm
->dot1xAuthEapolFramesTx
++;
242 static void ieee802_1x_tx_key(struct hostapd_data
*hapd
, struct sta_info
*sta
)
244 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
245 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
247 if (sm
== NULL
|| !sm
->eap_if
->eapKeyData
)
250 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR
,
253 #ifndef CONFIG_NO_VLAN
254 if (sta
->vlan_id
> 0) {
255 wpa_printf(MSG_ERROR
, "Using WEP with vlans is not supported.");
258 #endif /* CONFIG_NO_VLAN */
260 if (eapol
->default_wep_key
) {
261 ieee802_1x_tx_key_one(hapd
, sta
, eapol
->default_wep_key_idx
, 1,
262 eapol
->default_wep_key
,
263 hapd
->conf
->default_wep_key_len
);
266 if (hapd
->conf
->individual_wep_key_len
> 0) {
268 ikey
= os_malloc(hapd
->conf
->individual_wep_key_len
);
270 random_get_bytes(ikey
, hapd
->conf
->individual_wep_key_len
))
272 wpa_printf(MSG_ERROR
, "Could not generate random "
273 "individual WEP key.");
278 wpa_hexdump_key(MSG_DEBUG
, "Individual WEP key",
279 ikey
, hapd
->conf
->individual_wep_key_len
);
281 ieee802_1x_tx_key_one(hapd
, sta
, 0, 0, ikey
,
282 hapd
->conf
->individual_wep_key_len
);
284 /* TODO: set encryption in TX callback, i.e., only after STA
285 * has ACKed EAPOL-Key frame */
286 if (hostapd_drv_set_key(hapd
->conf
->iface
, hapd
, WPA_ALG_WEP
,
287 sta
->addr
, 0, 1, NULL
, 0, ikey
,
288 hapd
->conf
->individual_wep_key_len
)) {
289 wpa_printf(MSG_ERROR
, "Could not set individual WEP "
297 #endif /* CONFIG_NO_RC4 */
298 #endif /* CONFIG_FIPS */
301 const char *radius_mode_txt(struct hostapd_data
*hapd
)
303 switch (hapd
->iface
->conf
->hw_mode
) {
304 case HOSTAPD_MODE_IEEE80211AD
:
306 case HOSTAPD_MODE_IEEE80211A
:
308 case HOSTAPD_MODE_IEEE80211G
:
310 case HOSTAPD_MODE_IEEE80211B
:
317 int radius_sta_rate(struct hostapd_data
*hapd
, struct sta_info
*sta
)
322 for (i
= 0; i
< sta
->supported_rates_len
; i
++)
323 if ((sta
->supported_rates
[i
] & 0x7f) > rate
)
324 rate
= sta
->supported_rates
[i
] & 0x7f;
330 #ifndef CONFIG_NO_RADIUS
331 static void ieee802_1x_learn_identity(struct hostapd_data
*hapd
,
332 struct eapol_state_machine
*sm
,
333 const u8
*eap
, size_t len
)
337 const struct eap_hdr
*hdr
= (const struct eap_hdr
*) eap
;
339 if (len
<= sizeof(struct eap_hdr
) ||
340 (hdr
->code
== EAP_CODE_RESPONSE
&&
341 eap
[sizeof(struct eap_hdr
)] != EAP_TYPE_IDENTITY
) ||
342 (hdr
->code
== EAP_CODE_INITIATE
&&
343 eap
[sizeof(struct eap_hdr
)] != EAP_ERP_TYPE_REAUTH
) ||
344 (hdr
->code
!= EAP_CODE_RESPONSE
&&
345 hdr
->code
!= EAP_CODE_INITIATE
))
348 eap_erp_update_identity(sm
->eap
, eap
, len
);
349 identity
= eap_get_identity(sm
->eap
, &identity_len
);
350 if (identity
== NULL
)
353 /* Save station identity for future RADIUS packets */
354 os_free(sm
->identity
);
355 sm
->identity
= (u8
*) dup_binstr(identity
, identity_len
);
356 if (sm
->identity
== NULL
) {
357 sm
->identity_len
= 0;
361 sm
->identity_len
= identity_len
;
362 hostapd_logger(hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
363 HOSTAPD_LEVEL_DEBUG
, "STA identity '%s'", sm
->identity
);
364 sm
->dot1xAuthEapolRespIdFramesRx
++;
368 static int add_common_radius_sta_attr_rsn(struct hostapd_data
*hapd
,
369 struct hostapd_radius_attr
*req_attr
,
370 struct sta_info
*sta
,
371 struct radius_msg
*msg
)
376 ver
= wpa_auth_sta_wpa_version(sta
->wpa_sm
);
377 val
= wpa_auth_get_pairwise(sta
->wpa_sm
);
378 suite
= wpa_cipher_to_suite(ver
, val
);
380 !hostapd_config_get_radius_attr(req_attr
,
381 RADIUS_ATTR_WLAN_PAIRWISE_CIPHER
) &&
382 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_WLAN_PAIRWISE_CIPHER
,
384 wpa_printf(MSG_ERROR
, "Could not add WLAN-Pairwise-Cipher");
388 suite
= wpa_cipher_to_suite(((hapd
->conf
->wpa
& 0x2) ||
390 WPA_PROTO_RSN
: WPA_PROTO_WPA
,
391 hapd
->conf
->wpa_group
);
392 if (!hostapd_config_get_radius_attr(req_attr
,
393 RADIUS_ATTR_WLAN_GROUP_CIPHER
) &&
394 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_WLAN_GROUP_CIPHER
,
396 wpa_printf(MSG_ERROR
, "Could not add WLAN-Group-Cipher");
400 val
= wpa_auth_sta_key_mgmt(sta
->wpa_sm
);
401 suite
= wpa_akm_to_suite(val
);
403 !hostapd_config_get_radius_attr(req_attr
,
404 RADIUS_ATTR_WLAN_AKM_SUITE
) &&
405 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_WLAN_AKM_SUITE
,
407 wpa_printf(MSG_ERROR
, "Could not add WLAN-AKM-Suite");
411 #ifdef CONFIG_IEEE80211W
412 if (hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
413 suite
= wpa_cipher_to_suite(WPA_PROTO_RSN
,
414 hapd
->conf
->group_mgmt_cipher
);
415 if (!hostapd_config_get_radius_attr(
416 req_attr
, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER
) &&
417 !radius_msg_add_attr_int32(
418 msg
, RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER
, suite
)) {
419 wpa_printf(MSG_ERROR
,
420 "Could not add WLAN-Group-Mgmt-Cipher");
424 #endif /* CONFIG_IEEE80211W */
430 static int add_common_radius_sta_attr(struct hostapd_data
*hapd
,
431 struct hostapd_radius_attr
*req_attr
,
432 struct sta_info
*sta
,
433 struct radius_msg
*msg
)
437 if (!hostapd_config_get_radius_attr(req_attr
,
438 RADIUS_ATTR_SERVICE_TYPE
) &&
439 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_SERVICE_TYPE
,
440 RADIUS_SERVICE_TYPE_FRAMED
)) {
441 wpa_printf(MSG_ERROR
, "Could not add Service-Type");
445 if (!hostapd_config_get_radius_attr(req_attr
,
446 RADIUS_ATTR_NAS_PORT
) &&
448 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_NAS_PORT
, sta
->aid
)) {
449 wpa_printf(MSG_ERROR
, "Could not add NAS-Port");
453 os_snprintf(buf
, sizeof(buf
), RADIUS_802_1X_ADDR_FORMAT
,
455 buf
[sizeof(buf
) - 1] = '\0';
456 if (!radius_msg_add_attr(msg
, RADIUS_ATTR_CALLING_STATION_ID
,
457 (u8
*) buf
, os_strlen(buf
))) {
458 wpa_printf(MSG_ERROR
, "Could not add Calling-Station-Id");
462 if (sta
->flags
& WLAN_STA_PREAUTH
) {
463 os_strlcpy(buf
, "IEEE 802.11i Pre-Authentication",
466 os_snprintf(buf
, sizeof(buf
), "CONNECT %d%sMbps %s",
467 radius_sta_rate(hapd
, sta
) / 2,
468 (radius_sta_rate(hapd
, sta
) & 1) ? ".5" : "",
469 radius_mode_txt(hapd
));
470 buf
[sizeof(buf
) - 1] = '\0';
472 if (!hostapd_config_get_radius_attr(req_attr
,
473 RADIUS_ATTR_CONNECT_INFO
) &&
474 !radius_msg_add_attr(msg
, RADIUS_ATTR_CONNECT_INFO
,
475 (u8
*) buf
, os_strlen(buf
))) {
476 wpa_printf(MSG_ERROR
, "Could not add Connect-Info");
480 if (sta
->acct_session_id
) {
481 os_snprintf(buf
, sizeof(buf
), "%016llX",
482 (unsigned long long) sta
->acct_session_id
);
483 if (!radius_msg_add_attr(msg
, RADIUS_ATTR_ACCT_SESSION_ID
,
484 (u8
*) buf
, os_strlen(buf
))) {
485 wpa_printf(MSG_ERROR
, "Could not add Acct-Session-Id");
490 if ((hapd
->conf
->wpa
& 2) &&
491 !hapd
->conf
->disable_pmksa_caching
&&
492 sta
->eapol_sm
&& sta
->eapol_sm
->acct_multi_session_id
) {
493 os_snprintf(buf
, sizeof(buf
), "%016llX",
495 sta
->eapol_sm
->acct_multi_session_id
);
496 if (!radius_msg_add_attr(
497 msg
, RADIUS_ATTR_ACCT_MULTI_SESSION_ID
,
498 (u8
*) buf
, os_strlen(buf
))) {
500 "Could not add Acct-Multi-Session-Id");
505 #ifdef CONFIG_IEEE80211R_AP
506 if (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
508 (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) ||
509 sta
->auth_alg
== WLAN_AUTH_FT
) &&
510 !hostapd_config_get_radius_attr(req_attr
,
511 RADIUS_ATTR_MOBILITY_DOMAIN_ID
) &&
512 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_MOBILITY_DOMAIN_ID
,
514 hapd
->conf
->mobility_domain
))) {
515 wpa_printf(MSG_ERROR
, "Could not add Mobility-Domain-Id");
518 #endif /* CONFIG_IEEE80211R_AP */
520 if ((hapd
->conf
->wpa
|| hapd
->conf
->osen
) && sta
->wpa_sm
&&
521 add_common_radius_sta_attr_rsn(hapd
, req_attr
, sta
, msg
) < 0)
528 int add_common_radius_attr(struct hostapd_data
*hapd
,
529 struct hostapd_radius_attr
*req_attr
,
530 struct sta_info
*sta
,
531 struct radius_msg
*msg
)
534 struct hostapd_radius_attr
*attr
;
537 if (!hostapd_config_get_radius_attr(req_attr
,
538 RADIUS_ATTR_NAS_IP_ADDRESS
) &&
539 hapd
->conf
->own_ip_addr
.af
== AF_INET
&&
540 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IP_ADDRESS
,
541 (u8
*) &hapd
->conf
->own_ip_addr
.u
.v4
, 4)) {
542 wpa_printf(MSG_ERROR
, "Could not add NAS-IP-Address");
547 if (!hostapd_config_get_radius_attr(req_attr
,
548 RADIUS_ATTR_NAS_IPV6_ADDRESS
) &&
549 hapd
->conf
->own_ip_addr
.af
== AF_INET6
&&
550 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IPV6_ADDRESS
,
551 (u8
*) &hapd
->conf
->own_ip_addr
.u
.v6
, 16)) {
552 wpa_printf(MSG_ERROR
, "Could not add NAS-IPv6-Address");
555 #endif /* CONFIG_IPV6 */
557 if (!hostapd_config_get_radius_attr(req_attr
,
558 RADIUS_ATTR_NAS_IDENTIFIER
) &&
559 hapd
->conf
->nas_identifier
&&
560 !radius_msg_add_attr(msg
, RADIUS_ATTR_NAS_IDENTIFIER
,
561 (u8
*) hapd
->conf
->nas_identifier
,
562 os_strlen(hapd
->conf
->nas_identifier
))) {
563 wpa_printf(MSG_ERROR
, "Could not add NAS-Identifier");
567 len
= os_snprintf(buf
, sizeof(buf
), RADIUS_802_1X_ADDR_FORMAT
":",
568 MAC2STR(hapd
->own_addr
));
569 os_memcpy(&buf
[len
], hapd
->conf
->ssid
.ssid
,
570 hapd
->conf
->ssid
.ssid_len
);
571 len
+= hapd
->conf
->ssid
.ssid_len
;
572 if (!hostapd_config_get_radius_attr(req_attr
,
573 RADIUS_ATTR_CALLED_STATION_ID
) &&
574 !radius_msg_add_attr(msg
, RADIUS_ATTR_CALLED_STATION_ID
,
576 wpa_printf(MSG_ERROR
, "Could not add Called-Station-Id");
580 if (!hostapd_config_get_radius_attr(req_attr
,
581 RADIUS_ATTR_NAS_PORT_TYPE
) &&
582 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_NAS_PORT_TYPE
,
583 RADIUS_NAS_PORT_TYPE_IEEE_802_11
)) {
584 wpa_printf(MSG_ERROR
, "Could not add NAS-Port-Type");
588 #ifdef CONFIG_INTERWORKING
589 if (hapd
->conf
->interworking
&&
590 !is_zero_ether_addr(hapd
->conf
->hessid
)) {
591 os_snprintf(buf
, sizeof(buf
), RADIUS_802_1X_ADDR_FORMAT
,
592 MAC2STR(hapd
->conf
->hessid
));
593 buf
[sizeof(buf
) - 1] = '\0';
594 if (!hostapd_config_get_radius_attr(req_attr
,
595 RADIUS_ATTR_WLAN_HESSID
) &&
596 !radius_msg_add_attr(msg
, RADIUS_ATTR_WLAN_HESSID
,
597 (u8
*) buf
, os_strlen(buf
))) {
598 wpa_printf(MSG_ERROR
, "Could not add WLAN-HESSID");
602 #endif /* CONFIG_INTERWORKING */
604 if (sta
&& add_common_radius_sta_attr(hapd
, req_attr
, sta
, msg
) < 0)
607 for (attr
= req_attr
; attr
; attr
= attr
->next
) {
608 if (!radius_msg_add_attr(msg
, attr
->type
,
609 wpabuf_head(attr
->val
),
610 wpabuf_len(attr
->val
))) {
611 wpa_printf(MSG_ERROR
, "Could not add RADIUS "
621 int add_sqlite_radius_attr(struct hostapd_data
*hapd
, struct sta_info
*sta
,
622 struct radius_msg
*msg
, int acct
)
626 char addrtxt
[3 * ETH_ALEN
];
628 sqlite3_stmt
*stmt
= NULL
;
630 if (!hapd
->rad_attr_db
)
633 os_snprintf(addrtxt
, sizeof(addrtxt
), MACSTR
, MAC2STR(sta
->addr
));
635 sql
= "SELECT attr FROM radius_attributes WHERE sta=? AND (reqtype=? OR reqtype IS NULL);";
636 if (sqlite3_prepare_v2(hapd
->rad_attr_db
, sql
, os_strlen(sql
), &stmt
,
637 NULL
) != SQLITE_OK
) {
638 wpa_printf(MSG_ERROR
, "DB: Failed to prepare SQL statement: %s",
639 sqlite3_errmsg(hapd
->rad_attr_db
));
642 sqlite3_bind_text(stmt
, 1, addrtxt
, os_strlen(addrtxt
), SQLITE_STATIC
);
643 sqlite3_bind_text(stmt
, 2, acct
? "acct" : "auth", 4, SQLITE_STATIC
);
644 while (sqlite3_step(stmt
) == SQLITE_ROW
) {
645 struct hostapd_radius_attr
*attr
;
646 struct radius_attr_hdr
*hdr
;
648 attrtxt
= (const char *) sqlite3_column_text(stmt
, 0);
649 attr
= hostapd_parse_radius_attr(attrtxt
);
651 wpa_printf(MSG_ERROR
,
652 "Skipping invalid attribute from SQL: %s",
656 wpa_printf(MSG_DEBUG
, "Adding RADIUS attribute from SQL: %s",
658 hdr
= radius_msg_add_attr(msg
, attr
->type
,
659 wpabuf_head(attr
->val
),
660 wpabuf_len(attr
->val
));
661 hostapd_config_free_radius_attr(attr
);
663 wpa_printf(MSG_ERROR
,
664 "Could not add RADIUS attribute from SQL");
670 sqlite3_clear_bindings(stmt
);
671 sqlite3_finalize(stmt
);
672 #endif /* CONFIG_SQLITE */
678 void ieee802_1x_encapsulate_radius(struct hostapd_data
*hapd
,
679 struct sta_info
*sta
,
680 const u8
*eap
, size_t len
)
682 struct radius_msg
*msg
;
683 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
688 ieee802_1x_learn_identity(hapd
, sm
, eap
, len
);
690 wpa_printf(MSG_DEBUG
, "Encapsulating EAP message into a RADIUS "
693 sm
->radius_identifier
= radius_client_get_id(hapd
->radius
);
694 msg
= radius_msg_new(RADIUS_CODE_ACCESS_REQUEST
,
695 sm
->radius_identifier
);
697 wpa_printf(MSG_INFO
, "Could not create new RADIUS packet");
701 if (radius_msg_make_authenticator(msg
) < 0) {
702 wpa_printf(MSG_INFO
, "Could not make Request Authenticator");
707 !radius_msg_add_attr(msg
, RADIUS_ATTR_USER_NAME
,
708 sm
->identity
, sm
->identity_len
)) {
709 wpa_printf(MSG_INFO
, "Could not add User-Name");
713 if (add_common_radius_attr(hapd
, hapd
->conf
->radius_auth_req_attr
, sta
,
717 if (sta
&& add_sqlite_radius_attr(hapd
, sta
, msg
, 0) < 0)
720 /* TODO: should probably check MTU from driver config; 2304 is max for
721 * IEEE 802.11, but use 1400 to avoid problems with too large packets
723 if (!hostapd_config_get_radius_attr(hapd
->conf
->radius_auth_req_attr
,
724 RADIUS_ATTR_FRAMED_MTU
) &&
725 !radius_msg_add_attr_int32(msg
, RADIUS_ATTR_FRAMED_MTU
, 1400)) {
726 wpa_printf(MSG_INFO
, "Could not add Framed-MTU");
730 if (!radius_msg_add_eap(msg
, eap
, len
)) {
731 wpa_printf(MSG_INFO
, "Could not add EAP-Message");
735 /* State attribute must be copied if and only if this packet is
736 * Access-Request reply to the previous Access-Challenge */
737 if (sm
->last_recv_radius
&&
738 radius_msg_get_hdr(sm
->last_recv_radius
)->code
==
739 RADIUS_CODE_ACCESS_CHALLENGE
) {
740 int res
= radius_msg_copy_attr(msg
, sm
->last_recv_radius
,
743 wpa_printf(MSG_INFO
, "Could not copy State attribute from previous Access-Challenge");
747 wpa_printf(MSG_DEBUG
, "Copied RADIUS State Attribute");
751 if (hapd
->conf
->radius_request_cui
) {
754 /* Add previously learned CUI or nul CUI to request CUI */
755 if (sm
->radius_cui
) {
756 cui
= wpabuf_head(sm
->radius_cui
);
757 cui_len
= wpabuf_len(sm
->radius_cui
);
759 cui
= (const u8
*) "\0";
762 if (!radius_msg_add_attr(msg
,
763 RADIUS_ATTR_CHARGEABLE_USER_IDENTITY
,
765 wpa_printf(MSG_ERROR
, "Could not add CUI");
771 if (hapd
->conf
->hs20
) {
772 u8 ver
= hapd
->conf
->hs20_release
- 1;
774 if (!radius_msg_add_wfa(
775 msg
, RADIUS_VENDOR_ATTR_WFA_HS20_AP_VERSION
,
777 wpa_printf(MSG_ERROR
, "Could not add HS 2.0 AP "
782 if (sta
->hs20_ie
&& wpabuf_len(sta
->hs20_ie
) > 0) {
786 pos
= wpabuf_head_u8(sta
->hs20_ie
);
787 buf
[0] = (*pos
) >> 4;
788 if (((*pos
) & HS20_PPS_MO_ID_PRESENT
) &&
789 wpabuf_len(sta
->hs20_ie
) >= 3)
790 id
= WPA_GET_LE16(pos
+ 1);
793 WPA_PUT_BE16(buf
+ 1, id
);
794 if (!radius_msg_add_wfa(
796 RADIUS_VENDOR_ATTR_WFA_HS20_STA_VERSION
,
798 wpa_printf(MSG_ERROR
, "Could not add HS 2.0 "
804 if (sta
->roaming_consortium
&&
806 msg
, RADIUS_VENDOR_ATTR_WFA_HS20_ROAMING_CONSORTIUM
,
807 wpabuf_head(sta
->roaming_consortium
),
808 wpabuf_len(sta
->roaming_consortium
))) {
809 wpa_printf(MSG_ERROR
,
810 "Could not add HS 2.0 Roaming Consortium");
814 if (hapd
->conf
->t_c_filename
) {
817 if (!radius_msg_add_wfa(
819 RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILENAME
,
820 (const u8
*) hapd
->conf
->t_c_filename
,
821 os_strlen(hapd
->conf
->t_c_filename
))) {
822 wpa_printf(MSG_ERROR
,
823 "Could not add HS 2.0 T&C Filename");
827 timestamp
= host_to_be32(hapd
->conf
->t_c_timestamp
);
828 if (!radius_msg_add_wfa(
830 RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP
,
831 (const u8
*) ×tamp
,
832 sizeof(timestamp
))) {
833 wpa_printf(MSG_ERROR
,
834 "Could not add HS 2.0 Timestamp");
839 #endif /* CONFIG_HS20 */
841 if (radius_client_send(hapd
->radius
, msg
, RADIUS_AUTH
, sta
->addr
) < 0)
847 radius_msg_free(msg
);
849 #endif /* CONFIG_NO_RADIUS */
852 static void handle_eap_response(struct hostapd_data
*hapd
,
853 struct sta_info
*sta
, struct eap_hdr
*eap
,
857 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
861 data
= (u8
*) (eap
+ 1);
863 if (len
< sizeof(*eap
) + 1) {
864 wpa_printf(MSG_INFO
, "handle_eap_response: too short response data");
868 sm
->eap_type_supp
= type
= data
[0];
870 hostapd_logger(hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
871 HOSTAPD_LEVEL_DEBUG
, "received EAP packet (code=%d "
872 "id=%d len=%d) from STA: EAP Response-%s (%d)",
873 eap
->code
, eap
->identifier
, be_to_host16(eap
->length
),
874 eap_server_get_name(0, type
), type
);
876 sm
->dot1xAuthEapolRespFramesRx
++;
878 wpabuf_free(sm
->eap_if
->eapRespData
);
879 sm
->eap_if
->eapRespData
= wpabuf_alloc_copy(eap
, len
);
884 static void handle_eap_initiate(struct hostapd_data
*hapd
,
885 struct sta_info
*sta
, struct eap_hdr
*eap
,
890 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
895 if (len
< sizeof(*eap
) + 1) {
897 "handle_eap_initiate: too short response data");
901 data
= (u8
*) (eap
+ 1);
904 hostapd_logger(hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
905 HOSTAPD_LEVEL_DEBUG
, "received EAP packet (code=%d "
906 "id=%d len=%d) from STA: EAP Initiate type %u",
907 eap
->code
, eap
->identifier
, be_to_host16(eap
->length
),
910 wpabuf_free(sm
->eap_if
->eapRespData
);
911 sm
->eap_if
->eapRespData
= wpabuf_alloc_copy(eap
, len
);
913 #endif /* CONFIG_ERP */
917 #ifndef CONFIG_NO_STDOUT_DEBUG
918 static const char * eap_code_str(u8 code
)
921 case EAP_CODE_REQUEST
:
923 case EAP_CODE_RESPONSE
:
925 case EAP_CODE_SUCCESS
:
927 case EAP_CODE_FAILURE
:
929 case EAP_CODE_INITIATE
:
931 case EAP_CODE_FINISH
:
937 #endif /* CONFIG_NO_STDOUT_DEBUG */
940 /* Process incoming EAP packet from Supplicant */
941 static void handle_eap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
947 if (len
< sizeof(*eap
)) {
948 wpa_printf(MSG_INFO
, " too short EAP packet");
952 eap
= (struct eap_hdr
*) buf
;
954 eap_len
= be_to_host16(eap
->length
);
955 wpa_printf(MSG_DEBUG
, "EAP: code=%d (%s) identifier=%d length=%d",
956 eap
->code
, eap_code_str(eap
->code
), eap
->identifier
,
958 if (eap_len
< sizeof(*eap
)) {
959 wpa_printf(MSG_DEBUG
, " Invalid EAP length");
961 } else if (eap_len
> len
) {
962 wpa_printf(MSG_DEBUG
, " Too short frame to contain this EAP "
965 } else if (eap_len
< len
) {
966 wpa_printf(MSG_DEBUG
, " Ignoring %lu extra bytes after EAP "
967 "packet", (unsigned long) len
- eap_len
);
971 case EAP_CODE_RESPONSE
:
972 handle_eap_response(hapd
, sta
, eap
, eap_len
);
974 case EAP_CODE_INITIATE
:
975 handle_eap_initiate(hapd
, sta
, eap
, eap_len
);
981 struct eapol_state_machine
*
982 ieee802_1x_alloc_eapol_sm(struct hostapd_data
*hapd
, struct sta_info
*sta
)
985 if (sta
->flags
& WLAN_STA_PREAUTH
)
986 flags
|= EAPOL_SM_PREAUTH
;
988 flags
|= EAPOL_SM_USES_WPA
;
989 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
))
990 flags
|= EAPOL_SM_FROM_PMKSA_CACHE
;
992 return eapol_auth_alloc(hapd
->eapol_auth
, sta
->addr
, flags
,
993 sta
->wps_ie
, sta
->p2p_ie
, sta
,
994 sta
->identity
, sta
->radius_cui
);
998 static void ieee802_1x_save_eapol(struct sta_info
*sta
, const u8
*buf
,
1001 if (sta
->pending_eapol_rx
) {
1002 wpabuf_free(sta
->pending_eapol_rx
->buf
);
1004 sta
->pending_eapol_rx
=
1005 os_malloc(sizeof(*sta
->pending_eapol_rx
));
1006 if (!sta
->pending_eapol_rx
)
1010 sta
->pending_eapol_rx
->buf
= wpabuf_alloc_copy(buf
, len
);
1011 if (!sta
->pending_eapol_rx
->buf
) {
1012 os_free(sta
->pending_eapol_rx
);
1013 sta
->pending_eapol_rx
= NULL
;
1017 os_get_reltime(&sta
->pending_eapol_rx
->rx_time
);
1022 * ieee802_1x_receive - Process the EAPOL frames from the Supplicant
1023 * @hapd: hostapd BSS data
1024 * @sa: Source address (sender of the EAPOL frame)
1026 * @len: Length of buf in octets
1028 * This function is called for each incoming EAPOL frame from the interface
1030 void ieee802_1x_receive(struct hostapd_data
*hapd
, const u8
*sa
, const u8
*buf
,
1033 struct sta_info
*sta
;
1034 struct ieee802_1x_hdr
*hdr
;
1035 struct ieee802_1x_eapol_key
*key
;
1037 struct rsn_pmksa_cache_entry
*pmksa
;
1040 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&& !hapd
->conf
->osen
&&
1041 !hapd
->conf
->wps_state
)
1044 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: %lu bytes from " MACSTR
,
1045 (unsigned long) len
, MAC2STR(sa
));
1046 sta
= ap_get_sta(hapd
, sa
);
1047 if (!sta
|| (!(sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_PREAUTH
)) &&
1048 !(hapd
->iface
->drv_flags
& WPA_DRIVER_FLAGS_WIRED
))) {
1049 wpa_printf(MSG_DEBUG
, "IEEE 802.1X data frame from not "
1050 "associated/Pre-authenticating STA");
1052 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
)) {
1053 wpa_printf(MSG_DEBUG
, "Saving EAPOL frame from " MACSTR
1054 " for later use", MAC2STR(sta
->addr
));
1055 ieee802_1x_save_eapol(sta
, buf
, len
);
1061 if (len
< sizeof(*hdr
)) {
1062 wpa_printf(MSG_INFO
, " too short IEEE 802.1X packet");
1066 hdr
= (struct ieee802_1x_hdr
*) buf
;
1067 datalen
= be_to_host16(hdr
->length
);
1068 wpa_printf(MSG_DEBUG
, " IEEE 802.1X: version=%d type=%d length=%d",
1069 hdr
->version
, hdr
->type
, datalen
);
1071 if (len
- sizeof(*hdr
) < datalen
) {
1072 wpa_printf(MSG_INFO
, " frame too short for this IEEE 802.1X packet");
1074 sta
->eapol_sm
->dot1xAuthEapLengthErrorFramesRx
++;
1077 if (len
- sizeof(*hdr
) > datalen
) {
1078 wpa_printf(MSG_DEBUG
, " ignoring %lu extra octets after "
1079 "IEEE 802.1X packet",
1080 (unsigned long) len
- sizeof(*hdr
) - datalen
);
1083 if (sta
->eapol_sm
) {
1084 sta
->eapol_sm
->dot1xAuthLastEapolFrameVersion
= hdr
->version
;
1085 sta
->eapol_sm
->dot1xAuthEapolFramesRx
++;
1088 key
= (struct ieee802_1x_eapol_key
*) (hdr
+ 1);
1089 if (datalen
>= sizeof(struct ieee802_1x_eapol_key
) &&
1090 hdr
->type
== IEEE802_1X_TYPE_EAPOL_KEY
&&
1091 (key
->type
== EAPOL_KEY_TYPE_WPA
||
1092 key
->type
== EAPOL_KEY_TYPE_RSN
)) {
1093 wpa_receive(hapd
->wpa_auth
, sta
->wpa_sm
, (u8
*) hdr
,
1094 sizeof(*hdr
) + datalen
);
1098 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->osen
&&
1099 !(sta
->flags
& (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
))) {
1100 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Ignore EAPOL message - "
1101 "802.1X not enabled and WPS not used");
1105 key_mgmt
= wpa_auth_sta_key_mgmt(sta
->wpa_sm
);
1106 if (key_mgmt
!= -1 &&
1107 (wpa_key_mgmt_wpa_psk(key_mgmt
) || key_mgmt
== WPA_KEY_MGMT_OWE
||
1108 key_mgmt
== WPA_KEY_MGMT_DPP
)) {
1109 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Ignore EAPOL message - "
1110 "STA is using PSK");
1114 if (!sta
->eapol_sm
) {
1115 sta
->eapol_sm
= ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1120 if (!hapd
->conf
->ieee802_1x
&& hapd
->conf
->wps_state
) {
1121 u32 wflags
= sta
->flags
& (WLAN_STA_WPS
|
1123 WLAN_STA_MAYBE_WPS
);
1124 if (wflags
== WLAN_STA_MAYBE_WPS
||
1125 wflags
== (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
)) {
1127 * Delay EAPOL frame transmission until a
1128 * possible WPS STA initiates the handshake
1129 * with EAPOL-Start. Only allow the wait to be
1130 * skipped if the STA is known to support WPS
1133 wpa_printf(MSG_DEBUG
, "WPS: Do not start "
1134 "EAPOL until EAPOL-Start is "
1136 sta
->eapol_sm
->flags
|= EAPOL_SM_WAIT_START
;
1139 #endif /* CONFIG_WPS */
1141 sta
->eapol_sm
->eap_if
->portEnabled
= TRUE
;
1144 /* since we support version 1, we can ignore version field and proceed
1145 * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */
1146 /* TODO: actually, we are not version 1 anymore.. However, Version 2
1147 * does not change frame contents, so should be ok to process frames
1148 * more or less identically. Some changes might be needed for
1149 * verification of fields. */
1151 switch (hdr
->type
) {
1152 case IEEE802_1X_TYPE_EAP_PACKET
:
1153 handle_eap(hapd
, sta
, (u8
*) (hdr
+ 1), datalen
);
1156 case IEEE802_1X_TYPE_EAPOL_START
:
1157 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1158 HOSTAPD_LEVEL_DEBUG
, "received EAPOL-Start "
1160 sta
->eapol_sm
->flags
&= ~EAPOL_SM_WAIT_START
;
1161 pmksa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
1163 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
1164 HOSTAPD_LEVEL_DEBUG
, "cached PMKSA "
1165 "available - ignore it since "
1166 "STA sent EAPOL-Start");
1167 wpa_auth_sta_clear_pmksa(sta
->wpa_sm
, pmksa
);
1169 sta
->eapol_sm
->eapolStart
= TRUE
;
1170 sta
->eapol_sm
->dot1xAuthEapolStartFramesRx
++;
1171 eap_server_clear_identity(sta
->eapol_sm
->eap
);
1172 wpa_auth_sm_event(sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
1175 case IEEE802_1X_TYPE_EAPOL_LOGOFF
:
1176 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1177 HOSTAPD_LEVEL_DEBUG
, "received EAPOL-Logoff "
1179 sta
->acct_terminate_cause
=
1180 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1181 accounting_sta_stop(hapd
, sta
);
1182 sta
->eapol_sm
->eapolLogoff
= TRUE
;
1183 sta
->eapol_sm
->dot1xAuthEapolLogoffFramesRx
++;
1184 eap_server_clear_identity(sta
->eapol_sm
->eap
);
1187 case IEEE802_1X_TYPE_EAPOL_KEY
:
1188 wpa_printf(MSG_DEBUG
, " EAPOL-Key");
1189 if (!ap_sta_is_authorized(sta
)) {
1190 wpa_printf(MSG_DEBUG
, " Dropped key data from "
1191 "unauthorized Supplicant");
1196 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT
:
1197 wpa_printf(MSG_DEBUG
, " EAPOL-Encapsulated-ASF-Alert");
1198 /* TODO: implement support for this; show data */
1201 #ifdef CONFIG_MACSEC
1202 case IEEE802_1X_TYPE_EAPOL_MKA
:
1203 wpa_printf(MSG_EXCESSIVE
,
1204 "EAPOL type %d will be handled by MKA", hdr
->type
);
1206 #endif /* CONFIG_MACSEC */
1209 wpa_printf(MSG_DEBUG
, " unknown IEEE 802.1X packet type");
1210 sta
->eapol_sm
->dot1xAuthInvalidEapolFramesRx
++;
1214 eapol_auth_step(sta
->eapol_sm
);
1219 * ieee802_1x_new_station - Start IEEE 802.1X authentication
1220 * @hapd: hostapd BSS data
1223 * This function is called to start IEEE 802.1X authentication when a new
1224 * station completes IEEE 802.11 association.
1226 void ieee802_1x_new_station(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1228 struct rsn_pmksa_cache_entry
*pmksa
;
1234 if (hapd
->conf
->wps_state
&&
1235 ((hapd
->conf
->wpa
&& (sta
->flags
& WLAN_STA_MAYBE_WPS
)) ||
1236 (sta
->flags
& WLAN_STA_WPS
))) {
1238 * Need to enable IEEE 802.1X/EAPOL state machines for possible
1239 * WPS handshake even if IEEE 802.1X/EAPOL is not used for
1240 * authentication in this BSS.
1244 #endif /* CONFIG_WPS */
1246 if (!force_1x
&& !hapd
->conf
->ieee802_1x
&& !hapd
->conf
->osen
) {
1247 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Ignore STA - "
1248 "802.1X not enabled or forced for WPS");
1250 * Clear any possible EAPOL authenticator state to support
1251 * reassociation change from WPS to PSK.
1253 ieee802_1x_free_station(hapd
, sta
);
1257 key_mgmt
= wpa_auth_sta_key_mgmt(sta
->wpa_sm
);
1258 if (key_mgmt
!= -1 &&
1259 (wpa_key_mgmt_wpa_psk(key_mgmt
) || key_mgmt
== WPA_KEY_MGMT_OWE
||
1260 key_mgmt
== WPA_KEY_MGMT_DPP
)) {
1261 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Ignore STA - using PSK");
1263 * Clear any possible EAPOL authenticator state to support
1264 * reassociation change from WPA-EAP to PSK.
1266 ieee802_1x_free_station(hapd
, sta
);
1270 if (sta
->eapol_sm
== NULL
) {
1271 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1272 HOSTAPD_LEVEL_DEBUG
, "start authentication");
1273 sta
->eapol_sm
= ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1274 if (sta
->eapol_sm
== NULL
) {
1275 hostapd_logger(hapd
, sta
->addr
,
1276 HOSTAPD_MODULE_IEEE8021X
,
1278 "failed to allocate state machine");
1285 sta
->eapol_sm
->flags
&= ~EAPOL_SM_WAIT_START
;
1286 if (!hapd
->conf
->ieee802_1x
&& hapd
->conf
->wps_state
&&
1287 !(sta
->flags
& WLAN_STA_WPS2
)) {
1289 * Delay EAPOL frame transmission until a possible WPS STA
1290 * initiates the handshake with EAPOL-Start. Only allow the
1291 * wait to be skipped if the STA is known to support WPS 2.0.
1293 wpa_printf(MSG_DEBUG
, "WPS: Do not start EAPOL until "
1294 "EAPOL-Start is received");
1295 sta
->eapol_sm
->flags
|= EAPOL_SM_WAIT_START
;
1297 #endif /* CONFIG_WPS */
1299 sta
->eapol_sm
->eap_if
->portEnabled
= TRUE
;
1301 #ifdef CONFIG_IEEE80211R_AP
1302 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
1303 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1304 HOSTAPD_LEVEL_DEBUG
,
1305 "PMK from FT - skip IEEE 802.1X/EAP");
1306 /* Setup EAPOL state machines to already authenticated state
1307 * because of existing FT information from R0KH. */
1308 sta
->eapol_sm
->keyRun
= TRUE
;
1309 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
1310 sta
->eapol_sm
->auth_pae_state
= AUTH_PAE_AUTHENTICATING
;
1311 sta
->eapol_sm
->be_auth_state
= BE_AUTH_SUCCESS
;
1312 sta
->eapol_sm
->authSuccess
= TRUE
;
1313 sta
->eapol_sm
->authFail
= FALSE
;
1314 sta
->eapol_sm
->portValid
= TRUE
;
1315 if (sta
->eapol_sm
->eap
)
1316 eap_sm_notify_cached(sta
->eapol_sm
->eap
);
1317 ap_sta_bind_vlan(hapd
, sta
);
1320 #endif /* CONFIG_IEEE80211R_AP */
1323 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
1324 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
1325 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
1326 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1327 HOSTAPD_LEVEL_DEBUG
,
1328 "PMK from FILS - skip IEEE 802.1X/EAP");
1329 /* Setup EAPOL state machines to already authenticated state
1330 * because of existing FILS information. */
1331 sta
->eapol_sm
->keyRun
= TRUE
;
1332 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
1333 sta
->eapol_sm
->auth_pae_state
= AUTH_PAE_AUTHENTICATING
;
1334 sta
->eapol_sm
->be_auth_state
= BE_AUTH_SUCCESS
;
1335 sta
->eapol_sm
->authSuccess
= TRUE
;
1336 sta
->eapol_sm
->authFail
= FALSE
;
1337 sta
->eapol_sm
->portValid
= TRUE
;
1338 if (sta
->eapol_sm
->eap
)
1339 eap_sm_notify_cached(sta
->eapol_sm
->eap
);
1340 wpa_auth_set_ptk_rekey_timer(sta
->wpa_sm
);
1343 #endif /* CONFIG_FILS */
1345 pmksa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
1347 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1348 HOSTAPD_LEVEL_DEBUG
,
1349 "PMK from PMKSA cache - skip IEEE 802.1X/EAP");
1350 /* Setup EAPOL state machines to already authenticated state
1351 * because of existing PMKSA information in the cache. */
1352 sta
->eapol_sm
->keyRun
= TRUE
;
1353 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
1354 sta
->eapol_sm
->auth_pae_state
= AUTH_PAE_AUTHENTICATING
;
1355 sta
->eapol_sm
->be_auth_state
= BE_AUTH_SUCCESS
;
1356 sta
->eapol_sm
->authSuccess
= TRUE
;
1357 sta
->eapol_sm
->authFail
= FALSE
;
1358 if (sta
->eapol_sm
->eap
)
1359 eap_sm_notify_cached(sta
->eapol_sm
->eap
);
1360 pmksa_cache_to_eapol_data(hapd
, pmksa
, sta
->eapol_sm
);
1361 ap_sta_bind_vlan(hapd
, sta
);
1365 * Force EAPOL state machines to start
1366 * re-authentication without having to wait for the
1367 * Supplicant to send EAPOL-Start.
1369 sta
->eapol_sm
->reAuthenticate
= TRUE
;
1371 eapol_auth_step(sta
->eapol_sm
);
1376 void ieee802_1x_free_station(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1378 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1381 eloop_cancel_timeout(ieee802_1x_wnm_notif_send
, hapd
, sta
);
1382 #endif /* CONFIG_HS20 */
1384 if (sta
->pending_eapol_rx
) {
1385 wpabuf_free(sta
->pending_eapol_rx
->buf
);
1386 os_free(sta
->pending_eapol_rx
);
1387 sta
->pending_eapol_rx
= NULL
;
1393 sta
->eapol_sm
= NULL
;
1395 #ifndef CONFIG_NO_RADIUS
1396 radius_msg_free(sm
->last_recv_radius
);
1397 radius_free_class(&sm
->radius_class
);
1398 #endif /* CONFIG_NO_RADIUS */
1400 eapol_auth_free(sm
);
1404 #ifndef CONFIG_NO_RADIUS
1405 static void ieee802_1x_decapsulate_radius(struct hostapd_data
*hapd
,
1406 struct sta_info
*sta
)
1409 const struct eap_hdr
*hdr
;
1412 struct radius_msg
*msg
;
1413 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1415 if (sm
== NULL
|| sm
->last_recv_radius
== NULL
) {
1417 sm
->eap_if
->aaaEapNoReq
= TRUE
;
1421 msg
= sm
->last_recv_radius
;
1423 eap
= radius_msg_get_eap(msg
);
1425 /* RFC 3579, Chap. 2.6.3:
1426 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
1428 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1429 HOSTAPD_LEVEL_WARNING
, "could not extract "
1430 "EAP-Message from RADIUS message");
1431 sm
->eap_if
->aaaEapNoReq
= TRUE
;
1435 if (wpabuf_len(eap
) < sizeof(*hdr
)) {
1436 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1437 HOSTAPD_LEVEL_WARNING
, "too short EAP packet "
1438 "received from authentication server");
1440 sm
->eap_if
->aaaEapNoReq
= TRUE
;
1444 if (wpabuf_len(eap
) > sizeof(*hdr
))
1445 eap_type
= (wpabuf_head_u8(eap
))[sizeof(*hdr
)];
1447 hdr
= wpabuf_head(eap
);
1448 switch (hdr
->code
) {
1449 case EAP_CODE_REQUEST
:
1451 sm
->eap_type_authsrv
= eap_type
;
1452 os_snprintf(buf
, sizeof(buf
), "EAP-Request-%s (%d)",
1453 eap_server_get_name(0, eap_type
), eap_type
);
1455 case EAP_CODE_RESPONSE
:
1456 os_snprintf(buf
, sizeof(buf
), "EAP Response-%s (%d)",
1457 eap_server_get_name(0, eap_type
), eap_type
);
1459 case EAP_CODE_SUCCESS
:
1460 os_strlcpy(buf
, "EAP Success", sizeof(buf
));
1462 case EAP_CODE_FAILURE
:
1463 os_strlcpy(buf
, "EAP Failure", sizeof(buf
));
1466 os_strlcpy(buf
, "unknown EAP code", sizeof(buf
));
1469 buf
[sizeof(buf
) - 1] = '\0';
1470 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1471 HOSTAPD_LEVEL_DEBUG
, "decapsulated EAP packet (code=%d "
1472 "id=%d len=%d) from RADIUS server: %s",
1473 hdr
->code
, hdr
->identifier
, be_to_host16(hdr
->length
),
1475 sm
->eap_if
->aaaEapReq
= TRUE
;
1477 wpabuf_free(sm
->eap_if
->aaaEapReqData
);
1478 sm
->eap_if
->aaaEapReqData
= eap
;
1482 static void ieee802_1x_get_keys(struct hostapd_data
*hapd
,
1483 struct sta_info
*sta
, struct radius_msg
*msg
,
1484 struct radius_msg
*req
,
1485 const u8
*shared_secret
,
1486 size_t shared_secret_len
)
1488 struct radius_ms_mppe_keys
*keys
;
1491 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1495 keys
= radius_msg_get_ms_keys(msg
, req
, shared_secret
,
1498 if (keys
&& keys
->send
&& keys
->recv
) {
1499 len
= keys
->send_len
+ keys
->recv_len
;
1500 wpa_hexdump_key(MSG_DEBUG
, "MS-MPPE-Send-Key",
1501 keys
->send
, keys
->send_len
);
1502 wpa_hexdump_key(MSG_DEBUG
, "MS-MPPE-Recv-Key",
1503 keys
->recv
, keys
->recv_len
);
1505 os_free(sm
->eap_if
->aaaEapKeyData
);
1506 sm
->eap_if
->aaaEapKeyData
= os_malloc(len
);
1507 if (sm
->eap_if
->aaaEapKeyData
) {
1508 os_memcpy(sm
->eap_if
->aaaEapKeyData
, keys
->recv
,
1510 os_memcpy(sm
->eap_if
->aaaEapKeyData
+ keys
->recv_len
,
1511 keys
->send
, keys
->send_len
);
1512 sm
->eap_if
->aaaEapKeyDataLen
= len
;
1513 sm
->eap_if
->aaaEapKeyAvailable
= TRUE
;
1516 wpa_printf(MSG_DEBUG
,
1517 "MS-MPPE: 1x_get_keys, could not get keys: %p send: %p recv: %p",
1518 keys
, keys
? keys
->send
: NULL
,
1519 keys
? keys
->recv
: NULL
);
1523 os_free(keys
->send
);
1524 os_free(keys
->recv
);
1528 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_EAP_KEY_NAME
, &buf
, &len
,
1530 os_free(sm
->eap_if
->eapSessionId
);
1531 sm
->eap_if
->eapSessionId
= os_memdup(buf
, len
);
1532 if (sm
->eap_if
->eapSessionId
) {
1533 sm
->eap_if
->eapSessionIdLen
= len
;
1534 wpa_hexdump(MSG_DEBUG
, "EAP-Key Name",
1535 sm
->eap_if
->eapSessionId
,
1536 sm
->eap_if
->eapSessionIdLen
);
1539 sm
->eap_if
->eapSessionIdLen
= 0;
1544 static void ieee802_1x_store_radius_class(struct hostapd_data
*hapd
,
1545 struct sta_info
*sta
,
1546 struct radius_msg
*msg
)
1550 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1552 struct radius_attr_data
*nclass
;
1553 size_t nclass_count
;
1555 if (!hapd
->conf
->radius
->acct_server
|| hapd
->radius
== NULL
||
1559 radius_free_class(&sm
->radius_class
);
1560 count
= radius_msg_count_attr(msg
, RADIUS_ATTR_CLASS
, 1);
1564 nclass
= os_calloc(count
, sizeof(struct radius_attr_data
));
1571 for (i
= 0; i
< count
; i
++) {
1573 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_CLASS
,
1574 &attr_class
, &class_len
,
1579 } while (class_len
< 1);
1581 nclass
[nclass_count
].data
= os_memdup(attr_class
, class_len
);
1582 if (nclass
[nclass_count
].data
== NULL
)
1585 nclass
[nclass_count
].len
= class_len
;
1589 sm
->radius_class
.attr
= nclass
;
1590 sm
->radius_class
.count
= nclass_count
;
1591 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Stored %lu RADIUS Class "
1592 "attributes for " MACSTR
,
1593 (unsigned long) sm
->radius_class
.count
,
1594 MAC2STR(sta
->addr
));
1598 /* Update sta->identity based on User-Name attribute in Access-Accept */
1599 static void ieee802_1x_update_sta_identity(struct hostapd_data
*hapd
,
1600 struct sta_info
*sta
,
1601 struct radius_msg
*msg
)
1605 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1610 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_USER_NAME
, &buf
, &len
,
1614 identity
= (u8
*) dup_binstr(buf
, len
);
1615 if (identity
== NULL
)
1618 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1619 HOSTAPD_LEVEL_DEBUG
, "old identity '%s' updated with "
1620 "User-Name from Access-Accept '%s'",
1621 sm
->identity
? (char *) sm
->identity
: "N/A",
1624 os_free(sm
->identity
);
1625 sm
->identity
= identity
;
1626 sm
->identity_len
= len
;
1630 /* Update CUI based on Chargeable-User-Identity attribute in Access-Accept */
1631 static void ieee802_1x_update_sta_cui(struct hostapd_data
*hapd
,
1632 struct sta_info
*sta
,
1633 struct radius_msg
*msg
)
1635 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1643 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY
,
1644 &buf
, &len
, NULL
) < 0)
1647 cui
= wpabuf_alloc_copy(buf
, len
);
1651 wpabuf_free(sm
->radius_cui
);
1652 sm
->radius_cui
= cui
;
1658 static void ieee802_1x_hs20_sub_rem(struct sta_info
*sta
, u8
*pos
, size_t len
)
1660 sta
->remediation
= 1;
1661 os_free(sta
->remediation_url
);
1663 sta
->remediation_url
= os_malloc(len
);
1664 if (!sta
->remediation_url
)
1666 sta
->remediation_method
= pos
[0];
1667 os_memcpy(sta
->remediation_url
, pos
+ 1, len
- 1);
1668 sta
->remediation_url
[len
- 1] = '\0';
1669 wpa_printf(MSG_DEBUG
, "HS 2.0: Subscription remediation needed "
1670 "for " MACSTR
" - server method %u URL %s",
1671 MAC2STR(sta
->addr
), sta
->remediation_method
,
1672 sta
->remediation_url
);
1674 sta
->remediation_url
= NULL
;
1675 wpa_printf(MSG_DEBUG
, "HS 2.0: Subscription remediation needed "
1676 "for " MACSTR
, MAC2STR(sta
->addr
));
1678 /* TODO: assign the STA into remediation VLAN or add filtering */
1682 static void ieee802_1x_hs20_deauth_req(struct hostapd_data
*hapd
,
1683 struct sta_info
*sta
, u8
*pos
,
1687 return; /* Malformed information */
1688 sta
->hs20_deauth_requested
= 1;
1689 wpa_printf(MSG_DEBUG
, "HS 2.0: Deauthentication request - Code %u "
1691 *pos
, WPA_GET_LE16(pos
+ 1));
1692 wpabuf_free(sta
->hs20_deauth_req
);
1693 sta
->hs20_deauth_req
= wpabuf_alloc(len
+ 1);
1694 if (sta
->hs20_deauth_req
) {
1695 wpabuf_put_data(sta
->hs20_deauth_req
, pos
, 3);
1696 wpabuf_put_u8(sta
->hs20_deauth_req
, len
- 3);
1697 wpabuf_put_data(sta
->hs20_deauth_req
, pos
+ 3, len
- 3);
1699 ap_sta_session_timeout(hapd
, sta
, hapd
->conf
->hs20_deauth_req_timeout
);
1703 static void ieee802_1x_hs20_session_info(struct hostapd_data
*hapd
,
1704 struct sta_info
*sta
, u8
*pos
,
1705 size_t len
, int session_timeout
)
1708 int warning_time
, beacon_int
;
1711 return; /* Malformed information */
1712 os_free(sta
->hs20_session_info_url
);
1713 sta
->hs20_session_info_url
= os_malloc(len
);
1714 if (sta
->hs20_session_info_url
== NULL
)
1717 os_memcpy(sta
->hs20_session_info_url
, pos
+ 1, len
- 1);
1718 sta
->hs20_session_info_url
[len
- 1] = '\0';
1719 wpa_printf(MSG_DEBUG
, "HS 2.0: Session Information URL='%s' SWT=%u "
1720 "(session_timeout=%d)",
1721 sta
->hs20_session_info_url
, swt
, session_timeout
);
1722 if (session_timeout
< 0) {
1723 wpa_printf(MSG_DEBUG
, "HS 2.0: No Session-Timeout set - ignore session info URL");
1727 swt
= 1; /* Use one minute as the AP selected value */
1729 if ((unsigned int) session_timeout
< swt
* 60)
1732 warning_time
= session_timeout
- swt
* 60;
1734 beacon_int
= hapd
->iconf
->beacon_int
;
1736 beacon_int
= 100; /* best guess */
1737 sta
->hs20_disassoc_timer
= swt
* 60 * 1000 / beacon_int
* 125 / 128;
1738 if (sta
->hs20_disassoc_timer
> 65535)
1739 sta
->hs20_disassoc_timer
= 65535;
1741 ap_sta_session_warning_timeout(hapd
, sta
, warning_time
);
1745 static void ieee802_1x_hs20_t_c_filtering(struct hostapd_data
*hapd
,
1746 struct sta_info
*sta
, u8
*pos
,
1750 return; /* Malformed information */
1751 wpa_printf(MSG_DEBUG
,
1752 "HS 2.0: Terms and Conditions filtering %02x %02x %02x %02x",
1753 pos
[0], pos
[1], pos
[2], pos
[3]);
1754 hs20_t_c_filtering(hapd
, sta
, pos
[0] & BIT(0));
1758 static void ieee802_1x_hs20_t_c_url(struct hostapd_data
*hapd
,
1759 struct sta_info
*sta
, u8
*pos
, size_t len
)
1761 os_free(sta
->t_c_url
);
1762 sta
->t_c_url
= os_malloc(len
+ 1);
1765 os_memcpy(sta
->t_c_url
, pos
, len
);
1766 sta
->t_c_url
[len
] = '\0';
1767 wpa_printf(MSG_DEBUG
,
1768 "HS 2.0: Terms and Conditions URL %s", sta
->t_c_url
);
1771 #endif /* CONFIG_HS20 */
1774 static void ieee802_1x_check_hs20(struct hostapd_data
*hapd
,
1775 struct sta_info
*sta
,
1776 struct radius_msg
*msg
,
1777 int session_timeout
)
1780 u8
*buf
, *pos
, *end
, type
, sublen
;
1784 sta
->remediation
= 0;
1785 sta
->hs20_deauth_requested
= 0;
1788 if (radius_msg_get_attr_ptr(msg
, RADIUS_ATTR_VENDOR_SPECIFIC
,
1789 &buf
, &len
, buf
) < 0)
1795 if (WPA_GET_BE32(pos
) != RADIUS_VENDOR_ID_WFA
)
1802 continue; /* invalid length */
1803 sublen
-= 2; /* skip header */
1804 if (pos
+ sublen
> end
)
1805 continue; /* invalid WFA VSA */
1808 case RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION
:
1809 ieee802_1x_hs20_sub_rem(sta
, pos
, sublen
);
1811 case RADIUS_VENDOR_ATTR_WFA_HS20_DEAUTH_REQ
:
1812 ieee802_1x_hs20_deauth_req(hapd
, sta
, pos
, sublen
);
1814 case RADIUS_VENDOR_ATTR_WFA_HS20_SESSION_INFO_URL
:
1815 ieee802_1x_hs20_session_info(hapd
, sta
, pos
, sublen
,
1818 case RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING
:
1819 ieee802_1x_hs20_t_c_filtering(hapd
, sta
, pos
, sublen
);
1821 case RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL
:
1822 ieee802_1x_hs20_t_c_url(hapd
, sta
, pos
, sublen
);
1826 #endif /* CONFIG_HS20 */
1830 struct sta_id_search
{
1832 struct eapol_state_machine
*sm
;
1836 static int ieee802_1x_select_radius_identifier(struct hostapd_data
*hapd
,
1837 struct sta_info
*sta
,
1840 struct sta_id_search
*id_search
= ctx
;
1841 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
1843 if (sm
&& sm
->radius_identifier
>= 0 &&
1844 sm
->radius_identifier
== id_search
->identifier
) {
1852 static struct eapol_state_machine
*
1853 ieee802_1x_search_radius_identifier(struct hostapd_data
*hapd
, u8 identifier
)
1855 struct sta_id_search id_search
;
1856 id_search
.identifier
= identifier
;
1857 id_search
.sm
= NULL
;
1858 ap_for_each_sta(hapd
, ieee802_1x_select_radius_identifier
, &id_search
);
1859 return id_search
.sm
;
1863 #ifndef CONFIG_NO_VLAN
1864 static int ieee802_1x_update_vlan(struct radius_msg
*msg
,
1865 struct hostapd_data
*hapd
,
1866 struct sta_info
*sta
)
1868 struct vlan_description vlan_desc
;
1870 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
1871 vlan_desc
.notempty
= !!radius_msg_get_vlanid(msg
, &vlan_desc
.untagged
,
1872 MAX_NUM_TAGGED_VLAN
,
1875 if (vlan_desc
.notempty
&&
1876 !hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
1877 sta
->eapol_sm
->authFail
= TRUE
;
1878 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1880 "Invalid VLAN %d%s received from RADIUS server",
1882 vlan_desc
.tagged
[0] ? "+" : "");
1883 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
1884 ap_sta_set_vlan(hapd
, sta
, &vlan_desc
);
1888 if (hapd
->conf
->ssid
.dynamic_vlan
== DYNAMIC_VLAN_REQUIRED
&&
1889 !vlan_desc
.notempty
) {
1890 sta
->eapol_sm
->authFail
= TRUE
;
1891 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
1893 "authentication server did not include required VLAN ID in Access-Accept");
1897 return ap_sta_set_vlan(hapd
, sta
, &vlan_desc
);
1899 #endif /* CONFIG_NO_VLAN */
1903 * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server
1904 * @msg: RADIUS response message
1905 * @req: RADIUS request message
1906 * @shared_secret: RADIUS shared secret
1907 * @shared_secret_len: Length of shared_secret in octets
1908 * @data: Context data (struct hostapd_data *)
1909 * Returns: Processing status
1911 static RadiusRxResult
1912 ieee802_1x_receive_auth(struct radius_msg
*msg
, struct radius_msg
*req
,
1913 const u8
*shared_secret
, size_t shared_secret_len
,
1916 struct hostapd_data
*hapd
= data
;
1917 struct sta_info
*sta
;
1918 u32 session_timeout
= 0, termination_action
, acct_interim_interval
;
1919 int session_timeout_set
;
1921 struct eapol_state_machine
*sm
;
1922 int override_eapReq
= 0;
1923 struct radius_hdr
*hdr
= radius_msg_get_hdr(msg
);
1925 sm
= ieee802_1x_search_radius_identifier(hapd
, hdr
->identifier
);
1927 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: Could not find matching "
1928 "station for this RADIUS message");
1929 return RADIUS_RX_UNKNOWN
;
1933 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
1934 * present when packet contains an EAP-Message attribute */
1935 if (hdr
->code
== RADIUS_CODE_ACCESS_REJECT
&&
1936 radius_msg_get_attr(msg
, RADIUS_ATTR_MESSAGE_AUTHENTICATOR
, NULL
,
1938 radius_msg_get_attr(msg
, RADIUS_ATTR_EAP_MESSAGE
, NULL
, 0) < 0) {
1939 wpa_printf(MSG_DEBUG
, "Allowing RADIUS Access-Reject without "
1940 "Message-Authenticator since it does not include "
1942 } else if (radius_msg_verify(msg
, shared_secret
, shared_secret_len
,
1944 wpa_printf(MSG_INFO
, "Incoming RADIUS packet did not have correct Message-Authenticator - dropped");
1945 return RADIUS_RX_INVALID_AUTHENTICATOR
;
1948 if (hdr
->code
!= RADIUS_CODE_ACCESS_ACCEPT
&&
1949 hdr
->code
!= RADIUS_CODE_ACCESS_REJECT
&&
1950 hdr
->code
!= RADIUS_CODE_ACCESS_CHALLENGE
) {
1951 wpa_printf(MSG_INFO
, "Unknown RADIUS message code");
1952 return RADIUS_RX_UNKNOWN
;
1955 sm
->radius_identifier
= -1;
1956 wpa_printf(MSG_DEBUG
, "RADIUS packet matching with station " MACSTR
,
1957 MAC2STR(sta
->addr
));
1959 radius_msg_free(sm
->last_recv_radius
);
1960 sm
->last_recv_radius
= msg
;
1962 session_timeout_set
=
1963 !radius_msg_get_attr_int32(msg
, RADIUS_ATTR_SESSION_TIMEOUT
,
1965 if (radius_msg_get_attr_int32(msg
, RADIUS_ATTR_TERMINATION_ACTION
,
1966 &termination_action
))
1967 termination_action
= RADIUS_TERMINATION_ACTION_DEFAULT
;
1969 if (hapd
->conf
->acct_interim_interval
== 0 &&
1970 hdr
->code
== RADIUS_CODE_ACCESS_ACCEPT
&&
1971 radius_msg_get_attr_int32(msg
, RADIUS_ATTR_ACCT_INTERIM_INTERVAL
,
1972 &acct_interim_interval
) == 0) {
1973 if (acct_interim_interval
< 60) {
1974 hostapd_logger(hapd
, sta
->addr
,
1975 HOSTAPD_MODULE_IEEE8021X
,
1977 "ignored too small "
1978 "Acct-Interim-Interval %d",
1979 acct_interim_interval
);
1981 sta
->acct_interim_interval
= acct_interim_interval
;
1985 switch (hdr
->code
) {
1986 case RADIUS_CODE_ACCESS_ACCEPT
:
1987 #ifndef CONFIG_NO_VLAN
1988 if (hapd
->conf
->ssid
.dynamic_vlan
!= DYNAMIC_VLAN_DISABLED
&&
1989 ieee802_1x_update_vlan(msg
, hapd
, sta
) < 0)
1992 if (sta
->vlan_id
> 0) {
1993 hostapd_logger(hapd
, sta
->addr
,
1994 HOSTAPD_MODULE_RADIUS
,
1996 "VLAN ID %d", sta
->vlan_id
);
1999 if ((sta
->flags
& WLAN_STA_ASSOC
) &&
2000 ap_sta_bind_vlan(hapd
, sta
) < 0)
2002 #endif /* CONFIG_NO_VLAN */
2004 sta
->session_timeout_set
= !!session_timeout_set
;
2005 os_get_reltime(&sta
->session_timeout
);
2006 sta
->session_timeout
.sec
+= session_timeout
;
2008 /* RFC 3580, Ch. 3.17 */
2009 if (session_timeout_set
&& termination_action
==
2010 RADIUS_TERMINATION_ACTION_RADIUS_REQUEST
)
2011 sm
->reAuthPeriod
= session_timeout
;
2012 else if (session_timeout_set
)
2013 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2015 ap_sta_no_session_timeout(hapd
, sta
);
2017 sm
->eap_if
->aaaSuccess
= TRUE
;
2018 override_eapReq
= 1;
2019 ieee802_1x_get_keys(hapd
, sta
, msg
, req
, shared_secret
,
2021 ieee802_1x_store_radius_class(hapd
, sta
, msg
);
2022 ieee802_1x_update_sta_identity(hapd
, sta
, msg
);
2023 ieee802_1x_update_sta_cui(hapd
, sta
, msg
);
2024 ieee802_1x_check_hs20(hapd
, sta
, msg
,
2025 session_timeout_set
?
2026 (int) session_timeout
: -1);
2028 case RADIUS_CODE_ACCESS_REJECT
:
2029 sm
->eap_if
->aaaFail
= TRUE
;
2030 override_eapReq
= 1;
2031 if (radius_msg_get_attr_int32(msg
, RADIUS_ATTR_WLAN_REASON_CODE
,
2032 &reason_code
) == 0) {
2033 wpa_printf(MSG_DEBUG
,
2034 "RADIUS server indicated WLAN-Reason-Code %u in Access-Reject for "
2035 MACSTR
, reason_code
, MAC2STR(sta
->addr
));
2036 sta
->disconnect_reason_code
= reason_code
;
2039 case RADIUS_CODE_ACCESS_CHALLENGE
:
2040 sm
->eap_if
->aaaEapReq
= TRUE
;
2041 if (session_timeout_set
) {
2042 /* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */
2043 sm
->eap_if
->aaaMethodTimeout
= session_timeout
;
2044 hostapd_logger(hapd
, sm
->addr
,
2045 HOSTAPD_MODULE_IEEE8021X
,
2046 HOSTAPD_LEVEL_DEBUG
,
2047 "using EAP timeout of %d seconds (from "
2049 sm
->eap_if
->aaaMethodTimeout
);
2052 * Use dynamic retransmission behavior per EAP
2055 sm
->eap_if
->aaaMethodTimeout
= 0;
2060 ieee802_1x_decapsulate_radius(hapd
, sta
);
2061 if (override_eapReq
)
2062 sm
->eap_if
->aaaEapReq
= FALSE
;
2066 if (sta
->flags
& WLAN_STA_PENDING_FILS_ERP
) {
2067 /* TODO: Add a PMKSA entry on success? */
2068 ieee802_11_finish_fils_auth(
2069 hapd
, sta
, hdr
->code
== RADIUS_CODE_ACCESS_ACCEPT
,
2070 sm
->eap_if
->aaaEapReqData
,
2071 sm
->eap_if
->aaaEapKeyData
,
2072 sm
->eap_if
->aaaEapKeyDataLen
);
2074 #endif /* NEED_AP_MLME */
2075 #endif /* CONFIG_FILS */
2077 eapol_auth_step(sm
);
2079 return RADIUS_RX_QUEUED
;
2081 #endif /* CONFIG_NO_RADIUS */
2084 void ieee802_1x_abort_auth(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2086 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
2090 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
2091 HOSTAPD_LEVEL_DEBUG
, "aborting authentication");
2093 #ifndef CONFIG_NO_RADIUS
2094 radius_msg_free(sm
->last_recv_radius
);
2095 sm
->last_recv_radius
= NULL
;
2096 #endif /* CONFIG_NO_RADIUS */
2098 if (sm
->eap_if
->eapTimeout
) {
2100 * Disconnect the STA since it did not reply to the last EAP
2101 * request and we cannot continue EAP processing (EAP-Failure
2102 * could only be sent if the EAP peer actually replied).
2104 wpa_dbg(hapd
->msg_ctx
, MSG_DEBUG
, "EAP Timeout, STA " MACSTR
,
2105 MAC2STR(sta
->addr
));
2107 sm
->eap_if
->portEnabled
= FALSE
;
2108 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
2109 WLAN_REASON_PREV_AUTH_NOT_VALID
);
2114 static int ieee802_1x_rekey_broadcast(struct hostapd_data
*hapd
)
2116 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
2118 if (hapd
->conf
->default_wep_key_len
< 1)
2121 os_free(eapol
->default_wep_key
);
2122 eapol
->default_wep_key
= os_malloc(hapd
->conf
->default_wep_key_len
);
2123 if (eapol
->default_wep_key
== NULL
||
2124 random_get_bytes(eapol
->default_wep_key
,
2125 hapd
->conf
->default_wep_key_len
)) {
2126 wpa_printf(MSG_INFO
, "Could not generate random WEP key");
2127 os_free(eapol
->default_wep_key
);
2128 eapol
->default_wep_key
= NULL
;
2132 wpa_hexdump_key(MSG_DEBUG
, "IEEE 802.1X: New default WEP key",
2133 eapol
->default_wep_key
,
2134 hapd
->conf
->default_wep_key_len
);
2140 static int ieee802_1x_sta_key_available(struct hostapd_data
*hapd
,
2141 struct sta_info
*sta
, void *ctx
)
2143 if (sta
->eapol_sm
) {
2144 sta
->eapol_sm
->eap_if
->eapKeyAvailable
= TRUE
;
2145 eapol_auth_step(sta
->eapol_sm
);
2151 static void ieee802_1x_rekey(void *eloop_ctx
, void *timeout_ctx
)
2153 struct hostapd_data
*hapd
= eloop_ctx
;
2154 struct eapol_authenticator
*eapol
= hapd
->eapol_auth
;
2156 if (eapol
->default_wep_key_idx
>= 3)
2157 eapol
->default_wep_key_idx
=
2158 hapd
->conf
->individual_wep_key_len
> 0 ? 1 : 0;
2160 eapol
->default_wep_key_idx
++;
2162 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: New default WEP key index %d",
2163 eapol
->default_wep_key_idx
);
2165 if (ieee802_1x_rekey_broadcast(hapd
)) {
2166 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE8021X
,
2167 HOSTAPD_LEVEL_WARNING
, "failed to generate a "
2168 "new broadcast key");
2169 os_free(eapol
->default_wep_key
);
2170 eapol
->default_wep_key
= NULL
;
2174 /* TODO: Could setup key for RX here, but change default TX keyid only
2175 * after new broadcast key has been sent to all stations. */
2176 if (hostapd_drv_set_key(hapd
->conf
->iface
, hapd
, WPA_ALG_WEP
,
2177 broadcast_ether_addr
,
2178 eapol
->default_wep_key_idx
, 1, NULL
, 0,
2179 eapol
->default_wep_key
,
2180 hapd
->conf
->default_wep_key_len
)) {
2181 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE8021X
,
2182 HOSTAPD_LEVEL_WARNING
, "failed to configure a "
2183 "new broadcast key");
2184 os_free(eapol
->default_wep_key
);
2185 eapol
->default_wep_key
= NULL
;
2189 ap_for_each_sta(hapd
, ieee802_1x_sta_key_available
, NULL
);
2191 if (hapd
->conf
->wep_rekeying_period
> 0) {
2192 eloop_register_timeout(hapd
->conf
->wep_rekeying_period
, 0,
2193 ieee802_1x_rekey
, hapd
, NULL
);
2198 static void ieee802_1x_eapol_send(void *ctx
, void *sta_ctx
, u8 type
,
2199 const u8
*data
, size_t datalen
)
2202 struct sta_info
*sta
= sta_ctx
;
2204 if ((sta
->flags
& (WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
)) ==
2205 WLAN_STA_MAYBE_WPS
) {
2207 size_t identity_len
;
2208 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
2210 identity
= eap_get_identity(sm
->eap
, &identity_len
);
2212 ((identity_len
== WSC_ID_ENROLLEE_LEN
&&
2213 os_memcmp(identity
, WSC_ID_ENROLLEE
,
2214 WSC_ID_ENROLLEE_LEN
) == 0) ||
2215 (identity_len
== WSC_ID_REGISTRAR_LEN
&&
2216 os_memcmp(identity
, WSC_ID_REGISTRAR
,
2217 WSC_ID_REGISTRAR_LEN
) == 0))) {
2218 wpa_printf(MSG_DEBUG
, "WPS: WLAN_STA_MAYBE_WPS -> "
2220 sta
->flags
|= WLAN_STA_WPS
;
2223 #endif /* CONFIG_WPS */
2225 ieee802_1x_send(ctx
, sta_ctx
, type
, data
, datalen
);
2229 static void ieee802_1x_aaa_send(void *ctx
, void *sta_ctx
,
2230 const u8
*data
, size_t datalen
)
2232 #ifndef CONFIG_NO_RADIUS
2233 struct hostapd_data
*hapd
= ctx
;
2234 struct sta_info
*sta
= sta_ctx
;
2236 ieee802_1x_encapsulate_radius(hapd
, sta
, data
, datalen
);
2237 #endif /* CONFIG_NO_RADIUS */
2241 static void _ieee802_1x_finished(void *ctx
, void *sta_ctx
, int success
,
2242 int preauth
, int remediation
)
2244 struct hostapd_data
*hapd
= ctx
;
2245 struct sta_info
*sta
= sta_ctx
;
2247 rsn_preauth_finished(hapd
, sta
, success
);
2249 ieee802_1x_finished(hapd
, sta
, success
, remediation
);
2253 static int ieee802_1x_get_eap_user(void *ctx
, const u8
*identity
,
2254 size_t identity_len
, int phase2
,
2255 struct eap_user
*user
)
2257 struct hostapd_data
*hapd
= ctx
;
2258 const struct hostapd_eap_user
*eap_user
;
2262 eap_user
= hostapd_get_eap_user(hapd
, identity
, identity_len
, phase2
);
2263 if (eap_user
== NULL
)
2266 os_memset(user
, 0, sizeof(*user
));
2267 user
->phase2
= phase2
;
2268 for (i
= 0; i
< EAP_MAX_METHODS
; i
++) {
2269 user
->methods
[i
].vendor
= eap_user
->methods
[i
].vendor
;
2270 user
->methods
[i
].method
= eap_user
->methods
[i
].method
;
2273 if (eap_user
->password
) {
2274 user
->password
= os_memdup(eap_user
->password
,
2275 eap_user
->password_len
);
2276 if (user
->password
== NULL
)
2278 user
->password_len
= eap_user
->password_len
;
2279 user
->password_hash
= eap_user
->password_hash
;
2280 if (eap_user
->salt
&& eap_user
->salt_len
) {
2281 user
->salt
= os_memdup(eap_user
->salt
,
2282 eap_user
->salt_len
);
2285 user
->salt_len
= eap_user
->salt_len
;
2288 user
->force_version
= eap_user
->force_version
;
2289 user
->macacl
= eap_user
->macacl
;
2290 user
->ttls_auth
= eap_user
->ttls_auth
;
2291 user
->remediation
= eap_user
->remediation
;
2296 wpa_printf(MSG_DEBUG
, "%s: Failed to find user", __func__
);
2302 static int ieee802_1x_sta_entry_alive(void *ctx
, const u8
*addr
)
2304 struct hostapd_data
*hapd
= ctx
;
2305 struct sta_info
*sta
;
2306 sta
= ap_get_sta(hapd
, addr
);
2307 if (sta
== NULL
|| sta
->eapol_sm
== NULL
)
2313 static void ieee802_1x_logger(void *ctx
, const u8
*addr
,
2314 eapol_logger_level level
, const char *txt
)
2316 #ifndef CONFIG_NO_HOSTAPD_LOGGER
2317 struct hostapd_data
*hapd
= ctx
;
2321 case EAPOL_LOGGER_WARNING
:
2322 hlevel
= HOSTAPD_LEVEL_WARNING
;
2324 case EAPOL_LOGGER_INFO
:
2325 hlevel
= HOSTAPD_LEVEL_INFO
;
2327 case EAPOL_LOGGER_DEBUG
:
2329 hlevel
= HOSTAPD_LEVEL_DEBUG
;
2333 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE8021X
, hlevel
, "%s",
2335 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
2339 static void ieee802_1x_set_port_authorized(void *ctx
, void *sta_ctx
,
2342 struct hostapd_data
*hapd
= ctx
;
2343 struct sta_info
*sta
= sta_ctx
;
2344 ieee802_1x_set_sta_authorized(hapd
, sta
, authorized
);
2348 static void _ieee802_1x_abort_auth(void *ctx
, void *sta_ctx
)
2350 struct hostapd_data
*hapd
= ctx
;
2351 struct sta_info
*sta
= sta_ctx
;
2352 ieee802_1x_abort_auth(hapd
, sta
);
2356 static void _ieee802_1x_tx_key(void *ctx
, void *sta_ctx
)
2359 #ifndef CONFIG_NO_RC4
2360 struct hostapd_data
*hapd
= ctx
;
2361 struct sta_info
*sta
= sta_ctx
;
2362 ieee802_1x_tx_key(hapd
, sta
);
2363 #endif /* CONFIG_NO_RC4 */
2364 #endif /* CONFIG_FIPS */
2368 static void ieee802_1x_eapol_event(void *ctx
, void *sta_ctx
,
2369 enum eapol_event type
)
2371 /* struct hostapd_data *hapd = ctx; */
2372 struct sta_info
*sta
= sta_ctx
;
2374 case EAPOL_AUTH_SM_CHANGE
:
2375 wpa_auth_sm_notify(sta
->wpa_sm
);
2377 case EAPOL_AUTH_REAUTHENTICATE
:
2378 wpa_auth_sm_event(sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
2386 static struct eap_server_erp_key
*
2387 ieee802_1x_erp_get_key(void *ctx
, const char *keyname
)
2389 struct hostapd_data
*hapd
= ctx
;
2390 struct eap_server_erp_key
*erp
;
2392 dl_list_for_each(erp
, &hapd
->erp_keys
, struct eap_server_erp_key
,
2394 if (os_strcmp(erp
->keyname_nai
, keyname
) == 0)
2402 static int ieee802_1x_erp_add_key(void *ctx
, struct eap_server_erp_key
*erp
)
2404 struct hostapd_data
*hapd
= ctx
;
2406 dl_list_add(&hapd
->erp_keys
, &erp
->list
);
2410 #endif /* CONFIG_ERP */
2413 int ieee802_1x_init(struct hostapd_data
*hapd
)
2416 struct eapol_auth_config conf
;
2417 struct eapol_auth_cb cb
;
2419 dl_list_init(&hapd
->erp_keys
);
2421 os_memset(&conf
, 0, sizeof(conf
));
2422 conf
.eap_cfg
= hapd
->eap_cfg
;
2424 conf
.eap_reauth_period
= hapd
->conf
->eap_reauth_period
;
2425 conf
.wpa
= hapd
->conf
->wpa
;
2426 conf
.individual_wep_key_len
= hapd
->conf
->individual_wep_key_len
;
2427 conf
.eap_req_id_text
= hapd
->conf
->eap_req_id_text
;
2428 conf
.eap_req_id_text_len
= hapd
->conf
->eap_req_id_text_len
;
2429 conf
.erp_send_reauth_start
= hapd
->conf
->erp_send_reauth_start
;
2430 conf
.erp_domain
= hapd
->conf
->erp_domain
;
2432 os_memset(&cb
, 0, sizeof(cb
));
2433 cb
.eapol_send
= ieee802_1x_eapol_send
;
2434 cb
.aaa_send
= ieee802_1x_aaa_send
;
2435 cb
.finished
= _ieee802_1x_finished
;
2436 cb
.get_eap_user
= ieee802_1x_get_eap_user
;
2437 cb
.sta_entry_alive
= ieee802_1x_sta_entry_alive
;
2438 cb
.logger
= ieee802_1x_logger
;
2439 cb
.set_port_authorized
= ieee802_1x_set_port_authorized
;
2440 cb
.abort_auth
= _ieee802_1x_abort_auth
;
2441 cb
.tx_key
= _ieee802_1x_tx_key
;
2442 cb
.eapol_event
= ieee802_1x_eapol_event
;
2444 cb
.erp_get_key
= ieee802_1x_erp_get_key
;
2445 cb
.erp_add_key
= ieee802_1x_erp_add_key
;
2446 #endif /* CONFIG_ERP */
2448 hapd
->eapol_auth
= eapol_auth_init(&conf
, &cb
);
2449 if (hapd
->eapol_auth
== NULL
)
2452 if ((hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
) &&
2453 hostapd_set_drv_ieee8021x(hapd
, hapd
->conf
->iface
, 1))
2456 #ifndef CONFIG_NO_RADIUS
2457 if (radius_client_register(hapd
->radius
, RADIUS_AUTH
,
2458 ieee802_1x_receive_auth
, hapd
))
2460 #endif /* CONFIG_NO_RADIUS */
2462 if (hapd
->conf
->default_wep_key_len
) {
2463 for (i
= 0; i
< 4; i
++)
2464 hostapd_drv_set_key(hapd
->conf
->iface
, hapd
,
2465 WPA_ALG_NONE
, NULL
, i
, 0, NULL
, 0,
2468 ieee802_1x_rekey(hapd
, NULL
);
2470 if (hapd
->eapol_auth
->default_wep_key
== NULL
)
2478 void ieee802_1x_erp_flush(struct hostapd_data
*hapd
)
2480 struct eap_server_erp_key
*erp
;
2482 while ((erp
= dl_list_first(&hapd
->erp_keys
, struct eap_server_erp_key
,
2484 dl_list_del(&erp
->list
);
2485 bin_clear_free(erp
, sizeof(*erp
));
2490 void ieee802_1x_deinit(struct hostapd_data
*hapd
)
2492 eloop_cancel_timeout(ieee802_1x_rekey
, hapd
, NULL
);
2494 if (hapd
->driver
&& hapd
->drv_priv
&&
2495 (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
))
2496 hostapd_set_drv_ieee8021x(hapd
, hapd
->conf
->iface
, 0);
2498 eapol_auth_deinit(hapd
->eapol_auth
);
2499 hapd
->eapol_auth
= NULL
;
2501 ieee802_1x_erp_flush(hapd
);
2505 int ieee802_1x_tx_status(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2506 const u8
*buf
, size_t len
, int ack
)
2508 struct ieee80211_hdr
*hdr
;
2510 const unsigned char rfc1042_hdr
[ETH_ALEN
] =
2511 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
2515 if (len
< sizeof(*hdr
) + sizeof(rfc1042_hdr
) + 2)
2518 hdr
= (struct ieee80211_hdr
*) buf
;
2519 pos
= (u8
*) (hdr
+ 1);
2520 if (os_memcmp(pos
, rfc1042_hdr
, sizeof(rfc1042_hdr
)) != 0)
2522 pos
+= sizeof(rfc1042_hdr
);
2523 if (WPA_GET_BE16(pos
) != ETH_P_PAE
)
2527 return ieee802_1x_eapol_tx_status(hapd
, sta
, pos
, buf
+ len
- pos
,
2532 int ieee802_1x_eapol_tx_status(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2533 const u8
*buf
, int len
, int ack
)
2535 const struct ieee802_1x_hdr
*xhdr
=
2536 (const struct ieee802_1x_hdr
*) buf
;
2537 const u8
*pos
= buf
+ sizeof(*xhdr
);
2538 struct ieee802_1x_eapol_key
*key
;
2540 if (len
< (int) sizeof(*xhdr
))
2542 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
" TX status - version=%d "
2543 "type=%d length=%d - ack=%d",
2544 MAC2STR(sta
->addr
), xhdr
->version
, xhdr
->type
,
2545 be_to_host16(xhdr
->length
), ack
);
2548 if (xhdr
->type
== IEEE802_1X_TYPE_EAP_PACKET
&& ack
&&
2549 (sta
->flags
& WLAN_STA_WPS
) &&
2550 ap_sta_pending_delayed_1x_auth_fail_disconnect(hapd
, sta
)) {
2551 wpa_printf(MSG_DEBUG
,
2552 "WPS: Indicate EAP completion on ACK for EAP-Failure");
2553 hostapd_wps_eap_completed(hapd
);
2555 #endif /* CONFIG_WPS */
2557 if (xhdr
->type
!= IEEE802_1X_TYPE_EAPOL_KEY
)
2560 if (pos
+ sizeof(struct wpa_eapol_key
) <= buf
+ len
) {
2561 const struct wpa_eapol_key
*wpa
;
2562 wpa
= (const struct wpa_eapol_key
*) pos
;
2563 if (wpa
->type
== EAPOL_KEY_TYPE_RSN
||
2564 wpa
->type
== EAPOL_KEY_TYPE_WPA
)
2565 wpa_auth_eapol_key_tx_status(hapd
->wpa_auth
,
2569 /* EAPOL EAP-Packet packets are eventually re-sent by either Supplicant
2570 * or Authenticator state machines, but EAPOL-Key packets are not
2571 * retransmitted in case of failure. Try to re-send failed EAPOL-Key
2572 * packets couple of times because otherwise STA keys become
2573 * unsynchronized with AP. */
2574 if (!ack
&& pos
+ sizeof(*key
) <= buf
+ len
) {
2575 key
= (struct ieee802_1x_eapol_key
*) pos
;
2576 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE8021X
,
2577 HOSTAPD_LEVEL_DEBUG
, "did not Ack EAPOL-Key "
2578 "frame (%scast index=%d)",
2579 key
->key_index
& BIT(7) ? "uni" : "broad",
2580 key
->key_index
& ~BIT(7));
2581 /* TODO: re-send EAPOL-Key couple of times (with short delay
2582 * between them?). If all attempt fail, report error and
2583 * deauthenticate STA so that it will get new keys when
2584 * authenticating again (e.g., after returning in range).
2585 * Separate limit/transmit state needed both for unicast and
2586 * broadcast keys(?) */
2588 /* TODO: could move unicast key configuration from ieee802_1x_tx_key()
2589 * to here and change the key only if the EAPOL-Key packet was Acked.
2596 u8
* ieee802_1x_get_identity(struct eapol_state_machine
*sm
, size_t *len
)
2598 if (sm
== NULL
|| sm
->identity
== NULL
)
2601 *len
= sm
->identity_len
;
2602 return sm
->identity
;
2606 u8
* ieee802_1x_get_radius_class(struct eapol_state_machine
*sm
, size_t *len
,
2609 if (sm
== NULL
|| sm
->radius_class
.attr
== NULL
||
2610 idx
>= (int) sm
->radius_class
.count
)
2613 *len
= sm
->radius_class
.attr
[idx
].len
;
2614 return sm
->radius_class
.attr
[idx
].data
;
2618 struct wpabuf
* ieee802_1x_get_radius_cui(struct eapol_state_machine
*sm
)
2622 return sm
->radius_cui
;
2626 const u8
* ieee802_1x_get_key(struct eapol_state_machine
*sm
, size_t *len
)
2632 *len
= sm
->eap_if
->eapKeyDataLen
;
2633 return sm
->eap_if
->eapKeyData
;
2637 #ifdef CONFIG_MACSEC
2638 const u8
* ieee802_1x_get_session_id(struct eapol_state_machine
*sm
,
2642 if (!sm
|| !sm
->eap_if
)
2645 *len
= sm
->eap_if
->eapSessionIdLen
;
2646 return sm
->eap_if
->eapSessionId
;
2648 #endif /* CONFIG_MACSEC */
2651 void ieee802_1x_notify_port_enabled(struct eapol_state_machine
*sm
,
2656 sm
->eap_if
->portEnabled
= enabled
? TRUE
: FALSE
;
2657 eapol_auth_step(sm
);
2661 void ieee802_1x_notify_port_valid(struct eapol_state_machine
*sm
,
2666 sm
->portValid
= valid
? TRUE
: FALSE
;
2667 eapol_auth_step(sm
);
2671 void ieee802_1x_notify_pre_auth(struct eapol_state_machine
*sm
, int pre_auth
)
2676 sm
->flags
|= EAPOL_SM_PREAUTH
;
2678 sm
->flags
&= ~EAPOL_SM_PREAUTH
;
2682 static const char * bool_txt(Boolean val
)
2684 return val
? "TRUE" : "FALSE";
2688 int ieee802_1x_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
2695 int ieee802_1x_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2696 char *buf
, size_t buflen
)
2699 struct eapol_state_machine
*sm
= sta
->eapol_sm
;
2700 struct os_reltime diff
;
2703 char *identity_buf
= NULL
;
2708 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2709 "dot1xPaePortNumber=%d\n"
2710 "dot1xPaePortProtocolVersion=%d\n"
2711 "dot1xPaePortCapabilities=1\n"
2712 "dot1xPaePortInitialize=%d\n"
2713 "dot1xPaePortReauthenticate=FALSE\n",
2717 if (os_snprintf_error(buflen
- len
, ret
))
2721 /* dot1xAuthConfigTable */
2722 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2723 "dot1xAuthPaeState=%d\n"
2724 "dot1xAuthBackendAuthState=%d\n"
2725 "dot1xAuthAdminControlledDirections=%d\n"
2726 "dot1xAuthOperControlledDirections=%d\n"
2727 "dot1xAuthAuthControlledPortStatus=%d\n"
2728 "dot1xAuthAuthControlledPortControl=%d\n"
2729 "dot1xAuthQuietPeriod=%u\n"
2730 "dot1xAuthServerTimeout=%u\n"
2731 "dot1xAuthReAuthPeriod=%u\n"
2732 "dot1xAuthReAuthEnabled=%s\n"
2733 "dot1xAuthKeyTxEnabled=%s\n",
2734 sm
->auth_pae_state
+ 1,
2735 sm
->be_auth_state
+ 1,
2736 sm
->adminControlledDirections
,
2737 sm
->operControlledDirections
,
2743 bool_txt(sm
->reAuthEnabled
),
2744 bool_txt(sm
->keyTxEnabled
));
2745 if (os_snprintf_error(buflen
- len
, ret
))
2749 /* dot1xAuthStatsTable */
2750 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2751 "dot1xAuthEapolFramesRx=%u\n"
2752 "dot1xAuthEapolFramesTx=%u\n"
2753 "dot1xAuthEapolStartFramesRx=%u\n"
2754 "dot1xAuthEapolLogoffFramesRx=%u\n"
2755 "dot1xAuthEapolRespIdFramesRx=%u\n"
2756 "dot1xAuthEapolRespFramesRx=%u\n"
2757 "dot1xAuthEapolReqIdFramesTx=%u\n"
2758 "dot1xAuthEapolReqFramesTx=%u\n"
2759 "dot1xAuthInvalidEapolFramesRx=%u\n"
2760 "dot1xAuthEapLengthErrorFramesRx=%u\n"
2761 "dot1xAuthLastEapolFrameVersion=%u\n"
2762 "dot1xAuthLastEapolFrameSource=" MACSTR
"\n",
2763 sm
->dot1xAuthEapolFramesRx
,
2764 sm
->dot1xAuthEapolFramesTx
,
2765 sm
->dot1xAuthEapolStartFramesRx
,
2766 sm
->dot1xAuthEapolLogoffFramesRx
,
2767 sm
->dot1xAuthEapolRespIdFramesRx
,
2768 sm
->dot1xAuthEapolRespFramesRx
,
2769 sm
->dot1xAuthEapolReqIdFramesTx
,
2770 sm
->dot1xAuthEapolReqFramesTx
,
2771 sm
->dot1xAuthInvalidEapolFramesRx
,
2772 sm
->dot1xAuthEapLengthErrorFramesRx
,
2773 sm
->dot1xAuthLastEapolFrameVersion
,
2775 if (os_snprintf_error(buflen
- len
, ret
))
2779 /* dot1xAuthDiagTable */
2780 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2781 "dot1xAuthEntersConnecting=%u\n"
2782 "dot1xAuthEapLogoffsWhileConnecting=%u\n"
2783 "dot1xAuthEntersAuthenticating=%u\n"
2784 "dot1xAuthAuthSuccessesWhileAuthenticating=%u\n"
2785 "dot1xAuthAuthTimeoutsWhileAuthenticating=%u\n"
2786 "dot1xAuthAuthFailWhileAuthenticating=%u\n"
2787 "dot1xAuthAuthEapStartsWhileAuthenticating=%u\n"
2788 "dot1xAuthAuthEapLogoffWhileAuthenticating=%u\n"
2789 "dot1xAuthAuthReauthsWhileAuthenticated=%u\n"
2790 "dot1xAuthAuthEapStartsWhileAuthenticated=%u\n"
2791 "dot1xAuthAuthEapLogoffWhileAuthenticated=%u\n"
2792 "dot1xAuthBackendResponses=%u\n"
2793 "dot1xAuthBackendAccessChallenges=%u\n"
2794 "dot1xAuthBackendOtherRequestsToSupplicant=%u\n"
2795 "dot1xAuthBackendAuthSuccesses=%u\n"
2796 "dot1xAuthBackendAuthFails=%u\n",
2797 sm
->authEntersConnecting
,
2798 sm
->authEapLogoffsWhileConnecting
,
2799 sm
->authEntersAuthenticating
,
2800 sm
->authAuthSuccessesWhileAuthenticating
,
2801 sm
->authAuthTimeoutsWhileAuthenticating
,
2802 sm
->authAuthFailWhileAuthenticating
,
2803 sm
->authAuthEapStartsWhileAuthenticating
,
2804 sm
->authAuthEapLogoffWhileAuthenticating
,
2805 sm
->authAuthReauthsWhileAuthenticated
,
2806 sm
->authAuthEapStartsWhileAuthenticated
,
2807 sm
->authAuthEapLogoffWhileAuthenticated
,
2808 sm
->backendResponses
,
2809 sm
->backendAccessChallenges
,
2810 sm
->backendOtherRequestsToSupplicant
,
2811 sm
->backendAuthSuccesses
,
2812 sm
->backendAuthFails
);
2813 if (os_snprintf_error(buflen
- len
, ret
))
2817 /* dot1xAuthSessionStatsTable */
2818 os_reltime_age(&sta
->acct_session_start
, &diff
);
2819 if (sm
->eap
&& !sm
->identity
) {
2823 id
= eap_get_identity(sm
->eap
, &id_len
);
2825 identity_buf
= dup_binstr(id
, id_len
);
2827 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2828 /* TODO: dot1xAuthSessionOctetsRx */
2829 /* TODO: dot1xAuthSessionOctetsTx */
2830 /* TODO: dot1xAuthSessionFramesRx */
2831 /* TODO: dot1xAuthSessionFramesTx */
2832 "dot1xAuthSessionId=%016llX\n"
2833 "dot1xAuthSessionAuthenticMethod=%d\n"
2834 "dot1xAuthSessionTime=%u\n"
2835 "dot1xAuthSessionTerminateCause=999\n"
2836 "dot1xAuthSessionUserName=%s\n",
2837 (unsigned long long) sta
->acct_session_id
,
2838 (wpa_key_mgmt_wpa_ieee8021x(
2839 wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) ?
2841 (unsigned int) diff
.sec
,
2842 sm
->identity
? (char *) sm
->identity
:
2843 (identity_buf
? identity_buf
: "N/A"));
2844 os_free(identity_buf
);
2845 if (os_snprintf_error(buflen
- len
, ret
))
2849 if (sm
->acct_multi_session_id
) {
2850 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2851 "authMultiSessionId=%016llX\n",
2852 (unsigned long long)
2853 sm
->acct_multi_session_id
);
2854 if (os_snprintf_error(buflen
- len
, ret
))
2859 name1
= eap_server_get_name(0, sm
->eap_type_authsrv
);
2860 name2
= eap_server_get_name(0, sm
->eap_type_supp
);
2861 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2862 "last_eap_type_as=%d (%s)\n"
2863 "last_eap_type_sta=%d (%s)\n",
2864 sm
->eap_type_authsrv
, name1
,
2865 sm
->eap_type_supp
, name2
);
2866 if (os_snprintf_error(buflen
- len
, ret
))
2875 static void ieee802_1x_wnm_notif_send(void *eloop_ctx
, void *timeout_ctx
)
2877 struct hostapd_data
*hapd
= eloop_ctx
;
2878 struct sta_info
*sta
= timeout_ctx
;
2880 if (sta
->remediation
) {
2881 wpa_printf(MSG_DEBUG
, "HS 2.0: Send WNM-Notification to "
2882 MACSTR
" to indicate Subscription Remediation",
2883 MAC2STR(sta
->addr
));
2884 hs20_send_wnm_notification(hapd
, sta
->addr
,
2885 sta
->remediation_method
,
2886 sta
->remediation_url
);
2887 os_free(sta
->remediation_url
);
2888 sta
->remediation_url
= NULL
;
2891 if (sta
->hs20_deauth_req
) {
2892 wpa_printf(MSG_DEBUG
, "HS 2.0: Send WNM-Notification to "
2893 MACSTR
" to indicate imminent deauthentication",
2894 MAC2STR(sta
->addr
));
2895 hs20_send_wnm_notification_deauth_req(hapd
, sta
->addr
,
2896 sta
->hs20_deauth_req
);
2899 if (sta
->hs20_t_c_filtering
) {
2900 wpa_printf(MSG_DEBUG
, "HS 2.0: Send WNM-Notification to "
2901 MACSTR
" to indicate Terms and Conditions filtering",
2902 MAC2STR(sta
->addr
));
2903 hs20_send_wnm_notification_t_c(hapd
, sta
->addr
, sta
->t_c_url
);
2904 os_free(sta
->t_c_url
);
2905 sta
->t_c_url
= NULL
;
2908 #endif /* CONFIG_HS20 */
2911 static void ieee802_1x_finished(struct hostapd_data
*hapd
,
2912 struct sta_info
*sta
, int success
,
2917 /* TODO: get PMKLifetime from WPA parameters */
2918 static const int dot11RSNAConfigPMKLifetime
= 43200;
2919 unsigned int session_timeout
;
2920 struct os_reltime now
, remaining
;
2923 if (remediation
&& !sta
->remediation
) {
2924 sta
->remediation
= 1;
2925 os_free(sta
->remediation_url
);
2926 sta
->remediation_url
=
2927 os_strdup(hapd
->conf
->subscr_remediation_url
);
2928 sta
->remediation_method
= 1; /* SOAP-XML SPP */
2931 if (success
&& (sta
->remediation
|| sta
->hs20_deauth_req
||
2932 sta
->hs20_t_c_filtering
)) {
2933 wpa_printf(MSG_DEBUG
, "HS 2.0: Schedule WNM-Notification to "
2934 MACSTR
" in 100 ms", MAC2STR(sta
->addr
));
2935 eloop_cancel_timeout(ieee802_1x_wnm_notif_send
, hapd
, sta
);
2936 eloop_register_timeout(0, 100000, ieee802_1x_wnm_notif_send
,
2939 #endif /* CONFIG_HS20 */
2941 #ifdef CONFIG_MACSEC
2942 ieee802_1x_notify_create_actor_hapd(hapd
, sta
);
2943 #endif /* CONFIG_MACSEC */
2945 key
= ieee802_1x_get_key(sta
->eapol_sm
, &len
);
2946 if (sta
->session_timeout_set
) {
2947 os_get_reltime(&now
);
2948 os_reltime_sub(&sta
->session_timeout
, &now
, &remaining
);
2949 session_timeout
= (remaining
.sec
> 0) ? remaining
.sec
: 1;
2951 session_timeout
= dot11RSNAConfigPMKLifetime
;
2953 if (success
&& key
&& len
>= PMK_LEN
&& !sta
->remediation
&&
2954 !sta
->hs20_deauth_requested
&&
2955 wpa_auth_pmksa_add(sta
->wpa_sm
, key
, len
, session_timeout
,
2956 sta
->eapol_sm
) == 0) {
2957 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_WPA
,
2958 HOSTAPD_LEVEL_DEBUG
,
2959 "Added PMKSA cache entry (IEEE 802.1X)");
2964 * Many devices require deauthentication after WPS provisioning
2965 * and some may not be be able to do that themselves, so
2966 * disconnect the client here. In addition, this may also
2967 * benefit IEEE 802.1X/EAPOL authentication cases, too since
2968 * the EAPOL PAE state machine would remain in HELD state for
2969 * considerable amount of time and some EAP methods, like
2970 * EAP-FAST with anonymous provisioning, may require another
2971 * EAPOL authentication to be started to complete connection.
2973 ap_sta_delayed_1x_auth_fail_disconnect(hapd
, sta
);