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