2 * hostapd / IEEE 802.1X-2004 Authenticator - EAPOL state machine
3 * Copyright (c) 2002-2008, 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.
18 #include "ieee802_1x.h"
24 #include "eap_server/eap.h"
25 #include "state_machine.h"
26 #include "eap_common/eap_common.h"
28 #define STATE_MACHINE_DATA struct eapol_state_machine
29 #define STATE_MACHINE_DEBUG_PREFIX "IEEE 802.1X"
30 #define STATE_MACHINE_ADDR sm->addr
32 static struct eapol_callbacks eapol_cb
;
34 /* EAPOL state machines are described in IEEE Std 802.1X-2004, Chap. 8.2 */
36 #define setPortAuthorized() \
37 sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 1)
38 #define setPortUnauthorized() \
39 sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 0)
42 #define txCannedFail() eapol_auth_tx_canned_eap(sm, 0)
43 #define txCannedSuccess() eapol_auth_tx_canned_eap(sm, 1)
44 #define txReq() eapol_auth_tx_req(sm)
45 #define abortAuth() sm->eapol->cb.abort_auth(sm->hapd, sm->sta)
46 #define txKey() sm->eapol->cb.tx_key(sm->hapd, sm->sta)
47 #define processKey() do { } while (0)
50 static void eapol_sm_step_run(struct eapol_state_machine
*sm
);
51 static void eapol_sm_step_cb(void *eloop_ctx
, void *timeout_ctx
);
54 static void eapol_auth_logger(struct eapol_authenticator
*eapol
,
55 const u8
*addr
, logger_level level
,
58 if (eapol
->cb
.logger
== NULL
)
60 eapol
->cb
.logger(eapol
->conf
.hapd
, addr
, level
, txt
);
64 static void eapol_auth_vlogger(struct eapol_authenticator
*eapol
,
65 const u8
*addr
, logger_level level
,
72 if (eapol
->cb
.logger
== NULL
)
75 maxlen
= os_strlen(fmt
) + 100;
76 format
= os_malloc(maxlen
);
81 vsnprintf(format
, maxlen
, fmt
, ap
);
84 eapol_auth_logger(eapol
, addr
, level
, format
);
90 static void eapol_auth_tx_canned_eap(struct eapol_state_machine
*sm
,
95 os_memset(&eap
, 0, sizeof(eap
));
97 eap
.code
= success
? EAP_CODE_SUCCESS
: EAP_CODE_FAILURE
;
98 eap
.identifier
= ++sm
->last_eap_id
;
99 eap
.length
= host_to_be16(sizeof(eap
));
101 eapol_auth_vlogger(sm
->eapol
, sm
->addr
, EAPOL_LOGGER_DEBUG
,
102 "Sending canned EAP packet %s (identifier %d)",
103 success
? "SUCCESS" : "FAILURE", eap
.identifier
);
104 sm
->eapol
->cb
.eapol_send(sm
->hapd
, sm
->sta
, IEEE802_1X_TYPE_EAP_PACKET
,
105 (u8
*) &eap
, sizeof(eap
));
106 sm
->dot1xAuthEapolFramesTx
++;
110 static void eapol_auth_tx_req(struct eapol_state_machine
*sm
)
112 if (sm
->eap_if
->eapReqData
== NULL
||
113 wpabuf_len(sm
->eap_if
->eapReqData
) < sizeof(struct eap_hdr
)) {
114 eapol_auth_logger(sm
->eapol
, sm
->addr
,
116 "TxReq called, but there is no EAP request "
117 "from authentication server");
121 if (sm
->flags
& EAPOL_SM_WAIT_START
) {
122 wpa_printf(MSG_DEBUG
, "EAPOL: Drop EAPOL TX to " MACSTR
123 " while waiting for EAPOL-Start",
128 sm
->last_eap_id
= eap_get_id(sm
->eap_if
->eapReqData
);
129 eapol_auth_vlogger(sm
->eapol
, sm
->addr
, EAPOL_LOGGER_DEBUG
,
130 "Sending EAP Packet (identifier %d)",
132 sm
->eapol
->cb
.eapol_send(sm
->hapd
, sm
->sta
, IEEE802_1X_TYPE_EAP_PACKET
,
133 wpabuf_head(sm
->eap_if
->eapReqData
),
134 wpabuf_len(sm
->eap_if
->eapReqData
));
135 sm
->dot1xAuthEapolFramesTx
++;
136 if (eap_get_type(sm
->eap_if
->eapReqData
) == EAP_TYPE_IDENTITY
)
137 sm
->dot1xAuthEapolReqIdFramesTx
++;
139 sm
->dot1xAuthEapolReqFramesTx
++;
143 /* Port Timers state machine - implemented as a function that will be called
144 * once a second as a registered event loop timeout */
146 static void eapol_port_timers_tick(void *eloop_ctx
, void *timeout_ctx
)
148 struct eapol_state_machine
*state
= timeout_ctx
;
150 if (state
->aWhile
> 0) {
152 if (state
->aWhile
== 0) {
153 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
155 MAC2STR(state
->addr
));
159 if (state
->quietWhile
> 0) {
161 if (state
->quietWhile
== 0) {
162 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
163 " - quietWhile --> 0",
164 MAC2STR(state
->addr
));
168 if (state
->reAuthWhen
> 0) {
170 if (state
->reAuthWhen
== 0) {
171 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
172 " - reAuthWhen --> 0",
173 MAC2STR(state
->addr
));
177 eapol_sm_step_run(state
);
179 eloop_register_timeout(1, 0, eapol_port_timers_tick
, eloop_ctx
, state
);
184 /* Authenticator PAE state machine */
186 SM_STATE(AUTH_PAE
, INITIALIZE
)
188 SM_ENTRY_MA(AUTH_PAE
, INITIALIZE
, auth_pae
);
193 SM_STATE(AUTH_PAE
, DISCONNECTED
)
195 int from_initialize
= sm
->auth_pae_state
== AUTH_PAE_INITIALIZE
;
197 if (sm
->eapolLogoff
) {
198 if (sm
->auth_pae_state
== AUTH_PAE_CONNECTING
)
199 sm
->authEapLogoffsWhileConnecting
++;
200 else if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATED
)
201 sm
->authAuthEapLogoffWhileAuthenticated
++;
204 SM_ENTRY_MA(AUTH_PAE
, DISCONNECTED
, auth_pae
);
206 sm
->authPortStatus
= Unauthorized
;
207 setPortUnauthorized();
209 sm
->eapolLogoff
= FALSE
;
210 if (!from_initialize
) {
211 sm
->eapol
->cb
.finished(sm
->hapd
, sm
->sta
, 0,
212 sm
->flags
& EAPOL_SM_PREAUTH
);
217 SM_STATE(AUTH_PAE
, RESTART
)
219 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATED
) {
220 if (sm
->reAuthenticate
)
221 sm
->authAuthReauthsWhileAuthenticated
++;
223 sm
->authAuthEapStartsWhileAuthenticated
++;
225 sm
->authAuthEapLogoffWhileAuthenticated
++;
228 SM_ENTRY_MA(AUTH_PAE
, RESTART
, auth_pae
);
230 sm
->eap_if
->eapRestart
= TRUE
;
234 SM_STATE(AUTH_PAE
, CONNECTING
)
236 if (sm
->auth_pae_state
!= AUTH_PAE_CONNECTING
)
237 sm
->authEntersConnecting
++;
239 SM_ENTRY_MA(AUTH_PAE
, CONNECTING
, auth_pae
);
241 sm
->reAuthenticate
= FALSE
;
246 SM_STATE(AUTH_PAE
, HELD
)
248 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
&& sm
->authFail
)
249 sm
->authAuthFailWhileAuthenticating
++;
251 SM_ENTRY_MA(AUTH_PAE
, HELD
, auth_pae
);
253 sm
->authPortStatus
= Unauthorized
;
254 setPortUnauthorized();
255 sm
->quietWhile
= sm
->quietPeriod
;
256 sm
->eapolLogoff
= FALSE
;
258 eapol_auth_vlogger(sm
->eapol
, sm
->addr
, EAPOL_LOGGER_WARNING
,
259 "authentication failed - EAP type: %d (%s)",
260 sm
->eap_type_authsrv
,
261 eap_type_text(sm
->eap_type_authsrv
));
262 if (sm
->eap_type_authsrv
!= sm
->eap_type_supp
) {
263 eapol_auth_vlogger(sm
->eapol
, sm
->addr
, EAPOL_LOGGER_INFO
,
264 "Supplicant used different EAP type: "
265 "%d (%s)", sm
->eap_type_supp
,
266 eap_type_text(sm
->eap_type_supp
));
268 sm
->eapol
->cb
.finished(sm
->hapd
, sm
->sta
, 0,
269 sm
->flags
& EAPOL_SM_PREAUTH
);
273 SM_STATE(AUTH_PAE
, AUTHENTICATED
)
277 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
&& sm
->authSuccess
)
278 sm
->authAuthSuccessesWhileAuthenticating
++;
280 SM_ENTRY_MA(AUTH_PAE
, AUTHENTICATED
, auth_pae
);
282 sm
->authPortStatus
= Authorized
;
285 if (sm
->flags
& EAPOL_SM_PREAUTH
)
286 extra
= " (pre-authentication)";
287 else if (wpa_auth_sta_get_pmksa(sm
->sta
->wpa_sm
))
288 extra
= " (PMKSA cache)";
289 eapol_auth_vlogger(sm
->eapol
, sm
->addr
, EAPOL_LOGGER_INFO
,
290 "authenticated - EAP type: %d (%s)%s",
291 sm
->eap_type_authsrv
,
292 eap_type_text(sm
->eap_type_authsrv
), extra
);
293 sm
->eapol
->cb
.finished(sm
->hapd
, sm
->sta
, 1,
294 sm
->flags
& EAPOL_SM_PREAUTH
);
298 SM_STATE(AUTH_PAE
, AUTHENTICATING
)
300 SM_ENTRY_MA(AUTH_PAE
, AUTHENTICATING
, auth_pae
);
302 sm
->eapolStart
= FALSE
;
303 sm
->authSuccess
= FALSE
;
304 sm
->authFail
= FALSE
;
305 sm
->authTimeout
= FALSE
;
306 sm
->authStart
= TRUE
;
312 SM_STATE(AUTH_PAE
, ABORTING
)
314 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
) {
316 sm
->authAuthTimeoutsWhileAuthenticating
++;
318 sm
->authAuthEapStartsWhileAuthenticating
++;
320 sm
->authAuthEapLogoffWhileAuthenticating
++;
323 SM_ENTRY_MA(AUTH_PAE
, ABORTING
, auth_pae
);
325 sm
->authAbort
= TRUE
;
331 SM_STATE(AUTH_PAE
, FORCE_AUTH
)
333 SM_ENTRY_MA(AUTH_PAE
, FORCE_AUTH
, auth_pae
);
335 sm
->authPortStatus
= Authorized
;
337 sm
->portMode
= ForceAuthorized
;
338 sm
->eapolStart
= FALSE
;
343 SM_STATE(AUTH_PAE
, FORCE_UNAUTH
)
345 SM_ENTRY_MA(AUTH_PAE
, FORCE_UNAUTH
, auth_pae
);
347 sm
->authPortStatus
= Unauthorized
;
348 setPortUnauthorized();
349 sm
->portMode
= ForceUnauthorized
;
350 sm
->eapolStart
= FALSE
;
357 if ((sm
->portControl
== Auto
&& sm
->portMode
!= sm
->portControl
) ||
358 sm
->initialize
|| !sm
->eap_if
->portEnabled
)
359 SM_ENTER(AUTH_PAE
, INITIALIZE
);
360 else if (sm
->portControl
== ForceAuthorized
&&
361 sm
->portMode
!= sm
->portControl
&&
362 !(sm
->initialize
|| !sm
->eap_if
->portEnabled
))
363 SM_ENTER(AUTH_PAE
, FORCE_AUTH
);
364 else if (sm
->portControl
== ForceUnauthorized
&&
365 sm
->portMode
!= sm
->portControl
&&
366 !(sm
->initialize
|| !sm
->eap_if
->portEnabled
))
367 SM_ENTER(AUTH_PAE
, FORCE_UNAUTH
);
369 switch (sm
->auth_pae_state
) {
370 case AUTH_PAE_INITIALIZE
:
371 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
373 case AUTH_PAE_DISCONNECTED
:
374 SM_ENTER(AUTH_PAE
, RESTART
);
376 case AUTH_PAE_RESTART
:
377 if (!sm
->eap_if
->eapRestart
)
378 SM_ENTER(AUTH_PAE
, CONNECTING
);
381 if (sm
->quietWhile
== 0)
382 SM_ENTER(AUTH_PAE
, RESTART
);
384 case AUTH_PAE_CONNECTING
:
385 if (sm
->eapolLogoff
|| sm
->reAuthCount
> sm
->reAuthMax
)
386 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
387 else if ((sm
->eap_if
->eapReq
&&
388 sm
->reAuthCount
<= sm
->reAuthMax
) ||
389 sm
->eap_if
->eapSuccess
|| sm
->eap_if
->eapFail
)
390 SM_ENTER(AUTH_PAE
, AUTHENTICATING
);
392 case AUTH_PAE_AUTHENTICATED
:
393 if (sm
->eapolStart
|| sm
->reAuthenticate
)
394 SM_ENTER(AUTH_PAE
, RESTART
);
395 else if (sm
->eapolLogoff
|| !sm
->portValid
)
396 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
398 case AUTH_PAE_AUTHENTICATING
:
399 if (sm
->authSuccess
&& sm
->portValid
)
400 SM_ENTER(AUTH_PAE
, AUTHENTICATED
);
401 else if (sm
->authFail
||
402 (sm
->keyDone
&& !sm
->portValid
))
403 SM_ENTER(AUTH_PAE
, HELD
);
404 else if (sm
->eapolStart
|| sm
->eapolLogoff
||
406 SM_ENTER(AUTH_PAE
, ABORTING
);
408 case AUTH_PAE_ABORTING
:
409 if (sm
->eapolLogoff
&& !sm
->authAbort
)
410 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
411 else if (!sm
->eapolLogoff
&& !sm
->authAbort
)
412 SM_ENTER(AUTH_PAE
, RESTART
);
414 case AUTH_PAE_FORCE_AUTH
:
416 SM_ENTER(AUTH_PAE
, FORCE_AUTH
);
418 case AUTH_PAE_FORCE_UNAUTH
:
420 SM_ENTER(AUTH_PAE
, FORCE_UNAUTH
);
428 /* Backend Authentication state machine */
430 SM_STATE(BE_AUTH
, INITIALIZE
)
432 SM_ENTRY_MA(BE_AUTH
, INITIALIZE
, be_auth
);
435 sm
->eap_if
->eapNoReq
= FALSE
;
436 sm
->authAbort
= FALSE
;
440 SM_STATE(BE_AUTH
, REQUEST
)
442 SM_ENTRY_MA(BE_AUTH
, REQUEST
, be_auth
);
445 sm
->eap_if
->eapReq
= FALSE
;
446 sm
->backendOtherRequestsToSupplicant
++;
449 * Clearing eapolEap here is not specified in IEEE Std 802.1X-2004, but
450 * it looks like this would be logical thing to do there since the old
451 * EAP response would not be valid anymore after the new EAP request
454 * A race condition has been reported, in which hostapd ended up
455 * sending out EAP-Response/Identity as a response to the first
456 * EAP-Request from the main EAP method. This can be avoided by
457 * clearing eapolEap here.
459 sm
->eapolEap
= FALSE
;
463 SM_STATE(BE_AUTH
, RESPONSE
)
465 SM_ENTRY_MA(BE_AUTH
, RESPONSE
, be_auth
);
467 sm
->authTimeout
= FALSE
;
468 sm
->eapolEap
= FALSE
;
469 sm
->eap_if
->eapNoReq
= FALSE
;
470 sm
->aWhile
= sm
->serverTimeout
;
471 sm
->eap_if
->eapResp
= TRUE
;
472 /* sendRespToServer(); */
473 sm
->backendResponses
++;
477 SM_STATE(BE_AUTH
, SUCCESS
)
479 SM_ENTRY_MA(BE_AUTH
, SUCCESS
, be_auth
);
482 sm
->authSuccess
= TRUE
;
487 SM_STATE(BE_AUTH
, FAIL
)
489 SM_ENTRY_MA(BE_AUTH
, FAIL
, be_auth
);
496 SM_STATE(BE_AUTH
, TIMEOUT
)
498 SM_ENTRY_MA(BE_AUTH
, TIMEOUT
, be_auth
);
500 sm
->authTimeout
= TRUE
;
504 SM_STATE(BE_AUTH
, IDLE
)
506 SM_ENTRY_MA(BE_AUTH
, IDLE
, be_auth
);
508 sm
->authStart
= FALSE
;
512 SM_STATE(BE_AUTH
, IGNORE
)
514 SM_ENTRY_MA(BE_AUTH
, IGNORE
, be_auth
);
516 sm
->eap_if
->eapNoReq
= FALSE
;
522 if (sm
->portControl
!= Auto
|| sm
->initialize
|| sm
->authAbort
) {
523 SM_ENTER(BE_AUTH
, INITIALIZE
);
527 switch (sm
->be_auth_state
) {
528 case BE_AUTH_INITIALIZE
:
529 SM_ENTER(BE_AUTH
, IDLE
);
531 case BE_AUTH_REQUEST
:
533 SM_ENTER(BE_AUTH
, RESPONSE
);
534 else if (sm
->eap_if
->eapReq
)
535 SM_ENTER(BE_AUTH
, REQUEST
);
536 else if (sm
->eap_if
->eapTimeout
)
537 SM_ENTER(BE_AUTH
, TIMEOUT
);
539 case BE_AUTH_RESPONSE
:
540 if (sm
->eap_if
->eapNoReq
)
541 SM_ENTER(BE_AUTH
, IGNORE
);
542 if (sm
->eap_if
->eapReq
) {
543 sm
->backendAccessChallenges
++;
544 SM_ENTER(BE_AUTH
, REQUEST
);
545 } else if (sm
->aWhile
== 0)
546 SM_ENTER(BE_AUTH
, TIMEOUT
);
547 else if (sm
->eap_if
->eapFail
) {
548 sm
->backendAuthFails
++;
549 SM_ENTER(BE_AUTH
, FAIL
);
550 } else if (sm
->eap_if
->eapSuccess
) {
551 sm
->backendAuthSuccesses
++;
552 SM_ENTER(BE_AUTH
, SUCCESS
);
555 case BE_AUTH_SUCCESS
:
556 SM_ENTER(BE_AUTH
, IDLE
);
559 SM_ENTER(BE_AUTH
, IDLE
);
561 case BE_AUTH_TIMEOUT
:
562 SM_ENTER(BE_AUTH
, IDLE
);
565 if (sm
->eap_if
->eapFail
&& sm
->authStart
)
566 SM_ENTER(BE_AUTH
, FAIL
);
567 else if (sm
->eap_if
->eapReq
&& sm
->authStart
)
568 SM_ENTER(BE_AUTH
, REQUEST
);
569 else if (sm
->eap_if
->eapSuccess
&& sm
->authStart
)
570 SM_ENTER(BE_AUTH
, SUCCESS
);
574 SM_ENTER(BE_AUTH
, RESPONSE
);
575 else if (sm
->eap_if
->eapReq
)
576 SM_ENTER(BE_AUTH
, REQUEST
);
577 else if (sm
->eap_if
->eapTimeout
)
578 SM_ENTER(BE_AUTH
, TIMEOUT
);
585 /* Reauthentication Timer state machine */
587 SM_STATE(REAUTH_TIMER
, INITIALIZE
)
589 SM_ENTRY_MA(REAUTH_TIMER
, INITIALIZE
, reauth_timer
);
591 sm
->reAuthWhen
= sm
->reAuthPeriod
;
595 SM_STATE(REAUTH_TIMER
, REAUTHENTICATE
)
597 SM_ENTRY_MA(REAUTH_TIMER
, REAUTHENTICATE
, reauth_timer
);
599 sm
->reAuthenticate
= TRUE
;
600 wpa_auth_sm_event(sm
->sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
604 SM_STEP(REAUTH_TIMER
)
606 if (sm
->portControl
!= Auto
|| sm
->initialize
||
607 sm
->authPortStatus
== Unauthorized
|| !sm
->reAuthEnabled
) {
608 SM_ENTER(REAUTH_TIMER
, INITIALIZE
);
612 switch (sm
->reauth_timer_state
) {
613 case REAUTH_TIMER_INITIALIZE
:
614 if (sm
->reAuthWhen
== 0)
615 SM_ENTER(REAUTH_TIMER
, REAUTHENTICATE
);
617 case REAUTH_TIMER_REAUTHENTICATE
:
618 SM_ENTER(REAUTH_TIMER
, INITIALIZE
);
625 /* Authenticator Key Transmit state machine */
627 SM_STATE(AUTH_KEY_TX
, NO_KEY_TRANSMIT
)
629 SM_ENTRY_MA(AUTH_KEY_TX
, NO_KEY_TRANSMIT
, auth_key_tx
);
633 SM_STATE(AUTH_KEY_TX
, KEY_TRANSMIT
)
635 SM_ENTRY_MA(AUTH_KEY_TX
, KEY_TRANSMIT
, auth_key_tx
);
638 sm
->eap_if
->eapKeyAvailable
= FALSE
;
645 if (sm
->initialize
|| sm
->portControl
!= Auto
) {
646 SM_ENTER(AUTH_KEY_TX
, NO_KEY_TRANSMIT
);
650 switch (sm
->auth_key_tx_state
) {
651 case AUTH_KEY_TX_NO_KEY_TRANSMIT
:
652 if (sm
->keyTxEnabled
&& sm
->eap_if
->eapKeyAvailable
&&
653 sm
->keyRun
&& !wpa_auth_sta_wpa_version(sm
->sta
->wpa_sm
))
654 SM_ENTER(AUTH_KEY_TX
, KEY_TRANSMIT
);
656 case AUTH_KEY_TX_KEY_TRANSMIT
:
657 if (!sm
->keyTxEnabled
|| !sm
->keyRun
)
658 SM_ENTER(AUTH_KEY_TX
, NO_KEY_TRANSMIT
);
659 else if (sm
->eap_if
->eapKeyAvailable
)
660 SM_ENTER(AUTH_KEY_TX
, KEY_TRANSMIT
);
667 /* Key Receive state machine */
669 SM_STATE(KEY_RX
, NO_KEY_RECEIVE
)
671 SM_ENTRY_MA(KEY_RX
, NO_KEY_RECEIVE
, key_rx
);
675 SM_STATE(KEY_RX
, KEY_RECEIVE
)
677 SM_ENTRY_MA(KEY_RX
, KEY_RECEIVE
, key_rx
);
686 if (sm
->initialize
|| !sm
->eap_if
->portEnabled
) {
687 SM_ENTER(KEY_RX
, NO_KEY_RECEIVE
);
691 switch (sm
->key_rx_state
) {
692 case KEY_RX_NO_KEY_RECEIVE
:
694 SM_ENTER(KEY_RX
, KEY_RECEIVE
);
696 case KEY_RX_KEY_RECEIVE
:
698 SM_ENTER(KEY_RX
, KEY_RECEIVE
);
705 /* Controlled Directions state machine */
707 SM_STATE(CTRL_DIR
, FORCE_BOTH
)
709 SM_ENTRY_MA(CTRL_DIR
, FORCE_BOTH
, ctrl_dir
);
710 sm
->operControlledDirections
= Both
;
714 SM_STATE(CTRL_DIR
, IN_OR_BOTH
)
716 SM_ENTRY_MA(CTRL_DIR
, IN_OR_BOTH
, ctrl_dir
);
717 sm
->operControlledDirections
= sm
->adminControlledDirections
;
723 if (sm
->initialize
) {
724 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
728 switch (sm
->ctrl_dir_state
) {
729 case CTRL_DIR_FORCE_BOTH
:
730 if (sm
->eap_if
->portEnabled
&& sm
->operEdge
)
731 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
733 case CTRL_DIR_IN_OR_BOTH
:
734 if (sm
->operControlledDirections
!=
735 sm
->adminControlledDirections
)
736 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
737 if (!sm
->eap_if
->portEnabled
|| !sm
->operEdge
)
738 SM_ENTER(CTRL_DIR
, FORCE_BOTH
);
745 struct eapol_state_machine
*
746 eapol_auth_alloc(struct eapol_authenticator
*eapol
, const u8
*addr
,
747 int preauth
, struct sta_info
*sta
)
749 struct eapol_state_machine
*sm
;
750 struct hostapd_data
*hapd
; /* TODO: to be removed */
751 struct eap_config eap_conf
;
755 hapd
= eapol
->conf
.hapd
;
757 sm
= os_zalloc(sizeof(*sm
));
759 wpa_printf(MSG_DEBUG
, "IEEE 802.1X state machine allocation "
763 sm
->radius_identifier
= -1;
764 os_memcpy(sm
->addr
, addr
, ETH_ALEN
);
766 sm
->flags
|= EAPOL_SM_PREAUTH
;
772 /* Set default values for state machine constants */
773 sm
->auth_pae_state
= AUTH_PAE_INITIALIZE
;
774 sm
->quietPeriod
= AUTH_PAE_DEFAULT_quietPeriod
;
775 sm
->reAuthMax
= AUTH_PAE_DEFAULT_reAuthMax
;
777 sm
->be_auth_state
= BE_AUTH_INITIALIZE
;
778 sm
->serverTimeout
= BE_AUTH_DEFAULT_serverTimeout
;
780 sm
->reauth_timer_state
= REAUTH_TIMER_INITIALIZE
;
781 sm
->reAuthPeriod
= eapol
->conf
.eap_reauth_period
;
782 sm
->reAuthEnabled
= eapol
->conf
.eap_reauth_period
> 0 ? TRUE
: FALSE
;
784 sm
->auth_key_tx_state
= AUTH_KEY_TX_NO_KEY_TRANSMIT
;
786 sm
->key_rx_state
= KEY_RX_NO_KEY_RECEIVE
;
788 sm
->ctrl_dir_state
= CTRL_DIR_IN_OR_BOTH
;
790 sm
->portControl
= Auto
;
792 if (!eapol
->conf
.wpa
&&
793 (hapd
->default_wep_key
|| eapol
->conf
.individual_wep_key_len
> 0))
794 sm
->keyTxEnabled
= TRUE
;
796 sm
->keyTxEnabled
= FALSE
;
798 sm
->portValid
= FALSE
;
800 sm
->portValid
= TRUE
;
802 os_memset(&eap_conf
, 0, sizeof(eap_conf
));
803 eap_conf
.eap_server
= eapol
->conf
.eap_server
;
804 eap_conf
.ssl_ctx
= eapol
->conf
.ssl_ctx
;
805 eap_conf
.eap_sim_db_priv
= eapol
->conf
.eap_sim_db_priv
;
806 eap_conf
.pac_opaque_encr_key
= eapol
->conf
.pac_opaque_encr_key
;
807 eap_conf
.eap_fast_a_id
= eapol
->conf
.eap_fast_a_id
;
808 eap_conf
.eap_sim_aka_result_ind
= eapol
->conf
.eap_sim_aka_result_ind
;
809 eap_conf
.tnc
= eapol
->conf
.tnc
;
810 sm
->eap
= eap_server_sm_init(sm
, &eapol_cb
, &eap_conf
);
811 if (sm
->eap
== NULL
) {
815 sm
->eap_if
= eap_get_interface(sm
->eap
);
817 eapol_auth_initialize(sm
);
823 void eapol_auth_free(struct eapol_state_machine
*sm
)
828 eloop_cancel_timeout(eapol_port_timers_tick
, NULL
, sm
);
829 eloop_cancel_timeout(eapol_sm_step_cb
, sm
, NULL
);
831 eap_server_sm_deinit(sm
->eap
);
836 static int eapol_sm_sta_entry_alive(struct eapol_authenticator
*eapol
,
839 return eapol
->cb
.sta_entry_alive(eapol
->conf
.hapd
, addr
);
843 static void eapol_sm_step_run(struct eapol_state_machine
*sm
)
845 struct eapol_authenticator
*eapol
= sm
->eapol
;
847 unsigned int prev_auth_pae
, prev_be_auth
, prev_reauth_timer
,
848 prev_auth_key_tx
, prev_key_rx
, prev_ctrl_dir
;
851 os_memcpy(addr
, sm
->addr
, ETH_ALEN
);
854 * Allow EAPOL state machines to run as long as there are state
855 * changes, but exit and return here through event loop if more than
856 * 100 steps is needed as a precaution against infinite loops inside
860 prev_auth_pae
= sm
->auth_pae_state
;
861 prev_be_auth
= sm
->be_auth_state
;
862 prev_reauth_timer
= sm
->reauth_timer_state
;
863 prev_auth_key_tx
= sm
->auth_key_tx_state
;
864 prev_key_rx
= sm
->key_rx_state
;
865 prev_ctrl_dir
= sm
->ctrl_dir_state
;
867 SM_STEP_RUN(AUTH_PAE
);
868 if (sm
->initializing
|| eapol_sm_sta_entry_alive(eapol
, addr
))
869 SM_STEP_RUN(BE_AUTH
);
870 if (sm
->initializing
|| eapol_sm_sta_entry_alive(eapol
, addr
))
871 SM_STEP_RUN(REAUTH_TIMER
);
872 if (sm
->initializing
|| eapol_sm_sta_entry_alive(eapol
, addr
))
873 SM_STEP_RUN(AUTH_KEY_TX
);
874 if (sm
->initializing
|| eapol_sm_sta_entry_alive(eapol
, addr
))
876 if (sm
->initializing
|| eapol_sm_sta_entry_alive(eapol
, addr
))
877 SM_STEP_RUN(CTRL_DIR
);
879 if (prev_auth_pae
!= sm
->auth_pae_state
||
880 prev_be_auth
!= sm
->be_auth_state
||
881 prev_reauth_timer
!= sm
->reauth_timer_state
||
882 prev_auth_key_tx
!= sm
->auth_key_tx_state
||
883 prev_key_rx
!= sm
->key_rx_state
||
884 prev_ctrl_dir
!= sm
->ctrl_dir_state
) {
887 /* Re-run from eloop timeout */
892 if (eapol_sm_sta_entry_alive(eapol
, addr
) && sm
->eap
) {
893 if (eap_server_sm_step(sm
->eap
)) {
896 /* Re-run from eloop timeout */
901 /* TODO: find a better location for this */
902 if (sm
->eap_if
->aaaEapResp
) {
903 sm
->eap_if
->aaaEapResp
= FALSE
;
904 if (sm
->eap_if
->aaaEapRespData
== NULL
) {
905 wpa_printf(MSG_DEBUG
, "EAPOL: aaaEapResp set, "
906 "but no aaaEapRespData available");
909 sm
->eapol
->cb
.aaa_send(
911 wpabuf_head(sm
->eap_if
->aaaEapRespData
),
912 wpabuf_len(sm
->eap_if
->aaaEapRespData
));
916 if (eapol_sm_sta_entry_alive(eapol
, addr
))
917 wpa_auth_sm_notify(sm
->sta
->wpa_sm
);
921 static void eapol_sm_step_cb(void *eloop_ctx
, void *timeout_ctx
)
923 struct eapol_state_machine
*sm
= eloop_ctx
;
924 eapol_sm_step_run(sm
);
928 void eapol_auth_step(struct eapol_state_machine
*sm
)
931 * Run eapol_sm_step_run from a registered timeout to make sure that
932 * other possible timeouts/events are processed and to avoid long
933 * function call chains.
936 eloop_register_timeout(0, 0, eapol_sm_step_cb
, sm
, NULL
);
940 void eapol_auth_initialize(struct eapol_state_machine
*sm
)
942 sm
->initializing
= TRUE
;
943 /* Initialize the state machines by asserting initialize and then
944 * deasserting it after one step */
945 sm
->initialize
= TRUE
;
946 eapol_sm_step_run(sm
);
947 sm
->initialize
= FALSE
;
948 eapol_sm_step_run(sm
);
949 sm
->initializing
= FALSE
;
951 /* Start one second tick for port timers state machine */
952 eloop_cancel_timeout(eapol_port_timers_tick
, NULL
, sm
);
953 eloop_register_timeout(1, 0, eapol_port_timers_tick
, NULL
, sm
);
957 #ifdef HOSTAPD_DUMP_STATE
958 static inline const char * port_type_txt(PortTypes pt
)
961 case ForceUnauthorized
: return "ForceUnauthorized";
962 case ForceAuthorized
: return "ForceAuthorized";
963 case Auto
: return "Auto";
964 default: return "Unknown";
969 static inline const char * port_state_txt(PortState ps
)
972 case Unauthorized
: return "Unauthorized";
973 case Authorized
: return "Authorized";
974 default: return "Unknown";
979 static inline const char * ctrl_dir_txt(ControlledDirection dir
)
982 case Both
: return "Both";
983 case In
: return "In";
984 default: return "Unknown";
989 static inline const char * auth_pae_state_txt(int s
)
992 case AUTH_PAE_INITIALIZE
: return "INITIALIZE";
993 case AUTH_PAE_DISCONNECTED
: return "DISCONNECTED";
994 case AUTH_PAE_CONNECTING
: return "CONNECTING";
995 case AUTH_PAE_AUTHENTICATING
: return "AUTHENTICATING";
996 case AUTH_PAE_AUTHENTICATED
: return "AUTHENTICATED";
997 case AUTH_PAE_ABORTING
: return "ABORTING";
998 case AUTH_PAE_HELD
: return "HELD";
999 case AUTH_PAE_FORCE_AUTH
: return "FORCE_AUTH";
1000 case AUTH_PAE_FORCE_UNAUTH
: return "FORCE_UNAUTH";
1001 case AUTH_PAE_RESTART
: return "RESTART";
1002 default: return "Unknown";
1007 static inline const char * be_auth_state_txt(int s
)
1010 case BE_AUTH_REQUEST
: return "REQUEST";
1011 case BE_AUTH_RESPONSE
: return "RESPONSE";
1012 case BE_AUTH_SUCCESS
: return "SUCCESS";
1013 case BE_AUTH_FAIL
: return "FAIL";
1014 case BE_AUTH_TIMEOUT
: return "TIMEOUT";
1015 case BE_AUTH_IDLE
: return "IDLE";
1016 case BE_AUTH_INITIALIZE
: return "INITIALIZE";
1017 case BE_AUTH_IGNORE
: return "IGNORE";
1018 default: return "Unknown";
1023 static inline const char * reauth_timer_state_txt(int s
)
1026 case REAUTH_TIMER_INITIALIZE
: return "INITIALIZE";
1027 case REAUTH_TIMER_REAUTHENTICATE
: return "REAUTHENTICATE";
1028 default: return "Unknown";
1033 static inline const char * auth_key_tx_state_txt(int s
)
1036 case AUTH_KEY_TX_NO_KEY_TRANSMIT
: return "NO_KEY_TRANSMIT";
1037 case AUTH_KEY_TX_KEY_TRANSMIT
: return "KEY_TRANSMIT";
1038 default: return "Unknown";
1043 static inline const char * key_rx_state_txt(int s
)
1046 case KEY_RX_NO_KEY_RECEIVE
: return "NO_KEY_RECEIVE";
1047 case KEY_RX_KEY_RECEIVE
: return "KEY_RECEIVE";
1048 default: return "Unknown";
1053 static inline const char * ctrl_dir_state_txt(int s
)
1056 case CTRL_DIR_FORCE_BOTH
: return "FORCE_BOTH";
1057 case CTRL_DIR_IN_OR_BOTH
: return "IN_OR_BOTH";
1058 default: return "Unknown";
1063 void eapol_auth_dump_state(FILE *f
, const char *prefix
,
1064 struct eapol_state_machine
*sm
)
1066 fprintf(f
, "%sEAPOL state machine:\n", prefix
);
1067 fprintf(f
, "%s aWhile=%d quietWhile=%d reAuthWhen=%d\n", prefix
,
1068 sm
->aWhile
, sm
->quietWhile
, sm
->reAuthWhen
);
1069 #define _SB(b) ((b) ? "TRUE" : "FALSE")
1071 "%s authAbort=%s authFail=%s authPortStatus=%s authStart=%s\n"
1072 "%s authTimeout=%s authSuccess=%s eapFail=%s eapolEap=%s\n"
1073 "%s eapSuccess=%s eapTimeout=%s initialize=%s "
1075 "%s keyDone=%s keyRun=%s keyTxEnabled=%s portControl=%s\n"
1076 "%s portEnabled=%s portValid=%s reAuthenticate=%s\n",
1077 prefix
, _SB(sm
->authAbort
), _SB(sm
->authFail
),
1078 port_state_txt(sm
->authPortStatus
), _SB(sm
->authStart
),
1079 prefix
, _SB(sm
->authTimeout
), _SB(sm
->authSuccess
),
1080 _SB(sm
->eap_if
->eapFail
), _SB(sm
->eapolEap
),
1081 prefix
, _SB(sm
->eap_if
->eapSuccess
),
1082 _SB(sm
->eap_if
->eapTimeout
),
1083 _SB(sm
->initialize
), _SB(sm
->eap_if
->eapKeyAvailable
),
1084 prefix
, _SB(sm
->keyDone
), _SB(sm
->keyRun
),
1085 _SB(sm
->keyTxEnabled
), port_type_txt(sm
->portControl
),
1086 prefix
, _SB(sm
->eap_if
->portEnabled
), _SB(sm
->portValid
),
1087 _SB(sm
->reAuthenticate
));
1089 fprintf(f
, "%s Authenticator PAE:\n"
1091 "%s eapolLogoff=%s eapolStart=%s eapRestart=%s\n"
1092 "%s portMode=%s reAuthCount=%d\n"
1093 "%s quietPeriod=%d reAuthMax=%d\n"
1094 "%s authEntersConnecting=%d\n"
1095 "%s authEapLogoffsWhileConnecting=%d\n"
1096 "%s authEntersAuthenticating=%d\n"
1097 "%s authAuthSuccessesWhileAuthenticating=%d\n"
1098 "%s authAuthTimeoutsWhileAuthenticating=%d\n"
1099 "%s authAuthFailWhileAuthenticating=%d\n"
1100 "%s authAuthEapStartsWhileAuthenticating=%d\n"
1101 "%s authAuthEapLogoffWhileAuthenticating=%d\n"
1102 "%s authAuthReauthsWhileAuthenticated=%d\n"
1103 "%s authAuthEapStartsWhileAuthenticated=%d\n"
1104 "%s authAuthEapLogoffWhileAuthenticated=%d\n",
1105 prefix
, prefix
, auth_pae_state_txt(sm
->auth_pae_state
), prefix
,
1106 _SB(sm
->eapolLogoff
), _SB(sm
->eapolStart
),
1107 _SB(sm
->eap_if
->eapRestart
),
1108 prefix
, port_type_txt(sm
->portMode
), sm
->reAuthCount
,
1109 prefix
, sm
->quietPeriod
, sm
->reAuthMax
,
1110 prefix
, sm
->authEntersConnecting
,
1111 prefix
, sm
->authEapLogoffsWhileConnecting
,
1112 prefix
, sm
->authEntersAuthenticating
,
1113 prefix
, sm
->authAuthSuccessesWhileAuthenticating
,
1114 prefix
, sm
->authAuthTimeoutsWhileAuthenticating
,
1115 prefix
, sm
->authAuthFailWhileAuthenticating
,
1116 prefix
, sm
->authAuthEapStartsWhileAuthenticating
,
1117 prefix
, sm
->authAuthEapLogoffWhileAuthenticating
,
1118 prefix
, sm
->authAuthReauthsWhileAuthenticated
,
1119 prefix
, sm
->authAuthEapStartsWhileAuthenticated
,
1120 prefix
, sm
->authAuthEapLogoffWhileAuthenticated
);
1122 fprintf(f
, "%s Backend Authentication:\n"
1124 "%s eapNoReq=%s eapReq=%s eapResp=%s\n"
1125 "%s serverTimeout=%d\n"
1126 "%s backendResponses=%d\n"
1127 "%s backendAccessChallenges=%d\n"
1128 "%s backendOtherRequestsToSupplicant=%d\n"
1129 "%s backendAuthSuccesses=%d\n"
1130 "%s backendAuthFails=%d\n",
1132 be_auth_state_txt(sm
->be_auth_state
),
1133 prefix
, _SB(sm
->eap_if
->eapNoReq
), _SB(sm
->eap_if
->eapReq
),
1134 _SB(sm
->eap_if
->eapResp
),
1135 prefix
, sm
->serverTimeout
,
1136 prefix
, sm
->backendResponses
,
1137 prefix
, sm
->backendAccessChallenges
,
1138 prefix
, sm
->backendOtherRequestsToSupplicant
,
1139 prefix
, sm
->backendAuthSuccesses
,
1140 prefix
, sm
->backendAuthFails
);
1142 fprintf(f
, "%s Reauthentication Timer:\n"
1144 "%s reAuthPeriod=%d reAuthEnabled=%s\n", prefix
, prefix
,
1145 reauth_timer_state_txt(sm
->reauth_timer_state
), prefix
,
1146 sm
->reAuthPeriod
, _SB(sm
->reAuthEnabled
));
1148 fprintf(f
, "%s Authenticator Key Transmit:\n"
1149 "%s state=%s\n", prefix
, prefix
,
1150 auth_key_tx_state_txt(sm
->auth_key_tx_state
));
1152 fprintf(f
, "%s Key Receive:\n"
1154 "%s rxKey=%s\n", prefix
, prefix
,
1155 key_rx_state_txt(sm
->key_rx_state
), prefix
, _SB(sm
->rxKey
));
1157 fprintf(f
, "%s Controlled Directions:\n"
1159 "%s adminControlledDirections=%s "
1160 "operControlledDirections=%s\n"
1161 "%s operEdge=%s\n", prefix
, prefix
,
1162 ctrl_dir_state_txt(sm
->ctrl_dir_state
),
1163 prefix
, ctrl_dir_txt(sm
->adminControlledDirections
),
1164 ctrl_dir_txt(sm
->operControlledDirections
),
1165 prefix
, _SB(sm
->operEdge
));
1168 #endif /* HOSTAPD_DUMP_STATE */
1171 static int eapol_sm_get_eap_user(void *ctx
, const u8
*identity
,
1172 size_t identity_len
, int phase2
,
1173 struct eap_user
*user
)
1175 struct eapol_state_machine
*sm
= ctx
;
1176 return sm
->eapol
->cb
.get_eap_user(sm
->hapd
, identity
, identity_len
,
1181 static const char * eapol_sm_get_eap_req_id_text(void *ctx
, size_t *len
)
1183 struct eapol_state_machine
*sm
= ctx
;
1184 *len
= sm
->eapol
->conf
.eap_req_id_text_len
;
1185 return sm
->eapol
->conf
.eap_req_id_text
;
1189 static struct eapol_callbacks eapol_cb
=
1191 .get_eap_user
= eapol_sm_get_eap_user
,
1192 .get_eap_req_id_text
= eapol_sm_get_eap_req_id_text
,
1196 int eapol_auth_eap_pending_cb(struct eapol_state_machine
*sm
, void *ctx
)
1198 if (sm
== NULL
|| ctx
!= sm
->eap
)
1201 eap_sm_pending_cb(sm
->eap
);
1202 eapol_auth_step(sm
);
1208 static int eapol_auth_conf_clone(struct eapol_auth_config
*dst
,
1209 struct eapol_auth_config
*src
)
1211 dst
->hapd
= src
->hapd
;
1212 dst
->eap_reauth_period
= src
->eap_reauth_period
;
1213 dst
->wpa
= src
->wpa
;
1214 dst
->individual_wep_key_len
= src
->individual_wep_key_len
;
1215 dst
->eap_server
= src
->eap_server
;
1216 dst
->ssl_ctx
= src
->ssl_ctx
;
1217 dst
->eap_sim_db_priv
= src
->eap_sim_db_priv
;
1218 os_free(dst
->eap_req_id_text
);
1219 if (src
->eap_req_id_text
) {
1220 dst
->eap_req_id_text
= os_malloc(src
->eap_req_id_text_len
);
1221 if (dst
->eap_req_id_text
== NULL
)
1223 os_memcpy(dst
->eap_req_id_text
, src
->eap_req_id_text
,
1224 src
->eap_req_id_text_len
);
1225 dst
->eap_req_id_text_len
= src
->eap_req_id_text_len
;
1227 dst
->eap_req_id_text
= NULL
;
1228 dst
->eap_req_id_text_len
= 0;
1230 if (src
->pac_opaque_encr_key
) {
1231 dst
->pac_opaque_encr_key
= os_malloc(16);
1232 os_memcpy(dst
->pac_opaque_encr_key
, src
->pac_opaque_encr_key
,
1235 dst
->pac_opaque_encr_key
= NULL
;
1236 if (src
->eap_fast_a_id
)
1237 dst
->eap_fast_a_id
= os_strdup(src
->eap_fast_a_id
);
1239 dst
->eap_fast_a_id
= NULL
;
1240 dst
->eap_sim_aka_result_ind
= src
->eap_sim_aka_result_ind
;
1241 dst
->tnc
= src
->tnc
;
1246 static void eapol_auth_conf_free(struct eapol_auth_config
*conf
)
1248 os_free(conf
->eap_req_id_text
);
1249 conf
->eap_req_id_text
= NULL
;
1250 os_free(conf
->pac_opaque_encr_key
);
1251 conf
->pac_opaque_encr_key
= NULL
;
1252 os_free(conf
->eap_fast_a_id
);
1253 conf
->eap_fast_a_id
= NULL
;
1257 struct eapol_authenticator
* eapol_auth_init(struct eapol_auth_config
*conf
,
1258 struct eapol_auth_cb
*cb
)
1260 struct eapol_authenticator
*eapol
;
1262 eapol
= os_zalloc(sizeof(*eapol
));
1266 if (eapol_auth_conf_clone(&eapol
->conf
, conf
) < 0) {
1271 eapol
->cb
.eapol_send
= cb
->eapol_send
;
1272 eapol
->cb
.aaa_send
= cb
->aaa_send
;
1273 eapol
->cb
.finished
= cb
->finished
;
1274 eapol
->cb
.get_eap_user
= cb
->get_eap_user
;
1275 eapol
->cb
.sta_entry_alive
= cb
->sta_entry_alive
;
1276 eapol
->cb
.logger
= cb
->logger
;
1277 eapol
->cb
.set_port_authorized
= cb
->set_port_authorized
;
1278 eapol
->cb
.abort_auth
= cb
->abort_auth
;
1279 eapol
->cb
.tx_key
= cb
->tx_key
;
1285 void eapol_auth_deinit(struct eapol_authenticator
*eapol
)
1290 eapol_auth_conf_free(&eapol
->conf
);