<< 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();
// 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();
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";
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";
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";
"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",
"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",
"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",
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;
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;
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;
% 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.
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.
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.
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.
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.
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);
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);
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) {
/// @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.