# HG changeset patch # Parent 9e5f1fd5b5e2c3d8416cb2e2e539f43d8f1f173b 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 +#include +#include +#include +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 #endif +#ifdef LIBWRAP +#include +#include +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