Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Jul 2002 04:30:04 -0700 (PDT)
From:      Maxim Konovalov <maxim@macomnet.ru>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/36955: Stock ftpd does not reuse ports in passive mode and fails
Message-ID:  <200207221130.g6MBU4sX083926@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/36955; it has been noted by GNATS.

From: Maxim Konovalov <maxim@macomnet.ru>
To: Yar Tikhiy <yar@freebsd.org>
Cc: bug-followup@freebsd.org,
	Eugene Grosbein <eugen@svzserv.kemerovo.su>
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode and
 fails
Date: Mon, 22 Jul 2002 15:22:28 +0400 (MSD)

 Hi Yar,
 
 On 16:59+0400, Jul 21, 2002, Yar Tikhiy wrote:
 
 > Setting SO_REUSEADDR on a listening socket is always a good idea.
 > Plese refer to the following URL for a detailed explanation:
 > http://www.kohala.com/start/torek.94dec31.txt
 >
 > BTW, I'd omit casting the "&on" parameter to setsockopt(2) to "char
 > *" since now setsockopt(2) expects "void *" there.  In general, all
 > that pointer casting in our ftpd is a real mess.  As a matter of
 > fact, a pointer (or 0 as the null pointer) needs to be casted to a
 > certain type only when passing it to a function without a prototype.
 > And casting such a pointer to a wrong type is a really bad thing
 > to do.
 
 There is a comment in OpenBSD ftpd I was worrying about:
 
 void
 passive()
 {
 ...
         /*
          * XXX
          * At this point, it would be nice to have an algorithm that
          * inserted a growing delay in an attack scenario.  Such a thing
          * would look like continual passive sockets being opened, but
          * nothing serious being done with them.  They're not used to
          * move data; the entire attempt is just to use tcp FIN_WAIT
          * resources.
          */
         pdata = socket(AF_INET, SOCK_STREAM, 0);
 ...
 
 But AFAIU my patch does not make things worse. Here is a revised one:
 
 Index: ftpd.c
 ===================================================================
 RCS file: /home/ncvs/src/libexec/ftpd/ftpd.c,v
 retrieving revision 1.112
 diff -u -r1.112 ftpd.c
 --- ftpd.c	21 Jul 2002 12:06:56 -0000	1.112
 +++ ftpd.c	22 Jul 2002 10:34:23 -0000
 @@ -2470,7 +2470,7 @@
  void
  passive(void)
  {
 -	int len;
 +	int len, on;
  	char *p, *a;
 
  	if (pdata >= 0)		/* close old port if one set */
 @@ -2481,12 +2481,14 @@
  		perror_reply(425, "Can't open passive connection");
  		return;
  	}
 -
 +	on = 1;
 +	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
 +		syslog(LOG_ERR, "passive data connection setsockopt: %m");
  	(void) seteuid((uid_t)0);
 
  #ifdef IP_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET) {
 -	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
  					   : IP_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
 @@ -2496,7 +2498,7 @@
  #endif
  #ifdef IPV6_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET6) {
 -	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
  					   : IPV6_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
 @@ -2550,7 +2552,7 @@
  void
  long_passive(char *cmd, int pf)
  {
 -	int len;
 +	int len, on;
  	char *p, *a;
 
  	if (pdata >= 0)		/* close old port if one set */
 @@ -2588,6 +2590,9 @@
  		perror_reply(425, "Can't open passive connection");
  		return;
  	}
 +	on = 1;
 +	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
 +		syslog(LOG_ERR, "passive data connection setsockopt: %m");
 
  	(void) seteuid((uid_t)0);
 
 @@ -2597,7 +2602,7 @@
 
  #ifdef IP_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET) {
 -	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
  					   : IP_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
 @@ -2607,7 +2612,7 @@
  #endif
  #ifdef IPV6_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET6) {
 -	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
  					   : IPV6_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
 
 %%%
 
 If it looks OK feel free to commit it. Thank you!
 
 P.S. I have already tested it on our production ftp server.
 
 -- 
 Maxim Konovalov, MAcomnet, Internet Dept., system engineer
 phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207221130.g6MBU4sX083926>