mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
Fix erroneous error codes when HTTP Digest Authentication fails.
This commit is contained in:
parent
c19d76c024
commit
92035dbabd
@ -1,3 +1,22 @@
|
|||||||
|
2013-07-16 Darshit Shah <darnir@gmail.com>
|
||||||
|
|
||||||
|
* wget.h (err_t): Added new errors, ATTRMISSING and UNKNOWNATTR to
|
||||||
|
handle missing attributes and Unknown attribute values respectively in
|
||||||
|
HTTP Headers.
|
||||||
|
* exits.c (get_status_for_err): ATTRMISSING is a Protocol Error while
|
||||||
|
UNKNOWNATTR is a general error, presumably because of a feature that
|
||||||
|
is not yet implemented.
|
||||||
|
* http.c (gethttp): Call create_authorization_line () separately. In
|
||||||
|
case the auth_err flag has been set with an error, handle it and exit.
|
||||||
|
* http.c (create_authorization_line): Pass a pointer, auth_err to set
|
||||||
|
the flag for different kinds of errors encountered.
|
||||||
|
* http.c (http_loop): Handle the errors raised by the authentication
|
||||||
|
handlers.
|
||||||
|
* http.c (digest_authentication_encode): Pass pointer auth_err to set
|
||||||
|
the error flags.
|
||||||
|
Set qop to NULL in case the value of the qop / algorithm attribute is
|
||||||
|
unknown to Wget. Set an appropriate error too.
|
||||||
|
|
||||||
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
|
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||||
|
|
||||||
* http.c (digest_authentication_encode): Fix a crash when the algorithm
|
* http.c (digest_authentication_encode): Fix a crash when the algorithm
|
||||||
|
@ -68,7 +68,7 @@ get_status_for_err (uerr_t err)
|
|||||||
return WGET_EXIT_SSL_AUTH_FAIL;
|
return WGET_EXIT_SSL_AUTH_FAIL;
|
||||||
case FTPLOGINC: case FTPLOGREFUSED: case AUTHFAILED:
|
case FTPLOGINC: case FTPLOGREFUSED: case AUTHFAILED:
|
||||||
return WGET_EXIT_SERVER_AUTH_FAIL;
|
return WGET_EXIT_SERVER_AUTH_FAIL;
|
||||||
case HEOF: case HERR:
|
case HEOF: case HERR: case ATTRMISSING:
|
||||||
return WGET_EXIT_PROTOCOL_ERROR;
|
return WGET_EXIT_PROTOCOL_ERROR;
|
||||||
case WRONGCODE: case FTPPORTERR: case FTPSYSERR:
|
case WRONGCODE: case FTPPORTERR: case FTPSYSERR:
|
||||||
case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR:
|
case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR:
|
||||||
@ -76,7 +76,7 @@ get_status_for_err (uerr_t err)
|
|||||||
case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN:
|
case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN:
|
||||||
case PROXERR:
|
case PROXERR:
|
||||||
return WGET_EXIT_SERVER_ERROR;
|
return WGET_EXIT_SERVER_ERROR;
|
||||||
case URLERROR: case QUOTEXC: case SSLINITFAILED:
|
case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR:
|
||||||
default:
|
default:
|
||||||
return WGET_EXIT_UNKNOWN;
|
return WGET_EXIT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
103
src/http.c
103
src/http.c
@ -74,7 +74,7 @@ extern char *version_string;
|
|||||||
struct http_stat;
|
struct http_stat;
|
||||||
static char *create_authorization_line (const char *, const char *,
|
static char *create_authorization_line (const char *, const char *,
|
||||||
const char *, const char *,
|
const char *, const char *,
|
||||||
const char *, bool *);
|
const char *, bool *, uerr_t *);
|
||||||
static char *basic_authentication_encode (const char *, const char *);
|
static char *basic_authentication_encode (const char *, const char *);
|
||||||
static bool known_authentication_scheme_p (const char *, const char *);
|
static bool known_authentication_scheme_p (const char *, const char *);
|
||||||
static void ensure_extension (struct http_stat *, const char *, int *);
|
static void ensure_extension (struct http_stat *, const char *, int *);
|
||||||
@ -2350,6 +2350,7 @@ read_header:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pconn.authorized = false;
|
pconn.authorized = false;
|
||||||
|
uerr_t auth_err = RETROK;
|
||||||
if (!auth_finished && (user && passwd))
|
if (!auth_finished && (user && passwd))
|
||||||
{
|
{
|
||||||
/* IIS sends multiple copies of WWW-Authenticate, one with
|
/* IIS sends multiple copies of WWW-Authenticate, one with
|
||||||
@ -2377,28 +2378,44 @@ read_header:
|
|||||||
else if (!basic_auth_finished
|
else if (!basic_auth_finished
|
||||||
|| !BEGINS_WITH (www_authenticate, "Basic"))
|
|| !BEGINS_WITH (www_authenticate, "Basic"))
|
||||||
{
|
{
|
||||||
char *pth;
|
char *pth = url_full_path (u);
|
||||||
pth = url_full_path (u);
|
const char *value;
|
||||||
request_set_header (req, "Authorization",
|
uerr_t *auth_stat;
|
||||||
create_authorization_line (www_authenticate,
|
auth_stat = xmalloc (sizeof (uerr_t));
|
||||||
user, passwd,
|
*auth_stat = RETROK;
|
||||||
request_method (req),
|
|
||||||
pth,
|
value = create_authorization_line (www_authenticate,
|
||||||
&auth_finished),
|
user, passwd,
|
||||||
rel_value);
|
request_method (req),
|
||||||
if (BEGINS_WITH (www_authenticate, "NTLM"))
|
pth,
|
||||||
ntlm_seen = true;
|
&auth_finished,
|
||||||
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
|
auth_stat);
|
||||||
|
|
||||||
|
auth_err = *auth_stat;
|
||||||
|
if (auth_err == RETROK)
|
||||||
{
|
{
|
||||||
/* Need to register this host as using basic auth,
|
request_set_header (req, "Authorization", value, rel_value);
|
||||||
* so we automatically send creds next time. */
|
|
||||||
register_basic_auth_host (u->host);
|
if (BEGINS_WITH (www_authenticate, "NTLM"))
|
||||||
|
ntlm_seen = true;
|
||||||
|
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
|
||||||
|
{
|
||||||
|
/* Need to register this host as using basic auth,
|
||||||
|
* so we automatically send creds next time. */
|
||||||
|
register_basic_auth_host (u->host);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (pth);
|
||||||
|
xfree_null (message);
|
||||||
|
resp_free (resp);
|
||||||
|
xfree (head);
|
||||||
|
xfree (auth_stat);
|
||||||
|
goto retry_with_auth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Creating the Authorization header went wrong */
|
||||||
}
|
}
|
||||||
xfree (pth);
|
|
||||||
xfree_null (message);
|
|
||||||
resp_free (resp);
|
|
||||||
xfree (head);
|
|
||||||
goto retry_with_auth;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2406,12 +2423,14 @@ read_header:
|
|||||||
* give up. */
|
* give up. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
|
|
||||||
request_free (req);
|
request_free (req);
|
||||||
xfree_null (message);
|
xfree_null (message);
|
||||||
resp_free (resp);
|
resp_free (resp);
|
||||||
xfree (head);
|
xfree (head);
|
||||||
return AUTHFAILED;
|
if (auth_err == RETROK)
|
||||||
|
return AUTHFAILED;
|
||||||
|
else
|
||||||
|
return auth_err;
|
||||||
}
|
}
|
||||||
else /* statcode != HTTP_STATUS_UNAUTHORIZED */
|
else /* statcode != HTTP_STATUS_UNAUTHORIZED */
|
||||||
{
|
{
|
||||||
@ -3133,12 +3152,23 @@ Spider mode enabled. Check if remote file exists.\n"));
|
|||||||
logputs (LOG_VERBOSE, "\n");
|
logputs (LOG_VERBOSE, "\n");
|
||||||
logprintf (LOG_NOTQUIET, _("Cannot write to %s (%s).\n"),
|
logprintf (LOG_NOTQUIET, _("Cannot write to %s (%s).\n"),
|
||||||
quote (hstat.local_file), strerror (errno));
|
quote (hstat.local_file), strerror (errno));
|
||||||
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED:
|
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case SSLINITFAILED:
|
||||||
case SSLINITFAILED: case CONTNOTSUPPORTED: case VERIFCERTERR:
|
case CONTNOTSUPPORTED: case VERIFCERTERR: case FILEBADFILE:
|
||||||
case FILEBADFILE:
|
case UNKNOWNATTR:
|
||||||
/* Fatal errors just return from the function. */
|
/* Fatal errors just return from the function. */
|
||||||
ret = err;
|
ret = err;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
case ATTRMISSING:
|
||||||
|
/* A missing attribute in a Header is a fatal Protocol error. */
|
||||||
|
logputs (LOG_VERBOSE, "\n");
|
||||||
|
logprintf (LOG_NOTQUIET, _("Required attribute missing from Header received.\n"));
|
||||||
|
ret = err;
|
||||||
|
goto exit;
|
||||||
|
case AUTHFAILED:
|
||||||
|
logputs (LOG_VERBOSE, "\n");
|
||||||
|
logprintf (LOG_NOTQUIET, _("Username/Password Authentication Failed.\n"));
|
||||||
|
ret = err;
|
||||||
|
goto exit;
|
||||||
case WARC_ERR:
|
case WARC_ERR:
|
||||||
/* A fatal WARC error. */
|
/* A fatal WARC error. */
|
||||||
logputs (LOG_VERBOSE, "\n");
|
logputs (LOG_VERBOSE, "\n");
|
||||||
@ -3677,7 +3707,7 @@ dump_hash (char *buf, const unsigned char *hash)
|
|||||||
static char *
|
static char *
|
||||||
digest_authentication_encode (const char *au, const char *user,
|
digest_authentication_encode (const char *au, const char *user,
|
||||||
const char *passwd, const char *method,
|
const char *passwd, const char *method,
|
||||||
const char *path)
|
const char *path, uerr_t *auth_err)
|
||||||
{
|
{
|
||||||
static char *realm, *opaque, *nonce, *qop, *algorithm;
|
static char *realm, *opaque, *nonce, *qop, *algorithm;
|
||||||
static struct {
|
static struct {
|
||||||
@ -3717,22 +3747,27 @@ digest_authentication_encode (const char *au, const char *user,
|
|||||||
if (qop != NULL && strcmp(qop,"auth"))
|
if (qop != NULL && strcmp(qop,"auth"))
|
||||||
{
|
{
|
||||||
logprintf (LOG_NOTQUIET, _("Unsupported quality of protection '%s'.\n"), qop);
|
logprintf (LOG_NOTQUIET, _("Unsupported quality of protection '%s'.\n"), qop);
|
||||||
user = NULL; /* force freeing mem and return */
|
xfree_null (qop); /* force freeing mem and return */
|
||||||
|
qop = NULL;
|
||||||
}
|
}
|
||||||
|
else if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
|
||||||
if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
|
|
||||||
{
|
{
|
||||||
logprintf (LOG_NOTQUIET, _("Unsupported algorithm '%s'.\n"), algorithm);
|
logprintf (LOG_NOTQUIET, _("Unsupported algorithm '%s'.\n"), algorithm);
|
||||||
user = NULL; /* force freeing mem and return */
|
xfree_null (qop); /* force freeing mem and return */
|
||||||
|
qop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!realm || !nonce || !user || !passwd || !path || !method)
|
if (!realm || !nonce || !user || !passwd || !path || !method || !qop)
|
||||||
{
|
{
|
||||||
xfree_null (realm);
|
xfree_null (realm);
|
||||||
xfree_null (opaque);
|
xfree_null (opaque);
|
||||||
xfree_null (nonce);
|
xfree_null (nonce);
|
||||||
xfree_null (qop);
|
xfree_null (qop);
|
||||||
xfree_null (algorithm);
|
xfree_null (algorithm);
|
||||||
|
if (!qop)
|
||||||
|
*auth_err = UNKNOWNATTR;
|
||||||
|
else
|
||||||
|
*auth_err = ATTRMISSING;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3902,7 +3937,7 @@ known_authentication_scheme_p (const char *hdrbeg, const char *hdrend)
|
|||||||
static char *
|
static char *
|
||||||
create_authorization_line (const char *au, const char *user,
|
create_authorization_line (const char *au, const char *user,
|
||||||
const char *passwd, const char *method,
|
const char *passwd, const char *method,
|
||||||
const char *path, bool *finished)
|
const char *path, bool *finished, uerr_t *auth_err)
|
||||||
{
|
{
|
||||||
/* We are called only with known schemes, so we can dispatch on the
|
/* We are called only with known schemes, so we can dispatch on the
|
||||||
first letter. */
|
first letter. */
|
||||||
@ -3914,7 +3949,7 @@ create_authorization_line (const char *au, const char *user,
|
|||||||
#ifdef ENABLE_DIGEST
|
#ifdef ENABLE_DIGEST
|
||||||
case 'D': /* Digest */
|
case 'D': /* Digest */
|
||||||
*finished = true;
|
*finished = true;
|
||||||
return digest_authentication_encode (au, user, passwd, method, path);
|
return digest_authentication_encode (au, user, passwd, method, path, auth_err);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_NTLM
|
#ifdef ENABLE_NTLM
|
||||||
case 'N': /* NTLM */
|
case 'N': /* NTLM */
|
||||||
|
@ -357,7 +357,7 @@ typedef enum
|
|||||||
PROXERR,
|
PROXERR,
|
||||||
/* 50 */
|
/* 50 */
|
||||||
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
|
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
|
||||||
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED,
|
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, ATTRMISSING, UNKNOWNATTR,
|
||||||
|
|
||||||
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR
|
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR
|
||||||
} uerr_t;
|
} uerr_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user