]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3959] Checkpoint: added UTs
authorFrancis Dupont <fdupont@isc.org>
Mon, 3 Aug 2026 08:53:35 +0000 (10:53 +0200)
committerFrancis Dupont <fdupont@isc.org>
Wed, 12 Aug 2026 15:22:23 +0000 (17:22 +0200)
changelog_unreleased/3959-add-support-for-password-file-to-db-access [new file with mode: 0644]
src/hooks/dhcp/mysql/tests/mysql_host_data_source_unittest.cc
src/hooks/dhcp/mysql/tests/mysql_lease_mgr_unittest.cc
src/hooks/dhcp/pgsql/tests/pgsql_host_data_source_unittest.cc
src/hooks/dhcp/pgsql/tests/pgsql_lease_mgr_unittest.cc
src/lib/database/testutils/bad-password [new file with mode: 0644]
src/lib/database/testutils/meson.build
src/lib/database/testutils/password [new file with mode: 0644]
src/lib/database/testutils/schema.cc
src/lib/database/testutils/schema.h
src/lib/pgsql/pgsql_connection.cc

diff --git a/changelog_unreleased/3959-add-support-for-password-file-to-db-access b/changelog_unreleased/3959-add-support-for-password-file-to-db-access
new file mode 100644 (file)
index 0000000..a8c24a6
--- /dev/null
@@ -0,0 +1,6 @@
+[func]         fdupont
+       Added support for using a file to configure MySql
+       and PostgreSQL passwords. Instead of configuring
+       a value, it is taken from the content of a file.
+       The new parameter is "password-file".
+       (Gitlab #3959)
index 38bde7b56d39135205cc5f558bbae7826faf3443..358f969a1d81f82b9cd9afaf33712e5ef5ed31e8 100644 (file)
@@ -251,12 +251,23 @@ TEST(MySqlHostDataSource, OpenDatabase) {
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
         VALID_TIMEOUT, INVALID_READONLY_DB)), DbInvalidReadOnly);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
 
     // Check for missing parameters
     EXPECT_THROW(HostMgr::addBackend(connectionString(
-        MYSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
+        MYSQL_VALID_TYPE, 0, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+    HostMgr::delBackend("mysql");
+
     // Check for SSL/TLS support.
     if (hasMySQLTls()) {
         EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
@@ -353,12 +364,23 @@ TEST(MySqlHostDataSource, OpenDatabaseMultiThreading) {
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
         VALID_TIMEOUT, INVALID_READONLY_DB)), DbInvalidReadOnly);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
 
     // Check for missing parameters
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         MYSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+    HostMgr::delBackend("mysql");
+
     // Tidy up after the test
     destroyMySQLSchema();
 }
index dab6d563ccf8382522b439fe845dd9c5465256cc..a7a3ecc2952328cec64b5697b1e03bafc51abf99 100644 (file)
@@ -206,6 +206,14 @@ TEST(MySqlOpenTest, OpenDatabase) {
         MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, DEFAULT_PASSWORD)),
         isc::data::DefaultCredential);
 
+    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+
+    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
+
     // Check for invalid timeouts
     EXPECT_THROW(LeaseMgrFactory::create(connectionString(
         MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
@@ -217,9 +225,13 @@ TEST(MySqlOpenTest, OpenDatabase) {
 
     // Check for missing parameters
     EXPECT_THROW(LeaseMgrFactory::create(connectionString(
-        MYSQL_VALID_TYPE, NULL, VALID_HOST, VALID_USER, VALID_PASSWORD)),
+        MYSQL_VALID_TYPE, 0, VALID_HOST, VALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
+        MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+
     // Check for SSL/TLS support.
     if (hasMySQLTls()) {
         EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
index d0593473fa164d1f044cba3ad6e35ef8ca9f5470..0c7b1415f4bc77556b4e9ea2cdc8390abf7ee05f 100644 (file)
@@ -240,6 +240,12 @@ TEST(PgSqlHostDataSource, OpenDatabase) {
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, DEFAULT_PASSWORD)),
         DefaultCredential);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
         DbInvalidTimeout);
@@ -252,9 +258,13 @@ TEST(PgSqlHostDataSource, OpenDatabase) {
 
     // Check for missing parameters
     EXPECT_THROW(HostMgr::addBackend(connectionString(
-        PGSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
+        PGSQL_VALID_TYPE, 0, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+
     // Check for SSL/TLS support.
     if (hasPgSQLTls()) {
         EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
@@ -342,6 +352,12 @@ TEST(PgSqlHostDataSource, OpenDatabaseMultiThreading) {
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, DEFAULT_PASSWORD)),
         DefaultCredential);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+    EXPECT_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
     EXPECT_THROW(HostMgr::addBackend(connectionString(
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
         DbInvalidTimeout);
@@ -354,9 +370,13 @@ TEST(PgSqlHostDataSource, OpenDatabaseMultiThreading) {
 
     // Check for missing parameters
     EXPECT_THROW(HostMgr::addBackend(connectionString(
-        PGSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
+        PGSQL_VALID_TYPE, 0, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(HostMgr::addBackend(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+
     // Tidy up after the test
     destroyPgSQLSchema();
 }
index 2e99154622882f88d5d9e81d5d1c99bff7f5e393..cd13460ccf7173f94f294d24919baa9eac262da5 100644 (file)
@@ -211,6 +211,15 @@ TEST(PgSqlOpenTest, OpenDatabase) {
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, DEFAULT_PASSWORD)),
          isc::data::DefaultCredential);
 
+    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, NOT_EXIST_FILE)),
+        BadValue);
+
+    // See invalid password comment.
+    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_FILE)),
+        DbOpenError);
+
     // Check for invalid timeouts
     EXPECT_THROW(LeaseMgrFactory::create(connectionString(
         PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
@@ -222,9 +231,13 @@ TEST(PgSqlOpenTest, OpenDatabase) {
 
     // Check for missing parameters
     EXPECT_THROW(LeaseMgrFactory::create(connectionString(
-        PGSQL_VALID_TYPE, NULL, VALID_HOST, VALID_USER, VALID_PASSWORD)),
+        PGSQL_VALID_TYPE, 0, VALID_HOST, VALID_USER, VALID_PASSWORD)),
         NoDatabaseName);
 
+    // Check for password file.
+    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
+        PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_FILE)));
+
     // Check for SSL/TLS support.
     if (hasPgSQLTls()) {
         EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
@@ -1390,19 +1403,19 @@ TEST_F(PgSqlLeaseMgrTest, updateStatsOn4DifferentSubnet) {
     testUpdateStatsOn4DifferentSubnet();
 }
 
-TEST_F(PgSqlLeaseMgrTest, updateStatsOn6SameSubnet) { 
+TEST_F(PgSqlLeaseMgrTest, updateStatsOn6SameSubnet) {
     testUpdateStatsOn6SameSubnet();
 }
 
-TEST_F(PgSqlLeaseMgrTest, updateStatsOn6SameSubnetPD) { 
+TEST_F(PgSqlLeaseMgrTest, updateStatsOn6SameSubnetPD) {
     testUpdateStatsOn6SameSubnetPD();
 }
 
-TEST_F(PgSqlLeaseMgrTest, updateStatsOn6DifferentSubnet) { 
+TEST_F(PgSqlLeaseMgrTest, updateStatsOn6DifferentSubnet) {
     testUpdateStatsOn6DifferentSubnet();
 }
 
-TEST_F(PgSqlLeaseMgrTest, updateStatsOn6DifferentSubnetPD) { 
+TEST_F(PgSqlLeaseMgrTest, updateStatsOn6DifferentSubnetPD) {
     testUpdateStatsOn6DifferentSubnetPD();
 }
 
diff --git a/src/lib/database/testutils/bad-password b/src/lib/database/testutils/bad-password
new file mode 100644 (file)
index 0000000..323fae0
--- /dev/null
@@ -0,0 +1 @@
+foobar
index f11417a4d739c93a8646be0dd3485cdfbf667ab0..60e4d2de3c005385211e81e0f99fd320449c762b 100644 (file)
@@ -2,10 +2,14 @@ if not TESTS_OPT.enabled()
     subdir_done()
 endif
 
+current_source_dir = meson.current_source_dir()
 kea_database_testutils_lib = static_library(
     'kea-database-testutils',
     'schema.cc',
-    cpp_args: [f'-DTEST_CA_DIR="@TEST_CA_DIR@"'],
+    cpp_args: [
+        f'-DTEST_CA_DIR="@TEST_CA_DIR@"',
+        f'-DFILE_DIR="@current_source_dir@"',
+    ],
     dependencies: [GTEST_DEP],
     include_directories: [include_directories('.')] + INCLUDES,
 )
diff --git a/src/lib/database/testutils/password b/src/lib/database/testutils/password
new file mode 100644 (file)
index 0000000..eadbb15
--- /dev/null
@@ -0,0 +1 @@
+keatest
index 69e2841ab162b7f92e00252ad83a547fb9d0edcf..6530ff0f7056cd97eeda2ba3996260a10bd9aa8f 100644 (file)
@@ -35,6 +35,9 @@ const char* INVALID_USER = "user=invaliduser";
 const char* VALID_PASSWORD = "password=keatest";
 const char* INVALID_PASSWORD = "password=invalid";
 const char* DEFAULT_PASSWORD = "password=1234";
+const char* VALID_FILE = "password-file=" FILE_DIR "/password";
+const char* NOT_EXIST_FILE = "password-file=" FILE_DIR "/does-not-exit";
+const char* INVALID_FILE = "password-file=" FILE_DIR "/bad-password";
 const char* VALID_TIMEOUT = "connect-timeout=10";
 const char* INVALID_TIMEOUT_1 = "connect-timeout=foo";
 const char* INVALID_TIMEOUT_2 = "connect-timeout=-17";
index 830f1a5e532656aabc245fe0a2a62dae9bae6294..963d84533f7f8bf6d97df23fdb329d7e511a1adc 100644 (file)
@@ -29,6 +29,9 @@ extern const char* INVALID_USER;
 extern const char* VALID_PASSWORD;
 extern const char* INVALID_PASSWORD;
 extern const char* DEFAULT_PASSWORD;
+extern const char* VALID_FILE;
+extern const char* NOT_EXIST_FILE;
+extern const char* INVALID_FILE;
 extern const char* VALID_TIMEOUT;
 extern const char* INVALID_TIMEOUT_1;
 extern const char* INVALID_TIMEOUT_2;
index d621be60089f252a71b882a77acaf7a0b2537b9e..20409ba53f8b1976475c0132511d888c50774281 100644 (file)
@@ -409,6 +409,7 @@ PgSqlConnection::getConnParametersInternal(bool logging) {
     if (!spassword_file.empty()) {
         // This can throw.
         spassword = util::file::getContent(spassword_file);
+        dbconnparameters += " password = '" + spassword + "'";
     }
     if (!spassword.empty()) {
         // Refuse default password.