aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-01-05 23:11:14 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-01-05 23:11:14 +0000
commit4750e6f3c5fd42e19998242ddb63d7d5506b9fd9 (patch)
treeda414a616a37056c35bda6312721064e7d65839b
parentb7aaa4d9071227d481eb163887d7dd21535b7ae3 (diff)
- Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to
curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it will make libcurl shutdown SSL/TLS after the authentication is done on a FTP-SSL operation.
-rw-r--r--CHANGES6
-rw-r--r--RELEASE-NOTES5
-rw-r--r--docs/curl.110
-rw-r--r--docs/libcurl/curl_easy_setopt.38
-rw-r--r--include/curl/curl.h7
-rw-r--r--lib/ftp.c24
-rw-r--r--lib/gtls.c68
-rw-r--r--lib/gtls.h3
-rw-r--r--lib/sslgen.c14
-rw-r--r--lib/sslgen.h6
-rw-r--r--lib/ssluse.c100
-rw-r--r--lib/ssluse.h8
-rw-r--r--lib/strerror.c5
-rw-r--r--lib/url.c6
-rw-r--r--lib/urldata.h7
-rw-r--r--src/main.c12
16 files changed, 269 insertions, 20 deletions
diff --git a/CHANGES b/CHANGES
index 811122d1d..9aafe8d57 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@
Changelog
+Daniel (5 January 2007)
+- Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to
+ curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it
+ will make libcurl shutdown SSL/TLS after the authentication is done on a
+ FTP-SSL operation.
+
Daniel (4 January 2007)
- David McCreedy made changes to allow base64 encoding/decoding to work on
non-ASCII platforms.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index fe108df67..a9317ea60 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -5,7 +5,7 @@ Curl and libcurl 7.16.1
Available command line options: 112
Available curl_easy_setopt() options: 133
Number of public functions in libcurl: 54
- Amount of public web site mirrors: 39
+ Amount of public web site mirrors: 38
Number of known libcurl bindings: 35
Number of contributors: 524
@@ -13,6 +13,7 @@ This release includes the following changes:
o Support for SCP and SFTP were added
o CURLOPT_CLOSEPOLICY is now deprecated
+ o --ftp-ssl-ccc and CURLOPT_FTP_SSL_CCC were added
This release includes the following bugfixes:
@@ -67,6 +68,6 @@ advice from friends like these:
Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell,
Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd,
Robson Braga Araujo, David McCreedy, Robert Foreman, Nathanael Nerode,
- Victor Snezhko
+ Victor Snezhko, Linus Nielsen Feltzing
Thanks! (and sorry if I forgot to mention someone)
diff --git a/docs/curl.1 b/docs/curl.1
index c87474758..4830179bd 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -433,6 +433,14 @@ Terminates the connection if the server doesn't support SSL/TLS.
(Added in 7.15.5)
If this option is used twice, the second will again disable this.
+.IP "--ftp-ssl-ccc"
+(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.
+(Added in 7.16.1)
+
+If this option is used twice, the second will again disable this.
.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
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 4893c0e24..55f4353bc 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -925,6 +925,12 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
.IP CURLFTPAUTH_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)
.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,
diff --git a/include/curl/curl.h b/include/curl/curl.h
index ea5b46201..8bbdd1b24 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -397,6 +397,8 @@ typedef enum {
generic so the error message will be of
interest when this has happened */
+ CURLE_FTP_SSL_CCC_FAILED, /* 80 - Failed to clear the FTP command
+ channel */
CURL_LAST /* never use! */
} CURLcode;
@@ -1049,6 +1051,9 @@ typedef enum {
CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
+ /* Send CCC (Clear Command Channel) after authentication */
+ CINIT(FTP_SSL_CCC, LONG, 154),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/lib/ftp.c b/lib/ftp.c
index 015c5ad3f..56b6cf229 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -666,6 +666,7 @@ static void state(struct connectdata *conn,
"ACCT",
"PBSZ",
"PROT",
+ "CCC",
"PWD",
"QUOTE",
"RETR_PREQUOTE",
@@ -2545,6 +2546,27 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we failed and bails out */
return CURLE_FTP_SSL_FAILED;
+ if(data->set.ftp_use_ccc) {
+ /* CCC - Clear Command Channel
+ */
+ NBFTPSENDF(conn, "CCC", NULL);
+ state(conn, FTP_CCC);
+ }
+ else {
+ result = ftp_state_pwd(conn);
+ if(result)
+ return result;
+ }
+ break;
+
+ case FTP_CCC:
+ /* First shut down the SSL layer (note: this call will block) */
+ result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
+
+ if(result)
+ return CURLE_FTP_SSL_CCC_FAILED;
+
+ /* Then continue as normal */
result = ftp_state_pwd(conn);
if(result)
return result;
diff --git a/lib/gtls.c b/lib/gtls.c
index bbd87161d..250ecada4 100644
--- a/lib/gtls.c
+++ b/lib/gtls.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -517,6 +517,72 @@ void Curl_gtls_close(struct connectdata *conn)
}
/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
+{
+ int result;
+ int retval = 0;
+ struct SessionHandle *data = conn->data;
+ int done = 0;
+ ssize_t nread;
+ char buf[120];
+
+ /* This has only been tested on the proftpd server, and the mod_tls code
+ sends a close notify alert without waiting for a close notify alert in
+ 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(conn->ssl[sockindex].session) {
+ while(!done) {
+ int what = Curl_select(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+ if(what > 0) {
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server */
+ result = gnutls_record_recv(conn->ssl[sockindex].session,
+ buf, sizeof(buf));
+ switch(result) {
+ case 0:
+ /* This is the expected response. There was no data but only
+ the close notify alert */
+ done = 1;
+ break;
+ case GNUTLS_E_AGAIN:
+ case GNUTLS_E_INTERRUPTED:
+ infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
+ break;
+ default:
+ retval = -1;
+ done = 1;
+ break;
+ }
+ }
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL shutdown timeout");
+ done = 1;
+ break;
+ }
+ else {
+ /* anything that gets here is fatally bad */
+ failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
+ retval = -1;
+ done = 1;
+ }
+ }
+ gnutls_deinit(conn->ssl[sockindex].session);
+ }
+ gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
+
+ conn->ssl[sockindex].session = NULL;
+ conn->ssl[sockindex].use = FALSE;
+
+ return retval;
+}
+
+/*
* If the read would block we return -1 and set 'wouldblock' to TRUE.
* Otherwise we return the amount of data read. Other errors should return -1
* and set 'wouldblock' to FALSE.
diff --git a/lib/gtls.h b/lib/gtls.h
index 4e7025c89..bff3f8693 100644
--- a/lib/gtls.h
+++ b/lib/gtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -41,5 +41,6 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
bool *wouldblock);
void Curl_gtls_session_free(void *ptr);
size_t Curl_gtls_version(char *buffer, size_t size);
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
#endif
diff --git a/lib/sslgen.c b/lib/sslgen.c
index 1d88ba343..e4fb5fb24 100644
--- a/lib/sslgen.c
+++ b/lib/sslgen.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -397,6 +397,18 @@ void Curl_ssl_close(struct connectdata *conn)
}
}
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
+{
+ if(conn->ssl[sockindex].use) {
+#ifdef USE_GNUTLS
+ return Curl_gtls_shutdown(conn, sockindex);
+#else
+ return Curl_ossl_shutdown(conn, sockindex);
+#endif
+ }
+ return CURLE_OK;
+}
+
/* Selects an (Open)SSL crypto engine
*/
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
diff --git a/lib/sslgen.h b/lib/sslgen.h
index b910ac74b..11dea3243 100644
--- a/lib/sslgen.h
+++ b/lib/sslgen.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -69,9 +69,13 @@ size_t Curl_ssl_version(char *buffer, size_t size);
int Curl_ssl_check_cxn(struct connectdata *conn);
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
+
#if !defined(USE_SSL) && !defined(SSLGEN_C)
/* set up blank macros for none-SSL builds */
#define Curl_ssl_close_all(x)
#endif
+#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
+
#endif
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 1c02edc23..5d149ba53 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -728,6 +728,102 @@ void Curl_ossl_close(struct connectdata *conn)
}
}
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
+{
+ int result;
+ int retval = 0;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
+ to be at least 120 bytes long. */
+ unsigned long sslerror;
+ ssize_t nread;
+ int err;
+ int done = 0;
+
+ /* This has only been tested on the proftpd server, and the mod_tls code
+ sends a close notify alert without waiting for a close notify alert in
+ 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(connssl->handle) {
+ while(!done) {
+ int what = Curl_select(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+ if(what > 0) {
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server */
+ nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
+ sizeof(buf));
+ err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
+
+ switch(err) {
+ case SSL_ERROR_NONE: /* this is not an error */
+ case SSL_ERROR_ZERO_RETURN: /* no more data */
+ /* This is the expected response. There was no data but only
+ the close notify alert */
+ done = 1;
+ break;
+ case SSL_ERROR_WANT_READ:
+ /* there's data pending, re-invoke SSL_read() */
+ infof(data, "SSL_ERROR_WANT_READ\n");
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ /* SSL wants a write. Really odd. Let's bail out. */
+ infof(data, "SSL_ERROR_WANT_WRITE\n");
+ done = 1;
+ break;
+ default:
+ /* openssl/ssl.h says "look at error stack/return value/errno" */
+ sslerror = ERR_get_error();
+ failf(conn->data, "SSL read: %s, errno %d",
+ ERR_error_string(sslerror, buf),
+ Curl_sockerrno() );
+ done = 1;
+ break;
+ }
+ }
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL shutdown timeout");
+ done = 1;
+ break;
+ }
+ else {
+ /* anything that gets here is fatally bad */
+ failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
+ retval = -1;
+ done = 1;
+ }
+ } /* while()-loop for the select() */
+
+ if(data->set.verbose) {
+ switch(SSL_get_shutdown(connssl->handle)) {
+ case SSL_SENT_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
+ break;
+ case SSL_RECEIVED_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
+ break;
+ case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
+ "SSL_RECEIVED__SHUTDOWN\n");
+ break;
+ }
+ }
+
+ connssl->use = FALSE; /* get back to ordinary socket usage */
+
+ SSL_free (connssl->handle);
+ connssl->handle = NULL;
+ }
+ return retval;
+}
+
void Curl_ossl_session_free(void *ptr)
{
/* free the ID */
@@ -1629,7 +1725,7 @@ Curl_ossl_connect_common(struct connectdata *conn,
while(1) {
int what = Curl_select(readfd, writefd, nonblocking?0:(int)timeout_ms);
if(what > 0)
- /* reabable or writable, go loop in the outer loop */
+ /* readable or writable, go loop in the outer loop */
break;
else if(0 == what) {
if (nonblocking) {
diff --git a/lib/ssluse.h b/lib/ssluse.h
index 05238f0eb..5bb7090c5 100644
--- a/lib/ssluse.h
+++ b/lib/ssluse.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -29,8 +29,8 @@
#include "urldata.h"
CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
-CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
bool *done);
void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
/* tell OpenSSL to close down all open information regarding connections (and
@@ -66,4 +66,6 @@ size_t Curl_ossl_version(char *buffer, size_t size);
int Curl_ossl_check_cxn(struct connectdata *cxn);
int Curl_ossl_seed(struct SessionHandle *data);
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
+
#endif
diff --git a/lib/strerror.c b/lib/strerror.c
index 4c2dacabc..2634dffdb 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2004 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -244,6 +244,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_FTP_SSL_FAILED:
return "Requested FTP SSL level failed";
+ case CURLE_FTP_SSL_CCC_FAILED:
+ return "Failed to clear the FTP command channel";
+
case CURLE_SEND_FAIL_REWIND:
return "Send failed since rewinding of the data stream failed";
diff --git a/lib/url.c b/lib/url.c
index c988506b0..0f3f85a5f 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -1140,6 +1140,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
break;
+ case CURLOPT_FTP_SSL_CCC:
+ data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long));
+ break;
+
case CURLOPT_FTP_SKIP_PASV_IP:
/*
* Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
diff --git a/lib/urldata.h b/lib/urldata.h
index b94761c0b..e2cc0d158 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -302,7 +302,7 @@ struct HTTP {
***************************************************************************/
typedef enum {
FTP_STOP, /* do nothing state, stops the state machine */
- FTP_WAIT220, /* waiting for the inintial 220 response immediately after
+ FTP_WAIT220, /* waiting for the initial 220 response immediately after
a connect */
FTP_AUTH,
FTP_USER,
@@ -310,6 +310,7 @@ typedef enum {
FTP_ACCT,
FTP_PBSZ,
FTP_PROT,
+ FTP_CCC,
FTP_PWD,
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
FTP_RETR_PREQUOTE,
@@ -1273,6 +1274,8 @@ 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 */
bool no_signal; /* do not use any signal/alarm handler */
diff --git a/src/main.c b/src/main.c
index 5de0229ea..2dc94c115 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -349,6 +349,7 @@ struct Configurable {
bool ftp_ssl;
bool ftp_ssl_reqd;
bool ftp_ssl_control;
+ bool ftp_ssl_ccc;
char *socksproxy; /* set to server string */
int socksver; /* set to CURLPROXY_SOCKS* define */
@@ -529,6 +530,7 @@ 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)",
" -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 []",
@@ -1355,6 +1357,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"$v", "ftp-ssl-reqd", FALSE},
{"$w", "no-sessionid", FALSE},
{"$x", "ftp-ssl-control", FALSE},
+ {"$y", "ftp-ssl-ccc", FALSE},
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
@@ -1779,6 +1782,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
case 'x': /* --ftp-ssl-control */
config->ftp_ssl_control ^= TRUE;
break;
+ case 'y': /* --ftp-ssl-ccc */
+ config->ftp_ssl_ccc ^= TRUE;
+ break;
}
break;
case '#': /* --progress-bar */
@@ -4002,6 +4008,10 @@ operate(struct Configurable *config, int argc, char *argv[])
else if(config->ftp_ssl_control)
curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_CONTROL);
+ /* new in curl 7.16.1 */
+ if(config->ftp_ssl_ccc)
+ curl_easy_setopt(curl, CURLOPT_FTP_SSL_CCC, TRUE);
+
/* new in curl 7.11.1, modified in 7.15.2 */
if(config->socksproxy) {
curl_easy_setopt(curl, CURLOPT_PROXY, config->socksproxy);