diff --git a/src/shared/libcrypt-util.c b/src/shared/libcrypt-util.c index d19bcf1d8a..cb12cd65f3 100644 --- a/src/shared/libcrypt-util.c +++ b/src/shared/libcrypt-util.c @@ -8,6 +8,7 @@ #include "libcrypt-util.h" #include "log.h" #include "macro.h" +#include "memory-util.h" #include "missing_stdlib.h" #include "random-util.h" #include "string-util.h" @@ -75,21 +76,23 @@ int make_salt(char **ret) { #endif } -int hash_password(const char *password, char **ret) { +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; char *p; - struct crypt_data cd = {}; - int r; + int r, _cd_size = 0; + + assert(!!cd_data == !!cd_size); r = make_salt(&salt); if (r < 0) return log_debug_errno(r, "Failed to generate salt: %m"); errno = 0; - p = crypt_r(password, salt, &cd); + 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_r() failed: %m"); + "crypt_ra() failed: %m"); p = strdup(p); if (!p) diff --git a/src/shared/libcrypt-util.h b/src/shared/libcrypt-util.h index b10be2f7d2..2f8c352ab3 100644 --- a/src/shared/libcrypt-util.h +++ b/src/shared/libcrypt-util.h @@ -18,5 +18,8 @@ #include int make_salt(char **ret); -int hash_password(const char *password, char **ret); +int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret); +static inline int hash_password(const char *password, char **ret) { + return hash_password_full(password, NULL, NULL, ret); +} bool looks_like_hashed_password(const char *s); diff --git a/src/test/meson.build b/src/test/meson.build index 70450ea1c5..3e84e5a0d3 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -301,6 +301,10 @@ tests += [ [], []], + [['src/test/test-libcrypt-util.c'], + [], + []], + [['src/test/test-offline-passwd.c', 'src/shared/offline-passwd.c', 'src/shared/offline-passwd.h'], diff --git a/src/test/test-libcrypt-util.c b/src/test/test-libcrypt-util.c new file mode 100644 index 0000000000..94bd4172ea --- /dev/null +++ b/src/test/test-libcrypt-util.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "strv.h" +#include "tests.h" +#include "libcrypt-util.h" + +static void test_hash_password_full(void) { + log_info("/* %s */", __func__); + + _cleanup_free_ void *cd_data = NULL; + const char *i; + int cd_size = 0; + + log_info("sizeof(struct crypt_data): %zu bytes", sizeof(struct crypt_data)); + + for (unsigned c = 0; c < 2; c++) + FOREACH_STRING(i, "abc123", "password", "s3cr3t") { + _cleanup_free_ char *hashed; + + if (c == 0) + assert_se(hash_password_full(i, &cd_data, &cd_size, &hashed) == 0); + else + assert_se(hash_password_full(i, NULL, NULL, &hashed) == 0); + log_debug("\"%s\" → \"%s\"", i, hashed); + log_info("crypt_r[a] buffer size: %i bytes", cd_size); + } +} + +int main(int argc, char *argv[]) { + test_setup_logging(LOG_DEBUG); + + test_hash_password_full(); + + return 0; +}