Copyright [C] The Regents of the University of Michigan and Merit Network, Inc. 1993, 1994, 1995, 1996, 1997 All Rights Reserved. Finite State Machine (FSM) Information for the Merit AAA Server The Finite State Machine (FSM) addition to the Merit AAA server evolved out of the need to have a way to call more than one Authentication/Authorization Transfer Vector (AATV) action function in order to handle an incoming request. The Merit AAA server FSM depends on the Merit AAA server AATV concept. The AATV concept predates the FSM design by only a few months, since, from the start, it was considered that the two would indeed "play" together. For more information on the AATV concept, see the "aatv.txt" file in this distribution. An AATV action function is a normal C function which performs some algorithm to process a RADIUS authentication, authorization or accounting request. Each AATV has a unique, 32 character maximum, identifier or name. The Merit AAA server FSM is able to distinguish one AATV from another using the AATV identifier. The FSM is part of the Merit AAA server mainline or engine. Incoming socket requests generate "events" which are small integers representing the events. The FSM is basically an infinite while loop which controls the execution of one or more AATV action functions, in turn, as is dictated by: incoming events, the results of previous "states" in the FSM (also modeled as events) and the structure of the FSM configuration table (usually "radius.fsm" but this is configurable, too!). The configuration table (or FSM table) is read into memory at initialization time and whenever a UNIX HUP signal is received by the Merit AAA server. The syntax of the FSM table is one or more entries, where each entry describes one state. Comment text is allowed in this file and takes the form of arbitrary lines of text which begin with the pound sign ("#") character. Any such lines lines are ignored. The contents of the FSM file are not case sensitive, since everything is converted to uppercase when the file is parsed. The state name for each entry is followed by a colon (":") character. All state names are normally the first (column one) and only items on that line. All subsequent lines, until the next state name is encountered, indicate various conditions which result in the invocation of AATV action functions from this state. Each such line consists of from three to five fields, the first three of which are required while the last two are optional. The fields are separated from each other on each line with whitespace characters and should not start in the first column. The fields are named, in turn, the "event", the "action", the "next state", and optionally, an integer and a string. The optional last two fields are used to pass an arbitrary, user specified integer and/or string, respectively, to any AATV to be used according to the AATV implementation. The event field is actually a three-tuple which is used to identify an event. The three sub-fields are: a state name, an action name and an event number. Each of the three sub-fields are separated from each other with a period (".") character. The state name identifies which state generated this event. The action name is either the name of an AATV which generated this event (from the state in the first field) or an arbitrary string preceded by the plus ("+") sign character. These strings are found in the code or may arrive in a packet. The event number is usually the "return code" from the named AATV, several of which are listed at the end of this document. If a state has many such entries, a match on these three sub-fields with the current incoming event will either select one of these entries or else match a set of built-in events to determine which action to issue next. The action field names an AATV whose action function is to be invoked for the matching event. When that action function terminates, the FSM regains control and now begins to process the entries of the state indicated in the "next state" field. It is an error (detected when the FSM configuration file is initially read into memory) for a state to be defined, but never referenced. It is also an error if a "next state" is referenced, but never defined. It is all right to refer to a state which is not yet defined, but which is defined in an entry found later on in the configuration file. When the action function terminates in one of several different ways, it returns an event number to the FSM which is used to select which event (of several) in the next state to process next. The FSM continues in this way until the end of the FSM table is reached or a condition is reached in which there is "nothing left to do" in the processing of the current request. This might happen if, for example, a remote request was indicated and the local machine needed to wait for the results of the remote processing before it was able to complete its processing. When an event is pending in this fashion an entry is placed on a linked list of event structures which remembers the fact of the outstanding request. This list is used to help identify and match up incoming replies with outstanding or pending requests and to perform the retransmission of proxy requests when duplicate requests are detected. Note that this event list based architecture enables multiple RADIUS requests to be pending at once. This capability allows for redundant requests to be issued simultaneously and for timeouts of remote requests to cause transmission of these requests to alternate servers, for example. Such complex actions are actually fairly easy to configure. The event list has entries for both socket and forking type activity. For the forking type, a match is made with the recorded PID of the forked child process. For the socket type, the match is made using the value of the state from which the proxy request originated. This requires that the proxy request include the Proxy-State attribute-value pair containing the requesting server's current state. It also requires the remote RADIUS server to return, without modification, the Proxy-State attribute value pair in the RADIUS reply packet. Several different "utility" AATV concepts have been identified and made part of the Merit AAA server engine, for convenience. A sample list of AATV names is given at the end of this document. Some of these utility AATVs are used to help process the event list mentioned above. The AATV "NULL" causes the event list to be ignored when a duplicate request is detected. The REDO AATV causes all pending events of the matching request to be re-issued. The KILL AATV causes the list of pending events to be cleared (in this case, all events are assumed to be satisfied). Other utility AATVs perform other useful functions. The PENDING AATV checks if any events are still pending on the request's event list. The TIMER AATV sets a timer interval to an initial value. The END AATV terminates the FSM for this request. The LOG AATV is used to log an error condition. The REPLY AATV is used to do whatever is needed to issue the reply or response to the RADIUS request. The TIMEOUT AATV simply logs the fact that a request on the global request queue has timed out. Below is a diagram of the Merit AAA server finite state machine showing the entry and exit points plus various internal items and internal control flow. +-----------------------------------------------+ | | request ---> do any initialization needed | E | | | create an auth_req structure | N | | | do duplicate detection | G | | | create an event: | I | | | AUTHEN, ACCT, PASSWD, AUTH_ONLY, etc. | N | | | call state_machine (event, auth_req) below | E | | +-----------------------------------------------+ | | event -->---> | state_machine (integer event code, | / | auth. request pointer) | | | | | | *** Decision Function based on FSM Table *** | | | | | | (action, next_state) = f (cur_state, event) | | | | | | "cur_state" is a field in auth_req | | | | | | "event" is the first argment above | | | | | | set cur_state = next_state | | | | | +-----------------------------------------------+ | | | | | *** Take Action *** | | | | | | if (action .EQ. "NULL") exit state machine -------+ | | | | | | else, call AATV "action" function passing | | | | | | | | to it the auth. request pointer "ap": | | | | | | | | result = AATV->act_func (ap, ...) | | | | | | | | where "result" is an integer event from | | | | | | | | the set: [ACK, NAK, WAIT, ERROR, etc.] | | | | | | | | loop within state machine | | | | ----------+-------------- | | | | | | | | +------------------ | --------------------------+ | | | v +-------------------------+ back to main engine select() loop Sample List of Event Names and Their Meaning ACK acknowledgment of the previous action NAK negative acknowledgment of the previous action WAIT the previous action generated a pending event ERROR the previous action generated an error FATAL the previous action generated a fatal error DUP the incoming request is a duplicate TIMER the timer value has expired TIMEOUT the request has timed out due to inactivity AUTHEN the incoming request is an Access-Request ACCT the incoming request is an Accounting-Request PASSWD the incoming request is a Passwd-Request REACCESS the incoming request is is an Access-Request with State ACC_CHAL the incoming request is and Access-Challenge MGT_POLL the incoming request is is a Status-Server AUTH_ONLY the incoming request is for Authentication-Only RC1 general purpose return code of one RC2 general purpose return code of two RC3 general purpose return code of three RC4 general purpose return code of four RC5 general purpose return code of five RC6 general purpose return code of six RC7 general purpose return code of seven RC8 general purpose return code of eight RC9 general purpose return code of nine RC10 general purpose return code of ten RC11 general purpose return code of eleven RC12 general purpose return code of twelve Sample List of AATV Names and Their Purpose ACCT the AATV for Accounting requests ACK utility AATV used to always signify success AKERB the AATV for AFS Kerberos Authentication AUTHENTICATE the AATV for Authentication requests CLEANUP utility AATV used to exit the FSM FILE the AATV for FILE Authentication KCHAP the AATV for KCHAP Authentication KILL utility AATV used to unconditionally remove pending events LOG utility AATV used to log some error MKERB the AATV for MIT Kerberos Authentication NULL utility NULL AATV PASSWD the AATV for Passwd requests PENDING utility AATV used to test for pending events RAD2RAD the AATV used to send RADIUS proxy requests RADDNS the AATV for resolving DNS names RADIUS the main AATV in the Merit AAA server engine REALM the AATV for handling realm based Authentication REDO utility AATV used to re-invoke an action REPLY utility AATV used to send a RADIUS reply SRV_STATUS the AATV for Status-Server (Management-Poll) requests TACACS the AATV for TACACS Authentication TIMEOUT utility AATV used to do timeout logging TIMER utility AATV used to initialize the timeout value UNIX-PW the AATV for for UNIX password file Authentication