changeset 163:4d32c9c8d6c0

Added support for TLS connections
author Alain Mazy <alain@mazy.be>
date Mon, 13 Jul 2020 11:59:29 +0200
parents fc13b4e8f888
children 0632c2408af3
files Framework/MySQL/MySQLDatabase.cpp Framework/MySQL/MySQLParameters.cpp Framework/MySQL/MySQLParameters.h MySQL/NEWS MySQL/Plugins/IndexPlugin.cpp MySQL/Plugins/StoragePlugin.cpp
diffstat 6 files changed, 62 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/MySQL/MySQLDatabase.cpp	Mon Jul 13 11:50:54 2020 +0200
+++ b/Framework/MySQL/MySQLDatabase.cpp	Mon Jul 13 11:59:29 2020 +0200
@@ -140,7 +140,20 @@
       unsigned int protocol = MYSQL_PROTOCOL_TCP;
       mysql_options(mysql_, MYSQL_OPT_PROTOCOL, (unsigned int *) &protocol);
     }
-      
+
+    if (parameters_.IsSsl())
+    {
+      if (parameters_.IsVerifyServerCertificates())
+      {
+        my_bool verifyCert = 1;
+        mysql_options(mysql_, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *) &verifyCert);
+        mysql_optionsv(mysql_, MYSQL_OPT_SSL_CA, (void *)(parameters_.GetSslCaCertificates()));
+      }
+
+      my_bool enforceTls = 1;
+      mysql_options(mysql_, MYSQL_OPT_SSL_ENFORCE, (void *) &enforceTls);
+    }
+
     const char* socket = (parameters_.GetUnixSocket().empty() ? NULL :
                           parameters_.GetUnixSocket().c_str());
 
--- a/Framework/MySQL/MySQLParameters.cpp	Mon Jul 13 11:50:54 2020 +0200
+++ b/Framework/MySQL/MySQLParameters.cpp	Mon Jul 13 11:59:29 2020 +0200
@@ -52,46 +52,58 @@
   }
 
 
-  MySQLParameters::MySQLParameters(const OrthancPlugins::OrthancConfiguration& configuration)
+  MySQLParameters::MySQLParameters(const OrthancPlugins::OrthancConfiguration& pluginConfiguration, const OrthancPlugins::OrthancConfiguration& orthancConfiguration)
   {
     Reset();
 
     std::string s;
-    if (configuration.LookupStringValue(s, "Host"))
+    if (pluginConfiguration.LookupStringValue(s, "Host"))
     {
       SetHost(s);
     }
 
-    if (configuration.LookupStringValue(s, "Username"))
+    if (pluginConfiguration.LookupStringValue(s, "Username"))
     {
       SetUsername(s);
     }
 
-    if (configuration.LookupStringValue(s, "Password"))
+    if (pluginConfiguration.LookupStringValue(s, "Password"))
     {
       SetPassword(s);
     }
 
-    if (configuration.LookupStringValue(s, "Database"))
+    if (pluginConfiguration.LookupStringValue(s, "Database"))
     {
       SetDatabase(s);
     }
 
     unsigned int port;
-    if (configuration.LookupUnsignedIntegerValue(port, "Port"))
+    if (pluginConfiguration.LookupUnsignedIntegerValue(port, "Port"))
     {
       SetPort(port);
     }
 
-    if (configuration.LookupStringValue(s, "UnixSocket"))
+    if (pluginConfiguration.LookupStringValue(s, "UnixSocket"))
     {
       SetUnixSocket(s);
     }
 
-    lock_ = configuration.GetBooleanValue("Lock", true);  // Use locking by default
+    lock_ = pluginConfiguration.GetBooleanValue("Lock", true);  // Use locking by default
+
+    ssl_ = pluginConfiguration.GetBooleanValue("EnableSsl", false);
+    verifySslServerCertificates_ = pluginConfiguration.GetBooleanValue("SslVerifyServerCertificates", true);
+
+    const std::string defaultCaCertificates = orthancConfiguration.GetStringValue("HttpsCACertificates", "");
+    sslCaCertificates_ = pluginConfiguration.GetStringValue("SslCACertificates", defaultCaCertificates);
 
-    maxConnectionRetries_ = configuration.GetUnsignedIntegerValue("MaximumConnectionRetries", 10);
-    connectionRetryInterval_ = configuration.GetUnsignedIntegerValue("ConnectionRetryInterval", 5);
+    if (ssl_ && verifySslServerCertificates_ && sslCaCertificates_.empty())
+    {
+      LOG(ERROR) << "MySQL: No SslCACertificates defined, unable to check SSL Server certificates";
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
+    }
+
+    maxConnectionRetries_ = pluginConfiguration.GetUnsignedIntegerValue("MaximumConnectionRetries", 10);
+    connectionRetryInterval_ = pluginConfiguration.GetUnsignedIntegerValue("ConnectionRetryInterval", 5);
   }
 
 
--- a/Framework/MySQL/MySQLParameters.h	Mon Jul 13 11:50:54 2020 +0200
+++ b/Framework/MySQL/MySQLParameters.h	Mon Jul 13 11:59:29 2020 +0200
@@ -38,6 +38,9 @@
     std::string  database_;
     uint16_t     port_;
     std::string  unixSocket_;
+    bool         ssl_;
+    bool         verifySslServerCertificates_;
+    std::string  sslCaCertificates_;
     bool         lock_;
     unsigned int maxConnectionRetries_;
     unsigned int connectionRetryInterval_;
@@ -47,7 +50,7 @@
   public:
     MySQLParameters();
 
-    MySQLParameters(const OrthancPlugins::OrthancConfiguration& configuration);
+    MySQLParameters(const OrthancPlugins::OrthancConfiguration& pluginConfiguration, const OrthancPlugins::OrthancConfiguration& orthancConfiguration);
 
     const std::string& GetHost() const
     {
@@ -79,6 +82,21 @@
       return port_;
     }
 
+    bool IsSsl() const
+    {
+      return ssl_;
+    }
+
+    bool IsVerifyServerCertificates() const
+    {
+      return verifySslServerCertificates_;
+    }
+
+    const char* GetSslCaCertificates() const
+    {
+      return sslCaCertificates_.c_str();
+    }
+
     void SetHost(const std::string& host);
     
     void SetUsername(const std::string& username);
--- a/MySQL/NEWS	Mon Jul 13 11:50:54 2020 +0200
+++ b/MySQL/NEWS	Mon Jul 13 11:59:29 2020 +0200
@@ -8,6 +8,11 @@
 * Added "MaximumConnectionRetries" & "ConnectionRetryInterval" to configure 
   the retries when connecting to the DB at startup
 * Support of dynamic linking against the system-wide Orthanc framework library
+* Added support for TLS connections: 3 new options:
+  - "EnableSsl" (false by default)
+  - "SslVerifyServerCertificates" (true by default - inactive if EnableSsl if false)
+  - "SslCACertificates" (default value is "HttpsCACertificates" from global
+    Orthanc configuration)
 
 
 Release 2.0 (2019-01-23)
--- a/MySQL/Plugins/IndexPlugin.cpp	Mon Jul 13 11:50:54 2020 +0200
+++ b/MySQL/Plugins/IndexPlugin.cpp	Mon Jul 13 11:59:29 2020 +0200
@@ -65,7 +65,7 @@
 
     try
     {
-      OrthancDatabases::MySQLParameters parameters(mysql);
+      OrthancDatabases::MySQLParameters parameters(mysql, configuration);
 
       /* Create the database back-end */
       backend_.reset(new OrthancDatabases::MySQLIndex(parameters));
--- a/MySQL/Plugins/StoragePlugin.cpp	Mon Jul 13 11:50:54 2020 +0200
+++ b/MySQL/Plugins/StoragePlugin.cpp	Mon Jul 13 11:59:29 2020 +0200
@@ -62,7 +62,7 @@
 
     try
     {
-      OrthancDatabases::MySQLParameters parameters(mysql);
+      OrthancDatabases::MySQLParameters parameters(mysql, configuration);
       OrthancDatabases::StorageBackend::Register
         (context, new OrthancDatabases::MySQLStorageArea(parameters));
     }