Follows an SSL enabling diff to wu-ftpd-2.5.0 from WU-FTPD
Development Group.  The original package can be retreived
from ftp://ftp.wu-ftpd.org/pub/wu-ftpd/ The changes are mostly
just a copy of Tim Hudson's changes for BSD ftpd.  Note that
here is only ftpd server, you still need Tim's ftp client (see
ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/).  I made this patches because
wu-ftpd has many nice features missing in BSD ftpd, namely per-directory
permissions, guest users with personal `homes' and virtual servers.
Mehul Patel <mehul.patel@harbinger.com> fixed a bug with PASV mode and
added a `class' to allow ssl-only clients, like this:

class local1 realssl 207.16.69.68
 
Patches for more recent versions of wu-ftpd, if any, are on
ftp://ftp.average.org/pub/wuftp+SSL/.  OpenSSL library can be taken
from ftp.openssl.org.

Note that you will need to change makefile sutable for your platform by
hand, adding appropriate include directory and SSL libs, like this:

== src/makefiles/Makefile.xxx ==
IFLAGS   = ... -I/usr/local/ssl/include ...
LFLAGS   = ... -L/usr/local/ssl/lib ...
CFLAGS   = ... -DUSE_SSL ...
LIBES    = ... -lssl -lcrypto ...
================================
 
You can do whatever you like with these patches except pretend that you
wrote them.

Eugene Crosser <crosser@average.org> 04 Sep 1999.

=================
diff -urN ../wu-ftpd-2.5.0/src/access.c src/access.c
--- ../wu-ftpd-2.5.0/src/access.c	Fri May 21 18:44:00 1999
+++ src/access.c	Sat Sep  4 18:43:53 1999
@@ -1,3 +1,17 @@
+/*
+ * The modifications to support SSLeay/OpenSSL done by Eugene Crosser
+ * <crosser@average.org> and Mehul Patel <mehul.patel@harbinger.com>
+ * after BSD ftpd patches by Tim Hudson tjh@mincom.oz.au.
+ * The latter were mostly just pasted in.
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them. 
+ *
+ * Email ssl-users-request@mincom.oz.au to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
 /* Copyright (c) 1993, 1994  Washington University in Saint Louis
  * All rights reserved.
  *
@@ -60,7 +74,10 @@
 #if defined(SVR4) || defined(ISC)
 #include <fcntl.h>
 #endif
-
+#ifdef USE_SSL
+extern int ssl_only_flag;
+extern int ssl_secure_flag;
+#endif
 extern char remotehost[],
   remoteaddr[],
   *remoteident,
@@ -709,6 +726,10 @@
                 log_commands = 1;
             if (!guest && !anonymous && strcasestr(ARG1, "real"))
                 log_commands = 1;
+#ifdef USE_SSL
+            if (!guest && !anonymous && strcasestr(ARG1, "realssl"))
+                log_commands = 1;
+#endif
         }
         if (!strcasecmp(ARG0, "transfers")) {
             set = 0;
@@ -718,6 +739,10 @@
                 set = 1;
             if (strcasestr(ARG1, "real") && !guest && !anonymous)
                 set = 1;
+#ifdef USE_SSL
+            if (strcasestr(ARG1, "realssl") && !guest && !anonymous)
+                set = 1;
+#endif
             if (strcasestr(ARG2, "inbound"))
                 inbound = 1;
             if (strcasestr(ARG2, "outbound"))
@@ -773,7 +798,15 @@
 
             if (guest && strcasestr(ARG1, "guest") && hostmatch(ARG[which],remoteaddr,remotehost))
                 return (1);
-
+#ifdef USE_SSL
+            if (!guest && !anonymous && strcasestr(ARG1, "realssl") &&	
+                hostmatch(ARG[which],remoteaddr,remotehost))
+		{
+		ssl_only_flag=1;
+		ssl_secure_flag=1;
+                return (1);
+		}
+#endif
             if (!guest && !anonymous && strcasestr(ARG1, "real") &&
                 hostmatch(ARG[which],remoteaddr,remotehost))
                 return (1);
diff -urN ../wu-ftpd-2.5.0/src/ftpcmd.y src/ftpcmd.y
--- ../wu-ftpd-2.5.0/src/ftpcmd.y	Fri May 21 18:44:00 1999
+++ src/ftpcmd.y	Sat Sep  4 18:49:05 1999
@@ -1,4 +1,18 @@
 /*
+ * The modifications to support SSLeay/OpenSSL done by Eugene Crosser
+ * <crosser@average.org> and Mehul Patel <mehul.patel@harbinger.com>
+ * after BSD ftpd patches by Tim Hudson tjh@mincom.oz.au.
+ * The latter were mostly just pasted in.
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them. 
+ *
+ * Email ssl-users-request@mincom.oz.au to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
+/*
  * Copyright (c) 1985, 1988 Regents of the University of California.
  * All rights reserved.
  *
@@ -153,6 +167,14 @@
 static int alarm_running = 0;
 #endif
 
+
+#include "ssl_port.h"
+#ifdef USE_SSL
+extern int do_ssl_start();
+extern int ssl_secure_flag;
+extern int ssl_active_flag;
+#endif /* USE_SSL */
+
 static	unsigned short cliport = 0;
 static	struct in_addr cliaddr;
 static  int cmd_type;
@@ -189,8 +211,8 @@
 %}
 
 %token
-    A   B   C   E   F   I
-    L   N   P   R   S   T
+    cA   cB   cC   cE   cF   cI
+    cL   cN   cP   cR   cS   cT
 
     SP  CRLF    COMMA   STRING  NUMBER
 
@@ -201,6 +223,7 @@
     ABOR    DELE    CWD     LIST    NLST    SITE
     STAT    HELP    NOOP    MKD     RMD     PWD
     CDUP    STOU    SMNT    SYST    SIZE    MDTM
+    AUTH
 
     UMASK   IDLE    CHMOD   GROUP   GPASS   NEWER
     MINFO   INDEX   EXEC    ALIAS   CDPATH  GROUPS
@@ -232,18 +255,31 @@
 
 cmd:        USER SP username CRLF
         = {
+#ifdef USE_SSL
+            if (ssl_secure_flag && !ssl_active_flag) {
+                reply(504,"SSL is mandatory.");
+                break;
+            }
+#endif /* USE_SSL */
             user($3);
             if (log_commands) syslog(LOG_INFO, "USER %s", $3);
             free($3);
         }
     |   PASS SP password CRLF
         = {
+#ifdef USE_SSL
+            if (ssl_secure_flag && !ssl_active_flag) {
+                reply(504,"SSL is mandatory.");
+                break;
+            }
+#endif /* USE_SSL */
             if (log_commands)
                 if (anonymous)
                     syslog(LOG_INFO, "PASS %s", $3);
                 else
                     syslog(LOG_INFO, "PASS password");
 
+syslog(LOG_INFO, "TYPE %s", typenames[cmd_type]);
             pass($3);
             free($3);
         }
@@ -359,9 +395,9 @@
 	if ($2)
             reply(202, "ALLO command ignored.");
         }
-    |   ALLO check_login SP NUMBER SP R SP NUMBER CRLF
+    |   ALLO check_login SP NUMBER SP cR SP NUMBER CRLF
         = {
-            if (log_commands) syslog(LOG_INFO, "ALLO %d R %d", $4, $8);
+            if (log_commands) syslog(LOG_INFO, "ALLO %d cR %d", $4, $8);
 	if ($2)
             reply(202, "ALLO command ignored.");
         }
@@ -818,6 +854,21 @@
             if ($4 != NULL)
                 free($4);
         }
+    |   AUTH SP STRING CRLF
+        = {
+#ifdef USE_SSL
+            if (!strncmp((char *) $3,"SSL",3)) {
+                reply(334, "AUTH SSL OK.");
+                do_ssl_start();
+            } else {
+                reply(504,"AUTH type not supported.");
+            }
+#else /* !USE_SSL */
+            reply(500,"AUTH not supported.");
+#endif /* USE_SSL */
+            if ($3 != NULL)
+                free((char *)$3);
+        }
     |   QUIT CRLF
         = {
             if (log_commands) syslog(LOG_INFO, "QUIT");
@@ -947,85 +998,85 @@
 	}
     ;
 
-form_code:  N
+form_code:  cN
     = {
         $$ = FORM_N;
     }
-    |   T
+    |   cT
     = {
         $$ = FORM_T;
     }
-    |   C
+    |   cC
     = {
         $$ = FORM_C;
     }
     ;
 
-type_code:  A
+type_code:  cA
     = {
         cmd_type = TYPE_A;
         cmd_form = FORM_N;
     }
-    |   A SP form_code
+    |   cA SP form_code
     = {
         cmd_type = TYPE_A;
         cmd_form = $3;
     }
-    |   E
+    |   cE
     = {
         cmd_type = TYPE_E;
         cmd_form = FORM_N;
     }
-    |   E SP form_code
+    |   cE SP form_code
     = {
         cmd_type = TYPE_E;
         cmd_form = $3;
     }
-    |   I
+    |   cI
     = {
         cmd_type = TYPE_I;
     }
-    |   L
+    |   cL
     = {
         cmd_type = TYPE_L;
         cmd_bytesz = NBBY;
     }
-    |   L SP byte_size
+    |   cL SP byte_size
     = {
         cmd_type = TYPE_L;
         cmd_bytesz = $3;
     }
     /* this is for a bug in the BBN ftp */
-    |   L byte_size
+    |   cL byte_size
     = {
         cmd_type = TYPE_L;
         cmd_bytesz = $2;
     }
     ;
 
-struct_code:    F
+struct_code:    cF
     = {
         $$ = STRU_F;
     }
-    |   R
+    |   cR
     = {
         $$ = STRU_R;
     }
-    |   P
+    |   cP
     = {
         $$ = STRU_P;
     }
     ;
 
-mode_code:  S
+mode_code:  cS
     = {
         $$ = MODE_S;
     }
-    |   B
+    |   cB
     = {
         $$ = MODE_B;
     }
-    |   C
+    |   cC
     = {
         $$ = MODE_C;
     }
@@ -1213,6 +1264,7 @@
     { "STOU", STOU, STR1, 1,    "<sp> file-name" },
     { "SIZE", SIZE, OSTR, 1,    "<sp> path-name" },
     { "MDTM", MDTM, OSTR, 1,    "<sp> path-name" },
+    { "AUTH", AUTH, STR1, 1,    "<sp> auth-type" },
     { NULL,   0,    0,    0,    0 }
 };
 
@@ -1261,7 +1313,8 @@
     register int c;
     register char *cs;
     char *passtxt = "PASS password\r\n";
-
+	char buf[16];
+	
     cs = s;
 /* tmpline may contain saved command from urgent mode interruption */
     for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
@@ -1281,14 +1334,14 @@
             tmpline[0] = '\0';
     }
 retry:
-    while ((c = getc(iop)) != EOF) {
+    while ((c = GETC(iop)) != EOF) {
 #ifdef TRANSFER_COUNT
         byte_count_total++;
         byte_count_in++;
 #endif
         c &= 0377;
         if (c == IAC) {
-            if ((c = getc(iop)) != EOF) {
+            if ((c = GETC(iop)) != EOF) {
 #ifdef TRANSFER_COUNT
             byte_count_total++;
             byte_count_in++;
@@ -1297,23 +1350,35 @@
             switch (c) {
             case WILL:
             case WONT:
-                c = getc(iop);
+                c = GETC(iop);
+
 #ifdef TRANSFER_COUNT
                 byte_count_total++;
                 byte_count_in++;
 #endif
                 printf("%c%c%c", IAC, DONT, 0377&c);
-                (void) fflush(stdout);
+#ifdef USE_SSL
+                if (ssl_active_flag)
+                   SSL_write(ssl_con,buf,strlen(buf));
+                else
+#endif /* USE_SSL */
+                    fwrite(buf,strlen(buf),1,stdout);
+                 (void) FFLUSH(stdout);
                 continue;
-            case DO:
+	case DO:
             case DONT:
-                c = getc(iop);
+                c = GETC(iop);
 #ifdef TRANSFER_COUNT
                 byte_count_total++;
                 byte_count_in++;
 #endif
+#ifdef USE_SSL
+				if (ssl_active_flag)
+					SSL_write(ssl_con,buf,strlen(buf));
+				else
+#endif /* USE_SSL */
                 printf("%c%c%c", IAC, WONT, 0377&c);
-                (void) fflush(stdout);
+                (void) FFLUSH(stdout);
                 continue;
             case IAC:
                 break;
@@ -1588,51 +1653,51 @@
 
             case 'A':
             case 'a':
-                return (A);
+                return (cA);
 
             case 'B':
             case 'b':
-                return (B);
+                return (cB);
 
             case 'C':
             case 'c':
-                return (C);
+                return (cC);
 
             case 'E':
             case 'e':
-                return (E);
+                return (cE);
 
             case 'F':
             case 'f':
-                return (F);
+                return (cF);
 
             case 'I':
             case 'i':
-                return (I);
+                return (cI);
 
             case 'L':
             case 'l':
-                return (L);
+                return (cL);
 
             case 'N':
             case 'n':
-                return (N);
+                return (cN);
 
             case 'P':
             case 'p':
-                return (P);
+                return (cP);
 
             case 'R':
             case 'r':
-                return (R);
+                return (cR);
 
             case 'S':
             case 's':
-                return (S);
+                return (cS);
 
             case 'T':
             case 't':
-                return (T);
+                return (cT);
 
             }
             break;
@@ -1797,7 +1862,7 @@
         }
 
         count = 0;
-        while((c=getc(fin)) != EOF) {
+        while((c=GETC(fin)) != EOF) {
             if (c == '\n')  /* will get expanded to \r\n */
                 count++;
             count++;
diff -urN ../wu-ftpd-2.5.0/src/ftpd.c src/ftpd.c
--- ../wu-ftpd-2.5.0/src/ftpd.c	Fri May 21 18:44:01 1999
+++ src/ftpd.c	Sat Sep  4 19:05:17 1999
@@ -1,3 +1,17 @@
+/*
+ * The modifications to support SSLeay/OpenSSL done by Eugene Crosser
+ * <crosser@average.org> and Mehul Patel <mehul.patel@harbinger.com>
+ * after BSD ftpd patches by Tim Hudson tjh@mincom.oz.au.
+ * The latter were mostly just pasted in.
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them. 
+ *
+ * Email ssl-users-request@mincom.oz.au to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
 /* Copyright (c) 1985, 1988, 1990 Regents of the University of California.
  * All rights reserved.
  *
@@ -80,6 +94,55 @@
 #include <errno.h>
 #include <string.h>
 
+#include "ssl_port.h"
+
+#ifdef USE_SSL
+
+BIO *bio_err;
+BIO *bio_log;
+SSL *ssl_data_con=NULL;
+int ssl_auto_login=0;
+
+#include "openssl/rsa.h"        /* extra ... */
+#include "openssl/x509.h"
+#include "openssl/pem.h"
+#include "openssl/ssl.h"
+
+SSL *ssl_con;
+SSL_CTX *ssl_ctx;
+int ssl_debug_flag=1;
+int ssl_only_flag=0;
+int ssl_active_flag=0;
+int ssl_secure_flag=0;
+int ssl_verify_flag=SSL_VERIFY_NONE;
+int ssl_certsok_flag=0;
+
+static char *auth_ssl_name=NULL;
+FILE *cin, *cout;
+
+int ssl_data_active_flag=0;
+
+/* for the moment this is a compile time option only --tjh */
+int ssl_encrypt_data=1;
+
+char ssl_file_path[1024];    /* don't look at that nasty value to the left */
+
+X509 *ssl_public_cert;
+RSA *ssl_private_key;
+
+static char *my_ssl_key_file=NULL;
+static char *my_ssl_cert_file=NULL;
+
+#endif /* USE_SSL */
+
+void
+#ifdef __STDC__
+pass(char *passwd);
+#else
+pass();
+#endif
+
+
 /*
  *  Arrange to use either varargs or stdargs
  *
@@ -593,12 +656,20 @@
     else
     data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
 #endif /* DAEMON */
-
+#ifdef USE_SSL
 #ifndef DAEMON
-    while ((c = getopt(argc, argv, ":aAvdlLioP:qQr:t:T:u:wWX")) != -1) {
+    while ((c = getopt(argc, argv, ":aAvdlLioP:qQr:t:T:u:wWX:z:")) != -1) {
+#else /* DAEMON */
+    while ((c = getopt(argc, argv, ":aAvdlLiop:P:qQr:sSt:T:u:wWXz:")) != -1) {
+#endif /* DAEMON */
+#else /* USE_SSL */
+#ifndef DAEMON
+    while ((c = getopt(argc, argv, ":aAvdlLioP:qQr:t:T:u:wWX:")) != -1) {
 #else /* DAEMON */
     while ((c = getopt(argc, argv, ":aAvdlLiop:P:qQr:sSt:T:u:wWX")) != -1) {
 #endif /* DAEMON */
+#endif /* USE_SSL */
+
         switch (c) {
 
         case 'a':
@@ -712,11 +783,189 @@
             syslog(LOG_ERR, "option -%c requires an argument", optopt);
             break;
 
+#ifdef USE_SSL
+        case 'z':
+            syslog(LOG_WARNING, "SSL ENABLED");
+            if (strcmp(optarg, "debug") == 0 ) {
+                ssl_debug_flag=1;
+            }
+            if (strcmp(optarg, "ssl") == 0 ) {
+                ssl_only_flag=1;
+            }
+            if (strcmp(optarg, "secure") == 0 ) {
+                ssl_secure_flag=1;
+            }
+            if (strcmp(optarg, "certsok") == 0) {
+                ssl_certsok_flag=1;
+            }
+            if (strncmp(optarg, "verify=", strlen("verify=")) == 0 ) {
+                ssl_verify_flag=atoi(optarg+strlen("verify="));
+            }
+            if (strncmp(optarg, "cert=", strlen("cert=")) == 0 ) {
+                 my_ssl_cert_file=optarg+strlen("cert=");
+            }
+            if (strncmp(optarg, "key=", strlen("key=")) == 0 ) {
+                my_ssl_key_file=optarg+strlen("key=");
+            }
+            break;
+#endif /* USE_SSL */
+ 
         default:
             syslog(LOG_ERR, "unknown option -%c ignored", optopt);
             break;
         }
     }
+#ifdef USE_SSL
+        /* make sure we have access to the required certificate
+        * and key files now ... before we perhaps chroot and 
+        * do the other "muck" for anon-ftp style setup ... though
+        * why we want to run SSL for anon I don't know
+        */
+
+        {
+            int i;
+           FILE *fp;
+            char *filename;
+
+            /* if we are not running in debug then any error
+             * stuff from SSL debug *must* not go down
+             * the socket (which 0,1,2 are all pointing to by
+             * default)
+             */
+#ifdef SSLEAY8
+            if (ssl_debug_flag) {
+               (void)freopen("ftpd.err","w",stderr);
+               bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+               bio_log=BIO_new_file("ftpd.log","a");
+            } else {
+               bio_err=BIO_new(BIO_s_null());
+               bio_log=BIO_new(BIO_s_null());
+            }
+            BIO_printf(bio_err,"SSL_ERR started\n");
+            BIO_printf(bio_log,"SSL_LOG started\n");
+#else
+            if (ssl_debug_flag) {
+               (void)freopen("ftpd.err","w",stderr);
+               SSL_ERR=stderr;
+               SSL_LOG=NULL;
+                SSL_debug("ftpd.log");
+               if (SSL_LOG==NULL) {
+                   SSL_LOG=fopen("ftpd.log","w");
+                   if (SSL_LOG==NULL)
+                       SSL_LOG=stderr;
+               }
+               if (SSL_LOG!=NULL) {
+                   fprintf(SSL_LOG,"SSL_LOG started\n");
+                   fflush(SSL_LOG);
+               }
+               if (SSL_ERR!=NULL) {
+                   fprintf(SSL_ERR,"SSL_ERR started\n");
+                   fflush(SSL_ERR);
+               }
+            } else {
+                /* disable all the debug and trace */
+               SSL_LOG=SSL_ERR=NULL; /**/
+            }
+#endif
+
+           SSL_load_error_strings();
+#ifdef SSLEAY8
+           SSLeay_add_ssl_algorithms();
+#endif
+
+#ifdef SSLEAY8
+           ssl_ctx=SSL_CTX_new(SSLv23_server_method());
+#else
+           ssl_ctx=SSL_CTX_new();
+#endif
+
+           /* I really should syslog any of the following
+            * errors but I haven't bothered at this stage
+            * as that can wait
+            */
+#ifdef SSLEAY8
+            if (!SSL_CTX_set_default_verify_paths(ssl_ctx)) {
+               fprintf(stderr,"ftpd: cannot set default path via SSL_CTX_set_default_verify_paths\n");
+#else
+            if (!X509_set_default_verify_paths(ssl_ctx->cert)) {
+               fprintf(stderr,"ftpd: cannot set default path via X509_set_default_verify_paths\n");
+#endif
+               fflush(stderr);
+               sleep(1);
+               exit(1);
+            }
+
+#if 0
+            sprintf(ssl_file_path,"%s/%s",X509_get_default_cert_dir(),
+                        "ftpd.cert");
+#endif
+
+            sprintf(ssl_file_path,"%s/%s",X509_get_default_cert_dir(),
+                        "ftpd.pem");
+
+           filename=my_ssl_cert_file==NULL?ssl_file_path:my_ssl_cert_file;
+           fp=fopen(filename,"r");
+           if (fp==NULL) {
+               fprintf(stderr,"ftpd: cannot open public cert file \"%s\"\n",filename);
+               fflush(stderr);
+               exit(1);
+           }
+
+           ssl_public_cert=X509_new();
+           if (PEM_read_X509(fp,&ssl_public_cert,NULL,NULL)==NULL) {
+               fprintf(stderr,"ftpd: error reading public cert - %s\n",
+                                ERR_error_string(ERR_get_error(),NULL));
+               fflush(stderr);
+               exit(1);
+           }
+           fclose(fp);
+
+#ifdef SSLEAY8
+           BIO_printf(bio_log,"ftpd: got public cert\n");
+#else
+           if (ssl_debug_flag) {
+               fprintf(SSL_LOG,"ftpd: got public cert\n");
+               fflush(SSL_LOG);
+           }
+#endif
+
+#if 0
+            sprintf(ssl_file_path,"%s/private/%s",X509_get_default_cert_area(),
+                        "ftpd.key");
+#endif
+
+            sprintf(ssl_file_path,"%s/%s",X509_get_default_cert_dir(),
+                        "ftpd.pem");
+
+           filename=my_ssl_key_file==NULL?ssl_file_path:my_ssl_key_file;
+           fp=fopen(filename,"r");
+           if (fp==NULL) {
+               fprintf(stderr,"ftpd: cannot open private key file \"%s\"\n",filename);
+               fflush(stderr);
+               exit(1);
+           }
+
+           ssl_private_key=RSA_new();
+           if (PEM_read_RSAPrivateKey(fp,&ssl_private_key,NULL,NULL)==0) {
+               fprintf(stderr,"ftpd: error reading private key - %s\n",
+                       ERR_error_string(ERR_get_error(),NULL));
+               fflush(stderr);
+               exit(1);
+           }
+           fclose(fp);
+
+#ifdef SSLEAY8
+           BIO_printf(bio_log,"ftpd: got private key\n");
+#else
+           if (ssl_debug_flag) {
+               fprintf(SSL_LOG,"ftpd: got private key\n");
+               fflush(SSL_LOG);
+           }
+#endif
+
+        }
+#endif /* USE_SSL */
+ 
     initsetproctitle(argc, argv, envp);
     (void) freopen(_PATH_DEVNULL, "w", stderr);
 
@@ -1879,6 +2128,13 @@
 	if (use_accessfile)		/* see above.  _H*/
             acl_setfunctions();
 
+#ifdef  USE_SSL
+    if (pw && good_ssl_user(name)) {
+	askpasswd = 1;
+	ssl_auto_login = 1;
+	pass("xxx");
+    } else
+#endif /* USE_SSL */
 #ifdef	BSD_AUTH
     if ((cp = start_auth(auth, name, pw)) != NULL) {
 	char *s;
@@ -2336,7 +2592,11 @@
     else
         dolreplies = 1;
 /* ******** REGULAR/GUEST USER PASSWORD PROCESSING ********** */
-    if (!anonymous) {    /* "ftp" is only account allowed no password */
+    if (!anonymous
+#ifdef USE_SSL
+             && !ssl_auto_login
+#endif
+		) {    /* "ftp" is only account allowed no password */
 #ifndef HELP_CRACKERS
     if (DenyLoginAfterPassword) {
         pr_mesg (530, DelayedMessageFile);
@@ -3467,7 +3727,9 @@
             goto done;
         }
     }
+
     dout = dataconn(name, st.st_size, "w");
+
     if (dout == NULL)
         goto done;
 #ifdef BUFFER_SIZE
@@ -3491,6 +3753,13 @@
 #endif
 #endif
 #endif
+#ifdef USE_SSL
+    if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
+        SSL_free(ssl_data_con);
+        ssl_data_active_flag=0;
+        ssl_data_con=NULL;
+    }
+#endif /* USE_SSL */
     (void) fclose(dout);
 
   dolog:
@@ -3522,7 +3791,7 @@
 #ifdef _AIX42
 #define L_FORMAT "lld"
 #else
-#define L_FORMAT "d"
+#define L_FORMAT "ld"
 #endif
 #endif
 
@@ -4052,6 +4321,68 @@
                 dataaddr, name, sizebuf);
 #endif
         }
+
+#ifdef USE_SSL
+		/* time to negotiate SSL on the data connection ...
+		 * do this via SSL_accept (as we are still the server
+		 * even though things are started around the other way)
+		 * 
+		 * note: we really *must* make sure the session stuff
+		 *       is copied correctly as we cannot afford a full
+		 *       SSL negotiation for each data socket!
+		 */
+		/* TODO XXXX fill in the blanks :-)
+		 */
+		ssl_data_active_flag=0;
+		if (ssl_active_flag && ssl_encrypt_data) {
+		    /* do SSL */
+
+		    reply(150, "Opening %s mode SSL data connection for %s%s.",
+			 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+
+		    if (ssl_data_con!=NULL) {
+		      SSL_free(ssl_data_con);
+		      ssl_data_con=NULL;
+		    }
+
+		    ssl_data_con=(SSL *)SSL_new(ssl_ctx);
+
+		    /* copy session details ... */
+		    SSL_copy_session_id(ssl_data_con,ssl_con);
+
+		    /* for 0.5.2 - want to change the timeout value etc ... */
+
+		    SSL_set_fd(ssl_data_con,pdata);
+		    SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL);
+
+		    /* if is "safe" to read ahead */
+		    /* SSL_set_read_ahead(ssl_data_con,1); /**/
+
+		    if (ssl_debug_flag)
+			BIO_printf(bio_err,"===>START SSL_accept on DATA\n");
+
+		    if (SSL_accept(ssl_data_con)<=0) {
+			static char errbuf[1024];
+
+			sprintf(errbuf,"ftpd: SSL_accept DATA error %s\n",
+				    ERR_error_string(ERR_get_error(),NULL));
+			perror_reply(425, errbuf);
+			/* abort time methinks ... */
+			fclose(file);
+			return NULL;
+		    } else {
+
+			if (ssl_debug_flag) {
+			    BIO_printf(bio_err,"[SSL DATA Cipher %s]\n",
+					    SSL_get_cipher(ssl_con));
+			}
+			ssl_data_active_flag=1;
+		    }
+
+		    if (ssl_debug_flag)
+			BIO_printf(bio_err,"===>DONE SSL_accept on DATA\n");
+	
+		} else {
 #ifdef THROUGHPUT
         throughput_calc(name, &bps, &bpsmult);
         if (bps != -1) {
@@ -4061,8 +4392,27 @@
         }
         else
 #endif
+		  {
+		    reply(150, "Opening %s mode data connection for %s%s.",
+			type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+		  }
+		}
+#else /* !USE_SSL */
+#ifdef THROUGHPUT
+        throughput_calc(name, &bps, &bpsmult);
+        if (bps != -1) {
+            lreply(150, "Opening %s mode data connection for %s%s.",
+                   type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+            reply(150, "Restricting network throughput to %d bytes/s.", bps);
+        }
+        else
+#endif
+
+
         reply(150, "Opening %s mode data connection for %s%s.",
               type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+#endif /* USE_SSL */
+
         return (fdopen(pdata, mode));
     }
     if (data >= 0) {
@@ -4086,9 +4436,9 @@
         return (NULL);
     }
     data = fileno(file);
-    while (connect(data, (struct sockaddr *) &data_dest,
-                   sizeof(data_dest)) < 0) {
-        if ((errno == EADDRINUSE || errno == EINTR) && retry < swaitmax) {
+    while (connect(data, (struct sockaddr *)&data_dest,
+		   sizeof (data_dest)) < 0) {
+	if ((errno == EADDRINUSE || errno == EINTR) && retry < swaitmax) {
             sleep((unsigned) swaitint);
             retry += swaitint;
             continue;
@@ -4101,6 +4451,64 @@
     if (TCPwindowsize)
         (void) setsockopt(data, SOL_SOCKET, (*mode == 'w' ? SO_SNDBUF : SO_RCVBUF),
                           (char *) &TCPwindowsize, sizeof(TCPwindowsize));
+ #ifdef USE_SSL
+         /* time to negotiate SSL on the data connection ...
+ 	 * do this via SSL_accept (as we are still the server
+ 	 * even though things are started around the other way)
+ 	 * 
+ 	 * note: we really *must* make sure the session stuff
+ 	 *       is copied correctly as we cannot afford a full
+ 	 *       SSL negotiation for each data socket!
+ 	 */
+ 	/* TODO XXXX fill in the blanks :-)
+ 	 */
+ 	ssl_data_active_flag=0;
+ 	if (ssl_active_flag && ssl_encrypt_data) {
+ 	    /* do SSL */
+ 
+ 	    reply(150, "Opening %s mode SSL data connection for %s%s.",
+ 		 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+ 
+ 	    if (ssl_data_con!=NULL) {
+ 	      SSL_free(ssl_data_con);
+ 	      ssl_data_con=NULL;
+ 	    }
+ 	    ssl_data_con=(SSL *)SSL_new(ssl_ctx);
+ 
+             /* copy session details ... */
+ 	    SSL_copy_session_id(ssl_data_con,ssl_con);
+ 
+ 	    /* for 0.5.2 - want to change the timeout value etc ... */
+ 
+ 	    SSL_set_fd(ssl_data_con,data);
+ 	    SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL);
+ 
+ 	    /* if is "safe" to read ahead */
+             /* SSL_set_read_ahead(ssl_data_con,1); /**/
+ 
+ 	    if (ssl_debug_flag)
+ 		BIO_printf(bio_err,"===>START SSL_accept on DATA\n");
+ 
+ 	    if (SSL_accept(ssl_data_con)<=0) {
+                 static char errbuf[1024];
+ 
+ 	        sprintf(errbuf,"ftpd: SSL_accept DATA error %s\n",
+ 			    ERR_error_string(ERR_get_error(),NULL));
+ 		perror_reply(425, errbuf);
+ 		/* abort time methinks ... */
+ 		fclose(file);
+ 		return NULL;
+ 	    } else {
+ 		if (ssl_debug_flag)
+ 		    BIO_printf(bio_err,"[SSL DATA Cipher %s]\n",
+ 			            SSL_get_cipher(ssl_con));
+ 		ssl_data_active_flag=1;
+ 	    }
+ 
+ 	    if (ssl_debug_flag) 
+ 		BIO_printf(bio_err,"===>DONE SSL_accept on DATA\n");
+ 
+	} else {
 #ifdef THROUGHPUT
     throughput_calc(name, &bps, &bpsmult);
     if (bps != -1) {
@@ -4112,6 +4520,14 @@
 #endif
     reply(150, "Opening %s mode data connection for %s%s.",
           type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+
+ 	}
+ #else /* !USE_SSL */
+ 	reply(150, "Opening %s mode data connection for %s%s.",
+ 	     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+ #endif /* USE_SSL */
+
+
     return (file);
 }
 
@@ -4167,14 +4583,14 @@
     switch (type) {
 
     case TYPE_A:
-        alarm((unsigned)timeout);
+	alarm((unsigned)timeout);
         while ((c = getc(instr)) != EOF) {
             if (++byte_count % 4096 == 0)
                alarm((unsigned)timeout);
             if (c == '\n') {
                 if (ferror(outstr))
                     goto data_err;
-                (void) putc('\r', outstr);
+                (void) DATAPUTC('\r', outstr);
 #ifdef TRANSFER_COUNT
                 if (retrieve_is_data) {
                     data_count_total++;
@@ -4184,7 +4600,7 @@
                 byte_count_out++;
 #endif
             }
-            (void) putc(c, outstr);
+	    (void) DATAPUTC(c, outstr);
 #ifdef TRANSFER_COUNT
             if (retrieve_is_data) {
                 data_count_total++;
@@ -4195,7 +4611,7 @@
 #endif
         }
 	alarm(0);
-        fflush(outstr);
+	DATAFLUSH(outstr);
         transflag = 0;
         if (ferror(instr))
             goto file_err;
@@ -4228,6 +4644,16 @@
         netfd = fileno(outstr);
         filefd = fileno(instr);
 	alarm((unsigned)timeout);
+#ifdef USE_SSL
+	if (ssl_data_active_flag) {
+	    while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
+		SSL_write(ssl_data_con, buf, cnt) == cnt) {
+		    alarm((unsigned)timeout);
+		    byte_count += cnt;
+		}
+	} else
+#endif /* USE_SSL */
+
 #ifdef THROUGHPUT
         if (bps != -1)
             t1 = time(NULL);
@@ -4344,6 +4770,15 @@
         netfd = fileno(instr);
         filefd = fileno(outstr);
 	alarm((unsigned)timeout);
+#ifdef USE_SSL
+	if (ssl_data_active_flag) {
+	    while ((cnt = SSL_read(ssl_data_con,buf,sizeof buf)) > 0 &&
+		   (write(fileno(outstr), buf, cnt) == cnt)) {
+		byte_count += cnt;
+		alarm((unsigned)timeout);
+	    }
+	} else 
+#endif /* !USE_SSL */
         while ((cnt = read(netfd, buf, buffer_size)) > 0 &&
                write(filefd, buf, cnt) == cnt){
             byte_count += cnt;
@@ -4378,7 +4813,7 @@
 
     case TYPE_A:
 	alarm((unsigned)timeout);
-        while ((c = getc(instr)) != EOF) {
+	while ((c = DATAGETC(instr)) != EOF) {
             if (++byte_count % 4096 == 0)
                alarm((unsigned)timeout);
             if (c == '\n')
@@ -4387,8 +4822,8 @@
                 if (ferror(outstr))
                     goto file_err;
 		alarm((unsigned)timeout);
-                if ((c = getc(instr)) != '\n') {
-                    (void) putc('\r', outstr);
+		if ((c = DATAGETC(instr)) != '\n') {
+		    (void) DATAPUTC('\r', outstr);
 #ifdef TRANSFER_COUNT
                     data_count_total++;
                     data_count_in++;
@@ -4401,7 +4836,7 @@
 	               alarm((unsigned)timeout);
                 }
             }
-            (void) putc(c, outstr);
+	    (void) DATAPUTC(c, outstr);
 #ifdef TRANSFER_COUNT
             data_count_total++;
             data_count_in++;
@@ -4411,8 +4846,8 @@
           contin2:;
         }
 	alarm(0);
-        fflush(outstr);
-        if (ferror(instr))
+	DATAFLUSH(outstr);
+	if (ferror(instr))
             goto data_err;
         if (ferror(outstr))
             goto file_err;
@@ -4614,13 +5049,21 @@
    * stuff goes here, you see, and you want to log the cleartext and send
    * the wrapped text to the client.
    */
-
-  printf("%s\r\n", buf); /* and send it to the client */
+#ifdef USE_SSL
+  if (ssl_active_flag) {
+    SSL_write(ssl_con,buf,strlen(buf));
+    SSL_write(ssl_con,"\r\n",2);
+  } else
+  
+#endif
+  { printf("%s\r\n", buf); /* and send it to the client */
+  fflush(stdout);
+  }
 #ifdef TRANSFER_COUNT
   byte_count_total += strlen(buf);
   byte_count_out += strlen(buf);
 #endif
-  fflush(stdout);
+
 }
 
 void
@@ -4633,6 +5076,7 @@
      va_dcl
 #endif
 {
+/* USE_SSL */
   VA_LOCAL_DECL
 
   if (autospout != NULL) { /* deal with the autospout stuff... */
@@ -5750,8 +6194,18 @@
                     goto globfree;
                 transflag++;
             }
+#ifdef USE_SSL
+	    if (ssl_data_active_flag) {
+                SSL_write(ssl_data_con, dirname, strlen(dirname));
+                if (type == TYPE_A)
+                    SSL_write(ssl_data_con, "\r\n", 2);
+                else
+                    SSL_write(ssl_data_con, "\n", 1);
+            } else
+#endif
             fprintf(dout, "%s%s\n", dirname,
                     type == TYPE_A ? "\r" : "");
+
             byte_count += strlen(dirname) + 1;
 #ifdef TRANSFER_COUNT
             byte_count_total += strlen(dirname) + 1;
@@ -5804,13 +6258,33 @@
                     }
                     transflag++;
                 }
-                if (nbuf[0] == '.' && nbuf[1] == '/')
+                if (nbuf[0] == '.' && nbuf[1] == '/') {
+#ifdef USE_SSL
+                    if (ssl_data_active_flag) {
+                        SSL_write(ssl_data_con, &nbuf[2], strlen(&nbuf[2]));
+                        if (type == TYPE_A)
+                            SSL_write(ssl_data_con, "\r\n", 2);
+                        else
+                            SSL_write(ssl_data_con, "\n", 1);
+                    } else
+#endif
                     fprintf(dout, "%s%s\n", &nbuf[2],
                             type == TYPE_A ? "\r" : "");
+		} else {
+#ifdef USE_SSL
+                    if (ssl_data_active_flag) {
+                        SSL_write(ssl_data_con, nbuf, strlen(nbuf));
+                        if (type == TYPE_A)
+                            SSL_write(ssl_data_con, "\r\n", 2);
                 else
+                            SSL_write(ssl_data_con, "\n", 1);
+                    } else
+#endif
                     fprintf(dout, "%s%s\n", nbuf,
                             type == TYPE_A ? "\r" : "");
+                }
                 byte_count += strlen(nbuf) + 1;
+				
 #ifdef TRANSFER_COUNT
                 byte_count_total += strlen(nbuf) + 1;
                 byte_count_out += strlen(nbuf) + 1;
@@ -5841,8 +6315,16 @@
 #endif
 
     transflag = 0;
-    if (dout != NULL)
+    if (dout != NULL) {
+#ifdef USE_SSL
+        if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
+            SSL_free(ssl_data_con);
+            ssl_data_active_flag=0;
+            ssl_data_con=NULL;
+        }
+#endif /* USE_SSL */
         (void) fclose(dout);
+    }
     data = -1;
     pdata = -1;
 globfree:
@@ -6187,6 +6669,258 @@
     return -1;
 }
 #endif /* ULTRIX_AUTH */
+
+#ifdef USE_SSL
+
+static int verify_callback();
+
+do_ssl_start()
+{
+    static char errstr[1024];
+
+#ifdef SSLEAY8
+    BIO_printf(bio_log,"do_ssl_start triggered\n");
+#else
+    if (ssl_debug_flag && (SSL_LOG!=NULL)) {
+       fprintf(SSL_LOG,"do_ssl_start triggered\n");
+       fflush(SSL_LOG);
+    }
+#endif
+ 
+    /* do the SSL stuff now ... before we play with pty's */
+    ssl_con=(SSL *)SSL_new(ssl_ctx);
+
+    /* we are working with stdin (inetd based) by default */
+    SSL_set_fd(ssl_con,0);
+
+    if (SSL_use_RSAPrivateKey(ssl_con,ssl_private_key)==0) {
+        sprintf(errstr,"ftpd: SSL_use_RSAPrivateKey %s",ERR_error_string(ERR_get_error(),NULL));
+       perror_reply(421, errstr);
+       dologout(1);
+    }
+
+    if (SSL_use_certificate(ssl_con,ssl_public_cert)==0) {
+        sprintf(errstr,"ftpd: SSL_use_certificate %s",ERR_error_string(ERR_get_error(),NULL));
+       perror_reply(421, errstr);
+       dologout(1);
+    }
+
+    SSL_set_verify(ssl_con,ssl_verify_flag,
+           ssl_certsok_flag ? verify_callback : NULL);
+
+    if (SSL_accept(ssl_con)<=0) {
+       sprintf(errstr,"ftpd: SSL_accept %s",ERR_error_string(ERR_get_error(),NULL));
+
+       perror_reply(421, errstr);
+       dologout(1);
+
+       SSL_free(ssl_con);
+       ssl_con=NULL;
+
+       /* we will probably want to know this sort of stuff ...
+        * at least for the moment I'd like to keep track of
+        * who is using SSL - later I will probably make this
+        * just a debug option and only log after the user has
+        * actually connected --tjh
+        */
+       if (logging)
+           syslog(LOG_NOTICE, "SSL FAILED WITH %s", remotehost);
+
+    } else {
+       ssl_active_flag=1;
+
+       if (logging)
+            if (auth_ssl_name)
+                syslog(LOG_NOTICE, "SSL SUCCEEDED WITH %s as %s", remotehost,
+                    auth_ssl_name);
+            else
+                syslog(LOG_NOTICE, "SSL SUCCEEDED WITH %s", remotehost);
+    }
+
+    /* ssl_fprintf calls require that this be null to test
+     * for being an ssl stream
+     */
+    if (!ssl_active_flag) {
+       if (ssl_con!=NULL)
+         SSL_free(ssl_con);
+       ssl_con=NULL;
+    }
+
+    return 0;
+
+ }
+
+/* we really shouldn't have code like this! --tjh */
+int 
+ssl_getc(SSL *ssl_con)
+{
+    char onebyte;
+
+    if (SSL_read(ssl_con,&onebyte,1)!=1)
+      return -1;
+    else {
+#ifdef SSLEAY8
+       BIO_printf(bio_log,"ssl_getc: SSL_read %d (%c) ",
+			onebyte & 0xff,isprint(onebyte)?onebyte:'.');
+#else
+       if (ssl_debug_flag && (SSL_LOG!=NULL)) {
+           fprintf(SSL_LOG,"ssl_getc: SSL_read %d (%c) ",onebyte & 0xff,isprint(onebyte)?onebyte:'.');
+           fflush(SSL_LOG);
+       }
+#endif
+       return onebyte & 0xff;
+    }
+}
+
+
+/* got back to this an implemented some rather "simple" buffering */
+static char putc_buf[BUFSIZ];
+static int putc_buf_pos=0;
+
+int ssl_putc_flush(SSL *ssl_con)
+{
+
+    if (putc_buf_pos>0) {
+       if (SSL_write(ssl_con,putc_buf,putc_buf_pos)!=putc_buf_pos) {
+#ifdef SSLEAY8
+           BIO_printf(bio_log,"ssl_putc_flush: WRITE FAILED\n");
+#else
+           if (ssl_debug_flag && (SSL_LOG!=NULL)) {
+               fprintf(SSL_LOG,"ssl_putc_flush: WRITE FAILED\n");
+               fflush(SSL_LOG);
+           }
+#endif
+           putc_buf_pos=0;
+           return -1;
+       }
+    }
+    putc_buf_pos=0;
+    return 0;
+}
+
+int 
+ssl_putc(SSL *ssl_con,int oneint)
+{
+    char onebyte;
+
+    onebyte = oneint & 0xff;
+
+
+    /* make sure there is space */
+    if (putc_buf_pos>=BUFSIZ) 
+       if (ssl_putc_flush(ssl_con)!=0)
+         return EOF;
+    putc_buf[putc_buf_pos++]=onebyte;
+
+    return onebyte;
+}
+
+/* we really shouldn't have code like this! --tjh */
+int 
+old_ssl_putc(SSL *ssl_con,int oneint)
+{
+    char onebyte;
+
+    onebyte = oneint & 0xff;
+
+    if (SSL_write(ssl_con,&onebyte,1)!=1)
+      return -1;
+    else {
+#ifdef SSLEAY8
+       BIO_printf(bio_log,"ssl_putc: SSL_write %d (%c) ",
+                      onebyte & 0xff,isprint(onebyte)?onebyte:'.');
+#else
+       if (ssl_debug_flag && (SSL_LOG!=NULL)) {
+           fprintf(SSL_LOG,"ssl_putc: SSL_write %d (%c) ",onebyte & 0xff,isprint(onebyte)?onebyte:'.');
+           fflush(SSL_LOG);
+       }
+#endif
+       return onebyte & 0xff;
+    }
+}
+
+static int
+verify_callback(ok, xs, xi, depth, error, dummy)
+int ok;
+char *xs, *xi;
+int depth, error;
+{
+    /*
+     * If the verification fails, then don't remember the name.  However,
+     * if we don't require a certificate, then return success which will
+     * still allow us to set up an encrypted session.
+     *
+     */
+    if (!ok) {
+       /* If we can't verify the issuer, then don't accept the name. */
+    if (depth != 0 && auth_ssl_name) {
+               free(auth_ssl_name);
+               auth_ssl_name = 0;
+       }
+       return ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT ? 0 : 1;
+     }
+     if (depth == 0)
+       auth_ssl_name =
+#ifdef SSLEAY8
+           (char *)X509_NAME_oneline(X509_get_subject_name(xs),NULL,0);
+#else
+           (char *)X509_NAME_oneline(X509_get_subject_name(xs));
+#endif
+     return ok;
+}
+
+/* return true if this auth_ssl_name is authorized to use name. */
+int
+good_ssl_user(name)
+char *name;
+{
+   FILE *user_fp;
+   char buf[2048];
+
+   if (!auth_ssl_name)
+      return 0;
+   if (!ssl_certsok_flag)
+      return 0;        /* can't happen */
+   user_fp = fopen("/etc/ssl.users", "r");
+   if (!user_fp)
+      return 0;
+   while (fgets(buf, sizeof buf, user_fp)) {
+      char *cp;
+      char *n;
+
+      /* allow for comments in the file ... always nice
+       * to be able to add a little novel in files and
+       * also disable easily --tjh
+       */
+      if (buf[0]=='#')
+         continue;
+
+      if (cp = strchr(buf, '\n'))
+         *cp = '\0';
+      cp = strchr(buf, ':');
+      if (!cp)
+         continue;
+      *cp++ = '\0';
+      if (strcasecmp(cp, auth_ssl_name) == 0) {
+         n = buf;
+         while (n) {
+             cp = strchr(n, ',');
+             if (cp)
+                 *cp++ = '\0';
+             if (!strcmp(name, n)) {
+                 fclose(user_fp);
+                 return 1;
+             }
+             n = cp;
+         }
+      }
+   }
+   fclose(user_fp);
+   return 0;
+}
+
+#endif /* USE_SSL */
+
 
 #ifdef USE_PAM
 /* This is rather an abuse of PAM, but the FTP protocol doesn't allow much
diff -urN ../wu-ftpd-2.5.0/src/newvers.sh src/newvers.sh
--- ../wu-ftpd-2.5.0/src/newvers.sh	Fri May 21 18:44:01 1999
+++ src/newvers.sh	Fri Jul  9 21:47:10 1999
@@ -21,7 +21,7 @@
 if [ ! -r edit ]; then echo 0 > edit; fi
 touch edit
 awk '	{	edit = $1 + 1; }\
-END	{	printf "char version[] = \"Version wu-2.5.0(%d) ", edit > "vers.c";\
+END	{	printf "char version[] = \"Version wu-2.5.0(%d) + SSL ", edit > "vers.c";\
 #LANG=
 #LC_TIME=
 		printf "%d\n", edit > "edit"; }' < edit
diff -urN ../wu-ftpd-2.5.0/src/ssl_port.h src/ssl_port.h
--- ../wu-ftpd-2.5.0/src/ssl_port.h	Thu Jan  1 03:00:00 1970
+++ src/ssl_port.h	Tue Jul 20 18:32:29 1999
@@ -0,0 +1,68 @@
+/* ssl_port.h    - standard porting things 
+ *
+ * Slightly modified by Eugene Crosser to work with ssleay 0.8
+ *
+ * The modifications to support SSLeay were done by Tim Hudson
+ * tjh@mincom.oz.au
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them. 
+ *
+ * Email ssl-users-request@mincom.oz.au to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
+#ifndef HEADER_SSL_PORT_H
+#define HEADER_SSL_PORT_H
+
+#ifdef USE_SSL
+
+#include "openssl/crypto.h"
+#include "openssl/ssl.h"
+
+#if SSLEAY_VERSION_NUMBER >= 0x0800
+#define SSLEAY8
+#endif
+
+#include <stdio.h>
+#include "openssl/x509.h"
+extern SSL *ssl_con;
+extern int ssl_debug_flag;
+extern int ssl_only_flag;
+extern int ssl_active_flag;
+extern int ssl_verify_flag;
+extern int ssl_secure_flag;
+
+extern char *my_ssl_cert_file;
+extern char *my_ssl_key_file;
+extern int ssl_certsok_flag;
+
+#define is_ssl_fd(X,Y)    ( (SSL_get_fd((X))==0) || \
+                            (SSL_get_fd((X))==1) || \
+			    (SSL_get_fd((X))==(Y)) \
+			  )
+
+#define is_ssl_fp(X,Y)    ( ( (SSL_get_fd((X))==0) && (fileno((Y))==0) ) || \
+                            ( (SSL_get_fd((X))==1) && (fileno((Y))==1) ) || \
+			    (SSL_get_fd((X))==fileno(Y)) \
+			  )
+
+#define GETC(X)           (ssl_active_flag && (((X)==stdin)||((X)==stdin)) ? ssl_getc(ssl_con) : getc((X)) )
+
+#define DATAGETC(X)       (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_getc(ssl_data_con) : getc((X)) )
+#define DATAPUTC(X,Y)     (ssl_data_active_flag && ((fileno(Y)==data)||(fileno(Y)==pdata)) ? ssl_putc(ssl_data_con,(X)) : putc((X),(Y)) )
+#define DATAFLUSH(X)      (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_putc_flush(ssl_data_con) : fflush((X)) )
+#define FFLUSH(X)         (ssl_active_flag && (((X)==stdin)||((X)==stdout)) ? 1 : fflush((X)) )
+
+#else
+
+#define GETC(X)           getc((X))
+#define DATAGETC(X)       getc((X))
+#define DATAPUTC(X,Y)     putc((X),(Y))
+#define DATAFLUSH(X)      fflush((X))
+#define FFLUSH(X)      	  fflush((X))
+
+#endif /* USE_SSL */
+
+#endif /*  HEADER_SSL_PORT_H */
diff -urN ../wu-ftpd-2.5.0/src/sslapp.c src/sslapp.c
--- ../wu-ftpd-2.5.0/src/sslapp.c	Thu Jan  1 03:00:00 1970
+++ src/sslapp.c	Fri Jul 16 22:47:55 1999
@@ -0,0 +1,196 @@
+/* sslapp.c	- ssl application code */
+
+/*
+ * The modifications to support SSLeay were done by Tim Hudson
+ * tjh@cryptsoft.com
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them.
+ *
+ * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
+#ifdef USE_SSL
+
+#include "sslapp.h"
+
+SSL_CTX *ssl_ctx;
+SSL *ssl_con;
+int ssl_debug_flag=0;
+int ssl_only_flag=0;
+int ssl_active_flag=0;
+int ssl_verify_flag=SSL_VERIFY_NONE;
+int ssl_secure_flag=0;
+int ssl_certsok_flag=0;
+int ssl_cert_required=0;
+int ssl_verbose_flag=0;
+int ssl_disabled_flag=0;
+char *ssl_cert_file=NULL;
+char *ssl_key_file=NULL;
+char *ssl_cipher_list=NULL;
+char *ssl_log_file=NULL;
+
+/* fwd decl */
+static void client_info_callback();
+
+int do_ssleay_init(server)
+int server;
+{
+  char *p;
+
+  /* make sure we have somewhere we can log errors to */
+  if (bio_err==NULL) {
+    if ((bio_err=BIO_new(BIO_s_file()))!=NULL) {
+      if (ssl_log_file==NULL)
+	BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
+      else {
+	if (BIO_write_filename(bio_err,ssl_log_file)<=0) {
+	  /* not a lot we can do */
+	}
+      }
+    }
+  }
+
+  /* rather simple things these days ... the old SSL_LOG and SSL_ERR
+   * vars are long gone now SSLeay8 has rolled around and we have 
+   * a clean interface for doing things
+   */
+  if (ssl_debug_flag)
+    BIO_printf(bio_err,"SSL_DEBUG_FLAG on\r\n");
+
+
+  /* init things so we will get meaningful error messages
+   * rather than numbers 
+   */
+  SSL_load_error_strings();
+
+#ifdef SSLEAY8
+  SSLeay_add_ssl_algorithms();
+  ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_method());
+
+  /* we may require a temp 512 bit RSA key because of the
+   * wonderful way export things work ... if so we generate
+   * one now!
+   */
+  if (server) {
+    if (SSL_CTX_need_tmp_RSA(ssl_ctx)) {
+      RSA *rsa;
+
+      if (ssl_debug_flag)
+	  BIO_printf(bio_err,"Generating temp (512 bit) RSA key ...\r\n");
+      rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
+      if (ssl_debug_flag)
+	  BIO_printf(bio_err,"Generation of temp (512 bit) RSA key done\r\n");
+   
+      if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) {
+	BIO_printf(bio_err,"Failed to assign generated temp RSA key!\r\n");
+      }
+      RSA_free(rsa);
+      if (ssl_debug_flag)
+	  BIO_printf(bio_err,"Assigned temp (512 bit) RSA key\r\n");
+    }
+  }
+
+  /* also switch on all the interoperability and bug
+   * workarounds so that we will communicate with people
+   * that cannot read poorly written specs :-)
+   */
+  SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL);
+
+#else /* !SSLEAY8 */
+  ssl_ctx=(SSL_CTX *)SSL_CTX_new();
+#endif /* SSLEAY8 */
+
+  /* the user can set whatever ciphers they want to use */
+  if (ssl_cipher_list==NULL) {
+      p=getenv("SSL_CIPHER");
+      if (p!=NULL)
+        SSL_CTX_set_cipher_list(ssl_ctx,p);
+  } else
+      SSL_CTX_set_cipher_list(ssl_ctx,ssl_cipher_list);
+
+  /* for verbose we use the 0.6.x info callback that I got
+   * eric to finally add into the code :-) --tjh
+   */
+  if (ssl_verbose_flag) {
+      SSL_CTX_set_info_callback(ssl_ctx,client_info_callback);
+  }
+
+  /* Add in any certificates if you want to here ... */
+  if (ssl_cert_file) {
+      if (!SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_file, 
+		      X509_FILETYPE_PEM)) {
+	  BIO_printf(bio_err,"Error loading %s: ",ssl_cert_file);
+	  ERR_print_errors(bio_err);
+	  BIO_printf(bio_err,"\r\n");
+	  return(0);
+      } else {
+	  if (!ssl_key_file)
+	      ssl_key_file = ssl_cert_file;
+	  if (!SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, ssl_key_file,
+		      X509_FILETYPE_PEM)) {
+	      BIO_printf(bio_err,"Error loading %s: ",ssl_key_file);
+	      ERR_print_errors(bio_err);
+	      BIO_printf(bio_err,"\r\n");
+	      return(0);
+	  }
+      }
+  }
+
+  /* make sure we will find certificates in the standard
+   * location ... otherwise we don't look anywhere for
+   * these things which is going to make client certificate
+   * exchange rather useless :-)
+   */
+#ifdef SSLEAY8
+  SSL_CTX_set_default_verify_paths(ssl_ctx);
+#else
+  SSL_set_default_verify_paths(ssl_ctx);
+#endif
+
+  /* now create a connection */
+  ssl_con=(SSL *)SSL_new(ssl_ctx);
+  SSL_set_verify(ssl_con,ssl_verify_flag,NULL);
+
+#if 0
+  SSL_set_verify(ssl_con,ssl_verify_flag,client_verify_callback);
+#endif
+
+  return(1);
+}
+
+
+static void client_info_callback(s,where,ret)
+SSL *s;
+int where;
+int ret;
+{
+  if (where==SSL_CB_CONNECT_LOOP) {
+    BIO_printf(bio_err,"SSL_connect1:%s %s\r\n",
+		    SSL_state_string(s),SSL_state_string_long(s));
+  } else if (where==SSL_CB_CONNECT_EXIT) {
+    if (ret == 0) {
+      BIO_printf(bio_err,"SSL_connect2:failed in %s %s\r\n",
+	      SSL_state_string(s),SSL_state_string_long(s));
+    } else if (ret < 0) {
+      BIO_printf(bio_err,"SSL_connect3:error in %s %s\r\n",
+	      SSL_state_string(s),SSL_state_string_long(s));
+    }
+  }
+}
+
+
+#else /* !USE_SSL */
+
+/* something here to stop warnings if we build without SSL support */
+static int dummy_func()
+{
+  int i;
+
+  i++;
+}
+
+#endif /* USE_SSL */
+
diff -urN ../wu-ftpd-2.5.0/src/sslapp.h src/sslapp.h
--- ../wu-ftpd-2.5.0/src/sslapp.h	Thu Jan  1 03:00:00 1970
+++ src/sslapp.h	Mon Jul 12 17:20:48 1999
@@ -0,0 +1,72 @@
+/* sslapp.h	- ssl application code */
+
+/*
+ * The modifications to support SSLeay were done by Tim Hudson
+ * tjh@cryptsoft.com
+ *
+ * You can do whatever you like with these patches except pretend that
+ * you wrote them.
+ *
+ * Email ssl-users-request@mincom.oz.au to get instructions on how to
+ * join the mailing list that discusses SSLeay and also these patches.
+ *
+ */
+
+#ifdef USE_SSL
+
+#include <stdio.h>
+
+#include "openssl/crypto.h"
+
+#if SSLEAY_VERSION_NUMBER >= 0x0800
+#define SSLEAY8
+#endif
+ 
+#ifdef SSLEAY8
+#define SSL_set_pref_cipher(c,n)        SSL_set_cipher_list(c,n)
+#define ONELINE_NAME(X) X509_NAME_oneline(X,NULL,0)
+#else
+#define ONELINE_NAME(X) X509_NAME_oneline(X)
+#endif
+  
+#ifdef SSLEAY8
+#define OLDPROTO NOPROTO
+#define NOPROTO
+#include "openssl/bio.h"
+#undef NOPROTO
+#define NOPROTO OLDPROTO
+#undef OLDPROTO
+#endif
+#include "openssl/buffer.h"
+
+#include "openssl/x509.h"
+#include "openssl/ssl.h"
+
+extern BIO *bio_err;
+extern SSL *ssl_con;
+extern SSL_CTX *ssl_ctx;
+extern int ssl_debug_flag;
+extern int ssl_only_flag;
+extern int ssl_active_flag;
+extern int ssl_verify_flag;
+extern int ssl_secure_flag;
+extern int ssl_verbose_flag;
+extern int ssl_disabled_flag;
+extern int ssl_cert_required;
+extern int ssl_certsok_flag;
+
+extern char *ssl_log_file; 
+extern char *ssl_cert_file; 
+extern char *ssl_key_file;
+extern char *ssl_cipher_list;
+
+/* we hide all the initialisation code in a separate file now */
+extern int do_ssleay_init();
+
+extern int display_connect_details();
+extern int server_verify_callback();
+extern int client_verify_callback();
+
+#endif /* USE_SSL */
+
+
