diff --git a/Duplicati.Library.RestAPI/Strings.cs b/Duplicati.Library.RestAPI/Strings.cs index 51c5129ee..253dfd227 100644 --- a/Duplicati.Library.RestAPI/Strings.cs +++ b/Duplicati.Library.RestAPI/Strings.cs @@ -31,7 +31,7 @@ Error message: {0}", error); } public static string WebserverPortDescription { get { return LC.L(@"The port the webserver listens on. Multiple values may be supplied with a comma in between."); } } public static string WebserverUseHTTPSDescription { get { return LC.L(@"If provided, determine whether to use HTTPS. If not provided, compatibility mode determine based on certificate presence about usage of HTTPS."); } } public static string WebserverCertificateFileDescription { get { return LC.L(@"The certificate and key file in PKCS #12 format the webserver use for SSL."); } } - public static string WebserverCertificatePasswordDescription { get { return LC.L(@"The password for decryption of certificate PKCS #12 file. USE STRONG PASSWORD, CERTIFICATE FILE WILL BE SAVED TO DRIVE ENCRYPTED BY CERTIFICATE PASSWORD!"); } } + public static string WebserverCertificatePasswordDescription { get { return LC.L(@"The password for decryption of provided certificate PKCS #12 file."); } } public static string WebserverInterfaceDescription { get { return LC.L(@"The interface the webserver listens on. The special values ""*"" and ""any"" means any interface. The special value ""loopback"" means the loopback adapter."); } } public static string WebserverPasswordDescription { get { return LC.L(@"The password required to access the webserver. This option is saved so you do not need to set it on each run. Setting an empty value disables the password."); } } public static string WebserverAllowedhostnamesDescription { get { return LC.L(@"The hostnames that are accepted, separated with semicolons. If any of the hostnames are ""*"", all hostnames are allowed and the hostname checking is disabled."); } } @@ -55,7 +55,6 @@ Error message: {0}", error); } { public static string StartedServer(string ip, int port) { return LC.L(@"Server has started and is listening on {0}, port {1}", ip, port); } public static string SSLCertificateFileMissingOption { get { return LC.L(@"SSL certificate password option has no meaning when provided without SSL certificate file option!"); } } - public static string SSLCertificatePasswordEmpty { get { return LC.L(@"Cant accept empty password for certificate, save PKCS #12 file with strong password. CERTIFICATE FILE WILL BE SAVED TO DRIVE ENCRYPTED BY CERTIFICATE PASSWORD!"); } } public static string SSLParametersMismatch { get { return LC.L(@"Mismatch in SSL parameters. Cannot enable HTTPS without certificate."); } } public static string ServerStartFailure(IEnumerable portstried) { return LC.L(@"Unable to open a socket for listening, tried ports: {0}", string.Join(",", from n in (portstried ?? new int[0]) select n.ToString())); } } diff --git a/Duplicati/Server/WebServerLoader.cs b/Duplicati/Server/WebServerLoader.cs index f2e070c7a..766398d65 100644 --- a/Duplicati/Server/WebServerLoader.cs +++ b/Duplicati/Server/WebServerLoader.cs @@ -149,15 +149,15 @@ public static class WebServerLoader options.TryGetValue(OPTION_SSLCERTIFICATEFILEPASSWORD, out var certificateFilePassword); certificateFilePassword = certificateFilePassword?.Trim() ?? ""; - if (!string.IsNullOrEmpty(certificateFile) && string.IsNullOrEmpty(certificateFilePassword)) - throw new ArgumentException(Strings.Server.SSLCertificatePasswordEmpty); - else if (string.IsNullOrEmpty(certificateFile) && !string.IsNullOrEmpty(certificateFilePassword)) + if (string.IsNullOrEmpty(certificateFile) && !string.IsNullOrEmpty(certificateFilePassword)) Library.Logging.Log.WriteInformationMessage(LOGTAG, "ServerCertificate", Strings.Server.SSLCertificateFileMissingOption); if (!string.IsNullOrEmpty(certificateFile) && !string.IsNullOrEmpty(certificateFilePassword)) { - connection.ApplicationSettings.ServerSSLCertificate = Convert.ToBase64String(File.ReadAllBytes(certificateFile)); - connection.ApplicationSettings.ServerSSLCertificatePassword = certificateFilePassword; + var cert = new X509Certificate2(certificateFile, certificateFilePassword, X509KeyStorageFlags.Exportable); + + connection.ApplicationSettings.ServerSSLCertificate = Convert.ToBase64String(cert.Export(X509ContentType.Pkcs12, connection.ApplicationSettings.ServerSSLCertificatePassword)); + connection.ApplicationSettings.ServerSSLCertificatePassword = Guid.NewGuid().ToString().ToLowerInvariant(); } else if (certificateFile != null && certificateFile.Length == 0) {