]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
New FTP CCC functionality - adds passive and active mode to accomodate for different...
authorLinus Nielsen Feltzing <linus@haxx.se>
Tue, 20 Feb 2007 22:02:11 +0000 (22:02 +0000)
committerLinus Nielsen Feltzing <linus@haxx.se>
Tue, 20 Feb 2007 22:02:11 +0000 (22:02 +0000)
docs/curl.1
docs/libcurl/curl_easy_setopt.3
include/curl/curl.h
lib/ftp.c
lib/gtls.c
lib/ssluse.c
lib/url.c
lib/urldata.h
src/main.c

index 881cd77a27cb13440d52f8720ef4fdd0ee609bc1..56659e8c86dcd7d64c8f811408ebb75c9b49cd2b 100644 (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
index 66ca11f3428d109c508c89f91e5381ccaed5cb67..9e32f13aa58991cb185064713fac1e6b4490ded0 100644 (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,
index e911fca5ab41c3217f5c751363359a0698694cfe..d7f36645ca4a657ddaa4982b4bc11901d0f16ed2 100644 (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 */
index a23acd43ed1573006a27076ddb6d1aa748bb6fe4..8328315dc435caec31da03594b89526583b4d47b 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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);
index daf69aafe9f26f05b62fc8d0415dca07eb73f82d..f8c103450cf9d2c48ee631867df6762324eddacc 100644 (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],
index dc4fc927cf92282b81596d131be948f9c190e370..b362ab3f2e12206605a04398880474ce6e33ce8d 100644 (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],
index 3bd8dcb6d72f0da58be5a37836d5559012ee46a5..05920b72ed8b0c88d9aed3b5620764d170a7a282 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -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:
index d50f9e44ab241d0402832e50d56a3d87b99f6a7c..3325699d7c8e81ddfd4fb524aa955325136b8d3c 100644 (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 */
index b3f62959056b3a4b18ae726f1981d0acf3aaba1a..ed6f338eff7f99c25e629d39f69f5a06a6762c1e 100644 (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) {