[w3m-dev 04130] Multiple challeges in *-Authenticate header
Kiyokazu SUTO <[email protected]> 18 Dec 2004 19:27:45 +0900
| Newsgroups | gmane.comp.web.w3m.devel |
|---|---|
| Message-ID | <[email protected]> |
*-Authenticate 2 (,) -- <[email protected]> http://pub.ks-and-ks.ne.jp/pgp-public-key.html ----- ----- ----- ----- ----- Index: file.c =================================================================== RCS file: /cvsroot/w3m/w3m/file.c,v retrieving revision 1.236 diff -u -r1.236 file.c --- file.c 4 Nov 2004 17:25:45 -0000 1.236 +++ file.c 18 Dec 2004 09:57:32 -0000 @@ -972,7 +972,59 @@ HRequest *hr, FormList *request); }; -#define TOKEN_PAT "[^][()<>@,;:\\\"/?={} \t\001-\037\177]*" +enum { + AUTHCHR_NUL, + AUTHCHR_SEP, + AUTHCHR_TOKEN, +}; + +static int +skip_auth_token(char **pp) +{ + char *p; + int first = AUTHCHR_NUL, typ; + + for (p = *pp ;; ++p) { + switch (*p) { + case '\0': + goto endoftoken; + default: + if ((unsigned char)*p > 037) { + typ = AUTHCHR_TOKEN; + break; + } + /* thru */ + case '\177': + case '[': + case ']': + case '(': + case ')': + case '<': + case '>': + case '@': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '?': + case '=': + case ' ': + case '\t': + case ',': + typ = AUTHCHR_SEP; + break; + } + + if (!first) + first = typ; + else if (first != typ) + break; + } +endoftoken: + *pp = p; + return first; +} static Str extract_auth_val(char **q) @@ -993,12 +1045,13 @@ } if (!quoted) { switch (*qq) { + case '[': + case ']': case '(': case ')': case '<': case '>': case '@': - case ',': case ';': case ':': case '\\': @@ -1009,6 +1062,7 @@ case ' ': case '\t': qq++; + case ',': goto end_token; default: if (*qq <= 037 || *qq == 0177) { @@ -1022,11 +1076,6 @@ Strcat_char(val, *qq++); } end_token: - if (*qq != '\0') { - SKIP_BLANKS(qq); - if (*qq == ',') - qq++; - } *q = (char *)qq; return val; } @@ -1058,10 +1107,7 @@ extract_auth_param(char *q, struct auth_param *auth) { struct auth_param *ap; - char *q0; - Regex re_token; - - newRegex(TOKEN_PAT, FALSE, &re_token, NULL); + char *p; for (ap = auth; ap->name != NULL; ap++) { ap->val = NULL; @@ -1070,26 +1116,41 @@ while (*q != '\0') { SKIP_BLANKS(q); for (ap = auth; ap->name != NULL; ap++) { - if (strncasecmp(q, ap->name, strlen(ap->name)) == 0) { - q += strlen(ap->name); - SKIP_BLANKS(q); - if (*q != '=') + size_t len; + + len = strlen(ap->name); + if (strncasecmp(q, ap->name, len) == 0 && + (IS_SPACE(q[len]) || q[len] == '=')) { + p = q + len; + SKIP_BLANKS(p); + if (*p != '=') return q; - q++; + q = p + 1; ap->val = extract_auth_val(&q); break; } } if (ap->name == NULL) { /* skip unknown param */ - if (RegexMatch(&re_token, q, -1, TRUE) == 0) - return q; - MatchedPosition(&re_token, &q0, &q); + int token_type; + p = q; + if ((token_type = skip_auth_token(&q)) == AUTHCHR_TOKEN && + (IS_SPACE(*q) || *q == '=')) { + SKIP_BLANKS(q); + if (*q != '=') + return p; + q++; + extract_auth_val(&q); + } + else + return p; + } + if (*q != '\0') { SKIP_BLANKS(q); - if (*q != '=') - return q; - q++; - extract_auth_val(&q); + if (*q == ',') + q++; + else + break; } } return q; @@ -1344,12 +1405,9 @@ findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field) { struct http_auth *ha; - int len = strlen(auth_field); + int len = strlen(auth_field), slen; TextListItem *i; char *p0, *p; - Regex re_token; - - newRegex(TOKEN_PAT, FALSE, &re_token, NULL); bzero(hauth, sizeof(struct http_auth)); for (i = buf->document_header->first; i != NULL; i = i->next) { @@ -1358,29 +1416,30 @@ SKIP_BLANKS(p); p0 = p; for (ha = &www_auth[0]; ha->scheme != NULL; ha++) { - if (strncasecmp(p, ha->scheme, strlen(ha->scheme)) == 0) { + slen = strlen(ha->scheme); + if (strncasecmp(p, ha->scheme, slen) == 0) { + p += slen; + SKIP_BLANKS(p); if (hauth->pri < ha->pri) { *hauth = *ha; - p += strlen(ha->scheme); - SKIP_BLANKS(p); p = extract_auth_param(p, hauth->param); break; } else { /* weak auth */ - p += strlen(ha->scheme); - SKIP_BLANKS(p); p = extract_auth_param(p, none_auth_param); } } } if (p0 == p) { /* all unknown auth failed */ - if (RegexMatch(&re_token, p0, -1, TRUE) == 0) - return NULL; - MatchedPosition(&re_token, &p0, &p); - SKIP_BLANKS(p); - p = extract_auth_param(p, none_auth_param); + int token_type; + if ((token_type = skip_auth_token(&p)) == AUTHCHR_TOKEN && IS_SPACE(*p)) { + SKIP_BLANKS(p); + p = extract_auth_param(p, none_auth_param); + } + else + break; } } } @@ -1893,6 +1952,27 @@ status = HTST_NORMAL; goto load_doc; } +#ifdef AUTH_DEBUG + if ((p = checkHeader(t_buf, "WWW-Authenticate:")) != NULL) { + /* Authentication needed */ + struct http_auth hauth; + if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL + && (realm = get_auth_param(hauth.param, "realm")) != NULL) { + auth_pu = &pu; + getAuthCookie(&hauth, "Authorization:", extra_header, + auth_pu, &hr, request, &uname, &pwd); + if (uname == NULL) { + /* abort */ + TRAP_OFF; + goto page_loaded; + } + UFclose(&f); + add_auth_cookie_flag = 1; + status = HTST_NORMAL; + goto load_doc; + } + } +#endif /* defined(AUTH_DEBUG) */ t = checkContentType(t_buf); if (t == NULL) t = "text/plain";