From: Francis Dupont Date: Mon, 29 Nov 2021 17:10:03 +0000 (+0100) Subject: [#34] Chekpoint: added easy cases X-Git-Tag: Kea-2.1.2~158 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f80b854d2f59bbc0aee3c2eccc697f92e4e1d32;p=thirdparty%2Fkea.git [#34] Chekpoint: added easy cases --- diff --git a/src/lib/dhcpsrv/cql_host_data_source.cc b/src/lib/dhcpsrv/cql_host_data_source.cc index a4820874f5..d6a70b305a 100644 --- a/src/lib/dhcpsrv/cql_host_data_source.cc +++ b/src/lib/dhcpsrv/cql_host_data_source.cc @@ -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(); diff --git a/src/lib/dhcpsrv/cql_lease_mgr.cc b/src/lib/dhcpsrv/cql_lease_mgr.cc index 125121cca6..e1204aae97 100644 --- a/src/lib/dhcpsrv/cql_lease_mgr.cc +++ b/src/lib/dhcpsrv/cql_lease_mgr.cc @@ -2113,6 +2113,38 @@ CqlLeaseMgr::CqlLeaseMgr(const DatabaseConnection::ParameterMap ¶meters) // 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(); diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.cc b/src/lib/dhcpsrv/dhcpsrv_messages.cc index d69865f46d..d824b43268 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.cc +++ b/src/lib/dhcpsrv/dhcpsrv_messages.cc @@ -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", diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.h b/src/lib/dhcpsrv/dhcpsrv_messages.h index 3fe5dd7f97..3093f0f6f2 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.h +++ b/src/lib/dhcpsrv/dhcpsrv_messages.h @@ -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; diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.mes b/src/lib/dhcpsrv/dhcpsrv_messages.mes index 0e5fcbf175..daa0b9e8d4 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.mes +++ b/src/lib/dhcpsrv/dhcpsrv_messages.mes @@ -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. diff --git a/src/lib/dhcpsrv/pgsql_host_data_source.cc b/src/lib/dhcpsrv/pgsql_host_data_source.cc index 1817e574bf..2f95fb1005 100644 --- a/src/lib/dhcpsrv/pgsql_host_data_source.cc +++ b/src/lib/dhcpsrv/pgsql_host_data_source.cc @@ -2227,6 +2227,28 @@ PgSqlHostDataSourceImpl::PgSqlHostDataSourceImpl(const DatabaseConnection::Param timer_name_ += boost::lexical_cast(reinterpret_cast(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 code_version(PG_SCHEMA_VERSION_MAJOR, PG_SCHEMA_VERSION_MINOR); diff --git a/src/lib/dhcpsrv/pgsql_lease_mgr.cc b/src/lib/dhcpsrv/pgsql_lease_mgr.cc index 8b009f7e27..1c05c4dc67 100644 --- a/src/lib/dhcpsrv/pgsql_lease_mgr.cc +++ b/src/lib/dhcpsrv/pgsql_lease_mgr.cc @@ -1222,6 +1222,28 @@ PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters) timer_name_ += boost::lexical_cast(reinterpret_cast(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 code_version(PG_SCHEMA_VERSION_MAJOR, PG_SCHEMA_VERSION_MINOR); diff --git a/src/lib/pgsql/pgsql_connection.cc b/src/lib/pgsql/pgsql_connection.cc index d38466ea5c..efd0d06b08 100644 --- a/src/lib/pgsql/pgsql_connection.cc +++ b/src/lib/pgsql/pgsql_connection.cc @@ -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) { diff --git a/src/lib/pgsql/pgsql_connection.h b/src/lib/pgsql/pgsql_connection.h index 3450e3f5ba..4135d2951e 100644 --- a/src/lib/pgsql/pgsql_connection.h +++ b/src/lib/pgsql/pgsql_connection.h @@ -203,6 +203,9 @@ public: /// @brief Function invoked to process fetched row. typedef std::function ConsumeResultRowFun; + /// @brief Emit once the TLS support warning. + static bool warned_about_tls; + /// @brief Constructor /// /// Initialize PgSqlConnection object with parameters needed for connection.