mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 15:48:49 -05:00
proxy: fix hostname resolution and IDN conversion
Properly resolve, convert and log the proxy host names.
Support the "--connect-to" feature for SOCKS proxies and for passive FTP
data transfers.
Follow-up to cb4e2be
Reported-by: Jay Satiro
Fixes https://github.com/curl/curl/issues/1248
This commit is contained in:
parent
13e3a18b34
commit
2f8d0df085
@ -98,16 +98,21 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
* original pointer
|
||||
*
|
||||
* This function might be called several times in the multi interface case
|
||||
* if the proxy's CONNTECT response is not instant.
|
||||
* if the proxy's CONNECT response is not instant.
|
||||
*/
|
||||
prot_save = conn->data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else if(conn->bits.conn_to_host)
|
||||
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
|
@ -638,7 +638,10 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
|
||||
infof(data, "Connection #%ld to host %s left intact\n",
|
||||
conn->connection_id,
|
||||
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
|
||||
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);
|
||||
}
|
||||
else
|
||||
data->state.lastconnect = NULL;
|
||||
@ -1477,8 +1480,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
|
36
lib/url.c
36
lib/url.c
@ -3054,7 +3054,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
|
||||
free_fixed_hostname(&conn->host);
|
||||
free_fixed_hostname(&conn->conn_to_host);
|
||||
free_fixed_hostname(&conn->proxy);
|
||||
free_fixed_hostname(&conn->http_proxy.host);
|
||||
free_fixed_hostname(&conn->socks_proxy.host);
|
||||
|
||||
@ -3819,17 +3818,19 @@ CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(conn->bits.socksproxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char * const host = conn->bits.conn_to_host ?
|
||||
conn->conn_to_host.name :
|
||||
conn->bits.httpproxy ?
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
const char * const host = conn->bits.httpproxy ?
|
||||
conn->http_proxy.host.name :
|
||||
conn->bits.conn_to_host ?
|
||||
conn->conn_to_host.name :
|
||||
sockindex == SECONDARYSOCKET ?
|
||||
conn->secondaryhostname : conn->host.name;
|
||||
const int port = conn->bits.conn_to_port ? conn->conn_to_port :
|
||||
conn->bits.httpproxy ?
|
||||
(int)conn->http_proxy.port :
|
||||
sockindex == SECONDARYSOCKET ?
|
||||
conn->secondary_port : conn->remote_port;
|
||||
const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
|
||||
sockindex == SECONDARYSOCKET ? conn->secondary_port :
|
||||
conn->bits.conn_to_port ? conn->conn_to_port :
|
||||
conn->remote_port;
|
||||
conn->bits.socksproxy_connecting = TRUE;
|
||||
switch(conn->socks_proxy.proxytype) {
|
||||
case CURLPROXY_SOCKS5:
|
||||
@ -3867,7 +3868,8 @@ void Curl_verboseconnect(struct connectdata *conn)
|
||||
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
|
||||
conn->host.dispname,
|
||||
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
|
||||
conn->host.dispname,
|
||||
conn->ip_addr_str, conn->port, conn->connection_id);
|
||||
}
|
||||
#endif
|
||||
@ -4114,7 +4116,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
|
||||
conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
|
||||
conn->connection_id = -1; /* no ID */
|
||||
conn->port = -1; /* unknown at this point */
|
||||
conn->remote_port = -1; /* unknown */
|
||||
conn->remote_port = -1; /* unknown at this point */
|
||||
#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
|
||||
conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
|
||||
conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
|
||||
@ -5925,7 +5927,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
||||
if(conn->bits.conn_to_port)
|
||||
conn->port = conn->conn_to_port;
|
||||
else
|
||||
conn->port = conn->remote_port; /* it is the same port */
|
||||
conn->port = conn->remote_port;
|
||||
|
||||
/* Resolve target host right on */
|
||||
rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
|
||||
@ -5981,11 +5983,9 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
{
|
||||
free_fixed_hostname(&old_conn->http_proxy.host);
|
||||
free_fixed_hostname(&old_conn->socks_proxy.host);
|
||||
free_fixed_hostname(&old_conn->proxy);
|
||||
|
||||
free(old_conn->http_proxy.host.rawalloc);
|
||||
free(old_conn->socks_proxy.host.rawalloc);
|
||||
free(old_conn->proxy.rawalloc);
|
||||
|
||||
/* free the SSL config struct from this connection struct as this was
|
||||
allocated in vain and is targeted for destruction */
|
||||
@ -6432,12 +6432,14 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
fix_hostname(conn, &conn->host);
|
||||
if(conn->bits.conn_to_host)
|
||||
fix_hostname(conn, &conn->conn_to_host);
|
||||
if(conn->proxy.name && *conn->proxy.name)
|
||||
fix_hostname(conn, &conn->proxy);
|
||||
if(conn->bits.httpproxy)
|
||||
fix_hostname(conn, &conn->http_proxy.host);
|
||||
if(conn->bits.socksproxy)
|
||||
fix_hostname(conn, &conn->socks_proxy.host);
|
||||
|
||||
/*************************************************************
|
||||
* Check whether the host and the "connect to host" are equal.
|
||||
* Do this after the hostnames have been IDN-fixed .
|
||||
* Do this after the hostnames have been IDN-fixed.
|
||||
*************************************************************/
|
||||
if(conn->bits.conn_to_host &&
|
||||
strcasecompare(conn->conn_to_host.name, conn->host.name)) {
|
||||
|
@ -936,7 +936,6 @@ 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 */
|
||||
struct hostname proxy;
|
||||
|
||||
struct proxy_info socks_proxy;
|
||||
struct proxy_info http_proxy;
|
||||
@ -1644,7 +1643,6 @@ struct UserDefined {
|
||||
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
|
||||
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
curl_proxytype socks_proxytype; /* what kind of socks proxy that is in use */
|
||||
long dns_cache_timeout; /* DNS cache timeout */
|
||||
long buffer_size; /* size of receive buffer to use */
|
||||
void *private_data; /* application-private data */
|
||||
|
@ -80,7 +80,7 @@ test626 test627 test628 test629 test630 test631 test632 test633 test634 \
|
||||
test635 test636 test637 test638 test639 test640 test641 \
|
||||
\
|
||||
test700 test701 test702 test703 test704 test705 test706 test707 test708 \
|
||||
test709 test710 test711 test712 \
|
||||
test709 test710 test711 test712 test713 test714 test715 \
|
||||
\
|
||||
test800 test801 test802 test803 test804 test805 test806 test807 test808 \
|
||||
test809 test810 test811 test812 test813 test814 test815 test816 test817 \
|
||||
@ -176,4 +176,4 @@ test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
|
||||
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
|
||||
test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \
|
||||
test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \
|
||||
test2048 test2049 test2050 test2051 test2052 test2053 test2054
|
||||
test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055
|
||||
|
80
tests/data/test2055
Executable file
80
tests/data/test2055
Executable file
@ -0,0 +1,80 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP CONNECT
|
||||
HTTP proxy
|
||||
proxytunnel
|
||||
CURLOPT_CONNECT_TO
|
||||
SOCKS5
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
</connect>
|
||||
|
||||
<data>
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 3
|
||||
Content-Type: text/plain
|
||||
|
||||
OK
|
||||
</data>
|
||||
|
||||
<datacheck>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 3
|
||||
Content-Type: text/plain
|
||||
|
||||
OK
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
http-proxy
|
||||
socks5
|
||||
</server>
|
||||
<name>
|
||||
Connect to specific host via SOCKS proxy and HTTP proxy (switch to tunnel mode automatically)
|
||||
</name>
|
||||
|
||||
<command>
|
||||
http://www.example.com.2055/2055 --connect-to ::connect.example.com.2055:%HTTPPORT -x %HOSTIP:%PROXYPORT --preproxy socks5://%HOSTIP:%SOCKSPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
^User-Agent:.*
|
||||
</strip>
|
||||
<proxy>
|
||||
CONNECT connect.example.com.2055:%HTTPPORT HTTP/1.1
|
||||
Host: connect.example.com.2055:%HTTPPORT
|
||||
Proxy-Connection: Keep-Alive
|
||||
|
||||
</proxy>
|
||||
<protocol>
|
||||
GET /2055 HTTP/1.1
|
||||
Host: www.example.com.2055
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
|
||||
</verify>
|
||||
</testcase>
|
@ -6,7 +6,6 @@ FTP
|
||||
PASV
|
||||
RETR
|
||||
SOCKS5
|
||||
all_proxy
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
|
49
tests/data/test713
Executable file
49
tests/data/test713
Executable file
@ -0,0 +1,49 @@
|
||||
<testcase>
|
||||
#based off test 712
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
PASV
|
||||
RETR
|
||||
SOCKS5
|
||||
CURLOPT_CONNECT_TO
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
silly content
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
socks5
|
||||
</server>
|
||||
<name>
|
||||
FTP fetch with --proxy set to socks5:// and with --connect-to
|
||||
</name>
|
||||
<command>
|
||||
ftp://ftp.example.com/713 --connect-to ::%HOSTIP:%FTPPORT --proxy socks5://%HOSTIP:%SOCKSPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
EPSV
|
||||
TYPE I
|
||||
SIZE 713
|
||||
RETR 713
|
||||
QUIT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
64
tests/data/test714
Executable file
64
tests/data/test714
Executable file
@ -0,0 +1,64 @@
|
||||
<testcase>
|
||||
#based off test 712
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
PASV
|
||||
RETR
|
||||
HTTP
|
||||
HTTP CONNECT
|
||||
proxytunnel
|
||||
CURLOPT_CONNECT_TO
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
</connect>
|
||||
|
||||
<data nocheck="yes">
|
||||
silly content
|
||||
</data>
|
||||
|
||||
<datacheck>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
silly content
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
http-proxy
|
||||
</server>
|
||||
<name>
|
||||
FTP fetch with --proxy set to http:// and with --connect-to
|
||||
</name>
|
||||
<command>
|
||||
ftp://ftp.example.com.714/714 --connect-to ::connect.example.com.714:%FTPPORT --proxytunnel --proxy http://%HOSTIP:%PROXYPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
EPSV
|
||||
TYPE I
|
||||
SIZE 714
|
||||
RETR 714
|
||||
QUIT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
66
tests/data/test715
Executable file
66
tests/data/test715
Executable file
@ -0,0 +1,66 @@
|
||||
<testcase>
|
||||
#based off test 712
|
||||
<info>
|
||||
<keywords>
|
||||
FTP
|
||||
PASV
|
||||
RETR
|
||||
HTTP
|
||||
HTTP CONNECT
|
||||
proxytunnel
|
||||
SOCKS5
|
||||
CURLOPT_CONNECT_TO
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
</connect>
|
||||
|
||||
<data nocheck="yes">
|
||||
silly content
|
||||
</data>
|
||||
|
||||
<datacheck>
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
HTTP/1.1 200 Connection established
|
||||
|
||||
silly content
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
ftp
|
||||
http-proxy
|
||||
socks5
|
||||
</server>
|
||||
<name>
|
||||
FTP fetch with --preproxy, --proxy and --connect-to
|
||||
</name>
|
||||
<command>
|
||||
ftp://ftp.example.com.715/715 --connect-to ::connect.example.com.715:%FTPPORT --proxytunnel --proxy %HOSTIP:%PROXYPORT --preproxy socks5://%HOSTIP:%SOCKSPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
USER anonymous
|
||||
PASS ftp@example.com
|
||||
PWD
|
||||
EPSV
|
||||
TYPE I
|
||||
SIZE 715
|
||||
RETR 715
|
||||
QUIT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
Loading…
Reference in New Issue
Block a user