The attached patch (against inetutils 1.3.2-19) enables Cygwin ftpd to
support a restricted range of passive mode ports similar to ProFTPD's
PassivePorts option.  Using this version of Cygwin ftpd, I am able to
tunnel all ftp traffic (i.e., both control and all data connections)
through a ssh tunnel.  This is very useful in situations where sftp is
not an option.

Is the Cygwin inetutils maintainer willing to consider this patch for
inclusion in the standard Cygwin package?

Thanks,
Jason
--- ftpd.c.orig 2002-10-01 15:39:24.000000000 -0400
+++ ftpd.c      2002-10-02 12:06:47.000000000 -0400
@@ -170,6 +170,8 @@ int stru;                   /* avoid C keyword */
 int    mode;
 int    usedefault = 1;         /* for data transfers */
 int    pdata = -1;             /* for passive mode */
+int    pasv_start_port = 0;    /* for passive mode */
+int    pasv_end_port = 0;      /* for passive mode */
 sig_atomic_t transflag;
 off_t  file_size;
 off_t  byte_count;
@@ -325,16 +327,28 @@ main(argc, argv, envp)
        LastArgv = envp[-1] + strlen(envp[-1]);
 #endif /* SETPROCTITLE */
 
-       while ((ch = getopt(argc, argv, "dlt:T:u:v")) != EOF) {
+       while ((ch = getopt(argc, argv, "de:ls:t:T:u:v")) != EOF) {
                switch (ch) {
                case 'd':
                        debug = 1;
                        break;
 
+               case 'e':
+                       pasv_end_port = atoi(optarg);
+                       if (pasv_end_port < 0)
+                               pasv_end_port = 0;
+                       break;
+
                case 'l':
                        logging++;      /* > 1 == extra logging */
                        break;
 
+               case 's':
+                       pasv_start_port = atoi(optarg);
+                       if (pasv_start_port < 0)
+                               pasv_start_port = 0;
+                       break;
+
                case 't':
                        timeout = atoi(optarg);
                        if (maxtimeout < timeout)
@@ -370,6 +384,9 @@ main(argc, argv, envp)
                        break;
                }
        }
+       if (pasv_end_port < pasv_start_port)
+               pasv_end_port = pasv_start_port;
+
        (void) freopen(PATH_DEVNULL, "w", stderr);
        (void) signal(SIGPIPE, lostconn);
        (void) signal(SIGCHLD, SIG_IGN);
@@ -1582,6 +1599,7 @@ void
 passive()
 {
        int len;
+       int pasv_port;
        char *p, *a;
 
        pdata = socket(AF_INET, SOCK_STREAM, 0);
@@ -1589,12 +1607,16 @@ passive()
                perror_reply(425, "Can't open passive connection");
                return;
        }
-       pasv_addr = ctrl_addr;
-       pasv_addr.sin_port = 0;
        (void) seteuid(getuid ());
-       if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) {
-               (void) seteuid((uid_t)pw->pw_uid);
-               goto pasv_error;
+       pasv_addr = ctrl_addr;
+       for (pasv_port = pasv_start_port; pasv_port <= pasv_end_port; pasv_port++) {
+               pasv_addr.sin_port = htons(pasv_port);
+               if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) == 0)
+                       break;
+               if (errno != EADDRINUSE || pasv_port == pasv_end_port) {
+                       (void) seteuid((uid_t)pw->pw_uid);
+                       goto pasv_error;
+               }
        }
        (void) seteuid((uid_t)pw->pw_uid);
        len = sizeof(pasv_addr);

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to