From 58b1437cae71335fe78e850f0f2bacfcfb268333 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Sep 2003 21:11:22 +0000 Subject: [PATCH] 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! --- lib/http.c | 38 +++++++++++++++++++++++++++++++------- lib/http_ntlm.c | 7 ++++++- lib/http_ntlm.h | 2 +- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/http.c b/lib/http.c index 76198e0c2..8cb97dd1d 100644 --- a/lib/http.c +++ b/lib/http.c @@ -187,18 +187,25 @@ void Curl_http_auth_act(struct connectdata *conn) CURLcode http_auth_headers(struct connectdata *conn, 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; struct SessionHandle *data = conn->data; + *ready = FALSE; /* default is no */ + if(!data->state.authstage) { if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) Curl_http_auth_stage(data, 407); else if(conn->bits.user_passwd) Curl_http_auth_stage(data, 401); - else + else { + *ready = TRUE; return CURLE_OK; /* no authentication with no user or password */ + } } /* 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) { #ifdef USE_SSLEAY if(data->state.authwant == CURLAUTH_NTLM) { - result = Curl_output_ntlm(conn, TRUE); + result = Curl_output_ntlm(conn, TRUE, ready); if(result) return result; } @@ -224,6 +231,7 @@ CURLcode http_auth_headers(struct connectdata *conn, result = Curl_output_basic_proxy(conn); if(result) return result; + *ready = TRUE; /* Switch to web authentication after proxy authentication is done */ Curl_http_auth_stage(data, 401); } @@ -237,12 +245,13 @@ CURLcode http_auth_headers(struct connectdata *conn, result = Curl_output_negotiate(conn); if (result) return result; + *ready = TRUE; } else #endif #ifdef USE_SSLEAY if(data->state.authwant == CURLAUTH_NTLM) { - result = Curl_output_ntlm(conn, FALSE); + result = Curl_output_ntlm(conn, FALSE, ready); if(result) return result; } @@ -256,6 +265,7 @@ CURLcode http_auth_headers(struct connectdata *conn, (unsigned char *)path); if(result) return result; + *ready = TRUE; } else if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */ conn->bits.user_passwd && @@ -263,10 +273,13 @@ CURLcode http_auth_headers(struct connectdata *conn, result = Curl_output_basic(conn); if(result) return result; + *ready = TRUE; } } } } + else + *ready = TRUE; 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); 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) { /* 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() @@ -719,7 +735,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; /* 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) { /* OK, now send the connect request to the proxy */ @@ -993,6 +1009,8 @@ CURLcode Curl_http(struct connectdata *conn) const char *te = ""; /* tranfer-encoding */ char *ptr; char *request; + bool authdone=TRUE; /* if the authentication phase is done */ + Curl_HttpReq httpreq; /* type of HTTP request */ if(!conn->proto.http) { /* 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 */ - result = http_auth_headers(conn, request, ppath); + result = http_auth_headers(conn, request, ppath, &authdone); if(result) return result; @@ -1384,7 +1402,13 @@ CURLcode Curl_http(struct connectdata *conn) http->postdata = NULL; /* nothing to post at this point */ 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: if(Curl_FormInit(&http->form, http->sendit)) { diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 763cb96cb..4297dd3d8 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -277,7 +277,8 @@ static void mkhash(char *password, /* this is for creating ntlm header output */ CURLcode Curl_output_ntlm(struct connectdata *conn, - bool proxy) + bool proxy, + bool *ready) { const char *domain=""; /* empty */ const char *host=""; /* empty */ @@ -299,6 +300,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, /* point to the correct struct with this */ struct ntlmdata *ntlm; + *ready = FALSE; + if(proxy) { allocuserpwd = &conn->allocptr.proxyuserpwd; userp = conn->proxyuser; @@ -556,6 +559,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; /* FIX TODO */ ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ + *ready = TRUE; /* Switch to web authentication after proxy authentication is done */ if (proxy) @@ -570,6 +574,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, free(*allocuserpwd); *allocuserpwd=NULL; } + *ready = TRUE; break; } diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h index 88a248ccd..e2ea9e9e1 100644 --- a/lib/http_ntlm.h +++ b/lib/http_ntlm.h @@ -36,7 +36,7 @@ typedef enum { CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header); /* 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);