Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Nov 2003 02:25:33 +0300 (MSK)
From:      Nick Leuta <skynick@mail.sc.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/59772: ftpd(8)/FreeBSD 5: support for tcp_wrappers in daemon mode
Message-ID:  <20031128232533.BFA9049A29@chuck2.lstu>
Resent-Message-ID: <200311282330.hASNULnd048230@freefall.freebsd.org>

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


>Number:         59772
>Category:       bin
>Synopsis:       ftpd(8)/FreeBSD 5: support for tcp_wrappers in daemon mode
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 28 15:30:20 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Nick Leuta
>Release:        FreeBSD 4.9-RC i386
>Organization:
Lipetsk State Technical University
>Environment:
System: FreeBSD skynick.stu.lipetsk.ru 4.9-RC FreeBSD 4.9-RC #0: Sun Nov 23 19:53:55 MSK 2003 root@skynick.stu.lipetsk.ru:/usr/src/sys/compile/CORSAIR i386
>Description:
If ftpd(8) is started from inetd(8), inetd(8) itself can do access control with
help of libwrap. But if ftpd(8) runs in daemon mode, such possibility is
unavailable.
>How-To-Repeat:
>Fix:
diff -urN ftpd.ORI/Makefile ftpd/Makefile
--- ftpd.ORI/Makefile	Sun Jan 26 22:02:56 2003
+++ ftpd/Makefile	Wed Nov 26 02:04:56 2003
@@ -5,14 +5,14 @@
 MAN=	ftpd.8 ftpchroot.5
 SRCS=	ftpd.c ftpcmd.y logwtmp.c popen.c
 
-CFLAGS+=-DSETPROCTITLE -DLOGIN_CAP -DVIRTUAL_HOSTING
+CFLAGS+=-DSETPROCTITLE -DLOGIN_CAP -DVIRTUAL_HOSTING -DTCPWRAPPERS
 CFLAGS+=-DINET6
 CFLAGS+=-I${.CURDIR}
 YFLAGS=
 WFORMAT=0
 
-DPADD=	${LIBMD} ${LIBCRYPT} ${LIBUTIL}
-LDADD=	-lmd -lcrypt -lutil
+DPADD=	${LIBMD} ${LIBCRYPT} ${LIBUTIL} ${LIBWRAP}
+LDADD=	-lmd -lcrypt -lutil -lwrap
 
 # XXX Kluge! Conversation mechanism needs to be fixed.
 DPADD+=	${LIBOPIE}
diff -urN ftpd.ORI/ftpcmd.y ftpd/ftpcmd.y
--- ftpd.ORI/ftpcmd.y	Sun Oct 26 07:30:05 2003
+++ ftpd/ftpcmd.y	Wed Nov 26 02:07:25 2003
@@ -80,7 +80,7 @@
 extern	struct passwd *pw;
 extern	int guest;
 extern	char *homedir;
-extern 	int paranoid;
+extern 	int ftpdparanoid;
 extern	int logging;
 extern	int type;
 extern	int form;
@@ -1630,7 +1630,7 @@
 			reply(500, "Invalid address rejected.");
 			return 1;
 		}
-		if (paranoid &&
+		if (ftpdparanoid &&
 		    ((ntohs(data_dest.su_port) < IPPORT_RESERVED) ||
 		     memcmp(&data_dest.su_sin.sin_addr,
 			    &his_addr.su_sin.sin_addr,
@@ -1757,7 +1757,7 @@
 			reply(500, "Invalid address rejected.");
 			return 1;
 		}
-		if (paranoid &&
+		if (ftpdparanoid &&
 		    ((ntohs(data_dest.su_port) < IPPORT_RESERVED) ||
 		     memcmp(&data_dest.su_sin6.sin6_addr,
 			    &his_addr.su_sin6.sin6_addr,
diff -urN ftpd.ORI/ftpd.c ftpd/ftpd.c
--- ftpd.ORI/ftpd.c	Sat Nov 15 14:08:26 2003
+++ ftpd/ftpd.c	Wed Nov 26 02:09:43 2003
@@ -95,6 +95,10 @@
 #include <security/pam_appl.h>
 #endif
 
+#ifdef TCPWRAPPERS
+#include <tcpd.h>
+#endif /* TCPWRAPPERS */
+
 #include "pathnames.h"
 #include "extern.h"
 
@@ -124,7 +128,7 @@
 int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
 int	logging;
 int	restricted_data_ports = 1;
-int	paranoid = 1;	  /* be extra careful about security */
+int	ftpdparanoid = 1;	  /* be extra careful about security */
 int	anon_only = 0;    /* Only anonymous ftp allowed */
 int	guest;
 int	dochroot;
@@ -186,6 +190,12 @@
 static char opieprompt[OPIE_CHALLENGE_MAX+1];
 static int pwok;
 
+#ifdef TCPWRAPPERS
+static int check_host(struct sockaddr *);
+int	allow_severity = LOG_INFO;
+int	deny_severity = LOG_NOTICE;
+#endif /* TCPWRAPPERS */
+
 char	*pid_file = NULL;
 
 /*
@@ -367,7 +377,7 @@
 			break;
 
 		case 'R':
-			paranoid = 0;
+			ftpdparanoid = 0;
 			break;
 
 		case 'S':
@@ -580,6 +590,16 @@
 		syslog(LOG_ERR, "fcntl F_SETOWN: %m");
 #endif
 	dolog((struct sockaddr *)&his_addr);
+#ifdef TCPWRAPPERS
+	/* If ftpd runs in daemon mode, this code is reachable only in the
+	 * child process */
+	if (daemon_mode) {
+		/* Use tcp_wrappers to filter incoming requests */
+		if (!check_host((struct sockaddr *)&his_addr))
+			exit(1);
+	}
+#endif /* TCPWRAPPERS */
+
 	/*
 	 * Set up default state
 	 */
@@ -3212,3 +3232,40 @@
 	}
 	return(socks);
 }
+
+#ifdef TCPWRAPPERS
+static int
+check_host(struct sockaddr *sa)
+{
+    struct request_info req;
+
+    int error_name, error_addr;
+    char sa_name[MAXHOSTNAMELEN], sa_addr[NI_MAXHOST];
+
+	error_name = getnameinfo(sa, sa->sa_len,
+		sa_name, sizeof(sa_name) - 1, NULL, 0, NI_NAMEREQD);
+	error_addr = getnameinfo(sa, sa->sa_len,
+		sa_addr, sizeof(sa_addr) - 1, NULL, 0, NI_NUMERICHOST);
+
+    /* fill req struct with port name and fd number */
+    if (!error_name) {
+	request_init(&req, RQ_DAEMON, "ftpd", RQ_CLIENT_NAME, sa_name,
+		    RQ_CLIENT_ADDR, error_addr == 0 ? sa_addr : "", RQ_USER,
+		    STRING_UNKNOWN, NULL);
+    } else {
+	request_init(&req, RQ_DAEMON, "ftpd", RQ_CLIENT_NAME, STRING_UNKNOWN,
+		    RQ_CLIENT_ADDR, error_addr == 0 ? sa_addr : "", RQ_USER,
+		    STRING_UNKNOWN, NULL);
+    }
+
+    if (!hosts_access(&req)) {
+	syslog(LOG_NOTICE, "connection from %.256s rejected by tcp_wrappers",
+	      eval_client(&req));
+	return (0);
+    }
+
+    syslog(LOG_INFO, "connection from %.256s granted by tcp_wrappers",
+	  eval_client(&req));
+    return (1);
+}
+#endif /* TCPWRAPPERS */
>Release-Note:
>Audit-Trail:
>Unformatted:



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