commit fa64963ea3fba13b932238e31bc99330322799a5
Author: Frank Denis (Jedi/Sector One) <github@pureftpd.org>
Date:   Sat Oct 10 14:32:05 2009 +0200

    Support STAT over TLS.

Index: pure-ftpd-1.0.22/src/ftp_parser.c
===================================================================
--- pure-ftpd-1.0.22.orig/src/ftp_parser.c	2012-11-28 11:06:28.032856004 +0100
+++ pure-ftpd-1.0.22/src/ftp_parser.c	2012-11-28 11:06:28.045856452 +0100
@@ -569,15 +569,8 @@
 #ifndef MINIMAL
             } else if (!strcmp(cmd, "stat")) {
                 if (*arg != 0) {
-# ifdef WITH_TLS
-                    if (tls_cnx != NULL) {
-                        addreply_noformat(500, MSG_UNKNOWN_COMMAND);
-                    } else
-# endif
-                    {
-                        modern_listings = 0;
-                        donlist(arg, 1, 1, 1, 1);
-                    }
+                    modern_listings = 0;
+                    donlist(arg, 1, 1, 1, 1);
                 } else {
                     addreply_noformat(211, "http://www.pureftpd.org/");
                 }
Index: pure-ftpd-1.0.22/src/ftpd.c
===================================================================
--- pure-ftpd-1.0.22.orig/src/ftpd.c	2012-11-28 11:06:28.019855553 +0100
+++ pure-ftpd-1.0.22/src/ftpd.c	2012-11-28 13:50:54.765801568 +0100
@@ -87,7 +87,7 @@
 }
 
 #ifdef WITH_TLS
-int secure_safe_write(const void *buf_, size_t count)
+int secure_safe_write(void * const tls_fd, const void *buf_, size_t count)
 {
     ssize_t written;
     register const char *buf = (const char *) buf_;
@@ -95,10 +95,8 @@
     
     while (count > (size_t) 0U) {
         for (;;) {
-            if ((written = SSL_write(tls_data_cnx, buf, count)) <= (ssize_t) 0) {
-                if (errno == EAGAIN) {
-                    sleep(1);
-                } else if (errno != EINTR) {
+            if ((written = SSL_write(tls_fd, buf, count)) <= (ssize_t) 0) {
+                if (SSL_get_error(tls_fd, written) != SSL_ERROR_NONE) {
                     return -1;
                 }
                 continue;
@@ -2803,7 +2801,7 @@
 
 #ifdef WITH_TLS
     if (enforce_tls_auth && data_protection_level == CPL_PRIVATE) {
-        writeret = secure_safe_write(asciibuf,
+        writeret = secure_safe_write(tls_data_cnx, asciibuf,
                                      (size_t) (asciibufpnt - asciibuf));
     } else
 #endif
@@ -3140,7 +3138,7 @@
 
 # ifdef WITH_TLS
             if (enforce_tls_auth && data_protection_level == CPL_PRIVATE) {
-                w = secure_safe_write (p + skip, (size_t) (left - skip));
+                w = secure_safe_write (tls_data_cnx, p + skip, (size_t) (left - skip));
             } else
 # endif
             {
Index: pure-ftpd-1.0.22/src/ftpd.h
===================================================================
--- pure-ftpd-1.0.22.orig/src/ftpd.h	2012-11-28 11:06:28.032856004 +0100
+++ pure-ftpd-1.0.22/src/ftpd.h	2012-11-28 11:06:28.047856522 +0100
@@ -323,7 +323,7 @@
 
 int safe_write(const int fd, const void *buf_, size_t count);
 #ifdef WITH_TLS
-int secure_safe_write(const void *buf_, size_t count);
+int secure_safe_write(void * const tls_fd, const void *buf_, size_t count);
 #endif
 void *aborttransfer(int);
 void parser(void);
Index: pure-ftpd-1.0.22/src/ls.c
===================================================================
--- pure-ftpd-1.0.22.orig/src/ls.c	2012-11-28 11:06:28.033856038 +0100
+++ pure-ftpd-1.0.22/src/ls.c	2012-11-28 11:23:25.235048504 +0100
@@ -7,12 +7,15 @@
 #include "dynamic.h"
 #include "ftpwho-update.h"
 #include "globals.h"
+#ifdef WITH_TLS
+# include "tls.h"
+#endif
 
 #ifdef WITH_DMALLOC
 # include <dmalloc.h>
 #endif
 
-static void wrstr(const int f, const char *s)
+static void wrstr(const int f, void * const tls_fd, const char *s)
 {
     static char outbuf[CONF_TCP_SO_SNDBUF];
     static size_t outcnt;
@@ -21,8 +24,8 @@
     if (s == NULL) {
         if (outcnt > (size_t) 0U) {
 #ifdef WITH_TLS
-            if (data_protection_level == CPL_PRIVATE) {
-                if (secure_safe_write(outbuf, outcnt) < 0) {
+            if (tls_fd != NULL) {
+                if (secure_safe_write(tls_fd, outbuf, outcnt) < 0) {
                     return;
                 } 
             } else
@@ -53,7 +56,7 @@
     }
 #ifdef WITH_TLS
     if (data_protection_level == CPL_PRIVATE) {
-        if (secure_safe_write(outbuf, sizeof outbuf) < 0) {
+        if (secure_safe_write(tls_fd, outbuf, sizeof outbuf) < 0) {
             return;
         } 
     } else
@@ -66,7 +69,7 @@
 #ifdef WITH_TLS
     if (data_protection_level == CPL_PRIVATE) {    
         while (l > sizeof outbuf) {
-            if (secure_safe_write(s, sizeof outbuf) < 0) {
+            if (secure_safe_write(tls_fd, s, sizeof outbuf) < 0) {
                 return;
             }
             s += sizeof outbuf;
@@ -430,7 +433,7 @@
     return rval;
 }
 
-static void outputfiles(int f)
+static void outputfiles(int f, void * const tls_fd)
 {
     unsigned int n;
     struct filename *p;
@@ -507,13 +510,13 @@
                 pad[2] = 0;
             }
 #ifdef WITH_RFC2640
-        c_buf = charset_fs2client(q->line);
-            wrstr(f, c_buf);
-        free(c_buf);
+            c_buf = charset_fs2client(q->line);
+            wrstr(f, tls_fd, c_buf);
+            free(c_buf);
 #else
-            wrstr(f, q->line);
+            wrstr(f, tls_fd, q->line);
 #endif
-            wrstr(f, pad);
+            wrstr(f, tls_fd, pad);
             q = q->right;
             free(tmp);
         }
@@ -672,7 +675,8 @@
 }
 
 /* have to change to the directory first (speed hack for -R) */
-static void listdir(unsigned int depth, int f, const char *name)
+static void listdir(unsigned int depth, int f, void * const tls_fd,
+                    const char *name)
 {
     PureFileInfo *dir;
     char *names;
@@ -705,7 +709,7 @@
         }
         s++;
     }
-    outputfiles(f);
+    outputfiles(f, tls_fd);
     r = dir;
     while (opt_R && r != s) {
         if (r->name_offset != (size_t) -1 && !chdir(FI_NAME(r))) {
@@ -723,18 +727,18 @@
             if (modern_listings == 0) {
 #endif
 #ifdef FANCY_LS_DIRECTORY_HEADERS
-                wrstr(f, "\r\n>----------------[");
-                wrstr(f, alloca_subdir);
-                wrstr(f, "]----------------<\r\n\r\n");
+                wrstr(f, tls_fd, "\r\n>----------------[");
+                wrstr(f, tls_fd, alloca_subdir);
+                wrstr(f, tls_fd, "]----------------<\r\n\r\n");
 #else
-                wrstr(f, "\r\n\r\n");
-                wrstr(f, alloca_subdir);
-                wrstr(f, ":\r\n\r\n");                    
+                wrstr(f, tls_fd, "\r\n\r\n");
+                wrstr(f, tls_fd, alloca_subdir);
+                wrstr(f, tls_fd, ":\r\n\r\n");                    
 #endif
 #ifndef MINIMAL
             }
 #endif
-            listdir(depth + 1U, f, alloca_subdir);
+            listdir(depth + 1U, f, tls_fd, alloca_subdir);
             nolist:
             ALLOCA_FREE(alloca_subdir);
             if (matches >= max_ls_files) {
@@ -760,7 +764,8 @@
              const int opt_a_, const int split_args)
 {
     int c;
-
+    void *tls_fd = NULL;
+    
     matches = 0U;
 
     opt_C = opt_d = opt_F = opt_R = opt_r = opt_t = opt_S = 0;
@@ -827,18 +832,25 @@
         if (type == 2) {
             addreply_noformat(0, "ASCII");
         }
+#ifdef WITH_TLS
+        if (data_protection_level == CPL_PRIVATE) {
+            tls_fd = tls_data_cnx;
+        }
+#endif
     } else {                           /* STAT command */
         c = 1;
 #ifdef WITH_TLS
         if (data_protection_level == CPL_PRIVATE) {
-            secure_safe_write("213-STAT" CRLF, sizeof "213-STAT" CRLF - 1U);
+            secure_safe_write(tls_cnx, "213-STAT" CRLF,
+                              sizeof "213-STAT" CRLF - 1U);
+            tls_fd = tls_cnx;
         }
         else
 #endif
         {
             safe_write(c, "213-STAT" CRLF, sizeof "213-STAT" CRLF - 1U);
         }
-    }        
+    }
     if (arg != NULL && *arg != 0) {
         int justone;
 
@@ -888,7 +900,7 @@
                     }
                     path++;
                 }
-                outputfiles(c);    /* in case of opt_C */
+                outputfiles(c, tls_fd);    /* in case of opt_C */
                 path = g.gl_pathv;
                 while (path && *path) {
                     if (matches >= max_ls_files) {
@@ -897,17 +909,17 @@
                     if (**path) {
                         if (!justone) {
 #ifdef FANCY_LS_DIRECTORY_HEADERS                            
-                            wrstr(c, "\r\n>-----------------[");
-                            wrstr(c, *path);
-                            wrstr(c, "]-----------------<\r\n\r\n");
+                            wrstr(c, tls_fd, "\r\n>-----------------[");
+                            wrstr(c, tls_fd, *path);
+                            wrstr(c, tls_fd, "]-----------------<\r\n\r\n");
 #else
-                            wrstr(c, "\r\n\r\n");
-                            wrstr(c, *path);
-                            wrstr(c, ":\r\n\r\n");
+                            wrstr(c, tls_fd, "\r\n\r\n");
+                            wrstr(c, tls_fd, *path);
+                            wrstr(c, tls_fd, ":\r\n\r\n");
 #endif
                         }
                         if (!chdir(*path)) {
-                            listdir(0U, c, *path);
+                            listdir(0U, c, tls_fd, *path);
                             chdir(wd);
                         }
                     }
@@ -931,11 +943,11 @@
         if (opt_d) {
             listfile(NULL, ".");
         } else {
-            listdir(0U, c, ".");
+            listdir(0U, c, tls_fd, ".");
         }
-        outputfiles(c);
+        outputfiles(c, tls_fd);
     }
-    wrstr(c, NULL);
+    wrstr(c, tls_fd, NULL);
     if (on_ctrl_conn == 0) {
 #ifdef WITH_TLS
         closedata();
Index: pure-ftpd-1.0.22/src/tls.c
===================================================================
--- pure-ftpd-1.0.22.orig/src/tls.c	2012-11-28 11:06:28.020855588 +0100
+++ pure-ftpd-1.0.22/src/tls.c	2012-11-28 11:06:28.048856557 +0100
@@ -142,7 +142,7 @@
     if (SSL_set_rfd(tls_cnx, 0) != 1 || SSL_set_wfd(tls_cnx, 1) != 1) {
         tls_error();
     }
-    SSL_set_accept_state(tls_cnx);
+    SSL_set_accept_state(tls_cnx);    
     if (SSL_accept(tls_cnx) <= 0) {
         tls_error();
     }
@@ -186,7 +186,8 @@
     } else {
         SSL_set_connect_state(tls_data_cnx);
     }
-#if 1
+    SSL_set_accept_state(tls_data_cnx);
+#if 0
     for (;;) {
         if ((ret = SSL_accept(tls_data_cnx)) <= 0) {
             ret_ = SSL_get_error(tls_data_cnx, ret);
