summaryrefslogtreecommitdiff
path: root/openbsd-compat/xcrypt.c
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2020-08-20 16:14:23 -0700
committerAlistair Delva <adelva@google.com>2020-08-20 16:53:18 -0700
commitd9da10d147d633fdb6ec65e17ff4b8447419d83e (patch)
tree8f93e8fdc2907f141e0924910bfec26669819f0b /openbsd-compat/xcrypt.c
parent22246b08952d746a7cc5a292570636cf4277598f (diff)
parentecb2c02d994b3e21994f31a70ff911667c262f1f (diff)
Merge upstream-master into master
Commit ecb2c02d994b3e21994f31a70ff911667c262f1f upstream This nearly (but not quite) corresponds to V_8_3_P1; subsequent cherry-picks will correct this. Bug: 162492243 Change-Id: I3c079d86435b7c25aefff4538dc89a3002b1e25b
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;
}