From b1d19210d87dd411612c5cbb4e7da14d24a4ffaf Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 26 Jun 2016 16:09:07 +0200 Subject: [PATCH] adds ability to save ssl certificate to database --- .../Server/Database/ApplicationSettings.cs | 37 +++++++++++++++++++ Duplicati/Server/WebServer/Server.cs | 29 +++++++++++++-- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Duplicati/Server/Database/ApplicationSettings.cs b/Duplicati/Server/Database/ApplicationSettings.cs index e0948b4d1..61eefe4d5 100644 --- a/Duplicati/Server/Database/ApplicationSettings.cs +++ b/Duplicati/Server/Database/ApplicationSettings.cs @@ -18,6 +18,7 @@ using System; using System.Linq; using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; namespace Duplicati.Server.Database { @@ -40,6 +41,7 @@ namespace Duplicati.Server.Database public const string UNACKED_ERROR = "unacked-error"; public const string UNACKED_WARNING = "unacked-warning"; public const string SERVER_LISTEN_INTERFACE = "server-listen-interface"; + public const string SERVER_SSL_CERTIFICATE = "server-ssl-certificate"; public const string HAS_FIXED_INVALID_BACKUPID = "has-fixed-invalid-backup-id"; public const string UPDATE_CHANNEL = "update-channel"; public const string USAGE_REPORTER_LEVEL = "usage-reporter-level"; @@ -405,6 +407,41 @@ namespace Duplicati.Server.Database } } + public X509Certificate2 ServerSSLCertificate + { + get + { + try + { + if(String.IsNullOrEmpty(m_values[CONST.SERVER_SSL_CERTIFICATE])) + return null; + + var cert = new X509Certificate2(); + + cert.Import(Convert.FromBase64String(m_values[CONST.SERVER_SSL_CERTIFICATE])); + return cert; + } + catch + { + return null; + } + } + set + { + if (value == null) + { + lock (m_connection.m_lock) + m_values[CONST.SERVER_SSL_CERTIFICATE] = String.Empty; + } + else + { + lock (m_connection.m_lock) + m_values[CONST.SERVER_SSL_CERTIFICATE] = Convert.ToBase64String(value.Export(X509ContentType.Pkcs12)); + } + SaveSettings(); + } + } + public bool FixedInvalidBackupId { get diff --git a/Duplicati/Server/WebServer/Server.cs b/Duplicati/Server/WebServer/Server.cs index 3f4a90ca7..9a2666f46 100644 --- a/Duplicati/Server/WebServer/Server.cs +++ b/Duplicati/Server/WebServer/Server.cs @@ -110,14 +110,32 @@ namespace Duplicati.Server.WebServer X509Certificate2 cert = null; bool certValid = false; - if (!string.IsNullOrWhiteSpace(certificateFile)) + if (certificateFile == null) + { + try + { + cert = Program.DataConnection.ApplicationSettings.ServerSSLCertificate; + + if (cert != null) + certValid = cert.Verify(); + } + catch (Exception ex) + { + Library.Logging.Log.WriteMessage("Unable to create SSL certificate using data from database. Starting without SSL.", Duplicati.Library.Logging.LogMessageType.Warning, ex); + } + } + else if (certificateFile.Length == 0) + { + Program.DataConnection.ApplicationSettings.ServerSSLCertificate = null; + } + else { try { if (string.IsNullOrWhiteSpace(certificateFilePassword)) - cert = new X509Certificate2(certificateFile); + cert = new X509Certificate2(certificateFile, "", X509KeyStorageFlags.Exportable); else - cert = new X509Certificate2(certificateFile, certificateFilePassword); + cert = new X509Certificate2(certificateFile, certificateFilePassword, X509KeyStorageFlags.Exportable); certValid = cert.Verify(); } @@ -149,7 +167,10 @@ namespace Duplicati.Server.WebServer if (interfacestring != Program.DataConnection.ApplicationSettings.ServerListenInterface) Program.DataConnection.ApplicationSettings.ServerListenInterface = interfacestring; - + + if (certValid && !cert.Equals(Program.DataConnection.ApplicationSettings.ServerSSLCertificate)) + Program.DataConnection.ApplicationSettings.ServerSSLCertificate = cert; + return; } catch (System.Net.Sockets.SocketException)