diff options
Diffstat (limited to 'curl-7.15.5-bz657396.patch')
-rw-r--r-- | curl-7.15.5-bz657396.patch | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/curl-7.15.5-bz657396.patch b/curl-7.15.5-bz657396.patch new file mode 100644 index 0000000..8abba2c --- /dev/null +++ b/curl-7.15.5-bz657396.patch @@ -0,0 +1,465 @@ +From 795a6b48946f22d4562e6ad859306ac62eb3f6a0 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Fri, 3 Nov 2006 12:43:55 +0000 +Subject: [PATCH 1/4] Olaf Stueben provided a patch that I edited slightly. It + fixes the notorious KNOWN_BUGS #25, which happens when + a proxy closes the connection when libcurl has sent + CONNECT, as part of an authentication negotiation. + Starting now, libcurl will re-connect accordingly and + continue the authentication as it should. + +Signed-off-by: Kamil Dudka <kdudka@redhat.com> +--- + lib/http.c | 15 +++++++++++++++ + lib/url.c | 54 +++++++++++++++++++++++++++++++++--------------------- + lib/urldata.h | 3 +++ + 3 files changed, 51 insertions(+), 21 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 0fd0cbe..4d39a98 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1095,6 +1095,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + curl_socket_t tunnelsocket = conn->sock[sockindex]; + send_buffer *req_buffer; + curl_off_t cl=0; ++ bool closeConnection = FALSE; + + #define SELECT_OK 0 + #define SELECT_ERROR 1 +@@ -1102,6 +1103,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + int error = SELECT_OK; + + infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); ++ conn->bits.proxy_connect_closed = FALSE; + + do { + if(conn->newurl) { +@@ -1295,6 +1297,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + cl = curlx_strtoofft(line_start + strlen("Content-Length:"), + NULL, 10); + } ++ else if(Curl_compareheader(line_start, ++ "Connection:", "close")) ++ closeConnection = TRUE; + else if(2 == sscanf(line_start, "HTTP/1.%d %d", + &subversion, + &k->httpcode)) { +@@ -1321,11 +1326,21 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + headers. 'newurl' is set to a new URL if we must loop. */ + Curl_http_auth_act(conn); + ++ if (closeConnection && conn->newurl) { ++ /* Connection closed by server. Don't use it anymore */ ++ sclose(conn->sock[sockindex]); ++ conn->sock[sockindex] = CURL_SOCKET_BAD; ++ break; ++ } + } while(conn->newurl); + + if(200 != k->httpcode) { + failf(data, "Received HTTP code %d from proxy after CONNECT", + k->httpcode); ++ ++ if (closeConnection && conn->newurl) ++ conn->bits.proxy_connect_closed = TRUE; ++ + return CURLE_RECV_ERROR; + } + +diff --git a/lib/url.c b/lib/url.c +index 1a0c206..bf4a3dd 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -2484,7 +2484,8 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done) + + /* it has started, possibly even completed but that knowledge isn't stored + in this bit! */ +- conn->bits.protoconnstart = TRUE; ++ if (!result) ++ conn->bits.protoconnstart = TRUE; + } + + return result; /* pass back status */ +@@ -3981,30 +3982,41 @@ static CURLcode SetupConnection(struct connectdata *conn, + data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ + #endif /* CURL_DO_LINEEND_CONV */ + +- if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { +- bool connected = FALSE; ++ for(;;) { ++ /* loop for CURL_SERVER_CLOSED_CONNECTION */ + +- /* Connect only if not already connected! */ +- result = ConnectPlease(conn, hostaddr, &connected); ++ if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { ++ bool connected = FALSE; + +- if(connected) { +- result = Curl_protocol_connect(conn, protocol_done); +- if(CURLE_OK == result) +- conn->bits.tcpconnect = TRUE; +- } +- else +- conn->bits.tcpconnect = FALSE; ++ /* Connect only if not already connected! */ ++ result = ConnectPlease(conn, hostaddr, &connected); + ++ if(connected) { ++ result = Curl_protocol_connect(conn, protocol_done); ++ if(CURLE_OK == result) ++ conn->bits.tcpconnect = TRUE; ++ } ++ else ++ conn->bits.tcpconnect = FALSE; + +- if(CURLE_OK != result) +- return result; +- } +- else { +- Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ +- conn->bits.tcpconnect = TRUE; +- *protocol_done = TRUE; +- if(data->set.verbose) +- verboseconnect(conn); ++ /* if the connection was closed by the server while exchanging ++ authentication informations, retry with the new set ++ authentication information */ ++ if(conn->bits.proxy_connect_closed) ++ continue; ++ ++ if(CURLE_OK != result) ++ return result; ++ } ++ else { ++ Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ ++ conn->bits.tcpconnect = TRUE; ++ *protocol_done = TRUE; ++ if(data->set.verbose) ++ verboseconnect(conn); ++ } ++ /* Stop the loop now */ ++ break; + } + + conn->now = Curl_tvnow(); /* time this *after* the connect is done, we +diff --git a/lib/urldata.h b/lib/urldata.h +index d092113..3ac8fbf 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -454,6 +454,9 @@ struct ConnectBits { + when Curl_done() is called, to prevent Curl_done() to + get invoked twice when the multi interface is + used. */ ++ bool proxy_connect_closed; /* set true if a proxy disconnected the ++ connection in a CONNECT request with auth, so ++ that libcurl should reconnect and continue. */ + }; + + struct hostname { +-- +1.7.4.4 + + +From e3c76c19fd8d61f41b4025c4f085413dd9935e28 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Tue, 10 Jul 2007 22:31:13 +0000 +Subject: [PATCH 2/4] Giancarlo Formicuccia reported and fixed a problem with + a closed connection to a proxy during CONNECT auth + negotiation. + +Signed-off-by: Kamil Dudka <kdudka@redhat.com> +--- + lib/http.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 4d39a98..6481fa0 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1300,6 +1300,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + else if(Curl_compareheader(line_start, + "Connection:", "close")) + closeConnection = TRUE; ++ else if(Curl_compareheader(line_start, ++ "Proxy-Connection:", "close")) ++ closeConnection = TRUE; + else if(2 == sscanf(line_start, "HTTP/1.%d %d", + &subversion, + &k->httpcode)) { +-- +1.7.4.4 + + +From c1bfdb84733e58b11dce10eb2c99bf4c1f5c8806 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Fri, 21 Sep 2007 11:05:31 +0000 +Subject: [PATCH 3/4] Mark Davies fixed Negotiate authentication over proxy, + and also introduced the --proxy-negotiate command line + option to allow a user to explicitly select it. + +Signed-off-by: Kamil Dudka <kdudka@redhat.com> +--- + docs/curl.1 | 11 +++++++++++ + lib/http.c | 16 ++++++++++++++-- + lib/http_negotiate.c | 14 +++++++------- + lib/http_negotiate.h | 4 ++-- + src/main.c | 11 +++++++++++ + 5 files changed, 45 insertions(+), 11 deletions(-) + +diff --git a/docs/curl.1 b/docs/curl.1 +index e62be55..2658954 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -688,6 +688,9 @@ meant as a support for Kerberos5 authentication but may be also used along + with another authentication methods. For more information see IETF draft + draft-brezak-spnego-http-04.txt. + ++If you want to enable Negotiate for your proxy authentication, then use ++\fI--proxy-negotiate\fP. ++ + This option requires that the library was built with GSSAPI support. This is + not very common. Use \fI-V/--version\fP to see if your version supports + GSS-Negotiate. +@@ -768,6 +771,14 @@ Tells curl to use HTTP Digest authentication when communicating with the given + proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host. + + If this option is used twice, the second will again disable proxy HTTP Digest. ++.IP "--proxy-negotiate" ++Tells curl to use HTTP Negotiate authentication when communicating ++with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate ++with a remote host. ++ ++If this option is used twice, the second will again disable proxy HTTP ++Negotiate. ++ + .IP "--proxy-ntlm" + Tells curl to use HTTP NTLM authentication when communicating with the given + proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host. +diff --git a/lib/http.c b/lib/http.c +index 6481fa0..033ee9b 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -416,6 +416,18 @@ Curl_http_output_auth(struct connectdata *conn, + /* Send proxy authentication header if needed */ + if (conn->bits.httpproxy && + (conn->bits.tunnel_proxy == proxytunnel)) { ++#ifdef HAVE_GSSAPI ++ if((authproxy->picked == CURLAUTH_GSSNEGOTIATE) && ++ data->state.negotiate.context && ++ !GSS_ERROR(data->state.negotiate.status)) { ++ auth="GSS-Negotiate"; ++ result = Curl_output_negotiate(conn, TRUE); ++ if (result) ++ return result; ++ authproxy->done = TRUE; ++ } ++ else ++#endif + #ifdef USE_NTLM + if(authproxy->picked == CURLAUTH_NTLM) { + auth=(char *)"NTLM"; +@@ -478,7 +490,7 @@ Curl_http_output_auth(struct connectdata *conn, + data->state.negotiate.context && + !GSS_ERROR(data->state.negotiate.status)) { + auth=(char *)"GSS-Negotiate"; +- result = Curl_output_negotiate(conn); ++ result = Curl_output_negotiate(conn, FALSE); + if (result) + return result; + authhost->done = TRUE; +@@ -585,7 +597,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, + authp->avail |= CURLAUTH_GSSNEGOTIATE; + if(authp->picked == CURLAUTH_GSSNEGOTIATE) { + /* if exactly this is wanted, go */ +- int neg = Curl_input_negotiate(conn, start); ++ int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); + if (neg == 0) { + conn->newurl = strdup(data->change.url); + data->state.authproblem = (conn->newurl == NULL); +diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c +index 3fc678f..73deda5 100644 +--- a/lib/http_negotiate.c ++++ b/lib/http_negotiate.c +@@ -49,7 +49,7 @@ + #include "memdebug.h" + + static int +-get_gss_name(struct connectdata *conn, gss_name_t *server) ++get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server) + { + struct negotiatedata *neg_ctx = &conn->data->state.negotiate; + OM_uint32 major_status, minor_status; +@@ -69,11 +69,11 @@ get_gss_name(struct connectdata *conn, gss_name_t *server) + else + service = "HTTP"; + +- token.length = strlen(service) + 1 + strlen(conn->host.name) + 1; ++ token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name : conn->host.name) + 1; + if (token.length + 1 > sizeof(name)) + return EMSGSIZE; + +- snprintf(name, sizeof(name), "%s@%s", service, conn->host.name); ++ snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name : conn->host.name); + + token.value = (void *) name; + major_status = gss_import_name(&minor_status, +@@ -113,7 +113,7 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix) + infof(conn->data, "%s", buf); + } + +-int Curl_input_negotiate(struct connectdata *conn, char *header) ++int Curl_input_negotiate(struct connectdata *conn, bool proxy, char *header) + { + struct negotiatedata *neg_ctx = &conn->data->state.negotiate; + OM_uint32 major_status, minor_status, minor_status2; +@@ -169,7 +169,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header) + } + + if (neg_ctx->server_name == NULL && +- (ret = get_gss_name(conn, &neg_ctx->server_name))) ++ (ret = get_gss_name(conn, proxy, &neg_ctx->server_name))) + return ret; + + header += strlen(neg_ctx->protocol); +@@ -258,7 +258,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header) + } + + +-CURLcode Curl_output_negotiate(struct connectdata *conn) ++CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) + { + struct negotiatedata *neg_ctx = &conn->data->state.negotiate; + char *encoded = NULL; +@@ -310,7 +310,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn) + return CURLE_OUT_OF_MEMORY; + + conn->allocptr.userpwd = +- aprintf("Authorization: %s %s\r\n", neg_ctx->protocol, encoded); ++ aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", neg_ctx->protocol, encoded); + free(encoded); + Curl_cleanup_negotiate (conn->data); + return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; +diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h +index cf8b048..8604a0c 100644 +--- a/lib/http_negotiate.h ++++ b/lib/http_negotiate.h +@@ -27,10 +27,10 @@ + #ifdef HAVE_GSSAPI + + /* this is for Negotiate header input */ +-int Curl_input_negotiate(struct connectdata *conn, char *header); ++int Curl_input_negotiate(struct connectdata *conn, bool proxy, char *header); + + /* this is for creating Negotiate header output */ +-CURLcode Curl_output_negotiate(struct connectdata *conn); ++CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy); + + void Curl_cleanup_negotiate(struct SessionHandle *data); + +diff --git a/src/main.c b/src/main.c +index 9f378db..44dd2c4 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -309,6 +309,7 @@ struct Configurable { + bool create_dirs; + bool ftp_create_dirs; + bool ftp_skip_ip; ++ bool proxynegotiate; + bool proxyntlm; + bool proxydigest; + bool proxybasic; +@@ -555,6 +556,7 @@ static void help(void) + " --proxy-anyauth Pick \"any\" proxy authentication method (H)", + " --proxy-basic Use Basic authentication on the proxy (H)", + " --proxy-digest Use Digest authentication on the proxy (H)", ++ " --proxy-negotiate Use Negotiate authentication on the proxy (H)", + " --proxy-ntlm Use NTLM authentication on the proxy (H)", + " -P/--ftp-port <address> Use PORT with address instead of PASV (F)", + " -q If used as the first parameter disables .curlrc", +@@ -1347,6 +1349,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ + {"$t", "socks4", TRUE}, + {"$u", "ftp-alternative-to-user", TRUE}, + {"$v", "ftp-ssl-reqd", FALSE}, ++ {"$w", "proxy-negotiate", FALSE}, + + {"0", "http1.0", FALSE}, + {"1", "tlsv1", FALSE}, +@@ -1789,6 +1792,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ + case 'v': /* --ftp-ssl-reqd */ + config->ftp_ssl_reqd ^= TRUE; + break; ++ case 'w': /* --proxy-negotiate */ ++ if(curlinfo->features & CURL_VERSION_GSSNEGOTIATE) ++ config->proxynegotiate ^= TRUE; ++ else ++ return PARAM_LIBCURL_DOESNT_SUPPORT; ++ break; + } + break; + case '#': /* --progress-bar */ +@@ -3960,6 +3969,8 @@ operate(struct Configurable *config, int argc, char *argv[]) + config->ftp_create_dirs); + if(config->proxyanyauth) + curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); ++ else if(config->proxynegotiate) ++ curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_GSSNEGOTIATE); + else if(config->proxyntlm) + curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM); + else if(config->proxydigest) +-- +1.7.4.4 + + +From 88507544781155092ccee225bff92a0177e0f4df Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Mon, 16 Aug 2010 22:19:38 +0200 +Subject: [PATCH 4/4] negotiation: Wrong proxy authorization + +There's an error in http_negotiation.c where a mistake is using only +userpwd even for proxy requests. Ludek provided a patch, but I decided +to write the fix slightly different using his patch as inspiration. + +Reported by: Ludek Finstrle +Bug: http://curl.haxx.se/bug/view.cgi?id=3046066 + +Signed-off-by: Kamil Dudka <kdudka@redhat.com> +--- + lib/http_negotiate.c | 12 +++++++++--- + 1 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c +index 73deda5..1d6119d 100644 +--- a/lib/http_negotiate.c ++++ b/lib/http_negotiate.c +@@ -263,6 +263,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) + struct negotiatedata *neg_ctx = &conn->data->state.negotiate; + char *encoded = NULL; + int len; ++ char *userp; + + #ifdef HAVE_SPNEGO /* Handle SPNEGO */ + if (checkprefix("Negotiate",neg_ctx->protocol)) { +@@ -309,11 +310,16 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) + if (len < 0) + return CURLE_OUT_OF_MEMORY; + +- conn->allocptr.userpwd = +- aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", neg_ctx->protocol, encoded); ++ userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", ++ neg_ctx->protocol, encoded); ++ ++ if(proxy) ++ conn->allocptr.proxyuserpwd = userp; ++ else ++ conn->allocptr.userpwd = userp; + free(encoded); + Curl_cleanup_negotiate (conn->data); +- return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; ++ return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; + } + + void Curl_cleanup_negotiate(struct SessionHandle *data) +-- +1.7.4.4 + |