void authenticator_fsm(auth_t* auth_1x) { /* Change the state to AS_INITAILIZE if portControl is set to AUTO and */ /* other variables are appropriately set. */ if(((auth_1x->global.portControl == AUTO) && (auth_1x->auth_pae.portMode != auth_1x->global.portControl)) || (auth_1x->global.initialize == BTRUE) || (auth_1x->global.portEnabled == BFALSE)) { auth_initialize(auth_1x); return; } /* Transition to AS_FORCE_AUTH and AS_FORCE_UNAUTH may happen from any */ /* state. Hence the conditions for these transitions are checked here. */ /* Change the state to AS_FORCE_AUTH if portControl is set to */ /* FORCE_AUTHORIZED and other variables are appropriately set. */ if((auth_1x->global.portControl == FORCE_AUTHORIZED) && (auth_1x->auth_pae.portMode != auth_1x->global.portControl) && ((auth_1x->global.initialize == BFALSE) || (auth_1x->global.portEnabled == BTRUE))) { auth_force_auth(auth_1x); } /* Change the state to AS_FORCE_UNAUTH if portControl is set to */ /* FORCE_UNAUTHORIZED and other variables are appropriately set. */ else if((auth_1x->global.portControl == FORCE_UNAUTHORIZED) && (auth_1x->auth_pae.portMode != auth_1x->global.portControl) && ((auth_1x->global.initialize == BFALSE) || (auth_1x->global.portEnabled == BTRUE))) { auth_force_unauth(auth_1x); } switch(auth_1x->auth_pae.state) { case AS_INITIALIZE: { /* Change the state unconditionally to AS_DISCONNECTED */ auth_disconnected(auth_1x); } /* End of case AS_INITIALIZE: */ break; case AS_DISCONNECTED: { auth_connecting(auth_1x); } break; case AS_CONNECTING: { /* Change the state to AS_DISCONNECTED only if reAuthentication */ /* count has exceeded limit or an eapolLogoff message is received. */ if((auth_1x->auth_pae.eapolLogoff == BTRUE) || ((auth_1x->auth_pae.reAuthCount > auth_1x->auth_pae.reAuthMax) && (auth_1x->global.txWhenTimeout == BTRUE))) { auth_1x->auth_pae.authEapLogoffsWhileConnecting++; auth_disconnected(auth_1x); } /* If the retransmission limit is not reached and the time out has */ /* occured, re transmit the message to the Supplicant */ else if((auth_1x->auth_pae.reAuthCount <= auth_1x->auth_pae.reAuthMax) && (auth_1x->global.txWhenTimeout == BTRUE)) { auth_connecting(auth_1x); } /* Also, In the event of any reauthentication or if the EAPOL Start */ /* has been received in this state the ReqId message is resent to */ /* the Supplicant state machine */ else if((auth_1x->auth_pae.reAuthCount <= auth_1x->auth_pae.reAuthMax) && ((auth_1x->auth_pae.eapolStart == BTRUE) || (auth_1x->global.reAuthenticate == BTRUE))) { auth_1x->auth_pae.reAuthCount = 0; auth_connecting(auth_1x); } /* Change the state to AS_AUTHENTICATING only if a EAP message is to */ /* be sent from higher layer and reAuthentication count has not */ /* exceeded the limit. Also an indication of Authentication Success/ */ /* Failure from the higher layers initiates a change of state. */ else if((auth_1x->auth_pae.rxRespId == BTRUE) && (auth_1x->auth_pae.reAuthCount <= auth_1x->auth_pae.reAuthMax)) { auth_1x->auth_pae.authEntersAuthenticating++; auth_authenticating(auth_1x); } /* If a packet was ignored, restart the timer */ else if((auth_1x->auth_pae.rxRespId == BTRUE) || (auth_1x->auth_pae.eapolStart == BTRUE)) { auth_1x->auth_pae.authEapLogoffsWhileConnecting++; auth_disconnected(auth_1x); } else { /* No state change is required */ } } /* End of case AS_CONNECTING: */ break; case AS_AUTHENTICATING: { /* Change the state to AS_AUTHENTICATED only if authentication */ /* process successful along with portValid is TRUE (after */ /* establishing secure communication channel between authenticator */ /* and supplicant - after key exchanges in 802.11). */ if(auth_1x->global.authSuccess == BTRUE && auth_1x->global.portValid == BTRUE) { auth_1x->auth_pae.authAuthSuccessesWhileAuthenticating ++; auth_authenticated(auth_1x); } /* Change the state to AS_ABORTING if any of the messages namely, */ /* eapolStart, eapolLogoff or authTimeout has arrived. */ else if((auth_1x->auth_pae.eapolStart == BTRUE) || (auth_1x->auth_pae.eapolLogoff == BTRUE) || (auth_1x->global.authTimeout == BTRUE)) { if(auth_1x->global.authTimeout == BTRUE) auth_1x->auth_pae.authAuthTimeoutsWhileAuthenticating++; else if(auth_1x->auth_pae.eapolStart == BTRUE) auth_1x->auth_pae.authAuthEapStartsWhileAuthenticating++; else if(auth_1x->auth_pae.eapolLogoff== BTRUE) auth_1x->auth_pae.authAuthEapLogoffWhileAuthenticating++; auth_aborting(auth_1x); } /* Change the state to AS_HELD only if Authentication fails for the */ /* port or portValid is FALSE (after key state machine indicates if */ /* portValid can be tested. */ else if((auth_1x->global.authFail == BTRUE) || ((auth_1x->global.keyDone == BTRUE) && (auth_1x->global.portValid == BFALSE))) { auth_1x->auth_pae.authAuthFailWhileAuthenticating++; auth_held(auth_1x); } else { /* No state change is required */ } } /* End of case AS_AUTHENTICATING: */ break; case AS_AUTHENTICATED: { /* Change the state to AS_RESTART if eapolStart or reauthenticate */ /* message arrives. */ if((auth_1x->auth_pae.eapolStart == BTRUE) || (auth_1x->global.reAuthenticate == BTRUE)) { if(auth_1x->global.reAuthenticate == BTRUE) auth_1x->auth_pae.authAuthReauthsWhileAuthenticated++; else if(auth_1x->auth_pae.eapolStart == BTRUE) auth_1x->auth_pae.authAuthEapStartsWhileAuthenticated++; auth_connecting(auth_1x); } /* Change the state to AS_DISCONNECTED if either eapolLoff message */ /* comes or portValid is FALSE. */ else if((auth_1x->auth_pae.eapolLogoff == BTRUE) || (auth_1x->global.portValid == BFALSE)) { auth_1x->auth_pae.authAuthEapLogoffWhileAuthenticated++; auth_disconnected(auth_1x); } else { /* No state change is required */ } } /* End of case AS_AUTHENTICATED: */ break; case AS_ABORTING: { /* Change the state to AS_RESTART if eapolLogoff arrives or */ /* authAbort is reset by Authentication backend state machine. */ if((auth_1x->auth_pae.eapolLogoff == BFALSE) && (auth_1x->global.authAbort == BFALSE)) { auth_connecting(auth_1x); } /* Change the state to AS_DISCONNECTED if either eapolLoff message */ /* comes or authAbort is reset by the Authentication backend state */ /* machine. */ else if((auth_1x->auth_pae.eapolLogoff == BTRUE) && (auth_1x->global.authAbort == BFALSE)) { auth_disconnected(auth_1x); } else { /* No state change is required */ } } /* End of case AS_ABORTING: */ break; case AS_HELD: { /* Change the state to AS_RESTART after quietWhile timer expires */ if(auth_1x->global.quietWhileTimeout == BTRUE) { auth_connecting(auth_1x); } else { /* No state change is required */ } } /* End of case AS_HELD: */ break; case AS_FORCE_AUTH: { /* Remain in AS_FORCE_AUTH state. However, execute the function */ /* again only if EAPOL PDU carrying EAPOL-Start is received. */ if(auth_1x->auth_pae.eapolStart == BTRUE) { auth_force_auth(auth_1x); } else { /* No state change is required */ } } break; case AS_FORCE_UNAUTH: { /* Remain in AS_FORCE_UNAUTH state. However, execute the function */ /* again only if EAPOL PDU carrying EAPOL-Start is received. */ if(auth_1x->auth_pae.eapolStart == BTRUE) { auth_force_unauth(auth_1x); } else { /* No state change is required */ } } break; default: { /* Do nothing */ } } /* End of switch(auth_1x->auth_pae.state) */ }
/* * The main routine - parses command line and calls action procedures */ int main (int argc, char *argv[]) { int i; const char *sourcename = defsource; char **arglist = defcmds; int nargs = ndefcmds; int status; ProgramName = argv[0]; for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (arg[0] == '-') { const char *flag; for (flag = (arg + 1); *flag; flag++) { switch (*flag) { case 'f': /* -f authfilename */ if (++i >= argc) usage (); authfilename = argv[i]; continue; case 'v': /* -v */ verbose = 1; continue; case 'q': /* -q */ verbose = 0; continue; case 'b': /* -b */ break_locks = True; continue; case 'i': /* -i */ ignore_locks = True; continue; default: usage (); } } } else { sourcename = "(argv)"; nargs = argc - i; arglist = argv + i; if (verbose == -1) verbose = 0; break; } } if (verbose == -1) { /* set default, don't junk stdout */ verbose = (isatty(fileno(stdout)) != 0); } if (!authfilename) { authfilename = IceAuthFileName (); /* static name, do not free */ if (!authfilename) { fprintf (stderr, "%s: unable to generate an authority file name\n", ProgramName); exit (1); } } if (auth_initialize (authfilename) != 0) { /* error message printed in auth_initialize */ exit (1); } status = process_command (sourcename, 1, nargs, arglist); (void) auth_finalize (); exit ((status != 0) ? 1 : 0); }