From 6f7fd371862f92d2f48b114de25b4afcb0c5a1c6 Mon Sep 17 00:00:00 2001 From: hniksic Date: Sun, 19 Nov 2000 18:10:54 -0800 Subject: [PATCH] [svn] Auth tweaks. Published in . --- src/ChangeLog | 7 ++++++ src/connect.h | 3 ++- src/http.c | 60 +++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 5c3c4817..5bffb732 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2000-11-20 Hrvoje Niksic + + * http.c (http_loop): If username and password are known, try the + `Basic' authentication scheme by default. + + * connect.h: Declare test_socket_open. + 2000-11-20 Hrvoje Niksic * version.c: Bump version to 1.7-dev. diff --git a/src/connect.h b/src/connect.h index cd3aef17..03accb26 100644 --- a/src/connect.h +++ b/src/connect.h @@ -1,5 +1,5 @@ /* Declarations for connect. - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. This file is part of Wget. @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Function declarations */ uerr_t make_connection PARAMS ((int *, char *, unsigned short)); +int test_socket_open PARAMS ((int)); uerr_t bindport PARAMS ((unsigned short *)); uerr_t acceptport PARAMS ((int *)); void closeport PARAMS ((int)); 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 -- 2.39.2