summaryrefslogtreecommitdiff
path: root/openbsd-compat/xcrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/xcrypt.c')
-rw-r--r--openbsd-compat/xcrypt.c40
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 */
72static const char *
73pick_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
65char * 98char *
66xcrypt(const char *password, const char *salt) 99xcrypt(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);