SHA256
1
0
forked from pool/openssh

Accepting request 433780 from network

- remaining patches that were still missing
  since the update to 7.2p2 (FATE#319675):
  [openssh-7.2p2-disable_openssl_abi_check.patch]
- fix forwarding with IPv6 addresses in DISPLAY (bnc#847710)
  [openssh-7.2p2-IPv6_X_forwarding.patch]
- ignore PAM environment when using login
  (bsc#975865, CVE-2015-8325)
  [openssh-7.2p2-ignore_PAM_with_UseLogin.patch]
- limit accepted password length (prevents possible DoS)
  (bsc#992533, CVE-2016-6515)
  [openssh-7.2p2-limit_password_length.patch]
- Prevent user enumeration through the timing of password
  processing (bsc#989363, CVE-2016-6210)
  [openssh-7.2p2-prevent_timing_user_enumeration.patch]
- Add auditing for PRNG re-seeding
  [openssh-7.2p2-audit_seed_prng.patch] (forwarded request 433779 from pcerny)

OBS-URL: https://build.opensuse.org/request/show/433780
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssh?expand=0&rev=108
This commit is contained in:
Dominique Leuenberger 2016-10-10 15:35:10 +00:00 committed by Git OBS Bridge
commit 81b879f76f
37 changed files with 7552 additions and 36 deletions

View File

@ -0,0 +1,64 @@
Notes on FIPS mode and OpenSSH
---
SUSE OpenSSH comes with FIPS 140-2 support, and certain versions have been
certified as FIPS compliant by NIST. Apart from other things, this standard
puts restrictions on cryptographic algorithms that may be used.
Important notice: FIPS is not only a matter of functionality. If you want to
claim having a FIPS certified service, you *must* use the certified binaries.
Even binaries built from the same sources in the same environment and running
on a certified system, yet from a package lacking the certification, are
formally not considered to be fulfilling the requirements.
The certified binaries (ssh, sshd, sftp-server) perform mandatory selfcheck at
startup and proceed only when the checks succeed (non-certified binaries may
skip the check). These checks require the cryptographic hashes contained in the
openssh-fips subpackage.
The FIPS mode for OpenSSH is enabled in two ways - either:
1) /proc/sys/crypto/fips_enabled contains a single character '1' - this is a
system-wide setting controlled bu the fips kernel parameter; or
2) the environment variable SSH_FORCE_FIPS - if set (to any value), the
binaries behave as if they were running on a system in FIPS mode.
Since FIPS 140-2 only allows use of certain cryptographic algorithms, both the
client and server will fail if they are requested to use non-approved
algorithms while in FIPS mode. This means that working configurations for FIPS
mode form a proper subset of all working (generic) configurations. Some
configurations may even prevent the binaries from starting at all.
This however should be viewed in the context of FIPS being a security policy
tool - it is not of much use to run the same system both in FIPS mode and
outside of it, since that would defeat the main purpose of FIPS having
guaranteeing standardised minimum restrictions on cryptographic algorithms
(and thus on the overall security of the system).
Unless you specify what cryptographic algorithms you wish to use, both the
client and server should work out of the box in FIPS mode.
For sshd, you can use the `-t` option to check whether the configuration file
is working. Setting the above mentioned environment variable allows testing of
behaviour in FIPS mode (checksum files for both OpenSSH and OpenSSL must be
installed).
In addition to cryptographic algorithms restrictions, sshd performs periodic
PRNG re-seeding. The seed is read from entropy source either /dev/urandom or
/dev/random. By default, the former is used, unless the environment variable
SSH_USE_STRONG_RNG is set to a non-zero value or the binary is running in FIPS
mode. This has two important implications:
1) the selected entropy source must be available, i.e. when running in a
changeroot the device files need to be present there.
2) /dev/random is a blocking interface - unless enough randomness is available,
the process stops until the entropy pool is replenished. Thus on systems where
a long running processes are expected, one should make sure there is always
enough entropy for sshd. Sporadically this may also cause sshd to aborted,
since some versions of OpenSSL (the underlying cryptographic engine) don't
handle gracefully being interrupted while trying to read entropy from the
system source.

View File

@ -0,0 +1,72 @@
# HG changeset patch
# Parent 8c4cb20b9633595de68131224b2d434e8dc41e17
Correctly parse DISPLAY variable for cases where it contains an IPv6 address
(which should - but not always is - in (square) brackets).
bnc#847710 - https://bugzilla.novell.com/show_bug.cgi?id=847710
diff --git a/openssh-7.2p2/channels.c b/openssh-7.2p2/channels.c
--- a/openssh-7.2p2/channels.c
+++ b/openssh-7.2p2/channels.c
@@ -4049,18 +4049,19 @@ x11_connect_display(void)
/* OK, we now have a connection to the display. */
return sock;
}
#endif
/*
* Check if it is a unix domain socket. Unix domain displays are in
* one of the following formats: unix:d[.s], :d[.s], ::d[.s]
*/
+ cp = strrchr(display, ':');
if (strncmp(display, "unix:", 5) == 0 ||
- display[0] == ':') {
+ (display[0] == ':' && ((cp - display) < 2)) ) {
/* Connect to the unix domain socket. */
if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) {
error("Could not parse display number from DISPLAY: %.100s",
display);
return -1;
}
/* Create a socket. */
sock = connect_local_xsocket(display_number);
@@ -4068,30 +4069,39 @@ x11_connect_display(void)
return -1;
/* OK, we now have a connection to the display. */
return sock;
}
/*
* Connect to an inet socket. The DISPLAY value is supposedly
* hostname:d[.s], where hostname may also be numeric IP address.
+ * Note that IPv6 numberic addresses contain colons (e.g. ::1:0)
*/
strlcpy(buf, display, sizeof(buf));
- cp = strchr(buf, ':');
+ cp = strrchr(buf, ':');
if (!cp) {
error("Could not find ':' in DISPLAY: %.100s", display);
return -1;
}
*cp = 0;
/* buf now contains the host name. But first we parse the display number. */
if (sscanf(cp + 1, "%u", &display_number) != 1) {
error("Could not parse display number from DISPLAY: %.100s",
display);
return -1;
}
+
+ /* Remove brackets surrounding IPv6 addresses if there are any. */
+ if (buf[0] == '[' && (cp = strchr(buf, ']'))) {
+ *cp = 0;
+ cp = buf + 1;
+ } else {
+ cp = buf;
+ }
/* Look up the host address */
memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%u", 6000 + display_number);
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
error("%.100s: unknown host. (%s)", buf,

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 48bbbfeff186061b7fd4795bff15f15f571e2c8f
# Parent 7197d7a6b7c90566c68e980b5f8b937c183e79d0
# enable trusted X11 forwarding by default in both sshd and sshsystem-wide
# configuration
# bnc#50836 (was suse #35836)

View File

@ -0,0 +1,34 @@
# HG changeset patch
# Parent 28e8840bbf49c6e603bf2b55a08ed9050a60f9fb
Do not throw away already open sockets for X11 forwarding if another socket
family is not available for bind()
diff --git a/openssh-7.2p2/channels.c b/openssh-7.2p2/channels.c
--- a/openssh-7.2p2/channels.c
+++ b/openssh-7.2p2/channels.c
@@ -3937,22 +3937,24 @@ x11_create_display_inet(int x11_display_
}
if (ai->ai_family == AF_INET6)
sock_set_v6only(sock);
if (x11_use_localhost)
channel_set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
debug2("bind port %d: %.100s", port, strerror(errno));
close(sock);
-
+ continue;
+ /* do not remove successfully opened sockets
for (n = 0; n < num_socks; n++) {
close(socks[n]);
}
num_socks = 0;
break;
+ */
}
socks[num_socks++] = sock;
if (num_socks == NUM_SOCKS)
break;
}
freeaddrinfo(aitop);
if (num_socks > 0)
break;

View File

@ -0,0 +1,56 @@
# HG changeset patch
# Parent e7bdbc5ea8971599466becf01bff12b9fcb5df3e
Enable the seccomp-bpf sandbox on more architectures
upstream commit: b9c50614eba9d90939b2b119b6e1b7e03b462278 (7.3p1)
Author: Damien Miller <djm@mindrot.org>
Date: Fri Jul 8 13:59:13 2016 +1000
whitelist more architectures for seccomp-bpf
bz#2590 - testing and patch from Jakub Jelen
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
@@ -818,16 +818,40 @@ main() { if (NSVersionOfRunTimeLibrary("
seccomp_audit_arch=AUDIT_ARCH_I386
;;
arm*-*)
seccomp_audit_arch=AUDIT_ARCH_ARM
;;
aarch64*-*)
seccomp_audit_arch=AUDIT_ARCH_AARCH64
;;
+ s390x-*)
+ seccomp_audit_arch=AUDIT_ARCH_S390X
+ ;;
+ s390-*)
+ seccomp_audit_arch=AUDIT_ARCH_S390
+ ;;
+ powerpc64-*)
+ seccomp_audit_arch=AUDIT_ARCH_PPC64
+ ;;
+ powerpc64le-*)
+ seccomp_audit_arch=AUDIT_ARCH_PPC64LE
+ ;;
+ mips-*)
+ seccomp_audit_arch=AUDIT_ARCH_MIPS
+ ;;
+ mipsel-*)
+ seccomp_audit_arch=AUDIT_ARCH_MIPSEL
+ ;;
+ mips64-*)
+ seccomp_audit_arch=AUDIT_ARCH_MIPS64
+ ;;
+ mips64el-*)
+ seccomp_audit_arch=AUDIT_ARCH_MIPSEL64
+ ;;
esac
if test "x$seccomp_audit_arch" != "x" ; then
AC_MSG_RESULT(["$seccomp_audit_arch"])
AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch],
[Specify the system call convention in use])
else
AC_MSG_RESULT([architecture not supported])
fi

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 2730f36bee0d6e141d8391b414a702e1add5a853
# Parent d33bce122aa351a56ce457be35feda52171f9088
Enable DSS authentication by default to maintain compatibility with older
versions.

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 8cf6984812ab2211ce60c0a9156892b3a7ee3aaf
# Parent c43ae523939377778762e81743b77b3c75eb4bd1
Allow root login with password by default. While less secure than upstream
default of forbidding access to the root account with a password, we are
temporarily introducing this change to keep the default used in older OpenSSH

3241
openssh-7.2p2-audit.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
# HG changeset patch
# Parent 3aad88a155050008275527c0624ae6fa05d0cdad
Audit PRNG re-seeding
diff --git a/openssh-7.2p2/audit-bsm.c b/openssh-7.2p2/audit-bsm.c
--- a/openssh-7.2p2/audit-bsm.c
+++ b/openssh-7.2p2/audit-bsm.c
@@ -504,9 +504,15 @@ audit_destroy_sensitive_data(const char
/* not implemented */
}
void
audit_generate_ephemeral_server_key(const char *fp)
{
/* not implemented */
}
+
+void
+audit_linux_prng_seed(long bytes, const char *rf)
+{
+ /* not implemented */
+}
#endif /* BSM */
diff --git a/openssh-7.2p2/audit-linux.c b/openssh-7.2p2/audit-linux.c
--- a/openssh-7.2p2/audit-linux.c
+++ b/openssh-7.2p2/audit-linux.c
@@ -402,9 +402,31 @@ audit_generate_ephemeral_server_key(cons
}
audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
buf, NULL, 0, NULL, 1);
audit_close(audit_fd);
/* do not abort if the error is EPERM and sshd is run as non root user */
if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
error("cannot write into audit");
}
+
+void
+audit_linux_prng_seed(long bytes, const char *rf)
+{
+ char buf[AUDIT_LOG_SIZE];
+ int audit_fd, audit_ok;
+
+ snprintf(buf, sizeof(buf), "op=prng_seed kind=server bytes=%li source=%s ", bytes, rf);
+ audit_fd = audit_open();
+ if (audit_fd < 0) {
+ if (errno != EINVAL && errno != EPROTONOSUPPORT &&
+ errno != EAFNOSUPPORT)
+ error("cannot open audit");
+ return;
+ }
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_PARAM_CHANGE_USER,
+ buf, NULL, 0, NULL, 1);
+ audit_close(audit_fd);
+ /* do not abort if the error is EPERM and sshd is run as non root user */
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
+ error("cannot write into audit");
+}
#endif /* USE_LINUX_AUDIT */
diff --git a/openssh-7.2p2/audit.c b/openssh-7.2p2/audit.c
--- a/openssh-7.2p2/audit.c
+++ b/openssh-7.2p2/audit.c
@@ -304,10 +304,16 @@ audit_destroy_sensitive_data(const char
/*
* This will be called on generation of the ephemeral server key
*/
void
audit_generate_ephemeral_server_key(const char *)
{
debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
}
+
+void
+audit_linux_prng_seed(long bytes, const char *rf)
+{
+ debug("audit PRNG seed euid %d bytes %li source %s", geteuid(), bytes, rf);
+}
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
#endif /* SSH_AUDIT_EVENTS */
diff --git a/openssh-7.2p2/audit.h b/openssh-7.2p2/audit.h
--- a/openssh-7.2p2/audit.h
+++ b/openssh-7.2p2/audit.h
@@ -69,10 +69,11 @@ void audit_key(int, int *, const Key *);
void audit_unsupported(int);
void audit_kex(int, char *, char *, char *, char *);
void audit_unsupported_body(int);
void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
void audit_session_key_free(int ctos);
void audit_session_key_free_body(int ctos, pid_t, uid_t);
void audit_destroy_sensitive_data(const char *, pid_t, uid_t);
void audit_generate_ephemeral_server_key(const char *);
+void audit_linux_prng_seed(long, const char *);
#endif /* _SSH_AUDIT_H */
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
@@ -1421,16 +1421,19 @@ server_accept_loop(int *sock_in, int *so
if (maxfd < startup_p[0])
maxfd = startup_p[0];
startups++;
break;
}
if(!(--re_seeding_counter)) {
re_seeding_counter = RESEED_AFTER;
linux_seed();
+#ifdef SSH_AUDIT_EVENTS
+ audit_linux_prng_seed(rand_bytes, rand_file);
+#endif
}
/*
* Got connection. Fork a child to handle it, unless
* we are in debugging mode.
*/
if (debug_flag) {
/*

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 5469eb754184144e42c341ccc038309e2880cadc
# Parent 0bfb5dd4b190b546a3e40a59483b2b2884a47c39
block SIGALRM while logging through syslog to prevent deadlocks
(through grace_alarm_handler())

View File

@ -0,0 +1,64 @@
# HG changeset patch
# Parent 16c4937db837ab7cdbe0422b81de0e7a9a8479cd
disable run-time check for OpenSSL ABI by version number as that is not a
reliable indicator of ABI changes and doesn't make much sense in a
distribution package
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
@@ -4639,16 +4639,29 @@ AC_ARG_WITH([bsd-auth],
if test "x$withval" != "xno" ; then
AC_DEFINE([BSD_AUTH], [1],
[Define if you have BSD auth support])
BSD_AUTH_MSG=yes
fi
]
)
+# Whether we are using distribution (Open)SSL, so no runtime checks are necessary
+DISTRO_SSL=no
+AC_ARG_WITH([distro-ssl],
+ [ --with-distro-ssl Disable runtime OpenSSL version checks (good for distributions)],
+ [
+ if test "x$withval" != "xno" ; then
+ AC_DEFINE([DISTRO_SSL], [1],
+ [Define if you are using distribution SSL library and don;t expect its API/ABI to change])
+ DISTRO_SSL=yes
+ fi
+ ]
+)
+
# Where to place sshd.pid
piddir=/var/run
# make sure the directory exists
if test ! -d $piddir ; then
piddir=`eval echo ${sysconfdir}`
case $piddir in
NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
esac
diff --git a/openssh-7.2p2/entropy.c b/openssh-7.2p2/entropy.c
--- a/openssh-7.2p2/entropy.c
+++ b/openssh-7.2p2/entropy.c
@@ -209,19 +209,21 @@ rexec_recv_rng_seed(Buffer *m)
#endif /* OPENSSL_PRNG_ONLY */
void
seed_rng(void)
{
#ifndef OPENSSL_PRNG_ONLY
unsigned char buf[RANDOM_SEED_SIZE];
#endif
+#ifndef DISTRO_SSL
if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay()))
fatal("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
+#endif
#ifndef OPENSSL_PRNG_ONLY
if (RAND_status() == 1) {
debug3("RNG is ready, skipping seeding");
return;
}
if (seed_from_prngd(buf, sizeof(buf)) == -1)

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent c40dce555117c740f3df867e9fc2b07b64b3ad96
# Parent 7b5f436e0026923299fdd1994f8da8fd9948be7c
Raise minimal size of DH group parameters to 2048 bits like upstream did in
7.2. 1024b values are believed to be in breaking range for state adversaries

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 2aa634b7522f34ddbd380c96df4e750df0608604
# Parent e4886597a8984ae1594b6866fe1b232370b23529
# posix threads are generally not supported nor safe
# (see upstream log from 2005-05-24)
# --used to be called '-pam-fix3'

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent bbb49b3f344cf24e9bbd7eb7a7c40fea21be77eb
# Parent f19426f2fa9c634474e635bf33b86acea0518f6d
fix paths and references in sshd man pages
diff --git a/openssh-7.2p2/sshd.8 b/openssh-7.2p2/sshd.8

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 477d43e9a3889d36b58ff19cf3cb9583e1abf9ce
# Parent 980f301b2920c09b30577dd722546bca85d25fc1
# force PAM in defaullt install (this was removed from upstream in 3.8p1)
# bnc#46749
# --used to be called '-pam-fix2'

View File

@ -1,12 +1,12 @@
# HG changeset patch
# Parent 0dee2a3f80c2db73903388815fb4e311c8588a15
# Parent 3e1393b771d6430ae09ae30741a3b9b382e3e041
FIPS 140-2 compliance. Perform selftests on start and use only FIPS approved
algorithms.
diff --git a/openssh-7.2p2/Makefile.in b/openssh-7.2p2/Makefile.in
--- a/openssh-7.2p2/Makefile.in
+++ b/openssh-7.2p2/Makefile.in
@@ -87,17 +87,17 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
@@ -87,17 +87,18 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
ssh-pkcs11.o smult_curve25519_ref.o \
poly1305.o chacha.o cipher-chachapoly.o \
@ -16,7 +16,8 @@ diff --git a/openssh-7.2p2/Makefile.in b/openssh-7.2p2/Makefile.in
kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
- platform-pledge.o
+ platform-pledge.o fips.o
+ platform-pledge.o \
+ fips.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o mux.o

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent c2049622cf75dbab61a8f49b53a13dc1de6695fd
# Parent 84a6252b7ac18855cf188e5911bdf8a757d4460a
GSSAPI Key Exchange implementation
diff --git a/openssh-7.2p2/ChangeLog.gssapi b/openssh-7.2p2/ChangeLog.gssapi
@ -136,14 +136,14 @@ diff --git a/openssh-7.2p2/Makefile.in b/openssh-7.2p2/Makefile.in
- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
+ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o kexgssc.o \
+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o kexgsss.o \
platform-pledge.o fips.o
platform-pledge.o \
fips.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o mux.o
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
audit.o audit-bsm.o audit-linux.o platform.o \
sshpty.o sshlogin.o servconf.o serverloop.o \
diff --git a/openssh-7.2p2/auth-krb5.c b/openssh-7.2p2/auth-krb5.c
--- a/openssh-7.2p2/auth-krb5.c
+++ b/openssh-7.2p2/auth-krb5.c

View File

@ -0,0 +1,29 @@
# HG changeset patch
# Parent 605a6220fcc2c96e9196681fe480fab16b505ee1
Suggest command line for removal of offending keys from known_hosts file
diff --git a/openssh-7.2p2/sshconnect.c b/openssh-7.2p2/sshconnect.c
--- a/openssh-7.2p2/sshconnect.c
+++ b/openssh-7.2p2/sshconnect.c
@@ -1086,16 +1086,21 @@ check_host_key(char *hostname, struct so
ip_found->file, ip_found->line);
}
/* The host key has changed. */
warn_changed_key(host_key);
error("Add correct host key in %.100s to get rid of this message.",
user_hostfiles[0]);
error("Offending %s key in %s:%lu", key_type(host_found->key),
host_found->file, host_found->line);
+ error("You can use following command to remove all keys for this IP:");
+ if (host_found->file)
+ error("ssh-keygen -R %s -f %s", hostname, host_found->file);
+ else
+ error("ssh-keygen -R %s", hostname);
/*
* If strict host key checking is in use, the user will have
* to edit the key manually and we can only abort.
*/
if (options.strict_host_key_checking) {
error("%s host key for %.200s has changed and you have "
"requested strict checking.", type, host);

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent b5245fb016a3b83611d4b4ae0c1fe3423cadd6fe
# Parent f7ba2081f120bd1e44dbe68737c898f078725aab
# -- uset do be called '-xauthlocalhostname'
handle hostname changes when forwarding X

View File

@ -0,0 +1,33 @@
# HG changeset patch
# Parent cb9be7363a9f32133f0d105d515149dd77cc8cd3
Do not import PAM environment variables when using login, since it may have
security implications.
CVE-2015-8325
bsc#975865
Backport of upstream commit 85bdcd7c92fe7ff133bbc4e10a65c91810f88755
diff --git a/openssh-7.2p2/session.c b/openssh-7.2p2/session.c
--- a/openssh-7.2p2/session.c
+++ b/openssh-7.2p2/session.c
@@ -1351,17 +1351,17 @@ do_setup_env(Session *s, const char *she
child_set_env(&env, &envsize, "KRB5CCNAME",
s->authctxt->krb5_ccname);
#endif
#ifdef USE_PAM
/*
* Pull in any environment variables that may have
* been set by PAM.
*/
- if (options.use_pam) {
+ if (options.use_pam && !options.use_login) {
char **p;
p = fetch_pam_child_environment();
copy_environment(p, &env, &envsize);
free_pam_environment(p);
p = fetch_pam_environment();
copy_environment(p, &env, &envsize);

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 2ee086fa64dd40d0d50b13fa3a784717bfdd7e4b
# Parent 79c00e0f450c33b3f545ef104112b55186290e2c
# set uid for functions that use it to seek in lastlog and wtmp files
# bnc#18024 (was suse #3024)

2838
openssh-7.2p2-ldap.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
# HG changeset patch
# Parent e351203d2784230a3b56b8e3dd6955403ed10ca4
Limit accepted passwords length to prevent DoS by resource consumption
(via crypt() eating CPU cycles).
CVE-2016-6515
bsc#992533
upstream commit: fcd135c9df440bcd2d5870405ad3311743d78d97
diff --git a/openssh-7.2p2/auth-passwd.c b/openssh-7.2p2/auth-passwd.c
--- a/openssh-7.2p2/auth-passwd.c
+++ b/openssh-7.2p2/auth-passwd.c
@@ -61,16 +61,18 @@ extern ServerOptions options;
#ifdef HAVE_LOGIN_CAP
extern login_cap_t *lc;
#endif
#define DAY (24L * 60 * 60) /* 1 day in seconds */
#define TWO_WEEKS (2L * 7 * DAY) /* 2 weeks in seconds */
+#define MAX_PASSWORD_LEN 1024
+
void
disable_forwarding(void)
{
no_port_forwarding_flag = 1;
no_agent_forwarding_flag = 1;
no_x11_forwarding_flag = 1;
}
@@ -82,16 +84,19 @@ int
auth_password(Authctxt *authctxt, const char *password)
{
struct passwd * pw = authctxt->pw;
int result, ok = authctxt->valid;
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
static int expire_checked = 0;
#endif
+ if (strlen(password) > MAX_PASSWORD_LEN)
+ return 0;
+
#ifndef HAVE_CYGWIN
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
ok = 0;
#endif
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
#ifdef KRB5

View File

@ -0,0 +1,32 @@
# HG changeset patch
# Parent 295ae9c5f5da12d273f3b91e90145b449984a7dc
# HG changeset patch
# Parent b262fd34c8ecd55e93d457b3ca5593abce716856
# login-pam cannot handle the option terminator "--" as login from util-linux
# (this is correct behaviour considering its man-page), hence use option which
# selects the compile-time branch in the code which doesn't use the terminator
#
# bnc#833605
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
@@ -770,16 +770,18 @@ main() { if (NSVersionOfRunTimeLibrary("
AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
;;
*-*-linux*)
no_dev_ptmx=1
use_pie=auto
check_for_libcrypt_later=1
check_for_openpty_ctty_bug=1
+ AC_DEFINE([LOGIN_NO_ENDOPT], [1],
+ [Define if your login program cannot handle end of options ("--")])
AC_DEFINE([PAM_TTY_KLUDGE], [1],
[Work around problematic Linux PAM modules handling of PAM_TTY])
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"],
[String used in /etc/passwd to denote locked account])
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM],
[Define to whatever link() returns for "not supported"
if it doesn't return EOPNOTSUPP.])

View File

@ -0,0 +1,26 @@
# HG changeset patch
# Parent 7ce81a30bb196401c63782b646d8a6d511ddec4b
Do not write a PID file when not daemonizing (e.g. when running from systemd)
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
@@ -2107,17 +2107,17 @@ main(int ac, char **av)
signal(SIGCHLD, main_sigchld_handler);
signal(SIGTERM, sigterm_handler);
signal(SIGQUIT, sigterm_handler);
/*
* Write out the pid file after the sigterm handler
* is setup and the listen sockets are bound
*/
- if (options.pid_file != NULL && !debug_flag) {
+ if (!no_daemon_flag && options.pid_file != NULL && !debug_flag) {
FILE *f = fopen(options.pid_file, "w");
if (f == NULL) {
error("Couldn't create pid file \"%s\": %s",
options.pid_file, strerror(errno));
} else {
fprintf(f, "%ld\n", (long) getpid());
fclose(f);

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 5b217a9abc32fa963a125ae29c766c015db53bde
# Parent ac7f843cd7ebec413691d51823cdc67b611abdff
new option UsePAMCheckLocks to enforce checking for locked accounts while
UsePAM is used

View File

@ -0,0 +1,264 @@
# HG changeset patch
# Parent 323ac0fc20b1d5e9bf7037e020adfd760dd2d5f2
Prevent user enumeration through password processing timing
CVE-2016-6210
bsc#989363
non-PAM part:
upstream commit: 9286875a73b2de7736b5e50692739d314cd8d9dc
PAM part:
upstream commit: 283b97ff33ea2c641161950849931bd578de6946
diff --git a/openssh-7.2p2/auth-pam.c b/openssh-7.2p2/auth-pam.c
--- a/openssh-7.2p2/auth-pam.c
+++ b/openssh-7.2p2/auth-pam.c
@@ -227,17 +227,16 @@ static pam_handle_t *sshpam_handle = NUL
static int sshpam_err = 0;
static int sshpam_authenticated = 0;
static int sshpam_session_open = 0;
static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
-static char badpw[] = "\b\n\r\177INCORRECT";
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
static char **
pam_getenvlist(pam_handle_t *pamh)
{
/*
* XXX - If necessary, we can still support envrionment passing
@@ -807,22 +806,45 @@ sshpam_query(void *ctx, char **name, cha
free(msg);
ctxt->pam_done = -1;
return (-1);
}
}
return (-1);
}
+/*
+ * Returns a junk password of identical length to that the user supplied.
+ * Used to mitigate timing attacks against crypt(3)/PAM stacks that
+ * vary processing time in proportion to password length.
+ */
+static char *
+fake_password(const char *wire_password)
+{
+ const char junk[] = "\b\n\r\177INCORRECT";
+ char *ret = NULL;
+ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0;
+
+ if (l >= INT_MAX)
+ fatal("%s: password length too long: %zu", __func__, l);
+
+ ret = xmalloc(l + 1);
+ for (i = 0; i < l; i++)
+ ret[i] = junk[i % (sizeof(junk) - 1)];
+ ret[i] = '\0';
+ return ret;
+}
+
/* XXX - see also comment in auth-chall.c:verify_response */
static int
sshpam_respond(void *ctx, u_int num, char **resp)
{
Buffer buffer;
struct pam_ctxt *ctxt = ctx;
+ char *fake;
debug2("PAM: %s entering, %u responses", __func__, num);
switch (ctxt->pam_done) {
case 1:
sshpam_authenticated = 1;
return (0);
case 0:
break;
@@ -833,18 +855,21 @@ sshpam_respond(void *ctx, u_int num, cha
error("PAM: expected one response, got %u", num);
return (-1);
}
buffer_init(&buffer);
if (sshpam_authctxt->valid &&
(sshpam_authctxt->pw->pw_uid != 0 ||
options.permit_root_login == PERMIT_YES))
buffer_put_cstring(&buffer, *resp);
- else
- buffer_put_cstring(&buffer, badpw);
+ else {
+ fake = fake_password(*resp);
+ buffer_put_cstring(&buffer, fake);
+ free(fake);
+ }
if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
buffer_free(&buffer);
return (-1);
}
buffer_free(&buffer);
return (1);
}
@@ -1178,41 +1203,43 @@ static struct pam_conv passwd_conv = { s
/*
* Attempt password authentication via PAM
*/
int
sshpam_auth_passwd(Authctxt *authctxt, const char *password)
{
int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0);
+ char *fake = NULL;
if (!options.use_pam || sshpam_handle == NULL)
fatal("PAM: %s called when PAM disabled or failed to "
"initialise.", __func__);
sshpam_password = password;
sshpam_authctxt = authctxt;
/*
* If the user logging in is invalid, or is root but is not permitted
* by PermitRootLogin, use an invalid password to prevent leaking
* information via timing (eg if the PAM config has a delay on fail).
*/
if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
options.permit_root_login != PERMIT_YES))
- sshpam_password = badpw;
+ sshpam_password = fake = fake_password(password);
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&passwd_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_authenticate(sshpam_handle, flags);
sshpam_password = NULL;
+ free(fake);
if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
debug("PAM: password authentication accepted for %.100s",
authctxt->user);
return 1;
} else {
debug("PAM: password authentication failed for %.100s: %s",
authctxt->valid ? authctxt->user : "an illegal user",
pam_strerror(sshpam_handle, sshpam_err));
diff --git a/openssh-7.2p2/auth-passwd.c b/openssh-7.2p2/auth-passwd.c
--- a/openssh-7.2p2/auth-passwd.c
+++ b/openssh-7.2p2/auth-passwd.c
@@ -188,28 +188,32 @@ sys_auth_passwd(Authctxt *authctxt, cons
return (auth_close(as));
}
}
#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
{
struct passwd *pw = authctxt->pw;
- char *encrypted_password;
+ char *encrypted_password, *salt = NULL;
/* Just use the supplied fake password if authctxt is invalid */
char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
/* Check for users with no password. */
if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
return (1);
- /* Encrypt the candidate password using the proper salt. */
- encrypted_password = xcrypt(password,
- (pw_password[0] && pw_password[1]) ? pw_password : "xx");
+ /*
+ * Encrypt the candidate password using the proper salt, or pass a
+ * NULL and let xcrypt pick one.
+ */
+ if (authctxt->valid && pw_password[0] && pw_password[1])
+ salt = pw_password;
+ encrypted_password = xcrypt(password, salt);
/*
* Authentication is accepted if the encrypted passwords
* are identical.
*/
return encrypted_password != NULL &&
strcmp(encrypted_password, pw_password) == 0;
}
diff --git a/openssh-7.2p2/openbsd-compat/xcrypt.c b/openssh-7.2p2/openbsd-compat/xcrypt.c
--- a/openssh-7.2p2/openbsd-compat/xcrypt.c
+++ b/openssh-7.2p2/openbsd-compat/xcrypt.c
@@ -20,16 +20,17 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
+#include <string.h>
#include <unistd.h>
#include <pwd.h>
# if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE)
# include <crypt.h>
# endif
# ifdef __hpux
@@ -57,21 +58,54 @@
# include "md5crypt.h"
# endif
# if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT)
# include <openssl/des.h>
# define crypt DES_crypt
# endif
+/*
+ * Pick an appropriate password encryption type and salt for the running
+ * system.
+ */
+static const char *
+pick_salt(void)
+{
+ struct passwd *pw;
+ char *passwd, *p;
+ size_t typelen;
+ static char salt[32];
+
+ if (salt[0] != '\0')
+ return salt;
+ strlcpy(salt, "xx", sizeof(salt));
+ if ((pw = getpwuid(0)) == NULL)
+ return salt;
+ passwd = shadow_pw(pw);
+ if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL)
+ return salt; /* no $, DES */
+ typelen = p - passwd + 1;
+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
+ explicit_bzero(passwd, strlen(passwd));
+ return salt;
+}
+
char *
xcrypt(const char *password, const char *salt)
{
char *crypted;
+ /*
+ * If we don't have a salt we are encrypting a fake password for
+ * for timing purposes. Pick an appropriate salt.
+ */
+ if (salt == NULL)
+ salt = pick_salt();
+
# ifdef HAVE_MD5_PASSWORDS
if (is_md5_salt(salt))
crypted = md5_crypt(password, salt);
else
crypted = crypt(password, salt);
# elif defined(__hpux) && !defined(HAVE_SECUREWARE)
if (iscomsec())
crypted = bigcrypt(password, salt);

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 870f97b01b9ed00bac9ff0b8014a998434a6161b
# Parent 787bc0aab11e5a7b6510c8dbf771958743ca25b0
# use same lines naming as utempter (prevents problems with using different
# formats in ?tmp? files)
# --used to be called '-pts'

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 07998e381c9867b8b6f7b9205261811934bef40f
# Parent 18c2690afd988b9cb0fd0fa927d02cf5336dce9c
# --used to be called '-xauth'
try to remove xauth cookies on logout

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 3582dd949a01d8eca2816986ca4bc0c87c96bed3
# Parent c66097e5e31cd607bf2206b2da95730cce518b7a
add 'getuid' syscall to list of allowed ones to prevent the sanboxed thread
from being killed by the seccomp filter

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent d3afe6b01f8769713bde6c175e29a50412799e27
# Parent def949a57b8101691c79ecce6366cc7ae1685b07
Allow the stat() syscall for OpenSSL re-seed patch
(which causes OpenSSL use stat() on some file)

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 36ab4b78afea8cea4e3bed1291a49ba05cbb9115
# Parent 6ece65e11f754d75dd33d72b6f8e487a9d047f2e
# extended support for (re-)seeding the OpenSSL PRNG from /dev/random
# bnc#703221, FATE#312172

View File

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 505927e61d1a7848f0003adb3619cc726b8e5d15
# Parent dfcac093fca4d826a806b9d1c0bdc26e7ae8ee8e
send locales in default configuration
bnc#65747

View File

@ -0,0 +1,157 @@
# HG changeset patch
# Parent efa850d8312ceef224dbec0f2ae1002201afabd9
additional option for sftp-server to force file mode for new files
FATE#312774
http://lists.mindrot.org/pipermail/openssh-unix-dev/2010-November/029044.html
http://marc.info/?l=openssh-unix-dev&m=128896838930893
diff --git a/openssh-7.2p2/sftp-server.8 b/openssh-7.2p2/sftp-server.8
--- a/openssh-7.2p2/sftp-server.8
+++ b/openssh-7.2p2/sftp-server.8
@@ -33,16 +33,17 @@
.Bk -words
.Op Fl ehR
.Op Fl d Ar start_directory
.Op Fl f Ar log_facility
.Op Fl l Ar log_level
.Op Fl P Ar blacklisted_requests
.Op Fl p Ar whitelisted_requests
.Op Fl u Ar umask
+.Op Fl m Ar force_file_permissions
.Ek
.Nm
.Fl Q Ar protocol_feature
.Sh DESCRIPTION
.Nm
is a program that speaks the server side of SFTP protocol
to stdout and expects client requests from stdin.
.Nm
@@ -133,16 +134,20 @@ Places this instance of
into a read-only mode.
Attempts to open files for writing, as well as other operations that change
the state of the filesystem, will be denied.
.It Fl u Ar umask
Sets an explicit
.Xr umask 2
to be applied to newly-created files and directories, instead of the
user's default mask.
+.It Fl m Ar force_file_permissions
+Sets explicit file permissions to be applied to newly-created files instead
+of the default or client requested mode. Numeric values include:
+777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set.
.El
.Pp
On some systems,
.Nm
must be able to access
.Pa /dev/log
for logging to work, and use of
.Nm
diff --git a/openssh-7.2p2/sftp-server.c b/openssh-7.2p2/sftp-server.c
--- a/openssh-7.2p2/sftp-server.c
+++ b/openssh-7.2p2/sftp-server.c
@@ -73,16 +73,20 @@ static u_int version;
static int init_done;
/* Disable writes */
static int readonly;
/* Requests that are allowed/denied */
static char *request_whitelist, *request_blacklist;
+/* Force file permissions */
+int permforce = 0;
+long permforcemode;
+
/* portable attributes, etc. */
typedef struct Stat Stat;
struct Stat {
char *name;
char *long_name;
Attrib attrib;
};
@@ -687,16 +691,20 @@ process_open(u_int32_t id)
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
(r = decode_attrib(iqueue, &a)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
+ if (permforce == 1) {
+ mode = permforcemode;
+ (void)umask(0); /* so umask does not interfere */
+ }
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
((flags & O_ACCMODE) == O_WRONLY ||
(flags & O_ACCMODE) == O_RDWR)) {
verbose("Refusing open request in read-only mode");
status = SSH2_FX_PERMISSION_DENIED;
} else {
@@ -1489,17 +1497,18 @@ sftp_server_cleanup_exit(int i)
static void
sftp_server_usage(void)
{
extern char *__progname;
fprintf(stderr,
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
"[-l log_level]\n\t[-P blacklisted_requests] "
- "[-p whitelisted_requests] [-u umask]\n"
+ "[-p whitelisted_requests] [-u umask]\n\t"
+ "[-m force_file_permissions]\n"
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
}
int
sftp_server_main(int argc, char **argv, struct passwd *user_pw)
{
@@ -1515,17 +1524,17 @@ sftp_server_main(int argc, char **argv,
ssh_malloc_init(); /* must be called before any mallocs */
__progname = ssh_get_progname(argv[0]);
log_init(__progname, log_level, log_facility, log_stderr);
pw = pwcopy(user_pw);
while (!skipargs && (ch = getopt(argc, argv,
- "d:f:l:P:p:Q:u:cehR")) != -1) {
+ "d:f:l:P:p:Q:u:m:cehR")) != -1) {
switch (ch) {
case 'Q':
if (strcasecmp(optarg, "requests") != 0) {
fprintf(stderr, "Invalid query type\n");
exit(1);
}
for (i = 0; handlers[i].handler != NULL; i++)
printf("%s\n", handlers[i].name);
@@ -1575,16 +1584,23 @@ sftp_server_main(int argc, char **argv,
case 'u':
errno = 0;
mask = strtol(optarg, &cp, 8);
if (mask < 0 || mask > 0777 || *cp != '\0' ||
cp == optarg || (mask == 0 && errno != 0))
fatal("Invalid umask \"%s\"", optarg);
(void)umask((mode_t)mask);
break;
+ case 'm':
+ permforce = 1;
+ permforcemode = strtol(optarg, &cp, 8);
+ if (permforcemode < 0 || permforcemode > 0777 || *cp != '\0' ||
+ cp == optarg || (permforcemode == 0 && errno != 0))
+ fatal("Invalid umask \"%s\"", optarg);
+ break;
case 'h':
default:
sftp_server_usage();
}
}
log_init(__progname, log_level, log_facility, log_stderr);

View File

@ -0,0 +1,366 @@
# HG changeset patch
# Parent 9b1033f35a6cb173fbc13416065ed40c4b14e656
run sftp sessions inside a chroot
diff --git a/openssh-7.2p2/session.c b/openssh-7.2p2/session.c
--- a/openssh-7.2p2/session.c
+++ b/openssh-7.2p2/session.c
@@ -123,16 +123,18 @@ int do_exec(Session *, const char *);
void do_login(Session *, const char *);
#ifdef LOGIN_NEEDS_UTMPX
static void do_pre_login(Session *s);
#endif
void do_child(Session *, const char *);
void do_motd(void);
int check_quietlogin(Session *, const char *);
+int chroot_no_tree = 0;
+
static void do_authenticated1(Authctxt *);
static void do_authenticated2(Authctxt *);
static int session_pty_req(Session *);
/* import */
extern ServerOptions options;
extern char *__progname;
@@ -838,16 +840,21 @@ do_exec(Session *s, const char *command)
"subsystem '%.900s'", s->subsys);
} else if (command == NULL) {
snprintf(session_type, sizeof(session_type), "shell");
} else {
/* NB. we don't log unforced commands to preserve privacy */
snprintf(session_type, sizeof(session_type), "command");
}
+ if ((s->is_subsystem != SUBSYSTEM_INT_SFTP) && chroot_no_tree) {
+ logit("You aren't welcomed, go away!");
+ exit (1);
+ }
+
if (s->ttyfd != -1) {
tty = s->tty;
if (strncmp(tty, "/dev/", 5) == 0)
tty += 5;
}
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
@@ -1492,58 +1499,123 @@ do_nologin(struct passwd *pw)
while (fgets(buf, sizeof(buf), f))
fputs(buf, stderr);
fclose(f);
}
exit(254);
}
/*
+ * Test if filesystem is mounted nosuid and nodev
+ */
+
+static void
+test_nosuid (char * path, dev_t fs)
+{
+ FILE *f;
+ struct stat st;
+ char buf[4096], *s, *on, *mountpoint, *opt;
+ int nodev, nosuid;
+
+ if (!(f = popen ("/bin/mount", "r")))
+ fatal ("%s: popen(\"/bin/mount\", \"r\"): %s",
+ __func__, strerror (errno));
+ for (;;) {
+ s = fgets (buf, sizeof (buf), f);
+ if (ferror (f))
+ fatal ("%s: read from popen: %s", __func__,
+ strerror (errno));
+ if (!s) {
+ pclose (f);
+ fatal ("cannot find filesystem with the chroot directory");
+ }
+ (void) strtok (buf, " ");
+ on = strtok (NULL, " ");
+ if (strcmp (on, "on")) {
+ pclose (f);
+ fatal ("bad format of mount output");
+ }
+ mountpoint = strtok (NULL, " ");
+ if (memcmp (path, mountpoint, strlen (mountpoint)))
+ continue;
+ if (stat(mountpoint, &st) != 0) {
+ pclose (f);
+ fatal("%s: stat(\"%s\"): %s", __func__,
+ mountpoint, strerror(errno));
+ }
+ if (fs != st.st_dev)
+ continue;
+ nodev = nosuid = 0;
+ for (opt = strtok (NULL, "("); opt; opt = strtok (NULL, " ,)")) {
+ if (!strcmp (opt, "nodev"))
+ nodev = 1;
+ else if (!strcmp (opt, "nosuid"))
+ nosuid = 1;
+ else if (!strcmp (opt, "noexec"))
+ nosuid = 1;
+ if (nodev && nosuid) {
+ pclose (f);
+ return;
+ }
+ }
+ fatal ("chroot into directory without nodev and either noexec or nosuid");
+ }
+}
+
+/*
* Chroot into a directory after checking it for safety: all path components
* must be root-owned directories with strict permissions.
*/
static void
safely_chroot(const char *path, uid_t uid)
{
const char *cp;
char component[PATH_MAX];
struct stat st;
+ int last;
if (*path != '/')
fatal("chroot path does not begin at root");
if (strlen(path) >= sizeof(component))
fatal("chroot path too long");
/*
* Descend the path, checking that each component is a
* root-owned directory with strict permissions.
*/
for (cp = path; cp != NULL;) {
- if ((cp = strchr(cp, '/')) == NULL)
+ if (last = ((cp = strchr(cp, '/')) == NULL))
strlcpy(component, path, sizeof(component));
else {
cp++;
memcpy(component, path, cp - path);
component[cp - path] = '\0';
}
debug3("%s: checking '%s'", __func__, component);
if (stat(component, &st) != 0)
fatal("%s: stat(\"%s\"): %s", __func__,
component, strerror(errno));
- if (st.st_uid != 0 || (st.st_mode & 022) != 0)
+ if ((st.st_uid != 0 || (st.st_mode & 022) != 0) && !(last && st.st_uid == uid))
fatal("bad ownership or modes for chroot "
"directory %s\"%s\"",
cp == NULL ? "" : "component ", component);
if (!S_ISDIR(st.st_mode))
fatal("chroot path %s\"%s\" is not a directory",
cp == NULL ? "" : "component ", component);
}
+ setenv ("TZ", "/etc/localtime", 0);
+ tzset();
+
+ if (st.st_uid) {
+ test_nosuid(path, st.st_dev);
+ ++chroot_no_tree;
+ }
if (chdir(path) == -1)
fatal("Unable to chdir to chroot path \"%s\": "
"%s", path, strerror(errno));
if (chroot(path) == -1)
fatal("chroot(\"%s\"): %s", path, strerror(errno));
if (chdir("/") == -1)
fatal("%s: chdir(/) after chroot: %s",
diff --git a/openssh-7.2p2/sftp-chrootenv.h b/openssh-7.2p2/sftp-chrootenv.h
new file mode 100644
--- /dev/null
+++ b/openssh-7.2p2/sftp-chrootenv.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2009 Jan F Chadima. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CHROOTENV_H
+#define CHROOTENV_H
+
+extern int chroot_no_tree;
+
+#endif
+
diff --git a/openssh-7.2p2/sftp-common.c b/openssh-7.2p2/sftp-common.c
--- a/openssh-7.2p2/sftp-common.c
+++ b/openssh-7.2p2/sftp-common.c
@@ -43,16 +43,17 @@
#include "xmalloc.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "log.h"
#include "sftp.h"
#include "sftp-common.h"
+#include "sftp-chrootenv.h"
/* Clear contents of attributes structure */
void
attrib_clear(Attrib *a)
{
a->flags = 0;
a->size = 0;
a->uid = 0;
@@ -216,23 +217,23 @@ ls_file(const char *name, const struct s
int ulen, glen, sz = 0;
struct tm *ltime = localtime(&st->st_mtime);
char *user, *group;
char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
char sbuf[FMT_SCALED_STRSIZE];
time_t now;
strmode(st->st_mode, mode);
- if (!remote) {
+ if (!remote && !chroot_no_tree) {
user = user_from_uid(st->st_uid, 0);
} else {
snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
user = ubuf;
}
- if (!remote) {
+ if (!remote && !chroot_no_tree) {
group = group_from_gid(st->st_gid, 0);
} else {
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
group = gbuf;
}
if (ltime != NULL) {
now = time(NULL);
if (now - (365*24*60*60)/2 < st->st_mtime &&
diff --git a/openssh-7.2p2/sftp-server-main.c b/openssh-7.2p2/sftp-server-main.c
--- a/openssh-7.2p2/sftp-server-main.c
+++ b/openssh-7.2p2/sftp-server-main.c
@@ -17,22 +17,25 @@
#include "includes.h"
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
+//#include <time.h>
#include "log.h"
#include "sftp.h"
#include "misc.h"
#include "xmalloc.h"
+int chroot_no_tree = 0;
+
void
cleanup_exit(int i)
{
sftp_server_cleanup_exit(i);
}
int
main(int argc, char **argv)
diff --git a/openssh-7.2p2/sftp.c b/openssh-7.2p2/sftp.c
--- a/openssh-7.2p2/sftp.c
+++ b/openssh-7.2p2/sftp.c
@@ -112,16 +112,18 @@ struct complete_ctx {
char **remote_pathp;
};
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
extern char *__progname;
+int chroot_no_tree = 0;
+
/* Separators for interactive commands */
#define WHITESPACE " \t\r\n"
/* ls flags */
#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */
#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */
#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */
#define LS_NAME_SORT 0x0008 /* Sort by name (default) */
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
@@ -251,16 +251,24 @@ DESCRIPTION
directory on some operating systems (see sftp-server(8) for
details).
For safety, it is very important that the directory hierarchy be
prevented from modification by other processes on the system
(especially those outside the jail). Misconfiguration can lead
to unsafe environments which sshd(8) cannot detect.
+ In the special case when only sftp is used, not ssh nor scp, it
+ is possible to use ChrootDirectory %h or ChrootDirectory
+ /some/path/%u. The file system containing this directory must be
+ mounted with options nodev and either nosuid or noexec. The owner
+ of the directory should be the user. The ownership of the other
+ components of the path must fulfill the usual conditions. No adi-
+ tional files are required to be present in the directory.
+
The default is M-bM-^@M-^\noneM-bM-^@M-^], indicating not to chroot(2).
Ciphers
Specifies the ciphers allowed. Multiple ciphers must be comma-
separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character,
then the specified ciphers will be appended to the default set
instead of replacing them.
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
@@ -424,16 +424,27 @@ for details).
.Pp
For safety, it is very important that the directory hierarchy be
prevented from modification by other processes on the system (especially
those outside the jail).
Misconfiguration can lead to unsafe environments which
.Xr sshd 8
cannot detect.
.Pp
+In the special case when only sftp is used, not ssh nor scp,
+it is possible to use
+.Cm ChrootDirectory
+%h or
+.Cm ChrootDirectory
+/some/path/%u. The file system containing this directory must be
+mounted with options nodev and either nosuid or noexec. The owner of the
+directory should be the user. The ownership of the other components of the path
+must fulfill the usual conditions. No aditional files are required to be present
+in the directory.
+.Pp
The default is
.Dq none ,
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
Specifies the ciphers allowed.
Multiple ciphers must be comma-separated.
If the specified value begins with a

View File

@ -1,3 +1,43 @@
-------------------------------------------------------------------
Thu Sep 29 23:27:49 UTC 2016 - pcerny@suse.com
- remaining patches that were still missing
since the update to 7.2p2 (FATE#319675):
- allow X forwarding over IPv4 when IPv6 sockets is not available
[openssh-7.2p2-X_forward_with_disabled_ipv6.patch]
- do not write PID file when not daemonizing
[openssh-7.2p2-no_fork-no_pid_file.patch]
- use correct options when invoking login
[openssh-7.2p2-login_options.patch]
- helper application for retrieving users' public keys from
an LDAP server
[openssh-7.2p2-ldap.patch]
- allow forcing permissions over sftp
[openssh-7.2p2-sftp_force_permissions.patch]
- do not perform run-time checks for OpenSSL API/ABI change
[openssh-7.2p2-disable_openssl_abi_check.patch]
- suggest commands for cleaning known hosts file
[openssh-7.2p2-host_ident.patch]
- sftp home chroot patch
[openssh-7.2p2-sftp_homechroot.patch]
- ssh sessions auditing
[openssh-7.2p2-audit.patch]
- enable seccomp sandbox on additional architectures
[openssh-7.2p2-additional_seccomp_archs.patch]
- fix forwarding with IPv6 addresses in DISPLAY (bnc#847710)
[openssh-7.2p2-IPv6_X_forwarding.patch]
- ignore PAM environment when using login
(bsc#975865, CVE-2015-8325)
[openssh-7.2p2-ignore_PAM_with_UseLogin.patch]
- limit accepted password length (prevents possible DoS)
(bsc#992533, CVE-2016-6515)
[openssh-7.2p2-limit_password_length.patch]
- Prevent user enumeration through the timing of password
processing (bsc#989363, CVE-2016-6210)
[openssh-7.2p2-prevent_timing_user_enumeration.patch]
- Add auditing for PRNG re-seeding
[openssh-7.2p2-audit_seed_prng.patch]
-------------------------------------------------------------------
Fri Sep 16 12:45:11 UTC 2016 - pcerny@suse.com

View File

@ -53,11 +53,9 @@
%endif
%define sandbox_seccomp 0
%ifarch %ix86 x86_64
%if 0%{?suse_version} > 1220
%define sandbox_seccomp 1
%endif
%endif
%define _fwdir %{_sysconfdir}/sysconfig/SuSEfirewall2.d
%define _fwdefdir %{_fwdir}/services
@ -88,7 +86,10 @@ BuildRequires: pkgconfig(systemd)
%{?systemd_requires}
%endif
BuildRequires: tcpd-devel
PreReq: pwdutils %{insserv_prereq} %{fillup_prereq} coreutils
PreReq: pwdutils %{fillup_prereq} coreutils
%if ! %{uses_systemd}
PreReq: %{insserv_prereq}
%endif
Version: 7.2p2
Release: 0
Summary: Secure Shell Client and Server (Remote Login Program)
@ -128,6 +129,21 @@ Patch15: openssh-7.2p2-seccomp_stat.patch
Patch16: openssh-7.2p2-fips.patch
Patch17: openssh-7.2p2-seed-prng.patch
Patch18: openssh-7.2p2-gssapi_key_exchange.patch
Patch19: openssh-7.2p2-audit.patch
Patch20: openssh-7.2p2-audit_seed_prng.patch
Patch21: openssh-7.2p2-login_options.patch
Patch22: openssh-7.2p2-disable_openssl_abi_check.patch
Patch23: openssh-7.2p2-no_fork-no_pid_file.patch
Patch24: openssh-7.2p2-host_ident.patch
Patch25: openssh-7.2p2-sftp_homechroot.patch
Patch26: openssh-7.2p2-sftp_force_permissions.patch
Patch27: openssh-7.2p2-X_forward_with_disabled_ipv6.patch
Patch28: openssh-7.2p2-ldap.patch
Patch29: openssh-7.2p2-additional_seccomp_archs.patch
Patch30: openssh-7.2p2-IPv6_X_forwarding.patch
Patch31: openssh-7.2p2-ignore_PAM_with_UseLogin.patch
Patch32: openssh-7.2p2-prevent_timing_user_enumeration.patch
Patch33: openssh-7.2p2-limit_password_length.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Conflicts: nonfreessh
Recommends: audit
@ -198,14 +214,29 @@ FIPS140 CAVS tests related parts of the OpenSSH package
%patch16 -p2
%patch17 -p2
%patch18 -p2
%patch19 -p2
%patch20 -p2
%patch21 -p2
%patch22 -p2
%patch23 -p2
%patch24 -p2
%patch25 -p2
%patch26 -p2
%patch27 -p2
%patch28 -p2
%patch29 -p2
%patch30 -p2
%patch31 -p2
%patch32 -p2
%patch33 -p2
cp %{SOURCE3} %{SOURCE4} %{SOURCE11} .
%build
#### set libexec dir in the LDAP patch
###sed -i.libexec 's,@LIBEXECDIR@,%{_libexecdir}/ssh,' \
### $( grep -Rl @LIBEXECDIR@ \
### $( grep "^+++" %{PATCH40} | sed -r 's@^.+/([^/\t ]+).*$@\1@' )
### )
# set libexec dir in the LDAP patch
sed -i.libexec 's,@LIBEXECDIR@,%{_libexecdir}/ssh,' \
$( grep -Rl @LIBEXECDIR@ \
$( grep "^+++" %{PATCH28} | sed -r 's@^.+/([^/\t ]+).*$@\1@' )
)
autoreconf -fiv
%ifarch s390 s390x %sparc
@ -271,7 +302,7 @@ install -d -m 755 %{buildroot}%{_initddir}
%if %{uses_systemd}
install -m 0755 %{SOURCE1} .
install -D -m 0644 %{SOURCE10} %{buildroot}%{_unitdir}/sshd.service
ln -s /usr/sbin/service %{buildroot}%{_sbindir}/rcsshd
ln -s /sbin/service %{buildroot}%{_sbindir}/rcsshd
%else
install -D -m 0755 %{SOURCE1} %{buildroot}%{_initddir}/sshd
install -m 0644 %{SOURCE10} .
@ -376,7 +407,7 @@ rpm -q openssh-fips >& /dev/null && DISABLE_RESTART_ON_UPDATE=yes
%attr(0755,root,root) %{_bindir}/*
%attr(0755,root,root) %{_sbindir}/*
%attr(0755,root,root) %dir %{_libexecdir}/ssh
###%exclude %{_libexecdir}/ssh/ssh-ldap*
%exclude %{_libexecdir}/ssh/ssh-ldap*
%attr(0755,root,root) %{_libexecdir}/ssh/*
%attr(0444,root,root) %doc %{_mandir}/man1/*
%attr(0444,root,root) %doc %{_mandir}/man5/*
@ -395,10 +426,10 @@ rpm -q openssh-fips >& /dev/null && DISABLE_RESTART_ON_UPDATE=yes
%files helpers
%defattr(-,root,root)
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
###%verify(not mode) %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ldap.conf
%verify(not mode) %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ldap.conf
%attr(0755,root,root) %dir %{_libexecdir}/ssh
###%attr(0755,root,root) %{_libexecdir}/ssh/ssh-ldap*
###%doc HOWTO.ldap-keys openssh-lpk-openldap.schema openssh-lpk-sun.schema
%attr(0755,root,root) %{_libexecdir}/ssh/ssh-ldap*
%doc HOWTO.ldap-keys openssh-lpk-openldap.schema openssh-lpk-sun.schema
%files fips
%defattr(-,root,root)