summaryrefslogtreecommitdiff
path: root/openbsd-compat/xcrypt.c
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2020-08-21 00:00:13 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-08-21 00:00:13 +0000
commited358b3546c776c1c677fd88eb8f716cf6187510 (patch)
tree3c6134bcb2cda4b9dccc57b4a8b997a945aab62d /openbsd-compat/xcrypt.c
parent22246b08952d746a7cc5a292570636cf4277598f (diff)
parent44a1065de8a58c51a021243a28bfa01e87822e4f (diff)
Merge changes I934c73d4,I28cdc9a0,I9e734da9,I3c079d86
* changes: UPSTREAM: depend UPSTREAM: upstream: avoid possible NULL deref; from Pedro Martelletto Revert "upstream: fix compilation with DEBUG_KEXDH; bz#3160 ok dtucker@" Merge upstream-master into master
Diffstat (limited to 'openbsd-compat/xcrypt.c')
-rw-r--r--openbsd-compat/xcrypt.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
index 8577cbd8..360b187a 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>
@@ -41,7 +42,7 @@
# include <sys/security.h>
# include <sys/audit.h>
# include <prot.h>
-# endif
+# endif
# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
# include <shadow.h>
@@ -62,26 +63,66 @@
# define crypt DES_crypt
# endif
+/*
+ * Pick an appropriate password encryption type and salt for the running
+ * system by searching through accounts until we find one that has a valid
+ * salt. Usually this will be root unless the root account is locked out.
+ * If we don't find one we return a traditional DES-based salt.
+ */
+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));
+ setpwent();
+ while ((pw = getpwent()) != NULL) {
+ if ((passwd = shadow_pw(pw)) == NULL)
+ continue;
+ if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) {
+ typelen = p - passwd + 1;
+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
+ explicit_bzero(passwd, strlen(passwd));
+ goto out;
+ }
+ }
+ out:
+ endpwent();
+ 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);
+ 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);
- else
- crypted = crypt(password, salt);
+ crypted = bigcrypt(password, salt);
+ else
+ crypted = crypt(password, salt);
# elif defined(HAVE_SECUREWARE)
- crypted = bigcrypt(password, salt);
+ crypted = bigcrypt(password, salt);
# else
- crypted = crypt(password, salt);
-# endif
+ crypted = crypt(password, salt);
+# endif
return crypted;
}