using this option can be used to override a previous --ftp-port option. (Added
in 7.11.0)
+If this option is used twice, the second will again disable silent failure.
+.IP "--ftp-skip-pasv-ip"
+(FTP) Tell curl to not use the IP address the server suggests in its response
+to curl's PASV command when curl connects the data connection. Instead curl
+will re-use the same IP address it already uses for the control
+connection. (Added in 7.14.1)
+
+This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
+
If this option is used twice, the second will again disable silent failure.
.IP "--ftp-ssl"
(FTP) Make the FTP connection switch to use SSL/TLS. (Added in 7.11.0)
is recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set
\fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than
\fICURLOPT_TIMEOUT\fP. (Added in 7.10.8)
+.IP CURLOPT_FTP_SKIP_PASV_IP
+Pass a long. If set to a non-zero value, it instructs libcurl to not use the
+IP address the server suggests in its 227-response to libcurl's PASV command
+when libcurl connects the data connection. Instead libcurl will re-use the
+same IP address it already uses for the control connection. But it will use
+the port number from the 227-response. (Added in 7.14.1)
+
+This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
.IP CURLOPT_FTP_SSL
Pass a long using one of the values from below, to make libcurl use your
desired level of SSL for the ftp transfer. (Added in 7.11.0)
/* ignore Content-Length */
CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
return CURLE_FTP_WEIRD_227_FORMAT;
}
- snprintf(newhost, sizeof(newhost),
- "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+ /* we got OK from server */
+ if(data->set.ftp_skip_ip) {
+ /* told to ignore the remotely given IP but instead use the one we used
+ for the control connection */
+ infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
+ ip[0], ip[1], ip[2], ip[3],
+ conn->ip_addr_str);
+ snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
+ }
+ else
+ snprintf(newhost, sizeof(newhost),
+ "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
newport = (port[0]<<8) + port[1];
}
else if(ftp->count1 == 0) {
return CURLE_FTP_WEIRD_PASV_REPLY;
}
- /* we got OK from server */
-
if(data->change.proxy && *data->change.proxy) {
/*
* This is a tunnel through a http proxy and we need to connect to the
data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
break;
+ case CURLOPT_FTP_SKIP_PASV_IP:
+ /*
+ * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
+ * bypass of the IP address in PASV responses.
+ */
+ data->set.ftp_skip_ip = (bool)va_arg(param, long);
+ break;
+
case CURLOPT_INFILE:
/*
* FILE pointer to read the file to be uploaded from. Or possibly
/*
* Set a SSL_CTX callback
*/
- data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+ data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
break;
case CURLOPT_SSL_CTX_DATA:
/*
bool no_signal; /* do not use any signal/alarm handler */
bool global_dns_cache; /* subject for future removal */
bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */
-
bool ignorecl; /* ignore content length */
+ bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
+ us */
};
/*
bool insecure_ok; /* set TRUE to allow insecure SSL connects */
bool create_dirs;
bool ftp_create_dirs;
+ bool ftp_skip_ip;
bool proxyntlm;
bool proxydigest;
bool proxybasic;
" --crlf Convert LF to CRLF in upload",
" -f/--fail Fail silently (no output at all) on errors (H)",
" --ftp-create-dirs Create the remote dirs if not present (F)",
- " --ftp-pasv Use PASV instead of PORT (F)",
+ " --ftp-pasv Use PASV/EPSV instead of PORT (F)",
+ " --ftp-skip-pasv-ip Skip the IP address for PASV (F)\n"
" --ftp-ssl Enable SSL/TLS for the ftp transfer (F)",
" -F/--form <name=content> Specify HTTP multipart POST data (H)",
" --form-string <name=string> Specify HTTP multipart POST data (H)",
{"$n", "proxy-anyauth", FALSE},
{"$o", "trace-time", FALSE},
{"$p", "ignore-content-length", FALSE},
+ {"$q", "ftp-skip-pasv-ip", FALSE},
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
case 'p': /* --ignore-content-length */
config->ignorecl ^= TRUE;
break;
+ case 'q': /* --ftp-skip-pasv-ip */
+ config->ftp_skip_ip ^= TRUE;
+ break;
}
break;
case '#': /* --progress-bar */
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl);
+ /* curl 7.14.1 */
+ curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP,
+ config->ftp_skip_ip);
+
retry_numretries = config->req_retry;
retrystart = curlx_tvnow();
RETRNOSIZE
NOSAVE
SLOWDOWN
+PASVBADIP - makes PASV send back an illegal IP in its 227 response
For HTTP, one specified command is supported:
"auth_required" - if this is set and a POST/PUT is made without auth, the
test237 test238 test239 test243 test245 test246 test247 test248 test249 \
test250 test251 test252 test253 test254 test255 test521 test522 test523 \
test256 test257 test258 test259 test260 test261 test262 test263 test264 \
- test265 test266 test267 test268 test269
+ test265 test266 test267 test268 test269 test270
--- /dev/null
+<info>
+<keywords>
+FTP
+PASV
+RETR
+</keywords>
+</info>
+# Server-side
+<reply>
+<data>
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</data>
+<servercmd>
+PASVBADIP
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP RETR PASV --ftp-skip-pasv-ip
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/270 --ftp-skip-pasv-ip --disable-epsv
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous\r
+PASS curl_by_daniel@haxx.se\r
+PWD\r
+PASV\r
+TYPE I\r
+SIZE 270\r
+RETR 270\r
+QUIT\r
+</protocol>
+</verify>
}
my $verbose=0; # set to 1 for debugging
+my $pasvbadip=0;
my $retrweirdo=0;
my $retrnosize=0;
my $srcdir=".";
if($cmd ne "EPSV") {
# PASV reply
- sendcontrol sprintf("227 Entering Passive Mode (127,0,0,1,%d,%d)\n",
+ my $p="127,0,0,1";
+ if($pasvbadip) {
+ $p="1,2,3,4";
+ }
+ sendcontrol sprintf("227 Entering Passive Mode ($p,%d,%d)\n",
($pasvport/256), ($pasvport%256));
}
else {
logmsg "FTPD: instructed to use RETRNOSIZE\n";
$retrnosize=1;
}
+ elsif($_ =~ /PASVBADIP/) {
+ logmsg "FTPD: instructed to use PASVBADIP\n";
+ $pasvbadip=1;
+ }
elsif($_ =~ /NOSAVE/) {
# don't actually store the file we upload - to be used when
# uploading insanely huge amounts