[openssh-commits] [openssh] 02/04: avoid password authn bypass
git+noreply at mindrot.org
git+noreply at mindrot.org
Thu Nov 5 20:00:04 AEDT 2026
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch V_10_6
in repository openssh.
commit 90f9c2f7330b3b417b7d6202cd393ef3c226722c
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 a9d768891..fb3b22a05 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
/*
@@ -194,16 +196,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
@@ -217,7 +223,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 9cded6684..2721b3342 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) {
@@ -90,6 +96,8 @@ pick_salt(void)
}
}
out:
+ if (passwd != NULL)
+ freezero(passwd, strlen(passwd));
endpwent();
return salt;
}
@@ -122,9 +130,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)
{
@@ -138,7 +145,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)
@@ -152,5 +160,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