Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144172623
D51642.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
31 KB
Referenced Files
None
Subscribers
None
D51642.diff
View Options
Index: INSTALL
===================================================================
--- INSTALL
+++ INSTALL
@@ -78,6 +78,15 @@
http://www.jmknoble.net/software/x11-ssh-askpass/
+TCP Wrappers:
+
+If you wish to use the TCP wrappers functionality you will need at least
+tcpd.h and libwrap.a, either in the standard include and library paths,
+or in the directory specified by --with-tcp-wrappers. Version 7.6 is
+known to work.
+
+http://ftp.porcupine.org/pub/security/index.html
+
LibEdit:
sftp supports command-line editing via NetBSD's libedit. If your platform
@@ -196,6 +205,9 @@
--with-osfsia, --without-osfsia will enable or disable OSF1's Security
Integration Architecture. The default for OSF1 machines is enable.
+--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny)
+support.
+
--with-utmpx enables utmpx support. utmpx support is automatic for
some platforms.
Index: auth-pam.c
===================================================================
--- auth-pam.c
+++ auth-pam.c
@@ -101,6 +101,7 @@
#endif
#include "monitor_wrap.h"
#include "srclimit.h"
+#include "blacklist_client.h"
extern ServerOptions options;
extern struct sshbuf *loginmsg;
@@ -936,6 +937,8 @@
sshbuf_free(buffer);
return (0);
}
+ BLACKLIST_NOTIFY(NULL, BLACKLIST_BAD_USER,
+ sshpam_authctxt->user);
error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ",
sshpam_authctxt->user, sshpam_rhost);
Index: auth.c
===================================================================
--- auth.c
+++ auth.c
@@ -75,6 +75,7 @@
#include "monitor_wrap.h"
#include "ssherr.h"
#include "channels.h"
+#include "blacklist_client.h"
/* import */
extern ServerOptions options;
@@ -285,8 +286,11 @@
authmsg = "Postponed";
else if (partial)
authmsg = "Partial";
- else
+ else {
authmsg = authenticated ? "Accepted" : "Failed";
+ if (authenticated)
+ BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_OK, "ssh");
+ }
if ((extra = format_method_key(authctxt)) == NULL) {
if (authctxt->auth_method_info != NULL)
@@ -494,6 +498,7 @@
aix_restoreauthdb();
#endif
if (pw == NULL) {
+ BLACKLIST_NOTIFY(ssh, BLACKLIST_BAD_USER, user);
logit("Invalid user %.100s from %.100s port %d",
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#ifdef CUSTOM_FAILED_LOGIN
Index: auth2.c
===================================================================
--- auth2.c
+++ auth2.c
@@ -52,6 +52,7 @@
#include "dispatch.h"
#include "pathnames.h"
#include "ssherr.h"
+#include "blacklist_client.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
@@ -442,8 +443,10 @@
} else {
/* Allow initial try of "none" auth without failure penalty */
if (!partial && !authctxt->server_caused_failure &&
- (authctxt->attempt > 1 || strcmp(method, "none") != 0))
+ (authctxt->attempt > 1 || strcmp(method, "none") != 0)) {
authctxt->failures++;
+ BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, "ssh");
+ }
if (authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS
mm_audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES);
Index: configure.ac
===================================================================
--- configure.ac
+++ configure.ac
@@ -1090,6 +1090,7 @@
[NetBSD read function is sometimes redirected, breaking atomicio comparisons against it])
;;
*-*-freebsd*)
+ SKIP_DISABLE_LASTLOG_DEFINE=yes
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["*LOCKED*"], [Account locked with pw(1)])
AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
AC_CHECK_HEADER([net/if_tap.h], ,
@@ -1703,6 +1704,61 @@
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,
@@ -3348,11 +3404,11 @@
LIBFIDO2=`$PKGCONFIG --libs libfido2`
CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libfido2`"
else
- LIBFIDO2="-lfido2 -lcbor"
+ LIBFIDO2="-lprivatefido2 -lprivatecbor"
fi
OTHERLIBS=`echo $LIBFIDO2 | sed 's/-lfido2//'`
fido2_error=
- AC_CHECK_LIB([fido2], [fido_init],
+ AC_CHECK_LIB([privatefido2], [fido_init],
[ ],
[ fido2_error="missing/unusable libfido2" ],
[ $OTHERLIBS ]
@@ -5782,6 +5838,7 @@
echo " OSF SIA support: $SIA_MSG"
echo " KerberosV support: $KRB5_MSG"
echo " SELinux support: $SELINUX_MSG"
+echo " TCP Wrappers support: $TCPW_MSG"
echo " libedit support: $LIBEDIT_MSG"
echo " libldns support: $LDNS_MSG"
echo " Solaris process contract support: $SPC_MSG"
Index: packet.c
===================================================================
--- packet.c
+++ packet.c
@@ -96,6 +96,7 @@
#include "packet.h"
#include "ssherr.h"
#include "sshbuf.h"
+#include "blacklist_client.h"
#ifdef PACKET_DEBUG
#define DBG(x) x
@@ -2021,6 +2022,7 @@
case SSH_ERR_NO_KEX_ALG_MATCH:
case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
if (ssh->kex && ssh->kex->failed_choice) {
+ BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, "ssh");
ssh_packet_clear_keys(ssh);
errno = oerrno;
logdie("Unable to negotiate with %s: %s. "
Index: pathnames.h
===================================================================
--- pathnames.h
+++ pathnames.h
@@ -129,7 +129,7 @@
* Default location of askpass
*/
#ifndef _PATH_SSH_ASKPASS_DEFAULT
-#define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass"
+#define _PATH_SSH_ASKPASS_DEFAULT "/usr/local/bin/ssh-askpass"
#endif
/* Location of ssh-keysign for hostbased authentication */
@@ -149,7 +149,7 @@
/* xauth for X11 forwarding */
#ifndef _PATH_XAUTH
-#define _PATH_XAUTH "/usr/X11R6/bin/xauth"
+#define _PATH_XAUTH "/usr/local/bin/xauth"
#endif
/* UNIX domain socket for X11 server; displaynum will replace %u */
Index: regress/unittests/sshkey/test_sshkey.c
===================================================================
--- regress/unittests/sshkey/test_sshkey.c
+++ regress/unittests/sshkey/test_sshkey.c
@@ -8,6 +8,7 @@
#include "includes.h"
#include <sys/types.h>
+#include <paths.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
@@ -81,7 +82,7 @@
critopts = sshbuf_new();
ASSERT_PTR_NE(critopts, NULL);
- put_opt(critopts, "force-command", "/usr/local/bin/nethack");
+ put_opt(critopts, "force-command", _PATH_LOCALBASE "/bin/nethack");
put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
exts = sshbuf_new();
Index: servconf.h
===================================================================
--- servconf.h
+++ servconf.h
@@ -252,6 +252,8 @@
char *sshd_auth_path;
int refuse_connection;
+
+ int use_blacklist;
} ServerOptions;
/* Information about the incoming connection as used by Match */
Index: servconf.c
===================================================================
--- servconf.c
+++ servconf.c
@@ -217,6 +217,7 @@
options->sshd_session_path = NULL;
options->sshd_auth_path = NULL;
options->refuse_connection = -1;
+ options->use_blacklist = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -269,12 +270,16 @@
free(def_sig);
}
+static const char *defaultkey = "[default]";
+
void
servconf_add_hostkey(const char *file, const int line,
ServerOptions *options, const char *path, int userprovided)
{
char *apath = derelativise_path(path);
+ if (file == defaultkey && access(path, R_OK) != 0)
+ return;
opt_array_append2(file, line, "HostKey",
&options->host_key_files, &options->host_key_file_userprovided,
&options->num_host_key_files, apath, userprovided);
@@ -299,26 +304,28 @@
/* Portable-specific options */
if (options->use_pam == -1)
- options->use_pam = 0;
+ options->use_pam = 1;
if (options->pam_service_name == NULL)
options->pam_service_name = xstrdup(SSHD_PAM_SERVICE);
/* Standard Options */
if (options->num_host_key_files == 0) {
/* fill default hostkeys for protocols */
- servconf_add_hostkey("[default]", 0, options,
+ servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_RSA_KEY_FILE, 0);
#ifdef OPENSSL_HAS_ECC
- servconf_add_hostkey("[default]", 0, options,
+ servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_ECDSA_KEY_FILE, 0);
#endif
- servconf_add_hostkey("[default]", 0, options,
+ servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_ED25519_KEY_FILE, 0);
#ifdef WITH_XMSS
- servconf_add_hostkey("[default]", 0, options,
+ servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_XMSS_KEY_FILE, 0);
#endif /* WITH_XMSS */
}
+ if (options->num_host_key_files == 0)
+ fatal("No host key files found");
/* No certificates by default */
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
@@ -333,7 +340,7 @@
if (options->login_grace_time == -1)
options->login_grace_time = 120;
if (options->permit_root_login == PERMIT_NOT_SET)
- options->permit_root_login = PERMIT_NO_PASSWD;
+ options->permit_root_login = PERMIT_NO;
if (options->ignore_rhosts == -1)
options->ignore_rhosts = 1;
if (options->ignore_user_known_hosts == -1)
@@ -385,7 +392,7 @@
if (options->gss_strict_acceptor == -1)
options->gss_strict_acceptor = 1;
if (options->password_authentication == -1)
- options->password_authentication = 1;
+ options->password_authentication = 0;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 1;
if (options->permit_empty_passwd == -1)
@@ -454,17 +461,17 @@
if (options->max_sessions == -1)
options->max_sessions = DEFAULT_SESSIONS_MAX;
if (options->use_dns == -1)
- options->use_dns = 0;
+ options->use_dns = 1;
if (options->client_alive_interval == -1)
options->client_alive_interval = 0;
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
if (options->num_authkeys_files == 0) {
- opt_array_append("[default]", 0, "AuthorizedKeysFiles",
+ opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS);
- opt_array_append("[default]", 0, "AuthorizedKeysFiles",
+ opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS2);
@@ -476,7 +483,7 @@
if (options->ip_qos_bulk == -1)
options->ip_qos_bulk = IPTOS_DSCP_CS1;
if (options->version_addendum == NULL)
- options->version_addendum = xstrdup("");
+ options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
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)
@@ -499,6 +506,8 @@
options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH);
if (options->refuse_connection == -1)
options->refuse_connection = 0;
+ if (options->use_blacklist == -1)
+ options->use_blacklist = 0;
assemble_algorithms(options);
@@ -582,6 +591,7 @@
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
sSshdSessionPath, sSshdAuthPath, sRefuseConnection,
+ sUseBlacklist,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -751,6 +761,9 @@
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
{ "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL },
{ "refuseconnection", sRefuseConnection, SSHCFG_ALL },
+ { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
+ { "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
+
{ NULL, sBadOption, 0 }
};
@@ -2729,6 +2742,10 @@
multistate_ptr = multistate_flag;
goto parse_multistate;
+ case sUseBlacklist:
+ intptr = &options->use_blacklist;
+ goto parse_flag;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -3280,6 +3297,7 @@
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
dump_cfg_fmtint(sRefuseConnection, o->refuse_connection);
+ dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);
Index: session.c
===================================================================
--- session.c
+++ session.c
@@ -977,6 +977,9 @@
struct passwd *pw = s->pw;
#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
char *path = NULL;
+#else
+ extern char **environ;
+ char **senv, **var, *val;
#endif
/* Initialize the environment. */
@@ -998,6 +1001,9 @@
}
#endif
+ if (getenv("TZ"))
+ child_set_env(&env, &envsize, "TZ", getenv("TZ"));
+
#ifdef GSSAPI
/* Allow any GSSAPI methods that we've used to alter
* the child's environment as they see fit
@@ -1015,11 +1021,30 @@
child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
#endif
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
+ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name);
+ child_set_env(&env, &envsize, "MAIL", buf);
#ifdef HAVE_LOGIN_CAP
- if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
- child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
- else
- child_set_env(&env, &envsize, "PATH", getenv("PATH"));
+ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
+ child_set_env(&env, &envsize, "TERM", "su");
+ /*
+ * Temporarily swap out our real environment with an empty one,
+ * let setusercontext() apply any environment variables defined
+ * for the user's login class, copy those variables to the child,
+ * free the temporary environment, and restore the original.
+ */
+ senv = environ;
+ environ = xmalloc(sizeof(*environ));
+ *environ = NULL;
+ (void)setusercontext(lc, pw, pw->pw_uid, LOGIN_SETENV|LOGIN_SETPATH);
+ for (var = environ; *var != NULL; ++var) {
+ if ((val = strchr(*var, '=')) != NULL) {
+ *val++ = '\0';
+ child_set_env(&env, &envsize, *var, val);
+ }
+ free(*var);
+ }
+ free(environ);
+ environ = senv;
#else /* HAVE_LOGIN_CAP */
# ifndef HAVE_CYGWIN
/*
@@ -1039,17 +1064,9 @@
# endif /* HAVE_CYGWIN */
#endif /* HAVE_LOGIN_CAP */
- if (!options.use_pam) {
- snprintf(buf, sizeof buf, "%.200s/%.50s",
- _PATH_MAILDIR, pw->pw_name);
- child_set_env(&env, &envsize, "MAIL", buf);
- }
-
/* Normal systems set SHELL by default. */
child_set_env(&env, &envsize, "SHELL", shell);
- if (getenv("TZ"))
- child_set_env(&env, &envsize, "TZ", getenv("TZ"));
if (s->term)
child_set_env(&env, &envsize, "TERM", s->term);
if (s->display)
@@ -1263,7 +1280,8 @@
do_nologin(struct passwd *pw)
{
FILE *f = NULL;
- char buf[1024], *nl, *def_nl = _PATH_NOLOGIN;
+ const char *nl;
+ char buf[1024], *def_nl = _PATH_NOLOGIN;
struct stat sb;
#ifdef HAVE_LOGIN_CAP
@@ -1353,7 +1371,7 @@
if (platform_privileged_uidswap()) {
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid,
- (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
+ (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
perror("unable to set user context");
exit(1);
}
Index: ssh-agent.1
===================================================================
--- ssh-agent.1
+++ ssh-agent.1
@@ -43,7 +43,7 @@
.Sh SYNOPSIS
.Nm ssh-agent
.Op Fl c | s
-.Op Fl \&Dd
+.Op Fl \&Ddx
.Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash
.Op Fl O Ar option
@@ -181,6 +181,8 @@
.Xr ssh-add 1
overrides this value.
Without this option the default maximum lifetime is forever.
+.It Fl x
+Exit after the last client has disconnected.
.It Ar command Op Ar arg ...
If a command (and optional arguments) is given,
this is executed as a subprocess of the agent.
Index: ssh-agent.c
===================================================================
--- ssh-agent.c
+++ ssh-agent.c
@@ -203,11 +203,27 @@
static int restrict_websafe = 1;
static char *websafe_allowlist;
+/*
+ * Client connection count; incremented in new_socket() and decremented in
+ * close_socket(). When it reaches 0, ssh-agent will exit. Since it is
+ * normally initialized to 1, it will never reach 0. However, if the -x
+ * option is specified, it is initialized to 0 in main(); in that case,
+ * ssh-agent will exit as soon as it has had at least one client but no
+ * longer has any.
+ */
+static int xcount = 1;
+
static void
close_socket(SocketEntry *e)
{
size_t i;
+ int last = 0;
+ if (e->type == AUTH_CONNECTION) {
+ debug("xcount %d -> %d", xcount, xcount - 1);
+ if (--xcount == 0)
+ last = 1;
+ }
close(e->fd);
sshbuf_free(e->input);
sshbuf_free(e->output);
@@ -220,6 +236,8 @@
memset(e, '\0', sizeof(*e));
e->fd = -1;
e->type = AUTH_UNUSED;
+ if (last)
+ cleanup_exit(0);
}
static void
@@ -1918,6 +1936,10 @@
debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" :
(type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN"));
+ if (type == AUTH_CONNECTION) {
+ debug("xcount %d -> %d", xcount, xcount + 1);
+ ++xcount;
+ }
set_nonblock(fd);
if (fd > max_fd)
@@ -2208,7 +2230,7 @@
usage(void)
{
fprintf(stderr,
- "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
+ "usage: ssh-agent [-c | -s] [-Ddx] [-a bind_address] [-E fingerprint_hash]\n"
" [-O option] [-P allowed_providers] [-t life]\n"
" ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option]\n"
" [-P allowed_providers] [-t life] command [arg ...]\n"
@@ -2245,6 +2267,7 @@
/* drop */
(void)setegid(getgid());
(void)setgid(getgid());
+ setuid(geteuid());
platform_disable_tracing(0); /* strict=no */
@@ -2256,7 +2279,7 @@
__progname = ssh_get_progname(av[0]);
seed_rng();
- while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) {
+ while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:x")) != -1) {
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -2313,6 +2336,9 @@
usage();
}
break;
+ case 'x':
+ xcount = 0;
+ break;
default:
usage();
}
Index: ssh-gss.h
===================================================================
--- ssh-gss.h
+++ ssh-gss.h
@@ -28,10 +28,10 @@
#ifdef GSSAPI
-#ifdef HAVE_GSSAPI_H
-#include <gssapi.h>
-#elif defined(HAVE_GSSAPI_GSSAPI_H)
+#ifdef HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
+#elif defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
#endif
#ifdef KRB5
Index: ssh.c
===================================================================
--- ssh.c
+++ ssh.c
@@ -1468,6 +1468,26 @@
cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost,
cinfo->remhost, cinfo->portstr, cinfo->remuser, cinfo->jmphost);
+ /* Find canonic host name. */
+ if (strchr(host, '.') == NULL) {
+ struct addrinfo hints;
+ struct addrinfo *ai = NULL;
+ int errgai;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = options.address_family;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ errgai = getaddrinfo(host, NULL, &hints, &ai);
+ if (errgai == 0) {
+ if (ai->ai_canonname != NULL) {
+ free(host);
+ host = xstrdup(ai->ai_canonname);
+ }
+ freeaddrinfo(ai);
+ }
+ }
+
/*
* Expand tokens in arguments. NB. LocalCommand is expanded later,
* after port-forwarding is set up, so it may pick up any local
Index: ssh_config.5
===================================================================
--- ssh_config.5
+++ ssh_config.5
@@ -2226,7 +2226,7 @@
.Xr xauth 1
program.
The default is
-.Pa /usr/X11R6/bin/xauth .
+.Pa /usr/local/bin/xauth .
.El
.Sh PATTERNS
A
Index: sshd-session.c
===================================================================
--- sshd-session.c
+++ sshd-session.c
@@ -108,6 +108,7 @@
#include "sk-api.h"
#include "srclimit.h"
#include "dh.h"
+#include "blacklist_client.h"
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
@@ -1227,6 +1228,11 @@
cleanup_exit(255);
}
+#ifdef HAVE_LOGIN_CAP
+ /* Also caches remote hostname for sandboxed child. */
+ auth_get_canonical_hostname(ssh, options.use_dns);
+#endif
+
/*
* The rest of the code depends on the fact that
* ssh_remote_ipaddr() caches the remote ip, even if
@@ -1292,6 +1298,8 @@
fatal("sshbuf_new loginmsg failed");
auth_debug_reset();
+ BLACKLIST_INIT();
+
if (privsep_preauth(ssh) != 1)
fatal("privsep_preauth failed");
Index: sshd.8
===================================================================
--- sshd.8
+++ sshd.8
@@ -64,7 +64,7 @@
.Nm
listens for connections from clients.
It is normally started at boot from
-.Pa /etc/rc .
+.Pa /etc/rc.d/sshd .
It forks a new
daemon for each incoming connection.
The forked daemons handle
@@ -355,8 +355,9 @@
If the login is on a tty, records login time.
.It
Checks
-.Pa /etc/nologin ;
-if it exists, prints contents and quits
+.Pa /etc/nologin and
+.Pa /var/run/nologin ;
+if one exists, it prints the contents and quits
(unless root).
.It
Changes to run with normal user privileges.
@@ -925,6 +926,12 @@
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 ) .
@@ -1027,6 +1034,7 @@
.Xr ssh-keygen 1 ,
.Xr ssh-keyscan 1 ,
.Xr chroot 2 ,
+.Xr hosts_access 5 ,
.Xr login.conf 5 ,
.Xr moduli 5 ,
.Xr sshd_config 5 ,
Index: sshd.c
===================================================================
--- sshd.c
+++ sshd.c
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
@@ -71,6 +72,15 @@
#include <prot.h>
#endif
+#ifdef __FreeBSD__
+#include <resolv.h>
+#if defined(GSSAPI) && defined(HAVE_GSSAPI_GSSAPI_H)
+#include <gssapi/gssapi.h>
+#elif defined(GSSAPI) && defined(HAVE_GSSAPI_H)
+#include <gssapi.h>
+#endif
+#endif
+
#include "xmalloc.h"
#include "ssh.h"
#include "sshpty.h"
@@ -95,6 +105,11 @@
#include "srclimit.h"
#include "atomicio.h"
+#ifdef LIBWRAP
+#include <tcpd.h>
+#include <syslog.h>
+#endif /* LIBWRAP */
+
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2)
@@ -642,7 +657,14 @@
static void
usage(void)
{
- fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSH_OPENSSL_VERSION);
+ if (options.version_addendum != NULL &&
+ *options.version_addendum != '\0')
+ fprintf(stderr, "%s %s, %s\n",
+ SSH_RELEASE,
+ options.version_addendum, SSH_OPENSSL_VERSION);
+ else
+ fprintf(stderr, "%s, %s\n",
+ SSH_RELEASE, SSH_OPENSSL_VERSION);
fprintf(stderr,
"usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n"
" [-E log_file] [-f config_file] [-g login_grace_time]\n"
@@ -926,6 +948,11 @@
socklen_t fromlen;
u_char rnd[256];
sigset_t nsigset, osigset;
+#ifdef LIBWRAP
+ struct request_info req;
+
+ request_init(&req, RQ_DAEMON, __progname, 0);
+#endif
/* pipes connected to unauthenticated child sshd processes */
child_alloc();
@@ -1133,6 +1160,42 @@
usleep(100 * 1000);
continue;
}
+#ifdef LIBWRAP
+ /* Check whether logins are denied from this host. */
+ request_set(&req, RQ_FILE, *newsock,
+ RQ_CLIENT_NAME, "", RQ_CLIENT_ADDR, "", 0);
+ sock_host(&req);
+ if (!hosts_access(&req)) {
+ const struct linger l = { .l_onoff = 1,
+ .l_linger = 0 };
+
+ (void )setsockopt(*newsock, SOL_SOCKET,
+ SO_LINGER, &l, sizeof(l));
+ (void )close(*newsock);
+ /*
+ * Mimic message from libwrap's refuse() as
+ * precisely as we can afford. The authentic
+ * message prints the IP address and the
+ * hostname it resolves to in parentheses. If
+ * the IP address cannot be resolved to a
+ * hostname, the IP address will be repeated
+ * in parentheses. As name resolution in the
+ * main server loop could stall, and logging
+ * resolved names adds little or no value to
+ * incident investigation, this implementation
+ * only repeats the IP address in parentheses.
+ * This should resemble librwap's refuse()
+ * closely enough not to break auditing
+ * software like sshguard or custom scripts.
+ */
+ syslog(LOG_WARNING,
+ "refused connect from %s (%s)",
+ eval_hostaddr(req.client),
+ eval_hostaddr(req.client));
+ debug("Connection refused by tcp wrapper");
+ continue;
+ }
+#endif /* LIBWRAP */
if (unset_nonblock(*newsock) == -1) {
close(*newsock);
continue;
@@ -1819,6 +1882,10 @@
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
+ /* Avoid killing the process in high-pressure swapping environments. */
+ if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0)
+ debug("madvise(): %.200s", strerror(errno));
+
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
@@ -1906,6 +1973,28 @@
execv(rexec_argv[0], rexec_argv);
fatal("rexec of %s failed: %s", rexec_argv[0], strerror(errno));
+#ifdef __FreeBSD__
+ /*
+ * Initialize the resolver. This may not happen automatically
+ * before privsep chroot().
+ */
+ if ((_res.options & RES_INIT) == 0) {
+ debug("res_init()");
+ res_init();
+ }
+#ifdef GSSAPI
+ /*
+ * Force GSS-API to parse its configuration and load any
+ * mechanism plugins.
+ */
+ {
+ gss_OID_set mechs;
+ OM_uint32 minor_status;
+ gss_indicate_mechs(&minor_status, &mechs);
+ gss_release_oid_set(&minor_status, &mechs);
+ }
+#endif
+#endif
}
/* server specific fatal cleanup */
Index: sshd_config
===================================================================
--- sshd_config
+++ sshd_config
@@ -10,6 +10,9 @@
# possible, but leave them commented. Uncommented options override the
# default value.
+# Note that some of FreeBSD's defaults differ from OpenBSD's, and
+# FreeBSD has a few additional options.
+
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
@@ -29,7 +32,7 @@
# Authentication:
#LoginGraceTime 2m
-#PermitRootLogin prohibit-password
+#PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
@@ -53,13 +56,15 @@
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
-# To disable tunneled clear text passwords, change to "no" here!
-#PasswordAuthentication yes
+# Change to "yes" to enable built-in password authentication.
+# Note that passwords may also be accepted via KbdInteractiveAuthentication.
+#PasswordAuthentication no
#PermitEmptyPasswords no
# Change to "no" to disable keyboard-interactive authentication. Depending on
# the system's configuration, this may involve passwords, challenge-response,
# one-time passwords or some combination of these and other methods.
+# Keyboard interactive authentication is also used for PAM authentication.
#KbdInteractiveAuthentication yes
# Kerberos options
@@ -72,7 +77,7 @@
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
-# Set this to 'yes' to enable PAM authentication, account processing,
+# Set this to 'no' to disable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
@@ -81,7 +86,7 @@
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
-#UsePAM no
+#UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
@@ -97,12 +102,13 @@
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
-#UseDNS no
+#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
-#VersionAddendum none
+#UseBlacklist no
+#VersionAddendum FreeBSD-20250729
# no default banner path
#Banner none
Index: sshd_config.5
===================================================================
--- sshd_config.5
+++ sshd_config.5
@@ -881,7 +881,7 @@
The system-wide
.Pa /etc/hosts.equiv
and
-.Pa /etc/shosts.equiv
+.Pa /etc/ssh/shosts.equiv
are still used regardless of this setting.
.Pp
Accepted values are
@@ -1396,8 +1396,12 @@
.Cm sshd .
.It Cm PasswordAuthentication
Specifies whether password authentication is allowed.
+Note that passwords may also be accepted via
+.Cm KbdInteractiveAuthentication .
+See also
+.Cm UsePAM .
The default is
-.Cm yes .
+.Cm no .
.It Cm PermitEmptyPasswords
When password authentication is allowed, it specifies whether the
server allows login to accounts with empty password strings.
@@ -1490,7 +1494,14 @@
or
.Cm no .
The default is
-.Cm prohibit-password .
+.Cm no .
+Note that if
+.Cm ChallengeResponseAuthentication
+and
+.Cm UsePAM
+are both
+.Cm yes ,
+this setting may be overridden by the PAM policy.
.Pp
If this option is set to
.Cm prohibit-password
@@ -2009,6 +2020,20 @@
is to never expire connections for having no open channels.
This option may be useful in conjunction with
.Cm ChannelTimeout .
+.It Cm UseBlacklist
+Specifies whether
+.Xr sshd 8
+attempts to send authentication success and failure messages
+to the
+.Xr blacklistd 8
+daemon.
+The default is
+.Cm no .
+For forward compatibility with an upcoming
+.Xr blacklistd
+rename, the
+.Cm UseBlocklist
+alias can be used instead.
.It Cm UseDNS
Specifies whether
.Xr sshd 8
@@ -2017,8 +2042,8 @@
very same IP address.
.Pp
If this option is set to
-.Cm no
-(the default) then only addresses and not host names may be used in
+.Cm no ,
+then only addresses and not host names may be used in
.Pa ~/.ssh/authorized_keys
.Cm from
and
@@ -2026,6 +2051,8 @@
.Cm Match
.Cm Host
directives.
+The default is
+.Dq yes .
.It Cm UsePAM
Enables the Pluggable Authentication Module interface.
If set to
@@ -2049,12 +2076,15 @@
.Xr sshd 8
as a non-root user.
The default is
-.Cm no .
+.Cm yes .
.It Cm VersionAddendum
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.
The default is
-.Cm none .
+.Qq FreeBSD-20250729 .
+The value
+.Cm none
+may be used to disable this.
.It Cm X11DisplayOffset
Specifies the first display number available for
.Xr sshd 8 Ns 's
@@ -2124,7 +2154,7 @@
.Cm none
to not use one.
The default is
-.Pa /usr/X11R6/bin/xauth .
+.Pa /usr/local/bin/xauth .
.El
.Sh TIME FORMATS
.Xr sshd 8
Index: umac128.c
===================================================================
--- umac128.c
+++ umac128.c
@@ -1,5 +1,12 @@
/* $OpenBSD: umac128.c,v 1.2 2018/02/08 04:12:32 dtucker Exp $ */
+/* undo ssh_namespace.h munging */
+#undef umac_new
+#undef umac_update
+#undef umac_final
+#undef umac_delete
+#undef umac_ctx
+
#define UMAC_OUTPUT_LEN 16
#define umac_new umac128_new
#define umac_update umac128_update
Index: version.h
===================================================================
--- version.h
+++ version.h
@@ -4,3 +4,5 @@
#define SSH_PORTABLE "p2"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
+
+#define SSH_VERSION_FREEBSD "FreeBSD-20250729"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Feb 6, 10:25 PM (9 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28450946
Default Alt Text
D51642.diff (31 KB)
Attached To
Mode
D51642: OpenSSH update - FreeBSD patches vs upstream 10.0p2
Attached
Detach File
Event Timeline
Log In to Comment