Annotation of libwww/Library/src/HTRules.c, revision 2.13

2.1       timbl       1: /*     Configuration manager for Hypertext Daemon              HTRules.c
                      2: **     ==========================================
                      3: **
                      4: **
                      5: ** History:
                      6: **      3 Jun 91       Written TBL
                      7: **     10 Aug 91       Authorisation added after Daniel Martin (pass, fail)
                      8: **                     Rule order in file changed
                      9: **                     Comments allowed with # on 1st char of rule line
                     10: **      17 Jun 92       Bug fix: pass and fail failed if didn't contain '*' TBL
2.9       secret     11: **       1 Sep 93       Bug fix: no memory check - Nathan Torkington
                     12: **                      BYTE_ADDRESSING removed - Arthur Secret
2.12      luotonen   13: **     11 Sep 93  MD   Changed %i into %d in debug printf. 
2.10      duns       14: **                     VMS does not recognize %i.
                     15: **                     Bug Fix: in case of PASS, only one parameter to printf.
2.12      luotonen   16: **     19 Sep 93  AL   Added Access Authorization stuff.
                     17: **      1 Nov 93  AL   Added htbin.
2.11      luotonen   18: **
2.1       timbl      19: */
                     20: 
                     21: /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
                     22: #include "HTRules.h"
                     23: 
                     24: #include <stdio.h>
                     25: #include "tcp.h"
                     26: #include "HTFile.h"
2.11      luotonen   27: #include "HTAAServ.h"  /* Access Authorization */
2.1       timbl      28: 
                     29: #define LINE_LENGTH 256
                     30: 
                     31: 
                     32: typedef struct _rule {
                     33:        struct _rule *  next;
                     34:        HTRuleOp        op;
                     35:        char *          pattern;
                     36:        char *          equiv;
                     37: } rule;
                     38: 
2.12      luotonen   39: /*     Global variables
                     40: **     ----------------
                     41: */
                     42: PUBLIC char *HTBinDir = NULL;  /* Physical /htbin directory path.      */
                     43:                                 /* In future this should not be global.        */
2.13    ! luotonen   44: PUBLIC char *HTSearchScript = NULL;    /* Search script name.          */
2.12      luotonen   45: 
2.13    ! luotonen   46: 
2.1       timbl      47: /*     Module-wide variables
                     48: **     ---------------------
                     49: */
                     50: 
                     51: PRIVATE rule * rules = 0;      /* Pointer to first on list */
                     52: #ifndef PUT_ON_HEAD
                     53: PRIVATE rule * rule_tail = 0;  /* Pointer to last on list */
                     54: #endif
                     55: 
2.11      luotonen   56: 
2.1       timbl      57: /*     Add rule to the list                                    HTAddRule()
                     58: **     --------------------
                     59: **
                     60: **  On entry,
                     61: **     pattern         points to 0-terminated string containing a single "*"
                     62: **     equiv           points to the equivalent string with * for the
                     63: **                     place where the text matched by * goes.
                     64: **  On exit,
                     65: **     returns         0 if success, -1 if error.
                     66: */
2.9       secret     67: 
2.1       timbl      68: #ifdef __STDC__
                     69: PUBLIC int HTAddRule (HTRuleOp op, const char * pattern, const char * equiv)
                     70: #else
                     71: int HTAddRule(op, pattern, equiv)
                     72:     HTRuleOp   op;
                     73:     char *     pattern;
                     74:     char *     equiv;
                     75: #endif
2.9       secret     76: { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
                     77:     rule *      temp;
                     78:     char *      pPattern;
                     79: 
                     80:     temp = (rule *)malloc(sizeof(*temp));
                     81:     if (temp==NULL) 
                     82:        outofmem(__FILE__, "HTAddRule"); 
                     83:     pPattern = (char *)malloc(strlen(pattern)+1);
                     84:     if (pPattern==NULL) 
                     85:        outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      86:     if (equiv) {               /* Two operands */
                     87:        char *  pEquiv = (char *)malloc(strlen(equiv)+1);
2.9       secret     88:        if (pEquiv==NULL) 
                     89:            outofmem(__FILE__, "HTAddRule"); 
2.1       timbl      90:         temp->equiv = pEquiv;
                     91:         strcpy(pEquiv, equiv);
                     92:     } else {
                     93:         temp->equiv = 0;
                     94:     }
                     95:     temp->pattern = pPattern;
                     96:     temp->op = op;
                     97: 
                     98:     strcpy(pPattern, pattern);
2.10      duns       99:     if (TRACE) {
                    100:        if (equiv)
                    101:           printf("Rule: For `%s' op %d `%s'\n", pattern, op, equiv);
                    102:        else
                    103:           printf("Rule: For `%s' op %d\n", pattern, op);
                    104:     }
2.1       timbl     105: 
                    106: #ifdef PUT_ON_HEAD
                    107:     temp->next = rules;
                    108:     rules = temp;
                    109: #else
                    110:     temp->next = 0;
                    111:     if (rule_tail) rule_tail->next = temp;
                    112:     else rules = temp;
                    113:     rule_tail = temp;
                    114: #endif
                    115: 
                    116:         
                    117:     return 0;
                    118: }
                    119: 
                    120: 
                    121: /*     Clear all rules                                         HTClearRules()
                    122: **     ---------------
                    123: **
                    124: ** On exit,
                    125: **     There are no rules
                    126: **     returns         0 if success, -1 if error.
                    127: **
                    128: ** See also
                    129: **     HTAddRule()
                    130: */
                    131: #ifdef __STDC__
                    132: int HTClearRules(void)
                    133: #else
                    134: int HTClearRules()
                    135: #endif
                    136: {
                    137:     while (rules) {
                    138:        rule * temp = rules;
                    139:        rules = temp->next;
                    140:        free(temp->pattern);
                    141:        free(temp->equiv);
                    142:        free(temp);
                    143:     }
                    144: #ifndef PUT_ON_HEAD
                    145:     rule_tail = 0;
                    146: #endif
                    147: 
                    148:     return 0;
                    149: }
                    150: 
                    151: 
                    152: /*     Translate by rules                                      HTTranslate()
                    153: **     ------------------
                    154: **
                    155: **     The most recently defined rules are applied first.
                    156: **
                    157: ** On entry,
                    158: **     required        points to a string whose equivalent value is neeed
                    159: ** On exit,
                    160: **     returns         the address of the equivalent string allocated from
                    161: **                     the heap which the CALLER MUST FREE. If no translation
                    162: **                     occured, then it is a copy of te original.
2.11      luotonen  163: ** NEW FEATURES:
                    164: **                     When a "protect" or "defprot" rule is mathed,
                    165: **                     a call to HTAA_setCurrentProtection() or
                    166: **                     HTAA_setDefaultProtection() is made to notify
                    167: **                     the Access Authorization module that the file is
                    168: **                     protected, and so it knows how to handle it.
                    169: **                                                             -- AL
2.1       timbl     170: */
                    171: #ifdef __STDC__
                    172: char * HTTranslate(const char * required)
                    173: #else
                    174: char * HTTranslate(required)
                    175:        char * required;
                    176: #endif
                    177: {
                    178:     rule * r;
2.11      luotonen  179:     char *current = NULL;
                    180:     StrAllocCopy(current, required);
                    181: 
                    182:     HTAA_clearProtections();   /* Reset from previous call -- AL */
                    183: 
2.1       timbl     184:     for(r = rules; r; r = r->next) {
                    185:         char * p = r->pattern;
2.11      luotonen  186:        int m=0;   /* Number of characters matched against wildcard */
2.1       timbl     187:        CONST char * q = current;
                    188:        for(;*p && *q; p++, q++) {   /* Find first mismatch */
                    189:            if (*p!=*q) break;
                    190:        }
                    191: 
                    192:        if (*p == '*') {                /* Match up to wildcard */
                    193:            m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
                    194:            if(m<0) continue;           /* tail is too short to match */
                    195:            if (0!=strcmp(q+m, p+1)) continue;  /* Tail mismatch */
                    196:        } else                          /* Not wildcard */
                    197:            if (*p != *q) continue;     /* plain mismatch: go to next rule */
                    198: 
                    199:        switch (r->op) {                /* Perform operation */
2.11      luotonen  200: 
                    201: #ifdef ACCESS_AUTH
                    202:        case HT_DefProt:
                    203:        case HT_Protect:
                    204:            {
                    205:                char *local_copy = NULL;
                    206:                char *p;
                    207:                char *eff_ids = NULL;
                    208:                char *prot_file = NULL;
                    209: 
                    210:                if (TRACE) fprintf(stderr,
                    211:                                   "HTRule: `%s' matched %s %s: `%s'\n",
                    212:                                   current,
                    213:                                   (r->op==HT_Protect ? "Protect" : "DefProt"),
                    214:                                   "rule, setup",
                    215:                                   (r->equiv ? r->equiv :
                    216:                                    (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
                    217: 
                    218:                if (r->equiv) {
                    219:                    StrAllocCopy(local_copy, r->equiv);
                    220:                    p = local_copy;
                    221:                    prot_file = HTNextField(&p);
                    222:                    eff_ids = HTNextField(&p);
                    223:                }
                    224: 
                    225:                if (r->op == HT_Protect)
                    226:                    HTAA_setCurrentProtection(current, prot_file, eff_ids);
                    227:                else
                    228:                    HTAA_setDefaultProtection(current, prot_file, eff_ids);
                    229: 
                    230:                FREE(local_copy);
                    231: 
                    232:                /* continue translating rules */
                    233:            }
                    234:            break;
                    235: #endif ACCESS_AUTH
                    236: 
2.1       timbl     237:        case HT_Pass:                           /* Authorised */
                    238:                if (!r->equiv) {
                    239:                    if (TRACE) printf("HTRule: Pass `%s'\n", current);
                    240:                    return current;
                    241:                }
2.11      luotonen  242:                /* Else fall through ...to map and pass */
2.1       timbl     243:                
                    244:        case HT_Map:
                    245:            if (*p == *q) { /* End of both strings, no wildcard */
                    246:                  if (TRACE) printf(
                    247:                               "For `%s' using `%s'\n", current, r->equiv);  
                    248:                  StrAllocCopy(current, r->equiv); /* use entire translation */
                    249:            } else {
                    250:                  char * ins = strchr(r->equiv, '*');   /* Insertion point */
                    251:                  if (ins) {    /* Consistent rule!!! */
                    252:                        char * temp = (char *)malloc(
                    253:                                strlen(r->equiv)-1 + m + 1);
2.9       secret    254:                        if (temp==NULL) 
                    255:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     256:                        strncpy(temp,   r->equiv, ins-r->equiv);
                    257:                        /* Note: temp may be unterminated now! */
                    258:                        strncpy(temp+(ins-r->equiv), q, m);  /* Matched bit */
                    259:                        strcpy (temp+(ins-r->equiv)+m, ins+1);  /* Last bit */
                    260:                        if (TRACE) printf("For `%s' using `%s'\n",
                    261:                                                current, temp);
                    262:                        free(current);
                    263:                        current = temp;                 /* Use this */
                    264: 
                    265:                    } else {    /* No insertion point */
                    266:                        char * temp = (char *)malloc(strlen(r->equiv)+1);
2.9       secret    267:                        if (temp==NULL) 
                    268:                            outofmem(__FILE__, "HTTranslate"); /* NT & AS */
2.1       timbl     269:                        strcpy(temp, r->equiv);
                    270:                        if (TRACE) printf("For `%s' using `%s'\n",
                    271:                                                current, temp);
                    272:                        free(current);
                    273:                        current = temp;                 /* Use this */
                    274:                    } /* If no insertion point exists */
                    275:                }
                    276:                if (r->op == HT_Pass) {
                    277:                    if (TRACE) printf("HTRule: ...and pass `%s'\n", current);
                    278:                    return current;
                    279:                }
                    280:                break;
                    281: 
2.11      luotonen  282:        case HT_Invalid:
                    283:        case HT_Fail:                           /* Unauthorised */
2.1       timbl     284:                    if (TRACE) printf("HTRule: *** FAIL `%s'\n", current);
                    285:                    return (char *)0;
                    286:                                    
2.11      luotonen  287:        } /* if tail matches ... switch operation */
2.1       timbl     288: 
                    289:     } /* loop over rules */
                    290: 
                    291: 
                    292:     return current;
                    293: }
                    294: 
2.7       timbl     295: /*     Load one line of configuration
                    296: **     ------------------------------
                    297: **
                    298: **     Call this, for example, to load a X resource with config info.
                    299: **
                    300: ** returns     0 OK, < 0 syntax error.
                    301: */
                    302: PUBLIC int  HTSetConfiguration ARGS1(CONST char *, config)
                    303: {
                    304:     HTRuleOp op;
                    305:     char * line = NULL;
                    306:     char * pointer = line;
                    307:     char *word1, *word2, *word3;
                    308:     float quality, secs, secs_per_byte;
                    309:     int status;
                    310:     
                    311:     StrAllocCopy(line, config);
                    312:     {
                    313:        char * p = strchr(line, '#');   /* Chop off comments */
                    314:        if (p) *p = 0;
                    315:     }
                    316:     pointer = line;
                    317:     word1 = HTNextField(&pointer);
                    318:     if (!word1) {
                    319:        free(line);
                    320:        return 0;
                    321:     } ;        /* Comment only or blank */
2.11      luotonen  322: 
2.7       timbl     323:     word2 = HTNextField(&pointer);
2.11      luotonen  324: 
                    325:     if (0==strcasecomp(word1, "defprot") ||
                    326:        0==strcasecomp(word1, "protect"))
                    327:        word3 = pointer;  /* The rest of the line to be parsed by AA module */
                    328:     else
                    329:        word3 = HTNextField(&pointer);  /* Just the next word */
                    330: 
2.7       timbl     331:     if (!word2) {
                    332:        fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
                    333:        free(line);
                    334:        return -2;      /*syntax error */
                    335:     }
                    336: 
                    337:     if (0==strcasecomp(word1, "suffix")) {
2.8       timbl     338:         char * encoding = HTNextField(&pointer);
                    339:        if (pointer) status = sscanf(pointer, "%f", &quality);
                    340:        else status = 0;
                    341:        HTSetSuffix(word2,      word3,
                    342:                                encoding ? encoding : "binary",
                    343:                                status >= 1? quality : 1.0);
2.7       timbl     344: 
                    345:     } else if (0==strcasecomp(word1, "presentation")) {
2.8       timbl     346:         if (pointer) status = sscanf(pointer, "%f%f%f",
                    347:                            &quality, &secs, &secs_per_byte);
                    348:         else status = 0;
2.7       timbl     349:        HTSetPresentation(word2, word3,
                    350:                    status >= 1? quality                : 1.0,
2.11      luotonen  351:                    status >= 2 ? secs                  : 0.0,
2.7       timbl     352:                    status >= 3 ? secs_per_byte         : 0.0 );
2.12      luotonen  353: 
2.13    ! luotonen  354:     } else if (0==strncasecomp(word1, "htbin", 5) ||
        !           355:               0==strncasecomp(word1, "bindir", 6)) {
        !           356:        StrAllocCopy(HTBinDir, word2);  /* Physical /htbin location */
        !           357: 
        !           358:     } else if (0==strncasecomp(word1, "search", 6)) {
        !           359:        StrAllocCopy(HTSearchScript, word2);    /* Search script name */
2.12      luotonen  360: 
2.7       timbl     361:     } else {
                    362:        op =    0==strcasecomp(word1, "map")  ? HT_Map
                    363:            :   0==strcasecomp(word1, "pass") ? HT_Pass
                    364:            :   0==strcasecomp(word1, "fail") ? HT_Fail
2.11      luotonen  365:            :   0==strcasecomp(word1, "defprot") ? HT_DefProt
                    366:            :   0==strcasecomp(word1, "protect") ? HT_Protect
2.7       timbl     367:            :                                           HT_Invalid;
                    368:        if (op==HT_Invalid) {
                    369:            fprintf(stderr, "HTRule: Bad rule `%s'\n", config);
                    370:        } else {  
                    371:            HTAddRule(op, word2, word3);
                    372:        } 
                    373:     }
                    374:     free(line);
                    375:     return 0;
                    376: }
                    377: 
2.1       timbl     378: 
2.11      luotonen  379: /*     Load the rules from a file                              HTLoadRules()
2.1       timbl     380: **     --------------------------
                    381: **
                    382: ** On entry,
                    383: **     Rules can be in any state
                    384: ** On exit,
                    385: **     Any existing rules will have been kept.
2.7       timbl     386: **     Any new rules will have been loaded.
                    387: **     Returns         0 if no error, 0 if error!
2.1       timbl     388: **
                    389: ** Bugs:
                    390: **     The strings may not contain spaces.
                    391: */
                    392: 
                    393: int HTLoadRules ARGS1(CONST char *, filename)
                    394: {
                    395:     FILE * fp = fopen(filename, "r");
                    396:     char line[LINE_LENGTH+1];
                    397:     
                    398:     if (!fp) {
                    399:         if (TRACE) printf("HTRules: Can't open rules file %s\n", filename);
                    400:        return -1; /* File open error */
                    401:     }
                    402:     for(;;) {
                    403:        if (!fgets(line, LINE_LENGTH+1, fp)) break;     /* EOF or error */
2.7       timbl     404:        (void) HTSetConfiguration(line);
2.1       timbl     405:     }
                    406:     fclose(fp);
2.7       timbl     407:     return 0;          /* No error or syntax errors ignored */
2.1       timbl     408: }
2.11      luotonen  409: 
                    410: 

Webmaster