Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Mar 2001 21:15:44 +0200
From:      Peter Pentchev <roam@orbitel.bg>
To:        freebsd-arch@FreeBSD.org
Subject:   [PATCH] add a SITE MD5 command to ftpd
Message-ID:  <20010313211544.B17733@ringworld.oblivion.bg>

next in thread | raw e-mail | index | archive | help
Hi,

A recent thread about Bill Fenner's distfiles-checking scripts
set me thinking about easy detection of MD5 checksum mismatches.
Bill Fenner pointed out that these checks are not done because
of the sheer volume of the network traffic needed to download
all the distfiles from all the distsites.

I know that adding a ``SITE MD5 filename'' command to our ftpd
is a *very* little step in a possibly wrong direction (this will
not automagically make all the ftp daemons on all the distsites
implement this command), but IMHO, it's a start..  I'm thinking
of adding similar functionality to wu-ftpd and ProFTPd soon, and
submitting patches to the authors, in the hope of starting a ball
rolling :)

G'luck,
Peter

-- 
because I didn't think of a good beginning of it.

Index: src/libexec/ftpd/ftpcmd.y
===================================================================
RCS file: /home/ncvs/src/libexec/ftpd/ftpcmd.y,v
retrieving revision 1.21
diff -u -r1.21 ftpcmd.y
--- src/libexec/ftpd/ftpcmd.y	2001/02/19 21:51:26	1.21
+++ src/libexec/ftpd/ftpcmd.y	2001/03/13 18:48:54
@@ -58,6 +58,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <glob.h>
+#include <md5.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <setjmp.h>
@@ -92,6 +93,7 @@
 extern  char tmpline[];
 extern	int readonly;
 extern	int noepsv;
+extern	int nomd5;
 
 off_t	restart_point;
 
@@ -126,7 +128,7 @@
 	CDUP	STOU	SMNT	SYST	SIZE	MDTM
 	LPRT	LPSV	EPRT	EPSV
 
-	UMASK	IDLE	CHMOD
+	UMASK	IDLE	CHMOD	MD5
 
 	LEXERR
 
@@ -648,6 +650,34 @@
 				}
 			}
 		}
+	| SITE SP check_login MD5 SP pathname CRLF
+		{
+			if ($3) {
+				struct stat stbuf;
+				char hash[33];
+
+				if (nomd5)
+					reply(500,
+					    "SITE MD5 command disabled",
+					    $6);
+				else if (stat($6, &stbuf) < 0)
+			    		reply(550,
+					    "%s: %s",
+					    $6, strerror(errno));
+				else if (!S_ISREG(stbuf.st_mode))
+					reply(550,
+					    "%s: not a plain file",
+					    $6);
+				else if (MD5File($6, hash) == NULL)
+					reply(550,
+					    "%s: %s",
+					    $6, strerror(errno));
+				else
+					reply(200,
+					    "MD5 %s %s",
+					    hash, $6);
+			}
+		}
 	| STOU check_login_ro SP pathname CRLF
 		{
 			if ($2 && $4 != NULL)
@@ -1088,6 +1118,7 @@
 	{ "IDLE", IDLE, ARGS, 1,	"[ <sp> maximum-idle-time ]" },
 	{ "CHMOD", CHMOD, NSTR, 1,	"<sp> mode <sp> file-name" },
 	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
+	{ "MD5", MD5, STR1, 1,		"<sp> file-name" },
 	{ NULL,   0,    0,    0,	0 }
 };
 
Index: src/libexec/ftpd/ftpd.8
===================================================================
RCS file: /home/ncvs/src/libexec/ftpd/ftpd.8,v
retrieving revision 1.36
diff -u -r1.36 ftpd.8
--- src/libexec/ftpd/ftpd.8	2000/12/18 08:33:25	1.36
+++ src/libexec/ftpd/ftpd.8	2001/03/13 18:48:54
@@ -42,6 +42,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl 4
+.Op Fl 5
 .Op Fl 6
 .Op Fl d
 .Op Fl l Op Fl l
@@ -153,6 +154,10 @@
 When
 .Fl 6
 is not specified, accept IPv4 connection via AF_INET socket.
+.It Fl 5
+Disable the SITE MD5 command.
+This is useful for preventing possible denial of service attacks,
+especially on servers allowing anonymous ftp access.
 .It Fl A
 Allow only anonymous ftp access.
 .It Fl r
Index: src/libexec/ftpd/ftpd.c
===================================================================
RCS file: /home/ncvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.73
diff -u -r1.73 ftpd.c
--- src/libexec/ftpd/ftpd.c	2001/03/11 13:20:44	1.73
+++ src/libexec/ftpd/ftpd.c	2001/03/13 18:48:56
@@ -150,6 +150,7 @@
 int	pdata = -1;		/* for passive mode */
 int	readonly=0;		/* Server is in readonly mode.	*/
 int	noepsv=0;		/* EPSV command is disabled.	*/
+int	nomd5=0;		/* SITE MD5 command is disabled.	*/
 sig_atomic_t transflag;
 off_t	file_size;
 off_t	byte_count;
@@ -292,7 +293,7 @@
 #endif /* OLD_SETPROCTITLE */
 
 
-	while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:va:p:46")) != -1) {
+	while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:va:p:456")) != -1) {
 		switch (ch) {
 		case 'D':
 			daemon_mode++;
@@ -369,6 +370,10 @@
 			enable_v4 = 1;
 			if (family == AF_UNSPEC)
 				family = AF_INET;
+			break;
+
+		case '5':
+			nomd5 = 1;
 			break;
 
 		case '6':

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




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