Added FTP_SKIP_PASV_IP and --ftp-skip-pasv-ip

This commit is contained in:
Daniel Stenberg 2005-09-04 05:16:06 +00:00
parent 56d9624b56
commit 7e845e7cfd
11 changed files with 117 additions and 9 deletions

View File

@ -347,6 +347,15 @@ If this option is used twice, the second will again disable silent failure.
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)

View File

@ -767,6 +767,14 @@ curl is waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It
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)

View File

@ -903,6 +903,12 @@ typedef enum {
/* 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;

View File

@ -1601,8 +1601,18 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
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) {
@ -1622,8 +1632,6 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
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

View File

@ -965,6 +965,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
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
@ -1240,7 +1248,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* 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:
/*

View File

@ -1072,8 +1072,9 @@ struct UserDefined {
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 */
};
/*

View File

@ -315,6 +315,7 @@ struct Configurable {
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;
@ -508,7 +509,8 @@ static void help(void)
" --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)",
@ -1313,6 +1315,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"$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},
@ -1709,6 +1712,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
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 */
@ -3905,6 +3911,10 @@ operate(struct Configurable *config, int argc, char *argv[])
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();

View File

@ -81,6 +81,7 @@ RETRWEIRDO
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

View File

@ -33,4 +33,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
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

48
tests/data/test270 Normal file
View File

@ -0,0 +1,48 @@
<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
PASS curl_by_daniel@haxx.se
PWD
PASV
TYPE I
SIZE 270
RETR 270
QUIT
</protocol>
</verify>

View File

@ -70,6 +70,7 @@ sub ftpmsg {
}
my $verbose=0; # set to 1 for debugging
my $pasvbadip=0;
my $retrweirdo=0;
my $retrnosize=0;
my $srcdir=".";
@ -564,7 +565,11 @@ sub PASV_command {
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 {
@ -703,6 +708,10 @@ sub customize {
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