Subject: anti-hang patch and more (fwd)

From: Jon Lewis <[email-masked]>
Date: Tue, 18 Nov 1997 23:30:25 -0500 (EST)

I'm forwarding this back to the list since I've had several requests for
the patch recently.  This is against beta14, but will likely apply to 15
without much trouble.

I didn't get much in the way of feedback on this.  All I know is that I've
not seen an ftp session hang during a transfer since making this patch,
and nobody's complained about FTP being broken.

------------------------------------------------------------------
 Jon Lewis <[email-masked]>  |  Unsolicited commercial e-mail will
 Network Administrator       |  be proof-read for $199/message.
 Florida Digital Turnpike    |  
______http://inorganic5.fdt.net/~jlewis/pgp for PGP public key____

---------- Forwarded message ----------
Date: Sun, 24 Aug 1997 03:33:52 -0400 (EDT)
From: Jon Lewis <[email-masked]>
To: [email-masked]
Subject: anti-hang patch and more

This patch includes the anti-hang patch I posted about a few days ago.  It's
a slightly improved version of what I've been using the past month, so its
actually only very lightly tested...the price of progress.  Looking at
strace output of ascii mode transfers was scarey the way I'd originally done
it...an alarm() after every byte, only it was really just lots and lots of
alarm()s due to stdio buffering.  I've been using -z240.

Perhaps all the new alarm() calls should be replaced with if (zap_xfer_time)
alarm()...or zap_xfer_time should default to non-zero...I don't know.  I'm
open to suggestions.

There are also some changes to syslog's that log the result of ident as well
as remote host name.

Also, I think, a real bug fix, as the possible definition of USE_RUN had no
meaning.

diff -ruN wu-ftpd-2.4.2-beta-14/src/authenticate.h wu-ftpd-2.4.2-beta-14-fdt/src/authenticate.h
--- wu-ftpd-2.4.2-beta-14/src/authenticate.h	Fri Apr  1 14:03:39 1994
+++ wu-ftpd-2.4.2-beta-14-fdt/src/authenticate.h	Sat Aug 23 00:48:57 1997
@@ -1,7 +1,7 @@
 /* When of the supported authentication methods the ftp server will attempt
  * to use.  Define as 1 to enable, 0 to disable. */
 
-#define USE_A_RFC931    0               /* Use RFC931-style authentication */
+#define USE_A_RFC931    1               /* Use RFC931-style authentication */
 
 /* Bitmasks used to identify authentication methods that returned a result */
 #define A_RFC931        1 << 0;         /* RFC931 */
diff -ruN wu-ftpd-2.4.2-beta-14/src/config/config.lnx wu-ftpd-2.4.2-beta-14-fdt/src/config/config.lnx
--- wu-ftpd-2.4.2-beta-14/src/config/config.lnx	Mon Aug 11 23:43:30 1997
+++ wu-ftpd-2.4.2-beta-14-fdt/src/config/config.lnx	Mon Aug 18 15:01:35 1997
@@ -27,7 +27,7 @@
 #define OVERWRITE
 #undef  REGEX
 #define SPT_TYPE SPT_REUSEARGV
-#undef  SHADOW_PASSWORD
+#define SHADOW_PASSWORD
 #define UPLOAD
 #undef  USG
 #define SVR4
@@ -35,10 +35,10 @@
 #define HAVE_SYS_VFS
 #define HAVE_SYMLINK
 #define UTMAXTYPE
-#define USE_ETC
+#define USE_ETC_FTPD
 #define USE_LOG
 #define USE_VAR
-#define USE_RUN
+#define USE_VAR_RUN
 #define VIRTUAL
 #define NEED_SIGFIX
 
diff -ruN wu-ftpd-2.4.2-beta-14/src/ftpd.c wu-ftpd-2.4.2-beta-14-fdt/src/ftpd.c
--- wu-ftpd-2.4.2-beta-14/src/ftpd.c	Mon Aug 11 23:43:08 1997
+++ wu-ftpd-2.4.2-beta-14-fdt/src/ftpd.c	Sun Aug 24 03:01:37 1997
@@ -232,7 +232,9 @@
 int timeout = 900;              /* timeout after 15 minutes of inactivity */
 int maxtimeout = 7200;          /* don't allow idle time to be set beyond 2
                                  * hours */
-
+int zap_xfer_time = 0;		/* timeout after which an xfer is aborted
+				   by killing the session */
+				   
 /* previously defaulted to 1, and -l or -L set them to 1, so that there was
    no way to turn them *off*!  Changed so that the manpage reflects common
    sense.  -L is way noisy; -l we'll change to be "just right".  _H*/
@@ -450,7 +452,7 @@
         envp++;
     LastArgv = envp[-1] + strlen(envp[-1]);
 
-    while ((c = getopt(argc, argv, ":aAvdlLiot:T:u:")) != -1) {
+    while ((c = getopt(argc, argv, ":aAvdlLiot:T:u:z:")) != -1) {
         switch (c) {
 
         case 'a':
@@ -509,7 +511,13 @@
                     defumask = val;
                 break;
             }
-
+            
+	case 'z':
+	    {
+	        zap_xfer_time = atoi(optarg);
+	        break;
+	    }
+	    
         case ':':
             syslog(LOG_ERR, "option -%c requires an argument", optopt);
             break;
@@ -1662,16 +1670,16 @@
                     sizeof(": anonymous/")), passwd);
         setproctitle("%s", proctitle);
         if (logging)
-            syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s [%s], %s",
-                   remotehost, remoteaddr, passwd);
+            syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s@%s [%s], %s",
+                   authuser, remotehost, remoteaddr, passwd);
     } else {
         reply(230, "User %s logged in.%s", pw->pw_name, guest ?
               "  Access restrictions apply." : "");
         sprintf(proctitle, "%s: %s", remotehost, pw->pw_name);
         setproctitle(proctitle);
         if (logging)
-            syslog(LOG_INFO, "FTP LOGIN FROM %s [%s], %s",
-                   remotehost, remoteaddr, pw->pw_name);
+            syslog(LOG_INFO, "FTP LOGIN FROM %s@%s [%s], %s",
+                   authuser, remotehost, remoteaddr, pw->pw_name);
 /* H* mod: if non-anonymous user, copy it to "authuser" so everyone can
    see it, since whoever he was @foreign-host is now largely irrelevant. */
 	strcpy (authuser, pw->pw_name);
@@ -2413,8 +2421,10 @@
     switch (type) {
 
     case TYPE_A:
+        alarm(zap_xfer_time);
         while ((c = getc(instr)) != EOF) {
-            byte_count++;
+            if (++byte_count % 4096 == 0)
+            	alarm(zap_xfer_time);
             if (c == '\n') {
                 if (ferror(outstr))
                     goto data_err;
@@ -2422,6 +2432,7 @@
             }
             (void) putc(c, outstr);
         }
+        alarm(0);
         fflush(outstr);
         transflag = 0;
         if (ferror(instr))
@@ -2440,20 +2451,26 @@
         }
         netfd = fileno(outstr);
         filefd = fileno(instr);
+        alarm(zap_xfer_time);
 /* Debian fix: this seems gratuitous somehow, testing ... XXX: */
 #ifdef bogus__linux__
 	while ((cnt = read(filefd, buf, (u_int)blksize)) > 0)
 	{
-	int outcnt=0, newcnt=0;
-	while ((outcnt=write(netfd, buf+newcnt, cnt-newcnt))!= cnt-newcnt)
+	    int outcnt=0, newcnt=0;
+	    alarm(zap_xfer_time);
+	    while ((outcnt=write(netfd, buf+newcnt, cnt-newcnt))!= cnt-newcnt)
 		newcnt+=outcnt;
-	byte_count += cnt;				
+	    byte_count += cnt;				
 	}
 #else
         while ((cnt = read(filefd, buf, (u_int) blksize)) > 0 &&
                write(netfd, buf, cnt) == cnt)
+        {   
+            alarm(zap_xfer_time);
             byte_count += cnt;
+        }
 #endif
+        alarm(0);
         transflag = 0;
         (void) free(buf);
         if (cnt != 0) {
@@ -2471,6 +2488,7 @@
 
   data_err:
     transflag = 0;
+    alarm(0);
     perror_reply(426, "Data connection");
     return;
 
@@ -2507,11 +2525,14 @@
 
     case TYPE_I:
     case TYPE_L:
+        alarm(zap_xfer_time);
         while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0) {
+            alarm(zap_xfer_time);
             if (write(fileno(outstr), buf, cnt) != cnt)
                 goto file_err;
             byte_count += cnt;
         }
+        alarm(0);
         if (cnt < 0)
             goto data_err;
         transflag = 0;
@@ -2523,8 +2544,10 @@
         return (-1);
 
     case TYPE_A:
+        alarm(zap_xfer_time);
         while ((c = getc(instr)) != EOF) {
-            byte_count++;
+            if (++byte_count % 4096 == 0)
+            	alarm(zap_xfer_time);
             if (c == '\n')
                 bare_lfs++;
             while (c == '\r') {
@@ -2539,6 +2562,7 @@
             (void) putc(c, outstr);
           contin2:;
         }
+        alarm(0);
         fflush(outstr);
         if (ferror(instr))
             goto data_err;
@@ -2558,11 +2582,13 @@
 
   data_err:
     transflag = 0;
+    alarm(0);
     perror_reply(426, "Data Connection");
     return (-1);
 
   file_err:
     transflag = 0;
+    alarm(0);
     perror_reply(452, "Error writing file");
     return (-1);
 }
diff -ruN wu-ftpd-2.4.2-beta-14/src/pathnames.h wu-ftpd-2.4.2-beta-14-fdt/src/pathnames.h
--- wu-ftpd-2.4.2-beta-14/src/pathnames.h	Mon Aug 11 04:04:20 1997
+++ wu-ftpd-2.4.2-beta-14-fdt/src/pathnames.h	Mon Aug 18 15:01:38 1997
@@ -56,7 +56,7 @@
 #ifdef USE_PID
 #define _PATH_PIDNAMES  "/var/pid/ftp.pids-%s"
 #else
-#ifdef VAR_RUN
+#ifdef USE_VAR_RUN
 #define _PATH_PIDNAMES  "/var/run/ftp.pids-%s"
 #else
 #define _PATH_PIDNAMES  "/var/adm/ftp.pids-%s"

------------------------------------------------------------------
 Jon Lewis <[email-masked]>  |  Unsolicited commercial e-mail will
 Network Administrator       |  be proof-read for $199/message.
 Florida Digital Turnpike    |  
______http://inorganic5.fdt.net/~jlewis/pgp for PGP public key____