

              Authentication/Authorization Transfer Vector (AATV)


   The existing versions of RADIUS have used ad hoc methods to obtain
authentication credentials for requests originating at a Network Access
Server (NAS) client.  Early versions performed a simple table lookup in
a local "users" database -- essentially a flat file database.  Eventually
this was extended into look-up requests to the (default) UNIX host which
was running the RADIUS server.  Both of these methods did not scale well,
although both are extremely popular and adequate in many cases.  The Merit
extensions added a complex source module (auth_fun.c) to allow for multiple
kinds of authentication types (e.g., Kerberos) including the relaying of
(proxy) authentication requests to other RADIUS servers reachable over the
network.

   However, adding a new authentication type to RADIUS became a painful
and "guru" level activity.  At the requests of several individuals, Merit
has added what is essentially an authentication/authorization Applications
Programming Interface (or API).  This API is suitable for handling requests
of other types than just authentication/authorization.  In fact, it is now
possible to have a request travel through several "phases" of this API on
its journey from the NAS client, into RADIUS and back to the NAS client.

   It was felt a modular approach would make the code more manageable and
more understandable.  It also would allow the addition of new authentication
types to become an independent and constrained activity no longer requiring
the services of "expert" RADIUS programmers.  It will also permit different
vendors to attach proprietary authentication/authorization/accounting engines
in a hopefully portable and standard fashion.

   The resulting extensions, here called AATV for Authentication/Authorization
Transfer Vector, provide the required modularity and eliminate any global name
space pollution.  Some prefer to think of the modularity made possible by the
AATV as an object oriented mechanism (without using C++) while others think of
the various client modules as simple black boxes having only one public symbol
and one or more local (static) procedures for handling the actual work load.
The transfer vector derives from a public structure which is described below.
Basically it is an array of several function pointers and a few associated
flags used to inform the RADIUS engine about the client's internal processing
configuration (e.g., whether sockets or process creation, or neither, are used
to maintain a good response time for incoming requests).

   The "black box" contains an initialization function (think "constructor"
for C++) and a workhorse function (method) which implements the actual body
of the module's processing algorithm (here called the "action" function).
The "cleanup", "recv" and "timer" methods are optional.  An integer variable
is available to hold the file descriptor for a socket (if needed).  The three
remaining fields are just overhead to tell the RADIUS engine how to invoke
and control the AATV client module should an incoming request match the type
of the module.

   The AATV concept is integral to the use of a Finite State Machine (FSM) in
the RADIUS engine.  See the related FSM documentation for information on this.

   The AATV structure (think class in C++) describes the "public interface"
or protocol of the client module.  These methods (when present) are private
to the AATV module (in the strict C++ sense).  The RADIUS "engine" maintains
an array of these AATV structure pointers and uses that array to select which
module matches the incoming authentication (or authorization or accounting)
request.  So, now, here is the formal description of the AATV structure:


    typedef struct aatv
    {
        u_char       id[32];
        char         authen_type;
        u_char       aatvfunc_type;
        void       (*init) PROTO((struct aatv *));
        int        (*timer) PROTO((void));
        int        (*act_func) PROTO((AUTH_REQ *, int, char *));
        AUTH_REQ * (*recv) PROTO((struct sockaddr_in *, UINT4, u_int, EV *));
        void       (*cleanup) PROTO((void));
        int          sockfd;
    } AATV;


Where:   The "id" field is an unsigned character array containing the unique
         ASCII name for this particular AATV.  No more than one AATV having
         this name may be present in the AATV array in the RADIUS engine.


         The "authen_type" field is a character containing the numerical
         type code as defined in the "dictionary" file (REALM, MIT-KRB,
         TACACS, UNIX-PW, etc.) or "-1" for built-in types.


         The "aatvfunc_type" field indicates to RADIUS how a given client
         API module handles multitasking and how RADIUS should process these
         types of requests.  This field is an unsigned character containing
         one of the following numbers:

            0 (AA_DIRECT) - The API "act_func" function gives a direct reply.
                            This is the case when it is possible to perform
                            the processing locally using table lookup or some
                            computational means.  This is simply a direct
                            function call (and return) within the server
                            running on the local host.

            1 (AA_SOCKET) - The deferred reply is returned on a socket for
                            this type of API client module.  Presumably some
                            sort of separate processing is required and the
                            result is eventually returned using the socket.

            2 (AA_FORK)   - This type of client spawns a process and informs
                            the engine to expect a deferred reply.  The reply
                            is part of the exit status of the child process.

            3 (AA_FREPLY) - This type is similar to the AA_FORK since it does
                            fork, but it gets its reply on the standard server
                            socket (just like the AA_SOCKET type).

         The "init" field is a (possibly NULL) function pointer which points
         to the initialization function for this client module.  It takes a
         pointer to an AATV typically to have access to the socket file
         descriptor which needs to be initialized for type AA_SOCKET.


         The "timer" field is a (possibly NULL) function pointer which points
         to a timer function which will be called every second when a client
         request is pending.  This routine allows the API module to do general
         purpose timing functions, but is not normally necessary.


         The "act_func" field is a function pointer which points to the main
         processing function for this client module.  It is this function which
         "does all the work" corresponding to the given request.  The "action"
         function has arguments for an AUTH_REQ pointer, integer and a string.
         The integer and string are just general purpose arguments which the
         action function may or may not need.  All action functions need and
         use the AUTH_REQ pointer which grants them access to the engine's
         global queue of request data structures.  This structure contains
         everything there is to know about the current (outstanding) request.
         Each action function returns the results of its execution in a small
         integer valued return code.  A list of these "events" is given below.


         The "recv" field is a (possibly NULL) function pointer which points
         to a receiving function (if needed) to receive packets from a socket.
         It may be thought of as the "starting point" for handling requests on
         a socket or as the "termination" phase of a multi-phase transaction.
         The engine will hand off received packets to this function when it
         receives them and determines which function to call based on the
         socket upon which it arrived.  The first argument carries information
         about the originating socket, the second argument contains the IP
         address of the sender, the third argument is the number of octets
         received by the engine and the last argument is an EVENT_ENT pointer.
         The receive function builds an AUTH_REQ structure and populates it.
         It also returns an "event" for the FSM using the EVENT_ENT pointer.


         The "cleanup" field is a (possibly NULL) pointer to a function which
         is used to perform any post-processing or clean up type activities
         (if necessary) for this API module (think "destructor" for C++).


         The "sockfd" field is an integer containing the file descriptor
         for this API module (if it is an AA_SOCKET type).



   The flow of data through the RADIUS server engine normally begins on a
well-known socket and is then handed off to one of the (several) client API
modules for processing.  From these modules, the request may be satisfied
locally or relayed off the local host for further processing.  Eventually,
the request is satisfied in either a positive, or negative sense, and the
RADIUS server returns an acknowledgement, or a negative acknowledgement, to
the NAS client, respectively.

   The list of current AATV names is given below.  Several different "utility"
AATV concepts have been identified and made part of the RADIUS server engine,
for convenience.  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 logs the
fact that a request on the global queue has timed out.

               Current 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

               Current 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 RADIUS 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
