]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#34] Chekpoint: added easy cases
authorFrancis Dupont <fdupont@isc.org>
Mon, 29 Nov 2021 17:10:03 +0000 (18:10 +0100)
committerFrancis Dupont <fdupont@isc.org>
Thu, 6 Jan 2022 12:12:40 +0000 (13:12 +0100)
src/lib/dhcpsrv/cql_host_data_source.cc
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/dhcpsrv_messages.cc
src/lib/dhcpsrv/dhcpsrv_messages.h
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/pgsql_host_data_source.cc
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/pgsql/pgsql_connection.cc
src/lib/pgsql/pgsql_connection.h

index a4820874f5da65286bb5ca66826069dff61e260f..d6a70b305adc230f23c88eaa184d410835948655 100644 (file)
@@ -2522,6 +2522,38 @@ CqlHostDataSourceImpl::CqlHostDataSourceImpl(const DatabaseConnection::Parameter
                   << db_version.second);
     }
 
+    // Check TLS support.
+    bool tls(false);
+    try {
+        dbconn_.getParameter("trust-anchor");
+        tls = true;
+    } catch (...) {
+        // No trust anchor.
+    }
+    try {
+        dbconn_.getParameter("cert-file");
+        tls = true;
+    } catch (...) {
+        // No certificate file.
+    }
+    try {
+        dbconn_.getParameter("key-file");
+        tls = true;
+    } catch (...) {
+        // No private key file.
+    }
+    try {
+        dbconn_.getParameter("cipher-list");
+        tls = true;
+    } catch (...) {
+        // No cipher list.
+    }
+    if (tls) {
+        LOG_ERR(dhcpsrv_logger, DHCPSRV_CQL_NO_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters));
+        isc_throw(DbOpenError, "Attempt to configure TLS for CQL backend");
+    }
+
     // Open the database.
     dbconn_.openDatabase();
 
index 125121cca6844961bf25970f1b79902350bd32d0..e1204aae97159e08340805f3f62776321497fbb8 100644 (file)
@@ -2113,6 +2113,38 @@ CqlLeaseMgr::CqlLeaseMgr(const DatabaseConnection::ParameterMap &parameters)
     // Cassandra support is now deprecated.
     LOG_WARN(dhcpsrv_logger, DHCPSRV_DEPRECATED).arg("Cassandra lease backend");
 
+    // Check TLS support.
+    bool tls(false);
+    try {
+        dbconn_.getParameter("trust-anchor");
+        tls = true;
+    } catch (...) {
+        // No trust anchor.
+    }
+    try {
+        dbconn_.getParameter("cert-file");
+        tls = true;
+    } catch (...) {
+        // No certificate file.
+    }
+    try {
+        dbconn_.getParameter("key-file");
+        tls = true;
+    } catch (...) {
+        // No private key file.
+    }
+    try {
+        dbconn_.getParameter("cipher-list");
+        tls = true;
+    } catch (...) {
+        // No cipher list.
+    }
+    if (tls) {
+        LOG_ERR(dhcpsrv_logger, DHCPSRV_CQL_NO_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters));
+        isc_throw(DbOpenError, "Attempt to configure TLS for CQL");
+    }
+
     // Open the database.
     dbconn_.openDatabase();
 
index d69865f46d3494743fba43f29595267452aa78b5..d824b43268cd3e1df16cdd523a142e23112dcdad 100644 (file)
@@ -84,6 +84,7 @@ extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET4 = "DHCPSRV_CQL_HOST_GET4"
 extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET6 = "DHCPSRV_CQL_HOST_GET6";
 extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET_ALL = "DHCPSRV_CQL_HOST_GET_ALL";
 extern const isc::log::MessageID DHCPSRV_CQL_LEASE_EXCEPTION_THROWN = "DHCPSRV_CQL_LEASE_EXCEPTION_THROWN";
+extern const isc::log::MessageID DHCPSRV_CQL_NO_TLS_SUPPORT = "DHCPSRV_CQL_NO_TLS_SUPPORT";
 extern const isc::log::MessageID DHCPSRV_CQL_ROLLBACK = "DHCPSRV_CQL_ROLLBACK";
 extern const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR4 = "DHCPSRV_CQL_UPDATE_ADDR4";
 extern const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR6 = "DHCPSRV_CQL_UPDATE_ADDR6";
@@ -198,8 +199,10 @@ extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
 extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE = "DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE";
 extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_FAILED = "DHCPSRV_MYSQL_LEASE_DB_RECONNECT_FAILED";
 extern const isc::log::MessageID DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT = "DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT";
+extern const isc::log::MessageID DHCPSRV_MYSQL_NO_TLS = "DHCPSRV_MYSQL_NO_TLS";
 extern const isc::log::MessageID DHCPSRV_MYSQL_ROLLBACK = "DHCPSRV_MYSQL_ROLLBACK";
 extern const isc::log::MessageID DHCPSRV_MYSQL_START_TRANSACTION = "DHCPSRV_MYSQL_START_TRANSACTION";
+extern const isc::log::MessageID DHCPSRV_MYSQL_TLS_CIPHER = "DHCPSRV_MYSQL_TLS_CIPHER";
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR4 = "DHCPSRV_MYSQL_UPDATE_ADDR4";
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR6 = "DHCPSRV_MYSQL_UPDATE_ADDR6";
 extern const isc::log::MessageID DHCPSRV_NOTYPE_DB = "DHCPSRV_NOTYPE_DB";
@@ -245,8 +248,10 @@ extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
 extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE = "DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE";
 extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED = "DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED";
 extern const isc::log::MessageID DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT = "DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT";
+extern const isc::log::MessageID DHCPSRV_PGSQL_NO_TLS_SUPPORT = "DHCPSRV_PGSQL_NO_TLS_SUPPORT";
 extern const isc::log::MessageID DHCPSRV_PGSQL_ROLLBACK = "DHCPSRV_PGSQL_ROLLBACK";
 extern const isc::log::MessageID DHCPSRV_PGSQL_START_TRANSACTION = "DHCPSRV_PGSQL_START_TRANSACTION";
+extern const isc::log::MessageID DHCPSRV_PGSQL_TLS_SUPPORT = "DHCPSRV_PGSQL_TLS_SUPPORT";
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR4 = "DHCPSRV_PGSQL_UPDATE_ADDR4";
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR6 = "DHCPSRV_PGSQL_UPDATE_ADDR6";
 extern const isc::log::MessageID DHCPSRV_QUEUE_NCR = "DHCPSRV_QUEUE_NCR";
@@ -345,6 +350,7 @@ const char* values[] = {
     "DHCPSRV_CQL_HOST_GET6", "Retrieving one DHCPv6 host from a CQL database",
     "DHCPSRV_CQL_HOST_GET_ALL", "Retrieving multiple hosts from a CQL database",
     "DHCPSRV_CQL_LEASE_EXCEPTION_THROWN", "Exception thrown during Cassandra operation: %1",
+    "DHCPSRV_CQL_NO_TLS_SUPPORT", "Attempt to configure TLS (unsupported for CQL): %1",
     "DHCPSRV_CQL_ROLLBACK", "rolling back Cassandra database.",
     "DHCPSRV_CQL_UPDATE_ADDR4", "updating IPv4 lease for address %1",
     "DHCPSRV_CQL_UPDATE_ADDR6", "updating IPv6 lease for address %1",
@@ -459,8 +465,10 @@ const char* values[] = {
     "DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE", "scheduling attempt %1 of %2 in %3 milliseconds",
     "DHCPSRV_MYSQL_LEASE_DB_RECONNECT_FAILED", "maximum number of database reconnect attempts: %1, has been exhausted without success",
     "DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT", "recount of leases returned a negative value",
+    "DHCPSRV_MYSQL_NO_TLS", "TLS was required but is not used",
     "DHCPSRV_MYSQL_ROLLBACK", "rolling back MySQL database",
     "DHCPSRV_MYSQL_START_TRANSACTION", "starting new MySQL transaction",
+    "DHCPSRV_MYSQL_TLS_CIPHER", "TLS cipher: %1",
     "DHCPSRV_MYSQL_UPDATE_ADDR4", "updating IPv4 lease for address %1",
     "DHCPSRV_MYSQL_UPDATE_ADDR6", "updating IPv6 lease for address %1, lease type %2",
     "DHCPSRV_NOTYPE_DB", "no 'type' keyword to determine database backend: %1",
@@ -506,8 +514,10 @@ const char* values[] = {
     "DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE", "scheduling attempt %1 of %2 in %3 milliseconds",
     "DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED", "maximum number of database reconnect attempts: %1, has been exhausted without success",
     "DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT", "recount of leases returned a negative value",
+    "DHCPSRV_PGSQL_NO_TLS_SUPPORT", "Attempt to configure TLS (unsupported for PostgreSQL): %1",
     "DHCPSRV_PGSQL_ROLLBACK", "rolling back PostgreSQL database",
     "DHCPSRV_PGSQL_START_TRANSACTION", "starting a new PostgreSQL transaction",
+    "DHCPSRV_PGSQL_TLS_SUPPORT", "Attempt to configure TLS: %1",
     "DHCPSRV_PGSQL_UPDATE_ADDR4", "updating IPv4 lease for address %1",
     "DHCPSRV_PGSQL_UPDATE_ADDR6", "updating IPv6 lease for address %1, lease type %2",
     "DHCPSRV_QUEUE_NCR", "%1: Name change request to %2 DNS entry queued: %3",
index 3fe5dd7f97fa31e9913e7caec83c7996801eb8d4..3093f0f6f2340905449068964874b2d66c6ddfb2 100644 (file)
@@ -85,6 +85,7 @@ extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET4;
 extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET6;
 extern const isc::log::MessageID DHCPSRV_CQL_HOST_GET_ALL;
 extern const isc::log::MessageID DHCPSRV_CQL_LEASE_EXCEPTION_THROWN;
+extern const isc::log::MessageID DHCPSRV_CQL_NO_TLS_SUPPORT;
 extern const isc::log::MessageID DHCPSRV_CQL_ROLLBACK;
 extern const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR4;
 extern const isc::log::MessageID DHCPSRV_CQL_UPDATE_ADDR6;
@@ -199,8 +200,10 @@ extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
 extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE;
 extern const isc::log::MessageID DHCPSRV_MYSQL_LEASE_DB_RECONNECT_FAILED;
 extern const isc::log::MessageID DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT;
+extern const isc::log::MessageID DHCPSRV_MYSQL_NO_TLS;
 extern const isc::log::MessageID DHCPSRV_MYSQL_ROLLBACK;
 extern const isc::log::MessageID DHCPSRV_MYSQL_START_TRANSACTION;
+extern const isc::log::MessageID DHCPSRV_MYSQL_TLS_CIPHER;
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR4;
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR6;
 extern const isc::log::MessageID DHCPSRV_NOTYPE_DB;
@@ -246,8 +249,10 @@ extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_FAILED
 extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_ATTEMPT_SCHEDULE;
 extern const isc::log::MessageID DHCPSRV_PGSQL_LEASE_DB_RECONNECT_FAILED;
 extern const isc::log::MessageID DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT;
+extern const isc::log::MessageID DHCPSRV_PGSQL_NO_TLS_SUPPORT;
 extern const isc::log::MessageID DHCPSRV_PGSQL_ROLLBACK;
 extern const isc::log::MessageID DHCPSRV_PGSQL_START_TRANSACTION;
+extern const isc::log::MessageID DHCPSRV_PGSQL_TLS_SUPPORT;
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR4;
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR6;
 extern const isc::log::MessageID DHCPSRV_QUEUE_NCR;
index 0e5fcbf175028fa9d70a8cf1ff9bea66e0b2b6bf..daa0b9e8d4a733e7a668fd4ccb8ee373b1d50e01 100644 (file)
@@ -406,6 +406,11 @@ An informational message logged when multiple hosts from a CQL database are retr
 
 % DHCPSRV_CQL_LEASE_EXCEPTION_THROWN Exception thrown during Cassandra operation: %1
 
+% DHCPSRV_CQL_NO_TLS_SUPPORT Attempt to configure TLS (unsupported for CQL): %1
+This error message is printed when TLS support was required in the Kea
+configuration: this feature is not supported for Cassandra/CQL. The
+parameters of the connection are logged.
+
 % DHCPSRV_CQL_ROLLBACK rolling back Cassandra database.
 The code has issued a rollback call. For Cassandra, this is a no-op.
 
@@ -979,6 +984,10 @@ in the MySQL database returned a negative value. This shows a problem
 which can be fixed only by an offline direct recount on the database.
 This message is issued only once.
 
+% DHCPSRV_MYSQL_NO_TLS TLS was required but is not used
+This error message is issued when TLS for the connection was required but
+TLS is not used.
+
 % DHCPSRV_MYSQL_ROLLBACK rolling back MySQL database
 The code has issued a rollback call.  All outstanding transaction will
 be rolled back and not committed to the database.
@@ -992,6 +1001,10 @@ inserted into multiple tables with multiple INSERT statements
 and there may be a need to rollback the whole transaction if
 any of these INSERT statements fail.
 
+% DHCPSRV_MYSQL_TLS_CIPHER TLS cipher: %1
+A debug message issued when a new MySQL connected is created with TLS.
+The TLS cipher name is logged.
+
 % DHCPSRV_MYSQL_UPDATE_ADDR4 updating IPv4 lease for address %1
 A debug message issued when the server is attempting to update IPv4
 lease from the MySQL database for the specified address.
@@ -1203,6 +1216,11 @@ in the PostgreSQL database returned a negative value. This shows a problem
 which can be fixed only by an offline direct recount on the database.
 This message is issued only once.
 
+% DHCPSRV_PGSQL_NO_TLS_SUPPORT Attempt to configure TLS (unsupported for PostgreSQL): %1
+This error message is printed when TLS support was required in the Kea
+configuration: Kea was built with this feature was disabled for PostgreSQL.
+The parameters of the connection are logged.
+
 % DHCPSRV_PGSQL_ROLLBACK rolling back PostgreSQL database
 The code has issued a rollback call.  All outstanding transaction will
 be rolled back and not committed to the database.
@@ -1216,6 +1234,12 @@ inserted into multiple tables with multiple INSERT statements
 and there may be a need to rollback the whole transaction if
 any of these INSERT statements fail.
 
+% DHCPSRV_PGSQL_TLS_SUPPORT Attempt to configure TLS: %1
+This informational message is printed when TLS support was required in
+the Kea configuration: The TLS support in PostgreSQL will be initialized but
+its configuration is fully managed outside the C API.
+The parameters of the connection are logged.
+
 % DHCPSRV_PGSQL_UPDATE_ADDR4 updating IPv4 lease for address %1
 A debug message issued when the server is attempting to update IPv4
 lease from the PostgreSQL database for the specified address.
index 1817e574bf5ede5b35412fd6981eeebf4f683acb..2f95fb10059b5ca06537792d219d215255bdfae8 100644 (file)
@@ -2227,6 +2227,28 @@ PgSqlHostDataSourceImpl::PgSqlHostDataSourceImpl(const DatabaseConnection::Param
     timer_name_ += boost::lexical_cast<std::string>(reinterpret_cast<uint64_t>(this));
     timer_name_ += "]DbReconnectTimer";
 
+    // Check TLS support.
+    size_t tls(0);
+    tls += parameters.count("trust-anchor");
+    tls += parameters.count("cert-file");
+    tls += parameters.count("key-file");
+    tls += parameters.count("cipher-list");
+#ifdef HAVE_PGSQL_SSL
+    if ((tls > 0) && !PgSqlConnection::warned_about_tls) {
+        PgSqlConnection::warned_about_tls = true;
+        LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters_));
+        PQinitSSL(1);
+    }
+#else
+    if (tls > 0) {
+        LOG_ERR(dhcpsrv_logger, DHCPSRV_PGSQL_NO_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters_));
+        isc_throw(DbOpenError, "Attempt to configure TLS for PostgreSQL "
+                  << "backend (built with this feature disabled)");
+    }
+#endif
+
     // Validate the schema version first.
     std::pair<uint32_t, uint32_t> code_version(PG_SCHEMA_VERSION_MAJOR,
                                                PG_SCHEMA_VERSION_MINOR);
index 8b009f7e27fc9f7a6a14e7d2f07331a1e024dca4..1c05c4dc67aeb4b69ee48f28abc376323d62ccbc 100644 (file)
@@ -1222,6 +1222,28 @@ PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
     timer_name_ += boost::lexical_cast<std::string>(reinterpret_cast<uint64_t>(this));
     timer_name_ += "]DbReconnectTimer";
 
+    // Check TLS support.
+    size_t tls(0);
+    tls += parameters.count("trust-anchor");
+    tls += parameters.count("cert-file");
+    tls += parameters.count("key-file");
+    tls += parameters.count("cipher-list");
+#ifdef HAVE_PGSQL_SSL
+    if ((tls > 0) && !PgSqlConnection::warned_about_tls) {
+        PgSqlConnection::warned_about_tls = true;
+        LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters_));
+        PQinitSSL(1);
+    }
+#else
+    if (tls > 0) {
+        LOG_ERR(dhcpsrv_logger, DHCPSRV_PGSQL_NO_TLS_SUPPORT)
+            .arg(DatabaseConnection::redactedAccessString(parameters_));
+        isc_throw(DbOpenError, "Attempt to configure TLS for PostgreSQL "
+                  << "backend (built with this feature disabled)");
+    }
+#endif
+
     // Validate schema version first.
     std::pair<uint32_t, uint32_t> code_version(PG_SCHEMA_VERSION_MAJOR,
                                                PG_SCHEMA_VERSION_MINOR);
index d38466ea5cd9f90730847e4d59d0428ba61966b5..efd0d06b0835dba78255ba9cfc09a1ff92bafbbf 100644 (file)
@@ -39,6 +39,8 @@ const int PGSQL_DEFAULT_CONNECTION_TIMEOUT = 5; // seconds
 
 const char PgSqlConnection::DUPLICATE_KEY[] = ERRCODE_UNIQUE_VIOLATION;
 
+bool PgSqlConnection::warned_about_tls = false;
+
 PgSqlResult::PgSqlResult(PGresult *result)
     : result_(result), rows_(0), cols_(0) {
     if (!result) {
index 3450e3f5ba8b569e8bdda77ce71154ef5401832b..4135d2951ed7ae6e6ccf7a901573d8b865c94619 100644 (file)
@@ -203,6 +203,9 @@ public:
     /// @brief Function invoked to process fetched row.
     typedef std::function<void(PgSqlResult&, int)> ConsumeResultRowFun;
 
+    /// @brief Emit once the TLS support warning.
+    static bool warned_about_tls;
+
     /// @brief Constructor
     ///
     /// Initialize PgSqlConnection object with parameters needed for connection.