summaryrefslogtreecommitdiff
path: root/openbsd-compat/xcrypt.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2016-07-22 14:09:29 +0100
committerColin Watson <cjwatson@debian.org>2016-07-22 14:11:33 +0100
commit5ebf9c1d19aa0d9d20781bab05e9d73d8addecb3 (patch)
tree7d48ac2d5442eff8ca63a0dd6938651e05b9c7c3 /openbsd-compat/xcrypt.c
parent79139a04a0183cd47f3e837fa76fe5d51e62fcc9 (diff)
parentabde8dda29c2db2405d6fbca2fe022430e2c1177 (diff)
CVE-2016-6210: Mitigate user enumeration via covert timing channel.
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);