]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
42f3b2f9 | 2 | |
83764f8d ZJS |
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 | ||
42f3b2f9 LP |
18 | #include <errno.h> |
19 | #include <stdlib.h> | |
20 | ||
21 | #include "alloc-util.h" | |
0e98d17e | 22 | #include "errno-util.h" |
42f3b2f9 LP |
23 | #include "libcrypt-util.h" |
24 | #include "log.h" | |
25 | #include "macro.h" | |
a937ce2d | 26 | #include "memory-util.h" |
42f3b2f9 LP |
27 | #include "missing_stdlib.h" |
28 | #include "random-util.h" | |
29 | #include "string-util.h" | |
30 | #include "strv.h" | |
31 | ||
32 | int make_salt(char **ret) { | |
33 | ||
2b49f0ca | 34 | #if HAVE_CRYPT_GENSALT_RA |
42f3b2f9 LP |
35 | const char *e; |
36 | char *salt; | |
37 | ||
2b49f0ca ZJS |
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. */ | |
42f3b2f9 LP |
40 | |
41 | e = secure_getenv("SYSTEMD_CRYPT_PREFIX"); | |
42 | if (!e) | |
feee7f62 | 43 | #if HAVE_CRYPT_PREFERRED_METHOD |
42f3b2f9 | 44 | e = crypt_preferred_method(); |
feee7f62 LB |
45 | #else |
46 | e = "$6$"; | |
47 | #endif | |
42f3b2f9 LP |
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 | |
2b49f0ca | 58 | /* If crypt_gensalt_ra() is not available, we use SHA512 and generate the salt on our own. */ |
42f3b2f9 LP |
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 | ||
9de324c3 ZJS |
76 | log_debug("Generating fallback salt for hash prefix: $6$"); |
77 | ||
42f3b2f9 LP |
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 | } | |
64aa2622 | 98 | |
9de324c3 ZJS |
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 | ||
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 | ||
a937ce2d | 140 | int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret) { |
0e98d17e | 141 | _cleanup_free_ char *salt = NULL; |
a937ce2d | 142 | _cleanup_(erase_and_freep) void *_cd_data = NULL; |
0e98d17e | 143 | char *p; |
a937ce2d ZJS |
144 | int r, _cd_size = 0; |
145 | ||
146 | assert(!!cd_data == !!cd_size); | |
0e98d17e ZJS |
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; | |
a937ce2d | 153 | p = crypt_ra(password, salt, cd_data ?: &_cd_data, cd_size ?: &_cd_size); |
0e98d17e ZJS |
154 | if (!p) |
155 | return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)), | |
9de324c3 | 156 | CRYPT_RA_NAME "() failed: %m"); |
0e98d17e ZJS |
157 | |
158 | p = strdup(p); | |
159 | if (!p) | |
160 | return -ENOMEM; | |
161 | ||
162 | *ret = p; | |
163 | return 0; | |
164 | } | |
165 | ||
8f796e40 ZJS |
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) | |
64aa2622 LP |
175 | return false; |
176 | ||
8f796e40 ZJS |
177 | s += strspn(s, "!"); /* Skip (possibly duplicated) locking prefix */ |
178 | ||
179 | return !STR_IN_SET(s, "x", "*"); | |
64aa2622 | 180 | } |
2ae297fe ZJS |
181 | |
182 | int test_password_one(const char *hashed_password, const char *password) { | |
999b49c8 ZJS |
183 | _cleanup_(erase_and_freep) void *cd_data = NULL; |
184 | int cd_size = 0; | |
2ae297fe | 185 | const char *k; |
2ae297fe ZJS |
186 | |
187 | errno = 0; | |
999b49c8 | 188 | k = crypt_ra(password, hashed_password, &cd_data, &cd_size); |
35e22827 ZJS |
189 | if (!k) { |
190 | if (errno == ENOMEM) | |
191 | return -ENOMEM; | |
192 | /* Unknown or unavailable hashing method or string too short */ | |
193 | return 0; | |
194 | } | |
2ae297fe | 195 | |
999b49c8 | 196 | return streq(k, hashed_password); |
2ae297fe ZJS |
197 | } |
198 | ||
199 | int test_password_many(char **hashed_password, const char *password) { | |
2ae297fe ZJS |
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 | } |