diff options
author | Alistair Delva <adelva@google.com> | 2020-08-20 16:14:23 -0700 |
---|---|---|
committer | Alistair Delva <adelva@google.com> | 2020-08-20 16:53:18 -0700 |
commit | d9da10d147d633fdb6ec65e17ff4b8447419d83e (patch) | |
tree | 8f93e8fdc2907f141e0924910bfec26669819f0b /openbsd-compat/xcrypt.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | ecb2c02d994b3e21994f31a70ff911667c262f1f (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.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; } |