103 lines
4.5 KiB
C
103 lines
4.5 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#if HAVE_CRYPT_H
|
|
# include <crypt.h>
|
|
#else
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
#include "strv.h"
|
|
#include "tests.h"
|
|
#include "libcrypt-util.h"
|
|
|
|
static int test_hash_password(void) {
|
|
log_info("/* %s */", __func__);
|
|
|
|
/* As a warmup exercise, check if we can hash passwords. */
|
|
|
|
bool have_sane_hash = false;
|
|
const char *hash;
|
|
|
|
FOREACH_STRING(hash,
|
|
"ew3bU1.hoKk4o",
|
|
"$1$gc5rWpTB$wK1aul1PyBn9AX1z93stk1",
|
|
"$2b$12$BlqcGkB/7BFvNMXKGxDea.5/8D6FTny.cbNcHW/tqcrcyo6ZJd8u2",
|
|
"$5$lGhDrcrao9zb5oIK$05KlOVG3ocknx/ThreqXE/gk.XzFFBMTksc4t2CPDUD",
|
|
"$6$c7wB/3GiRk0VHf7e$zXJ7hN0aLZapE.iO4mn/oHu6.prsXTUG/5k1AxpgR85ELolyAcaIGRgzfwJs3isTChMDBjnthZyaMCfCNxo9I.",
|
|
"$y$j9T$$9cKOWsAm4m97WiYk61lPPibZpy3oaGPIbsL4koRe/XD") {
|
|
int b;
|
|
|
|
b = test_password_one(hash, "ppp");
|
|
log_info("%s: %s", hash, yes_no(b));
|
|
#if defined(XCRYPT_VERSION_MAJOR)
|
|
/* xcrypt is supposed to always implement all methods. */
|
|
assert_se(b);
|
|
#endif
|
|
|
|
if (b && IN_SET(hash[1], '6', 'y'))
|
|
have_sane_hash = true;
|
|
}
|
|
|
|
return have_sane_hash;
|
|
}
|
|
|
|
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", "h⸿sło") {
|
|
_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);
|
|
|
|
assert_se(test_password_one(hashed, i) == true);
|
|
assert_se(test_password_one(i, hashed) <= 0); /* We get an error for non-utf8 */
|
|
assert_se(test_password_one(hashed, "foobar") == false);
|
|
assert_se(test_password_many(STRV_MAKE(hashed), i) == true);
|
|
assert_se(test_password_many(STRV_MAKE(hashed), "foobar") == false);
|
|
assert_se(test_password_many(STRV_MAKE(hashed, hashed, hashed), "foobar") == false);
|
|
assert_se(test_password_many(STRV_MAKE("$y$j9T$dlCXwkX0GC5L6B8Gf.4PN/$VCyEH",
|
|
hashed,
|
|
"$y$j9T$SAayASazWZIQeJd9AS02m/$"),
|
|
i) == true);
|
|
assert_se(test_password_many(STRV_MAKE("$W$j9T$dlCXwkX0GC5L6B8Gf.4PN/$VCyEH", /* no such method exists... */
|
|
hashed,
|
|
"$y$j9T$SAayASazWZIQeJd9AS02m/$"),
|
|
i) == true);
|
|
assert_se(test_password_many(STRV_MAKE("$y$j9T$dlCXwkX0GC5L6B8Gf.4PN/$VCyEH",
|
|
hashed,
|
|
"$y$j9T$SAayASazWZIQeJd9AS02m/$"),
|
|
"") == false);
|
|
assert_se(test_password_many(STRV_MAKE("$W$j9T$dlCXwkX0GC5L6B8Gf.4PN/$VCyEH", /* no such method exists... */
|
|
hashed,
|
|
"$y$j9T$SAayASazWZIQeJd9AS02m/$"),
|
|
"") == false);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
test_setup_logging(LOG_DEBUG);
|
|
|
|
#if defined(__powerpc__) && !defined(XCRYPT_VERSION_MAJOR)
|
|
return log_tests_skipped("crypt_r() causes a buffer overflow on ppc64el, see https://github.com/systemd/systemd/pull/16981#issuecomment-691203787");
|
|
#endif
|
|
|
|
if (!test_hash_password())
|
|
return log_tests_skipped("crypt doesn't support yescrypt or sha512crypt");
|
|
|
|
test_hash_password_full();
|
|
|
|
return 0;
|
|
}
|