build: disable more code/data when built without proxy support

Added build to travis to verify

Closes #5466
This commit is contained in:
Daniel Stenberg 2020-05-27 11:51:34 +02:00
parent c4e6968127
commit f3d501dc67
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
26 changed files with 419 additions and 153 deletions

View File

@ -82,6 +82,8 @@ jobs:
- OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- env:
- T=normal C="--enable-mqtt"
- env:
- T=normal C="--disable-proxy"
- env:
- T=normal C="--disable-verbose" CPPFLAGS="-Wno-variadic-macros" NOTESTS=1
- OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"

View File

@ -494,11 +494,14 @@ static CURLcode resolver_error(struct connectdata *conn)
const char *host_or_proxy;
CURLcode result;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy) {
host_or_proxy = "proxy";
result = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
else
#endif
{
host_or_proxy = "host";
result = CURLE_COULDNT_RESOLVE_HOST;
}

View File

@ -143,12 +143,15 @@ static void hashkey(struct connectdata *conn, char *buf,
const char *hostname;
long port = conn->remote_port;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
hostname = conn->http_proxy.host.name;
port = conn->port;
}
else if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
#endif
if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;

View File

@ -747,8 +747,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
{
CURLcode result = CURLE_OK;
if(conn->bits.socksproxy) {
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy) {
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
@ -781,11 +781,12 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
failf(conn->data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
#else
(void)sockindex;
#endif /* CURL_DISABLE_PROXY */
}
else
#else
(void)conn;
(void)sockindex;
#endif /* CURL_DISABLE_PROXY */
*done = TRUE; /* no SOCKS proxy, so consider us connected */
return result;
@ -986,18 +987,19 @@ CURLcode Curl_is_connected(struct connectdata *conn,
/* if the first address family runs out of addresses to try before
the happy eyeball timeout, go ahead and try the next family now */
{
result = trynextip(conn, sockindex, 1);
if(!result)
return result;
}
result = trynextip(conn, sockindex, 1);
if(!result)
return result;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy)
hostname = conn->socks_proxy.host.name;
else if(conn->bits.httpproxy)
hostname = conn->http_proxy.host.name;
else if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
#endif
if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;

View File

@ -394,11 +394,15 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
DEBUGASSERT(conn->data);
if(proxy) {
#ifndef CURL_DISABLE_PROXY
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->http_proxy.user;
ntlm = &conn->proxyntlm;
state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
#else
return CURLE_NOT_BUILT_IN;
#endif
}
else {
allocuserpwd = &conn->allocptr.userpwd;

View File

@ -264,9 +264,14 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
size_t len = 0;
saslstate state1 = SASL_STOP;
saslstate state2 = SASL_FINAL;
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
#else
const char * const hostname = conn->host.name;
const long int port = conn->remote_port;
#endif
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
@ -417,18 +422,23 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
struct Curl_easy *data = conn->data;
saslstate newstate = SASL_FINAL;
char *resp = NULL;
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
#else
const char * const hostname = conn->host.name;
const long int port = conn->remote_port;
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
char *chlg = NULL;
size_t chlglen = 0;
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
defined(USE_NTLM)
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
char *serverdata;
#endif
size_t len = 0;

View File

@ -221,7 +221,9 @@ static void close_secondarysocket(struct connectdata *conn)
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
}
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
#ifndef CURL_DISABLE_PROXY
conn->bits.proxy_ssl_connected[SECONDARYSOCKET] = FALSE;
#endif
}
/*
@ -1762,7 +1764,11 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) {
if(conn->bits.ipv6
#ifndef CURL_DISABLE_PROXY
&& !(conn->bits.tunnel_proxy || conn->bits.socksproxy)
#endif
) {
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
failf(conn->data, "Failed EPSV attempt, exiting\n");
return CURLE_WEIRD_SERVER_REPLY;
@ -1787,9 +1793,10 @@ static char *control_address(struct connectdata *conn)
If a proxy tunnel is used, returns the original host name instead, because
the effective control connection address is the proxy address,
not the ftp host. */
#ifndef CURL_DISABLE_PROXY
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
return conn->host.name;
#endif
return conn->ip_addr_str;
}
@ -1906,6 +1913,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_PASV_REPLY;
}
#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy) {
/*
* This connection uses a proxy and we need to connect to the proxy again
@ -1928,7 +1936,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_COULDNT_RESOLVE_PROXY;
}
}
else {
else
#endif
{
/* normal, direct, ftp connection */
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
if(rc == CURLRESOLV_PENDING)
@ -2637,9 +2647,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
#endif
if(data->set.use_ssl &&
(!conn->ssl[FIRSTSOCKET].use ||
(conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
!conn->proxy_ssl[FIRSTSOCKET].use))) {
(!conn->ssl[FIRSTSOCKET].use
#ifndef CURL_DISABLE_PROXY
|| (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
!conn->proxy_ssl[FIRSTSOCKET].use)
#endif
)) {
/* We don't have a SSL/TLS connection yet, but FTPS is
requested. Try a FTPS connection now */
@ -3503,6 +3516,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
}
}
#ifndef CURL_DISABLE_PROXY
result = Curl_proxy_connect(conn, SECONDARYSOCKET);
if(result)
return result;
@ -3513,7 +3527,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
Curl_connect_ongoing(conn))
return result;
#endif
if(ftpc->state) {
/* already in a state so skip the initial commands.

View File

@ -198,9 +198,11 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->set.ssl.certverifyresult;
break;
#ifndef CURL_DISABLE_PROXY
case CURLINFO_PROXY_SSL_VERIFYRESULT:
*param_longp = data->set.proxy_ssl.certverifyresult;
break;
#endif
case CURLINFO_REDIRECT_COUNT:
*param_longp = data->set.followlocation;
break;

View File

@ -292,9 +292,13 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
char *out;
if(proxy) {
#ifndef CURL_DISABLE_PROXY
userp = &conn->allocptr.proxyuserpwd;
user = conn->http_proxy.user;
pwd = conn->http_proxy.passwd;
#else
return CURLE_NOT_BUILT_IN;
#endif
}
else {
userp = &conn->allocptr.userpwd;
@ -578,6 +582,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
}
}
#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_user_passwd &&
((data->req.httpcode == 407) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
@ -586,6 +591,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(!pickproxy)
data->state.authproblem = TRUE;
}
#endif
if(pickhost || pickproxy) {
if((data->set.httpreq != HTTPREQ_GET) &&
@ -689,10 +695,13 @@ output_auth_headers(struct connectdata *conn,
#endif
if(authstatus->picked == CURLAUTH_BASIC) {
/* Basic */
if((proxy && conn->bits.proxy_user_passwd &&
!Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
(!proxy && conn->bits.user_passwd &&
!Curl_checkheaders(conn, "Authorization"))) {
if(
#ifndef CURL_DISABLE_PROXY
(proxy && conn->bits.proxy_user_passwd &&
!Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
#endif
(!proxy && conn->bits.user_passwd &&
!Curl_checkheaders(conn, "Authorization"))) {
auth = "Basic";
result = http_output_basic(conn, proxy);
if(result)
@ -719,10 +728,15 @@ output_auth_headers(struct connectdata *conn,
}
if(auth) {
#ifndef CURL_DISABLE_PROXY
infof(data, "%s auth using %s with user '%s'\n",
proxy ? "Proxy" : "Server", auth,
proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
(conn->user ? conn->user : ""));
(conn->user ? conn->user : ""));
#else
infof(data, "Server auth using %s with user '%s'\n",
auth, conn->user ? conn->user : "");
#endif
authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
}
else
@ -762,7 +776,10 @@ Curl_http_output_auth(struct connectdata *conn,
authhost = &data->state.authhost;
authproxy = &data->state.authproxy;
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
if(
#ifndef CURL_DISABLE_PROXY
(conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
#endif
conn->bits.user_passwd || data->set.str[STRING_BEARER])
/* continue please */;
else {
@ -1067,8 +1084,10 @@ static int http_should_fail(struct connectdata *conn)
*/
if((httpcode == 401) && !conn->bits.user_passwd)
return TRUE;
#ifndef CURL_DISABLE_PROXY
if((httpcode == 407) && !conn->bits.proxy_user_passwd)
return TRUE;
#endif
return data->state.authproblem;
}
@ -1173,8 +1192,11 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
return result;
}
if((conn->handler->flags & PROTOPT_SSL ||
conn->http_proxy.proxytype == CURLPROXY_HTTPS)
if((conn->handler->flags & PROTOPT_SSL
#ifndef CURL_DISABLE_PROXY
|| conn->http_proxy.proxytype == CURLPROXY_HTTPS
#endif
)
&& conn->httpversion != 20) {
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
when we speak HTTPS, as if only a fraction of it is sent now, this data
@ -1367,6 +1389,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
function to make the re-use checks properly be able to check this bit. */
connkeep(conn, "HTTP default");
#ifndef CURL_DISABLE_PROXY
/* the CONNECT procedure might not have been completed */
result = Curl_proxy_connect(conn, FIRSTSOCKET);
if(result)
@ -1383,7 +1406,6 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
/* nothing else to do except wait right now - we're not done here. */
return CURLE_OK;
#ifndef CURL_DISABLE_PROXY
if(conn->data->set.haproxyprotocol) {
/* add HAProxy PROXY protocol header */
result = add_haproxy_protocol_header(conn);
@ -1665,6 +1687,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
struct Curl_easy *data = conn->data;
int i;
#ifndef CURL_DISABLE_PROXY
enum proxy_use proxy;
if(is_connect)
@ -1691,6 +1714,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
h[0] = data->set.headers;
break;
}
#else
(void)is_connect;
h[0] = data->set.headers;
#endif
/* loop through one or two lists */
for(i = 0; i < numlists; i++) {
@ -1922,13 +1949,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
#ifdef USE_NGHTTP2
if(conn->data->set.httpversion ==
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
/* We don't support HTTP/2 proxies yet. Also it's debatable
whether or not this setting should apply to HTTP/2 proxies. */
infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
break;
}
#endif
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
conn->httpversion = 20;
@ -2535,10 +2563,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
conn->allocptr.accept_encoding:"",
(data->change.referer && conn->allocptr.ref)?
conn->allocptr.ref:"" /* Referer: <data> */,
#ifndef CURL_DISABLE_PROXY
(conn->bits.httpproxy &&
!conn->bits.tunnel_proxy &&
!Curl_checkProxyheaders(conn, "Proxy-Connection"))?
"Proxy-Connection: Keep-Alive\r\n":"",
#else
"",
#endif
te,
altused ? altused : ""
);
@ -3646,8 +3678,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
}
else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
((k->httpcode != 401) || !conn->bits.user_passwd) &&
((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
((k->httpcode != 401) || !conn->bits.user_passwd)
#ifndef CURL_DISABLE_PROXY
&& ((k->httpcode != 407) || !conn->bits.proxy_user_passwd)
#endif
) {
/* serious error, go home! */
print_http_error(data);
return CURLE_HTTP_RETURNED_ERROR;
@ -3757,6 +3792,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
data->info.contenttype = contenttype;
}
}
#ifndef CURL_DISABLE_PROXY
else if((conn->httpversion == 10) &&
conn->bits.httpproxy &&
Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
@ -3779,6 +3815,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
connclose(conn, "Proxy-Connection: asked to close after done");
infof(data, "HTTP/1.1 proxy connection set close!\n");
}
#endif
else if((conn->httpversion == 10) &&
Curl_compareheader(headp, "Connection:", "keep-alive")) {
/*

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -94,11 +94,15 @@ CURLcode Curl_output_digest(struct connectdata *conn,
struct auth *authp;
if(proxy) {
#ifdef CURL_DISABLE_PROXY
return CURLE_NOT_BUILT_IN;
#else
digest = &data->state.proxydigest;
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
authp = &data->state.authproxy;
#endif
}
else {
digest = &data->state.digest;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -52,6 +52,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
curlnegotiate state;
if(proxy) {
#ifndef CURL_DISABLE_PROXY
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
@ -59,6 +60,9 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
host = conn->http_proxy.host.name;
neg_ctx = &conn->proxyneg;
state = conn->proxy_negotiate_state;
#else
return CURLE_NOT_BUILT_IN;
#endif
}
else {
userp = conn->user;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -136,6 +136,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
DEBUGASSERT(conn->data);
if(proxy) {
#ifndef CURL_DISABLE_PROXY
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
@ -145,6 +146,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
ntlm = &conn->proxyntlm;
state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
#else
return CURLE_NOT_BUILT_IN;
#endif
}
else {
allocuserpwd = &conn->allocptr.userpwd;

View File

@ -659,14 +659,18 @@ static CURLcode multi_done(struct Curl_easy *data,
}
else {
char buffer[256];
const char *host =
#ifndef CURL_DISABLE_PROXY
conn->bits.socksproxy ?
conn->socks_proxy.host.dispname :
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
#endif
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname;
/* create string before returning the connection */
msnprintf(buffer, sizeof(buffer),
"Connection #%ld to host %s left intact",
conn->connection_id,
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname);
conn->connection_id, host);
/* the connection is no longer in use by this transfer */
CONNCACHE_UNLOCK(data);
if(Curl_conncache_return_conn(data, conn)) {
@ -867,8 +871,10 @@ static int waitconnect_getsock(struct connectdata *conn,
int rc = 0;
#ifdef USE_SSL
#ifndef CURL_DISABLE_PROXY
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
return Curl_ssl_getsock(conn, sock);
#endif
#endif
if(SOCKS_STATE(conn->cnnct.state))
@ -1490,7 +1496,7 @@ static CURLcode protocol_connect(struct connectdata *conn,
}
if(!conn->bits.protoconnstart) {
#ifndef CURL_DISABLE_PROXY
result = Curl_proxy_connect(conn, FIRSTSOCKET);
if(result)
return result;
@ -1504,7 +1510,7 @@ static CURLcode protocol_connect(struct connectdata *conn,
/* when using an HTTP tunnel proxy, await complete tunnel establishment
before proceeding further. Return CURLE_OK so we'll be called again */
return CURLE_OK;
#endif
if(conn->handler->connect_it) {
/* is there a protocol-specific connect() procedure? */
@ -1706,9 +1712,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
const char *hostname;
DEBUGASSERT(conn);
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy)
hostname = conn->http_proxy.host.name;
else if(conn->bits.conn_to_host)
else
#endif
if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
@ -1774,7 +1783,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
DEBUGASSERT(data->conn);
result = Curl_http_connect(data->conn, &protocol_connected);
#ifndef CURL_DISABLE_PROXY
if(data->conn->bits.proxy_connect_closed) {
rc = CURLM_CALL_MULTI_PERFORM;
/* connect back to proxy again */
@ -1782,15 +1791,20 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multi_done(data, CURLE_OK, FALSE);
multistate(data, CURLM_STATE_CONNECT);
}
else if(!result) {
if((data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
Curl_connect_complete(data->conn)) {
rc = CURLM_CALL_MULTI_PERFORM;
/* initiate protocol connect phase */
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
else
#endif
if(!result) {
if(
#ifndef CURL_DISABLE_PROXY
(data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
#endif
Curl_connect_complete(data->conn)) {
rc = CURLM_CALL_MULTI_PERFORM;
/* initiate protocol connect phase */
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
}
}
}
else if(result)
stream_error = TRUE;
break;
@ -1802,17 +1816,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
if(connected && !result) {
#ifndef CURL_DISABLE_HTTP
if((data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
!data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
Curl_connect_ongoing(data->conn)) {
if(
#ifndef CURL_DISABLE_PROXY
(data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
!data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
#endif
Curl_connect_ongoing(data->conn)) {
multistate(data, CURLM_STATE_WAITPROXYCONNECT);
break;
}
#endif
rc = CURLM_CALL_MULTI_PERFORM;
multistate(data, data->conn->bits.tunnel_proxy?
#ifndef CURL_DISABLE_PROXY
multistate(data,
data->conn->bits.tunnel_proxy?
CURLM_STATE_WAITPROXYCONNECT:
CURLM_STATE_SENDPROTOCONNECT);
#else
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
#endif
}
else if(result) {
/* failure detected */

View File

@ -394,7 +394,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
case CURLOPT_SSLVERSION:
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLVERSION:
#endif
/*
* Set explicit SSL version to try to connect with, as some SSL
* implementations are lame.
@ -402,9 +404,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#ifdef USE_SSL
{
long version, version_max;
struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ?
&data->set.ssl.primary :
&data->set.proxy_ssl.primary);
struct ssl_primary_config *primary = &data->set.ssl.primary;
#ifndef CURL_DISABLE_PROXY
if(option != CURLOPT_SSLVERSION)
primary = &data->set.proxy_ssl.primary;
#endif
arg = va_arg(param, long);
@ -2333,7 +2337,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_SSL_SESSIONID_CACHE:
data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
TRUE : FALSE;
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
#endif
break;
#ifdef USE_SSH
@ -2635,9 +2641,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PROXY_TLSAUTH_USERNAME:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
va_arg(param, char *));
#ifndef CURL_DISABLE_PROXY
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
!data->set.proxy_ssl.authtype)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
#endif
break;
case CURLOPT_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
@ -2648,9 +2656,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PROXY_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
va_arg(param, char *));
#ifndef CURL_DISABLE_PROXY
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
!data->set.proxy_ssl.authtype)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
#endif
break;
case CURLOPT_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
@ -2660,6 +2670,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
else
data->set.ssl.authtype = CURL_TLSAUTH_NONE;
break;
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
if(!argptr ||
@ -2669,6 +2680,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
break;
#endif
#endif
#ifdef USE_ARES
case CURLOPT_DNS_SERVERS:
result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS],

130
lib/url.c
View File

@ -501,7 +501,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
type */
set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
default */
#ifndef CURL_DISABLE_PROXY
set->proxy_ssl = set->ssl;
#endif
set->new_file_perms = 0644; /* Default permissions */
set->new_directory_perms = 0755; /* Default permissions */
@ -706,17 +708,21 @@ static void conn_free(struct connectdata *conn)
Curl_free_idnconverted_hostname(&conn->host);
Curl_free_idnconverted_hostname(&conn->conn_to_host);
#ifndef CURL_DISABLE_PROXY
Curl_free_idnconverted_hostname(&conn->http_proxy.host);
Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
Curl_safefree(conn->sasl_authzid);
Curl_safefree(conn->options);
Curl_safefree(conn->http_proxy.user);
Curl_safefree(conn->socks_proxy.user);
Curl_safefree(conn->http_proxy.passwd);
Curl_safefree(conn->socks_proxy.passwd);
Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
#endif
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
Curl_safefree(conn->sasl_authzid);
Curl_safefree(conn->options);
Curl_safefree(conn->allocptr.proxyuserpwd);
Curl_safefree(conn->allocptr.uagent);
Curl_safefree(conn->allocptr.userpwd);
@ -732,15 +738,12 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
Curl_safefree(conn->hostname_resolve);
Curl_safefree(conn->secondaryhostname);
Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
Curl_safefree(conn->connect_state);
conn_reset_all_postponed_data(conn);
Curl_llist_destroy(&conn->easyq, NULL);
Curl_safefree(conn->localdev);
Curl_free_primary_ssl_config(&conn->ssl_config);
Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
#ifdef USE_UNIX_SOCKETS
Curl_safefree(conn->unix_domain_socket);
@ -1052,10 +1055,14 @@ ConnectionExists(struct Curl_easy *data,
bool wantNTLMhttp = ((data->state.authhost.want &
(CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
(needle->handler->protocol & PROTO_FAMILY_HTTP));
#ifndef CURL_DISABLE_PROXY
bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
((data->state.authproxy.want &
(CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
(needle->handler->protocol & PROTO_FAMILY_HTTP)));
#else
bool wantProxyNTLMhttp = FALSE;
#endif
#endif
*force_reuse = FALSE;
@ -1168,6 +1175,7 @@ ConnectionExists(struct Curl_easy *data,
/* except protocols that have been upgraded via TLS */
continue;
#ifndef CURL_DISABLE_PROXY
if(needle->bits.httpproxy != check->bits.httpproxy ||
needle->bits.socksproxy != check->bits.socksproxy)
continue;
@ -1176,7 +1184,7 @@ ConnectionExists(struct Curl_easy *data,
!socks_proxy_info_matches(&needle->socks_proxy,
&check->socks_proxy))
continue;
#endif
if(needle->bits.conn_to_host != check->bits.conn_to_host)
/* don't mix connections that use the "connect to host" feature and
* connections that don't use this feature */
@ -1187,6 +1195,7 @@ ConnectionExists(struct Curl_easy *data,
* connections that don't use this feature */
continue;
#ifndef CURL_DISABLE_PROXY
if(needle->bits.httpproxy) {
if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
continue;
@ -1213,6 +1222,7 @@ ConnectionExists(struct Curl_easy *data,
}
}
}
#endif
DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data));
@ -1255,8 +1265,11 @@ ConnectionExists(struct Curl_easy *data,
}
}
if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
needle->bits.tunnel_proxy) {
if((needle->handler->flags&PROTOPT_SSL)
#ifndef CURL_DISABLE_PROXY
|| !needle->bits.httpproxy || needle->bits.tunnel_proxy
#endif
) {
/* The requested connection does not use a HTTP proxy or it uses SSL or
it is a non-SSL protocol tunneled or it is a non-SSL protocol which
is allowed to be upgraded via TLS */
@ -1325,6 +1338,7 @@ ConnectionExists(struct Curl_easy *data,
continue;
}
#ifndef CURL_DISABLE_PROXY
/* Same for Proxy NTLM authentication */
if(wantProxyNTLMhttp) {
/* Both check->http_proxy.user and check->http_proxy.passwd can be
@ -1340,7 +1354,7 @@ ConnectionExists(struct Curl_easy *data,
/* Proxy connection is using NTLM auth but we don't want NTLM */
continue;
}
#endif
if(wantNTLMhttp || wantProxyNTLMhttp) {
/* Credentials are already checked, we can use this connection */
chosen = check;
@ -1428,8 +1442,10 @@ void Curl_verboseconnect(struct connectdata *conn)
{
if(conn->data->set.verbose)
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
#ifndef CURL_DISABLE_PROXY
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
#endif
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname,
conn->ip_addr_str, conn->port, conn->connection_id);
@ -1576,8 +1592,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_extra = ssl;
conn->ssl[0].backend = (void *)ssl;
conn->ssl[1].backend = (void *)(ssl + sslsize);
#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
#endif
}
#endif
@ -1616,10 +1634,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->data = data; /* Setup the association between this connection
and the Curl_easy */
#ifndef CURL_DISABLE_PROXY
conn->http_proxy.proxytype = data->set.proxytype;
conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
#if !defined(CURL_DISABLE_PROXY)
/* note that these two proxy bits are now just on what looks to be
requested, they may be altered down the road */
conn->bits.proxy = (data->set.str[STRING_PROXY] &&
@ -1650,10 +1668,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl_config.verifystatus =
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
#endif
conn->ip_version = data->set.ipver;
conn->bits.connect_only = data->set.connect_only;
conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
@ -3173,6 +3193,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
}
else
#endif
if(!conn->bits.proxy) {
struct hostname *connhost;
if(conn->bits.conn_to_host)
@ -3205,6 +3226,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
/* don't return yet, we need to clean up the timeout first */
}
}
#ifndef CURL_DISABLE_PROXY
else {
/* This is a proxy that hasn't been resolved yet. */
@ -3230,6 +3252,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
/* don't return yet, we need to clean up the timeout first */
}
}
#endif
DEBUGASSERT(conn->dns_entry == NULL);
conn->dns_entry = hostaddr;
}
@ -3245,16 +3268,17 @@ static CURLcode resolve_server(struct Curl_easy *data,
static void reuse_conn(struct connectdata *old_conn,
struct connectdata *conn)
{
#ifndef CURL_DISABLE_PROXY
Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
free(old_conn->http_proxy.host.rawalloc);
free(old_conn->socks_proxy.host.rawalloc);
Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
#endif
/* free the SSL config struct from this connection struct as this was
allocated in vain and is targeted for destruction */
Curl_free_primary_ssl_config(&old_conn->ssl_config);
Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
conn->data = old_conn->data;
@ -3271,6 +3295,7 @@ static void reuse_conn(struct connectdata *old_conn,
old_conn->passwd = NULL;
}
#ifndef CURL_DISABLE_PROXY
conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
if(conn->bits.proxy_user_passwd) {
/* use the new proxy user name and proxy password though */
@ -3287,6 +3312,11 @@ static void reuse_conn(struct connectdata *old_conn,
old_conn->http_proxy.passwd = NULL;
old_conn->socks_proxy.passwd = NULL;
}
Curl_safefree(old_conn->http_proxy.user);
Curl_safefree(old_conn->socks_proxy.user);
Curl_safefree(old_conn->http_proxy.passwd);
Curl_safefree(old_conn->socks_proxy.passwd);
#endif
/* host can change, when doing keepalive with a proxy or if the case is
different this time etc */
@ -3314,10 +3344,6 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->user);
Curl_safefree(old_conn->passwd);
Curl_safefree(old_conn->options);
Curl_safefree(old_conn->http_proxy.user);
Curl_safefree(old_conn->socks_proxy.user);
Curl_safefree(old_conn->http_proxy.passwd);
Curl_safefree(old_conn->socks_proxy.passwd);
Curl_safefree(old_conn->localdev);
Curl_llist_destroy(&old_conn->easyq, NULL);
@ -3412,7 +3438,6 @@ static CURLcode create_conn(struct Curl_easy *data,
result = create_conn_helper_init_proxy(conn);
if(result)
goto out;
#endif
/*************************************************************
* If the protocol is using SSL and HTTP proxy is used, we set
@ -3420,6 +3445,7 @@ static CURLcode create_conn(struct Curl_easy *data,
*************************************************************/
if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
conn->bits.tunnel_proxy = TRUE;
#endif
/*************************************************************
* Figure out the remote port number and fix it in the URL
@ -3458,6 +3484,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
}
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy) {
result = Curl_idnconvert_hostname(conn, &conn->http_proxy.host);
if(result)
@ -3468,6 +3495,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
}
#endif
/*************************************************************
* Check whether the host and the "connect to host" are equal.
@ -3486,6 +3514,7 @@ static CURLcode create_conn(struct Curl_easy *data,
conn->bits.conn_to_port = FALSE;
}
#ifndef CURL_DISABLE_PROXY
/*************************************************************
* If the "connect to" feature is used with an HTTP proxy,
* we set the tunnel_proxy bit.
@ -3493,6 +3522,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
conn->bits.httpproxy)
conn->bits.tunnel_proxy = TRUE;
#endif
/*************************************************************
* Setup internals depending on protocol. Needs to be done after
@ -3560,54 +3590,58 @@ static CURLcode create_conn(struct Curl_easy *data,
copies will be separately allocated.
*/
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
data->set.proxy_ssl.primary.random_file =
data->set.str[STRING_SSL_RANDOM_FILE];
data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.proxy_ssl.primary.random_file =
data->set.str[STRING_SSL_RANDOM_FILE];
data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
#endif
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
#ifdef USE_TLS_SRP
data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
#endif
data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG];
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
@ -3616,11 +3650,13 @@ static CURLcode create_conn(struct Curl_easy *data,
goto out;
}
#ifndef CURL_DISABLE_PROXY
if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
&conn->proxy_ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
#endif
prune_dead_connections(data);
@ -3658,12 +3694,17 @@ static CURLcode create_conn(struct Curl_easy *data,
conn = conn_temp;
*in_connect = conn;
#ifndef CURL_DISABLE_PROXY
infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
conn->connection_id,
conn->bits.proxy?"proxy":"host",
conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
conn->host.dispname);
conn->host.dispname);
#else
infof(data, "Re-using existing connection! (#%ld) with host %s\n",
conn->connection_id, conn->host.dispname);
#endif
}
else {
/* We have decided that we want a new connection. However, we may not
@ -3794,10 +3835,12 @@ static CURLcode create_conn(struct Curl_easy *data,
/* Strip trailing dots. resolve_server copied the name. */
strip_trailing_dot(&conn->host);
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy)
strip_trailing_dot(&conn->http_proxy.host);
if(conn->bits.socksproxy)
strip_trailing_dot(&conn->socks_proxy.host);
#endif
if(conn->bits.conn_to_host)
strip_trailing_dot(&conn->conn_to_host);
@ -3828,12 +3871,13 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
}
*protocol_done = FALSE; /* default to not done */
#ifndef CURL_DISABLE_PROXY
/* set proxy_connect_closed to false unconditionally already here since it
is used strictly to provide extra information to a parent function in the
case of proxy CONNECT failures and we must make sure we don't have it
lingering set from a previous invoke */
conn->bits.proxy_connect_closed = FALSE;
#endif
/*
* Set user-agent. Used for HTTP, but since we can attempt to tunnel
* basically anything through a http proxy we can't limit this based on

View File

@ -77,6 +77,10 @@ void Curl_free_idnconverted_hostname(struct hostname *host);
void Curl_verboseconnect(struct connectdata *conn);
#endif
#ifdef CURL_DISABLE_PROXY
#define CONNECT_PROXY_SSL() FALSE
#else
#define CONNECT_PROXY_SSL()\
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
!conn->bits.proxy_ssl_connected[sockindex])
@ -88,5 +92,6 @@ void Curl_verboseconnect(struct connectdata *conn);
#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
!conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
#endif /* !CURL_DISABLE_PROXY */
#endif /* HEADER_CURL_URL_H */

View File

@ -420,11 +420,23 @@ struct negotiatedata {
* Boolean values that concerns this connection.
*/
struct ConnectBits {
/* always modify bits.close with the connclose() and connkeep() macros! */
bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
is complete */
bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
the first time on the first connect function call */
#ifndef CURL_DISABLE_PROXY
bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
is complete */
BIT(httpproxy); /* if set, this transfer is done through a http proxy */
BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
BIT(proxy_user_passwd); /* user+password for the proxy? */
BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
This is implicit when SSL-protocols are used through
proxies, but can also be enabled explicitly by
apps */
BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
in a CONNECT request with auth, so that
libcurl should reconnect and continue. */
#endif
/* always modify bits.close with the connclose() and connkeep() macros! */
BIT(close); /* if set, we close the connection after this request */
BIT(reuse); /* if set, this is a re-used connection */
BIT(altused); /* this is an alt-svc "redirect" */
@ -433,10 +445,7 @@ struct ConnectBits {
BIT(conn_to_port); /* if set, this connection has a "connect to port"
that overrides the port in the URL (remote port) */
BIT(proxy); /* if set, this transfer is done through a proxy - any type */
BIT(httpproxy); /* if set, this transfer is done through a http proxy */
BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
BIT(user_passwd); /* do we use user+password for this connection? */
BIT(proxy_user_passwd); /* user+password for the proxy? */
BIT(ipv6_ip); /* we communicate with a remote site specified with pure IPv6
IP address */
BIT(ipv6); /* we communicate with a site using an IPv6 address */
@ -446,10 +455,6 @@ struct ConnectBits {
the TCP layer connect */
BIT(retry); /* this connection is about to get closed and then
re-attempted at another connection. */
BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
This is implicit when SSL-protocols are used through
proxies, but can also be enabled explicitly by
apps */
BIT(authneg); /* TRUE when the auth phase has started, which means
that we are creating a request with an auth header,
but it is not the final request in the auth
@ -468,9 +473,6 @@ struct ConnectBits {
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
#endif
BIT(netrc); /* name+password provided by netrc */
BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
in a CONNECT request with auth, so that
libcurl should reconnect and continue. */
BIT(bound); /* set true if bind() has already been done on this socket/
connection */
BIT(multiplex); /* connection is multiplexed */
@ -910,10 +912,10 @@ struct connectdata {
char *secondaryhostname; /* secondary socket host name (ftp) */
struct hostname conn_to_host; /* the host to connect to. valid only if
bits.conn_to_host is set */
#ifndef CURL_DISABLE_PROXY
struct proxy_info socks_proxy;
struct proxy_info http_proxy;
#endif
long port; /* which port to use locally */
int remote_port; /* the remote port, not the proxy port! */
int conn_to_port; /* the remote port to connect to. valid only if
@ -961,12 +963,16 @@ struct connectdata {
struct postponed_data postponed[2]; /* two buffers for two sockets */
#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
#ifndef CURL_DISABLE_PROXY
struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
#endif
#ifdef USE_SSL
void *ssl_extra; /* separately allocated backend-specific data */
#endif
struct ssl_primary_config ssl_config;
#ifndef CURL_DISABLE_PROXY
struct ssl_primary_config proxy_ssl_config;
#endif
struct ConnectBits bits; /* various state-flags for this connection */
/* connecttime: when connect() is called on the current IP address. Used to
@ -1676,7 +1682,9 @@ struct UserDefined {
long httpversion; /* when non-zero, a specific HTTP version requested to
be used in the library's request(s) */
struct ssl_config_data ssl; /* user defined SSL stuff */
#ifndef CURL_DISABLE_PROXY
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
#endif
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
curl_proxytype proxytype; /* what kind of proxy that is in use */
long dns_cache_timeout; /* DNS cache timeout */

View File

@ -1339,7 +1339,9 @@ static void ossl_close(struct ssl_connect_data *connssl)
static void Curl_ossl_close(struct connectdata *conn, int sockindex)
{
ossl_close(&conn->ssl[sockindex]);
#ifndef CURL_DISABLE_PROXY
ossl_close(&conn->proxy_ssl[sockindex]);
#endif
}
/*
@ -1566,10 +1568,16 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
CURLcode result = CURLE_OK;
bool dNSName = FALSE; /* if a dNSName field exists in the cert */
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name : conn->host.name;
const char * const dispname = SSL_IS_PROXY() ?
conn->http_proxy.host.dispname : conn->host.dispname;
#else
/* disabled proxy support */
const char * const hostname = conn->host.name;
const char * const dispname = conn->host.dispname;
#endif
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@ -2448,16 +2456,25 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
#else
const char * const hostname = conn->host.name;
#endif
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
struct in_addr addr;
#endif
#endif
#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
#else
long * const certverifyresult = &data->set.ssl.certverifyresult;
#endif
const long int ssl_version = SSL_CONN_CONFIG(version);
#ifdef USE_TLS_SRP
const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
@ -2685,8 +2702,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
unsigned char protocols[128];
#ifdef USE_NGHTTP2
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
(!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
if(data->set.httpversion >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
@ -3153,6 +3173,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
Curl_ssl_sessionid_unlock(conn);
}
#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
BIO *const bio = BIO_new(BIO_f_ssl());
SSL *handle = conn->proxy_ssl[sockindex].backend->handle;
@ -3162,7 +3183,9 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
BIO_set_ssl(bio, handle, FALSE);
SSL_set_bio(backend->handle, bio, bio);
}
else if(!SSL_set_fd(backend->handle, (int)sockfd)) {
else
#endif
if(!SSL_set_fd(backend->handle, (int)sockfd)) {
/* pass the raw socket into the SSL layers */
failf(data, "SSL: SSL_set_fd failed: %s",
ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
@ -3179,8 +3202,12 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
struct Curl_easy *data = conn->data;
int err;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
#else
long * const certverifyresult = &data->set.ssl.certverifyresult;
#endif
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@ -3266,9 +3293,14 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
* the SO_ERROR is also lost.
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name : conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
#else
const char * const hostname = conn->host.name;
const long int port = conn->remote_port;
#endif
char extramsg[80]="";
int sockerr = SOCKERRNO;
if(sockerr && detail == SSL_ERROR_SYSCALL)
@ -3721,8 +3753,12 @@ static CURLcode servercert(struct connectdata *conn,
char error_buffer[256]="";
char buffer[2048];
const char *ptr;
#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
#else
long * const certverifyresult = &data->set.ssl.certverifyresult;
#endif
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
@ -4054,14 +4090,15 @@ static bool Curl_ossl_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
if(connssl->backend->handle && SSL_pending(connssl->backend->handle))
return TRUE;
if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
return TRUE;
#ifndef CURL_DISABLE_PROXY
{
const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
return TRUE;
}
#endif
return FALSE;
}
@ -4122,8 +4159,11 @@ static ssize_t ossl_send(struct connectdata *conn,
sslerror = ERR_get_error();
if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
conn->ssl[sockindex].state == ssl_connection_complete &&
conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
conn->ssl[sockindex].state == ssl_connection_complete
#ifndef CURL_DISABLE_PROXY
&& conn->proxy_ssl[sockindex].state == ssl_connection_complete
#endif
) {
char ver[120];
Curl_ossl_version(ver, 120);
failf(conn->data, "Error: %s does not support double SSL tunneling.",

View File

@ -215,6 +215,7 @@ static bool ssl_prefs_check(struct Curl_easy *data)
return TRUE;
}
#ifndef CURL_DISABLE_PROXY
static CURLcode
ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
{
@ -238,17 +239,20 @@ ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
}
return CURLE_OK;
}
#endif
CURLcode
Curl_ssl_connect(struct connectdata *conn, int sockindex)
{
CURLcode result;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_ssl_connected[sockindex]) {
result = ssl_connect_init_proxy(conn, sockindex);
if(result)
return result;
}
#endif
if(!ssl_prefs_check(conn->data))
return CURLE_SSL_CONNECT_ERROR;
@ -270,12 +274,13 @@ Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
bool *done)
{
CURLcode result;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_ssl_connected[sockindex]) {
result = ssl_connect_init_proxy(conn, sockindex);
if(result)
return result;
}
#endif
if(!ssl_prefs_check(conn->data))
return CURLE_SSL_CONNECT_ERROR;
@ -321,13 +326,21 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
long *general_age;
bool no_match = TRUE;
#ifndef CURL_DISABLE_PROXY
const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
const char * const name = isProxy ? conn->http_proxy.host.name :
conn->host.name;
const char * const name = isProxy ?
conn->http_proxy.host.name : conn->host.name;
int port = isProxy ? (int)conn->port : conn->remote_port;
#else
/* no proxy support */
struct ssl_primary_config * const ssl_config = &conn->ssl_config;
const char * const name = conn->host.name;
int port = conn->remote_port;
(void)sockindex;
#endif
*ssl_sessionid = NULL;
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
@ -429,14 +442,23 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
char *clone_conn_to_host;
int conn_to_port;
long *general_age;
#ifndef CURL_DISABLE_PROXY
const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
const char *hostname = isProxy ? conn->http_proxy.host.name :
conn->host.name;
#else
/* proxy support disabled */
const bool isProxy = FALSE;
struct ssl_primary_config * const ssl_config = &conn->ssl_config;
const char *hostname = conn->host.name;
(void)sockindex;
#endif
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
clone_host = strdup(hostname);
if(!clone_host)
return CURLE_OUT_OF_MEMORY; /* bail out */

View File

@ -129,14 +129,21 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
/* set of helper macros for the backends to access the correct fields. For the
proxy or for the remote host - to properly support HTTPS proxy */
#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
data->set.ssl.var)
#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ? \
conn->proxy_ssl_config.var : conn->ssl_config.var)
#ifndef CURL_DISABLE_PROXY
#define SSL_IS_PROXY() \
(CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
ssl_connection_complete != \
conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
#define SSL_SET_OPTION(var) \
(SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
#define SSL_CONN_CONFIG(var) \
(SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
#else
#define SSL_IS_PROXY() FALSE
#define SSL_SET_OPTION(var) data->set.ssl.var
#define SSL_CONN_CONFIG(var) conn->ssl_config.var
#endif
bool Curl_ssl_config_matches(struct ssl_primary_config *data,
struct ssl_primary_config *needle);

View File

@ -416,8 +416,12 @@ wolfssl_connect_step1(struct connectdata *conn,
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
#else
const char * const hostname = conn->host.name;
#endif
size_t hostname_len = strlen(hostname);
if((hostname_len < USHRT_MAX) &&
(0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
@ -538,13 +542,20 @@ wolfssl_connect_step2(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const char * const dispname = SSL_IS_PROXY() ?
conn->http_proxy.host.dispname : conn->host.dispname;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
#else
const char * const hostname = conn->host.name;
const char * const dispname = conn->host.dispname;
const char * const pinnedpubkey =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
#endif
conn->recv[sockindex] = wolfssl_recv;
conn->send[sockindex] = wolfssl_send;

View File

@ -47,6 +47,7 @@ https
NTLM
SSL
!SSPI
proxy
</features>
<name>
HTTP POST using CONNECT with --proxy-ntlm but no auth is required

View File

@ -32,10 +32,13 @@ wrong
http
https
</server>
<name>
<features>
proxy
</features>
<name>
HTTP GET same URL - different proxy ports
</name>
<command>
</name>
<command>
http://%HOSTIP:%HTTPPORT/1244 -x %HOSTIP:%HTTPPORT --next http://%HOSTIP:%HTTPPORT/124400001 -x %HOSTIP:%HTTPSPORT
</command>
</client>

View File

@ -40,6 +40,7 @@ http
</server>
<features>
idn
proxy
</features>
<setenv>
LC_ALL=en_US.UTF-8

View File

@ -24,6 +24,7 @@ And you should ignore this data.
<client>
<features>
SSL
proxy
</features>
<server>
https

Binary file not shown.