authenticator_backend_fsm.c
Go to the documentation of this file.
1 /**
2  * @file authenticator_backend_fsm.c
3  * @brief Backend authentication state machine
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneEAP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL AUTHENTICATOR_TRACE_LEVEL
33 
34 //Dependencies
40 #include "eap/eap_debug.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (AUTHENTICATOR_SUPPORT == ENABLED)
45 
46 //Backend authentication states
48 {
57 };
58 
59 
60 /**
61  * @brief Backend authentication state machine initialization
62  * @param[in] port Pointer to the port context
63  **/
64 
66 {
67  //Enter initial state
69 }
70 
71 
72 /**
73  * @brief Backend authentication state machine implementation
74  * @param[in] port Pointer to the port context
75  **/
76 
78 {
79  //A global transition can occur from any of the possible states. When the
80  //condition associated with a global transition is met, it supersedes all
81  //other exit conditions
82  if(port->portControl != AUTHENTICATOR_PORT_MODE_AUTO ||
83  port->initialize || port->authAbort)
84  {
85  //Switch to the INITIALIZE state
87  }
88  else
89  {
90  //All exit conditions for the state are evaluated continuously until one
91  //of the conditions is met (refer to IEEE Std 802.1X-2004, section 8.2.1)
92  switch(port->authBackendState)
93  {
94  //INITIALIZE state?
96  //Unconditional transition (UCT) to IDLE state
98  break;
99 
100  //IDLE state?
102  //Evaluate conditions for the current state
103  if(port->eapFail && port->authStart)
104  {
105  //Switch to the FAIL state
107  }
108  else if(port->eapReq && port->authStart)
109  {
110  //Switch to the REQUEST state
112  }
113  else if(port->eapSuccess && port->authStart)
114  {
115  //Switch to the SUCCESS state
117  }
118  else
119  {
120  //Just for sanity
121  }
122 
123  break;
124 
125  //REQUEST state?
127  //Evaluate conditions for the current state
128  if(port->eapTimeout)
129  {
130  //Switch to the TIMEOUT state
132  }
133  else if(port->eapolEap)
134  {
135  //Switch to the RESPONSE state
137  }
138  else if(port->eapReq)
139  {
140  //Switch to the REQUEST state
142  }
143  else
144  {
145  //Just for sanity
146  }
147 
148  break;
149 
150  //RESPONSE state?
152  //Evaluate conditions for the current state
153  if(port->eapNoReq)
154  {
155  //Switch to the IGNORE state
157  }
158  else if(port->aWhile == 0)
159  {
160  //Switch to the TIMEOUT state
162  }
163  else if(port->eapFail)
164  {
165  //Switch to the FAIL state
167  }
168  else if(port->eapSuccess)
169  {
170  //Switch to the SUCCESS state
172  }
173  else if(port->eapReq)
174  {
175  //Switch to the REQUEST state
177  }
178  else
179  {
180  //Just for sanity
181  }
182 
183  break;
184 
185  //IGNORE state?
187  //Evaluate conditions for the current state
188  if(port->eapolEap)
189  {
190  //Switch to the RESPONSE state
192  }
193  else if(port->eapReq)
194  {
195  //Switch to the REQUEST state
197  }
198  else if(port->eapTimeout)
199  {
200  //Switch to the TIMEOUT state
202  }
203  else
204  {
205  //Just for sanity
206  }
207 
208  break;
209 
210  //FAIL state?
212  //Unconditional transition (UCT) to IDLE state
214  break;
215 
216  //TIMEOUT state?
218  //Unconditional transition (UCT) to IDLE state
220  break;
221 
222  //SUCCESS state?
224  //Unconditional transition (UCT) to IDLE state
226  break;
227 
228  //Invalid state?
229  default:
230  //Just for sanity
231  authenticatorFsmError(port->context);
232  break;
233  }
234  }
235 }
236 
237 
238 /**
239  * @brief Update backend authentication state
240  * @param[in] port Pointer to the port context
241  * @param[in] newState New state to switch to
242  **/
243 
245  AuthenticatorBackendState newState)
246 {
247  AuthenticatorBackendState oldState;
248 
249  //Retrieve current state
250  oldState = port->authBackendState;
251 
252  //Any state change?
253  if(newState != oldState)
254  {
255  //Dump the state transition
256  TRACE_DEBUG("Port %" PRIu8 ": Backend authentication state machine %s -> %s\r\n",
257  port->portIndex,
262  }
263 
264  //Switch to the new state
265  port->authBackendState = newState;
266 
267  //On entry to a state, the procedures defined for the state are executed
268  //exactly once (refer to IEEE Std 802.1X-2004, section 8.2.1)
269  switch(newState)
270  {
271  //INITIALIZE state?
273  //The abortAuth procedure is used to release any system resources that
274  //may have been occupied by the session
276  port->eapNoReq = FALSE;
277  port->authAbort = FALSE;
278  break;
279 
280  //IDLE state?
282  //In this state, the state machine is waiting for the authenticator state
283  //machine to signal the start of a new authentication session
284  port->authStart = FALSE;
285  break;
286 
287  //REQUEST state?
289  //In this state, the state machine has received an EAP request packet
290  //from the higher layer and is relaying that packet to the supplicant as
291  //an EAPOL-encapsulated frame
293  port->eapReq = FALSE;
294  break;
295 
296  //RESPONSE state?
298  //In this state, the state machine has received an EAPOL-encapsulated
299  //EAP response packet from the supplicant, and is relaying the EAP packet
300  //to the higher layer to be relayed on to the Authentication Server, and
301  //is awaiting instruction from the higher layer as to what to do next
302  port->authTimeout = FALSE;
303  port->eapolEap = FALSE;
304  port->eapNoReq = FALSE;
305  port->aWhile = port->serverTimeout;
306  port->eapResp = TRUE;
308  break;
309 
310  //IGNORE state?
312  //This state is entered when the higher layer has decided to ignore the
313  //previous EAP response message received from the supplicant
314  port->eapNoReq = FALSE;
315  break;
316 
317  //FAIL state?
319  //The state machine sets the global variable authFail TRUE in order to
320  //signal to the Authenticator state machine that the authentication
321  //session has terminated with an authentication failure, and it transmits
322  //the final EAP message from the AAA client that was encapsulated in the
323  //Reject message from the authentication server
325  port->authFail = TRUE;
326  break;
327 
328  //TIMEOUT state?
330  //The state machine sets the global variable authTimeout TRUE in order
331  //to signal to the Authenticator state machine that the authentication
332  //session has terminated with a timeout
333  port->authTimeout = TRUE;
334  break;
335 
336  //SUCCESS state?
338  //The state machine sets the global variable authSuccess TRUE in order
339  //to signal to the authenticator state machine that the authentication
340  //session has terminated successfully, and it transmits the final EAP
341  //message from the AAA client that was encapsulated in the Accept message
342  //from the authentication server
344  port->authSuccess = TRUE;
345  port->keyRun = TRUE;
346  break;
347 
348  //Invalid state?
349  default:
350  //Just for sanity
351  break;
352  }
353 
354  //Any state change?
355  if(newState != oldState)
356  {
357  //Any registered callback?
358  if(port->context->backendStateChangeCallback != NULL)
359  {
360  //Invoke user callback function
361  port->context->backendStateChangeCallback(port, newState);
362  }
363  }
364 
365  //Check whether the port is enabled
366  if(port->portControl == AUTHENTICATOR_PORT_MODE_AUTO &&
367  !port->initialize && !port->authAbort)
368  {
369  //The backend authentication state machine is busy
370  port->context->busy = TRUE;
371  }
372 }
373 
374 #endif
const char_t * eapGetParamName(uint_t value, const EapParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: eap_debug.c:219
#define TRUE
Definition: os_port.h:50
void authenticatorSendRespToServer(AuthenticatorPort *port)
Deliver the received EAP frame to EAP for processing (8.2.9.1.3 b)
void authenticatorBackendFsm(AuthenticatorPort *port)
Backend authentication state machine implementation.
Helper functions for 802.1X authenticator.
Authenticator state machine procedures.
#define FALSE
Definition: os_port.h:46
802.1X authenticator
Backend authentication state machine.
AuthenticatorBackendState
Backend authentication states.
@ AUTHENTICATOR_BACKEND_STATE_INITIALIZE
@ AUTHENTICATOR_BACKEND_STATE_SUCCESS
void authenticatorAbortAuth(AuthenticatorPort *port)
Release any system resources (8.2.9.1.3 c)
@ AUTHENTICATOR_BACKEND_STATE_REQUEST
void authenticatorFsmError(AuthenticatorContext *context)
Authenticator state machine error handler.
Authenticator state machine.
@ AUTHENTICATOR_BACKEND_STATE_RESPONSE
uint16_t port
Definition: dns_common.h:267
#define TRACE_DEBUG(...)
Definition: debug.h:107
Data logging functions for debugging purpose (EAP)
const EapParamName authenticatorBackendStates[]
@ AUTHENTICATOR_BACKEND_STATE_FAIL
@ AUTHENTICATOR_PORT_MODE_AUTO
void authenticatorTxReq(AuthenticatorPort *port)
Transmit an EAPOL frame of type EAP-Packet (8.2.9.1.3 a)
void authenticatorBackendInitFsm(AuthenticatorPort *port)
Backend authentication state machine initialization.
void authenticatorBackendChangeState(AuthenticatorPort *port, AuthenticatorBackendState newState)
Update backend authentication state.
@ AUTHENTICATOR_BACKEND_STATE_TIMEOUT
#define AuthenticatorPort
Definition: authenticator.h:40
Parameter value/name binding.
Definition: eap_debug.h:50
@ AUTHENTICATOR_BACKEND_STATE_IGNORE
@ AUTHENTICATOR_BACKEND_STATE_IDLE
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:71