Loading lib/http.c +99 −26 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ #include "http_negotiate.h" #include "url.h" #include "share.h" #include "http.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> Loading @@ -102,6 +103,8 @@ #include "memdebug.h" #endif static CURLcode Curl_output_basic_proxy(struct connectdata *conn); /* fread() emulation to provide POST and/or request data */ static int readmoredata(char *buffer, size_t size, Loading Loading @@ -430,6 +433,13 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); /* * This code currently only supports Basic authentication for this CONNECT * request to a proxy. */ if(conn->bits.proxy_user_passwd) Curl_output_basic_proxy(conn); /* OK, now send the connect request to the proxy */ result = Curl_sendf(tunnelsocket, conn, Loading Loading @@ -561,6 +571,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, Curl_safefree(conn->allocptr.proxyuserpwd); conn->allocptr.proxyuserpwd = NULL; Curl_http_auth_stage(data, 401); /* move on to the host auth */ infof (data, "Proxy replied to CONNECT request\n"); return CURLE_OK; } Loading Loading @@ -672,6 +684,37 @@ static CURLcode Curl_output_basic(struct connectdata *conn) return CURLE_OK; } static CURLcode Curl_output_basic_proxy(struct connectdata *conn) { char *authorization; struct SessionHandle *data=conn->data; 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; } void Curl_http_auth_stage(struct SessionHandle *data, int stage) { if(stage == 401) data->state.authwant = data->set.httpauth; else if(stage == 407) data->state.authwant = data->set.proxyauth; else return; /* bad input stage */ data->state.authstage = stage; data->state.authavail = CURLAUTH_NONE; } CURLcode Curl_http(struct connectdata *conn) { struct SessionHandle *data=conn->data; Loading @@ -685,6 +728,13 @@ CURLcode Curl_http(struct connectdata *conn) char *ptr; char *request; if(!data->state.authstage) { if(conn->bits.httpproxy) Curl_http_auth_stage(data, 407); else Curl_http_auth_stage(data, 401); } if(!conn->proto.http) { /* Only allocate this struct if we don't already have it! */ Loading Loading @@ -728,6 +778,28 @@ CURLcode Curl_http(struct connectdata *conn) curl_strequal(data->state.auth_host, conn->hostname) || data->set.http_disable_hostname_check_before_authentication) { /* Send proxy authentication header if needed */ if (data->state.authstage == 407) { #ifdef USE_SSLEAY if(data->state.authwant == CURLAUTH_NTLM) { result = Curl_output_ntlm(conn, TRUE); if(result) return result; } else #endif if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */ conn->bits.proxy_user_passwd && !checkheaders(data, "Proxy-authorization:")) { result = Curl_output_basic_proxy(conn); if(result) return result; /* Switch to web authentication after proxy authentication is done */ Curl_http_auth_stage(data, 401); } } /* Send web authentication header if needed */ if (data->state.authstage == 401) { #ifdef GSSAPI if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) && data->state.negotiate.context && Loading Loading @@ -764,6 +836,7 @@ CURLcode Curl_http(struct connectdata *conn) } } } } if((data->change.referer) && !checkheaders(data, "Referer:")) { if(conn->allocptr.ref) Loading lib/http.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,5 +42,6 @@ CURLcode Curl_http_connect(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn); CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, ssize_t length, ssize_t *wrote); void Curl_http_auth_stage(struct SessionHandle *data, int stage); #endif #endif lib/http_ntlm.c +4 −1 Original line number Diff line number Diff line Loading @@ -552,6 +552,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ /* Switch to web authentication after proxy authentication is done */ if (proxy) Curl_http_auth_stage(conn->data, 401); } break; Loading lib/transfer.c +18 −6 Original line number Diff line number Diff line Loading @@ -726,12 +726,24 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->set.get_filetime) data->info.filetime = k->timeofdoc; } else if(checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode)) { else if((checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode)) || (checkprefix("Proxy-authenticate:", k->p) && (407 == k->httpcode))) { /* * This page requires authentication */ char *start = k->p+strlen("WWW-Authenticate:"); char *start = (k->httpcode == 407) ? k->p+strlen("Proxy-authenticate:"): k->p+strlen("WWW-Authenticate:"); /* * Switch from proxy to web authentication and back if needed */ if (k->httpcode == 407 && data->state.authstage != 407) Curl_http_auth_stage(data, 407); else if (k->httpcode == 401 && data->state.authstage != 401) Curl_http_auth_stage(data, 401); /* pass all white spaces */ while(*start && isspace((int)*start)) Loading @@ -757,7 +769,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->state.authwant == CURLAUTH_NTLM) { /* NTLM authentication is activated */ CURLntlm ntlm = Curl_input_ntlm(conn, FALSE, start); Curl_input_ntlm(conn, k->httpcode == 407, start); if(CURLNTLM_BAD != ntlm) conn->newurl = strdup(data->change.url); /* clone string */ Loading Loading @@ -1506,8 +1518,8 @@ CURLcode Curl_pretransfer(struct SessionHandle *data) data->state.errorbuf = FALSE; /* no error has occurred */ /* set preferred authentication, default to basic */ data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC; data->state.authavail = CURLAUTH_NONE; /* nothing so far */ data->state.authstage = 0; /* initialize authentication later */ /* If there was a list of cookie files to read and we haven't done it before, do it now! */ Loading lib/url.c +25 −0 Original line number Diff line number Diff line Loading @@ -312,6 +312,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */ data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */ /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) Loading Loading @@ -878,6 +881,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; case CURLOPT_PROXYAUTH: /* * Set HTTP Authentication type BITMASK. */ { long auth = va_arg(param, long); /* switch off bits we can't support */ #ifndef USE_SSLEAY auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef GSSAPI auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif if(!auth) return CURLE_FAILED_INIT; /* no supported types left! */ data->set.proxyauth = auth; } break; case CURLOPT_USERPWD: /* * user:password to use in the operation Loading Loading @@ -3066,6 +3089,7 @@ static CURLcode SetupConnection(struct connectdata *conn, /************************************************************* * Proxy authentication *************************************************************/ #if 0 /* This code is not needed anymore (moved to http.c) */ if(conn->bits.proxy_user_passwd) { char *authorization; snprintf(data->state.buffer, BUFSIZE, "%s:%s", Loading @@ -3078,6 +3102,7 @@ static CURLcode SetupConnection(struct connectdata *conn, free(authorization); } } #endif /************************************************************* * Send user-agent to HTTP proxies even if the target protocol Loading Loading
lib/http.c +99 −26 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ #include "http_negotiate.h" #include "url.h" #include "share.h" #include "http.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> Loading @@ -102,6 +103,8 @@ #include "memdebug.h" #endif static CURLcode Curl_output_basic_proxy(struct connectdata *conn); /* fread() emulation to provide POST and/or request data */ static int readmoredata(char *buffer, size_t size, Loading Loading @@ -430,6 +433,13 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); /* * This code currently only supports Basic authentication for this CONNECT * request to a proxy. */ if(conn->bits.proxy_user_passwd) Curl_output_basic_proxy(conn); /* OK, now send the connect request to the proxy */ result = Curl_sendf(tunnelsocket, conn, Loading Loading @@ -561,6 +571,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, Curl_safefree(conn->allocptr.proxyuserpwd); conn->allocptr.proxyuserpwd = NULL; Curl_http_auth_stage(data, 401); /* move on to the host auth */ infof (data, "Proxy replied to CONNECT request\n"); return CURLE_OK; } Loading Loading @@ -672,6 +684,37 @@ static CURLcode Curl_output_basic(struct connectdata *conn) return CURLE_OK; } static CURLcode Curl_output_basic_proxy(struct connectdata *conn) { char *authorization; struct SessionHandle *data=conn->data; 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; } void Curl_http_auth_stage(struct SessionHandle *data, int stage) { if(stage == 401) data->state.authwant = data->set.httpauth; else if(stage == 407) data->state.authwant = data->set.proxyauth; else return; /* bad input stage */ data->state.authstage = stage; data->state.authavail = CURLAUTH_NONE; } CURLcode Curl_http(struct connectdata *conn) { struct SessionHandle *data=conn->data; Loading @@ -685,6 +728,13 @@ CURLcode Curl_http(struct connectdata *conn) char *ptr; char *request; if(!data->state.authstage) { if(conn->bits.httpproxy) Curl_http_auth_stage(data, 407); else Curl_http_auth_stage(data, 401); } if(!conn->proto.http) { /* Only allocate this struct if we don't already have it! */ Loading Loading @@ -728,6 +778,28 @@ CURLcode Curl_http(struct connectdata *conn) curl_strequal(data->state.auth_host, conn->hostname) || data->set.http_disable_hostname_check_before_authentication) { /* Send proxy authentication header if needed */ if (data->state.authstage == 407) { #ifdef USE_SSLEAY if(data->state.authwant == CURLAUTH_NTLM) { result = Curl_output_ntlm(conn, TRUE); if(result) return result; } else #endif if((data->state.authwant == CURLAUTH_BASIC) && /* Basic */ conn->bits.proxy_user_passwd && !checkheaders(data, "Proxy-authorization:")) { result = Curl_output_basic_proxy(conn); if(result) return result; /* Switch to web authentication after proxy authentication is done */ Curl_http_auth_stage(data, 401); } } /* Send web authentication header if needed */ if (data->state.authstage == 401) { #ifdef GSSAPI if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) && data->state.negotiate.context && Loading Loading @@ -764,6 +836,7 @@ CURLcode Curl_http(struct connectdata *conn) } } } } if((data->change.referer) && !checkheaders(data, "Referer:")) { if(conn->allocptr.ref) Loading
lib/http.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,5 +42,6 @@ CURLcode Curl_http_connect(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn); CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, ssize_t length, ssize_t *wrote); void Curl_http_auth_stage(struct SessionHandle *data, int stage); #endif #endif
lib/http_ntlm.c +4 −1 Original line number Diff line number Diff line Loading @@ -552,6 +552,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ /* Switch to web authentication after proxy authentication is done */ if (proxy) Curl_http_auth_stage(conn->data, 401); } break; Loading
lib/transfer.c +18 −6 Original line number Diff line number Diff line Loading @@ -726,12 +726,24 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->set.get_filetime) data->info.filetime = k->timeofdoc; } else if(checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode)) { else if((checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode)) || (checkprefix("Proxy-authenticate:", k->p) && (407 == k->httpcode))) { /* * This page requires authentication */ char *start = k->p+strlen("WWW-Authenticate:"); char *start = (k->httpcode == 407) ? k->p+strlen("Proxy-authenticate:"): k->p+strlen("WWW-Authenticate:"); /* * Switch from proxy to web authentication and back if needed */ if (k->httpcode == 407 && data->state.authstage != 407) Curl_http_auth_stage(data, 407); else if (k->httpcode == 401 && data->state.authstage != 401) Curl_http_auth_stage(data, 401); /* pass all white spaces */ while(*start && isspace((int)*start)) Loading @@ -757,7 +769,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->state.authwant == CURLAUTH_NTLM) { /* NTLM authentication is activated */ CURLntlm ntlm = Curl_input_ntlm(conn, FALSE, start); Curl_input_ntlm(conn, k->httpcode == 407, start); if(CURLNTLM_BAD != ntlm) conn->newurl = strdup(data->change.url); /* clone string */ Loading Loading @@ -1506,8 +1518,8 @@ CURLcode Curl_pretransfer(struct SessionHandle *data) data->state.errorbuf = FALSE; /* no error has occurred */ /* set preferred authentication, default to basic */ data->state.authwant = data->set.httpauth?data->set.httpauth:CURLAUTH_BASIC; data->state.authavail = CURLAUTH_NONE; /* nothing so far */ data->state.authstage = 0; /* initialize authentication later */ /* If there was a list of cookie files to read and we haven't done it before, do it now! */ Loading
lib/url.c +25 −0 Original line number Diff line number Diff line Loading @@ -312,6 +312,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */ data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */ /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) Loading Loading @@ -878,6 +881,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; case CURLOPT_PROXYAUTH: /* * Set HTTP Authentication type BITMASK. */ { long auth = va_arg(param, long); /* switch off bits we can't support */ #ifndef USE_SSLEAY auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef GSSAPI auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif if(!auth) return CURLE_FAILED_INIT; /* no supported types left! */ data->set.proxyauth = auth; } break; case CURLOPT_USERPWD: /* * user:password to use in the operation Loading Loading @@ -3066,6 +3089,7 @@ static CURLcode SetupConnection(struct connectdata *conn, /************************************************************* * Proxy authentication *************************************************************/ #if 0 /* This code is not needed anymore (moved to http.c) */ if(conn->bits.proxy_user_passwd) { char *authorization; snprintf(data->state.buffer, BUFSIZE, "%s:%s", Loading @@ -3078,6 +3102,7 @@ static CURLcode SetupConnection(struct connectdata *conn, free(authorization); } } #endif /************************************************************* * Send user-agent to HTTP proxies even if the target protocol Loading