diff options
author | Alistair Delva <adelva@google.com> | 2020-08-21 00:00:13 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-08-21 00:00:13 +0000 |
commit | ed358b3546c776c1c677fd88eb8f716cf6187510 (patch) | |
tree | 3c6134bcb2cda4b9dccc57b4a8b997a945aab62d /openbsd-compat/xcrypt.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | 44a1065de8a58c51a021243a28bfa01e87822e4f (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.c | 63 |
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; } |