1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #if HAVE_CRYPT_H
4 /* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be
5  * removed from glibc at some point. As part of the removal, defines for
6  * crypt(3) are dropped from unistd.h, and we must include crypt.h instead.
7  *
8  * Newer versions of glibc (v2.0+) already ship crypt.h with a definition
9  * of crypt(3) as well, so we simply include it if it is present.  MariaDB,
10  * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the
11  * same way since ages without any problems.
12  */
13 #  include <crypt.h>
14 #else
15 #  include <unistd.h>
16 #endif
17 
18 #include <errno.h>
19 #include <stdlib.h>
20 
21 #include "alloc-util.h"
22 #include "errno-util.h"
23 #include "libcrypt-util.h"
24 #include "log.h"
25 #include "macro.h"
26 #include "memory-util.h"
27 #include "missing_stdlib.h"
28 #include "random-util.h"
29 #include "string-util.h"
30 #include "strv.h"
31 
make_salt(char ** ret)32 int make_salt(char **ret) {
33 
34 #if HAVE_CRYPT_GENSALT_RA
35         const char *e;
36         char *salt;
37 
38         /* If we have crypt_gensalt_ra() we default to the "preferred method" (i.e. usually yescrypt).
39          * crypt_gensalt_ra() is usually provided by libxcrypt. */
40 
41         e = secure_getenv("SYSTEMD_CRYPT_PREFIX");
42         if (!e)
43 #if HAVE_CRYPT_PREFERRED_METHOD
44                 e = crypt_preferred_method();
45 #else
46                 e = "$6$";
47 #endif
48 
49         log_debug("Generating salt for hash prefix: %s", e);
50 
51         salt = crypt_gensalt_ra(e, 0, NULL, 0);
52         if (!salt)
53                 return -errno;
54 
55         *ret = salt;
56         return 0;
57 #else
58         /* If crypt_gensalt_ra() is not available, we use SHA512 and generate the salt on our own. */
59 
60         static const char table[] =
61                 "abcdefghijklmnopqrstuvwxyz"
62                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
63                 "0123456789"
64                 "./";
65 
66         uint8_t raw[16];
67         char *salt, *j;
68         size_t i;
69         int r;
70 
71         /* This is a bit like crypt_gensalt_ra(), but doesn't require libcrypt, and doesn't do anything but
72          * SHA512, i.e. is legacy-free and minimizes our deps. */
73 
74         assert_cc(sizeof(table) == 64U + 1U);
75 
76         log_debug("Generating fallback salt for hash prefix: $6$");
77 
78         /* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
79         r = genuine_random_bytes(raw, sizeof(raw), RANDOM_BLOCK);
80         if (r < 0)
81                 return r;
82 
83         salt = new(char, 3+sizeof(raw)+1+1);
84         if (!salt)
85                 return -ENOMEM;
86 
87         /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */
88         j = stpcpy(salt, "$6$");
89         for (i = 0; i < sizeof(raw); i++)
90                 j[i] = table[raw[i] & 63];
91         j[i++] = '$';
92         j[i] = 0;
93 
94         *ret = salt;
95         return 0;
96 #endif
97 }
98 
99 #if HAVE_CRYPT_RA
100 #  define CRYPT_RA_NAME "crypt_ra"
101 #else
102 #  define CRYPT_RA_NAME "crypt_r"
103 
104 /* Provide a poor man's fallback that uses a fixed size buffer. */
105 
systemd_crypt_ra(const char * phrase,const char * setting,void ** data,int * size)106 static char* systemd_crypt_ra(const char *phrase, const char *setting, void **data, int *size) {
107         assert(data);
108         assert(size);
109 
110         /* We allocate the buffer because crypt(3) says: struct crypt_data may be quite large (32kB in this
111          * implementation of libcrypt; over 128kB in some other implementations). This is large enough that
112          * it may be unwise to allocate it on the stack. */
113 
114         if (!*data) {
115                 *data = new0(struct crypt_data, 1);
116                 if (!*data) {
117                         errno = -ENOMEM;
118                         return NULL;
119                 }
120 
121                 *size = (int) (sizeof(struct crypt_data));
122         }
123 
124         char *t = crypt_r(phrase, setting, *data);
125         if (!t)
126                 return NULL;
127 
128         /* crypt_r may return a pointer to an invalid hashed password on error. Our callers expect NULL on
129          * error, so let's just return that. */
130         if (t[0] == '*')
131                 return NULL;
132 
133         return t;
134 }
135 
136 #define crypt_ra systemd_crypt_ra
137 
138 #endif
139 
hash_password_full(const char * password,void ** cd_data,int * cd_size,char ** ret)140 int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret) {
141         _cleanup_free_ char *salt = NULL;
142         _cleanup_(erase_and_freep) void *_cd_data = NULL;
143         char *p;
144         int r, _cd_size = 0;
145 
146         assert(!!cd_data == !!cd_size);
147 
148         r = make_salt(&salt);
149         if (r < 0)
150                 return log_debug_errno(r, "Failed to generate salt: %m");
151 
152         errno = 0;
153         p = crypt_ra(password, salt, cd_data ?: &_cd_data, cd_size ?: &_cd_size);
154         if (!p)
155                 return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)),
156                                        CRYPT_RA_NAME "() failed: %m");
157 
158         p = strdup(p);
159         if (!p)
160                 return -ENOMEM;
161 
162         *ret = p;
163         return 0;
164 }
165 
looks_like_hashed_password(const char * s)166 bool looks_like_hashed_password(const char *s) {
167         /* Returns false if the specified string is certainly not a hashed UNIX password. crypt(5) lists
168          * various hashing methods. We only reject (return false) strings which are documented to have
169          * different meanings.
170          *
171          * In particular, we allow locked passwords, i.e. strings starting with "!", including just "!",
172          * i.e. the locked empty password. See also fc58c0c7bf7e4f525b916e3e5be0de2307fef04e.
173          */
174         if (!s)
175                 return false;
176 
177         s += strspn(s, "!"); /* Skip (possibly duplicated) locking prefix */
178 
179         return !STR_IN_SET(s, "x", "*");
180 }
181 
test_password_one(const char * hashed_password,const char * password)182 int test_password_one(const char *hashed_password, const char *password) {
183         _cleanup_(erase_and_freep) void *cd_data = NULL;
184         int cd_size = 0;
185         const char *k;
186 
187         errno = 0;
188         k = crypt_ra(password, hashed_password, &cd_data, &cd_size);
189         if (!k) {
190                 if (errno == ENOMEM)
191                         return -ENOMEM;
192                 /* Unknown or unavailable hashing method or string too short */
193                 return 0;
194         }
195 
196         return streq(k, hashed_password);
197 }
198 
test_password_many(char ** hashed_password,const char * password)199 int test_password_many(char **hashed_password, const char *password) {
200         int r;
201 
202         STRV_FOREACH(hpw, hashed_password) {
203                 r = test_password_one(*hpw, password);
204                 if (r < 0)
205                         return r;
206                 if (r > 0)
207                         return true;
208         }
209 
210         return false;
211 }
212