From 2f8d0df085519351dbd7123178895ba910d756c1 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Sat, 18 Feb 2017 13:56:56 +0100 Subject: 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 --- lib/http_proxy.c | 13 +++++++++---- lib/multi.c | 9 ++++++--- lib/url.c | 36 +++++++++++++++++++----------------- lib/urldata.h | 2 -- 4 files changed, 34 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/http_proxy.c b/lib/http_proxy.c index d523ba519..7fde11dbb 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -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; diff --git a/lib/multi.c b/lib/multi.c index 950b600cb..04bf3f937 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -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 diff --git a/lib/url.c b/lib/url.c index 8d1c0cc7f..2886abec8 100644 --- a/lib/url.c +++ b/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)) { diff --git a/lib/urldata.h b/lib/urldata.h index e37b566a5..c17e42cc0 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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 */ -- cgit v1.2.3