Authentication Manager

/*
**	(c) COPYRIGHT MIT 1995.
**	Please first read the full copyright statement in the file COPYRIGH.
*/
This module handles the registration of multiple Access authentication schemes with support for both clients and servers. The module allows multiple authentication schemes to be registered at run time so that the client and server easily can extend the set of authentication schemes. The Library does already support two welknown schemes from the HTTP specification: basic and digest but othes can be added.

Authentication information is kept separate from the various autehntication schemes so that the management of authentication information such as challenges and credentials can be handed independent of the scheme used. All information about authentication information is stored in a Authentication Information base.

This module is implemented by HTAAUtil.c, and it is a part of the W3C Reference Library.

#ifndef HTAAUTIL_H
#define HTAAUTIL_H
#include "HTAssoc.h"
#include "HTReq.h"

Default filenames

#ifndef PASSWD_FILE
#define PASSWD_FILE	"/tmp/passwd"
#endif

#ifndef GROUP_FILE
#define GROUP_FILE	"/tmp/group"
#endif

#define ACL_FILE_NAME	".www_acl"

/*
** Numeric constants
*/
#define MAX_USERNAME_LEN	16	/* @@ Longest allowed username	  */
#define MAX_PASSWORD_LEN	4*13	/* @@ Longest allowed password	  */
					/* (encrypted, so really only 4*8)*/
#define MAX_METHODNAME_LEN	12	/* @@ Longest allowed method name */
#define MAX_FIELDNAME_LEN	16	/* @@ Longest field name in	  */
					/* protection setup file	  */
#define MAX_PATHNAME_LEN	80	/* @@ Longest passwd/group file	  */
					/* patname to allow		  */
We need to define the following structures as they are used in the HTRequest object.
/*
** Access Authorization failure reasons
*/
typedef enum {
    HTAA_OK,		/* 200 OK				*/
    HTAA_OK_GATEWAY,	/* 200 OK, acting as a gateway		*/
    HTAA_OK_REDIRECT,	/* 302 OK, redirected			*/
    HTAA_NO_AUTH,	/* 401 Unauthorized, not authenticated	*/
    HTAA_NOT_MEMBER,	/* 401 Unauthorized, not authorized	*/
    HTAA_IP_MASK,	/* 403 Forbidden by IP mask		*/
    HTAA_IP_MASK_PROXY,	/* 403 Forbidden by IP mask on proxy	*/
    HTAA_BY_RULE,	/* 403 Forbidden by rule		*/
    HTAA_NO_ACL,	/* 403 Forbidden, ACL non-existent	*/
    HTAA_NO_ENTRY,	/* 403 Forbidden, no ACL entry		*/
    HTAA_SETUP_ERROR,	/* 403 Forbidden, server setup error	*/
    HTAA_DOTDOT,	/* 403 Forbidden, URL with /../ illegal	*/
    HTAA_HTBIN,		/* 403 Forbidden, /htbin not enabled	*/
    HTAA_INVALID_REDIRECT,
			/* 403 Forbidden, bad redirection setup */
    HTAA_INVALID_USER,	/* 403 Forbidden, bad user directory	*/
    HTAA_NOT_ALLOWED,	/* 403 Forbidden, dangerous method must	*/
			/*		  be explicitly allowed	*/
    HTAA_NOT_FOUND,	/* 404 Not found, or read protected	*/
    HTAA_MULTI_FAILED	/* 404 No suitable presentation found	*/
} HTAAFailReason;

Authentication Scheme Registration

Registering an autentication scheme involes the following parts:
scheme
The name of the scheme which is used to identify the scheme, for example as the <scheme> part of the WWW-authenticate HTTP header.
parser
Each scheme must have a parser callback function that can parse and interpret either the challenge sent by a server application or the credentials sent by the client to see whether they can be fulfilled or not. In the case of a client, the parser is called each time a request did not optain authorization to access the resource. The parser should then parse the challenge and store it so that we know what we must fulfill if a new request is issued. If the app is a server then the parser should validate that the credentails are sufficent for accessing the resource.
generator
A scheme must also have a generator callback function that can be called to generate a valid challenge or credentials to be sent to the other part. If a new request is issued and we have a challenge for this request then the generator should make sure that we get the right credentials. This can for example be by asking the user for a user name a and password. In the case of a server, the generator should generate a challenge that must be answered in order to access the resource.
garbage collection
The authentication information base has to be able to delete authentication information but as it doesn't know the format of the scheme specific parts, you must register a garbage collector which also is a callback function. The info base manager then calls this function each time authentication information is either being deleted or updated.
The request object has two hooks for the access authentication handler: challenge and credentials.. Both are association lists but the format is completely for the parser and the generator callback functions to manage. By using callback functions for parsing and generating valid authentication/authorization information, this module is independent of each scheme and hence allows for highly different schemes.

Callback Functions

The types for the parser and generator callback functions are symmetric in that the parser expects an association list of unparsed data and returns a scheme dependent data object to be added to the authentication information base. The callback functions are made so that they can be used both on client side and on server side. The scheme parameter is to tell the current authentication scheme. That way, the same callback functions can be for multiple schemes if needed.
typedef BOOL HTAuthParCallback	(HTRequest *	request,
				 const char *	scheme);

typedef BOOL HTAuthGenCallback	(HTRequest *	request,
				 const char *	scheme,
				 char *		realm,
				 void *		data);

typedef BOOL HTAuthGcCallback	(const char *	scheme,
				 void *		data);

Add an Authentication Scheme

You can add an authentication scheme by using the following method. Each of the callback function must have the type as defined below.
extern BOOL HTAuthCall_add	(const char *		scheme,
				 HTAuthParCallback *	parser,
				 HTAuthGenCallback *	generator,
				 HTAuthGcCallback *	gc);

Delete an Authentication Scheme

Likewise, you can delete an authentication scheme:
extern BOOL HTAuthCall_delete (const char * scheme);
extern BOOL HTAuthCall_deleteAll (void);

Generating Calls to callback functions

Call An authentication Scheme Parser

This function looks for a authentication scheme that matches what we have in the request object and calls the parser callback function. Case is not significant. Return YES or whatever callback returns
extern BOOL HTAuth_parse (HTRequest * request);

Call An authentication Scheme Generator

This function looks for a any authentication scheme that protects this resource and calls the generator callback in order to make a challenge or credentials. Return YES or whatever callback returns
extern BOOL HTAuth_generate (HTRequest * request);

Call An authentication Scheme Garbage Collector

This function looks for a authentication scheme that matches what we have in the request object and calls the cleanup callback function. Case is not significant. Return YES if callback found else NO
extern BOOL HTAuth_cleanup (const char * scheme, void * data);

Authentication Information Databases

The authentication information is stored in a database managed by this module. In the current implementation, a database is a list of sub-authentication databases, each uniquely identified by a hostname and a port number. Each database contains a set of templates which can be used to predict what information to use in a hierarchical tree. All authentication dependent information is stored as opaque data in a node referenced by a realm and a URL template.

Normally applications would only keep one auth base but if it wants different protection setup as a function of different interfaces then it can have one auth base representing each interface.

Server applications can have different authentication setups for each hostname and port number they control. For example, a server with interfaces "www.foo.com" and "internal.foo.com" can have different protection setups for each interface.

Add information to the Database

Add an access authentication information node to the database. If the entry is already found then it is replaced with the new one. The template must follow normal URI syntax but can include a wildcard Return YES if added (or replaced), else NO
extern BOOL HTAuthInfo_add (const char * scheme, char * url,
			    char * realm, void * data);

Delete the Database

extern BOOL HTAuthInfo_deleteAll (void);
#endif	/* NOT HTAAUTIL_H */

@(#) $Id: HTAAUtil.html,v 2.30 1996/04/12 17:45:29 frystyk Exp $