From fe0bf161cbff2748aef24e4dcd48e8ea014561b9 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Wed, 18 Apr 2018 15:30:06 +0200 Subject: [PATCH] Add TLS support for DB IDO PostgreSQL feature fixes #6211 --- doc/09-object-types.md | 4 ++ lib/db_ido_pgsql/idopgsqlconnection.cpp | 50 +++++++++++++++++-------- lib/db_ido_pgsql/idopgsqlconnection.ti | 4 ++ lib/pgsql_shim/pgsqlinterface.cpp | 5 +++ lib/pgsql_shim/pgsqlinterface.hpp | 1 + 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/doc/09-object-types.md b/doc/09-object-types.md index a0e0739ed..622fc418c 100644 --- a/doc/09-object-types.md +++ b/doc/09-object-types.md @@ -948,6 +948,10 @@ Configuration Attributes: user | String | **Optional.** PostgreSQL database user with read/write permission to the icinga database. Defaults to `icinga`. password | String | **Optional.** PostgreSQL database user's password. Defaults to `icinga`. database | String | **Optional.** PostgreSQL database name. Defaults to `icinga`. + ssl\_mode | String | **Optional.** Enable SSL connection mode. Value must be set according to the [sslmode setting](https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNSTRING): `prefer`, `require`, `verify-ca`, `verify-full`, `allow`, `disable`. + ssl\_key | String | **Optional.** PostgreSQL SSL client key file path. + ssl\_cert | String | **Optional.** PostgreSQL SSL certificate file path. + ssl\_ca | String | **Optional.** PostgreSQL SSL certificate authority certificate file path. table\_prefix | String | **Optional.** PostgreSQL database table prefix. Defaults to `icinga_`. instance\_name | String | **Optional.** Unique identifier for the local Icinga 2 instance. Defaults to `default`. instance\_description | String | **Optional.** Description for the Icinga 2 instance. diff --git a/lib/db_ido_pgsql/idopgsqlconnection.cpp b/lib/db_ido_pgsql/idopgsqlconnection.cpp index 6bb4ee7ee..9771d4027 100644 --- a/lib/db_ido_pgsql/idopgsqlconnection.cpp +++ b/lib/db_ido_pgsql/idopgsqlconnection.cpp @@ -208,22 +208,41 @@ void IdoPgsqlConnection::Reconnect() ClearIDCache(); - String ihost, iport, iuser, ipasswd, idb; - const char *host, *port, *user , *passwd, *db; + String host = GetHost(); + String port = GetPort(); + String user = GetUser(); + String password = GetPassword(); + String database = GetDatabase(); - ihost = GetHost(); - iport = GetPort(); - iuser = GetUser(); - ipasswd = GetPassword(); - idb = GetDatabase(); + String sslMode = GetSslMode(); + String sslKey = GetSslKey(); + String sslCert = GetSslCert(); + String sslCa = GetSslCa(); - host = (!ihost.IsEmpty()) ? ihost.CStr() : nullptr; - port = (!iport.IsEmpty()) ? iport.CStr() : nullptr; - user = (!iuser.IsEmpty()) ? iuser.CStr() : nullptr; - passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : nullptr; - db = (!idb.IsEmpty()) ? idb.CStr() : nullptr; + String conninfo; - m_Connection = m_Pgsql->setdbLogin(host, port, nullptr, nullptr, db, user, passwd); + if (!host.IsEmpty()) + conninfo += " host=" + host; + if (!port.IsEmpty()) + conninfo += " port=" + port; + if (!user.IsEmpty()) + conninfo += " user=" + user; + if (!password.IsEmpty()) + conninfo += " password=" + password; + if (!database.IsEmpty()) + conninfo += " dbname=" + database; + + if (!sslMode.IsEmpty()) + conninfo += " sslmode=" + sslMode; + if (!sslKey.IsEmpty()) + conninfo += " sslkey=" + sslKey; + if (!sslCert.IsEmpty()) + conninfo += " sslcert=" + sslCert; + if (!sslCa.IsEmpty()) + conninfo += " sslrootcert=" + sslCa; + + /* connection */ + m_Connection = m_Pgsql->connectdb(conninfo.CStr()); if (!m_Connection) return; @@ -234,7 +253,7 @@ void IdoPgsqlConnection::Reconnect() SetConnected(false); Log(LogCritical, "IdoPgsqlConnection") - << "Connection to database '" << db << "' with user '" << user << "' on '" << host << ":" << port + << "Connection to database '" << database << "' with user '" << user << "' on '" << host << ":" << port << "' failed: \"" << message << "\""; BOOST_THROW_EXCEPTION(std::runtime_error(message)); @@ -346,7 +365,8 @@ void IdoPgsqlConnection::Reconnect() } Log(LogInformation, "IdoPgsqlConnection") - << "pgSQL IDO instance id: " << static_cast(m_InstanceID) << " (schema version: '" + version + "')"; + << "PGSQL IDO instance id: " << static_cast(m_InstanceID) << " (schema version: '" + version + "')" + << (!sslMode.IsEmpty() ? ", sslmode='" + sslMode + "'" : ""); Query("BEGIN"); diff --git a/lib/db_ido_pgsql/idopgsqlconnection.ti b/lib/db_ido_pgsql/idopgsqlconnection.ti index 5ce36668e..a4657c0b1 100644 --- a/lib/db_ido_pgsql/idopgsqlconnection.ti +++ b/lib/db_ido_pgsql/idopgsqlconnection.ti @@ -45,6 +45,10 @@ class IdoPgsqlConnection : DbConnection default {{{ return "default"; }}} }; [config] String instance_description; + [config] String ssl_mode; + [config] String ssl_key; + [config] String ssl_cert; + [config] String ssl_ca; }; } diff --git a/lib/pgsql_shim/pgsqlinterface.cpp b/lib/pgsql_shim/pgsqlinterface.cpp index 0b3eb0b97..b5b3ef351 100644 --- a/lib/pgsql_shim/pgsqlinterface.cpp +++ b/lib/pgsql_shim/pgsqlinterface.cpp @@ -108,6 +108,11 @@ struct PgsqlInterfaceImpl final : public PgsqlInterface return PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd); } + PGconn *connectdb(const char *conninfo) const override + { + return PQconnectdb(conninfo); + } + ConnStatusType status(const PGconn *conn) const override { return PQstatus(conn); diff --git a/lib/pgsql_shim/pgsqlinterface.hpp b/lib/pgsql_shim/pgsqlinterface.hpp index 041966eac..49148080b 100644 --- a/lib/pgsql_shim/pgsqlinterface.hpp +++ b/lib/pgsql_shim/pgsqlinterface.hpp @@ -50,6 +50,7 @@ struct PgsqlInterface virtual ExecStatusType resultStatus(const PGresult *res) const = 0; virtual int serverVersion(const PGconn *conn) const = 0; virtual PGconn *setdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd) const = 0; + virtual PGconn *connectdb(const char *conninfo) const = 0; virtual ConnStatusType status(const PGconn *conn) const = 0; protected: