From owner-freebsd-bugs@FreeBSD.ORG Wed Aug 16 21:40:14 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 80A3516A4E1 for ; Wed, 16 Aug 2006 21:40:14 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id E42FC43D4C for ; Wed, 16 Aug 2006 21:40:12 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k7GLeCwa017389 for ; Wed, 16 Aug 2006 21:40:12 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k7GLeCBG017385; Wed, 16 Aug 2006 21:40:12 GMT (envelope-from gnats) Resent-Date: Wed, 16 Aug 2006 21:40:12 GMT Resent-Message-Id: <200608162140.k7GLeCBG017385@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Aaron Gifford Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3579C16A4DD for ; Wed, 16 Aug 2006 21:33:14 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id EB7EB43D49 for ; Wed, 16 Aug 2006 21:33:13 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k7GLXDNl081596 for ; Wed, 16 Aug 2006 21:33:13 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id k7GLXDlS081594; Wed, 16 Aug 2006 21:33:13 GMT (envelope-from nobody) Message-Id: <200608162133.k7GLXDlS081594@www.freebsd.org> Date: Wed, 16 Aug 2006 21:33:13 GMT From: Aaron Gifford To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Cc: Subject: misc/102162: New Feature (Patch Included): Limit port range for tftpd X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Aug 2006 21:40:14 -0000 >Number: 102162 >Category: misc >Synopsis: New Feature (Patch Included): Limit port range for tftpd >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Wed Aug 16 21:40:12 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Aaron Gifford >Release: 6.1-RELEASE >Organization: >Environment: Not applicable >Description: NEW FEATURE FOR tftpd: This patch the TFTP daemon adds a new command line option -p that permits the user to specify what port or port range the tftpd daemon will bind to during transfers. This is useful in cases where one must limit tftpd (perhaps for firewall reasons) to a small subset of ports. The patch applies cleanly to 5.x as well as 6.x up to 6.1-STABLE as of 16 Aug. 2006. While this has been tested on IPv4 networks, it has not been tested on IPv6. The code is so simple, however, that severe bugs under IPv6 are unlikely (but it would be nice for someone with an IPv6 net to give it a good walloping test). -Aaron out. (The patch is included in the "Fix to the problem" section.) >How-To-Repeat: >Fix: PATCH FOLLOWS: --- /usr/src/libexec/tftpd/tftpd.c.orig Tue May 31 11:22:53 2005 +++ /usr/src/libexec/tftpd/tftpd.c Fri May 12 07:28:28 2006 @@ -130,11 +130,13 @@ char *chroot_dir = NULL; struct passwd *nobody; const char *chuser = "nobody"; + char *pp; + u_short startport = 0, endport = 0; tzset(); /* syslog in localtime */ openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP); - while ((ch = getopt(argc, argv, "cClns:u:U:w")) != -1) { + while ((ch = getopt(argc, argv, "cClnp:s:u:U:w")) != -1) { switch (ch) { case 'c': ipchroot = 1; @@ -148,6 +150,17 @@ case 'n': suppress_naks = 1; break; + case 'p': + pp = strchr(optarg, (int)'-'); + if (pp == NULL) { + startport = atoi(optarg); + endport = startport; + } else { + *pp++ = (char)0; + startport = atoi(optarg); + endport = atoi(pp); + } + break; case 's': chroot_dir = optarg; break; @@ -289,19 +302,7 @@ } len = sizeof(me); - if (getsockname(0, (struct sockaddr *)&me, &len) == 0) { - switch (me.ss_family) { - case AF_INET: - ((struct sockaddr_in *)&me)->sin_port = 0; - break; - case AF_INET6: - ((struct sockaddr_in6 *)&me)->sin6_port = 0; - break; - default: - /* unsupported */ - break; - } - } else { + if (getsockname(0, (struct sockaddr *)&me, &len) != 0) { memset(&me, 0, sizeof(me)); me.ss_family = from.ss_family; me.ss_len = from.ss_len; @@ -314,9 +315,27 @@ syslog(LOG_ERR, "socket: %m"); exit(1); } - if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) { - syslog(LOG_ERR, "bind: %m"); - exit(1); + while (1) { + switch (me.ss_family) { + case AF_INET: + ((struct sockaddr_in *)&me)->sin_port = htons(startport); + break; + case AF_INET6: + ((struct sockaddr_in6 *)&me)->sin6_port = htons(startport); + break; + default: + /* unsupported */ + break; + } + if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) { + if (errno == EADDRINUSE && startport < endport) { + startport++; + continue; + } + syslog(LOG_ERR, "bind: %m"); + exit(1); + } + break; } if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) { syslog(LOG_ERR, "connect: %m"); --- /usr/src/libexec/tftpd/tftpd.8.orig Wed Jul 7 13:57:14 2004 +++ /usr/src/libexec/tftpd/tftpd.8 Wed May 10 16:36:10 2006 @@ -147,6 +147,21 @@ .It Fl n Suppress negative acknowledgement of requests for nonexistent relative filenames. +.It Fl p Ar port-range +Force +.Nm +to bind to a local udp port within the specified +.Pa port-range . +.Nm +This is useful when the server is behind a firewall because it +limits the size of hole that must be opened in the firewall for +to function. You can specify either a single port number, or +a port range (two numbers separated by the '-' dash character). +If you only use a single port, your tftp server will only be +able to handle a single tftp session at a time. If you use +this option, it is recommended that you choose a large enough +range to support as many concurrent tftp sessions as you +ever expect to encounter. .It Fl s Ar directory Cause .Nm >Release-Note: >Audit-Trail: >Unformatted: