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.
This commit is contained in:
Damien Miller committed 2026-11-05 08:57:56 +11:00
1 parent 3c6ec4c637
commit 4353fdc43e
3 files changed
+34 -17

No files matched your search

+13 -4
View File
@@ -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
+8 -8
View File
@@ -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
+13 -5
View File
@@ -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);
}