summaryrefslogtreecommitdiffstats
path: root/usr.bin/ftp
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1995-08-05 19:12:05 +0000
committerpst <pst@FreeBSD.org>1995-08-05 19:12:05 +0000
commit0e79ca4d900784f6fb111f73eee3ea92efdc87be (patch)
tree0bb9b657884348aa946f639d6e015b17af89ad79 /usr.bin/ftp
parentf87a14f2ec9b2da3dd881d031cc3eb22beded92e (diff)
downloadFreeBSD-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/ftp')
-rw-r--r--usr.bin/ftp/Makefile1
-rw-r--r--usr.bin/ftp/cmds.c12
-rw-r--r--usr.bin/ftp/cmdtab.c2
-rw-r--r--usr.bin/ftp/extern.h1
-rw-r--r--usr.bin/ftp/ftp.115
-rw-r--r--usr.bin/ftp/ftp.c55
-rw-r--r--usr.bin/ftp/ftp_var.h1
-rw-r--r--usr.bin/ftp/main.c7
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");
OpenPOWER on IntegriCloud