summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/ftp.c
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-02-07 11:38:00 -0500
committerBrad King <brad.king@kitware.com>2017-02-07 11:38:00 -0500
commit1df9d5f91944e0b5ba00815d55bb7dc545053b4c (patch)
tree7f3ac8bf78c485cd3254a16754657bd5d43bd561 /Utilities/cmcurl/lib/ftp.c
parentf4a3290ae7ae096f8b92f7adfba7088e6918bc0b (diff)
parent4cc2908fdaaf1ab8afe5c2ae5dbb3401859a9aab (diff)
downloadcmake-1df9d5f91944e0b5ba00815d55bb7dc545053b4c.tar.gz
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2016-12-22 (44b9b4d4)
Diffstat (limited to 'Utilities/cmcurl/lib/ftp.c')
-rw-r--r--Utilities/cmcurl/lib/ftp.c196
1 files changed, 68 insertions, 128 deletions
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 9d0a03ce97..89c7e40595 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -384,10 +384,10 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
* Curl_pgrsTime(..., TIMER_STARTACCEPT);
*
*/
-static long ftp_timeleft_accept(struct Curl_easy *data)
+static time_t ftp_timeleft_accept(struct Curl_easy *data)
{
- long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
- long other;
+ time_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+ time_t other;
struct timeval now;
if(data->set.accepttimeout > 0)
@@ -430,7 +430,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
int result;
- long timeout_ms;
+ time_t timeout_ms;
ssize_t nread;
int ftpcode;
@@ -455,7 +455,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
/* see if the connection request is already here */
- switch (result) {
+ switch(result) {
case -1: /* error */
/* let's die here */
failf(data, "Error while waiting for server connect");
@@ -499,7 +499,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
struct FTP *ftp = data->req.protop;
CURLcode result = CURLE_OK;
- if(conn->ssl[SECONDARYSOCKET].use) {
+ if(conn->bits.ftp_use_data_ssl) {
/* since we only have a plaintext TCP connection here, we must now
* do the TLS stuff */
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
@@ -547,7 +547,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
{
struct Curl_easy *data = conn->data;
- long timeout_ms;
+ time_t timeout_ms;
CURLcode result = CURLE_OK;
*connected = FALSE;
@@ -687,8 +687,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line in a response or continue reading. */
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
- long timeout; /* timeout in milliseconds */
- long interval_ms;
+ time_t timeout; /* timeout in milliseconds */
+ time_t interval_ms;
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -740,8 +740,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* wait for more data anyway.
*/
}
- else {
- switch (SOCKET_READABLE(sockfd, interval_ms)) {
+ else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) {
+ switch(SOCKET_READABLE(sockfd, interval_ms)) {
case -1: /* select() error, stop reading */
failf(data, "FTP response aborted due to select/poll error: %d",
SOCKERRNO);
@@ -1035,7 +1035,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(*string_ftpport == '[') {
/* [ipv6]:port(-range) */
ip_start = string_ftpport + 1;
- if((ip_end = strchr(string_ftpport, ']')) != NULL)
+ ip_end = strchr(string_ftpport, ']');
+ if(ip_end)
strncpy(addr, ip_start, ip_end - ip_start);
}
else
@@ -1043,30 +1044,35 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(*string_ftpport == ':') {
/* :port */
ip_end = string_ftpport;
- }
- else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
- /* either ipv6 or (ipv4|domain|interface):port(-range) */
-#ifdef ENABLE_IPV6
- if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
- /* ipv6 */
- port_min = port_max = 0;
- strcpy(addr, string_ftpport);
- ip_end = NULL; /* this got no port ! */
}
- else
+ else {
+ ip_end = strchr(string_ftpport, ':');
+ if(ip_end) {
+ /* either ipv6 or (ipv4|domain|interface):port(-range) */
+#ifdef ENABLE_IPV6
+ if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
+ /* ipv6 */
+ port_min = port_max = 0;
+ strcpy(addr, string_ftpport);
+ ip_end = NULL; /* this got no port ! */
+ }
+ else
#endif
- /* (ipv4|domain|interface):port(-range) */
- strncpy(addr, string_ftpport, ip_end - ip_start);
- }
- else
- /* ipv4|interface */
- strcpy(addr, string_ftpport);
+ /* (ipv4|domain|interface):port(-range) */
+ strncpy(addr, string_ftpport, ip_end - ip_start);
+ }
+ else
+ /* ipv4|interface */
+ strcpy(addr, string_ftpport);
+ }
/* parse the port */
if(ip_end != NULL) {
- if((port_start = strchr(ip_end, ':')) != NULL) {
+ port_start = strchr(ip_end, ':');
+ if(port_start) {
port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
- if((port_sep = strchr(port_start, '-')) != NULL) {
+ port_sep = strchr(port_start, '-');
+ if(port_sep) {
port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
}
else
@@ -1850,84 +1856,6 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
return result;
}
-/*
- * Perform the necessary magic that needs to be done once the TCP connection
- * to the proxy has completed.
- */
-static CURLcode proxy_magic(struct connectdata *conn,
- char *newhost, unsigned short newport,
- bool *magicdone)
-{
- CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
-
-#if defined(CURL_DISABLE_PROXY)
- (void) newhost;
- (void) newport;
-#endif
-
- *magicdone = FALSE;
-
- switch(conn->proxytype) {
- case CURLPROXY_SOCKS5:
- case CURLPROXY_SOCKS5_HOSTNAME:
- result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
- newport, SECONDARYSOCKET, conn);
- *magicdone = TRUE;
- break;
- case CURLPROXY_SOCKS4:
- result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
- SECONDARYSOCKET, conn, FALSE);
- *magicdone = TRUE;
- break;
- case CURLPROXY_SOCKS4A:
- result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
- SECONDARYSOCKET, conn, TRUE);
- *magicdone = TRUE;
- break;
- case CURLPROXY_HTTP:
- case CURLPROXY_HTTP_1_0:
- /* do nothing here. handled later. */
- break;
- default:
- failf(data, "unknown proxytype option given");
- result = CURLE_COULDNT_CONNECT;
- break;
- }
-
- if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
- /* BLOCKING */
- /* We want "seamless" FTP operations through HTTP proxy tunnel */
-
- /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
- * member conn->proto.http; we want FTP through HTTP and we have to
- * change the member temporarily for connecting to the HTTP proxy. After
- * Curl_proxyCONNECT we have to set back the member to the original
- * struct FTP pointer
- */
- struct HTTP http_proxy;
- struct FTP *ftp_save = data->req.protop;
- memset(&http_proxy, 0, sizeof(http_proxy));
- data->req.protop = &http_proxy;
-
- result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
-
- data->req.protop = ftp_save;
-
- if(result)
- return result;
-
- if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
- /* the CONNECT procedure is not complete, the tunnel is not yet up */
- state(conn, FTP_STOP); /* this phase is completed */
- return result;
- }
- else
- *magicdone = TRUE;
- }
-
- return result;
-}
static char *control_address(struct connectdata *conn)
{
@@ -1935,11 +1863,7 @@ 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. */
- if(conn->bits.tunnel_proxy ||
- conn->proxytype == CURLPROXY_SOCKS5 ||
- conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- conn->proxytype == CURLPROXY_SOCKS4 ||
- conn->proxytype == CURLPROXY_SOCKS4A)
+ if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
return conn->host.name;
return conn->ip_addr_str;
@@ -2063,7 +1987,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
* here. We don't want to rely on a former host lookup that might've
* expired now, instead we remake the lookup here and now!
*/
- rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
+ const char * const host_name = conn->bits.socksproxy ?
+ conn->socks_proxy.host.name : conn->http_proxy.host.name;
+ rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING, ignores the return code but 'addr' will be NULL in
case of failure */
@@ -2073,8 +1999,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
(unsigned short)conn->port; /* we connect to the proxy's port */
if(!addr) {
- failf(data, "Can't resolve proxy host %s:%hu",
- conn->proxy.name, connectport);
+ failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
return CURLE_FTP_CANT_GET_HOST;
}
}
@@ -2115,6 +2040,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
/* this just dumps information about this second connection */
ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
+ Curl_safefree(conn->secondaryhostname);
+ conn->secondaryhostname = strdup(ftpc->newhost);
+ conn->secondary_port = ftpc->newport;
+
Curl_resolv_unlock(data, addr); /* we're done using this address */
conn->bits.do_more = TRUE;
state(conn, FTP_STOP); /* this phase is completed */
@@ -2763,7 +2692,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
}
#endif
- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ if(data->set.use_ssl &&
+ (!conn->ssl[FIRSTSOCKET].use ||
+ (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
+ !conn->proxy_ssl[FIRSTSOCKET].use))) {
/* We don't have a SSL/TLS connection yet, but FTPS is
requested. Try a FTPS connection now */
@@ -2808,7 +2740,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(!result) {
- conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
+ conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
result = ftp_state_user(conn);
}
}
@@ -2850,7 +2782,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
case FTP_PROT:
if(ftpcode/100 == 2)
/* We have enabled SSL for the data connection! */
- conn->ssl[SECONDARYSOCKET].use =
+ conn->bits.ftp_use_data_ssl =
(data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
/* FTP servers typically responds with 500 if they decide to reject
our 'P' request */
@@ -3250,7 +3182,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
ssize_t nread;
int ftpcode;
CURLcode result = CURLE_OK;
- char *path;
+ char *path = NULL;
const char *path_to_use = data->state.path;
if(!ftp)
@@ -3666,10 +3598,6 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
/* Ready to do more? */
if(connected) {
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
- if(conn->bits.proxy) {
- infof(data, "Connection to proxy confirmed\n");
- result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
- }
}
else {
if(result && (ftpc->count1 == 0)) {
@@ -3681,6 +3609,18 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
}
}
+ result = Curl_proxy_connect(conn, SECONDARYSOCKET);
+ if(result)
+ return result;
+
+ if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
+ return result;
+
+ if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+ conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE)
+ return result;
+
+
if(ftpc->state) {
/* already in a state so skip the initial commands.
They are only done to kickstart the do_more state */
@@ -3940,7 +3880,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
struct WildcardData * const wildcard = &(conn->data->wildcard);
CURLcode result = CURLE_OK;
- switch (wildcard->state) {
+ switch(wildcard->state) {
case CURLWC_INIT:
result = init_wc_data(conn);
if(wildcard->state == CURLWC_CLEAN)
@@ -4247,8 +4187,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
const char *cur_pos;
const char *filename = NULL;
- cur_pos = path_to_use; /* current position in path. point at the begin
- of next path component */
+ cur_pos = path_to_use; /* current position in path. point at the begin of
+ next path component */
ftpc->ctl_valid = FALSE;
ftpc->cwdfail = FALSE;
@@ -4568,7 +4508,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
command = Curl_raw_toupper(type[6]);
conn->bits.type_set = TRUE;
- switch (command) {
+ switch(command) {
case 'A': /* ASCII mode */
data->set.prefer_ascii = TRUE;
break;