summary refs log tree commit diff
path: root/gnu/packages/patches/openssh-CVE-2016-6210-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/openssh-CVE-2016-6210-1.patch')
-rw-r--r--gnu/packages/patches/openssh-CVE-2016-6210-1.patch114
1 files changed, 114 insertions, 0 deletions
diff --git a/gnu/packages/patches/openssh-CVE-2016-6210-1.patch b/gnu/packages/patches/openssh-CVE-2016-6210-1.patch
new file mode 100644
index 0000000000..9b46ec12a9
--- /dev/null
+++ b/gnu/packages/patches/openssh-CVE-2016-6210-1.patch
@@ -0,0 +1,114 @@
+From e5ef9d3942cebda819a6fd81647b51c8d87d23df Mon Sep 17 00:00:00 2001
+From: Darren Tucker <dtucker@zip.com.au>
+Date: Fri, 15 Jul 2016 13:32:45 +1000
+Subject: Determine appropriate salt for invalid users.
+
+When sshd is processing a non-PAM login for a non-existent user it uses
+the string from the fakepw structure as the salt for crypt(3)ing the
+password supplied by the client.  That string has a Blowfish prefix, so on
+systems that don't understand that crypt will fail fast due to an invalid
+salt, and even on those that do it may have significantly different timing
+from the hash methods used for real accounts (eg sha512).  This allows
+user enumeration by, eg, sending large password strings.  This was noted
+by EddieEzra.Harari at verint.com (CVE-2016-6210).
+
+To mitigate, use the same hash algorithm that root uses for hashing
+passwords for users that do not exist on the system.  ok djm@
+
+Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=9286875a73b2de7736b5e50692739d314cd8d9dc
+Bug-Debian: https://bugs.debian.org/831902
+Last-Update: 2016-07-22
+
+Patch-Name: CVE-2016-6210-1.patch
+---
+ auth-passwd.c           | 12 ++++++++----
+ openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/auth-passwd.c b/auth-passwd.c
+index 63ccf3c..530b5d4 100644
+--- a/auth-passwd.c
++++ b/auth-passwd.c
+@@ -193,7 +193,7 @@ 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;
+@@ -202,9 +202,13 @@ sys_auth_passwd(Authctxt *authctxt, const char *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
+diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
+index 8577cbd..8913bb8 100644
+--- a/openbsd-compat/xcrypt.c
++++ b/openbsd-compat/xcrypt.c
+@@ -25,6 +25,7 @@
+ #include "includes.h"
+ 
+ #include <sys/types.h>
++#include <string.h>
+ #include <unistd.h>
+ #include <pwd.h>
+ 
+@@ -62,11 +63,44 @@
+ #  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);