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