Annotation of libwww/Library/src/HTAAUtil.c, revision 2.11.2.1
2.9 frystyk 1: /* HTAAUtil.c
2: ** COMMON PARTS OF ACCESS AUTHORIZATION MODULE
3: ** FOR BOTH SERVER AND BROWSER
4: **
5: ** (c) COPYRIGHT CERN 1994.
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: */
68: PUBLIC HTAAScheme HTAAScheme_enum ARGS1(CONST char*, name)
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: */
101: PUBLIC char *HTAAScheme_name ARGS1(HTAAScheme, scheme)
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.8 frystyk 138: PUBLIC BOOL HTAA_templateMatch ARGS2(CONST char *, tmplate,
2.1 luotonen 139: CONST char *, filename)
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.11 frystyk 146: if (TRACE) fprintf(TDEST,
2.4 luotonen 147: "HTAA_templateMatch: invalid param: %s is NULL!!\n",
2.8 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.8 frystyk 191: PUBLIC BOOL HTAA_templateCaseMatch ARGS2(CONST char *, tmplate,
2.3 duns 192: CONST char *, filename)
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.11 frystyk 199: if (TRACE) fprintf(TDEST,
2.4 luotonen 200: "HTAA_templateCaseMatch: invalid param: %s is NULL!!\n",
2.8 frystyk 201: (tmplate ? "filename" : "template"));
2.4 luotonen 202: return NO;
203: }
204:
2.11.2.1! frystyk 205: for( ; *p && *q && TOUPPER(*p) == TOUPPER(*q); p++, q++) /* Find first mismatch */
2.3 duns 206: ; /* do nothing else */
207:
208: if (!*p && !*q) return YES; /* Equally long equal strings */
209: else if ('*' == *p) { /* Wildcard */
210: p++; /* Skip wildcard character */
211: m = strlen(q) - strlen(p); /* Amount to match to wildcard */
212: if (m < 0) return NO; /* No match, filename too short */
213: else { /* Skip the matched characters and compare */
214: if (strcasecomp(p, q+m)) return NO; /* Tail mismatch */
215: else return YES; /* Tail match */
216: }
217: } /* if wildcard */
218: else return NO; /* Length or character mismatch */
219: }
2.1 luotonen 220:
221:
222: /* PUBLIC HTAA_makeProtectionTemplate()
223: ** CREATE A PROTECTION TEMPLATE FOR THE FILES
224: ** IN THE SAME DIRECTORY AS THE GIVEN FILE
225: ** (Used by server if there is no fancier way for
226: ** it to tell the client, and by browser if server
227: ** didn't send WWW-ProtectionTemplate: field)
228: ** ON ENTRY:
229: ** docname is the document pathname (from URL).
230: **
231: ** ON EXIT:
232: ** returns a template matching docname, and other files
233: ** files in that directory.
234: **
235: ** E.g. /foo/bar/x.html => /foo/bar/ *
236: ** ^
237: ** Space only to prevent it from
238: ** being a comment marker here,
239: ** there really isn't any space.
240: */
241: PUBLIC char *HTAA_makeProtectionTemplate ARGS1(CONST char *, docname)
242: {
2.8 frystyk 243: char *tmplate = NULL;
2.1 luotonen 244: char *slash = NULL;
245:
246: if (docname) {
2.8 frystyk 247: StrAllocCopy(tmplate, docname);
248: slash = strrchr(tmplate, '/');
2.1 luotonen 249: if (slash) slash++;
2.8 frystyk 250: else slash = tmplate;
2.2 luotonen 251: *slash = (char)0;
2.8 frystyk 252: StrAllocCat(tmplate, "*");
2.1 luotonen 253: }
2.8 frystyk 254: else StrAllocCopy(tmplate, "*");
2.1 luotonen 255:
2.11 frystyk 256: if (TRACE) fprintf(TDEST,
2.1 luotonen 257: "make_template: made template `%s' for file `%s'\n",
2.8 frystyk 258: tmplate, docname);
2.1 luotonen 259:
2.8 frystyk 260: return tmplate;
2.1 luotonen 261: }
262:
263:
264:
265:
266: /*
267: ** Skip leading whitespace from *s forward
268: */
269: #define SKIPWS(s) while (*s==' ' || *s=='\t') s++;
270:
271: /*
272: ** Kill trailing whitespace starting from *(s-1) backwords
273: */
2.2 luotonen 274: #define KILLWS(s) {char *c=s-1; while (*c==' ' || *c=='\t') *(c--)=(char)0;}
2.1 luotonen 275:
276:
277: /* PUBLIC HTAA_parseArgList()
278: ** PARSE AN ARGUMENT LIST GIVEN IN A HEADER FIELD
279: ** ON ENTRY:
280: ** str is a comma-separated list:
281: **
282: ** item, item, item
283: ** where
284: ** item ::= value
285: ** | name=value
286: ** | name="value"
287: **
288: ** Leading and trailing whitespace is ignored
289: ** everywhere except inside quotes, so the following
290: ** examples are equal:
291: **
292: ** name=value,foo=bar
293: ** name="value",foo="bar"
294: ** name = value , foo = bar
295: ** name = "value" , foo = "bar"
296: **
297: ** ON EXIT:
298: ** returns a list of name-value pairs (actually HTAssocList*).
299: ** For items with no name, just value, the name is
300: ** the number of order number of that item. E.g.
301: ** "1" for the first, etc.
302: */
303: PUBLIC HTAssocList *HTAA_parseArgList ARGS1(char *, str)
304: {
305: HTAssocList *assoc_list = HTAssocList_new();
306: char *cur = NULL;
307: char *name = NULL;
308: int index = 0;
309:
310: if (!str) return assoc_list;
311:
312: while (*str) {
313: SKIPWS(str); /* Skip leading whitespace */
314: cur = str;
315: index++;
316:
317: while (*cur && *cur != '=' && *cur != ',')
318: cur++; /* Find end of name (or lonely value without a name) */
319: KILLWS(cur); /* Kill trailing whitespace */
320:
321: if (*cur == '=') { /* Name followed by a value */
2.2 luotonen 322: *(cur++) = (char)0; /* Terminate name */
2.1 luotonen 323: StrAllocCopy(name, str);
324: SKIPWS(cur); /* Skip WS leading the value */
325: str = cur;
326: if (*str == '"') { /* Quoted value */
327: str++;
328: cur = str;
329: while (*cur && *cur != '"') cur++;
330: if (*cur == '"')
2.2 luotonen 331: *(cur++) = (char)0; /* Terminate value */
2.1 luotonen 332: /* else it is lacking terminating quote */
333: SKIPWS(cur); /* Skip WS leading comma */
334: if (*cur == ',') cur++; /* Skip separating colon */
335: }
336: else { /* Unquoted value */
337: while (*cur && *cur != ',') cur++;
338: KILLWS(cur); /* Kill trailing whitespace */
339: if (*cur == ',')
2.2 luotonen 340: *(cur++) = (char)0;
2.1 luotonen 341: /* else *cur already NULL */
342: }
343: }
344: else { /* No name, just a value */
345: if (*cur == ',')
2.2 luotonen 346: *(cur++) = (char)0; /* Terminate value */
2.1 luotonen 347: /* else last value on line (already terminated by NULL) */
348: StrAllocCopy(name, "nnn"); /* Room for item order number */
349: sprintf(name, "%d", index); /* Item order number for name */
350: }
351: HTAssocList_add(assoc_list, name, str);
352: str = cur;
353: } /* while *str */
2.6 frystyk 354: FREE(name); /* Henrik 14/03-94 */
2.1 luotonen 355: return assoc_list;
356: }
2.6 frystyk 357:
358:
359:
360:
361:
2.1 luotonen 362:
Webmaster