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

2.9       frystyk     1: /*                                                                  HTAAUtil.c
                      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.1       luotonen    7: **
                      8: ** IMPORTANT:
                      9: **     Routines in this module use dynamic allocation, but free
                     10: **     automatically all the memory reserved by them.
                     11: **
                     12: **     Therefore the caller never has to (and never should)
                     13: **     free() any object returned by these functions.
                     14: **
                     15: **     Therefore also all the strings returned by this package
                     16: **     are only valid until the next call to the same function
                     17: **     is made. This approach is selected, because of the nature
                     18: **     of access authorization: no string returned by the package
                     19: **     needs to be valid longer than until the next call.
                     20: **
                     21: **     This also makes it easy to plug the AA package in:
                     22: **     you don't have to ponder whether to free() something
                     23: **     here or is it done somewhere else (because it is always
                     24: **     done somewhere else).
                     25: **
                     26: **     The strings that the package needs to store are copied
                     27: **     so the original strings given as parameters to AA
                     28: **     functions may be freed or modified with no side effects.
                     29: **
                     30: **     The AA package does not free() anything else than what
                     31: **     it has itself allocated.
                     32: **
                     33: **     AA (Access Authorization) package means modules which
                     34: **     names start with HTAA.
                     35: **
                     36: ** AUTHORS:
                     37: **     AL      Ari Luotonen    luotonen@dxcern.cern.ch
2.3       duns       38: **     MD      Mark Donszelmann    duns@vxdeop.cern.ch
2.1       luotonen   39: **
                     40: ** HISTORY:
2.4       luotonen   41: **      8 Nov 93  MD   (VMS only) Added case insensitive comparison
                     42: **                     in HTAA_templateCaseMatch
2.1       luotonen   43: **
                     44: **
                     45: ** BUGS:
                     46: **
                     47: **
                     48: */
                     49: 
2.11      frystyk    50: /* Library include files */
                     51: #include "tcp.h"
2.1       luotonen   52: #include "HTUtils.h"
2.11      frystyk    53: #include "HTString.h"
2.1       luotonen   54: #include "HTAAUtil.h"  /* Implemented here     */
                     55: #include "HTAssoc.h"   /* Assoc list           */
                     56: 
                     57: 
                     58: /* PUBLIC                                              HTAAScheme_enum()
                     59: **             TRANSLATE SCHEME NAME INTO
                     60: **             A SCHEME ENUMERATION
                     61: **
                     62: ** ON ENTRY:
                     63: **     name            is a string representing the scheme name.
                     64: **
                     65: ** ON EXIT:
                     66: **     returns         the enumerated constant for that scheme.
                     67: */
2.16    ! frystyk    68: PUBLIC HTAAScheme HTAAScheme_enum (CONST char* name)
2.1       luotonen   69: {
                     70:     static char *upcased = NULL;
                     71:     char *cur;
                     72: 
                     73:     if (!name) return HTAA_UNKNOWN;
                     74: 
                     75:     StrAllocCopy(upcased, name);
                     76:     cur = upcased;
                     77:     while (*cur) {
                     78:        *cur = TOUPPER(*cur);
                     79:        cur++;
                     80:     }
                     81:     
2.4       luotonen   82:     if      (!strncmp(upcased, "NONE", 4))        return HTAA_NONE;
                     83:     else if (!strncmp(upcased, "BASIC", 5))       return HTAA_BASIC;
                     84:     else if (!strncmp(upcased, "PUBKEY", 6))      return HTAA_PUBKEY;
                     85:     else if (!strncmp(upcased, "KERBEROSV4", 10))  return HTAA_KERBEROS_V4;
                     86:     else if (!strncmp(upcased, "KERBEROSV5", 10))  return HTAA_KERBEROS_V5;
                     87:     else                                          return HTAA_UNKNOWN;
2.1       luotonen   88: }
                     89: 
                     90: 
                     91: /* PUBLIC                                              HTAAScheme_name()
                     92: **                     GET THE NAME OF A GIVEN SCHEME
                     93: ** ON ENTRY:
                     94: **     scheme          is one of the scheme enum values:
                     95: **                     HTAA_NONE, HTAA_BASIC, HTAA_PUBKEY, ...
                     96: **
                     97: ** ON EXIT:
                     98: **     returns         the name of the scheme, i.e.
                     99: **                     "None", "Basic", "Pubkey", ...
                    100: */
2.16    ! frystyk   101: PUBLIC char *HTAAScheme_name (HTAAScheme scheme)
2.1       luotonen  102: {
                    103:     switch (scheme) {
                    104:       case HTAA_NONE:          return "None";          break;
                    105:       case HTAA_BASIC:         return "Basic";         break;
                    106:       case HTAA_PUBKEY:                return "Pubkey";        break;
                    107:       case HTAA_KERBEROS_V4:   return "KerberosV4";    break;
                    108:       case HTAA_KERBEROS_V5:   return "KerberosV5";    break;
                    109:       case HTAA_UNKNOWN:       return "UNKNOWN";       break;
                    110:       default:                 return "THIS-IS-A-BUG";
                    111:     }
                    112: }
                    113: 
                    114: 
                    115: 
                    116: /* PUBLIC                                              HTAA_templateMatch()
                    117: **             STRING COMPARISON FUNCTION FOR FILE NAMES
                    118: **                WITH ONE WILDCARD * IN THE TEMPLATE
                    119: ** NOTE:
                    120: **     This is essentially the same code as in HTRules.c, but it
                    121: **     cannot be used because it is embedded in between other code.
                    122: **     (In fact, HTRules.c should use this routine, but then this
                    123: **      routine would have to be more sophisticated... why is life
                    124: **      sometimes so hard...)
                    125: **
                    126: ** ON ENTRY:
                    127: **     template        is a template string to match the file name
                    128: **                     agaist, may contain a single wildcard
                    129: **                     character * which matches zero or more
                    130: **                     arbitrary characters.
                    131: **     filename        is the filename (or pathname) to be matched
                    132: **                     agaist the template.
                    133: **
                    134: ** ON EXIT:
                    135: **     returns         YES, if filename matches the template.
                    136: **                     NO, otherwise.
                    137: */
2.16    ! frystyk   138: PUBLIC BOOL HTAA_templateMatch (CONST char * tmplate, 
        !           139:                                     CONST char * filename)
2.1       luotonen  140: {
2.8       frystyk   141:     CONST char *p = tmplate;
2.1       luotonen  142:     CONST char *q = filename;
                    143:     int m;
                    144: 
2.8       frystyk   145:     if (!tmplate || !filename) {
2.14      frystyk   146:        if (PROT_TRACE)
2.15      frystyk   147:            TTYPrint(TDEST, "HTAA_templateMatch: invalid param: %s is NULL!!\n",
2.14      frystyk   148:                    (tmplate ? "filename" : "template"));
2.4       luotonen  149:        return NO;
                    150:     }
                    151: 
2.1       luotonen  152:     for( ; *p  &&  *q  &&  *p == *q; p++, q++) /* Find first mismatch */
                    153:        ; /* do nothing else */
2.3       duns      154: 
2.1       luotonen  155:     if (!*p && !*q)    return YES;     /* Equally long equal strings */
                    156:     else if ('*' == *p) {              /* Wildcard */
                    157:        p++;                            /* Skip wildcard character */
                    158:        m = strlen(q) - strlen(p);      /* Amount to match to wildcard */
                    159:        if (m < 0) return NO;           /* No match, filename too short */
                    160:        else {                  /* Skip the matched characters and compare */
                    161:            if (strcmp(p, q+m)) return NO;      /* Tail mismatch */
                    162:            else                return YES;     /* Tail match */
                    163:        }
                    164:     }  /* if wildcard */
                    165:     else               return NO;      /* Length or character mismatch */
2.3       duns      166: }    
                    167: 
                    168: 
2.4       luotonen  169: /* PUBLIC                                      HTAA_templateCaseMatch()
2.3       duns      170: **             STRING COMPARISON FUNCTION FOR FILE NAMES
2.4       luotonen  171: **        WITH ONE WILDCARD * IN THE TEMPLATE (Case Insensitive)
2.3       duns      172: ** NOTE:
                    173: **     This is essentially the same code as in HTAA_templateMatch, but
                    174: **     it compares case insensitive (for VMS). Reason for this routine
                    175: **     is that HTAA_templateMatch gets called from several places, also 
                    176: **     there where a case sensitive match is needed, so one cannot just
                    177: **     change the HTAA_templateMatch routine for VMS.
                    178: **
                    179: ** ON ENTRY:
2.8       frystyk   180: **     tmplate         is a template string to match the file name
2.3       duns      181: **                     agaist, may contain a single wildcard
                    182: **                     character * which matches zero or more
                    183: **                     arbitrary characters.
                    184: **     filename        is the filename (or pathname) to be matched
                    185: **                     agaist the template.
                    186: **
                    187: ** ON EXIT:
                    188: **     returns         YES, if filename matches the template.
                    189: **                     NO, otherwise.
                    190: */
2.16    ! frystyk   191: PUBLIC BOOL HTAA_templateCaseMatch (CONST char * tmplate, 
        !           192:                                         CONST char * filename)
2.3       duns      193: {
2.8       frystyk   194:     CONST char *p = tmplate;
2.3       duns      195:     CONST char *q = filename;
                    196:     int m;
                    197: 
2.8       frystyk   198:     if (!tmplate || !filename) {
2.14      frystyk   199:        if (PROT_TRACE)
2.15      frystyk   200:            TTYPrint(TDEST,
2.14      frystyk   201:                    "HTAA_templateCaseMatch: invalid param: %s is NULL!!\n",
                    202:                    (tmplate ? "filename" : "template"));
2.4       luotonen  203:        return NO;
                    204:     }
                    205: 
2.12      frystyk   206:     for( ; *p  &&  *q  &&  TOUPPER(*p) == TOUPPER(*q); p++, q++) /* Find first mismatch */
2.3       duns      207:        ; /* do nothing else */
                    208: 
                    209:     if (!*p && !*q)    return YES;     /* Equally long equal strings */
                    210:     else if ('*' == *p) {              /* Wildcard */
                    211:        p++;                            /* Skip wildcard character */
                    212:        m = strlen(q) - strlen(p);      /* Amount to match to wildcard */
                    213:        if (m < 0) return NO;           /* No match, filename too short */
                    214:        else {                  /* Skip the matched characters and compare */
                    215:            if (strcasecomp(p, q+m))    return NO;      /* Tail mismatch */
                    216:            else                return YES;     /* Tail match */
                    217:        }
                    218:     }  /* if wildcard */
                    219:     else               return NO;      /* Length or character mismatch */
                    220: }    
2.1       luotonen  221: 
                    222: 
                    223: /* PUBLIC                                      HTAA_makeProtectionTemplate()
                    224: **             CREATE A PROTECTION TEMPLATE FOR THE FILES
                    225: **             IN THE SAME DIRECTORY AS THE GIVEN FILE
                    226: **             (Used by server if there is no fancier way for
                    227: **             it to tell the client, and by browser if server
                    228: **             didn't send WWW-ProtectionTemplate: field)
                    229: ** ON ENTRY:
                    230: **     docname is the document pathname (from URL).
                    231: **
                    232: ** ON EXIT:
                    233: **     returns a template matching docname, and other files
                    234: **             files in that directory.
                    235: **
                    236: **             E.g.  /foo/bar/x.html  =>  /foo/bar/ *
                    237: **                                                 ^
                    238: **                             Space only to prevent it from
                    239: **                             being a comment marker here,
                    240: **                             there really isn't any space.
                    241: */
2.16    ! frystyk   242: PUBLIC char *HTAA_makeProtectionTemplate (CONST char * docname)
2.1       luotonen  243: {
2.8       frystyk   244:     char *tmplate = NULL;
2.1       luotonen  245:     char *slash = NULL;
                    246: 
                    247:     if (docname) {
2.8       frystyk   248:        StrAllocCopy(tmplate, docname);
                    249:        slash = strrchr(tmplate, '/');
2.1       luotonen  250:        if (slash) slash++;
2.8       frystyk   251:        else slash = tmplate;
2.2       luotonen  252:        *slash = (char)0;
2.8       frystyk   253:        StrAllocCat(tmplate, "*");
2.1       luotonen  254:     }
2.8       frystyk   255:     else StrAllocCopy(tmplate, "*");
2.1       luotonen  256: 
2.14      frystyk   257:     if (PROT_TRACE)
2.15      frystyk   258:        TTYPrint(TDEST, "make_template: made template `%s' for file `%s'\n",
2.14      frystyk   259:                tmplate, docname);
2.1       luotonen  260: 
2.8       frystyk   261:     return tmplate;
2.1       luotonen  262: }
                    263: 
                    264: 
                    265: 
                    266: 
                    267: /*
                    268: ** Skip leading whitespace from *s forward
                    269: */
                    270: #define SKIPWS(s) while (*s==' ' || *s=='\t') s++;
                    271: 
                    272: /*
                    273: ** Kill trailing whitespace starting from *(s-1) backwords
                    274: */
2.2       luotonen  275: #define KILLWS(s) {char *c=s-1; while (*c==' ' || *c=='\t') *(c--)=(char)0;}
2.1       luotonen  276: 
                    277: 
                    278: /* PUBLIC                                              HTAA_parseArgList()
                    279: **             PARSE AN ARGUMENT LIST GIVEN IN A HEADER FIELD
                    280: ** ON ENTRY:
                    281: **     str     is a comma-separated list:
                    282: **
                    283: **                     item, item, item
                    284: **             where
                    285: **                     item ::= value
                    286: **                            | name=value
                    287: **                            | name="value"
                    288: **
                    289: **             Leading and trailing whitespace is ignored
                    290: **             everywhere except inside quotes, so the following
                    291: **             examples are equal:
                    292: **
                    293: **                     name=value,foo=bar
                    294: **                      name="value",foo="bar"
                    295: **                       name = value ,  foo = bar
                    296: **                        name = "value" ,  foo = "bar"
                    297: **
                    298: ** ON EXIT:
                    299: **     returns a list of name-value pairs (actually HTAssocList*).
                    300: **             For items with no name, just value, the name is
                    301: **             the number of order number of that item. E.g.
                    302: **             "1" for the first, etc.
                    303: */
2.16    ! frystyk   304: PUBLIC HTAssocList *HTAA_parseArgList (char * str)
2.1       luotonen  305: {
                    306:     HTAssocList *assoc_list = HTAssocList_new();
                    307:     char *cur = NULL;
                    308:     char *name = NULL;
                    309:     int index = 0;
                    310: 
                    311:     if (!str) return assoc_list;
                    312: 
                    313:     while (*str) {
                    314:        SKIPWS(str);                            /* Skip leading whitespace */
                    315:        cur = str;
                    316:        index++;
                    317: 
                    318:        while (*cur  &&  *cur != '='  &&  *cur != ',')
                    319:            cur++;      /* Find end of name (or lonely value without a name) */
                    320:        KILLWS(cur);    /* Kill trailing whitespace */
                    321: 
                    322:        if (*cur == '=') {                      /* Name followed by a value */
2.2       luotonen  323:            *(cur++) = (char)0;                 /* Terminate name */
2.1       luotonen  324:            StrAllocCopy(name, str);
                    325:            SKIPWS(cur);                        /* Skip WS leading the value */
                    326:            str = cur;
                    327:            if (*str == '"') {                  /* Quoted value */
                    328:                str++;
                    329:                cur = str;
                    330:                while (*cur  &&  *cur != '"') cur++;
                    331:                if (*cur == '"')
2.2       luotonen  332:                    *(cur++) = (char)0; /* Terminate value */
2.1       luotonen  333:                /* else it is lacking terminating quote */
                    334:                SKIPWS(cur);                    /* Skip WS leading comma */
                    335:                if (*cur == ',') cur++;         /* Skip separating colon */
                    336:            }
                    337:            else {                              /* Unquoted value */
                    338:                while (*cur  &&  *cur != ',') cur++;
                    339:                KILLWS(cur);                    /* Kill trailing whitespace */
                    340:                if (*cur == ',')
2.2       luotonen  341:                    *(cur++) = (char)0;
2.1       luotonen  342:                /* else *cur already NULL */
                    343:            }
                    344:        }
                    345:        else {  /* No name, just a value */
                    346:            if (*cur == ',') 
2.2       luotonen  347:                *(cur++) = (char)0;             /* Terminate value */
2.1       luotonen  348:            /* else last value on line (already terminated by NULL) */
                    349:            StrAllocCopy(name, "nnn");  /* Room for item order number */
                    350:            sprintf(name, "%d", index); /* Item order number for name */
                    351:        }
                    352:        HTAssocList_add(assoc_list, name, str);
                    353:        str = cur;
                    354:     } /* while *str */
2.6       frystyk   355:     FREE(name);                                                  /* Henrik 14/03-94 */
2.1       luotonen  356:     return assoc_list;
                    357: }
2.6       frystyk   358: 
                    359: 
                    360: 
                    361: 
                    362: 
2.1       luotonen  363: 

Webmaster