Hi,

it seems like this bug was fixed by upstream in version 2.0.7. See the
full Changelog[0] for more details about what was fixed in 2.0.7. Thanks
to Andreas for pointing that out.

However, backporting the fixes to 2.0.6 would be nice. The attached diff
takes care of that. Or, simply use the original 2.0.7 source from
upstream.

Best,
        Christian

[0] ftp://vsftpd.beasts.org/users/cevans/untar/vsftpd-2.0.7/Changelog
Only in vsftpd-2.0.7/: .postlogin.c.swp
diff -u vsftpd-2.0.6/Changelog vsftpd-2.0.7/Changelog
--- vsftpd-2.0.6/Changelog      2008-02-12 06:34:34.000000000 +0100
+++ vsftpd-2.0.7/Changelog      2008-07-30 05:55:17.000000000 +0200
@@ -975,3 +975,20 @@
 
 At this point: v2.0.6 released!
 ===============================
+
+- Fix finding libcap for the link on Slackware systems, thanks to Roman
+Kravchenko <[EMAIL PROTECTED]>.
+- Fix build on Solaris 2.8 due to non-standard C, thanks to IIDA Yosiaki
+<[EMAIL PROTECTED]>.
+- Fix man page typo, thanks Matt Selsky <[EMAIL PROTECTED]>.
+- Bring the PASV listen() into the bind() retry loop to resolve a race under
+extreme load. Thanks to Curtis Taylor <[EMAIL PROTECTED]>.
+- Enhance logging for debug_ssl.
+- Shutdown the SSL data connections properly. This prevents clients such as
+recent FileZilla from complaining. Reported by various people.
+- Add option to enforce proper SSL shutdown on uploads. Left it off after much
+agonizing because clients are so broken in this area.
+- Add option to delete failed uploads.
+
+At this point: v2.0.7 released!
+===============================
Common subdirectories: vsftpd-2.0.6/EXAMPLE and vsftpd-2.0.7/EXAMPLE
diff -u vsftpd-2.0.6/README vsftpd-2.0.7/README
--- vsftpd-2.0.6/README 2008-02-12 05:42:21.000000000 +0100
+++ vsftpd-2.0.7/README 2008-07-29 06:15:28.000000000 +0200
@@ -1,4 +1,4 @@
-This is vsftpd, version 2.0.6
+This is vsftpd, version 2.0.7
 Author: Chris Evans
 Contact: [EMAIL PROTECTED]
 Website: http://vsftpd.beasts.org/
Common subdirectories: vsftpd-2.0.6/RedHat and vsftpd-2.0.7/RedHat
Common subdirectories: vsftpd-2.0.6/SECURITY and vsftpd-2.0.7/SECURITY
Common subdirectories: vsftpd-2.0.6/dummyinc and vsftpd-2.0.7/dummyinc
diff -u vsftpd-2.0.6/ftpdataio.c vsftpd-2.0.7/ftpdataio.c
--- vsftpd-2.0.6/ftpdataio.c    2008-02-03 19:45:35.000000000 +0100
+++ vsftpd-2.0.7/ftpdataio.c    2008-07-29 06:54:55.000000000 +0200
@@ -51,9 +51,10 @@
                           enum EVSFRWTarget target);
 static unsigned int get_chunk_size();
 
-void
+int
 vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess)
 {
+  int dispose_ret = 1;
   int retval;
   if (p_sess->data_fd == -1)
   {
@@ -64,7 +65,7 @@
   vsf_sysutil_uninstall_io_handler();
   if (p_sess->p_data_ssl != 0)
   {
-    ssl_data_close(p_sess);
+    dispose_ret = ssl_data_close(p_sess);
   }
   /* This close() blocks because we set SO_LINGER */
   retval = vsf_sysutil_close_failok(p_sess->data_fd);
@@ -76,6 +77,7 @@
   }
   vsf_sysutil_clear_alarm();
   p_sess->data_fd = -1;
+  return dispose_ret;
 }
 
 int
diff -u vsftpd-2.0.6/ftpdataio.h vsftpd-2.0.7/ftpdataio.h
--- vsftpd-2.0.6/ftpdataio.h    2008-02-02 02:30:39.000000000 +0100
+++ vsftpd-2.0.7/ftpdataio.h    2008-07-29 06:53:56.000000000 +0200
@@ -15,8 +15,11 @@
  * timeout goes off, or the connection is severed).
  * PARAMETERS
  * p_sess       - the current FTP session object
+ * RETURNS
+ * 1 on success, 0 otherwise.
+ * 
  */
-void vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess);
+int vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess);
 
 /* vsf_ftpdataio_get_pasv_fd()
  * PURPOSE
diff -u vsftpd-2.0.6/parseconf.c vsftpd-2.0.7/parseconf.c
--- vsftpd-2.0.6/parseconf.c    2008-02-12 05:53:32.000000000 +0100
+++ vsftpd-2.0.7/parseconf.c    2008-07-30 03:53:05.000000000 +0200
@@ -102,6 +102,10 @@
   { "debug_ssl", &tunable_debug_ssl },
   { "require_cert", &tunable_require_cert },
   { "validate_cert", &tunable_validate_cert },
+  { "strict_ssl_read_eof", &tunable_strict_ssl_read_eof },
+  { "strict_ssl_write_shutdown", &tunable_strict_ssl_write_shutdown },
+  { "ssl_request_cert", &tunable_ssl_request_cert },
+  { "delete_failed_uploads", &tunable_delete_failed_uploads },
   { 0, 0 }
 };
 
Common subdirectories: vsftpd-2.0.6/port and vsftpd-2.0.7/port
diff -u vsftpd-2.0.6/postlogin.c vsftpd-2.0.7/postlogin.c
--- vsftpd-2.0.6/postlogin.c    2008-02-12 04:53:06.000000000 +0100
+++ vsftpd-2.0.7/postlogin.c    2008-07-30 03:51:09.000000000 +0200
@@ -568,19 +568,22 @@
     retval = vsf_sysutil_bind(p_sess->pasv_listen_fd, s_p_sockaddr);
     if (!vsf_sysutil_retval_is_error(retval))
     {
-      break;
+      retval = vsf_sysutil_listen(p_sess->pasv_listen_fd, 1);
+      if (!vsf_sysutil_retval_is_error(retval))
+      {
+        break;
+      }
     }
     if (vsf_sysutil_get_error() == kVSFSysUtilErrADDRINUSE)
     {
       continue;
     }
-    die("vsf_sysutil_bind");
+    die("vsf_sysutil_bind / listen");
   }
   if (!bind_retries)
   {
     die("vsf_sysutil_bind");
   }
-  vsf_sysutil_listen(p_sess->pasv_listen_fd, 1);
   if (is_epsv)
   {
     str_alloc_text(&s_pasv_res_str, "Entering Extended Passive Mode (|||");
@@ -718,7 +721,10 @@
   }
   trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,
                                           opened_file, 0, is_ascii);
-  vsf_ftpdataio_dispose_transfer_fd(p_sess);
+  if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)
+  {
+    trans_ret.retval = -2;
+  }
   p_sess->transfer_size = trans_ret.transferred;
   /* Log _after_ the blocking dispose call, so we get transfer times right */
   if (trans_ret.retval == 0)
@@ -863,7 +869,10 @@
   }
   if (!stat_cmd)
   {
-    vsf_ftpdataio_dispose_transfer_fd(p_sess);
+    if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && retval == 0)
+    {
+      retval = -1;
+    }
   }
   if (stat_cmd)
   {
@@ -972,6 +981,8 @@
   struct vsf_transfer_ret trans_ret;
   int new_file_fd;
   int remote_fd;
+  int success = 0;
+  int created = 0;
   filesize_t offset = p_sess->restart_pos;
   p_sess->restart_pos = 0;
   if (!data_transfer_checks_ok(p_sess))
@@ -1018,6 +1029,7 @@
     vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create file.");
     return;
   }
+  created = 1;
   vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);
   if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
   {
@@ -1075,11 +1087,14 @@
     trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,
                                             new_file_fd, 1, 0);
   }
-  vsf_ftpdataio_dispose_transfer_fd(p_sess);
+  if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)
+  {
+    trans_ret.retval = -2;
+  }
   p_sess->transfer_size = trans_ret.transferred;
-  /* XXX - handle failure, delete file? */
   if (trans_ret.retval == 0)
   {
+    success = 1;
     vsf_log_do_log(p_sess, 1);
   }
   if (trans_ret.retval == -1)
@@ -1098,6 +1113,10 @@
 port_pasv_cleanup_out:
   port_cleanup(p_sess);
   pasv_cleanup(p_sess);
+  if (tunable_delete_failed_uploads && created && !success)
+  {
+    str_unlink(p_filename);
+  }
   vsf_sysutil_close(new_file_fd);
 }
 
diff -u vsftpd-2.0.6/privops.c vsftpd-2.0.7/privops.c
--- vsftpd-2.0.6/privops.c      2008-02-04 14:22:23.000000000 +0100
+++ vsftpd-2.0.7/privops.c      2008-07-29 04:00:33.000000000 +0200
@@ -44,6 +44,7 @@
    */
   for (i = 0; i < 2; ++i)
   {
+    double sleep_for;
     vsf_sysutil_sockaddr_clone(&p_sockaddr, p_sess->p_local_addr);
     vsf_sysutil_sockaddr_set_port(p_sockaddr, tunable_ftp_data_port);
     retval = vsf_sysutil_bind(s, p_sockaddr);
@@ -55,7 +56,7 @@
     {
       die("vsf_sysutil_bind");
     }
-    double sleep_for = vsf_sysutil_get_random_byte();
+    sleep_for = vsf_sysutil_get_random_byte();
     sleep_for /= 256.0;
     sleep_for += 1.0;
     vsf_sysutil_sleep(sleep_for);
diff -u vsftpd-2.0.6/readwrite.c vsftpd-2.0.7/readwrite.c
--- vsftpd-2.0.6/readwrite.c    2008-02-02 02:30:40.000000000 +0100
+++ vsftpd-2.0.7/readwrite.c    2008-07-30 03:30:16.000000000 +0200
@@ -51,11 +51,11 @@
 }
 
 int
-ftp_read_data(const struct vsf_session* p_sess, char* p_buf, unsigned int len)
+ftp_read_data(struct vsf_session* p_sess, char* p_buf, unsigned int len)
 {
   if (p_sess->data_use_ssl)
   {
-    return ssl_read(p_sess->p_data_ssl, p_buf, len);
+    return ssl_read(p_sess, p_buf, len);
   }
   else
   {
diff -u vsftpd-2.0.6/readwrite.h vsftpd-2.0.7/readwrite.h
--- vsftpd-2.0.6/readwrite.h    2008-02-02 02:30:40.000000000 +0100
+++ vsftpd-2.0.7/readwrite.h    2008-07-30 03:30:08.000000000 +0200
@@ -12,8 +12,7 @@
 
 int ftp_write_str(const struct vsf_session* p_sess, const struct mystr* p_str,
                   enum EVSFRWTarget target);
-int ftp_read_data(const struct vsf_session* p_sess, char* p_buf,
-                  unsigned int len);
+int ftp_read_data(struct vsf_session* p_sess, char* p_buf, unsigned int len);
 int ftp_write_data(const struct vsf_session* p_sess, const char* p_buf,
                    unsigned int len);
 void ftp_getline(const struct vsf_session* p_sess, struct mystr* p_str,
diff -u vsftpd-2.0.6/ssl.c vsftpd-2.0.7/ssl.c
--- vsftpd-2.0.6/ssl.c  2008-02-12 05:57:58.000000000 +0100
+++ vsftpd-2.0.7/ssl.c  2008-07-30 05:56:39.000000000 +0200
@@ -28,6 +28,7 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include <openssl/bio.h>
+#include <errno.h>
 
 static char* get_ssl_error();
 static SSL* get_ssl(struct vsf_session* p_sess, int fd);
@@ -38,6 +39,8 @@
 static int ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx);
 static int ssl_cert_digest(
   SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str);
+static void maybe_log_shutdown_state(struct vsf_session* p_sess);
+static void maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret);
 
 static int ssl_inited;
 static struct mystr debug_str;
@@ -111,17 +114,23 @@
     {
       die("SSL: RNG is not seeded");
     }
-    verify_option = SSL_VERIFY_PEER;
+    if (tunable_ssl_request_cert)
+    {
+      verify_option |= SSL_VERIFY_PEER;
+    }
     if (tunable_require_cert)
     {
       verify_option |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
     }
-    SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
-    if (tunable_ca_certs_file)
+    if (verify_option)
     {
-      if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
+      SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
+      if (tunable_ca_certs_file)
       {
-        die("SSL: could not load verify file");
+        if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
+        {
+          die("SSL: could not load verify file");
+        }
       }
     }
     p_sess->p_ssl_ctx = p_ctx;
@@ -207,11 +216,12 @@
 ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
             char end_char, char* p_buf, unsigned int buflen)
 {
+  char* p_buf_start;
   if (buflen == 0)
   {
     return;
   }
-  char* p_buf_start = p_buf;
+  p_buf_start = p_buf;
   p_buf[buflen - 1] = end_char;
   buflen--;
   while (1)
@@ -238,17 +248,30 @@
 }
 
 int
-ssl_read(void* p_ssl, char* p_buf, unsigned int len)
+ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len)
 {
   int retval;
   int err;
+  SSL* p_ssl = p_sess->p_data_ssl;
   do
   {
-    retval = SSL_read((SSL*) p_ssl, p_buf, len);
-    err = SSL_get_error((SSL*) p_ssl, retval);
+    retval = SSL_read(p_ssl, p_buf, len);
+    err = SSL_get_error(p_ssl, retval);
   }
   while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
                         err == SSL_ERROR_WANT_WRITE));
+  // If we hit an EOF, make sure it was from the peer, not injected by the
+  // attacker.
+  if (retval == 0 && SSL_get_shutdown(p_ssl) != SSL_RECEIVED_SHUTDOWN)
+  {
+    str_alloc_text(&debug_str, "Connection terminated without SSL shutdown "
+                               "- buggy client?");
+    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
+    if (tunable_strict_ssl_read_eof)
+    {
+      return -1;
+    }
+  }
   return retval;
 }
 
@@ -279,14 +302,93 @@
   return 0;
 }
 
-void
-ssl_data_close(struct vsf_session* p_sess)
+static void
+maybe_log_shutdown_state(struct vsf_session* p_sess)
 {
-  if (p_sess->p_data_ssl)
+  if (tunable_debug_ssl)
   {
-    SSL_free(p_sess->p_data_ssl);
+    int ret = SSL_get_shutdown(p_sess->p_data_ssl);
+    str_alloc_text(&debug_str, "SSL shutdown state is: ");
+    if (ret == 0)
+    {
+      str_append_text(&debug_str, "NONE");
+    }
+    else if (ret == SSL_SENT_SHUTDOWN)
+    {
+      str_append_text(&debug_str, "SSL_SENT_SHUTDOWN");
+    }
+    else if (ret == SSL_RECEIVED_SHUTDOWN)
+    {
+      str_append_text(&debug_str, "SSL_RECEIVED_SHUTDOWN");
+    }
+    else
+    {
+      str_append_ulong(&debug_str, ret);
+    }
+    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
+  }
+}
+
+static void
+maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret)
+{
+  if (tunable_debug_ssl)
+  {
+    str_alloc_text(&debug_str, "SSL ret: ");
+    str_append_ulong(&debug_str, ret);
+    str_append_text(&debug_str, ", SSL error: ");
+    str_append_text(&debug_str, get_ssl_error());
+    str_append_text(&debug_str, ", errno: ");
+    str_append_ulong(&debug_str, errno);
+    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
+  }
+}
+
+int
+ssl_data_close(struct vsf_session* p_sess)
+{
+  int success = 1;
+  SSL* p_ssl = p_sess->p_data_ssl;
+  if (p_ssl)
+  {
+    int ret;
+    maybe_log_shutdown_state(p_sess);
+    // This is a mess. Ideally, when we're the sender, we'd like to get to the
+    // SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the
+    // peer received all the data and shut the connection down cleanly. It
+    // doesn't matter hugely apart from logging, but it's a nagging detail.
+    // Unfortunately, no FTP client I found was able to get sends into that
+    // state, so the best we can do is issue SSL_shutdown but not check the
+    // errors / returns. At least this enables the receiver to be sure of the
+    // integrity of the send in terms of unwanted truncation.
+    ret = SSL_shutdown(p_ssl);
+    maybe_log_shutdown_state(p_sess);
+    if (ret == 0)
+    {
+      ret = SSL_shutdown(p_ssl);
+      maybe_log_shutdown_state(p_sess);
+      if (ret != 1)
+      {
+        if (tunable_strict_ssl_write_shutdown)
+        {
+          success = 0;
+        }
+        maybe_log_shutdown_state(p_sess);
+        maybe_log_ssl_error_state(p_sess, ret);
+      }
+    }
+    else if (ret < 0)
+    {
+      if (tunable_strict_ssl_write_shutdown)
+      {
+        success = 0;
+      }
+      maybe_log_ssl_error_state(p_sess, ret);
+    }
+    SSL_free(p_ssl);
     p_sess->p_data_ssl = NULL;
   }
+  return success;
 }
 
 int
@@ -296,11 +398,12 @@
    * protocol. If a client sends an unfortunately optional client cert then
    * we can check for a match between the control and data connections.
    */
+  SSL* p_ssl;
   if (p_sess->p_data_ssl != NULL)
   {
     die("p_data_ssl should be NULL.");
   }
-  SSL* p_ssl = get_ssl(p_sess, fd);
+  p_ssl = get_ssl(p_sess, fd);
   if (p_ssl == NULL)
   {
     return 0;
@@ -549,9 +652,9 @@
 }
 
 int
-ssl_read(void* p_ssl, char* p_buf, unsigned int len)
+ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len)
 {
-  (void) p_ssl;
+  (void) p_sess;
   (void) p_buf;
   (void) len;
   return -1;
@@ -582,10 +685,11 @@
   return -1;
 }
 
-void
+int
 ssl_data_close(struct vsf_session* p_sess)
 {
   (void) p_sess;
+  return 1;
 }
 
 void
diff -u vsftpd-2.0.6/ssl.h vsftpd-2.0.7/ssl.h
--- vsftpd-2.0.6/ssl.h  2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/ssl.h  2008-07-30 03:24:26.000000000 +0200
@@ -6,12 +6,12 @@
 
 void ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
                  char end_char, char* p_buf, unsigned int buflen);
-int ssl_read(void* p_ssl, char* p_buf, unsigned int len);
+int ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len);
 int ssl_write(void* p_ssl, const char* p_buf, unsigned int len);
 int ssl_write_str(void* p_ssl, const struct mystr* p_str);
 void ssl_init(struct vsf_session* p_sess);
 int ssl_accept(struct vsf_session* p_sess, int fd);
-void ssl_data_close(struct vsf_session* p_sess);
+int ssl_data_close(struct vsf_session* p_sess);
 void ssl_comm_channel_init(struct vsf_session* p_sess);
 void handle_auth(struct vsf_session* p_sess);
 void handle_pbsz(struct vsf_session* p_sess);
diff -u vsftpd-2.0.6/standalone.c vsftpd-2.0.7/standalone.c
--- vsftpd-2.0.6/standalone.c   2008-02-02 02:30:40.000000000 +0100
+++ vsftpd-2.0.7/standalone.c   2008-07-29 05:22:25.000000000 +0200
@@ -130,7 +130,11 @@
       die("could not bind listening IPv6 socket");
     }
   }
-  vsf_sysutil_listen(listen_sock, VSFTP_LISTEN_BACKLOG);
+  retval = vsf_sysutil_listen(listen_sock, VSFTP_LISTEN_BACKLOG);
+  if (vsf_sysutil_retval_is_error(retval))
+  {
+    die("could not listen");
+  }
   vsf_sysutil_sockaddr_alloc(&p_accept_addr);
   while (1)
   {
diff -u vsftpd-2.0.6/sysutil.c vsftpd-2.0.7/sysutil.c
--- vsftpd-2.0.6/sysutil.c      2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/sysutil.c      2008-07-29 05:21:02.000000000 +0200
@@ -917,10 +917,11 @@
 char*
 vsf_sysutil_getcwd(char* p_dest, const unsigned int buf_size)
 {
+  char* p_retval;
   if (buf_size == 0) {
     return p_dest;
   }
-  char* p_retval = getcwd(p_dest, buf_size);
+  p_retval = getcwd(p_dest, buf_size);
   p_dest[buf_size - 1] = '\0';
   return p_retval;
 }
@@ -1515,10 +1516,11 @@
 int
 vsf_sysutil_readlink(const char* p_filename, char* p_dest, unsigned int bufsiz)
 {
+  int retval;
   if (bufsiz == 0) {
     return -1;
   }
-  int retval = readlink(p_filename, p_dest, bufsiz - 1);
+  retval = readlink(p_filename, p_dest, bufsiz - 1);
   if (retval < 0)
   {
     return retval;
@@ -1620,14 +1622,16 @@
   return bind(fd, p_sockaddr, len);
 }
 
-void
+int
 vsf_sysutil_listen(int fd, const unsigned int backlog)
 {
   int retval = listen(fd, backlog);
-  if (retval != 0)
+  if (vsf_sysutil_retval_is_error(retval) &&
+      vsf_sysutil_get_error() != kVSFSysUtilErrADDRINUSE)
   {
     die("listen");
   }
+  return retval;
 }
 
 /* Warning: callers of this function assume it does NOT make use of any
diff -u vsftpd-2.0.6/sysutil.h vsftpd-2.0.7/sysutil.h
--- vsftpd-2.0.6/sysutil.h      2008-02-02 02:30:39.000000000 +0100
+++ vsftpd-2.0.7/sysutil.h      2008-07-29 05:18:32.000000000 +0200
@@ -239,7 +239,7 @@
 struct vsf_sysutil_socketpair_retval
   vsf_sysutil_unix_stream_socketpair(void);
 int vsf_sysutil_bind(int fd, const struct vsf_sysutil_sockaddr* p_sockptr);
-void vsf_sysutil_listen(int fd, const unsigned int backlog);
+int vsf_sysutil_listen(int fd, const unsigned int backlog);
 void vsf_sysutil_getsockname(int fd, struct vsf_sysutil_sockaddr** p_sockptr);
 void vsf_sysutil_getpeername(int fd, struct vsf_sysutil_sockaddr** p_sockptr);
 int vsf_sysutil_accept_timeout(int fd, struct vsf_sysutil_sockaddr* p_sockaddr,
diff -u vsftpd-2.0.6/tunables.c vsftpd-2.0.7/tunables.c
--- vsftpd-2.0.6/tunables.c     2008-02-12 05:53:01.000000000 +0100
+++ vsftpd-2.0.7/tunables.c     2008-07-30 03:52:23.000000000 +0200
@@ -74,6 +74,10 @@
 int tunable_debug_ssl = 0;
 int tunable_require_cert = 0;
 int tunable_validate_cert = 0;
+int tunable_strict_ssl_read_eof = 0;
+int tunable_strict_ssl_write_shutdown = 0;
+int tunable_ssl_request_cert = 1;
+int tunable_delete_failed_uploads = 0;
 
 unsigned int tunable_accept_timeout = 60;
 unsigned int tunable_connect_timeout = 60;
diff -u vsftpd-2.0.6/tunables.h vsftpd-2.0.7/tunables.h
--- vsftpd-2.0.6/tunables.h     2008-02-12 05:52:49.000000000 +0100
+++ vsftpd-2.0.7/tunables.h     2008-07-30 03:52:11.000000000 +0200
@@ -70,6 +70,10 @@
 extern int tunable_debug_ssl;                 /* Verbose SSL logging */
 extern int tunable_require_cert;              /* SSL client cert required */
 extern int tunable_validate_cert;             /* SSL certs must be valid */
+extern int tunable_strict_ssl_read_eof;       /* Need SSL_shutdown() on read */
+extern int tunable_strict_ssl_write_shutdown; /* Need SSL_shutdown() on write 
*/
+extern int tunable_ssl_request_cert;          /* Ask client for cert */
+extern int tunable_delete_failed_uploads;     /* Delete an upload that failed 
*/
 
 /* Integer/numeric defines */
 extern unsigned int tunable_accept_timeout;
diff -u vsftpd-2.0.6/vsf_findlibs.sh vsftpd-2.0.7/vsf_findlibs.sh
--- vsftpd-2.0.6/vsf_findlibs.sh        2008-02-02 02:30:40.000000000 +0100
+++ vsftpd-2.0.7/vsf_findlibs.sh        2008-07-29 03:52:35.000000000 +0200
@@ -45,6 +45,7 @@
 # Look for libcap (capabilities)
 locate_library /lib/libcap.so.1 && echo "/lib/libcap.so.1";
 locate_library /usr/lib/libcap.so && echo "-lcap";
+locate_library /lib/libcap.so && echo "-lcap";
 
 # Solaris needs this for nanosleep()..
 locate_library /lib/libposix4.so && echo "-lposix4";
diff -u vsftpd-2.0.6/vsftpd.conf.5 vsftpd-2.0.7/vsftpd.conf.5
--- vsftpd-2.0.6/vsftpd.conf.5  2008-02-12 05:56:32.000000000 +0100
+++ vsftpd-2.0.7/vsftpd.conf.5  2008-07-30 03:56:30.000000000 +0200
@@ -169,6 +169,11 @@
 
 Default: NO
 .TP
+.B delete_failed_uploads
+If true, any failed upload files are deleted.  (Added in v2.0.7).
+
+Default: NO
+.TP
 .B deny_email_enable
 If activated, you may provide a list of anonymous password e-mail responses
 which cause login to be denied. By default, the file containing this list is
@@ -445,6 +450,14 @@
 
 Default: NO
 .TP
+.B ssl_request_cert
+If enabled, vsftpd will request (but not necessarily require; see
+.BR require_cert) a certificate on incoming SSL connections. Normally this
+should not cause any trouble at all, but IBM zOS seems to have issues.
+(New in v2.0.7).
+
+Default: YES
+.TP
 .B ssl_sslv2
 Only applies if
 .BR ssl_enable
@@ -469,6 +482,23 @@
 
 Default: YES
 .TP
+.B strict_ssl_read_eof
+If enabled, SSL data uploads are required to terminate via SSL, not an
+EOF on the socket. This option is required to be sure that an attacker did
+not terminate an upload prematurely with a faked TCP FIN. Unfortunately, it
+is not enabled by default because so few clients get it right. (New in v2.0.7).
+
+Default: NO
+.TP
+.B strict_ssl_write_shutdown
+If enabled, SSL data downloads are required to terminate via SSL, not an
+EOF on the socket. This is off by default as I was unable to find a single
+FTP client that does this. It is minor. All it affects is our ability to tell
+whether the client confirmed full receipt of the file. Even without this 
option,
+the client is able to check the integrity of the download. (New in v2.0.7).
+
+Default: NO
+.TP
 .B syslog_enable
 If enabled, then any log output which would have gone to /var/log/vsftpd.log
 goes to the system log instead. Logging is done under the FTPD facility.
@@ -915,7 +945,7 @@
 .TP
 .B ssl_ciphers
 This option can be used to select which SSL ciphers vsftpd will allow for
-encrpyted SSL connections. See the
+encrypted SSL connections. See the
 .BR ciphers
 man page for further details. Note that restricting ciphers can be a useful
 security precaution as it prevents malicious remote parties forcing a cipher
diff -u vsftpd-2.0.6/vsftpver.h vsftpd-2.0.7/vsftpver.h
--- vsftpd-2.0.6/vsftpver.h     2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/vsftpver.h     2008-07-29 06:15:16.000000000 +0200
@@ -1,7 +1,7 @@
 #ifndef VSF_VERSION_H
 #define VSF_VERSION_H
 
-#define VSF_VERSION "2.0.6"
+#define VSF_VERSION "2.0.7"
 
 #endif /* VSF_VERSION_H */
 
Common subdirectories: vsftpd-2.0.6/xinetd.d and vsftpd-2.0.7/xinetd.d

Reply via email to