# HG changeset patch
# Parent  327e611bd491d65826fb6de435250c037ed7e307
Forward port TCP wrappers support (libwrap) from OpenSSH 6.6p1. Make it
run-time switchable through the new UseTCPWrappers option for sshd.

diff --git a/openssh-7.2p2/configure.ac b/openssh-7.2p2/configure.ac
--- a/openssh-7.2p2/configure.ac
+++ b/openssh-7.2p2/configure.ac
@@ -1501,16 +1501,72 @@ AC_ARG_WITH([skey],
 					function takes 4 arguments (NetBSD)])],
 			[
 				AC_MSG_RESULT([no])
 			])
 		fi
 	]
 )
 
+# Check whether user wants TCP wrappers support
+TCPW_MSG="no"
+AC_ARG_WITH([tcp-wrappers],
+	[  --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)],
+	[
+		if test "x$withval" != "xno" ; then
+			saved_LIBS="$LIBS"
+			saved_LDFLAGS="$LDFLAGS"
+			saved_CPPFLAGS="$CPPFLAGS"
+			if test -n "${withval}" && \
+			    test "x${withval}" != "xyes"; then
+				if test -d "${withval}/lib"; then
+					if test -n "${need_dash_r}"; then
+						LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+					else
+						LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+					fi
+				else
+					if test -n "${need_dash_r}"; then
+						LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+					else
+						LDFLAGS="-L${withval} ${LDFLAGS}"
+					fi
+				fi
+				if test -d "${withval}/include"; then
+					CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+				else
+					CPPFLAGS="-I${withval} ${CPPFLAGS}"
+				fi
+			fi
+			LIBS="-lwrap $LIBS"
+			AC_MSG_CHECKING([for libwrap])
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <tcpd.h>
+int deny_severity = 0, allow_severity = 0;
+				]], [[
+	hosts_access(0);
+				]])], [
+					AC_MSG_RESULT([yes])
+					AC_DEFINE([LIBWRAP], [1],
+						[Define if you want
+						TCP Wrappers support])
+					SSHDLIBS="$SSHDLIBS -lwrap"
+					TCPW_MSG="yes"
+				], [
+					AC_MSG_ERROR([*** libwrap missing])
+				
+			])
+			LIBS="$saved_LIBS"
+		fi
+	]
+)
+
 # Check whether user wants to use ldns
 LDNS_MSG="no"
 AC_ARG_WITH(ldns,
 	[  --with-ldns[[=PATH]]      Use ldns for DNSSEC support (optionally in PATH)],
     [
         if test "x$withval" != "xno" ; then
 
 			if test "x$withval" != "xyes" ; then
@@ -5159,16 +5215,17 @@ echo "          sshd superuser user PATH
 fi
 echo "                    Manpage format: $MANTYPE"
 echo "                       PAM support: $PAM_MSG"
 echo "                   OSF SIA support: $SIA_MSG"
 echo "                 KerberosV support: $KRB5_MSG"
 echo "                   SELinux support: $SELINUX_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
+echo "              TCP Wrappers support: $TCPW_MSG"
 echo "              MD5 password support: $MD5_MSG"
 echo "                   libedit support: $LIBEDIT_MSG"
 echo "  Solaris process contract support: $SPC_MSG"
 echo "           Solaris project support: $SP_MSG"
 echo "         Solaris privilege support: $SPP_MSG"
 echo "                   systemd support: $SYSTEMD_MSG"
 echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
 echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
diff --git a/openssh-7.2p2/servconf.c b/openssh-7.2p2/servconf.c
--- a/openssh-7.2p2/servconf.c
+++ b/openssh-7.2p2/servconf.c
@@ -173,16 +173,17 @@ initialize_server_options(ServerOptions 
 	options->trusted_user_ca_keys = NULL;
 	options->authorized_principals_file = NULL;
 	options->authorized_principals_command = NULL;
 	options->authorized_principals_command_user = NULL;
 	options->ip_qos_interactive = -1;
 	options->ip_qos_bulk = -1;
 	options->version_addendum = NULL;
 	options->fingerprint_hash = -1;
+	options->use_tcpwrappers = -1;
 }
 
 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
 static int
 option_clear_or_none(const char *o)
 {
 	return o == NULL || strcasecmp(o, "none") == 0;
 }
@@ -392,16 +393,19 @@ fill_default_server_options(ServerOption
 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
 		options->fwd_opts.streamlocal_bind_mask = 0177;
 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
 		options->fwd_opts.streamlocal_bind_unlink = 0;
 	if (options->fingerprint_hash == -1)
 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
 	options->fingerprint_hash =
 		fips_correct_dgst(options->fingerprint_hash);
+	if (options->use_tcpwrappers == -1) {
+		options->use_tcpwrappers = 0;
+	}
 
 	assemble_algorithms(options);
 
 	/* Turn privilege separation and sandboxing on by default */
 	if (use_privsep == -1)
 		use_privsep = PRIVSEP_ON;
 
 #define CLEAR_ON_NONE(v) \
@@ -471,16 +475,17 @@ typedef enum {
 	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
 	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
 	sKexAlgorithms, sKexDHMin,
 	sIPQoS, sVersionAddendum,
 	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
 	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
 	sStreamLocalBindMask, sStreamLocalBindUnlink,
 	sAllowStreamLocalForwarding, sFingerprintHash,
+	sUseTCPWrappers,
 	sDeprecated, sUnsupported
 } ServerOpCodes;
 
 #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
 #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
 #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
 
 /* Textual representation of the tokens. */
@@ -622,16 +627,17 @@ static struct {
 	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
 	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
 	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
 	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
 	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
 	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
 	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
 	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
+	{ "usetcpwrappers", sUseTCPWrappers, SSHCFG_GLOBAL },
 	{ NULL, sBadOption, 0 }
 };
 
 static struct {
 	int val;
 	char *text;
 } tunmode_desc[] = {
 	{ SSH_TUNMODE_NO, "no" },
@@ -1245,16 +1251,20 @@ process_server_config_line(ServerOptions
 	case sHostbasedAuthentication:
 		intptr = &options->hostbased_authentication;
 		goto parse_flag;
 
 	case sHostbasedUsesNameFromPacketOnly:
 		intptr = &options->hostbased_uses_name_from_packet_only;
 		goto parse_flag;
 
+	case sUseTCPWrappers:
+		intptr = &options->use_tcpwrappers;
+		goto parse_flag;
+
 	case sHostbasedAcceptedKeyTypes:
 		charptr = &options->hostbased_key_types;
  parse_keytypes:
 		arg = strdelim(&cp);
 		if (!arg || *arg == '\0')
 			fatal("%s line %d: Missing argument.",
 			    filename, linenum);
 		if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
@@ -2400,16 +2410,17 @@ dump_config(ServerOptions *o)
 	dump_cfg_fmtint(sCompression, o->compression);
 	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
 	dump_cfg_fmtint(sUseDNS, o->use_dns);
 	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
 	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
 	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
+	dump_cfg_fmtint(sUseTCPWrappers, o->use_tcpwrappers);
 
 	/* string arguments */
 	dump_cfg_string(sPidFile, o->pid_file);
 	dump_cfg_string(sXAuthLocation, o->xauth_location);
 	dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
 	dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
 	dump_cfg_string(sBanner, o->banner);
 	dump_cfg_string(sForceCommand, o->adm_forced_command);
diff --git a/openssh-7.2p2/servconf.h b/openssh-7.2p2/servconf.h
--- a/openssh-7.2p2/servconf.h
+++ b/openssh-7.2p2/servconf.h
@@ -196,16 +196,17 @@ typedef struct {
 	int	rekey_interval;
 
 	char   *version_addendum;	/* Appended to SSH banner */
 
 	u_int	num_auth_methods;
 	char   *auth_methods[MAX_AUTH_METHODS];
 
 	int	fingerprint_hash;
+	int	use_tcpwrappers;
 }       ServerOptions;
 
 /* Information about the incoming connection as used by Match */
 struct connection_info {
 	const char *user;
 	const char *host;	/* possibly resolved hostname */
 	const char *address; 	/* remote address */
 	const char *laddress;	/* local address */
diff --git a/openssh-7.2p2/sshd.8 b/openssh-7.2p2/sshd.8
--- a/openssh-7.2p2/sshd.8
+++ b/openssh-7.2p2/sshd.8
@@ -875,16 +875,22 @@ This file should be writable only by roo
 can, but need not be, world-readable.
 .Pp
 .It Pa ~/.ssh/rc
 Contains initialization routines to be run before
 the user's home directory becomes accessible.
 This file should be writable only by the user, and need not be
 readable by anyone else.
 .Pp
+.It Pa /etc/hosts.allow
+.It Pa /etc/hosts.deny
+Access controls that should be enforced by tcp-wrappers are defined here.
+Further details are described in
+.Xr hosts_access 5 .
+.Pp
 .It Pa /etc/hosts.equiv
 This file is for host-based authentication (see
 .Xr ssh 1 ) .
 It should only be writable by root.
 .Pp
 .It Pa /etc/moduli
 Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange"
 key exchange method.
@@ -998,16 +1004,17 @@ be blocked until enough entropy is avail
 .Xr scp 1 ,
 .Xr sftp 1 ,
 .Xr ssh 1 ,
 .Xr ssh-add 1 ,
 .Xr ssh-agent 1 ,
 .Xr ssh-keygen 1 ,
 .Xr ssh-keyscan 1 ,
 .Xr chroot 2 ,
+.Xr hosts_access 5 ,
 .Xr login.defs 5 ,
 .Xr moduli 5 ,
 .Xr sshd_config 5 ,
 .Xr inetd 8 ,
 .Xr sftp-server 8
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
diff --git a/openssh-7.2p2/sshd.c b/openssh-7.2p2/sshd.c
--- a/openssh-7.2p2/sshd.c
+++ b/openssh-7.2p2/sshd.c
@@ -132,16 +132,23 @@
 #include "ssherr.h"
 
 #include "fips.h"
 
 #ifdef USE_SECURITY_SESSION_API
 #include <Security/AuthSession.h>
 #endif
 
+#ifdef LIBWRAP
+#include <tcpd.h>
+#include <syslog.h>
+int allow_severity;
+int deny_severity;
+#endif /* LIBWRAP */
+
 #ifndef O_NOCTTY
 #define O_NOCTTY	0
 #endif
 
 /* Re-exec fds */
 #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
 #define REEXEC_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
 #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
@@ -2298,16 +2305,37 @@ main(int ac, char **av)
 	 * the socket goes away.
 	 */
 	remote_ip = get_remote_ipaddr();
 
 #ifdef SSH_AUDIT_EVENTS
 	audit_connection_from(remote_ip, remote_port);
 #endif
 
+#ifdef LIBWRAP
+	if (options.use_tcpwrappers) {
+		allow_severity = options.log_facility|LOG_INFO;
+		deny_severity = options.log_facility|LOG_WARNING;
+		/* Check whether logins are denied from this host. */
+		if (packet_connection_is_on_socket()) {
+			struct request_info req;
+
+			request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0);
+			fromhost(&req);
+
+			if (!hosts_access(&req)) {
+				debug("Connection refused by tcp wrapper");
+				refuse(&req);
+				/* NOTREACHED */
+				fatal("libwrap refuse returns");
+			}
+		}
+	}
+#endif /* LIBWRAP */
+
 	/* Log the connection. */
 	laddr = get_local_ipaddr(sock_in);
 	verbose("Connection from %s port %d on %s port %d",
 	    remote_ip, remote_port, laddr,  get_local_port());
 	free(laddr);
 
 #ifdef USE_SECURITY_SESSION_API
 	/*
diff --git a/openssh-7.2p2/sshd_config b/openssh-7.2p2/sshd_config
--- a/openssh-7.2p2/sshd_config
+++ b/openssh-7.2p2/sshd_config
@@ -120,16 +120,17 @@ X11Forwarding yes
 #ClientAliveInterval 0
 #ClientAliveCountMax 3
 #UseDNS no
 #PidFile /var/run/sshd.pid
 #MaxStartups 10:30:100
 #PermitTunnel no
 #ChrootDirectory none
 #VersionAddendum none
+#UseTCPWrappers yes
 
 # no default banner path
 #Banner none
 
 # override default of no subsystems
 Subsystem	sftp	/usr/libexec/sftp-server
 
 # This enables accepting locale enviroment variables LC_* LANG, see sshd_config(5).
diff --git a/openssh-7.2p2/sshd_config.0 b/openssh-7.2p2/sshd_config.0
--- a/openssh-7.2p2/sshd_config.0
+++ b/openssh-7.2p2/sshd_config.0
@@ -1008,16 +1008,27 @@ DESCRIPTION
              that has the privilege of the authenticated user.  The goal of
              privilege separation is to prevent privilege escalation by
              containing any corruption within the unprivileged processes.  The
              argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\sandboxM-bM-^@M-^].  If
              UsePrivilegeSeparation is set to M-bM-^@M-^\sandboxM-bM-^@M-^] then the pre-
              authentication unprivileged process is subject to additional
              restrictions.  The default is M-bM-^@M-^\sandboxM-bM-^@M-^].
 
+     UseTCPWrappers
+             When set to "yes" , TCP wrappers (libwrap) are used to determine
+             whether a connection from a remote system should be allowed as
+             specified in hosts_accept(5).  The default is "yes".
+
+             Warning: This functionality has been backported for backward
+             compatibility and should be avoided, since libwrap pulls in a
+             whole load of security issues.  Moving to sshd's internal host
+             matching is highly recommended - see the Match keyword for
+             details.
+
      VersionAddendum
              Optionally specifies additional text to append to the SSH
              protocol banner sent by the server upon connection.  The default
              is M-bM-^@M-^\noneM-bM-^@M-^].
 
      X11DisplayOffset
              Specifies the first display number available for sshd(8)'s X11
              forwarding.  This prevents sshd from interfering with real X11
diff --git a/openssh-7.2p2/sshd_config.5 b/openssh-7.2p2/sshd_config.5
--- a/openssh-7.2p2/sshd_config.5
+++ b/openssh-7.2p2/sshd_config.5
@@ -1657,16 +1657,32 @@ or
 If
 .Cm UsePrivilegeSeparation
 is set to
 .Dq sandbox
 then the pre-authentication unprivileged process is subject to additional
 restrictions.
 The default is
 .Dq sandbox .
+.It Cm UseTCPWrappers
+When set to
+.Dq yes
+, TCP wrappers (libwrap) are used to determine whether a connection from a
+remote system should be allowed as specified in
+.Xr hosts_accept 5 .
+The default is
+.Dq no .
+
+.Em Warning: This functionality has been backported for backward \
+compatibility and should be avoided, since libwrap pulls in a whole load of \
+security issues.
+Moving to sshd's internal host matching is highly
+recommended - see the
+.Cm Match
+keyword for details.
 .It Cm VersionAddendum
 Optionally specifies additional text to append to the SSH protocol banner
 sent by the server upon connection.
 The default is
 .Dq none .
 .It Cm X11DisplayOffset
 Specifies the first display number available for
 .Xr sshd 8 Ns 's
