X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fhttp.c;h=40b1f580b68a5eaa948a4ee3520efcf11edfba76;hb=6f7fd371862f92d2f48b114de25b4afcb0c5a1c6;hp=f75980317a8ac001d48f9710a19ce4f86101540f;hpb=ba3f5ce0a2f6df3ba53b61a0ec1734c3f8e3c35f;p=wget diff --git a/src/http.c b/src/http.c index f7598031..40b1f580 100644 --- a/src/http.c +++ b/src/http.c @@ -422,6 +422,11 @@ static int known_authentication_scheme_p PARAMS ((const char *)); static time_t http_atotm PARAMS ((char *)); +#define BEGINS_WITH(line, string_constant) \ + (!strncasecmp (line, string_constant, sizeof (string_constant) - 1) \ + && (ISSPACE (line[sizeof (string_constant) - 1]) \ + || !line[sizeof (string_constant) - 1])) + /* Retrieve a document through HTTP protocol. It recognizes status code, and correctly handles redirections. It closes the network socket. If it receives an error from the functions below it, it @@ -477,7 +482,9 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) again: /* We need to come back here when the initial attempt to retrieve - without authorization header fails. */ + without authorization header fails. (Expected to happen at least + for the Digest authorization scheme.) */ + keep_alive = 0; http_keep_alive_1 = http_keep_alive_2 = 0; @@ -588,10 +595,37 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) passwd = passwd ? passwd : opt.http_passwd; wwwauth = NULL; - if (authenticate_h && user && passwd) + if (user && passwd) { - wwwauth = create_authorization_line (authenticate_h, user, passwd, - command, ou->path); + if (!authenticate_h) + { + /* We have the username and the password, but haven't tried + any authorization yet. Let's see if the "Basic" method + works. If not, we'll come back here and construct a + proper authorization method with the right challenges. + + If we didn't employ this kind of logic, every URL that + requires authorization would have to be processed twice, + which is very suboptimal and generates a bunch of false + "unauthorized" errors in the server log. + + #### But this logic also has a serious problem when used + with stronger authentications: we *first* transmit the + username and the password in clear text, and *then* + attempt a stronger authentication scheme. That cannot be + right! We are only fortunate that almost everyone still + uses the `Basic' scheme anyway. + + There should be an option to prevent this from happening, + for those who use strong authentication schemes and value + their passwords. */ + wwwauth = basic_authentication_encode (user, passwd, "Authorization"); + } + else + { + wwwauth = create_authorization_line (authenticate_h, user, passwd, + command, ou->path); + } } proxyauth = NULL; @@ -891,6 +925,7 @@ Accept: %s\r\n\ { /* If we have tried it already, then there is not point retrying it. */ + failed: logputs (LOG_NOTQUIET, _("Authorization failed.\n")); free (authenticate_h); return AUTHFAILED; @@ -901,6 +936,13 @@ Accept: %s\r\n\ logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n")); return AUTHFAILED; } + else if (BEGINS_WITH (authenticate_h, "Basic")) + { + /* The authentication scheme is basic, the one we try by + default, and it failed. There's no sense in trying + again. */ + goto failed; + } else { auth_tried_already = 1; @@ -1908,7 +1950,7 @@ username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", #endif /* USE_DIGEST */ -#define HACK_O_MATIC(line, string_constant) \ +#define BEGINS_WITH(line, string_constant) \ (!strncasecmp (line, string_constant, sizeof (string_constant) - 1) \ && (ISSPACE (line[sizeof (string_constant) - 1]) \ || !line[sizeof (string_constant) - 1])) @@ -1916,12 +1958,12 @@ username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", static int known_authentication_scheme_p (const char *au) { - return HACK_O_MATIC (au, "Basic") - || HACK_O_MATIC (au, "Digest") - || HACK_O_MATIC (au, "NTLM"); + return BEGINS_WITH (au, "Basic") + || BEGINS_WITH (au, "Digest") + || BEGINS_WITH (au, "NTLM"); } -#undef HACK_O_MATIC +#undef BEGINS_WITH /* Create the HTTP authorization request header. When the `WWW-Authenticate' response header is seen, according to the