diff options
author | pst <pst@FreeBSD.org> | 1995-08-05 19:12:05 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1995-08-05 19:12:05 +0000 |
commit | 0e79ca4d900784f6fb111f73eee3ea92efdc87be (patch) | |
tree | 0bb9b657884348aa946f639d6e015b17af89ad79 /usr.bin | |
parent | f87a14f2ec9b2da3dd881d031cc3eb22beded92e (diff) | |
download | FreeBSD-src-0e79ca4d900784f6fb111f73eee3ea92efdc87be.zip FreeBSD-src-0e79ca4d900784f6fb111f73eee3ea92efdc87be.tar.gz |
Use data ports in the range 40000..44999 by default to enhance FTP usability
in a firewall environment. Original idea by Mark Tracy (?).
Reviewed by: wollman
Submitted by: pst
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ftp/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/ftp/cmds.c | 12 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 2 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 1 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 15 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 55 | ||||
-rw-r--r-- | usr.bin/ftp/ftp_var.h | 1 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 7 |
8 files changed, 84 insertions, 10 deletions
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile index dc8197f..e9d0a62 100644 --- a/usr.bin/ftp/Makefile +++ b/usr.bin/ftp/Makefile @@ -4,5 +4,6 @@ PROG= ftp SRCS= cmds.c cmdtab.c ftp.c main.c ruserpass.c domacro.c LINKS= ${BINDIR}/ftp ${BINDIR}/pftp MLINKS= ftp.1 pftp.1 +CFLAGS+=-DFTP_DATA_BOTTOM=40000 -DFTP_DATA_TOP=44999 .include <bsd.prog.mk> diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c index 34cca4c..9756042 100644 --- a/usr.bin/ftp/cmds.c +++ b/usr.bin/ftp/cmds.c @@ -2144,6 +2144,18 @@ setpassive() } /* + * Restrict FTP data port range to a high group of "safe" ports + */ +void +setrestrict() +{ + restricted_data_ports = !restricted_data_ports; + printf("Data port range restrictions %s.\n", + onoff(restricted_data_ports)); + code = restricted_data_ports; +} + +/* * get size of file on remote machine */ /*VARARGS*/ diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c index a55cd86..fd9afb2 100644 --- a/usr.bin/ftp/cmdtab.c +++ b/usr.bin/ftp/cmdtab.c @@ -90,6 +90,7 @@ char regethelp[] = "get file restarting at end of local file"; char remotehelp[] = "get help from remote server"; char renamehelp[] = "rename file"; char restarthelp[]= "restart file transfer at bytecount"; +char restricthelp[]= "toggle restriction of data port range"; char rmdirhelp[] = "remove directory on the remote machine"; char rmtstatushelp[]="show status of remote machine"; char runiquehelp[] = "toggle store unique for local files"; @@ -166,6 +167,7 @@ struct cmd cmdtab[] = { { "rename", renamehelp, 0, 1, 1, renamefile }, { "reset", resethelp, 0, 1, 1, reset }, { "restart", restarthelp, 1, 1, 1, restart }, + { "restrict", restricthelp, 0, 0, 0, setrestrict }, { "rmdir", rmdirhelp, 0, 1, 1, removedir }, { "runique", runiquehelp, 0, 0, 1, setrunique }, { "send", sendhelp, 1, 1, 1, put }, diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h index 30ba06b..fb9aecf 100644 --- a/usr.bin/ftp/extern.h +++ b/usr.bin/ftp/extern.h @@ -124,6 +124,7 @@ void setpassive __P(()); void setpeer __P((int, char **)); void setport __P((int, char **)); void setprompt __P((int, char **)); +void setrestrict __P(()); void setrunique __P((int, char **)); void setstruct __P((int, char **)); void setsunique __P((int, char **)); diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1 index 4790407..4a3df6a 100644 --- a/usr.bin/ftp/ftp.1 +++ b/usr.bin/ftp/ftp.1 @@ -45,6 +45,7 @@ file transfer program .Op Fl d .Op Fl i .Op Fl n +.Op Fl U .Op Fl p .Op Fl g .Op Ar host @@ -86,6 +87,8 @@ multiple file transfers. Enables debugging. .It Fl g Disables file name globbing. +.It Fl U +Disable data port range restrictions. .It Fl p Enable passive mode operation for use behind connection filtering firewalls. .El @@ -733,6 +736,18 @@ On .Ux systems, marker is usually a byte offset into the file. +.It Ic restrict +Toggle data port range restrictions. +When not operating in passive mode, the +.Nm ftp , +client program requests that the remote server open a connection back +to the client host on a separate data port. In previous versions, that +remote port fell in the range 1024..4999. However, most firewall setups +filter that range of TCP ports because other services reside there. +The default behavior now is for the client to request that the server +connect back to the client using the port range 40000..44999. Firewall +administrators can chose to allow TCP connections in that range, if they +deem it to not be a security risk. .It Ic rmdir Ar directory-name Delete a directory on the remote machine. .It Ic runique diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c index 10327c5..137e8c2 100644 --- a/usr.bin/ftp/ftp.c +++ b/usr.bin/ftp/ftp.c @@ -1000,7 +1000,9 @@ initconn() char *p, *a; int result, len, tmpno = 0; int on = 1; + int count; u_long a1,a2,a3,a4,p1,p2; + static u_short last_port = FTP_DATA_BOTTOM; if (passivemode) { data = socket(AF_INET, SOCK_STREAM, 0); @@ -1051,9 +1053,6 @@ initconn() } noport: - data_addr = myctladdr; - if (sendport) - data_addr.sin_port = 0; /* let system pick one */ if (data != -1) (void) close(data); data = socket(AF_INET, SOCK_STREAM, 0); @@ -1063,15 +1062,53 @@ noport: sendport = 1; return (1); } - if (!sendport) - if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { + data_addr = myctladdr; + if (sendport) { + if (restricted_data_ports) { + for (count = 0; + count < FTP_DATA_TOP-FTP_DATA_BOTTOM; count++) { + last_port++; + if (last_port < FTP_DATA_BOTTOM || + last_port > FTP_DATA_TOP) + last_port = FTP_DATA_BOTTOM; + + data_addr.sin_port = htons(last_port); + if (bind(data, (struct sockaddr *)&data_addr, + sizeof(data_addr)) < 0) { + if (errno == EADDRINUSE) + continue; + else { + warn("bind"); + goto bad; + } + } + break; + } + if (count >= FTP_DATA_TOP-FTP_DATA_BOTTOM) { + perror("ftp: all data ports in use"); + goto bad; + } + } else { + data_addr.sin_port = 0; /* use any port */ + if (bind(data, (struct sockaddr *)&data_addr, + sizeof(data_addr)) < 0) { + warn("bind"); + goto bad; + } + } + } else { + if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof (on)) < 0) { warn("setsockopt (reuse address)"); goto bad; } - if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { - warn("bind"); - goto bad; - } + if (bind(data, (struct sockaddr *)&data_addr, + sizeof (data_addr)) < 0) { + warn("bind"); + goto bad; + } + } + if (options & SO_DEBUG && setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) warn("setsockopt (ignored)"); diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h index 5778f69..85895a8 100644 --- a/usr.bin/ftp/ftp_var.h +++ b/usr.bin/ftp/ftp_var.h @@ -67,6 +67,7 @@ int code; /* return/reply code for ftp command */ int crflag; /* if 1, strip car. rets. on ascii gets */ char pasv[64]; /* passive port for proxy data connection */ int passivemode; /* passive mode enabled */ +int restricted_data_ports; /* restrict data port range */ char *altarg; /* argv[1] with no shell-like preprocessing */ char ntin[17]; /* input translation table */ char ntout[17]; /* output translation table */ diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c index 7df165c..cca7a919 100644 --- a/usr.bin/ftp/main.c +++ b/usr.bin/ftp/main.c @@ -82,13 +82,14 @@ main(argc, argv) interactive = 1; autologin = 1; passivemode = 0; + restricted_data_ports = 1; cp = strrchr(argv[0], '/'); cp = (cp == NULL) ? argv[0] : cp+1; if (strcmp(cp, "pftp") == 0) passivemode = 1; - while ((ch = getopt(argc, argv, "dginptv")) != EOF) { + while ((ch = getopt(argc, argv, "dginptvU")) != EOF) { switch (ch) { case 'd': options |= SO_DEBUG; @@ -119,6 +120,10 @@ main(argc, argv) verbose++; break; + case 'U': + restricted_data_ports = 0; + break; + default: (void)fprintf(stderr, "usage: ftp [-dginptv] [host [port]]\n"); |