mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 10:51:20 +03:00
shared/libcrypt-util: add fallback for crypt_ra()
Following the style in missing_syscall.h, we use a non-conflicting name for the function and use a macro to map to the real name to the replacement.
This commit is contained in:
parent
2b49f0ca83
commit
9de324c3c9
@ -69,6 +69,8 @@ int make_salt(char **ret) {
|
||||
|
||||
assert_cc(sizeof(table) == 64U + 1U);
|
||||
|
||||
log_debug("Generating fallback salt for hash prefix: $6$");
|
||||
|
||||
/* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
|
||||
r = genuine_random_bytes(raw, sizeof(raw), RANDOM_BLOCK);
|
||||
if (r < 0)
|
||||
@ -90,6 +92,47 @@ int make_salt(char **ret) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_CRYPT_RA
|
||||
# define CRYPT_RA_NAME "crypt_ra"
|
||||
#else
|
||||
# define CRYPT_RA_NAME "crypt_r"
|
||||
|
||||
/* Provide a poor man's fallback that uses a fixed size buffer. */
|
||||
|
||||
static char* systemd_crypt_ra(const char *phrase, const char *setting, void **data, int *size) {
|
||||
assert(data);
|
||||
assert(size);
|
||||
|
||||
/* We allocate the buffer because crypt(3) says: struct crypt_data may be quite large (32kB in this
|
||||
* implementation of libcrypt; over 128kB in some other implementations). This is large enough that
|
||||
* it may be unwise to allocate it on the stack. */
|
||||
|
||||
if (!*data) {
|
||||
*data = new0(struct crypt_data, 1);
|
||||
if (!*data) {
|
||||
errno = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*size = (int) (sizeof(struct crypt_data));
|
||||
}
|
||||
|
||||
char *t = crypt_r(phrase, setting, *data);
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
/* crypt_r may return a pointer to an invalid hashed password on error. Our callers expect NULL on
|
||||
* error, so let's just return that. */
|
||||
if (t[0] == '*')
|
||||
return NULL;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#define crypt_ra systemd_crypt_ra
|
||||
|
||||
#endif
|
||||
|
||||
int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret) {
|
||||
_cleanup_free_ char *salt = NULL;
|
||||
_cleanup_(erase_and_freep) void *_cd_data = NULL;
|
||||
@ -106,7 +149,7 @@ int hash_password_full(const char *password, void **cd_data, int *cd_size, char
|
||||
p = crypt_ra(password, salt, cd_data ?: &_cd_data, cd_size ?: &_cd_size);
|
||||
if (!p)
|
||||
return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)),
|
||||
"crypt_ra() failed: %m");
|
||||
CRYPT_RA_NAME "() failed: %m");
|
||||
|
||||
p = strdup(p);
|
||||
if (!p)
|
||||
|
Loading…
Reference in New Issue
Block a user