Subject: ftp-pasv patch and ProFTPD.

From: Berend De Schouwer <[email-masked]>
Date: Wed, 3 Jan 2001 14:31:58 +0200

[To be removed from this list send the message "unsubscribe fwtk-users" in the
BODY of a mail message to [email-masked].]

Hi,

I've tried the ftp-pasv patch for TIS FWTK, and noticed
it failed to connect to some Pro-FTPD servers.  It breaks
when it tries to decode the remote port.

So here goes:
* The patch expects 'Entering Passive Mode (a,b,c,d,x,y)'
* Pro-FTPD sends 'Entering Passive Mode (a,b,c,d,x,y).'
  (notice the full-stop).

I'm playing with a lot of other options, so I can't
give the exact line numbers, but here is an attempt
at a patch:

To fix it, in ftp-gw/ftp-gw.c, replace

        for(i=1;i<tokac;i++) {
                if( tokav[i][0] == '(' ) {
                        x = strlen(tokav[i]);
                        if ( tokav[i][x-1] == ')' ) {
                                tokav[i][x-1] = 0;
                                (tokav[i])++;
                                break;
                         }
                }
        }

with:

        for(i=1;i<tokac;i++) {
                if( tokav[i][0] == '(' ) {
                        x = strlen(tokav[i]);
                        if (x < 2) {
                                syslog(LLEV,
                               "WARNING: response from server too
short.");
                        }
                        if ( (tokav[i][x-1] == ')') ||
                             ( (tokav[i][x-1] == '.') &&
                               (tokav[i][x-2] == ')')
                             )
                           ) {
                                tokav[i][x-1] = 0;
                                (tokav[i])++;
                                break;
                         }
                }
        }

Kind regards,				  
Berend                                  

-- 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Berend De Schouwer, +27-11-712-1435, UCS

---

From: Tor Perkins <[email-masked]>
Date: Tue, 9 Jan 2001 12:48:34 -0800

The problem:

   The original code for parsing an FTP servers PASV response was not
   sufficiently general, so sometimes the port decode would fail and
   the data connection could not happen.

     possible formats include (RFC 959 is ambiguous):

       227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)    <-- most servers
       227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).   <-- some servers
       227 =h1,h2,h3,h4,p1,p2                           <-- sez' D. J. Bernstein

Luis Fernando Barrera pointed this out to me and Berend De Schouwer
has even included a patch for it already.  This is the patch I made.
It tries to handle all of the cases listed above.

-- 
}    __o
}  _(\<._  Tor Perkins           Send me e-mail with subject "get
} (_)/ (_) 979071968@noidDoTnet  pgp key" for automatic response.
--- ./ftp-gw.c.org	Mon May 17 23:00:12 1999
+++ ./ftp-gw.c	Tue Nov 14 23:46:08 2000
@@ -2228,6 +2230,13 @@
  
  	x = getresp(rfd,buf,sizeof(buf),1);
  
+  /*
+   * possible formats include (RFC 959 is ambiguous):
+   *   227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)    <-- most servers
+   *   227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).   <-- some servers
+   *   227 =h1,h2,h3,h4,p1,p2                           <-- sez' D. J. Bernstein
+   */
+
  	if (x != 227)
  		return( ( sayn(0,buf,strlen(buf)) ? 1 : -1 ) );
  
@@ -2237,23 +2246,20 @@
  		return( ( sayn(0,nadr,sizeof(nadr)) ? 1 : -1 ) );
  	}
  
-	for(i=1;i<tokac;i++) {
-		if( tokav[i][0] == '(' ) {
-			x = strlen(tokav[i]);
-			if ( tokav[i][x-1] == ')' ) {
-				tokav[i][x-1] = 0;
-				(tokav[i])++;
-				break;
-			}
-		}
-	}
+  for( i = 1 ; i < tokac ; i++ ) {
+    if( strchr(tokav[i], ',') ) {
+      while ( tokav[i][0] && ( tokav[i][0] < '0' || tokav[i][0] > '9' ) )
+        (tokav[i])++;
+      x = strlen(tokav[i]);
+      while ( x > 10 && ( tokav[i][x-1] < '0' || tokav[i][x-1] > '9' ) ) x--;
+      if ( x > 10 ) {
+        tokav[i][x] = 0;
+        if( porttoaddr(tokav[i],&srvport) == 0 ) break;
+      }
+    }
+  }
  
  	if(i == tokac) {
-		sendsaved(0,500);
-		return( ( sayn(0,nadr,sizeof(nadr)) ? 1 : -1 ) );
-	}
-
-	if(porttoaddr(tokav[i],&srvport)) {
  		sendsaved(0,500);
  		return( ( sayn(0,nadr,sizeof(nadr)) ? 1 : -1 ) );
  	}