mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
When we issue a HTTP request, first make sure if the authentication phase
is over or not, as if it isn't we shall not begin any PUT or POST operation. This cures bug report #805853, and test case 88 verifies it!
This commit is contained in:
parent
c611ac958e
commit
58b1437cae
38
lib/http.c
38
lib/http.c
@ -187,18 +187,25 @@ void Curl_http_auth_act(struct connectdata *conn)
|
|||||||
|
|
||||||
CURLcode http_auth_headers(struct connectdata *conn,
|
CURLcode http_auth_headers(struct connectdata *conn,
|
||||||
char *request,
|
char *request,
|
||||||
char *path)
|
char *path,
|
||||||
|
bool *ready) /* set TRUE when the auth phase is
|
||||||
|
done and ready to do the *actual*
|
||||||
|
request */
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
*ready = FALSE; /* default is no */
|
||||||
|
|
||||||
if(!data->state.authstage) {
|
if(!data->state.authstage) {
|
||||||
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd)
|
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd)
|
||||||
Curl_http_auth_stage(data, 407);
|
Curl_http_auth_stage(data, 407);
|
||||||
else if(conn->bits.user_passwd)
|
else if(conn->bits.user_passwd)
|
||||||
Curl_http_auth_stage(data, 401);
|
Curl_http_auth_stage(data, 401);
|
||||||
else
|
else {
|
||||||
|
*ready = TRUE;
|
||||||
return CURLE_OK; /* no authentication with no user or password */
|
return CURLE_OK; /* no authentication with no user or password */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
@ -212,7 +219,7 @@ CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
if (data->state.authstage == 407) {
|
if (data->state.authstage == 407) {
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
result = Curl_output_ntlm(conn, TRUE);
|
result = Curl_output_ntlm(conn, TRUE, ready);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -224,6 +231,7 @@ CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
result = Curl_output_basic_proxy(conn);
|
result = Curl_output_basic_proxy(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
*ready = TRUE;
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
/* Switch to web authentication after proxy authentication is done */
|
||||||
Curl_http_auth_stage(data, 401);
|
Curl_http_auth_stage(data, 401);
|
||||||
}
|
}
|
||||||
@ -237,12 +245,13 @@ CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
result = Curl_output_negotiate(conn);
|
result = Curl_output_negotiate(conn);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
*ready = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
result = Curl_output_ntlm(conn, FALSE);
|
result = Curl_output_ntlm(conn, FALSE, ready);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -256,6 +265,7 @@ CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
(unsigned char *)path);
|
(unsigned char *)path);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
*ready = TRUE;
|
||||||
}
|
}
|
||||||
else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
|
else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */
|
||||||
conn->bits.user_passwd &&
|
conn->bits.user_passwd &&
|
||||||
@ -263,10 +273,13 @@ CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
result = Curl_output_basic(conn);
|
result = Curl_output_basic(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
*ready = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*ready = TRUE;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -706,6 +719,9 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
bool auth; /* we don't really have to know when the auth phase is done,
|
||||||
|
but this variable will be set to true then */
|
||||||
|
|
||||||
if(conn->newurl) {
|
if(conn->newurl) {
|
||||||
/* This only happens if we've looped here due to authentication reasons,
|
/* This only happens if we've looped here due to authentication reasons,
|
||||||
and we don't really use the newly cloned URL here then. Just free()
|
and we don't really use the newly cloned URL here then. Just free()
|
||||||
@ -719,7 +735,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 = http_auth_headers(conn, (char *)"CONNECT", host_port, &auth);
|
||||||
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 */
|
||||||
@ -993,6 +1009,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
const char *te = ""; /* tranfer-encoding */
|
const char *te = ""; /* tranfer-encoding */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *request;
|
char *request;
|
||||||
|
bool authdone=TRUE; /* if the authentication phase is done */
|
||||||
|
Curl_HttpReq httpreq; /* type of HTTP request */
|
||||||
|
|
||||||
if(!conn->proto.http) {
|
if(!conn->proto.http) {
|
||||||
/* Only allocate this struct if we don't already have it! */
|
/* Only allocate this struct if we don't already have it! */
|
||||||
@ -1031,7 +1049,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup the authentication headers */
|
/* setup the authentication headers */
|
||||||
result = http_auth_headers(conn, request, ppath);
|
result = http_auth_headers(conn, request, ppath, &authdone);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -1384,7 +1402,13 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
http->postdata = NULL; /* nothing to post at this point */
|
http->postdata = NULL; /* nothing to post at this point */
|
||||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||||
|
|
||||||
switch(data->set.httpreq) {
|
if(!authdone)
|
||||||
|
/* until the auth is done, pretend we only do GET */
|
||||||
|
httpreq = HTTPREQ_GET;
|
||||||
|
else
|
||||||
|
httpreq = data->set.httpreq;
|
||||||
|
|
||||||
|
switch(httpreq) {
|
||||||
|
|
||||||
case HTTPREQ_POST_FORM:
|
case HTTPREQ_POST_FORM:
|
||||||
if(Curl_FormInit(&http->form, http->sendit)) {
|
if(Curl_FormInit(&http->form, http->sendit)) {
|
||||||
|
@ -277,7 +277,8 @@ static void mkhash(char *password,
|
|||||||
|
|
||||||
/* this is for creating ntlm header output */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||||
bool proxy)
|
bool proxy,
|
||||||
|
bool *ready)
|
||||||
{
|
{
|
||||||
const char *domain=""; /* empty */
|
const char *domain=""; /* empty */
|
||||||
const char *host=""; /* empty */
|
const char *host=""; /* empty */
|
||||||
@ -299,6 +300,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
/* point to the correct struct with this */
|
/* point to the correct struct with this */
|
||||||
struct ntlmdata *ntlm;
|
struct ntlmdata *ntlm;
|
||||||
|
|
||||||
|
*ready = FALSE;
|
||||||
|
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||||
userp = conn->proxyuser;
|
userp = conn->proxyuser;
|
||||||
@ -556,6 +559,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 */
|
||||||
|
*ready = TRUE;
|
||||||
|
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
/* Switch to web authentication after proxy authentication is done */
|
||||||
if (proxy)
|
if (proxy)
|
||||||
@ -570,6 +574,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
free(*allocuserpwd);
|
free(*allocuserpwd);
|
||||||
*allocuserpwd=NULL;
|
*allocuserpwd=NULL;
|
||||||
}
|
}
|
||||||
|
*ready = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ typedef enum {
|
|||||||
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||||
|
|
||||||
/* this is for creating ntlm header output */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy, bool *ready);
|
||||||
|
|
||||||
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user