From 7baf10a7be8bd1bad36d333f7013ed5c2b7b7d13 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Aug 2020 10:37:44 +0200 Subject: [PATCH] firstboot: hook up with libpwquality --- src/firstboot/firstboot.c | 10 ++++++++++ src/shared/pwquality-util.c | 33 +++++++++++++++++++++++++++++++++ src/shared/pwquality-util.h | 7 +++++++ 3 files changed, 50 insertions(+) diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index e4c7a2d374..cf1ec28dd5 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -28,6 +28,7 @@ #include "path-util.h" #include "pretty-print.h" #include "proc-cmdline.h" +#include "pwquality-util.h" #include "random-util.h" #include "string-util.h" #include "strv.h" @@ -568,8 +569,11 @@ static int prompt_root_password(void) { msg1 = strjoina(special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET), " Please enter a new root password (empty to skip):"); msg2 = strjoina(special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET), " Please enter new root password again:"); + suggest_passwords(); + for (;;) { _cleanup_strv_free_erase_ char **a = NULL, **b = NULL; + _cleanup_free_ char *error = NULL; r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a); if (r < 0) @@ -583,6 +587,12 @@ static int prompt_root_password(void) { break; } + r = quality_check_password(*a, "root", &error); + if (r < 0) + return log_error_errno(r, "Failed to check quality of password: %m"); + if (r == 0) + log_warning("Password is weak, accepting anyway: %s", error); + r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b); if (r < 0) return log_error_errno(r, "Failed to query root password: %m"); diff --git a/src/shared/pwquality-util.c b/src/shared/pwquality-util.c index 799c39f32b..67332833a5 100644 --- a/src/shared/pwquality-util.c +++ b/src/shared/pwquality-util.c @@ -155,4 +155,37 @@ int suggest_passwords(void) { return 1; } +int quality_check_password(const char *password, const char *username, char **ret_error) { + _cleanup_(sym_pwquality_free_settingsp) pwquality_settings_t *pwq = NULL; + char buf[PWQ_MAX_ERROR_MESSAGE_LEN]; + void *auxerror; + int r; + + assert(password); + + r = pwq_allocate_context(&pwq); + if (ERRNO_IS_NOT_SUPPORTED(r)) + return 0; + if (r < 0) + return log_debug_errno(r, "Failed to allocate libpwquality context: %m"); + + r = sym_pwquality_check(pwq, password, NULL, username, &auxerror); + if (r < 0) { + + if (ret_error) { + _cleanup_free_ char *e = NULL; + + e = strdup(sym_pwquality_strerror(buf, sizeof(buf), r, auxerror)); + if (!e) + return -ENOMEM; + + *ret_error = TAKE_PTR(e); + } + + return 0; /* all bad */ + } + + return 1; /* all good */ +} + #endif diff --git a/src/shared/pwquality-util.h b/src/shared/pwquality-util.h index 2ef34dabee..a49de07990 100644 --- a/src/shared/pwquality-util.h +++ b/src/shared/pwquality-util.h @@ -24,6 +24,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(pwquality_settings_t*, sym_pwquality_free_settings); void pwq_maybe_disable_dictionary(pwquality_settings_t *pwq); int pwq_allocate_context(pwquality_settings_t **ret); int suggest_passwords(void); +int quality_check_password(const char *password, const char *username, char **ret_error); #else @@ -31,4 +32,10 @@ static inline int suggest_passwords(void) { return 0; } +static inline int quality_check_password(const char *password, const char *username, char **ret_error) { + if (ret_error) + *ret_error = NULL; + return 1; /* all good */ +} + #endif