Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: Wed, 02 Oct 2002 12:49:57 -0400 From: Jason Tishler Subject: ftpd passive port range patch To: Cygwin Mail-followup-to: Cygwin Message-id: <20021002164957.GB1596@tishler.net> MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_ueumOkiM8gUyjaAzuOc/Zw)" User-Agent: Mutt/1.4i --Boundary_(ID_ueumOkiM8gUyjaAzuOc/Zw) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline 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 --Boundary_(ID_ueumOkiM8gUyjaAzuOc/Zw) Content-type: text/plain; charset=us-ascii; NAME=ftpd.c.diff Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=ftpd.c.diff --- 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); --Boundary_(ID_ueumOkiM8gUyjaAzuOc/Zw) Content-Type: text/plain; charset=us-ascii -- 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/ --Boundary_(ID_ueumOkiM8gUyjaAzuOc/Zw)--