From 6e3b38286d3b4953033fe7a1c776d20f06de1cd7 Mon Sep 17 00:00:00 2001 From: hanjinpeng Date: Sun, 2 Jun 2024 17:42:17 +0800 Subject: [PATCH] vncpasswd add password complexity rule check to enhance security Use the library pwquality to check password complexity and improve security. Additionally, optional enable support is also set in CMake. --- BUILDING.txt | 3 +++ CMakeLists.txt | 14 ++++++++++++ unix/vncpasswd/CMakeLists.txt | 4 ++++ unix/vncpasswd/vncpasswd.cxx | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/BUILDING.txt b/BUILDING.txt index 83a68aee17..9bb3d61b6c 100644 --- a/BUILDING.txt +++ b/BUILDING.txt @@ -55,6 +55,9 @@ Build Requirements (Unix) * You might have to enable additional repositories for this. E.g., on RHEL, EPEL and RPMFusion (free + nonfree) need to be enabled. +-- If building vncpasswd with password quality check support: + * libpwquality + ============================ Build Requirements (Windows) ============================ diff --git a/CMakeLists.txt b/CMakeLists.txt index ba6b320367..8e797f8c65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -324,6 +324,20 @@ if(UNIX AND NOT APPLE) endif() endif() +# check for password pwquality check support +option(ENABLE_PWQUALITY "Enable password pwquality check" ON) +if(ENABLE_PWQUALITY) + if(UNIX) + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PWQUALITY pwquality) + if(PWQUALITY_FOUND) + add_definitions(-DHAVE_PWQUALITY) + endif() + endif() + endif() +endif() + # Generate config.h and make sure the source finds it configure_file(config.h.in config.h) add_definitions(-DHAVE_CONFIG_H) diff --git a/unix/vncpasswd/CMakeLists.txt b/unix/vncpasswd/CMakeLists.txt index 9b672041d7..f490a9338d 100644 --- a/unix/vncpasswd/CMakeLists.txt +++ b/unix/vncpasswd/CMakeLists.txt @@ -4,5 +4,9 @@ add_executable(vncpasswd target_include_directories(vncpasswd PUBLIC ${CMAKE_SOURCE_DIR}/common) target_link_libraries(vncpasswd tx rfb os) +if(PWQUALITY_FOUND) + target_link_libraries(vncpasswd pwquality) +endif() + install(TARGETS vncpasswd DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) install(FILES vncpasswd.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncpasswd.1) diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx index 30091a3db6..eb8ad03728 100644 --- a/unix/vncpasswd/vncpasswd.cxx +++ b/unix/vncpasswd/vncpasswd.cxx @@ -37,6 +37,9 @@ #include +#ifdef HAVE_PWQUALITY +#include +#endif using namespace rfb; @@ -99,6 +102,36 @@ static int encrypt_pipe() { return 0; } +#ifdef HAVE_PWQUALITY +static int check_passwd_pwquality(const char *password) +{ + int r; + void *auxerror; + pwquality_settings_t *pwq; + pwq = pwquality_default_settings(); + if (!pwq) + return -EINVAL; + r = pwquality_read_config(pwq, NULL, &auxerror); + if (r) { + printf("Cannot check password quality: %s \n", + pwquality_strerror(NULL, 0, r, auxerror)); + pwquality_free_settings(pwq); + return -EINVAL; + } + + r = pwquality_check(pwq, password, NULL, NULL, &auxerror); + if (r < 0) { + printf("Password quality check failed:\n %s \n", + pwquality_strerror(NULL, 0, r, auxerror)); + r = -EPERM; + } + pwquality_free_settings(pwq); + + //return the score of password quality + return r; +} +#endif + static std::vector readpassword() { while (true) { const char *passwd = getpassword("Password:"); @@ -116,6 +149,15 @@ static std::vector readpassword() { continue; } +#ifdef HAVE_PWQUALITY + //the function return score of password quality + int r = check_passwd_pwquality(passwd); + if (r < 0){ + printf("Password quality check failed, please set it correctly.\n"); + continue; + } +#endif + passwd = getpassword("Verify:"); if (passwd == NULL) { perror("getpass error");