Annotation of libwww/Library/src/HTAAUtil.c, revision 2.23

2.23    ! frystyk     1: /*
2.9       frystyk     2: **     COMMON PARTS OF ACCESS AUTHORIZATION MODULE
                      3: **     FOR BOTH SERVER AND BROWSER
                      4: **
2.13      frystyk     5: **     (c) COPYRIGHT MIT 1995.
2.9       frystyk     6: **     Please first read the full copyright statement in the file COPYRIGH.
2.23    ! frystyk     7: **     @(#) $Id: HTAAUtil.c,v 2.22 1996/06/28 16:30:46 frystyk Exp $
2.1       luotonen    8: **
2.19      frystyk     9: **     The authentication information is stored in a list of authentication
                     10: **     data bases, each uniquely identified by a hostname and a port number.
                     11: **     Each data base contains a set of templates which can be used to predict
                     12: **     what information to use in a hierarchical tree. All authentication
                     13: **     dependent information is stored as opaque data in a anode. Normally
                     14: **     a server application would only keep one auth base but if it wants
                     15: **     different protection setup as a function of different interfaces then
                     16: **     it can have one auth base representing each interface. For example a
                     17: **     server with interfaces "www.foo.com" and "internal.foo.com" can have
                     18: **     different protection setups for each interface.
2.1       luotonen   19: **
                     20: ** AUTHORS:
                     21: **     AL      Ari Luotonen    luotonen@dxcern.cern.ch
2.3       duns       22: **     MD      Mark Donszelmann    duns@vxdeop.cern.ch
2.19      frystyk    23: **     HFN     Henrik Frystyk
2.1       luotonen   24: **
                     25: ** HISTORY:
2.4       luotonen   26: **      8 Nov 93  MD   (VMS only) Added case insensitive comparison
                     27: **                     in HTAA_templateCaseMatch
2.1       luotonen   28: */
                     29: 
2.11      frystyk    30: /* Library include files */
2.20      frystyk    31: #include "sysdep.h"
2.23    ! frystyk    32: #include "WWWUtil.h"
        !            33: #include "WWWCore.h"
2.19      frystyk    34: #include "HTAAUtil.h"                                   /* Implemented here */
                     35: 
2.23    ! frystyk    36: #define AA_NAME                        "w3c-AA"              /* Name of the AA tree */
        !            37: #define DEFAULT_PORT            80                    /* Concentrate on HTTP */
        !            38: 
        !            39: struct _HTAAModule {
2.19      frystyk    40:     char *             scheme;
2.23    ! frystyk    41:     HTNetCallback *    before;
        !            42:     HTNetCallback *    after;
        !            43:     HTUTree_gc *       gc;
        !            44: };
        !            45: 
        !            46: typedef struct _HTAAElement {
        !            47:     char *             scheme;
        !            48:     void *             context;
        !            49: } HTAAElement;
2.19      frystyk    50: 
                     51: PRIVATE HTList * HTSchemes;    /* List of registered authentication schemes */
                     52: 
                     53: /* ------------------------------------------------------------------------- */
2.23    ! frystyk    54: /*                      AUTHENTICATION MODULE MANAGEMENT                    */
2.19      frystyk    55: /* ------------------------------------------------------------------------- */
                     56: 
2.23    ! frystyk    57: PRIVATE BOOL delete_module (HTAAModule * module)
2.19      frystyk    58: {
2.23    ! frystyk    59:     if (module) {
        !            60:        HT_FREE(module->scheme);
        !            61:        HT_FREE(module);
        !            62:        return YES;
2.19      frystyk    63:     }
                     64:     return NO;
                     65: }
2.1       luotonen   66: 
2.23    ! frystyk    67: PRIVATE HTAAModule * find_module (const char * scheme)
2.19      frystyk    68: {
2.23    ! frystyk    69:     if (!HTSchemes) HTSchemes = HTList_new();
        !            70:     if (scheme) {
        !            71:        HTList * cur = HTSchemes;
        !            72:        HTAAModule * pres = NULL;
        !            73:        while ((pres = (HTAAModule *) HTList_nextObject(cur)))
        !            74:            if (!strcasecomp(pres->scheme, scheme)) return pres;
        !            75:     } else
        !            76:        if (AUTH_TRACE) HTTrace("Auth Engine. Bad argument\n");
        !            77:     return NULL;
2.19      frystyk    78: }
2.1       luotonen   79: 
2.23    ! frystyk    80: PUBLIC HTAAModule * HTAA_newModule (const char *       scheme,
        !            81:                                    HTNetCallback *     before,
        !            82:                                    HTNetCallback *     after,
        !            83:                                    HTUTree_gc *        gc)
        !            84: {
        !            85:     if (scheme) {
        !            86:        HTAAModule * pres = find_module(scheme);
        !            87: 
        !            88:        /* If found then update entry - else create a new one */
        !            89:        if (!pres) {
        !            90:            if (!(pres = (HTAAModule *) HT_CALLOC(1, sizeof(HTAAModule))))
        !            91:                HT_OUTOFMEM("HTAA_newModule");
        !            92:            StrAllocCopy(pres->scheme, scheme);
        !            93:            pres->before = before;
        !            94:            pres->after = after;
        !            95:            pres->gc = gc;
        !            96: 
        !            97:            /* Add the new AA Module to the list */
        !            98:            HTList_addObject(HTSchemes, (void *) pres);
        !            99:            if (AUTH_TRACE) HTTrace("Auth Engine. Created module %p\n", pres);
        !           100:        } else {
        !           101:            if (AUTH_TRACE) HTTrace("Auth Engine. Found module %p\n", pres);
2.19      frystyk   102:        }
2.23    ! frystyk   103:        return pres;
        !           104:     } else {
        !           105:        if (AUTH_TRACE) HTTrace("Auth Engine. Bad argument\n");
        !           106:        return NULL;
2.19      frystyk   107:     }
                    108: }
2.1       luotonen  109: 
2.23    ! frystyk   110: PUBLIC HTAAModule * HTAA_findModule (const char * scheme)
2.19      frystyk   111: {
2.23    ! frystyk   112:     if (scheme) {
        !           113:        HTAAModule * pres = find_module(scheme);
        !           114:        if (AUTH_TRACE)
        !           115:            HTTrace("Auth Engine. did %sfind %s\n", pres ? "" : "NOT ",scheme);
        !           116:        return pres;
        !           117:     } else {
        !           118:        if (AUTH_TRACE) HTTrace("Auth Engine. Bad augument\n");
2.19      frystyk   119:     }
                    120:     return NULL;
                    121: }
2.1       luotonen  122: 
2.23    ! frystyk   123: PUBLIC BOOL HTAA_deleteModule (const char * scheme)
2.19      frystyk   124: {
2.23    ! frystyk   125:     if (scheme) {
        !           126:        HTAAModule * pres = find_module(scheme);
        !           127:        if (pres) {
        !           128:            HTList_removeObject(HTSchemes, pres);
        !           129:            if (AUTH_TRACE) HTTrace("Auth Engine. deleted %p\n", pres);
        !           130:            delete_module(pres);
        !           131:            return YES;
        !           132:        }
2.1       luotonen  133:     }
2.19      frystyk   134:     return NO;
2.1       luotonen  135: }
                    136: 
2.23    ! frystyk   137: PUBLIC BOOL HTAA_deleteAllModules (void)
2.19      frystyk   138: {
2.23    ! frystyk   139:     if (HTSchemes) {
        !           140:        HTList * cur = HTSchemes;
        !           141:        HTAAModule * pres;
        !           142:        while ((pres = (HTAAModule *) HTList_nextObject(cur)))
        !           143:            delete_module(pres);
        !           144:        HTList_delete(HTSchemes);
        !           145:        HTSchemes = NULL;
2.19      frystyk   146:        return YES;
                    147:     }
                    148:     return NO;
                    149: }
2.1       luotonen  150: 
2.23    ! frystyk   151: /* ------------------------------------------------------------------------- */
        !           152: /*                         HANDLE THE AA URL TREE                           */
        !           153: /* ------------------------------------------------------------------------- */
        !           154: 
2.19      frystyk   155: /*
2.23    ! frystyk   156: **     A AA element is a particular AA procotol associated with a
        !           157: **     particular point in the URL tree. The scheme is the name of the
        !           158: **     AA protocol known to be able to handle this context. This protocol
        !           159: **     must have been registered as a AA module.
        !           160: */
        !           161: PRIVATE HTAAElement * HTAA_newElement (const char * scheme, void * context)
        !           162: {
        !           163:     if (scheme) {
        !           164:        HTAAElement * me;
        !           165:        if ((me = (HTAAElement *) HT_CALLOC(1, sizeof(HTAAElement))) == NULL)
        !           166:            HT_OUTOFMEM("HTAAElement_new");
        !           167:        StrAllocCopy(me->scheme, scheme);
        !           168:        me->context = context;
        !           169:        if (AUTH_TRACE) HTTrace("Auth Engine. Created element %p\n", me);
        !           170:        return me;
2.19      frystyk   171:     }
                    172:     return NULL;
                    173: }
2.1       luotonen  174: 
2.23    ! frystyk   175: PRIVATE BOOL HTAA_updateElement (HTAAElement * element,
        !           176:                                 const char * scheme, void * context)
2.19      frystyk   177: {
2.23    ! frystyk   178:     if (element && scheme) {
        !           179:        StrAllocCopy(element->scheme, scheme);
        !           180:        element->context = context;
        !           181:        return YES;
2.19      frystyk   182:     }
                    183:     return NO;
                    184: }
2.1       luotonen  185: 
2.23    ! frystyk   186: PRIVATE int HTAA_deleteElement (void * context)
2.19      frystyk   187: {
2.23    ! frystyk   188:     HTAAElement * me = (HTAAElement *) context;
        !           189:     if (me) {
        !           190:        HTAAModule * module = HTAA_findModule(me->scheme);
2.1       luotonen  191: 
2.23    ! frystyk   192:        /* If module then call the gc of the Authentication Module */
        !           193:        if (module && module->gc && me->context)
        !           194:            (*module->gc)(me->context);
2.1       luotonen  195: 
2.23    ! frystyk   196:        if (AUTH_TRACE) HTTrace("Auth Engine. Deleted element %p\n", me);
        !           197:        HT_FREE(me->scheme);
        !           198:        HT_FREE(me);
2.19      frystyk   199:        return YES;
                    200:     }
                    201:     return NO;
                    202: }
2.1       luotonen  203: 
                    204: /*
2.23    ! frystyk   205: **     Find AA Element
        !           206: **     ---------------
        !           207: **     Seaches the set of authentication information bases for a match
        !           208: **     In order to find an anode we do the following:
        !           209: **
        !           210: **             1) Find the right auth base
        !           211: **             2) See if there is a realm match
        !           212: **             3) See if there is a template match for URL
        !           213: **
        !           214: **     Return the node found else NULL which means that we don't have any
        !           215: **     authentication information to hook on to this request or response
2.1       luotonen  216: */
2.23    ! frystyk   217: PRIVATE HTAAElement * HTAA_findElement (const char * realm, const char * url)
2.19      frystyk   218: {
2.23    ! frystyk   219:     HTUTree * tree;
        !           220:     if (!url) {
        !           221:        if (AUTH_TRACE) HTTrace("Auth Engine. Bad argument\n");
        !           222:        return NULL;
2.19      frystyk   223:     }
2.23    ! frystyk   224:     if (AUTH_TRACE) HTTrace("Auth Engine. Looking up `%s'\n", url);
2.19      frystyk   225: 
2.23    ! frystyk   226:     /* Find an existing URL Tree for this URL (if any) */
2.19      frystyk   227:     {
                    228:        char * host = HTParse(url, "", PARSE_HOST);
                    229:        char * colon = strchr(host, ':');
2.23    ! frystyk   230:        int port = DEFAULT_PORT;
2.19      frystyk   231:        if (colon ) {
                    232:            *(colon++) = '\0';                       /* Chop off port number */
                    233:            port = atoi(colon);
2.23    ! frystyk   234:        }       
        !           235:        tree = HTUTree_find(AA_NAME, host, port);
        !           236:        HT_FREE(host);
        !           237:        if (!tree) {
        !           238:            if (AUTH_TRACE) HTTrace("Auth Engine. No information\n");
        !           239:            return NULL;
2.19      frystyk   240:        }
                    241:     }
2.1       luotonen  242: 
2.23    ! frystyk   243:     /* Find a matching AA element (if any) */
2.19      frystyk   244:     {
2.23    ! frystyk   245:        char * path = HTParse(url, "", PARSE_PATH);
        !           246:        HTAAElement *element = (HTAAElement*)HTUTree_findNode(tree,realm,path);
        !           247:        HT_FREE(path);
        !           248:        return element;
2.19      frystyk   249:     }
2.23    ! frystyk   250:     return NULL;
2.19      frystyk   251: }
                    252: 
2.23    ! frystyk   253: /*     Add a AA context to the URL tree
        !           254: **     --------------------------------
        !           255: **     Each node in the AA URL tree is a list of the modules we must call
        !           256: **     for this particular node.
        !           257: */
        !           258: PUBLIC BOOL HTAA_addNode (char const * scheme,
        !           259:                          const char * realm, const char * url, void * context)
        !           260: {
        !           261:     HTUTree * tree = NULL;
        !           262:     HTAAModule * module = NULL;
        !           263:     if (!scheme || !url) {
        !           264:        if (AUTH_TRACE) HTTrace("Auth Engine. Bad argument\n");
        !           265:        return NO;
        !           266:     }
        !           267:     if (AUTH_TRACE) HTTrace("Auth Engine. Adding info for `%s'\n", url);
        !           268: 
        !           269:     /* Find the AA module with this name */
        !           270:     if ((module = HTAA_findModule(scheme)) == NULL) {
        !           271:        if (AUTH_TRACE) HTTrace("Auth Engine. Module `%s\' not registered\n",
        !           272:                               scheme ? scheme : "<null>");
        !           273:        return NO;
2.19      frystyk   274:     }
                    275: 
2.23    ! frystyk   276:     /* Find an existing URL Tree or create a new one */
2.19      frystyk   277:     {
                    278:        char * host = HTParse(url, "", PARSE_HOST);
                    279:        char * colon = strchr(host, ':');
2.23    ! frystyk   280:        int port = DEFAULT_PORT;
2.19      frystyk   281:        if (colon ) {
                    282:            *(colon++) = '\0';                       /* Chop off port number */
                    283:            port = atoi(colon);
2.23    ! frystyk   284:        }
        !           285:        tree = HTUTree_new(AA_NAME, host, port, HTAA_deleteElement);
2.19      frystyk   286:        HT_FREE(host);
2.23    ! frystyk   287:        if (!tree) {
        !           288:            if (AUTH_TRACE) HTTrace("Auth Engine. Can't create tree\n");
        !           289:            return NO;
2.19      frystyk   290:        }
                    291:     }
                    292: 
2.23    ! frystyk   293:     /* Find a matching AA element or create a new one */
2.19      frystyk   294:     {
2.23    ! frystyk   295:        char * path = HTParse(url, "", PARSE_PATH);
        !           296:        HTAAElement * element = NULL;
        !           297:        BOOL status;
        !           298:        if ((element = (HTAAElement *) HTUTree_findNode(tree, realm, path)))
        !           299:            status = HTAA_updateElement(element, scheme, context);
        !           300:        else {
        !           301:            element = HTAA_newElement(scheme, context);
        !           302:            status = HTUTree_addNode(tree, realm, path, element);
        !           303:        }
        !           304:        HT_FREE(path);
        !           305:        return status;
2.19      frystyk   306:     }
                    307: }
                    308: 
                    309: /* ------------------------------------------------------------------------- */
2.23    ! frystyk   310: /*                            AUTHENTICATION ENGINE                         */
2.19      frystyk   311: /* ------------------------------------------------------------------------- */
                    312: 
2.23    ! frystyk   313: /*     HTAA_beforeFilter
        !           314: **     ------------------
        !           315: **     Return HT_OK or whatever callback returns
2.19      frystyk   316: */
2.23    ! frystyk   317: PUBLIC int HTAA_beforeFilter (HTRequest * request, void * param, int status)
2.19      frystyk   318: {
2.23    ! frystyk   319:     char * url = HTAnchor_physical(HTRequest_anchor(request));
        !           320:     const char * realm = HTRequest_realm(request);
        !           321:     HTAAElement * element = HTAA_findElement(realm, url); 
        !           322: 
        !           323:     /* Delete any old credentials if any */
        !           324:     if (element) {
        !           325:        HTAAModule * module = HTAA_findModule(element->scheme);
        !           326:        HTRequest_deleteChallenge(request);
        !           327:        if (module) {
        !           328:            if (AUTH_TRACE) HTTrace("Auth Engine. Found BEFORE filter %p\n",
        !           329:                                   module->before);
        !           330:            return (*module->before)(request, element->context,status);
2.19      frystyk   331:        }
                    332:     }
2.23    ! frystyk   333:     return HT_OK;
2.19      frystyk   334: }
                    335: 
2.23    ! frystyk   336: /*     HTAA_afterFilter
        !           337: **     -----------------
2.19      frystyk   338: **     Return YES or whatever callback returns
                    339: */
2.23    ! frystyk   340: PUBLIC BOOL HTAA_afterFilter (HTRequest * request, void * param, int status)
2.19      frystyk   341: {
2.23    ! frystyk   342:     const char * scheme = HTRequest_scheme(request);
        !           343:     HTAAModule * module = HTAA_findModule(scheme);
        !           344:     if (module) {
        !           345:        if (AUTH_TRACE)
        !           346:            HTTrace("Auth Engine. Found AFTER filter %p\n", module->after);
        !           347:        return (*module->after)(request, NULL, status);
2.19      frystyk   348:     }
2.23    ! frystyk   349:     return HT_OK;
2.19      frystyk   350: }
2.1       luotonen  351: 

Webmaster