1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Remember that the NTLM-authorized TCP connections stay authorized.

This commit is contained in:
hniksic 2005-04-22 19:03:19 -07:00
parent 009d2ebcc4
commit 5bcaac1177
3 changed files with 62 additions and 9 deletions

View File

@ -1,3 +1,14 @@
2005-04-23 Hrvoje Niksic <hniksic@xemacs.org>
* cmpt.c: Reenable the memmove implementation for systems that
lack it.
* http.c (gethttp): Store the "authorized" state of the persistent
connection.
(request_remove_header): New function.
(gethttp): Don't send the "Basic" authentication if the connection
is already authorized.
2005-04-23 Hrvoje Niksic <hniksic@xemacs.org> 2005-04-23 Hrvoje Niksic <hniksic@xemacs.org>
* utils.c (base64_encode): Treat input as unsigned chars. * utils.c (base64_encode): Treat input as unsigned chars.

View File

@ -1435,10 +1435,6 @@ const unsigned short int __mon_yday[2][13] =
}; };
#endif #endif
/* Currently unused in Wget. Uncomment if we start using memmove
again. */
#if 0
#ifndef HAVE_MEMMOVE #ifndef HAVE_MEMMOVE
void * void *
memmove (char *dest, const char *source, unsigned length) memmove (char *dest, const char *source, unsigned length)
@ -1458,8 +1454,6 @@ memmove (char *dest, const char *source, unsigned length)
} }
#endif /* not HAVE_MEMMOVE */ #endif /* not HAVE_MEMMOVE */
#endif /* 0 */
/* fnmatch is a POSIX function, but we include an implementation for /* fnmatch is a POSIX function, but we include an implementation for
the sake of systems that don't have it. Furthermore, according to the sake of systems that don't have it. Furthermore, according to
anecdotal evidence, historical implementations of fnmatch are buggy anecdotal evidence, historical implementations of fnmatch are buggy

View File

@ -202,7 +202,7 @@ release_header (struct request_header *hdr)
/* Set the request named NAME to VALUE. Specifically, this means that /* Set the request named NAME to VALUE. Specifically, this means that
a "NAME: VALUE\r\n" header line will be used in the request. If a a "NAME: VALUE\r\n" header line will be used in the request. If a
header with the same name previously existed in the request, its header with the same name previously existed in the request, its
value will be replaced by this one. value will be replaced by this one. A NULL value means do nothing.
RELEASE_POLICY determines whether NAME and VALUE should be released RELEASE_POLICY determines whether NAME and VALUE should be released
(freed) with request_free. Allowed values are: (freed) with request_free. Allowed values are:
@ -233,6 +233,7 @@ request_set_header (struct request *req, char *name, char *value,
{ {
struct request_header *hdr; struct request_header *hdr;
int i; int i;
if (!value) if (!value)
{ {
/* A NULL value is a no-op; if freeing the name is requested, /* A NULL value is a no-op; if freeing the name is requested,
@ -241,6 +242,7 @@ request_set_header (struct request *req, char *name, char *value,
xfree (name); xfree (name);
return; return;
} }
for (i = 0; i < req->hcount; i++) for (i = 0; i < req->hcount; i++)
{ {
hdr = &req->headers[i]; hdr = &req->headers[i];
@ -260,8 +262,7 @@ request_set_header (struct request *req, char *name, char *value,
if (req->hcount >= req->hcapacity) if (req->hcount >= req->hcapacity)
{ {
req->hcapacity <<= 1; req->hcapacity <<= 1;
req->headers = xrealloc (req->headers, req->headers = xrealloc (req->headers, req->hcapacity * sizeof (*hdr));
req->hcapacity * sizeof (struct request_header));
} }
hdr = &req->headers[req->hcount++]; hdr = &req->headers[req->hcount++];
hdr->name = name; hdr->name = name;
@ -288,6 +289,29 @@ request_set_user_header (struct request *req, const char *header)
request_set_header (req, xstrdup (name), (char *) p, rel_name); request_set_header (req, xstrdup (name), (char *) p, rel_name);
} }
/* Remove the header with specified name from REQ. Returns 1 if the
header was actually removed, 0 otherwise. */
static int
request_remove_header (struct request *req, char *name)
{
int i;
for (i = 0; i < req->hcount; i++)
{
struct request_header *hdr = &req->headers[i];
if (0 == strcasecmp (name, hdr->name))
{
release_header (hdr);
/* Move the remaining headers by one. */
if (i < req->hcount - 1)
memmove (hdr, hdr + 1, (req->hcount - i - 1) * sizeof (*hdr));
--req->hcount;
return 1;
}
}
return 0;
}
#define APPEND(p, str) do { \ #define APPEND(p, str) do { \
int A_len = strlen (str); \ int A_len = strlen (str); \
memcpy (p, str, A_len); \ memcpy (p, str, A_len); \
@ -855,6 +879,12 @@ static struct {
/* Whether a ssl handshake has occoured on this connection. */ /* Whether a ssl handshake has occoured on this connection. */
int ssl; int ssl;
/* Whether the connection was authorized. This is only done by
NTLM, which authorizes *connections* rather than individual
requests. (That practice is peculiar for HTTP, but it is a
useful optimization.) */
int authorized;
#ifdef ENABLE_NTLM #ifdef ENABLE_NTLM
/* NTLM data of the current connection. */ /* NTLM data of the current connection. */
struct ntlmdata ntlm; struct ntlmdata ntlm;
@ -909,6 +939,7 @@ register_persistent (const char *host, int port, int fd, int ssl)
pconn.host = xstrdup (host); pconn.host = xstrdup (host);
pconn.port = port; pconn.port = port;
pconn.ssl = ssl; pconn.ssl = ssl;
pconn.authorized = 0;
DEBUGP (("Registered socket %d for persistent reuse.\n", fd)); DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
} }
@ -1113,6 +1144,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
not be tried again. */ not be tried again. */
int auth_finished = 0; int auth_finished = 0;
/* Whether NTLM authentication is used for this request. */
int ntlm_seen = 0;
/* Whether our connection to the remote host is through SSL. */ /* Whether our connection to the remote host is through SSL. */
int using_ssl = 0; int using_ssl = 0;
@ -1381,6 +1415,11 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"), logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
escnonprint (pconn.host), pconn.port); escnonprint (pconn.host), pconn.port);
DEBUGP (("Reusing fd %d.\n", sock)); DEBUGP (("Reusing fd %d.\n", sock));
if (pconn.authorized)
/* If the connection is already authorized, the "Basic"
authorization added by code above is unnecessary and
only hurts us. */
request_remove_header (req, "Authorization");
} }
} }
@ -1587,6 +1626,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
CLOSE_FINISH (sock); CLOSE_FINISH (sock);
else else
CLOSE_INVALIDATE (sock); CLOSE_INVALIDATE (sock);
pconn.authorized = 0;
if (auth_finished || !(user && passwd)) if (auth_finished || !(user && passwd))
{ {
/* If we have tried it already, then there is not point /* If we have tried it already, then there is not point
@ -1631,6 +1671,8 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
pth, pth,
&auth_finished), &auth_finished),
rel_value); rel_value);
if (BEGINS_WITH (www_authenticate, "NTLM"))
ntlm_seen = 1;
xfree (pth); xfree (pth);
xfree (www_authenticate); xfree (www_authenticate);
goto retry_with_auth; goto retry_with_auth;
@ -1639,6 +1681,12 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
request_free (req); request_free (req);
return AUTHFAILED; return AUTHFAILED;
} }
else /* statcode != HTTP_STATUS_UNAUTHORIZED */
{
/* Kludge: if NTLM is used, mark the TCP connection as authorized. */
if (ntlm_seen)
pconn.authorized = 1;
}
request_free (req); request_free (req);
hs->statcode = statcode; hs->statcode = statcode;