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>
