mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
General HTTP authentication cleanup and fixes
This commit is contained in:
parent
e7ee1ccf45
commit
fc6eff13b5
13
CHANGES
13
CHANGES
@ -6,6 +6,19 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Daniel (3 May 2004)
|
||||||
|
- Rewritten HTTP authentication code. The previous code could not properly
|
||||||
|
deal with the added test cases 167, 168 and 169. I've now rewritten the code
|
||||||
|
to better separate host and proxy authentication and not re-use the same
|
||||||
|
variables as much as before as it proved non working in the more involved
|
||||||
|
cases. All the current tests run OK now, and so do the new ones. The curl
|
||||||
|
tool got a new option named --proxy-digest to enable HTTP Digest
|
||||||
|
authentication with the proxy. I also made the library support it.
|
||||||
|
|
||||||
|
- Gisle Vanem made the LDAP code work with wldap32.dll as supplied with
|
||||||
|
Win-98/ME/2000/XP, so no extra .dlls are required when curl/libcurl is used
|
||||||
|
on these Windows versions.
|
||||||
|
|
||||||
Daniel (30 April 2004)
|
Daniel (30 April 2004)
|
||||||
- runtests.pl now scans the valgrind log for valgrind-detected memory leaks
|
- runtests.pl now scans the valgrind log for valgrind-detected memory leaks
|
||||||
after each test case if valgrind was found and used.
|
after each test case if valgrind was found and used.
|
||||||
|
@ -2,12 +2,14 @@ Curl and libcurl 7.12.0.
|
|||||||
|
|
||||||
Public curl release number: 81
|
Public curl release number: 81
|
||||||
Releases counted from the very beginning: 108
|
Releases counted from the very beginning: 108
|
||||||
Available command line options: 94
|
Available command line options: 95
|
||||||
Available curl_easy_setopt() options: 113
|
Available curl_easy_setopt() options: 113
|
||||||
Number of public functions in libcurl: 35
|
Number of public functions in libcurl: 35
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
|
o curl --proxy-digest is a new command line option
|
||||||
|
o the Windows version of libcurl can use wldap32.dll for LDAP
|
||||||
o curl_easy_strerror(), curl_multi_strerror() and curl_share_strerror()
|
o curl_easy_strerror(), curl_multi_strerror() and curl_share_strerror()
|
||||||
o IPv6-enabled Windows hosts now resolves names threaded/asynch as well
|
o IPv6-enabled Windows hosts now resolves names threaded/asynch as well
|
||||||
o configure --with-libidn can be used to point out the root dir of a libidn
|
o configure --with-libidn can be used to point out the root dir of a libidn
|
||||||
@ -16,6 +18,7 @@ This release includes the following changes:
|
|||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
|
o HTTP Digest authentication with the proxy works
|
||||||
o mulipart formposting with -F and file names with spaces work again
|
o mulipart formposting with -F and file names with spaces work again
|
||||||
o curl_easy_duphandle() now works when ares-enabled
|
o curl_easy_duphandle() now works when ares-enabled
|
||||||
o HTTP Digest authentication works a lot more like the RFC says
|
o HTTP Digest authentication works a lot more like the RFC says
|
||||||
|
428
lib/http.c
428
lib/http.c
@ -103,8 +103,6 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CURLcode Curl_output_basic_proxy(struct connectdata *conn);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* checkheaders() checks the linked list of custom HTTP headers for a
|
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||||
* particular header (prefix).
|
* particular header (prefix).
|
||||||
@ -124,23 +122,39 @@ static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_output_basic() sets up an Authorization: header for HTTP Basic
|
* Curl_output_basic() sets up an Authorization: header (or the proxy version)
|
||||||
* authentication. It uses the conn->user, conn->passwd fields for it.
|
* for HTTP Basic authentication.
|
||||||
*
|
*
|
||||||
* Returns CURLcode.
|
* Returns CURLcode.
|
||||||
*/
|
*/
|
||||||
static CURLcode Curl_output_basic(struct connectdata *conn)
|
static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
|
||||||
{
|
{
|
||||||
char *authorization;
|
char *authorization;
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
|
char **userp;
|
||||||
|
char *user;
|
||||||
|
char *pwd;
|
||||||
|
|
||||||
sprintf(data->state.buffer, "%s:%s", conn->user, conn->passwd);
|
if(proxy) {
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
userp = &conn->allocptr.proxyuserpwd;
|
||||||
|
user = conn->proxyuser;
|
||||||
|
pwd = conn->proxypasswd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
userp = &conn->allocptr.userpwd;
|
||||||
|
user = conn->user;
|
||||||
|
pwd = conn->passwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(data->state.buffer, "%s:%s", user, pwd);
|
||||||
|
if(Curl_base64_encode(data->state.buffer,
|
||||||
|
strlen(data->state.buffer),
|
||||||
&authorization) > 0) {
|
&authorization) > 0) {
|
||||||
if(conn->allocptr.userpwd)
|
if(*userp)
|
||||||
free(conn->allocptr.userpwd);
|
free(*userp);
|
||||||
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
*userp = aprintf( "%sAuthorization: Basic %s\015\012",
|
||||||
authorization);
|
proxy?"Proxy-":"",
|
||||||
|
authorization);
|
||||||
free(authorization);
|
free(authorization);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -148,61 +162,74 @@ static CURLcode Curl_output_basic(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* pickoneauth() selects the most favourable authentication method from the
|
||||||
* Curl_output_basic_proxy() sets up a proxy-Authorization: header for HTTP
|
* ones available and the ones we want.
|
||||||
* Basic proxy authentication. It uses the conn->proxyuser and
|
|
||||||
* conn->proxypasswd fields for it.
|
|
||||||
*
|
*
|
||||||
* Returns CURLcode.
|
* return TRUE if one was picked
|
||||||
*/
|
*/
|
||||||
static CURLcode Curl_output_basic_proxy(struct connectdata *conn)
|
static bool pickoneauth(struct auth *pick)
|
||||||
{
|
{
|
||||||
char *authorization;
|
bool picked;
|
||||||
struct SessionHandle *data=conn->data;
|
if(pick->avail) {
|
||||||
|
/* only deal with authentication we want */
|
||||||
|
long avail = pick->avail & pick->want;
|
||||||
|
picked = TRUE;
|
||||||
|
|
||||||
sprintf(data->state.buffer, "%s:%s",
|
|
||||||
conn->proxyuser, conn->proxypasswd);
|
|
||||||
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
|
|
||||||
&authorization) > 0) {
|
|
||||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
|
||||||
conn->allocptr.proxyuserpwd =
|
|
||||||
aprintf("Proxy-authorization: Basic %s\015\012", authorization);
|
|
||||||
free(authorization);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_http_auth_act() checks what authentication methods that are available
|
|
||||||
* and decides which one (if any) to use. It will set 'newurl' if an auth
|
|
||||||
* metod was picked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Curl_http_auth_act(struct connectdata *conn)
|
|
||||||
{
|
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
|
|
||||||
if(data->state.authavail) {
|
|
||||||
/* The order of these checks is highly relevant, as this will be the order
|
/* The order of these checks is highly relevant, as this will be the order
|
||||||
of preference in case of the existance of multiple accepted types. */
|
of preference in case of the existance of multiple accepted types. */
|
||||||
if(data->state.authavail & CURLAUTH_GSSNEGOTIATE)
|
if(avail & CURLAUTH_GSSNEGOTIATE)
|
||||||
data->state.authwant = CURLAUTH_GSSNEGOTIATE;
|
pick->picked = CURLAUTH_GSSNEGOTIATE;
|
||||||
else if(data->state.authavail & CURLAUTH_DIGEST)
|
else if(avail & CURLAUTH_DIGEST)
|
||||||
data->state.authwant = CURLAUTH_DIGEST;
|
pick->picked = CURLAUTH_DIGEST;
|
||||||
else if(data->state.authavail & CURLAUTH_NTLM)
|
else if(avail & CURLAUTH_NTLM)
|
||||||
data->state.authwant = CURLAUTH_NTLM;
|
pick->picked = CURLAUTH_NTLM;
|
||||||
else if(data->state.authavail & CURLAUTH_BASIC)
|
else if(avail & CURLAUTH_BASIC)
|
||||||
data->state.authwant = CURLAUTH_BASIC;
|
pick->picked = CURLAUTH_BASIC;
|
||||||
else
|
else {
|
||||||
data->state.authwant = CURLAUTH_NONE; /* clear it */
|
pick->picked = CURLAUTH_NONE; /* none was picked clear it */
|
||||||
|
picked = FALSE;
|
||||||
if(data->state.authwant)
|
}
|
||||||
conn->newurl = strdup(data->change.url); /* clone URL */
|
pick->avail = CURLAUTH_NONE; /* clear it here */
|
||||||
data->state.authavail = CURLAUTH_NONE; /* clear it here */
|
|
||||||
}
|
}
|
||||||
else if(!data->state.authdone && (data->info.httpcode < 400)) {
|
else
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return picked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_http_auth_act() gets called when a all HTTP headers have been received
|
||||||
|
* and it checks what authentication methods that are available and decides
|
||||||
|
* which one (if any) to use. It will set 'newurl' if an auth metod was
|
||||||
|
* picked.
|
||||||
|
*/
|
||||||
|
|
||||||
|
CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
bool pickhost;
|
||||||
|
bool pickproxy;
|
||||||
|
CURLcode code = CURLE_OK;
|
||||||
|
|
||||||
|
if(data->state.authproblem)
|
||||||
|
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
|
||||||
|
|
||||||
|
if(conn->bits.user_passwd) {
|
||||||
|
pickhost = pickoneauth(&data->state.authhost);
|
||||||
|
if(!pickhost && (conn->keep.httpcode == 401))
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
|
if(conn->bits.proxy_user_passwd) {
|
||||||
|
pickproxy = pickoneauth(&data->state.authproxy);
|
||||||
|
if(!pickproxy && (conn->keep.httpcode == 407))
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pickhost || pickproxy)
|
||||||
|
conn->newurl = strdup(data->change.url); /* clone URL */
|
||||||
|
|
||||||
|
else if((data->info.httpcode < 400) &&
|
||||||
|
(!data->state.authhost.done)) {
|
||||||
/* no (known) authentication available,
|
/* no (known) authentication available,
|
||||||
authentication is not "done" yet and
|
authentication is not "done" yet and
|
||||||
no authentication seems to be required and
|
no authentication seems to be required and
|
||||||
@ -210,23 +237,34 @@ void Curl_http_auth_act(struct connectdata *conn)
|
|||||||
if((data->set.httpreq != HTTPREQ_GET) &&
|
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||||
(data->set.httpreq != HTTPREQ_HEAD)) {
|
(data->set.httpreq != HTTPREQ_HEAD)) {
|
||||||
conn->newurl = strdup(data->change.url); /* clone URL */
|
conn->newurl = strdup(data->change.url); /* clone URL */
|
||||||
data->state.authdone = TRUE;
|
data->state.authhost.done = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Curl_http_should_fail(conn)) {
|
||||||
|
failf (data, "The requested URL returned error: %d",
|
||||||
|
conn->keep.httpcode);
|
||||||
|
code = CURLE_HTTP_RETURNED_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http_auth_headers() setups the authentication headers for the host/proxy
|
* Curl_http_output_auth() setups the authentication headers for the
|
||||||
* and the correct authentication method. conn->data->state.authdone is set to
|
* host/proxy and the correct authentication
|
||||||
* TRUE when authentication is done.
|
* method. conn->data->state.authdone is set to TRUE when authentication is
|
||||||
|
* done.
|
||||||
*
|
*
|
||||||
* @param conn all information about the current connection
|
* @param conn all information about the current connection
|
||||||
*
|
*
|
||||||
* Returns CURLcode
|
* Returns CURLcode
|
||||||
*/
|
*/
|
||||||
static CURLcode http_auth_headers(struct connectdata *conn,
|
static CURLcode
|
||||||
char *request,
|
Curl_http_output_auth(struct connectdata *conn,
|
||||||
char *path)
|
char *request,
|
||||||
|
char *path,
|
||||||
|
bool proxytunnel) /* TRUE if this is the request setting
|
||||||
|
up the proxy tunnel */
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
@ -234,19 +272,29 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
|
|
||||||
curlassert(data);
|
curlassert(data);
|
||||||
|
|
||||||
if(!data->state.authstage) {
|
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
||||||
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) {
|
conn->bits.user_passwd)
|
||||||
data->state.authdone = FALSE;
|
/* continue please */ ;
|
||||||
Curl_http_auth_stage(data, 407);
|
else {
|
||||||
}
|
data->state.authhost.done = TRUE;
|
||||||
else if(conn->bits.user_passwd) {
|
data->state.authproxy.done = TRUE;
|
||||||
data->state.authdone = FALSE;
|
return CURLE_OK; /* no authentication with no user or password */
|
||||||
Curl_http_auth_stage(data, 401);
|
}
|
||||||
}
|
|
||||||
else {
|
if(data->state.authhost.want &&
|
||||||
data->state.authdone = TRUE;
|
!data->state.authhost.picked) {
|
||||||
return CURLE_OK; /* no authentication with no user or password */
|
/* The app has selected one or more methods, but none has been picked
|
||||||
}
|
so far by a server round-trip. Then we set the picked one to the
|
||||||
|
want one, and if this is one single bit it'll be used instantly. */
|
||||||
|
data->state.authhost.picked = data->state.authhost.want;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data->state.authproxy.want &&
|
||||||
|
!data->state.authproxy.picked) {
|
||||||
|
/* The app has selected one or more methods, but none has been picked
|
||||||
|
so far by a server round-trip. Then we set the picked one to the
|
||||||
|
want one, and if this is one single bit it'll be used instantly. */
|
||||||
|
data->state.authproxy.picked = data->state.authproxy.want;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To prevent the user+password to get sent to other than the original
|
/* To prevent the user+password to get sent to other than the original
|
||||||
@ -256,10 +304,11 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
curl_strequal(data->state.auth_host, conn->host.name) ||
|
curl_strequal(data->state.auth_host, conn->host.name) ||
|
||||||
data->set.http_disable_hostname_check_before_authentication) {
|
data->set.http_disable_hostname_check_before_authentication) {
|
||||||
|
|
||||||
/* Send proxy authentication header if needed */
|
/* Send proxy authentication header if needed */
|
||||||
if (data->state.authstage == 407) {
|
if (conn->bits.httpproxy &&
|
||||||
|
(data->set.tunnel_thru_httpproxy == proxytunnel)) {
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authproxy.want == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, TRUE);
|
result = Curl_output_ntlm(conn, TRUE);
|
||||||
if(result)
|
if(result)
|
||||||
@ -267,39 +316,52 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(data->state.authwant == CURLAUTH_BASIC) {
|
if(data->state.authproxy.want == CURLAUTH_BASIC) {
|
||||||
/* Basic */
|
/* Basic */
|
||||||
if(conn->bits.proxy_user_passwd &&
|
if(conn->bits.proxy_user_passwd &&
|
||||||
!checkheaders(data, "Proxy-authorization:")) {
|
!checkheaders(data, "Proxy-authorization:")) {
|
||||||
auth=(char *)"Basic";
|
auth=(char *)"Basic";
|
||||||
result = Curl_output_basic_proxy(conn);
|
result = Curl_output_basic(conn, TRUE);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
data->state.authdone = TRUE;
|
data->state.authproxy.done = TRUE;
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
|
||||||
Curl_http_auth_stage(data, 401);
|
|
||||||
}
|
}
|
||||||
|
else if(data->state.authproxy.want == CURLAUTH_DIGEST) {
|
||||||
|
auth=(char *)"Digest";
|
||||||
|
result = Curl_output_digest(conn,
|
||||||
|
TRUE, /* proxy */
|
||||||
|
(unsigned char *)request,
|
||||||
|
(unsigned char *)path);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
infof(data, "Proxy auth using %s with user '%s'\n",
|
infof(data, "Proxy auth using %s with user '%s'\n",
|
||||||
auth, conn->proxyuser?conn->proxyuser:"");
|
auth, conn->proxyuser?conn->proxyuser:"");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
/* we have no proxy so let's pretend we're done authenticating
|
||||||
|
with it */
|
||||||
|
data->state.authproxy.done = TRUE;
|
||||||
|
|
||||||
/* Send web authentication header if needed */
|
/* Send web authentication header if needed */
|
||||||
if (data->state.authstage == 401) {
|
{
|
||||||
auth = NULL;
|
auth = NULL;
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
|
if((data->state.authhost.want == CURLAUTH_GSSNEGOTIATE) &&
|
||||||
data->state.negotiate.context &&
|
data->state.negotiate.context &&
|
||||||
!GSS_ERROR(data->state.negotiate.status)) {
|
!GSS_ERROR(data->state.negotiate.status)) {
|
||||||
auth=(char *)"GSS-Negotiate";
|
auth=(char *)"GSS-Negotiate";
|
||||||
result = Curl_output_negotiate(conn);
|
result = Curl_output_negotiate(conn);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
data->state.authdone = TRUE;
|
data->state.authhost.done = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authhost.picked == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, FALSE);
|
result = Curl_output_ntlm(conn, FALSE);
|
||||||
if(result)
|
if(result)
|
||||||
@ -308,26 +370,25 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if((data->state.authwant == CURLAUTH_DIGEST) &&
|
if(data->state.authhost.picked == CURLAUTH_DIGEST) {
|
||||||
data->state.digest.nonce) {
|
|
||||||
auth=(char *)"Digest";
|
auth=(char *)"Digest";
|
||||||
result = Curl_output_digest(conn,
|
result = Curl_output_digest(conn,
|
||||||
|
FALSE, /* not a proxy */
|
||||||
(unsigned char *)request,
|
(unsigned char *)request,
|
||||||
(unsigned char *)path);
|
(unsigned char *)path);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
data->state.authdone = TRUE;
|
|
||||||
}
|
}
|
||||||
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
|
else if(data->state.authhost.picked == CURLAUTH_BASIC) {
|
||||||
if(conn->bits.user_passwd &&
|
if(conn->bits.user_passwd &&
|
||||||
!checkheaders(data, "Authorization:")) {
|
!checkheaders(data, "Authorization:")) {
|
||||||
auth=(char *)"Basic";
|
auth=(char *)"Basic";
|
||||||
result = Curl_output_basic(conn);
|
result = Curl_output_basic(conn, FALSE);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* basic is always ready */
|
/* basic is always ready */
|
||||||
data->state.authdone = TRUE;
|
data->state.authhost.done = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(auth)
|
if(auth)
|
||||||
@ -336,21 +397,21 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
data->state.authdone = TRUE;
|
data->state.authhost.done = TRUE;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_http_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
|
* Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
|
||||||
* headers. They are dealt with both in the transfer.c main loop and in the
|
* headers. They are dealt with both in the transfer.c main loop and in the
|
||||||
* proxy CONNECT loop.
|
* proxy CONNECT loop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_http_auth(struct connectdata *conn,
|
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||||
int httpcode,
|
int httpcode,
|
||||||
char *header) /* pointing to the first non-space */
|
char *header) /* the first non-space */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This resource requires authentication
|
* This resource requires authentication
|
||||||
@ -359,23 +420,18 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
|
|
||||||
long *availp;
|
long *availp;
|
||||||
char *start;
|
char *start;
|
||||||
|
struct auth *authp;
|
||||||
|
|
||||||
if (httpcode == 407) {
|
if (httpcode == 407) {
|
||||||
start = header+strlen("Proxy-authenticate:");
|
start = header+strlen("Proxy-authenticate:");
|
||||||
availp = &data->info.proxyauthavail;
|
availp = &data->info.proxyauthavail;
|
||||||
|
authp = &data->state.authproxy;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
start = header+strlen("WWW-Authenticate:");
|
start = header+strlen("WWW-Authenticate:");
|
||||||
availp = &data->info.httpauthavail;
|
availp = &data->info.httpauthavail;
|
||||||
|
authp = &data->state.authhost;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Switch from proxy to web authentication and back if needed
|
|
||||||
*/
|
|
||||||
if (httpcode == 407 && data->state.authstage != 407)
|
|
||||||
Curl_http_auth_stage(data, 407);
|
|
||||||
|
|
||||||
else if (httpcode == 401 && data->state.authstage != 401)
|
|
||||||
Curl_http_auth_stage(data, 401);
|
|
||||||
|
|
||||||
/* pass all white spaces */
|
/* pass all white spaces */
|
||||||
while(*start && isspace((int)*start))
|
while(*start && isspace((int)*start))
|
||||||
@ -394,7 +450,8 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
if (checkprefix("GSS-Negotiate", start) ||
|
if (checkprefix("GSS-Negotiate", start) ||
|
||||||
checkprefix("Negotiate", start)) {
|
checkprefix("Negotiate", start)) {
|
||||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||||
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||||
|
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
|
||||||
/* if exactly this is wanted, go */
|
/* if exactly this is wanted, go */
|
||||||
int neg = Curl_input_negotiate(conn, start);
|
int neg = Curl_input_negotiate(conn, start);
|
||||||
if (neg == 0) {
|
if (neg == 0) {
|
||||||
@ -406,9 +463,6 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
|
||||||
data->state.authavail |= CURLAUTH_GSSNEGOTIATE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -416,76 +470,50 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
/* NTLM support requires the SSL crypto libs */
|
/* NTLM support requires the SSL crypto libs */
|
||||||
if(checkprefix("NTLM", start)) {
|
if(checkprefix("NTLM", start)) {
|
||||||
*availp |= CURLAUTH_NTLM;
|
*availp |= CURLAUTH_NTLM;
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
authp->avail |= CURLAUTH_NTLM;
|
||||||
/* NTLM authentication is activated */
|
if(authp->picked == CURLAUTH_NTLM) {
|
||||||
|
/* NTLM authentication is picked and activated */
|
||||||
CURLntlm ntlm =
|
CURLntlm ntlm =
|
||||||
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
||||||
|
|
||||||
if(CURLNTLM_BAD != ntlm) {
|
if(CURLNTLM_BAD != ntlm)
|
||||||
conn->newurl = strdup(data->change.url); /* clone string */
|
data->state.authproblem = FALSE;
|
||||||
data->state.authproblem = (conn->newurl == NULL);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if(data->state.authwant & CURLAUTH_NTLM)
|
|
||||||
data->state.authavail |= CURLAUTH_NTLM;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(checkprefix("Digest", start)) {
|
if(checkprefix("Digest", start)) {
|
||||||
|
CURLdigest dig;
|
||||||
*availp |= CURLAUTH_DIGEST;
|
*availp |= CURLAUTH_DIGEST;
|
||||||
if(data->state.authwant == CURLAUTH_DIGEST) {
|
authp->avail |= CURLAUTH_DIGEST;
|
||||||
/* Digest authentication is activated */
|
|
||||||
CURLdigest dig = Curl_input_digest(conn, start);
|
/* We call this function on input Digest headers even if Digest
|
||||||
|
* authentication isn't activated yet, as we need to store the
|
||||||
|
* incoming data from this header in case we are gonna use Digest. */
|
||||||
|
dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
|
||||||
|
|
||||||
if(CURLDIGEST_FINE == dig) {
|
if(CURLDIGEST_FINE != dig) {
|
||||||
/* We act on it. Store our new url, which happens to be
|
|
||||||
the same one we already use! */
|
|
||||||
conn->newurl = strdup(data->change.url); /* clone string */
|
|
||||||
data->state.authproblem = (conn->newurl == NULL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
|
||||||
data->state.authproblem = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(data->state.authwant & CURLAUTH_DIGEST) {
|
|
||||||
/* We don't know if Digest is what we're gonna use, but we
|
|
||||||
call this function anyway to store the digest data that
|
|
||||||
is provided on this line, to skip the extra round-trip
|
|
||||||
we need to do otherwise. We must sure to free this
|
|
||||||
data! */
|
|
||||||
Curl_input_digest(conn, start);
|
|
||||||
data->state.authavail |= CURLAUTH_DIGEST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(checkprefix("Basic", start)) {
|
|
||||||
*availp |= CURLAUTH_BASIC;
|
|
||||||
if((data->state.authwant == CURLAUTH_BASIC) &&
|
|
||||||
(httpcode == data->state.authstage)) {
|
|
||||||
/* We asked for Basic authentication but got a 40X back
|
|
||||||
anyway, which basicly means our name+password isn't
|
|
||||||
valid. */
|
|
||||||
data->state.authavail = CURLAUTH_NONE;
|
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
else if(data->state.authwant & CURLAUTH_BASIC) {
|
}
|
||||||
data->state.authavail |= CURLAUTH_BASIC;
|
else if(checkprefix("Basic", start)) {
|
||||||
} else {
|
*availp |= CURLAUTH_BASIC;
|
||||||
/*
|
authp->avail |= CURLAUTH_BASIC;
|
||||||
** We asked for something besides basic but got
|
if(authp->picked == CURLAUTH_BASIC) {
|
||||||
** Basic anyway. This is no good.
|
/* We asked for Basic authentication but got a 40X back
|
||||||
*/
|
anyway, which basicly means our name+password isn't
|
||||||
infof(data, "Server expects Basic auth, but we're doing something else.\n");
|
valid. */
|
||||||
data->state.authproblem = TRUE;
|
authp->avail = CURLAUTH_NONE;
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,15 +590,16 @@ int Curl_http_should_fail(struct connectdata *conn)
|
|||||||
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
|
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (data->state.authstage &&
|
|
||||||
(data->state.authstage == k->httpcode))
|
|
||||||
return (data->state.authdone || data->state.authproblem);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Either we're not authenticating, or we're supposed to
|
** Either we're not authenticating, or we're supposed to
|
||||||
** be authenticating something else. This is an error.
|
** be authenticating something else. This is an error.
|
||||||
*/
|
*/
|
||||||
return 1;
|
if((k->httpcode == 401) && !conn->bits.user_passwd)
|
||||||
|
return TRUE;
|
||||||
|
if((k->httpcode == 407) && !conn->bits.proxy_user_passwd)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return data->state.authproblem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -876,9 +905,9 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
char *hostname,
|
char *hostname,
|
||||||
int remote_port)
|
int remote_port)
|
||||||
{
|
{
|
||||||
int httpcode=0;
|
|
||||||
int subversion=0;
|
int subversion=0;
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
|
struct Curl_transfer_keeper *k = &conn->keep;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -916,7 +945,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Setup the proxy-authorization header, if any */
|
/* Setup the proxy-authorization header, if any */
|
||||||
result = http_auth_headers(conn, (char *)"CONNECT", host_port);
|
result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
|
||||||
if(CURLE_OK == result) {
|
if(CURLE_OK == result) {
|
||||||
|
|
||||||
/* OK, now send the connect request to the proxy */
|
/* OK, now send the connect request to the proxy */
|
||||||
@ -1039,18 +1068,18 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
letter = line_start[perline];
|
letter = line_start[perline];
|
||||||
line_start[perline]=0; /* zero terminate the buffer */
|
line_start[perline]=0; /* zero terminate the buffer */
|
||||||
if((checkprefix("WWW-Authenticate:", line_start) &&
|
if((checkprefix("WWW-Authenticate:", line_start) &&
|
||||||
(401 == httpcode)) ||
|
(401 == k->httpcode)) ||
|
||||||
(checkprefix("Proxy-authenticate:", line_start) &&
|
(checkprefix("Proxy-authenticate:", line_start) &&
|
||||||
(407 == httpcode))) {
|
(407 == k->httpcode))) {
|
||||||
result = Curl_http_auth(conn, httpcode, line_start);
|
result = Curl_http_input_auth(conn, k->httpcode, line_start);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||||
&subversion,
|
&subversion,
|
||||||
&httpcode)) {
|
&k->httpcode)) {
|
||||||
/* store the HTTP code */
|
/* store the HTTP code */
|
||||||
data->info.httpproxycode = httpcode;
|
data->info.httpproxycode = k->httpcode;
|
||||||
}
|
}
|
||||||
/* put back the letter we blanked out before */
|
/* put back the letter we blanked out before */
|
||||||
line_start[perline]= letter;
|
line_start[perline]= letter;
|
||||||
@ -1073,8 +1102,9 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
|
|
||||||
} while(conn->newurl);
|
} while(conn->newurl);
|
||||||
|
|
||||||
if(200 != httpcode) {
|
if(200 != k->httpcode) {
|
||||||
failf(data, "Received HTTP code %d from proxy after CONNECT", httpcode);
|
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||||
|
k->httpcode);
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,7 +1114,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||||
conn->allocptr.proxyuserpwd = NULL;
|
conn->allocptr.proxyuserpwd = NULL;
|
||||||
|
|
||||||
Curl_http_auth_stage(data, 401); /* move on to the host auth */
|
data->state.authproxy.done = TRUE;
|
||||||
|
|
||||||
infof (data, "Proxy replied OK to CONNECT request\n");
|
infof (data, "Proxy replied OK to CONNECT request\n");
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@ -1189,24 +1219,6 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_http_auth_stage() sets the "authentication stage" - which is 407 for
|
|
||||||
* proxy authentication or 401 for host authentication.
|
|
||||||
*/
|
|
||||||
void Curl_http_auth_stage(struct SessionHandle *data,
|
|
||||||
int stage)
|
|
||||||
{
|
|
||||||
curlassert((stage == 401) || (stage == 407));
|
|
||||||
|
|
||||||
/* We set none, one or more bits for which authentication types we accept
|
|
||||||
for this stage. */
|
|
||||||
data->state.authwant = (stage == 401)?
|
|
||||||
data->set.httpauth:data->set.proxyauth;
|
|
||||||
|
|
||||||
data->state.authstage = stage;
|
|
||||||
data->state.authavail = CURLAUTH_NONE; /* no type available yet */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
||||||
* request is to be performed. This creates and sends a propperly constructed
|
* request is to be performed. This creates and sends a propperly constructed
|
||||||
@ -1284,11 +1296,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup the authentication headers */
|
/* setup the authentication headers */
|
||||||
result = http_auth_headers(conn, request, ppath);
|
result = Curl_http_output_auth(conn, request, ppath, FALSE);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if(!data->state.authdone && (httpreq != HTTPREQ_GET)) {
|
if((!data->state.authhost.done || !data->state.authproxy.done ) &&
|
||||||
|
(httpreq != HTTPREQ_GET)) {
|
||||||
/* Until we are authenticated, we switch over to HEAD. Unless its a GET
|
/* Until we are authenticated, we switch over to HEAD. Unless its a GET
|
||||||
we want to do. The explanation for this is rather long and boring, but
|
we want to do. The explanation for this is rather long and boring, but
|
||||||
the point is that it can't be done otherwise without risking having to
|
the point is that it can't be done otherwise without risking having to
|
||||||
@ -1583,7 +1596,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
request,
|
request,
|
||||||
ppath,
|
ppath,
|
||||||
httpstring,
|
httpstring,
|
||||||
(conn->bits.httpproxy && conn->allocptr.proxyuserpwd)?
|
conn->allocptr.proxyuserpwd?
|
||||||
conn->allocptr.proxyuserpwd:"",
|
conn->allocptr.proxyuserpwd:"",
|
||||||
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||||
(conn->bits.use_range && conn->allocptr.rangeline)?
|
(conn->bits.use_range && conn->allocptr.rangeline)?
|
||||||
@ -1755,8 +1768,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* setup variables for the upcoming transfer */
|
/* setup variables for the upcoming transfer */
|
||||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
data->state.authdone?FIRSTSOCKET:-1,
|
FIRSTSOCKET,
|
||||||
data->state.authdone?&http->writebytecount:NULL);
|
&http->writebytecount);
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_formclean(http->sendit); /* free that whole lot */
|
Curl_formclean(http->sendit); /* free that whole lot */
|
||||||
return result;
|
return result;
|
||||||
@ -1794,8 +1807,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* prepare for transfer */
|
/* prepare for transfer */
|
||||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
data->state.authdone?FIRSTSOCKET:-1,
|
FIRSTSOCKET,
|
||||||
data->state.authdone?&http->writebytecount:NULL);
|
&http->writebytecount);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
break;
|
break;
|
||||||
@ -1826,7 +1839,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
|
|
||||||
if(data->set.postfields) {
|
if(data->set.postfields) {
|
||||||
|
|
||||||
if(data->state.authdone && (postsize < (100*1024))) {
|
if((data->state.authhost.done || data->state.authproxy.done )
|
||||||
|
&& (postsize < (100*1024))) {
|
||||||
/* If we're not done with the authentication phase, we don't expect
|
/* If we're not done with the authentication phase, we don't expect
|
||||||
to actually send off any data yet. Hence, we delay the sending of
|
to actually send off any data yet. Hence, we delay the sending of
|
||||||
the body until we receive that friendly 100-continue response */
|
the body until we receive that friendly 100-continue response */
|
||||||
@ -1862,7 +1876,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||||
|
|
||||||
if(!data->state.authdone && !checkheaders(data, "Expect:")) {
|
if(!checkheaders(data, "Expect:")) {
|
||||||
/* if not disabled explicitly we add a Expect: 100-continue to the
|
/* if not disabled explicitly we add a Expect: 100-continue to the
|
||||||
headers which actually speeds up post operations (as there is
|
headers which actually speeds up post operations (as there is
|
||||||
one packet coming back from the web server) */
|
one packet coming back from the web server) */
|
||||||
|
@ -45,9 +45,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
|||||||
|
|
||||||
/* These functions are in http.c */
|
/* These functions are in http.c */
|
||||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||||
CURLcode Curl_http_auth(struct connectdata *conn,
|
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||||
int httpcode, char *header);
|
int httpcode, char *header);
|
||||||
void Curl_http_auth_act(struct connectdata *conn);
|
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||||
|
|
||||||
int Curl_http_should_fail(struct connectdata *conn);
|
int Curl_http_should_fail(struct connectdata *conn);
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,14 +47,16 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Test example header:
|
/* Test example headers:
|
||||||
|
|
||||||
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||||
|
Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||||
char *header) /* rest of the www-authenticate:
|
bool proxy,
|
||||||
|
char *header) /* rest of the *-authenticate:
|
||||||
header */
|
header */
|
||||||
{
|
{
|
||||||
bool more = TRUE;
|
bool more = TRUE;
|
||||||
@ -64,7 +66,14 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
bool foundAuthInt = FALSE;
|
bool foundAuthInt = FALSE;
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
bool before = FALSE; /* got a nonce before */
|
bool before = FALSE; /* got a nonce before */
|
||||||
struct digestdata *d = &data->state.digest;
|
struct digestdata *d;
|
||||||
|
|
||||||
|
if(proxy) {
|
||||||
|
d = &data->state.proxydigest;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = &data->state.digest;
|
||||||
|
}
|
||||||
|
|
||||||
/* skip initial whitespaces */
|
/* skip initial whitespaces */
|
||||||
while(*header && isspace((int)*header))
|
while(*header && isspace((int)*header))
|
||||||
@ -78,7 +87,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
before = TRUE;
|
before = TRUE;
|
||||||
|
|
||||||
/* clear off any former leftovers and init to defaults */
|
/* clear off any former leftovers and init to defaults */
|
||||||
Curl_digest_cleanup(data);
|
Curl_digest_cleanup_one(d);
|
||||||
|
|
||||||
while(more) {
|
while(more) {
|
||||||
char value[32];
|
char value[32];
|
||||||
@ -183,6 +192,7 @@ static void md5_to_ascii(unsigned char *source, /* 16 bytes */
|
|||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||||
|
bool proxy,
|
||||||
unsigned char *request,
|
unsigned char *request,
|
||||||
unsigned char *uripath)
|
unsigned char *uripath)
|
||||||
{
|
{
|
||||||
@ -198,9 +208,28 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
char *cnonce;
|
char *cnonce;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
struct auth *authp;
|
||||||
|
char **userp;
|
||||||
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct digestdata *d = &data->state.digest;
|
struct digestdata *d;
|
||||||
|
|
||||||
|
if(proxy) {
|
||||||
|
d = &data->state.proxydigest;
|
||||||
|
authp = &data->state.authproxy;
|
||||||
|
userp = &conn->allocptr.proxyuserpwd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = &data->state.digest;
|
||||||
|
authp = &data->state.authhost;
|
||||||
|
userp = &conn->allocptr.userpwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!d->nonce) {
|
||||||
|
authp->done = FALSE;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
authp->done = TRUE;
|
||||||
|
|
||||||
ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */
|
ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */
|
||||||
|
|
||||||
@ -293,8 +322,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
Curl_safefree(conn->allocptr.userpwd);
|
Curl_safefree(conn->allocptr.userpwd);
|
||||||
|
|
||||||
if (d->qop) {
|
if (d->qop) {
|
||||||
conn->allocptr.userpwd =
|
*userp =
|
||||||
aprintf( "Authorization: Digest "
|
aprintf( "%sAuthorization: Digest "
|
||||||
"username=\"%s\", "
|
"username=\"%s\", "
|
||||||
"realm=\"%s\", "
|
"realm=\"%s\", "
|
||||||
"nonce=\"%s\", "
|
"nonce=\"%s\", "
|
||||||
@ -303,6 +332,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
"nc=\"%08x\", "
|
"nc=\"%08x\", "
|
||||||
"qop=\"%s\", "
|
"qop=\"%s\", "
|
||||||
"response=\"%s\"",
|
"response=\"%s\"",
|
||||||
|
proxy?"Proxy-":"",
|
||||||
conn->user,
|
conn->user,
|
||||||
d->realm,
|
d->realm,
|
||||||
d->nonce,
|
d->nonce,
|
||||||
@ -318,13 +348,14 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
same nonce in the qop=auth mode. */
|
same nonce in the qop=auth mode. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn->allocptr.userpwd =
|
*userp =
|
||||||
aprintf( "Authorization: Digest "
|
aprintf( "%sAuthorization: Digest "
|
||||||
"username=\"%s\", "
|
"username=\"%s\", "
|
||||||
"realm=\"%s\", "
|
"realm=\"%s\", "
|
||||||
"nonce=\"%s\", "
|
"nonce=\"%s\", "
|
||||||
"uri=\"%s\", "
|
"uri=\"%s\", "
|
||||||
"response=\"%s\"",
|
"response=\"%s\"",
|
||||||
|
proxy?"Proxy-":"",
|
||||||
conn->user,
|
conn->user,
|
||||||
d->realm,
|
d->realm,
|
||||||
d->nonce,
|
d->nonce,
|
||||||
@ -336,36 +367,28 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
if(d->opaque) {
|
if(d->opaque) {
|
||||||
/* append opaque */
|
/* append opaque */
|
||||||
tmp = aprintf(", opaque=\"%s\"", d->opaque);
|
tmp = aprintf(", opaque=\"%s\"", d->opaque);
|
||||||
conn->allocptr.userpwd = (char*)
|
*userp = (char*) realloc(*userp, strlen(*userp) + strlen(tmp) + 1);
|
||||||
realloc(conn->allocptr.userpwd,
|
strcat(*userp, tmp);
|
||||||
strlen(conn->allocptr.userpwd) + strlen(tmp) + 1);
|
|
||||||
strcat(conn->allocptr.userpwd, tmp);
|
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d->algorithm) {
|
if(d->algorithm) {
|
||||||
/* append algorithm */
|
/* append algorithm */
|
||||||
tmp = aprintf(", algorithm=\"%s\"", d->algorithm);
|
tmp = aprintf(", algorithm=\"%s\"", d->algorithm);
|
||||||
conn->allocptr.userpwd = (char*)
|
*userp = (char*) realloc(*userp, strlen(*userp) + strlen(tmp) + 1);
|
||||||
realloc(conn->allocptr.userpwd,
|
|
||||||
strlen(conn->allocptr.userpwd) + strlen(tmp) + 1);
|
|
||||||
strcat(conn->allocptr.userpwd, tmp);
|
strcat(conn->allocptr.userpwd, tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append CRLF to the userpwd header */
|
/* append CRLF to the userpwd header */
|
||||||
conn->allocptr.userpwd = (char*)
|
*userp = (char*) realloc(*userp, strlen(*userp) + 3 + 1);
|
||||||
realloc(conn->allocptr.userpwd,
|
strcat(*userp, "\r\n");
|
||||||
strlen(conn->allocptr.userpwd) + 3 + 1);
|
|
||||||
strcat(conn->allocptr.userpwd, "\r\n");
|
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
void Curl_digest_cleanup_one(struct digestdata *d)
|
||||||
{
|
{
|
||||||
struct digestdata *d = &data->state.digest;
|
|
||||||
|
|
||||||
if(d->nonce)
|
if(d->nonce)
|
||||||
free(d->nonce);
|
free(d->nonce);
|
||||||
d->nonce = NULL;
|
d->nonce = NULL;
|
||||||
@ -395,4 +418,11 @@ void Curl_digest_cleanup(struct SessionHandle *data)
|
|||||||
d->stale = FALSE; /* default means normal, not stale */
|
d->stale = FALSE; /* default means normal, not stale */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
Curl_digest_cleanup_one(&data->state.digest);
|
||||||
|
Curl_digest_cleanup_one(&data->state.proxydigest);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,12 +38,15 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* this is for digest header input */
|
/* this is for digest header input */
|
||||||
CURLdigest Curl_input_digest(struct connectdata *conn, char *header);
|
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||||
|
bool proxy, char *header);
|
||||||
|
|
||||||
/* this is for creating digest header output */
|
/* this is for creating digest header output */
|
||||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||||
|
bool proxy,
|
||||||
unsigned char *request,
|
unsigned char *request,
|
||||||
unsigned char *uripath);
|
unsigned char *uripath);
|
||||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||||
|
void Curl_digest_cleanup_one(struct digestdata *dig);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "http_ntlm.h"
|
#include "http_ntlm.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "http.h" /* for Curl_http_auth_stage() */
|
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@ -298,23 +297,26 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
char *passwdp;
|
char *passwdp;
|
||||||
/* point to the correct struct with this */
|
/* point to the correct struct with this */
|
||||||
struct ntlmdata *ntlm;
|
struct ntlmdata *ntlm;
|
||||||
|
struct auth *authp;
|
||||||
|
|
||||||
curlassert(conn);
|
curlassert(conn);
|
||||||
curlassert(conn->data);
|
curlassert(conn->data);
|
||||||
conn->data->state.authdone = FALSE;
|
|
||||||
|
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||||
userp = conn->proxyuser;
|
userp = conn->proxyuser;
|
||||||
passwdp = conn->proxypasswd;
|
passwdp = conn->proxypasswd;
|
||||||
ntlm = &conn->proxyntlm;
|
ntlm = &conn->proxyntlm;
|
||||||
|
authp = &conn->data->state.authproxy;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
allocuserpwd = &conn->allocptr.userpwd;
|
allocuserpwd = &conn->allocptr.userpwd;
|
||||||
userp = conn->user;
|
userp = conn->user;
|
||||||
passwdp = conn->passwd;
|
passwdp = conn->passwd;
|
||||||
ntlm = &conn->ntlm;
|
ntlm = &conn->ntlm;
|
||||||
|
authp = &conn->data->state.authhost;
|
||||||
}
|
}
|
||||||
|
authp->done = FALSE;
|
||||||
|
|
||||||
/* not set means empty */
|
/* not set means empty */
|
||||||
if(!userp)
|
if(!userp)
|
||||||
@ -563,11 +565,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||||
|
|
||||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||||
conn->data->state.authdone = TRUE;
|
authp->done = TRUE;
|
||||||
|
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
|
||||||
if (proxy)
|
|
||||||
Curl_http_auth_stage(conn->data, 401);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -578,7 +576,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
free(*allocuserpwd);
|
free(*allocuserpwd);
|
||||||
*allocuserpwd=NULL;
|
*allocuserpwd=NULL;
|
||||||
}
|
}
|
||||||
conn->data->state.authdone = TRUE;
|
authp->done = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,9 +445,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Now that all of the headers have been parsed, see
|
* When all the headers have been parsed, see if we should give
|
||||||
** if we should give up and return an error.
|
* up and return an error.
|
||||||
*/
|
*/
|
||||||
if (Curl_http_should_fail(conn)) {
|
if (Curl_http_should_fail(conn)) {
|
||||||
failf (data, "The requested URL returned error: %d",
|
failf (data, "The requested URL returned error: %d",
|
||||||
k->httpcode);
|
k->httpcode);
|
||||||
@ -483,19 +483,23 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* we wanted to resume a download, although the server
|
/* we wanted to resume a download, although the server
|
||||||
doesn't seem to support this and we did this with a GET
|
* doesn't seem to support this and we did this with a GET
|
||||||
(if it wasn't a GET we did a POST or PUT resume) */
|
* (if it wasn't a GET we did a POST or PUT resume) */
|
||||||
failf (data, "HTTP server doesn't seem to support "
|
failf (data, "HTTP server doesn't seem to support "
|
||||||
"byte ranges. Cannot resume.");
|
"byte ranges. Cannot resume.");
|
||||||
return CURLE_HTTP_RANGE_ERROR;
|
return CURLE_HTTP_RANGE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!stop_reading)
|
if(!stop_reading) {
|
||||||
/* *auth_act() checks what authentication methods that are
|
/* Curl_http_auth_act() checks what authentication methods
|
||||||
available and decides which one (if any) to use. It will
|
* that are available and decides which one (if any) to
|
||||||
set 'newurl' if an auth metod was picked. */
|
* use. It will set 'newurl' if an auth metod was picked. */
|
||||||
Curl_http_auth_act(conn);
|
result = Curl_http_auth_act(conn);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if(!k->header) {
|
if(!k->header) {
|
||||||
/*
|
/*
|
||||||
@ -593,22 +597,17 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
data->info.httpversion = k->httpversion;
|
data->info.httpversion = k->httpversion;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This code executes as part of processing
|
* This code executes as part of processing the header. As a
|
||||||
** the header. As a result, it's not
|
* result, it's not totally clear how to interpret the
|
||||||
** totally clear how to interpret the
|
* response code yet as that depends on what other headers may
|
||||||
** response code yet as that depends on what
|
* be present. 401 and 407 may be errors, but may be OK
|
||||||
** other headers may be present. 401 and
|
* depending on how authentication is working. Other codes
|
||||||
** 407 may be errors, but may be OK
|
* are definitely errors, so give up here.
|
||||||
** depending on how authentication is
|
*/
|
||||||
** working. Other codes are definitely
|
|
||||||
** errors, so give up here.
|
|
||||||
*/
|
|
||||||
if (data->set.http_fail_on_error &&
|
if (data->set.http_fail_on_error &&
|
||||||
(k->httpcode >= 400) &&
|
(k->httpcode >= 400) &&
|
||||||
(k->httpcode != 401) &&
|
(k->httpcode != 401) &&
|
||||||
(k->httpcode != 407)) {
|
(k->httpcode != 407)) {
|
||||||
/* If we have been told to fail hard on HTTP-errors,
|
|
||||||
here is the check for that: */
|
|
||||||
/* serious error, go home! */
|
/* serious error, go home! */
|
||||||
failf (data, "The requested URL returned error: %d",
|
failf (data, "The requested URL returned error: %d",
|
||||||
k->httpcode);
|
k->httpcode);
|
||||||
@ -821,7 +820,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
(401 == k->httpcode)) ||
|
(401 == k->httpcode)) ||
|
||||||
(checkprefix("Proxy-authenticate:", k->p) &&
|
(checkprefix("Proxy-authenticate:", k->p) &&
|
||||||
(407 == k->httpcode))) {
|
(407 == k->httpcode))) {
|
||||||
result = Curl_http_auth(conn, k->httpcode, k->p);
|
result = Curl_http_input_auth(conn, k->httpcode, k->p);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1514,10 +1513,9 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
|||||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||||
data->state.errorbuf = FALSE; /* no error has occurred */
|
data->state.errorbuf = FALSE; /* no error has occurred */
|
||||||
|
|
||||||
/* set preferred authentication, default to basic */
|
|
||||||
|
|
||||||
data->state.authstage = 0; /* initialize authentication later */
|
|
||||||
data->state.authproblem = FALSE;
|
data->state.authproblem = FALSE;
|
||||||
|
data->state.authhost.want = data->set.httpauth;
|
||||||
|
data->state.authproxy.want = data->set.proxyauth;
|
||||||
|
|
||||||
/* If there was a list of cookie files to read and we haven't done it before,
|
/* If there was a list of cookie files to read and we haven't done it before,
|
||||||
do it now! */
|
do it now! */
|
||||||
|
22
lib/url.c
22
lib/url.c
@ -1332,9 +1332,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
|
|
||||||
CURLcode Curl_disconnect(struct connectdata *conn)
|
CURLcode Curl_disconnect(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
|
struct SessionHandle *data;
|
||||||
if(!conn)
|
if(!conn)
|
||||||
return CURLE_OK; /* this is closed and fine already */
|
return CURLE_OK; /* this is closed and fine already */
|
||||||
|
|
||||||
|
data = conn->data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The range string is usually freed in curl_done(), but we might
|
* The range string is usually freed in curl_done(), but we might
|
||||||
* get here *instead* if we fail prematurely. Thus we need to be able
|
* get here *instead* if we fail prematurely. Thus we need to be able
|
||||||
@ -1346,11 +1349,20 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((conn->ntlm.state != NTLMSTATE_NONE) ||
|
if((conn->ntlm.state != NTLMSTATE_NONE) ||
|
||||||
(conn->proxyntlm.state != NTLMSTATE_NONE))
|
(conn->proxyntlm.state != NTLMSTATE_NONE)) {
|
||||||
/* Authentication data is a mix of connection-related and sessionhandle-
|
/* Authentication data is a mix of connection-related and sessionhandle-
|
||||||
related stuff. NTLM is connection-related so when we close the shop
|
related stuff. NTLM is connection-related so when we close the shop
|
||||||
we shall forget. */
|
we shall forget. */
|
||||||
conn->data->state.authstage = 0;
|
data->state.authhost.done = FALSE;
|
||||||
|
data->state.authhost.picked =
|
||||||
|
data->state.authhost.want;
|
||||||
|
|
||||||
|
data->state.authproxy.done = FALSE;
|
||||||
|
data->state.authproxy.picked =
|
||||||
|
data->state.authhost.want;
|
||||||
|
|
||||||
|
data->state.authproblem = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(conn->curl_disconnect)
|
if(conn->curl_disconnect)
|
||||||
/* This is set if protocol-specific cleanups should be made */
|
/* This is set if protocol-specific cleanups should be made */
|
||||||
@ -1358,8 +1370,8 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
|
|
||||||
if(-1 != conn->connectindex) {
|
if(-1 != conn->connectindex) {
|
||||||
/* unlink ourselves! */
|
/* unlink ourselves! */
|
||||||
infof(conn->data, "Closing connection #%d\n", conn->connectindex);
|
infof(data, "Closing connection #%d\n", conn->connectindex);
|
||||||
conn->data->state.connects[conn->connectindex] = NULL;
|
data->state.connects[conn->connectindex] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(conn->proto.generic);
|
Curl_safefree(conn->proto.generic);
|
||||||
@ -1488,7 +1500,7 @@ ConnectionExists(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
if((needle->protocol & PROT_FTP) ||
|
if((needle->protocol & PROT_FTP) ||
|
||||||
((needle->protocol & PROT_HTTP) &&
|
((needle->protocol & PROT_HTTP) &&
|
||||||
(needle->data->state.authwant==CURLAUTH_NTLM))) {
|
(needle->data->state.authhost.want==CURLAUTH_NTLM))) {
|
||||||
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
||||||
and password as well */
|
and password as well */
|
||||||
if(!strequal(needle->user, check->user) ||
|
if(!strequal(needle->user, check->user) ||
|
||||||
|
@ -678,6 +678,16 @@ typedef enum {
|
|||||||
#define MAX_CURL_USER_LENGTH_TXT "255"
|
#define MAX_CURL_USER_LENGTH_TXT "255"
|
||||||
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
|
#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
|
||||||
|
|
||||||
|
struct auth {
|
||||||
|
long want; /* Bitmask set to the authentication methods wanted by the app
|
||||||
|
(with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
|
||||||
|
long picked;
|
||||||
|
long avail; /* bitmask for what the server reports to support for this
|
||||||
|
resource */
|
||||||
|
bool done; /* TRUE when the auth phase is done and ready to do the *actual*
|
||||||
|
request */
|
||||||
|
};
|
||||||
|
|
||||||
struct UrlState {
|
struct UrlState {
|
||||||
enum {
|
enum {
|
||||||
Curl_if_none,
|
Curl_if_none,
|
||||||
@ -724,22 +734,16 @@ struct UrlState {
|
|||||||
is always set TRUE when curl_easy_perform() is called. */
|
is always set TRUE when curl_easy_perform() is called. */
|
||||||
|
|
||||||
struct digestdata digest;
|
struct digestdata digest;
|
||||||
|
struct digestdata proxydigest;
|
||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
struct negotiatedata negotiate;
|
struct negotiatedata negotiate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long authstage; /* 0 - authwant and authavail are still not initialized
|
struct auth authhost;
|
||||||
401 - web authentication is performed
|
struct auth authproxy;
|
||||||
407 - proxy authentication is performed */
|
|
||||||
long authwant; /* initially set to authentication methods requested by
|
|
||||||
client (either with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH
|
|
||||||
depending on authstage) */
|
|
||||||
long authavail; /* what the server reports */
|
|
||||||
|
|
||||||
bool authproblem; /* TRUE if there's some problem authenticating */
|
bool authproblem; /* TRUE if there's some problem authenticating */
|
||||||
bool authdone; /* TRUE when the auth phase is done and ready
|
|
||||||
to do the *actual* request */
|
|
||||||
#ifdef USE_ARES
|
#ifdef USE_ARES
|
||||||
ares_channel areschannel; /* for name resolves */
|
ares_channel areschannel; /* for name resolves */
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,26 +3,27 @@ install:
|
|||||||
test:
|
test:
|
||||||
|
|
||||||
EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
||||||
test10 test109 test118 test13 test200 test28 test36 test47 test100 \
|
test10 test109 test118 test13 test200 test28 test36 test47 test100 \
|
||||||
test11 test119 test14 test201 test29 test37 test5 test101 test110 \
|
test11 test119 test14 test201 test29 test37 test5 test101 test110 \
|
||||||
test12 test15 test202 test3 test4 test6 test102 test111 test120 test16 \
|
test12 test15 test202 test3 test4 test6 test102 test111 test120 \
|
||||||
test21 test30 test7 test103 test112 test121 test17 test22 test300 \
|
test16 test21 test30 test7 test103 test112 test121 test17 test22 \
|
||||||
test8 test104 test113 test122 test18 test23 test301 test9 test105 \
|
test300 test8 test104 test113 test122 test18 test23 test301 test9 \
|
||||||
test114 test123 test19 test24 test302 test43 test31 test106 test115 \
|
test105 test114 test123 test19 test24 test302 test43 test31 test106 \
|
||||||
test124 test190 test25 test303 test44 test38 test107 test116 test125 \
|
test115 test124 test190 test25 test303 test44 test38 test107 test116 \
|
||||||
test2 test26 test33 test45 test126 test304 test39 test32 test128 \
|
test125 test2 test26 test33 test45 test126 test304 test39 test32 \
|
||||||
test48 test306 test130 test131 test132 test133 test134 test135 test305 \
|
test128 test48 test306 test130 test131 test132 test133 test134 \
|
||||||
test49 test50 test51 test52 test53 test54 test55 test56 test500 \
|
test135 test305 test49 test50 test51 test52 test53 test54 test55 \
|
||||||
test501 test502 test503 test504 test136 test57 test137 test138 test58 \
|
test56 test500 test501 test502 test503 test504 test136 test57 test137 \
|
||||||
test139 test140 test141 test59 test60 test61 test142 test143 test62 \
|
test138 test58 test139 test140 test141 test59 test60 test61 test142 \
|
||||||
test63 test64 test65 test66 test144 test145 test67 test68 test41 \
|
test143 test62 test63 test64 test65 test66 test144 test145 test67 \
|
||||||
test40 test42 test69 test70 test71 test72 test73 test146 test505 \
|
test68 test41 test40 test42 test69 test70 test71 test72 test73 \
|
||||||
test74 test75 test76 test77 test78 test147 test148 test506 test79 \
|
test146 test505 test74 test75 test76 test77 test78 test147 test148 \
|
||||||
test80 test81 test82 test83 test84 test85 test86 test87 test507 \
|
test506 test79 test80 test81 test82 test83 test84 test85 test86 \
|
||||||
test149 test88 test89 test90 test508 test91 test92 test203 test93 \
|
test87 test507 test149 test88 test89 test90 test508 test91 test92 \
|
||||||
test94 test95 test509 test510 test97 test98 test99 test150 test151 \
|
test203 test93 test94 test95 test509 test510 test97 test98 test99 \
|
||||||
test152 test153 test154 test155 test156 test157 test158 test159 test511 \
|
test150 test151 test152 test153 test154 test155 test156 test157 \
|
||||||
test160 test161 test162 test163 test164 test512 test165 test166
|
test158 test159 test511 test160 test161 test162 test163 test164 \
|
||||||
|
test512 test165 test166 test167 test168 test169
|
||||||
|
|
||||||
# The following tests have been removed from the dist since they no longer
|
# The following tests have been removed from the dist since they no longer
|
||||||
# work. We need to fix the test suite's FTPS server first, then bring them
|
# work. We need to fix the test suite's FTPS server first, then bring them
|
||||||
|
@ -32,7 +32,7 @@ HTTP with proxy athorization
|
|||||||
</strip>
|
</strip>
|
||||||
<protocol>
|
<protocol>
|
||||||
GET http://we.want.that.site.com/16 HTTP/1.1
|
GET http://we.want.that.site.com/16 HTTP/1.1
|
||||||
Proxy-authorization: Basic ZmFrZUB1c2VyOqenp2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZw==
|
Proxy-Authorization: Basic ZmFrZUB1c2VyOqenp2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZw==
|
||||||
Host: we.want.that.site.com
|
Host: we.want.that.site.com
|
||||||
Pragma: no-cache
|
Pragma: no-cache
|
||||||
Accept: */*
|
Accept: */*
|
||||||
|
62
tests/data/test167
Normal file
62
tests/data/test167
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 401 Authorization Required swsclose
|
||||||
|
WWW-Authenticate: Digest realm="weirdorealm", nonce="12345"
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<data1000>
|
||||||
|
HTTP/1.1 200 OK swsclose
|
||||||
|
Server: no
|
||||||
|
|
||||||
|
Nice auth sir!
|
||||||
|
</data1000>
|
||||||
|
|
||||||
|
<datacheck>
|
||||||
|
HTTP/1.1 401 Authorization Required swsclose
|
||||||
|
WWW-Authenticate: Digest realm="weirdorealm", nonce="12345"
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK swsclose
|
||||||
|
Server: no
|
||||||
|
|
||||||
|
Nice auth sir!
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP with proxy-requiring-Basic to site-requiring-Digest
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://data.from.server.requiring.digest.hohoho.com/167 --proxy http://%HOSTIP:%HOSTPORT --proxy-user foo:bar --digest --user digest:alot
|
||||||
|
</command>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent: curl/.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/167 HTTP/1.1
|
||||||
|
Proxy-Authorization: Basic Zm9vOmJhcg==
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/167 HTTP/1.1
|
||||||
|
Proxy-Authorization: Basic Zm9vOmJhcg==
|
||||||
|
Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/167", response="13c7c02a252cbe1c46d8669898a3be26"
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
82
tests/data/test168
Normal file
82
tests/data/test168
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
|
||||||
|
# this is returned first since we get no proxy-auth
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 407 Authorization Required to proxy me my dear swsclose
|
||||||
|
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
|
||||||
|
|
||||||
|
And you should ignore this data.
|
||||||
|
</data>
|
||||||
|
|
||||||
|
# then this is returned since we get no server-auth
|
||||||
|
<data1000>
|
||||||
|
HTTP/1.1 401 Authorization to the remote host as well swsbounce swsclose
|
||||||
|
WWW-Authenticate: Digest realm="realmweirdo", nonce="123456"
|
||||||
|
|
||||||
|
you should ignore this data too
|
||||||
|
</data1000>
|
||||||
|
|
||||||
|
<data1001>
|
||||||
|
HTTP/1.1 200 OK swsclose
|
||||||
|
Server: no
|
||||||
|
|
||||||
|
Nice auth sir!
|
||||||
|
</data1001>
|
||||||
|
|
||||||
|
<datacheck>
|
||||||
|
HTTP/1.1 407 Authorization Required to proxy me my dear swsclose
|
||||||
|
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
|
||||||
|
|
||||||
|
HTTP/1.1 401 Authorization to the remote host as well swsbounce swsclose
|
||||||
|
WWW-Authenticate: Digest realm="realmweirdo", nonce="123456"
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK swsclose
|
||||||
|
Server: no
|
||||||
|
|
||||||
|
Nice auth sir!
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP with proxy-requiring-Digest to site-requiring-Digest
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://data.from.server.requiring.digest.hohoho.com/168 --proxy http://%HOSTIP:%HOSTPORT --proxy-user foo:bar --proxy-digest --digest --user digest:alot
|
||||||
|
</command>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent: curl/.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
|
||||||
|
Proxy-Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/168", response="4e79e4fc104ef1f16ab4567e1ad4dede"
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
|
||||||
|
Proxy-Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/168", response="4e79e4fc104ef1f16ab4567e1ad4dede"
|
||||||
|
Authorization: Digest username="digest", realm="realmweirdo", nonce="123456", uri="/168", response="ca87f2d768a231e2d637a55698d5c416"
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
107
tests/data/test169
Normal file
107
tests/data/test169
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
|
||||||
|
# this is returned first since we get no proxy-auth
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 407 Authorization Required to proxy me my dear swsclose
|
||||||
|
Proxy-Authenticate: NTLM
|
||||||
|
|
||||||
|
And you should ignore this data.
|
||||||
|
</data>
|
||||||
|
|
||||||
|
# then this is returned since we get no server-auth
|
||||||
|
<data1000>
|
||||||
|
HTTP/1.1 200 Authorizated fine
|
||||||
|
Content-Length: 27
|
||||||
|
|
||||||
|
Welcome to the end station
|
||||||
|
</data1000>
|
||||||
|
|
||||||
|
<data1001>
|
||||||
|
HTTP/1.1 407 NTLM type-1 received sending back type-2
|
||||||
|
Server: Microsoft-IIS/5.0
|
||||||
|
Content-Length: 34
|
||||||
|
Content-Type: text/html; charset=iso-8859-1
|
||||||
|
Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
|
||||||
|
|
||||||
|
This is not the real page either!
|
||||||
|
</data1001>
|
||||||
|
|
||||||
|
# This is supposed to be returned when the server gets the second
|
||||||
|
# Authorization: NTLM line passed-in from the client
|
||||||
|
<data1002>
|
||||||
|
HTTP/1.1 401 You now need to authenticate with the host
|
||||||
|
Server: Microsoft-IIS/5.0
|
||||||
|
WWW-Authenticate: Digest realm="r e a l m", nonce="abcdef"
|
||||||
|
Content-Length: 40
|
||||||
|
Content-Type: text/html; charset=iso-8859-1
|
||||||
|
|
||||||
|
We have not authenticated with the server yet
|
||||||
|
</data1002>
|
||||||
|
|
||||||
|
<datacheck>
|
||||||
|
HTTP/1.1 407 NTLM type-1 received sending back type-2
|
||||||
|
Server: Microsoft-IIS/5.0
|
||||||
|
Content-Length: 34
|
||||||
|
Content-Type: text/html; charset=iso-8859-1
|
||||||
|
Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
|
||||||
|
|
||||||
|
HTTP/1.1 401 You now need to authenticate with the host
|
||||||
|
Server: Microsoft-IIS/5.0
|
||||||
|
WWW-Authenticate: Digest realm="r e a l m", nonce="abcdef"
|
||||||
|
Content-Length: 40
|
||||||
|
Content-Type: text/html; charset=iso-8859-1
|
||||||
|
|
||||||
|
HTTP/1.1 200 Authorizated fine
|
||||||
|
Content-Length: 27
|
||||||
|
|
||||||
|
Welcome to the end station
|
||||||
|
</datacheck>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
# NTLM only works if we are built with SSL
|
||||||
|
<features>
|
||||||
|
SSL
|
||||||
|
</features>
|
||||||
|
<name>
|
||||||
|
HTTP with proxy-requiring-NTLM to site-requiring-Digest
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://data.from.server.requiring.digest.hohoho.com/169 --proxy http://%HOSTIP:%HOSTPORT --proxy-user foo:bar --proxy-ntlm --digest --user digest:alot
|
||||||
|
</command>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent: curl/.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
|
||||||
|
Proxy-Authorization: NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA=
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
|
||||||
|
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEMAAAAYABgAWwAAAAAAAABAAAAAAwADAEAAAAAAAAAAQwAAAAAAAABzAAAAAYIAAGZvb4P6B+XVQ6vQsx3DfDXUVhd9436GAxPu0IYcl2Z7LxHmNeOAWQ+vxUmhuCFJBUgXCQ==
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
|
||||||
|
Authorization: Digest username="digest", realm="r e a l m", nonce="abcdef", uri="/169", response="95d48591985a03c4b49cb962aa7bd3e6"
|
||||||
|
User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
|
||||||
|
Host: data.from.server.requiring.digest.hohoho.com
|
||||||
|
Pragma: no-cache
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
@ -49,7 +49,7 @@ moo
|
|||||||
<verify>
|
<verify>
|
||||||
<protocol>
|
<protocol>
|
||||||
CONNECT 127.0.0.1:8433 HTTP/1.0
|
CONNECT 127.0.0.1:8433 HTTP/1.0
|
||||||
Proxy-authorization: Basic dGVzdDppbmc=
|
Proxy-Authorization: Basic dGVzdDppbmc=
|
||||||
|
|
||||||
GET /503 HTTP/1.1
|
GET /503 HTTP/1.1
|
||||||
Authorization: Basic dGVzdDppbmc=
|
Authorization: Basic dGVzdDppbmc=
|
||||||
|
@ -32,7 +32,7 @@ http://we.want.that.site.com/63
|
|||||||
</strip>
|
</strip>
|
||||||
<protocol>
|
<protocol>
|
||||||
GET http://we.want.that.site.com/63 HTTP/1.1
|
GET http://we.want.that.site.com/63 HTTP/1.1
|
||||||
Proxy-authorization: Basic ZmFrZTp1c2Vy
|
Proxy-Authorization: Basic ZmFrZTp1c2Vy
|
||||||
Host: we.want.that.site.com
|
Host: we.want.that.site.com
|
||||||
Pragma: no-cache
|
Pragma: no-cache
|
||||||
Accept: */*
|
Accept: */*
|
||||||
|
@ -45,7 +45,7 @@ http://%HOSTIP:%HOSTPORT/we/want/that/page/80 -p -x %HOSTIP:%HOSTPORT --user iam
|
|||||||
</strip>
|
</strip>
|
||||||
<protocol>
|
<protocol>
|
||||||
CONNECT 127.0.0.1:8999 HTTP/1.0
|
CONNECT 127.0.0.1:8999 HTTP/1.0
|
||||||
Proxy-authorization: Basic eW91YXJlOnlvdXJzZWxm
|
Proxy-Authorization: Basic eW91YXJlOnlvdXJzZWxm
|
||||||
User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
|
User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
|
||||||
|
|
||||||
GET /we/want/that/page/80 HTTP/1.1
|
GET /we/want/that/page/80 HTTP/1.1
|
||||||
|
@ -35,7 +35,7 @@ http://%HOSTIP:%HOSTPORT/82 --proxy-user testuser:testpass -x http://%HOSTIP:%HO
|
|||||||
</strip>
|
</strip>
|
||||||
<protocol>
|
<protocol>
|
||||||
GET http://127.0.0.1:8999/82 HTTP/1.1
|
GET http://127.0.0.1:8999/82 HTTP/1.1
|
||||||
Proxy-authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
|
Proxy-Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
|
||||||
User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
|
User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
|
||||||
Host: 127.0.0.1:8999
|
Host: 127.0.0.1:8999
|
||||||
Pragma: no-cache
|
Pragma: no-cache
|
||||||
|
@ -34,7 +34,7 @@ http://%HOSTIP:%HOSTPORT/we/want/that/page/85 -x %HOSTIP:%HOSTPORT --user iam:my
|
|||||||
</strip>
|
</strip>
|
||||||
<protocol>
|
<protocol>
|
||||||
GET http://127.0.0.1:8999/we/want/that/page/85 HTTP/1.1
|
GET http://127.0.0.1:8999/we/want/that/page/85 HTTP/1.1
|
||||||
Proxy-authorization: Basic dGVzdGluZzp0aGlz
|
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
|
||||||
Authorization: Basic aWFtOm15c2VsZg==
|
Authorization: Basic aWFtOm15c2VsZg==
|
||||||
User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
|
User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
|
||||||
Host: 127.0.0.1:8999
|
Host: 127.0.0.1:8999
|
||||||
|
Loading…
Reference in New Issue
Block a user