diff options
Diffstat (limited to 'openbsd-compat/xcrypt.c')
-rw-r--r-- | openbsd-compat/xcrypt.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c index 8577cbd8a..cf6a9b99f 100644 --- a/openbsd-compat/xcrypt.c +++ b/openbsd-compat/xcrypt.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | 26 | ||
27 | #include <sys/types.h> | 27 | #include <sys/types.h> |
28 | #include <string.h> | ||
28 | #include <unistd.h> | 29 | #include <unistd.h> |
29 | #include <pwd.h> | 30 | #include <pwd.h> |
30 | 31 | ||
@@ -62,11 +63,50 @@ | |||
62 | # define crypt DES_crypt | 63 | # define crypt DES_crypt |
63 | # endif | 64 | # endif |
64 | 65 | ||
66 | /* | ||
67 | * Pick an appropriate password encryption type and salt for the running | ||
68 | * system by searching through accounts until we find one that has a valid | ||
69 | * salt. Usually this will be root unless the root account is locked out. | ||
70 | * If we don't find one we return a traditional DES-based salt. | ||
71 | */ | ||
72 | static const char * | ||
73 | pick_salt(void) | ||
74 | { | ||
75 | struct passwd *pw; | ||
76 | char *passwd, *p; | ||
77 | size_t typelen; | ||
78 | static char salt[32]; | ||
79 | |||
80 | if (salt[0] != '\0') | ||
81 | return salt; | ||
82 | strlcpy(salt, "xx", sizeof(salt)); | ||
83 | setpwent(); | ||
84 | while ((pw = getpwent()) != NULL) { | ||
85 | passwd = shadow_pw(pw); | ||
86 | if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) { | ||
87 | typelen = p - passwd + 1; | ||
88 | strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); | ||
89 | explicit_bzero(passwd, strlen(passwd)); | ||
90 | goto out; | ||
91 | } | ||
92 | } | ||
93 | out: | ||
94 | endpwent(); | ||
95 | return salt; | ||
96 | } | ||
97 | |||
65 | char * | 98 | char * |
66 | xcrypt(const char *password, const char *salt) | 99 | xcrypt(const char *password, const char *salt) |
67 | { | 100 | { |
68 | char *crypted; | 101 | char *crypted; |
69 | 102 | ||
103 | /* | ||
104 | * If we don't have a salt we are encrypting a fake password for | ||
105 | * for timing purposes. Pick an appropriate salt. | ||
106 | */ | ||
107 | if (salt == NULL) | ||
108 | salt = pick_salt(); | ||
109 | |||
70 | # ifdef HAVE_MD5_PASSWORDS | 110 | # ifdef HAVE_MD5_PASSWORDS |
71 | if (is_md5_salt(salt)) | 111 | if (is_md5_salt(salt)) |
72 | crypted = md5_crypt(password, salt); | 112 | crypted = md5_crypt(password, salt); |