[w3m-dev 04132] Re: Multiple challeges in *-Authenticate header
Kiyokazu SUTO <[email protected]> 26 Dec 2004 12:58:43 +0900
| Newsgroups | gmane.comp.web.w3m.devel |
|---|---|
| Message-ID | <[email protected]> |
Citation (with leading "> " of each line) from article: <[email protected]> by Kiyokazu SUTO <[email protected]> : > *-Authenticate > 2 qopqop="auth,auth-int"auth auth-intAuthorization:qop qop=auth,auth-int( Apache(1.3.33)mod_auth_digest) Citation (with leading "| " of each line) from article: <[email protected]> by Kiyokazu SUTO <[email protected]> : | [w3m-dev 04130]request->body | () [w3m-dev 4130][w3m-dev 4131] -- <[email protected]> http://pub.ks-and-ks.ne.jp/pgp-public-key.html ----- ----- ----- ----- ----- --- file.c~ Sat Dec 18 20:13:03 2004 +++ file.c Sun Dec 26 12:51:14 2004 @@ -1218,6 +1218,12 @@ return tmp; } +enum { + QOP_NONE, + QOP_AUTH, + QOP_AUTH_INT, +}; + static Str AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, HRequest *hr, FormList *request) @@ -1229,11 +1235,50 @@ Str algorithm = qstr_unquote(get_auth_param(ha->param, "algorithm")); Str nonce = qstr_unquote(get_auth_param(ha->param, "nonce")); - Str cnonce = qstr_unquote(get_auth_param(ha->param, "cnonce")); + Str cnonce /* = qstr_unquote(get_auth_param(ha->param, "cnonce")) */; + /* cnonce is what client should generate. */ Str qop = qstr_unquote(get_auth_param(ha->param, "qop")); - if (cnonce == NULL) - cnonce = Strnew_charp("cnonce"); /* XXX */ + static union { + int r[4]; + char s[sizeof(int) * 4]; + } cnonce_seed; + int qop_i = QOP_NONE; + + cnonce_seed.r[0] = rand(); + cnonce_seed.r[1] = rand(); + cnonce_seed.r[2] = rand(); + MD5(cnonce_seed.s, sizeof(cnonce_seed.s), md5); + cnonce = digest_hex(md5); + cnonce_seed.r[3]++; + + if (qop) { + char *p; + size_t i; + + p = qop->ptr; + SKIP_BLANKS(p); + + for (;;) { + if ((i = strcspn(p, " \t,")) > 0) { + if (i == sizeof("auth-int") - sizeof("") && !strncasecmp(p, "auth-int", i)) { + if (qop_i < QOP_AUTH_INT) + qop_i = QOP_AUTH_INT; + } + else if (i == sizeof("auth") - sizeof("") && !strncasecmp(p, "auth", i)) { + if (qop_i < QOP_AUTH) + qop_i = QOP_AUTH; + } + } + + if (p[i]) { + p += i + 1; + SKIP_BLANKS(p); + } + else + break; + } + } /* A1 = unq(username-value) ":" unq(realm-value) ":" passwd */ tmp = Strnew_m_charp(uname->ptr, ":", @@ -1265,10 +1310,10 @@ /* A2 = Method ":" digest-uri-value */ tmp = Strnew_m_charp(HTTPrequestMethod(hr)->ptr, ":", uri->ptr, NULL); - if (qop && (strcasecmp(qop->ptr, "auth-int") == 0)) { + if (qop_i == QOP_AUTH_INT) { /* A2 = Method ":" digest-uri-value ":" H(entity-body) */ if (request && request->body) { - if (request->enctype == FORM_ENCTYPE_MULTIPART) { + if (request->method == FORM_METHOD_POST && request->enctype == FORM_ENCTYPE_MULTIPART) { FILE *fp = fopen(request->body, "r"); if (fp != NULL) { Str ebody; @@ -1292,9 +1337,7 @@ MD5(tmp->ptr, strlen(tmp->ptr), md5); a2buf = digest_hex(md5); - if (qop && - (strcasecmp(qop->ptr, "auth") == 0 - || strcasecmp(qop->ptr, "auth-int") == 0)) { + if (qop_i >= QOP_AUTH) { /* request-digest = <"> < KD ( H(A1), unq(nonce-value) * ":" nc-value * ":" unq(cnonce-value) @@ -1307,7 +1350,7 @@ tmp = Strnew_m_charp(a1buf->ptr, ":", qstr_unquote(nonce)->ptr, ":", nc, ":", qstr_unquote(cnonce)->ptr, - ":", qstr_unquote(qop)->ptr, + ":", qop_i == QOP_AUTH ? "auth" : "auth-int", ":", a2buf->ptr, NULL); MD5(tmp->ptr, strlen(tmp->ptr), md5); rd = digest_hex(md5); @@ -1348,10 +1391,13 @@ if ((s = get_auth_param(ha->param, "opaque")) != NULL) Strcat_m_charp(tmp, ", opaque=", s->ptr, NULL); - if (qop) { + if (qop_i >= QOP_AUTH) { Strcat_m_charp(tmp, ", qop=", - get_auth_param(ha->param, "qop")->ptr, NULL); + qop_i == QOP_AUTH ? "auth" : "auth-int", + NULL); /* XXX how to count? */ + /* Since nonce is unique up to each *-Authenticate and w3m does not re-use *-Authenticate: headers, + nonce-count should be always "00000001". */ Strcat_m_charp(tmp, ", nc=", nc, NULL); }