New FTP CCC functionality - adds passive and active mode to accomodate for different server behaviour

This commit is contained in:
Linus Nielsen Feltzing 2007-02-20 22:02:11 +00:00
parent 6014c21bc9
commit 2f5e99ca02
9 changed files with 61 additions and 11 deletions

View File

@ -448,10 +448,18 @@ If this option is used twice, the second will again disable this.
(FTP) Use CCC (Clear Command Channel)
Shuts down the SSL/TLS layer after authenticating. The rest of the
control channel communication will be unencrypted. This allows
NAT routers to follow the FTP transaction.
NAT routers to follow the FTP transaction. The default mode is
passive. See --ftp-ssl-ccc-mode for other modes.
(Added in 7.16.1)
If this option is used twice, the second will again disable this.
.IP "--ftp-ssl-ccc-mode [active/passive]"
(FTP) Use CCC (Clear Command Channel)
Sets the CCC mode. The passive mode will not initiate the shutdown, but
instead wait for the server to do it, and will not reply to the
shutdown from the server. The active mode initiates the shutdown and
waits for a reply from the server.
(Added in 7.16.2)
.IP "-F/--form <name=content>"
(HTTP) This lets curl emulate a filled in form in which a user has pressed the
submit button. This causes curl to POST data using the Content-Type

View File

@ -936,11 +936,20 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
Try "AUTH TLS" first, and only if that fails try "AUTH SSL"
.RE
.IP CURLOPT_FTP_SSL_CCC
Pass a long that is set to 0 to disable and 1 to enable. If enabled, this
option makes libcurl use CCC (Clear Command Channel). It shuts down the
SSL/TLS layer after authenticating. The rest of the control channel
communication will be unencrypted. This allows NAT routers to follow the FTP
transaction. (Added in 7.16.1)
If enabled, this option makes libcurl use CCC (Clear Command Channel). It
shuts down the SSL/TLS layer after authenticating. The rest of the
control channel communication will be unencrypted. This allows NAT routers
to follow the FTP transaction. Pass a long using one of the values below.
(Added in 7.16.1)
.RS
.IP CURLFTPSSL_CCC_NONE
Don't attempt to use CCC.
.IP CURLFTPSSL_CCC_PASSIVE
Do not initiate the shutdown, but wait for the server to do it. Do not send
a reply.
.IP CURLFTPSSL_CCC_ACTIVE
Initiate the shutdown and wait for a reply.
.RE
.IP CURLOPT_FTP_ACCOUNT
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
server asks for "account data" after user name and password has been provided,

View File

@ -465,6 +465,14 @@ typedef enum {
CURLFTPSSL_LAST /* not an option, never use */
} curl_ftpssl;
/* parameter for the CURLOPT_FTP_SSL_CCC option */
typedef enum {
CURLFTPSSL_CCC_NONE, /* do not send CCC */
CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
CURLFTPSSL_CCC_LAST /* not an option, never use */
} curl_ftpccc;
/* parameter for the CURLOPT_FTPSSLAUTH option */
typedef enum {
CURLFTPAUTH_DEFAULT, /* let libcurl decide */

View File

@ -2566,7 +2566,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we failed and bails out */
return CURLE_FTP_SSL_FAILED;
if(data->set.ftp_use_ccc) {
if(data->set.ftp_ccc) {
/* CCC - Clear Command Channel
*/
NBFTPSENDF(conn, "CCC", NULL);

View File

@ -533,6 +533,9 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
if(conn->ssl[sockindex].session) {
while(!done) {
int what = Curl_select(conn->sock[sockindex],

View File

@ -749,6 +749,9 @@ int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
(void)SSL_shutdown(connssl->handle);
if(connssl->handle) {
while(!done) {
int what = Curl_select(conn->sock[sockindex],

View File

@ -1156,7 +1156,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
case CURLOPT_FTP_SSL_CCC:
data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long));
data->set.ftp_ccc = va_arg(param, long);
break;
case CURLOPT_FTP_SKIP_PASV_IP:

View File

@ -1283,10 +1283,10 @@ struct UserDefined {
bool reuse_fresh; /* do not re-use an existing connection */
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
bool ftp_use_ccc; /* if CCC is to be attempted or not */
curl_ftpssl ftp_ssl; /* if AUTH TLS is to be attempted etc */
curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
curl_ftpccc ftp_ccc; /* FTP CCC options */
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 */

View File

@ -440,6 +440,7 @@ struct Configurable {
bool ftp_ssl_reqd;
bool ftp_ssl_control;
bool ftp_ssl_ccc;
int ftp_ssl_ccc_mode;
char *socksproxy; /* set to server string */
int socksver; /* set to CURLPROXY_SOCKS* define */
@ -627,7 +628,8 @@ static void help(void)
" --ftp-ssl Try SSL/TLS for ftp transfer (F)",
" --ftp-ssl-control Require SSL/TLS for ftp login, clear for transfer (F)",
" --ftp-ssl-reqd Require SSL/TLS for ftp transfer (F)",
" --ftp-ssl-ccc Send CCC after authenticating (F)",
" --ftp-ssl-ccc Send CCC after authenticating. (F)",
" --ftp-ssl-ccc-mode [active/passive] Set CCC mode (F)",
" -F/--form <name=content> Specify HTTP multipart POST data (H)",
" --form-string <name=string> Specify HTTP multipart POST data (H)",
" -g/--globoff Disable URL sequences and ranges using {} and []",
@ -1380,6 +1382,16 @@ static int ftpfilemethod(struct Configurable *config, char *str)
return CURLFTPMETHOD_MULTICWD;
}
static int ftpcccmethod(struct Configurable *config, char *str)
{
if(curlx_strequal("passive", str))
return CURLFTPSSL_CCC_PASSIVE;
if(curlx_strequal("active", str))
return CURLFTPSSL_CCC_ACTIVE;
warnf(config, "unrecognized ftp CCC method '%s', using default\n", str);
return CURLFTPSSL_CCC_PASSIVE;
}
static ParameterError getparameter(char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
bool *usedarg, /* set to TRUE if the arg
@ -1460,6 +1472,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"$w", "no-sessionid", FALSE},
{"$x", "ftp-ssl-control", FALSE},
{"$y", "ftp-ssl-ccc", FALSE},
{"$j", "ftp-ssl-ccc-mode", TRUE},
{"$z", "libcurl", TRUE},
{"$#", "raw", FALSE},
@ -1888,6 +1901,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
break;
case 'y': /* --ftp-ssl-ccc */
config->ftp_ssl_ccc ^= TRUE;
if(!config->ftp_ssl_ccc_mode)
config->ftp_ssl_ccc_mode = CURLFTPSSL_CCC_PASSIVE;
break;
case 'j': /* --ftp-ssl-ccc-mode */
config->ftp_ssl_ccc = TRUE;
config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg);
break;
case 'z': /* --libcurl */
GetStr(&config->libcurl, nextarg);
@ -4211,7 +4230,7 @@ operate(struct Configurable *config, int argc, char *argv[])
/* new in curl 7.16.1 */
if(config->ftp_ssl_ccc)
my_setopt(curl, CURLOPT_FTP_SSL_CCC, TRUE);
my_setopt(curl, CURLOPT_FTP_SSL_CCC, config->ftp_ssl_ccc_mode);
/* new in curl 7.11.1, modified in 7.15.2 */
if(config->socksproxy) {