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