2 * hostapd / IEEE 802.1X Authenticator - EAPOL state machine
3 * Copyright (c) 2002-2005, 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"
25 #include "state_machine.h"
27 #define STATE_MACHINE_DATA struct eapol_state_machine
28 #define STATE_MACHINE_DEBUG_PREFIX "IEEE 802.1X"
29 #define STATE_MACHINE_ADDR sm->addr
31 static struct eapol_callbacks eapol_cb
;
33 /* EAPOL state machines are described in IEEE Std 802.1X-REV-d11, Chap. 8.2 */
35 #define setPortAuthorized() \
36 ieee802_1x_set_sta_authorized(sm->hapd, sm->sta, 1)
37 #define setPortUnauthorized() \
38 ieee802_1x_set_sta_authorized(sm->hapd, sm->sta, 0)
41 #define txCannedFail() ieee802_1x_tx_canned_eap(sm->hapd, sm->sta, 0)
42 #define txCannedSuccess() ieee802_1x_tx_canned_eap(sm->hapd, sm->sta, 1)
43 #define txReq() ieee802_1x_tx_req(sm->hapd, sm->sta)
44 #define sendRespToServer() ieee802_1x_send_resp_to_server(sm->hapd, sm->sta)
45 #define abortAuth() ieee802_1x_abort_auth(sm->hapd, sm->sta)
46 #define txKey() ieee802_1x_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 /* Port Timers state machine - implemented as a function that will be called
55 * once a second as a registered event loop timeout */
57 static void eapol_port_timers_tick(void *eloop_ctx
, void *timeout_ctx
)
59 struct eapol_state_machine
*state
= timeout_ctx
;
61 if (state
->aWhile
> 0) {
63 if (state
->aWhile
== 0) {
64 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
66 MAC2STR(state
->addr
));
70 if (state
->quietWhile
> 0) {
72 if (state
->quietWhile
== 0) {
73 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
74 " - quietWhile --> 0",
75 MAC2STR(state
->addr
));
79 if (state
->reAuthWhen
> 0) {
81 if (state
->reAuthWhen
== 0) {
82 wpa_printf(MSG_DEBUG
, "IEEE 802.1X: " MACSTR
83 " - reAuthWhen --> 0",
84 MAC2STR(state
->addr
));
88 eapol_sm_step_run(state
);
90 eloop_register_timeout(1, 0, eapol_port_timers_tick
, eloop_ctx
, state
);
95 /* Authenticator PAE state machine */
97 SM_STATE(AUTH_PAE
, INITIALIZE
)
99 SM_ENTRY_MA(AUTH_PAE
, INITIALIZE
, auth_pae
);
106 SM_STATE(AUTH_PAE
, DISCONNECTED
)
108 int from_initialize
= sm
->auth_pae_state
== AUTH_PAE_INITIALIZE
;
110 if (sm
->eapolLogoff
) {
111 if (sm
->auth_pae_state
== AUTH_PAE_CONNECTING
)
112 sm
->authEapLogoffsWhileConnecting
++;
113 else if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATED
)
114 sm
->authAuthEapLogoffWhileAuthenticated
++;
117 SM_ENTRY_MA(AUTH_PAE
, DISCONNECTED
, auth_pae
);
119 sm
->authPortStatus
= Unauthorized
;
120 setPortUnauthorized();
122 sm
->eapolLogoff
= FALSE
;
123 if (!from_initialize
) {
124 if (sm
->flags
& EAPOL_SM_PREAUTH
)
125 rsn_preauth_finished(sm
->hapd
, sm
->sta
, 0);
127 ieee802_1x_finished(sm
->hapd
, sm
->sta
, 0);
132 SM_STATE(AUTH_PAE
, RESTART
)
134 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATED
) {
135 if (sm
->reAuthenticate
)
136 sm
->authAuthReauthsWhileAuthenticated
++;
138 sm
->authAuthEapStartsWhileAuthenticated
++;
140 sm
->authAuthEapLogoffWhileAuthenticated
++;
143 SM_ENTRY_MA(AUTH_PAE
, RESTART
, auth_pae
);
145 sm
->eapRestart
= TRUE
;
146 ieee802_1x_request_identity(sm
->hapd
, sm
->sta
);
150 SM_STATE(AUTH_PAE
, CONNECTING
)
152 if (sm
->auth_pae_state
!= AUTH_PAE_CONNECTING
)
153 sm
->authEntersConnecting
++;
155 SM_ENTRY_MA(AUTH_PAE
, CONNECTING
, auth_pae
);
157 sm
->reAuthenticate
= FALSE
;
162 SM_STATE(AUTH_PAE
, HELD
)
164 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
&& sm
->authFail
)
165 sm
->authAuthFailWhileAuthenticating
++;
167 SM_ENTRY_MA(AUTH_PAE
, HELD
, auth_pae
);
169 sm
->authPortStatus
= Unauthorized
;
170 setPortUnauthorized();
171 sm
->quietWhile
= sm
->quietPeriod
;
172 sm
->eapolLogoff
= FALSE
;
174 hostapd_logger(sm
->hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
175 HOSTAPD_LEVEL_WARNING
, "authentication failed - "
177 sm
->eap_type_authsrv
,
178 eap_type_text(sm
->eap_type_authsrv
));
179 if (sm
->eap_type_authsrv
!= sm
->eap_type_supp
) {
180 hostapd_logger(sm
->hapd
, sm
->addr
,
181 HOSTAPD_MODULE_IEEE8021X
, HOSTAPD_LEVEL_INFO
,
182 "Supplicant used different EAP type: %d (%s)",
184 eap_type_text(sm
->eap_type_supp
));
186 if (sm
->flags
& EAPOL_SM_PREAUTH
)
187 rsn_preauth_finished(sm
->hapd
, sm
->sta
, 0);
189 ieee802_1x_finished(sm
->hapd
, sm
->sta
, 0);
193 SM_STATE(AUTH_PAE
, AUTHENTICATED
)
197 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
&& sm
->authSuccess
)
198 sm
->authAuthSuccessesWhileAuthenticating
++;
200 SM_ENTRY_MA(AUTH_PAE
, AUTHENTICATED
, auth_pae
);
202 sm
->authPortStatus
= Authorized
;
205 if (sm
->flags
& EAPOL_SM_PREAUTH
)
206 extra
= " (pre-authentication)";
207 else if (wpa_auth_sta_get_pmksa(sm
->sta
->wpa_sm
))
208 extra
= " (PMKSA cache)";
209 hostapd_logger(sm
->hapd
, sm
->addr
, HOSTAPD_MODULE_IEEE8021X
,
210 HOSTAPD_LEVEL_INFO
, "authenticated - EAP type: %d (%s)"
211 "%s", sm
->eap_type_authsrv
,
212 eap_type_text(sm
->eap_type_authsrv
), extra
);
213 if (sm
->flags
& EAPOL_SM_PREAUTH
)
214 rsn_preauth_finished(sm
->hapd
, sm
->sta
, 1);
216 ieee802_1x_finished(sm
->hapd
, sm
->sta
, 1);
220 SM_STATE(AUTH_PAE
, AUTHENTICATING
)
222 if (sm
->auth_pae_state
== AUTH_PAE_CONNECTING
&& sm
->rx_identity
) {
223 sm
->authEntersAuthenticating
++;
224 sm
->rx_identity
= FALSE
;
227 SM_ENTRY_MA(AUTH_PAE
, AUTHENTICATING
, auth_pae
);
229 sm
->eapolStart
= FALSE
;
230 sm
->authSuccess
= FALSE
;
231 sm
->authFail
= FALSE
;
232 sm
->authTimeout
= FALSE
;
233 sm
->authStart
= TRUE
;
239 SM_STATE(AUTH_PAE
, ABORTING
)
241 if (sm
->auth_pae_state
== AUTH_PAE_AUTHENTICATING
) {
243 sm
->authAuthTimeoutsWhileAuthenticating
++;
245 sm
->authAuthEapStartsWhileAuthenticating
++;
247 sm
->authAuthEapLogoffWhileAuthenticating
++;
250 SM_ENTRY_MA(AUTH_PAE
, ABORTING
, auth_pae
);
252 sm
->authAbort
= TRUE
;
258 SM_STATE(AUTH_PAE
, FORCE_AUTH
)
260 SM_ENTRY_MA(AUTH_PAE
, FORCE_AUTH
, auth_pae
);
262 sm
->authPortStatus
= Authorized
;
264 sm
->portMode
= ForceAuthorized
;
265 sm
->eapolStart
= FALSE
;
270 SM_STATE(AUTH_PAE
, FORCE_UNAUTH
)
272 SM_ENTRY_MA(AUTH_PAE
, FORCE_UNAUTH
, auth_pae
);
274 sm
->authPortStatus
= Unauthorized
;
275 setPortUnauthorized();
276 sm
->portMode
= ForceUnauthorized
;
277 sm
->eapolStart
= FALSE
;
284 if ((sm
->portControl
== Auto
&& sm
->portMode
!= sm
->portControl
) ||
285 sm
->initialize
|| !sm
->portEnabled
)
286 SM_ENTER(AUTH_PAE
, INITIALIZE
);
287 else if (sm
->portControl
== ForceAuthorized
&&
288 sm
->portMode
!= sm
->portControl
&&
289 !(sm
->initialize
|| !sm
->portEnabled
))
290 SM_ENTER(AUTH_PAE
, FORCE_AUTH
);
291 else if (sm
->portControl
== ForceUnauthorized
&&
292 sm
->portMode
!= sm
->portControl
&&
293 !(sm
->initialize
|| !sm
->portEnabled
))
294 SM_ENTER(AUTH_PAE
, FORCE_UNAUTH
);
296 switch (sm
->auth_pae_state
) {
297 case AUTH_PAE_INITIALIZE
:
298 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
300 case AUTH_PAE_DISCONNECTED
:
301 SM_ENTER(AUTH_PAE
, RESTART
);
303 case AUTH_PAE_RESTART
:
305 SM_ENTER(AUTH_PAE
, CONNECTING
);
308 if (sm
->quietWhile
== 0)
309 SM_ENTER(AUTH_PAE
, RESTART
);
311 case AUTH_PAE_CONNECTING
:
312 if (sm
->eapolLogoff
|| sm
->reAuthCount
> sm
->reAuthMax
)
313 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
314 else if ((sm
->eapReq
&&
315 sm
->reAuthCount
<= sm
->reAuthMax
) ||
316 sm
->eapSuccess
|| sm
->eapFail
)
317 SM_ENTER(AUTH_PAE
, AUTHENTICATING
);
319 case AUTH_PAE_AUTHENTICATED
:
320 if (sm
->eapolStart
|| sm
->reAuthenticate
)
321 SM_ENTER(AUTH_PAE
, RESTART
);
322 else if (sm
->eapolLogoff
|| !sm
->portValid
)
323 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
325 case AUTH_PAE_AUTHENTICATING
:
326 if (sm
->authSuccess
&& sm
->portValid
)
327 SM_ENTER(AUTH_PAE
, AUTHENTICATED
);
328 else if (sm
->authFail
||
329 (sm
->keyDone
&& !sm
->portValid
))
330 SM_ENTER(AUTH_PAE
, HELD
);
331 else if (sm
->eapolStart
|| sm
->eapolLogoff
||
333 SM_ENTER(AUTH_PAE
, ABORTING
);
335 case AUTH_PAE_ABORTING
:
336 if (sm
->eapolLogoff
&& !sm
->authAbort
)
337 SM_ENTER(AUTH_PAE
, DISCONNECTED
);
338 else if (!sm
->eapolLogoff
&& !sm
->authAbort
)
339 SM_ENTER(AUTH_PAE
, RESTART
);
341 case AUTH_PAE_FORCE_AUTH
:
343 SM_ENTER(AUTH_PAE
, FORCE_AUTH
);
345 case AUTH_PAE_FORCE_UNAUTH
:
347 SM_ENTER(AUTH_PAE
, FORCE_UNAUTH
);
355 /* Backend Authentication state machine */
357 SM_STATE(BE_AUTH
, INITIALIZE
)
359 SM_ENTRY_MA(BE_AUTH
, INITIALIZE
, be_auth
);
362 sm
->eapNoReq
= FALSE
;
363 sm
->authAbort
= FALSE
;
367 SM_STATE(BE_AUTH
, REQUEST
)
369 SM_ENTRY_MA(BE_AUTH
, REQUEST
, be_auth
);
373 sm
->backendOtherRequestsToSupplicant
++;
376 * Clearing eapolEap here is not specified in IEEE Std 802.1X-2004, but
377 * it looks like this would be logical thing to do there since the old
378 * EAP response would not be valid anymore after the new EAP request
381 * A race condition has been reported, in which hostapd ended up
382 * sending out EAP-Response/Identity as a response to the first
383 * EAP-Request from the main EAP method. This can be avoided by
384 * clearing eapolEap here.
386 sm
->eapolEap
= FALSE
;
390 SM_STATE(BE_AUTH
, RESPONSE
)
392 SM_ENTRY_MA(BE_AUTH
, RESPONSE
, be_auth
);
394 sm
->authTimeout
= FALSE
;
395 sm
->eapolEap
= FALSE
;
396 sm
->eapNoReq
= FALSE
;
397 sm
->aWhile
= sm
->serverTimeout
;
400 sm
->backendResponses
++;
404 SM_STATE(BE_AUTH
, SUCCESS
)
406 SM_ENTRY_MA(BE_AUTH
, SUCCESS
, be_auth
);
409 sm
->authSuccess
= TRUE
;
414 SM_STATE(BE_AUTH
, FAIL
)
416 SM_ENTRY_MA(BE_AUTH
, FAIL
, be_auth
);
418 /* Note: IEEE 802.1X-REV-d11 has unconditional txReq() here.
419 * txCannelFail() is used as a workaround for the case where
420 * authentication server does not include EAP-Message with
422 if (sm
->last_eap_radius
== NULL
)
430 SM_STATE(BE_AUTH
, TIMEOUT
)
432 SM_ENTRY_MA(BE_AUTH
, TIMEOUT
, be_auth
);
434 sm
->authTimeout
= TRUE
;
438 SM_STATE(BE_AUTH
, IDLE
)
440 SM_ENTRY_MA(BE_AUTH
, IDLE
, be_auth
);
442 sm
->authStart
= FALSE
;
446 SM_STATE(BE_AUTH
, IGNORE
)
448 SM_ENTRY_MA(BE_AUTH
, IGNORE
, be_auth
);
450 sm
->eapNoReq
= FALSE
;
456 if (sm
->portControl
!= Auto
|| sm
->initialize
|| sm
->authAbort
) {
457 SM_ENTER(BE_AUTH
, INITIALIZE
);
461 switch (sm
->be_auth_state
) {
462 case BE_AUTH_INITIALIZE
:
463 SM_ENTER(BE_AUTH
, IDLE
);
465 case BE_AUTH_REQUEST
:
467 SM_ENTER(BE_AUTH
, RESPONSE
);
469 SM_ENTER(BE_AUTH
, REQUEST
);
470 else if (sm
->eapTimeout
)
471 SM_ENTER(BE_AUTH
, TIMEOUT
);
473 case BE_AUTH_RESPONSE
:
475 SM_ENTER(BE_AUTH
, IGNORE
);
477 sm
->backendAccessChallenges
++;
478 SM_ENTER(BE_AUTH
, REQUEST
);
479 } else if (sm
->aWhile
== 0)
480 SM_ENTER(BE_AUTH
, TIMEOUT
);
481 else if (sm
->eapFail
) {
482 sm
->backendAuthFails
++;
483 SM_ENTER(BE_AUTH
, FAIL
);
484 } else if (sm
->eapSuccess
) {
485 sm
->backendAuthSuccesses
++;
486 SM_ENTER(BE_AUTH
, SUCCESS
);
489 case BE_AUTH_SUCCESS
:
490 SM_ENTER(BE_AUTH
, IDLE
);
493 SM_ENTER(BE_AUTH
, IDLE
);
495 case BE_AUTH_TIMEOUT
:
496 SM_ENTER(BE_AUTH
, IDLE
);
499 if (sm
->eapFail
&& sm
->authStart
)
500 SM_ENTER(BE_AUTH
, FAIL
);
501 else if (sm
->eapReq
&& sm
->authStart
)
502 SM_ENTER(BE_AUTH
, REQUEST
);
503 else if (sm
->eapSuccess
&& sm
->authStart
)
504 SM_ENTER(BE_AUTH
, SUCCESS
);
508 SM_ENTER(BE_AUTH
, RESPONSE
);
510 SM_ENTER(BE_AUTH
, REQUEST
);
511 else if (sm
->eapTimeout
)
512 SM_ENTER(BE_AUTH
, TIMEOUT
);
519 /* Reauthentication Timer state machine */
521 SM_STATE(REAUTH_TIMER
, INITIALIZE
)
523 SM_ENTRY_MA(REAUTH_TIMER
, INITIALIZE
, reauth_timer
);
525 sm
->reAuthWhen
= sm
->reAuthPeriod
;
529 SM_STATE(REAUTH_TIMER
, REAUTHENTICATE
)
531 SM_ENTRY_MA(REAUTH_TIMER
, REAUTHENTICATE
, reauth_timer
);
533 sm
->reAuthenticate
= TRUE
;
534 wpa_auth_sm_event(sm
->sta
->wpa_sm
, WPA_REAUTH_EAPOL
);
538 SM_STEP(REAUTH_TIMER
)
540 if (sm
->portControl
!= Auto
|| sm
->initialize
||
541 sm
->authPortStatus
== Unauthorized
|| !sm
->reAuthEnabled
) {
542 SM_ENTER(REAUTH_TIMER
, INITIALIZE
);
546 switch (sm
->reauth_timer_state
) {
547 case REAUTH_TIMER_INITIALIZE
:
548 if (sm
->reAuthWhen
== 0)
549 SM_ENTER(REAUTH_TIMER
, REAUTHENTICATE
);
551 case REAUTH_TIMER_REAUTHENTICATE
:
552 SM_ENTER(REAUTH_TIMER
, INITIALIZE
);
559 /* Authenticator Key Transmit state machine */
561 SM_STATE(AUTH_KEY_TX
, NO_KEY_TRANSMIT
)
563 SM_ENTRY_MA(AUTH_KEY_TX
, NO_KEY_TRANSMIT
, auth_key_tx
);
567 SM_STATE(AUTH_KEY_TX
, KEY_TRANSMIT
)
569 SM_ENTRY_MA(AUTH_KEY_TX
, KEY_TRANSMIT
, auth_key_tx
);
572 sm
->keyAvailable
= FALSE
;
579 if (sm
->initialize
|| sm
->portControl
!= Auto
) {
580 SM_ENTER(AUTH_KEY_TX
, NO_KEY_TRANSMIT
);
584 switch (sm
->auth_key_tx_state
) {
585 case AUTH_KEY_TX_NO_KEY_TRANSMIT
:
586 if (sm
->keyTxEnabled
&& sm
->keyAvailable
&& sm
->keyRun
&&
587 !wpa_auth_sta_wpa_version(sm
->sta
->wpa_sm
))
588 SM_ENTER(AUTH_KEY_TX
, KEY_TRANSMIT
);
590 case AUTH_KEY_TX_KEY_TRANSMIT
:
591 if (!sm
->keyTxEnabled
|| !sm
->keyRun
)
592 SM_ENTER(AUTH_KEY_TX
, NO_KEY_TRANSMIT
);
593 else if (sm
->keyAvailable
)
594 SM_ENTER(AUTH_KEY_TX
, KEY_TRANSMIT
);
601 /* Key Receive state machine */
603 SM_STATE(KEY_RX
, NO_KEY_RECEIVE
)
605 SM_ENTRY_MA(KEY_RX
, NO_KEY_RECEIVE
, key_rx
);
609 SM_STATE(KEY_RX
, KEY_RECEIVE
)
611 SM_ENTRY_MA(KEY_RX
, KEY_RECEIVE
, key_rx
);
620 if (sm
->initialize
|| !sm
->portEnabled
) {
621 SM_ENTER(KEY_RX
, NO_KEY_RECEIVE
);
625 switch (sm
->key_rx_state
) {
626 case KEY_RX_NO_KEY_RECEIVE
:
628 SM_ENTER(KEY_RX
, KEY_RECEIVE
);
630 case KEY_RX_KEY_RECEIVE
:
632 SM_ENTER(KEY_RX
, KEY_RECEIVE
);
639 /* Controlled Directions state machine */
641 SM_STATE(CTRL_DIR
, FORCE_BOTH
)
643 SM_ENTRY_MA(CTRL_DIR
, FORCE_BOTH
, ctrl_dir
);
644 sm
->operControlledDirections
= Both
;
648 SM_STATE(CTRL_DIR
, IN_OR_BOTH
)
650 SM_ENTRY_MA(CTRL_DIR
, IN_OR_BOTH
, ctrl_dir
);
651 sm
->operControlledDirections
= sm
->adminControlledDirections
;
657 if (sm
->initialize
) {
658 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
662 switch (sm
->ctrl_dir_state
) {
663 case CTRL_DIR_FORCE_BOTH
:
664 if (sm
->portEnabled
&& sm
->operEdge
)
665 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
667 case CTRL_DIR_IN_OR_BOTH
:
668 if (sm
->operControlledDirections
!=
669 sm
->adminControlledDirections
)
670 SM_ENTER(CTRL_DIR
, IN_OR_BOTH
);
671 if (!sm
->portEnabled
|| !sm
->operEdge
)
672 SM_ENTER(CTRL_DIR
, FORCE_BOTH
);
679 struct eapol_state_machine
*
680 eapol_sm_alloc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
682 struct eapol_state_machine
*sm
;
684 sm
= wpa_zalloc(sizeof(*sm
));
686 printf("IEEE 802.1X port state allocation failed\n");
689 sm
->radius_identifier
= -1;
690 memcpy(sm
->addr
, sta
->addr
, ETH_ALEN
);
691 if (sta
->flags
& WLAN_STA_PREAUTH
)
692 sm
->flags
|= EAPOL_SM_PREAUTH
;
697 /* Set default values for state machine constants */
698 sm
->auth_pae_state
= AUTH_PAE_INITIALIZE
;
699 sm
->quietPeriod
= AUTH_PAE_DEFAULT_quietPeriod
;
700 sm
->reAuthMax
= AUTH_PAE_DEFAULT_reAuthMax
;
702 sm
->be_auth_state
= BE_AUTH_INITIALIZE
;
703 sm
->serverTimeout
= BE_AUTH_DEFAULT_serverTimeout
;
705 sm
->reauth_timer_state
= REAUTH_TIMER_INITIALIZE
;
706 sm
->reAuthPeriod
= hapd
->conf
->eap_reauth_period
;
707 sm
->reAuthEnabled
= hapd
->conf
->eap_reauth_period
> 0 ? TRUE
: FALSE
;
709 sm
->auth_key_tx_state
= AUTH_KEY_TX_NO_KEY_TRANSMIT
;
711 sm
->key_rx_state
= KEY_RX_NO_KEY_RECEIVE
;
713 sm
->ctrl_dir_state
= CTRL_DIR_IN_OR_BOTH
;
715 sm
->portEnabled
= FALSE
;
716 sm
->portControl
= Auto
;
718 sm
->keyAvailable
= FALSE
;
719 if (!hapd
->conf
->wpa
&&
720 (hapd
->default_wep_key
|| hapd
->conf
->individual_wep_key_len
> 0))
721 sm
->keyTxEnabled
= TRUE
;
723 sm
->keyTxEnabled
= FALSE
;
725 sm
->portValid
= FALSE
;
727 sm
->portValid
= TRUE
;
729 if (hapd
->conf
->eap_server
) {
730 struct eap_config eap_conf
;
731 memset(&eap_conf
, 0, sizeof(eap_conf
));
732 eap_conf
.ssl_ctx
= hapd
->ssl_ctx
;
733 eap_conf
.eap_sim_db_priv
= hapd
->eap_sim_db_priv
;
734 sm
->eap
= eap_sm_init(sm
, &eapol_cb
, &eap_conf
);
735 if (sm
->eap
== NULL
) {
741 eapol_sm_initialize(sm
);
747 void eapol_sm_free(struct eapol_state_machine
*sm
)
752 eloop_cancel_timeout(eapol_port_timers_tick
, sm
->hapd
, sm
);
753 eloop_cancel_timeout(eapol_sm_step_cb
, sm
, NULL
);
755 eap_sm_deinit(sm
->eap
);
760 static int eapol_sm_sta_entry_alive(struct hostapd_data
*hapd
, u8
*addr
)
762 struct sta_info
*sta
;
763 sta
= ap_get_sta(hapd
, addr
);
764 if (sta
== NULL
|| sta
->eapol_sm
== NULL
)
770 static void eapol_sm_step_run(struct eapol_state_machine
*sm
)
772 struct hostapd_data
*hapd
= sm
->hapd
;
774 unsigned int prev_auth_pae
, prev_be_auth
, prev_reauth_timer
,
775 prev_auth_key_tx
, prev_key_rx
, prev_ctrl_dir
;
778 memcpy(addr
, sm
->sta
->addr
, ETH_ALEN
);
781 * Allow EAPOL state machines to run as long as there are state
782 * changes, but exit and return here through event loop if more than
783 * 100 steps is needed as a precaution against infinite loops inside
787 prev_auth_pae
= sm
->auth_pae_state
;
788 prev_be_auth
= sm
->be_auth_state
;
789 prev_reauth_timer
= sm
->reauth_timer_state
;
790 prev_auth_key_tx
= sm
->auth_key_tx_state
;
791 prev_key_rx
= sm
->key_rx_state
;
792 prev_ctrl_dir
= sm
->ctrl_dir_state
;
794 SM_STEP_RUN(AUTH_PAE
);
795 if (sm
->initializing
|| eapol_sm_sta_entry_alive(hapd
, addr
))
796 SM_STEP_RUN(BE_AUTH
);
797 if (sm
->initializing
|| eapol_sm_sta_entry_alive(hapd
, addr
))
798 SM_STEP_RUN(REAUTH_TIMER
);
799 if (sm
->initializing
|| eapol_sm_sta_entry_alive(hapd
, addr
))
800 SM_STEP_RUN(AUTH_KEY_TX
);
801 if (sm
->initializing
|| eapol_sm_sta_entry_alive(hapd
, addr
))
803 if (sm
->initializing
|| eapol_sm_sta_entry_alive(hapd
, addr
))
804 SM_STEP_RUN(CTRL_DIR
);
806 if (prev_auth_pae
!= sm
->auth_pae_state
||
807 prev_be_auth
!= sm
->be_auth_state
||
808 prev_reauth_timer
!= sm
->reauth_timer_state
||
809 prev_auth_key_tx
!= sm
->auth_key_tx_state
||
810 prev_key_rx
!= sm
->key_rx_state
||
811 prev_ctrl_dir
!= sm
->ctrl_dir_state
) {
814 /* Re-run from eloop timeout */
819 if (eapol_sm_sta_entry_alive(hapd
, addr
) && sm
->eap
) {
820 if (eap_sm_step(sm
->eap
)) {
823 /* Re-run from eloop timeout */
829 if (eapol_sm_sta_entry_alive(hapd
, addr
))
830 wpa_auth_sm_notify(sm
->sta
->wpa_sm
);
834 static void eapol_sm_step_cb(void *eloop_ctx
, void *timeout_ctx
)
836 struct eapol_state_machine
*sm
= eloop_ctx
;
837 eapol_sm_step_run(sm
);
841 void eapol_sm_step(struct eapol_state_machine
*sm
)
844 * Run eapol_sm_step_run from a registered timeout to make sure that
845 * other possible timeouts/events are processed and to avoid long
846 * function call chains.
849 eloop_register_timeout(0, 0, eapol_sm_step_cb
, sm
, NULL
);
853 void eapol_sm_initialize(struct eapol_state_machine
*sm
)
855 sm
->initializing
= TRUE
;
856 /* Initialize the state machines by asserting initialize and then
857 * deasserting it after one step */
858 sm
->initialize
= TRUE
;
859 eapol_sm_step_run(sm
);
860 sm
->initialize
= FALSE
;
861 eapol_sm_step_run(sm
);
862 sm
->initializing
= FALSE
;
864 /* Start one second tick for port timers state machine */
865 eloop_cancel_timeout(eapol_port_timers_tick
, sm
->hapd
, sm
);
866 eloop_register_timeout(1, 0, eapol_port_timers_tick
, sm
->hapd
, sm
);
870 #ifdef HOSTAPD_DUMP_STATE
871 static inline const char * port_type_txt(PortTypes pt
)
874 case ForceUnauthorized
: return "ForceUnauthorized";
875 case ForceAuthorized
: return "ForceAuthorized";
876 case Auto
: return "Auto";
877 default: return "Unknown";
882 static inline const char * port_state_txt(PortState ps
)
885 case Unauthorized
: return "Unauthorized";
886 case Authorized
: return "Authorized";
887 default: return "Unknown";
892 static inline const char * ctrl_dir_txt(ControlledDirection dir
)
895 case Both
: return "Both";
896 case In
: return "In";
897 default: return "Unknown";
902 static inline const char * auth_pae_state_txt(int s
)
905 case AUTH_PAE_INITIALIZE
: return "INITIALIZE";
906 case AUTH_PAE_DISCONNECTED
: return "DISCONNECTED";
907 case AUTH_PAE_CONNECTING
: return "CONNECTING";
908 case AUTH_PAE_AUTHENTICATING
: return "AUTHENTICATING";
909 case AUTH_PAE_AUTHENTICATED
: return "AUTHENTICATED";
910 case AUTH_PAE_ABORTING
: return "ABORTING";
911 case AUTH_PAE_HELD
: return "HELD";
912 case AUTH_PAE_FORCE_AUTH
: return "FORCE_AUTH";
913 case AUTH_PAE_FORCE_UNAUTH
: return "FORCE_UNAUTH";
914 case AUTH_PAE_RESTART
: return "RESTART";
915 default: return "Unknown";
920 static inline const char * be_auth_state_txt(int s
)
923 case BE_AUTH_REQUEST
: return "REQUEST";
924 case BE_AUTH_RESPONSE
: return "RESPONSE";
925 case BE_AUTH_SUCCESS
: return "SUCCESS";
926 case BE_AUTH_FAIL
: return "FAIL";
927 case BE_AUTH_TIMEOUT
: return "TIMEOUT";
928 case BE_AUTH_IDLE
: return "IDLE";
929 case BE_AUTH_INITIALIZE
: return "INITIALIZE";
930 case BE_AUTH_IGNORE
: return "IGNORE";
931 default: return "Unknown";
936 static inline const char * reauth_timer_state_txt(int s
)
939 case REAUTH_TIMER_INITIALIZE
: return "INITIALIZE";
940 case REAUTH_TIMER_REAUTHENTICATE
: return "REAUTHENTICATE";
941 default: return "Unknown";
946 static inline const char * auth_key_tx_state_txt(int s
)
949 case AUTH_KEY_TX_NO_KEY_TRANSMIT
: return "NO_KEY_TRANSMIT";
950 case AUTH_KEY_TX_KEY_TRANSMIT
: return "KEY_TRANSMIT";
951 default: return "Unknown";
956 static inline const char * key_rx_state_txt(int s
)
959 case KEY_RX_NO_KEY_RECEIVE
: return "NO_KEY_RECEIVE";
960 case KEY_RX_KEY_RECEIVE
: return "KEY_RECEIVE";
961 default: return "Unknown";
966 static inline const char * ctrl_dir_state_txt(int s
)
969 case CTRL_DIR_FORCE_BOTH
: return "FORCE_BOTH";
970 case CTRL_DIR_IN_OR_BOTH
: return "IN_OR_BOTH";
971 default: return "Unknown";
976 void eapol_sm_dump_state(FILE *f
, const char *prefix
,
977 struct eapol_state_machine
*sm
)
979 fprintf(f
, "%sEAPOL state machine:\n", prefix
);
980 fprintf(f
, "%s aWhile=%d quietWhile=%d reAuthWhen=%d\n", prefix
,
981 sm
->aWhile
, sm
->quietWhile
, sm
->reAuthWhen
);
982 #define _SB(b) ((b) ? "TRUE" : "FALSE")
984 "%s authAbort=%s authFail=%s authPortStatus=%s authStart=%s\n"
985 "%s authTimeout=%s authSuccess=%s eapFail=%s eapolEap=%s\n"
986 "%s eapSuccess=%s eapTimeout=%s initialize=%s "
988 "%s keyDone=%s keyRun=%s keyTxEnabled=%s portControl=%s\n"
989 "%s portEnabled=%s portValid=%s reAuthenticate=%s\n",
990 prefix
, _SB(sm
->authAbort
), _SB(sm
->authFail
),
991 port_state_txt(sm
->authPortStatus
), _SB(sm
->authStart
),
992 prefix
, _SB(sm
->authTimeout
), _SB(sm
->authSuccess
),
993 _SB(sm
->eapFail
), _SB(sm
->eapolEap
),
994 prefix
, _SB(sm
->eapSuccess
), _SB(sm
->eapTimeout
),
995 _SB(sm
->initialize
), _SB(sm
->keyAvailable
),
996 prefix
, _SB(sm
->keyDone
), _SB(sm
->keyRun
),
997 _SB(sm
->keyTxEnabled
), port_type_txt(sm
->portControl
),
998 prefix
, _SB(sm
->portEnabled
), _SB(sm
->portValid
),
999 _SB(sm
->reAuthenticate
));
1001 fprintf(f
, "%s Authenticator PAE:\n"
1003 "%s eapolLogoff=%s eapolStart=%s eapRestart=%s\n"
1004 "%s portMode=%s reAuthCount=%d\n"
1005 "%s quietPeriod=%d reAuthMax=%d\n"
1006 "%s authEntersConnecting=%d\n"
1007 "%s authEapLogoffsWhileConnecting=%d\n"
1008 "%s authEntersAuthenticating=%d\n"
1009 "%s authAuthSuccessesWhileAuthenticating=%d\n"
1010 "%s authAuthTimeoutsWhileAuthenticating=%d\n"
1011 "%s authAuthFailWhileAuthenticating=%d\n"
1012 "%s authAuthEapStartsWhileAuthenticating=%d\n"
1013 "%s authAuthEapLogoffWhileAuthenticating=%d\n"
1014 "%s authAuthReauthsWhileAuthenticated=%d\n"
1015 "%s authAuthEapStartsWhileAuthenticated=%d\n"
1016 "%s authAuthEapLogoffWhileAuthenticated=%d\n",
1017 prefix
, prefix
, auth_pae_state_txt(sm
->auth_pae_state
), prefix
,
1018 _SB(sm
->eapolLogoff
), _SB(sm
->eapolStart
), _SB(sm
->eapRestart
),
1019 prefix
, port_type_txt(sm
->portMode
), sm
->reAuthCount
,
1020 prefix
, sm
->quietPeriod
, sm
->reAuthMax
,
1021 prefix
, sm
->authEntersConnecting
,
1022 prefix
, sm
->authEapLogoffsWhileConnecting
,
1023 prefix
, sm
->authEntersAuthenticating
,
1024 prefix
, sm
->authAuthSuccessesWhileAuthenticating
,
1025 prefix
, sm
->authAuthTimeoutsWhileAuthenticating
,
1026 prefix
, sm
->authAuthFailWhileAuthenticating
,
1027 prefix
, sm
->authAuthEapStartsWhileAuthenticating
,
1028 prefix
, sm
->authAuthEapLogoffWhileAuthenticating
,
1029 prefix
, sm
->authAuthReauthsWhileAuthenticated
,
1030 prefix
, sm
->authAuthEapStartsWhileAuthenticated
,
1031 prefix
, sm
->authAuthEapLogoffWhileAuthenticated
);
1033 fprintf(f
, "%s Backend Authentication:\n"
1035 "%s eapNoReq=%s eapReq=%s eapResp=%s\n"
1036 "%s serverTimeout=%d\n"
1037 "%s backendResponses=%d\n"
1038 "%s backendAccessChallenges=%d\n"
1039 "%s backendOtherRequestsToSupplicant=%d\n"
1040 "%s backendAuthSuccesses=%d\n"
1041 "%s backendAuthFails=%d\n",
1043 be_auth_state_txt(sm
->be_auth_state
),
1044 prefix
, _SB(sm
->eapNoReq
), _SB(sm
->eapReq
), _SB(sm
->eapResp
),
1045 prefix
, sm
->serverTimeout
,
1046 prefix
, sm
->backendResponses
,
1047 prefix
, sm
->backendAccessChallenges
,
1048 prefix
, sm
->backendOtherRequestsToSupplicant
,
1049 prefix
, sm
->backendAuthSuccesses
,
1050 prefix
, sm
->backendAuthFails
);
1052 fprintf(f
, "%s Reauthentication Timer:\n"
1054 "%s reAuthPeriod=%d reAuthEnabled=%s\n", prefix
, prefix
,
1055 reauth_timer_state_txt(sm
->reauth_timer_state
), prefix
,
1056 sm
->reAuthPeriod
, _SB(sm
->reAuthEnabled
));
1058 fprintf(f
, "%s Authenticator Key Transmit:\n"
1059 "%s state=%s\n", prefix
, prefix
,
1060 auth_key_tx_state_txt(sm
->auth_key_tx_state
));
1062 fprintf(f
, "%s Key Receive:\n"
1064 "%s rxKey=%s\n", prefix
, prefix
,
1065 key_rx_state_txt(sm
->key_rx_state
), prefix
, _SB(sm
->rxKey
));
1067 fprintf(f
, "%s Controlled Directions:\n"
1069 "%s adminControlledDirections=%s "
1070 "operControlledDirections=%s\n"
1071 "%s operEdge=%s\n", prefix
, prefix
,
1072 ctrl_dir_state_txt(sm
->ctrl_dir_state
),
1073 prefix
, ctrl_dir_txt(sm
->adminControlledDirections
),
1074 ctrl_dir_txt(sm
->operControlledDirections
),
1075 prefix
, _SB(sm
->operEdge
));
1078 #endif /* HOSTAPD_DUMP_STATE */
1081 static Boolean
eapol_sm_get_bool(void *ctx
, enum eapol_bool_var variable
)
1083 struct eapol_state_machine
*sm
= ctx
;
1087 case EAPOL_eapSuccess
:
1088 return sm
->eapSuccess
;
1089 case EAPOL_eapRestart
:
1090 return sm
->eapRestart
;
1097 case EAPOL_eapNoReq
:
1098 return sm
->eapNoReq
;
1099 case EAPOL_portEnabled
:
1100 return sm
->portEnabled
;
1101 case EAPOL_eapTimeout
:
1102 return sm
->eapTimeout
;
1108 static void eapol_sm_set_bool(void *ctx
, enum eapol_bool_var variable
,
1111 struct eapol_state_machine
*sm
= ctx
;
1115 case EAPOL_eapSuccess
:
1116 sm
->eapSuccess
= value
;
1118 case EAPOL_eapRestart
:
1119 sm
->eapRestart
= value
;
1122 sm
->eapFail
= value
;
1125 sm
->eapResp
= value
;
1130 case EAPOL_eapNoReq
:
1131 sm
->eapNoReq
= value
;
1133 case EAPOL_portEnabled
:
1134 sm
->portEnabled
= value
;
1136 case EAPOL_eapTimeout
:
1137 sm
->eapTimeout
= value
;
1143 static void eapol_sm_set_eapReqData(void *ctx
, const u8
*eapReqData
,
1144 size_t eapReqDataLen
)
1146 struct eapol_state_machine
*sm
= ctx
;
1150 free(sm
->last_eap_radius
);
1151 sm
->last_eap_radius
= malloc(eapReqDataLen
);
1152 if (sm
->last_eap_radius
== NULL
)
1154 memcpy(sm
->last_eap_radius
, eapReqData
, eapReqDataLen
);
1155 sm
->last_eap_radius_len
= eapReqDataLen
;
1159 static void eapol_sm_set_eapKeyData(void *ctx
, const u8
*eapKeyData
,
1160 size_t eapKeyDataLen
)
1162 struct eapol_state_machine
*sm
= ctx
;
1163 struct hostapd_data
*hapd
;
1170 if (eapKeyData
&& eapKeyDataLen
>= 64) {
1171 free(sm
->eapol_key_sign
);
1172 free(sm
->eapol_key_crypt
);
1173 sm
->eapol_key_crypt
= malloc(32);
1174 if (sm
->eapol_key_crypt
) {
1175 memcpy(sm
->eapol_key_crypt
, eapKeyData
, 32);
1176 sm
->eapol_key_crypt_len
= 32;
1178 sm
->eapol_key_sign
= malloc(32);
1179 if (sm
->eapol_key_sign
) {
1180 memcpy(sm
->eapol_key_sign
, eapKeyData
+ 32, 32);
1181 sm
->eapol_key_sign_len
= 32;
1183 if (hapd
->default_wep_key
||
1184 hapd
->conf
->individual_wep_key_len
> 0 ||
1186 sm
->keyAvailable
= TRUE
;
1188 free(sm
->eapol_key_sign
);
1189 free(sm
->eapol_key_crypt
);
1190 sm
->eapol_key_sign
= NULL
;
1191 sm
->eapol_key_crypt
= NULL
;
1192 sm
->eapol_key_sign_len
= 0;
1193 sm
->eapol_key_crypt_len
= 0;
1194 sm
->keyAvailable
= FALSE
;
1199 static int eapol_sm_get_eap_user(void *ctx
, const u8
*identity
,
1200 size_t identity_len
, int phase2
,
1201 struct eap_user
*user
)
1203 struct eapol_state_machine
*sm
= ctx
;
1204 const struct hostapd_eap_user
*eap_user
;
1207 eap_user
= hostapd_get_eap_user(sm
->hapd
->conf
, identity
,
1208 identity_len
, phase2
);
1209 if (eap_user
== NULL
)
1212 memset(user
, 0, sizeof(*user
));
1213 user
->phase2
= phase2
;
1214 count
= EAP_USER_MAX_METHODS
;
1215 if (count
> EAP_MAX_METHODS
)
1216 count
= EAP_MAX_METHODS
;
1217 for (i
= 0; i
< count
; i
++) {
1218 user
->methods
[i
].vendor
= eap_user
->methods
[i
].vendor
;
1219 user
->methods
[i
].method
= eap_user
->methods
[i
].method
;
1222 if (eap_user
->password
) {
1223 user
->password
= malloc(eap_user
->password_len
);
1224 if (user
->password
== NULL
)
1226 memcpy(user
->password
, eap_user
->password
,
1227 eap_user
->password_len
);
1228 user
->password_len
= eap_user
->password_len
;
1230 user
->force_version
= eap_user
->force_version
;
1236 static const char * eapol_sm_get_eap_req_id_text(void *ctx
, size_t *len
)
1238 struct eapol_state_machine
*sm
= ctx
;
1239 *len
= sm
->hapd
->conf
->eap_req_id_text_len
;
1240 return sm
->hapd
->conf
->eap_req_id_text
;
1244 static struct eapol_callbacks eapol_cb
=
1246 .get_bool
= eapol_sm_get_bool
,
1247 .set_bool
= eapol_sm_set_bool
,
1248 .set_eapReqData
= eapol_sm_set_eapReqData
,
1249 .set_eapKeyData
= eapol_sm_set_eapKeyData
,
1250 .get_eap_user
= eapol_sm_get_eap_user
,
1251 .get_eap_req_id_text
= eapol_sm_get_eap_req_id_text
,
1255 int eapol_sm_eap_pending_cb(struct eapol_state_machine
*sm
, void *ctx
)
1257 if (sm
== NULL
|| ctx
!= sm
->eap
)
1260 eap_sm_pending_cb(sm
->eap
);