[openssh-commits] [openssh] 01/04: avoid password authn bypass

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Nov 5 20:00:08 AEDT 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 4353fdc43ef646c43a8dda7025cc1a898caf1482
Author: Damien Miller <djm at mindrot.org>
AuthorDate: Thu Nov 5 08:18:18 2026 +1100

    avoid password authn bypass
    
    This bypass affects some configurations and runtime configurations.
    We do not consider the root cause to be within OpenSSH but we are
    well equipped to avoid it.
---
 auth-passwd.c            | 17 +++++++++++++----
 openbsd-compat/port-uw.c | 16 ++++++++--------
 openbsd-compat/xcrypt.c  | 18 +++++++++++++-----
 3 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/auth-passwd.c b/auth-passwd.c
index 37dba168c..5406e2d55 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -50,6 +50,7 @@
 #include "ssherr.h"
 #include "log.h"
 #include "misc.h"
+#include "xmalloc.h"
 #include "servconf.h"
 #include "sshkey.h"
 #include "hostfile.h"
@@ -67,6 +68,7 @@ extern login_cap_t *lc;
 #define DAY		(24L * 60 * 60) /* 1 day in seconds */
 #define TWO_WEEKS	(2L * 7 * DAY)	/* 2 weeks in seconds */
 
+#define MIN_PASSWORD_HASH_LEN	4
 #define MAX_PASSWORD_LEN	1024
 
 /*
@@ -198,16 +200,20 @@ sys_auth_passwd(struct ssh *ssh, const char *password)
 	Authctxt *authctxt = ssh->authctxt;
 	struct passwd *pw = authctxt->pw;
 	char *encrypted_password, *salt = NULL;
+	int ret;
 
 	/* Just use the supplied fake password if authctxt is invalid */
-	char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
+	char *pw_password = authctxt->valid ?
+	    shadow_pw(pw) : xstrdup(pw->pw_passwd);
 
 	if (pw_password == NULL)
 		return 0;
 
 	/* Check for users with no password. */
-	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
-		return (1);
+	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) {
+		free(pw_password);
+		return 1;
+	}
 
 	/*
 	 * Encrypt the candidate password using the proper salt, or pass a
@@ -221,7 +227,10 @@ sys_auth_passwd(struct ssh *ssh, const char *password)
 	 * Authentication is accepted if the encrypted passwords
 	 * are identical.
 	 */
-	return encrypted_password != NULL &&
+	ret = encrypted_password != NULL &&
+	    strlen(pw_password) >= MIN_PASSWORD_HASH_LEN &&
 	    strcmp(encrypted_password, pw_password) == 0;
+	freezero(pw_password, strlen(pw_password));
+	return ret;
 }
 #endif
diff --git a/openbsd-compat/port-uw.c b/openbsd-compat/port-uw.c
index 074f80c8d..5c50ffa0f 100644
--- a/openbsd-compat/port-uw.c
+++ b/openbsd-compat/port-uw.c
@@ -58,14 +58,17 @@ sys_auth_passwd(struct ssh *ssh, const char *password)
 	int result;
 
 	/* Just use the supplied fake password if authctxt is invalid */
-	char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
+	char *pw_password = authctxt->valid ?
+	    shadow_pw(pw) : xstrdup(pw->pw_passwd);
 
 	if (pw_password == NULL)
 		return 0;
 
 	/* Check for users with no password. */
-	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
-		return (1);
+	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) {
+		free(pw_password);
+		return 1;
+	}
 
 	/* Encrypt the candidate password using the proper salt. */
 	salt = (pw_password[0] && pw_password[1]) ? pw_password : "xx";
@@ -83,11 +86,8 @@ sys_auth_passwd(struct ssh *ssh, const char *password)
 #endif /* UNIXWARE_LONG_PASSWORDS */
 		result = (strcmp(xcrypt(password, salt), pw_password) == 0);
 
-#ifdef USE_LIBIAF
-	if (authctxt->valid)
-		free(pw_password);
-#endif
-	return(result);
+	freezero(pw_password, strlen(pw_password));
+	return result;
 }
 
 #ifdef UNIXWARE_LONG_PASSWORDS
diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
index 4e0d0d644..80b13a5c4 100644
--- a/openbsd-compat/xcrypt.c
+++ b/openbsd-compat/xcrypt.c
@@ -25,6 +25,8 @@
 #include "includes.h"
 
 #include <sys/types.h>
+#include <stdarg.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <pwd.h>
@@ -59,6 +61,8 @@
 #  define crypt DES_crypt
 # endif
 
+#include "xmalloc.h"
+
 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
 
 /*
@@ -71,7 +75,7 @@ static const char *
 pick_salt(void)
 {
 	struct passwd *pw;
-	char *passwd, *p;
+	char *passwd = NULL, *p;
 	size_t typelen;
 	static char salt[32];
 
@@ -80,6 +84,8 @@ pick_salt(void)
 	strlcpy(salt, "xx", sizeof(salt));
 	setpwent();
 	while ((pw = getpwent()) != NULL) {
+		if (passwd != NULL)
+			freezero(passwd, strlen(passwd));
 		if ((passwd = shadow_pw(pw)) == NULL)
 			continue;
 		if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) {
@@ -97,6 +103,8 @@ pick_salt(void)
 		}
 	}
  out:
+	if (passwd != NULL)
+		freezero(passwd, strlen(passwd));
 	endpwent();
 	return salt;
 }
@@ -129,9 +137,8 @@ xcrypt(const char *password, const char *salt)
 
 /*
  * Handle shadowed password systems in a cleaner way for portable
- * version.
+ * version. Caller must free returned value.
  */
-
 char *
 shadow_pw(struct passwd *pw)
 {
@@ -145,7 +152,8 @@ shadow_pw(struct passwd *pw)
 # endif
 
 #ifdef USE_LIBIAF
-	return(get_iaf_password(pw));
+	pw_password = get_iaf_password(pw);
+	return pw_password == NULL ? NULL : xstrdup(pw_password);
 #endif
 
 # if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
@@ -159,5 +167,5 @@ shadow_pw(struct passwd *pw)
 		pw_password = spw->ufld.fd_encrypt;
 # endif
 
-	return pw_password;
+	return pw_password == NULL ? NULL : xstrdup(pw_password);
 }

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list