From 36e1ba66c76d979ba2494a5b39d7055f092ae940 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 24 Oct 2017 08:45:48 -0400 Subject: [PATCH] cert builder --- util/Setup/CertBuilder.cs | 84 ++++++++++++++++++++++++++++ util/Setup/NginxConfigBuilder.cs | 49 ++++++++--------- util/Setup/Program.cs | 94 +++++--------------------------- 3 files changed, 122 insertions(+), 105 deletions(-) create mode 100644 util/Setup/CertBuilder.cs diff --git a/util/Setup/CertBuilder.cs b/util/Setup/CertBuilder.cs new file mode 100644 index 0000000000..fee547150f --- /dev/null +++ b/util/Setup/CertBuilder.cs @@ -0,0 +1,84 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +namespace Bit.Setup +{ + public class CertBuilder + { + public CertBuilder(string domain, string identityCertPassword, bool letsEncrypt, bool ssl) + { + Domain = domain; + IdentityCertPassword = identityCertPassword; + LetsEncrypt = letsEncrypt; + Ssl = ssl; + } + + public string Domain { get; private set; } + public bool LetsEncrypt { get; private set; } + public bool Ssl { get; private set; } + public string IdentityCertPassword { get; private set; } + + public bool BuildForInstall() + { + var selfSignedSsl = false; + if(!Ssl) + { + Directory.CreateDirectory($"/bitwarden/ssl/self/{Domain}/"); + Console.WriteLine("Generating self signed SSL certificate."); + Ssl = selfSignedSsl = true; + Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 365 " + + $"-keyout /bitwarden/ssl/self/{Domain}/private.key " + + $"-out /bitwarden/ssl/self/{Domain}/certificate.crt " + + $"-subj \"/C=US/ST=New York/L=New York/O=8bit Solutions LLC/OU=bitwarden/CN={Domain}\""); + } + + if(LetsEncrypt) + { + Directory.CreateDirectory($"/bitwarden/letsencrypt/live/{Domain}/"); + Exec($"openssl dhparam -out /bitwarden/letsencrypt/live/{Domain}/dhparam.pem 2048"); + } + + Console.WriteLine("Generating key for IdentityServer."); + Directory.CreateDirectory("/bitwarden/identity/"); + Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout identity.key " + + "-out identity.crt -subj \"/CN=bitwarden IdentityServer\" -days 10950"); + Exec("openssl pkcs12 -export -out /bitwarden/identity/identity.pfx -inkey identity.key " + + $"-in identity.crt -certfile identity.crt -passout pass:{IdentityCertPassword}"); + + return selfSignedSsl; + } + + private string Exec(string cmd) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden + } + }; + + if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var escapedArgs = cmd.Replace("\"", "\\\""); + process.StartInfo.FileName = "/bin/bash"; + process.StartInfo.Arguments = $"-c \"{escapedArgs}\""; + } + else + { + process.StartInfo.FileName = "powershell"; + process.StartInfo.Arguments = cmd; + } + + process.Start(); + var result = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + return result; + } + } +} diff --git a/util/Setup/NginxConfigBuilder.cs b/util/Setup/NginxConfigBuilder.cs index 29a5d5e0cf..b070657dd0 100644 --- a/util/Setup/NginxConfigBuilder.cs +++ b/util/Setup/NginxConfigBuilder.cs @@ -34,12 +34,32 @@ namespace Bit.Setup public void BuildForInstaller() { - Build(true); + if(Ssl && !SelfSignedSsl && !LetsEncrypt) + { + Console.Write("(!) Use Diffie Hellman ephemeral parameters for SSL (requires dhparam.pem)? (y/n): "); + DiffieHellman = Console.ReadLine().ToLowerInvariant() == "y"; + } + else + { + DiffieHellman = LetsEncrypt; + } + + if(Ssl && !SelfSignedSsl && !LetsEncrypt) + { + Console.Write("(!) Is this a trusted SSL certificate (requires ca.crt)? (y/n): "); + Trusted = Console.ReadLine().ToLowerInvariant() == "y"; + } + else + { + Trusted = LetsEncrypt; + } + + Build(); } public void BuildForUpdater() { - Build(false); + Build(); } public bool UpdateContext() @@ -58,31 +78,8 @@ namespace Bit.Setup return true; } - private void Build(bool installer) + private void Build() { - if(installer) - { - if(Ssl && !SelfSignedSsl && !LetsEncrypt) - { - Console.Write("(!) Use Diffie Hellman ephemeral parameters for SSL (requires dhparam.pem)? (y/n): "); - DiffieHellman = Console.ReadLine().ToLowerInvariant() == "y"; - } - else - { - DiffieHellman = LetsEncrypt; - } - - if(Ssl && !SelfSignedSsl && !LetsEncrypt) - { - Console.Write("(!) Is this a trusted SSL certificate (requires ca.crt)? (y/n): "); - Trusted = Console.ReadLine().ToLowerInvariant() == "y"; - } - else - { - Trusted = LetsEncrypt; - } - } - Directory.CreateDirectory("/bitwarden/nginx/"); var sslPath = LetsEncrypt ? $"/etc/letsencrypt/live/{Domain}" : diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index c4683485ae..b3396ef9fe 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -3,11 +3,8 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data.SqlClient; -using System.Diagnostics; -using System.IO; using System.Net.Http; using System.Reflection; -using System.Runtime.InteropServices; namespace Bit.Setup { @@ -15,11 +12,6 @@ namespace Bit.Setup { private static string[] _args = null; private static IDictionary _parameters = null; - private static string _domain = null; - private static string _identityCertPassword = null; - private static bool _ssl = false; - private static bool _selfSignedSsl = false; - private static bool _letsEncrypt = false; private static Guid? _installationId = null; private static string _installationKey = null; @@ -49,9 +41,9 @@ namespace Bit.Setup { var outputDir = _parameters.ContainsKey("out") ? _parameters["out"].ToLowerInvariant() : "/etc/bitwarden"; - _domain = _parameters.ContainsKey("domain") ? + var domain = _parameters.ContainsKey("domain") ? _parameters["domain"].ToLowerInvariant() : "localhost"; - _letsEncrypt = _parameters.ContainsKey("letsencrypt") ? + var letsEncrypt = _parameters.ContainsKey("letsencrypt") ? _parameters["letsencrypt"].ToLowerInvariant() == "y" : false; if(!ValidateInstallation()) @@ -59,24 +51,26 @@ namespace Bit.Setup return; } - _ssl = _letsEncrypt; - if(!_letsEncrypt) + var ssl = letsEncrypt; + if(!letsEncrypt) { Console.Write("(!) Do you have a SSL certificate to use? (y/n): "); - _ssl = Console.ReadLine().ToLowerInvariant() == "y"; + ssl = Console.ReadLine().ToLowerInvariant() == "y"; - if(_ssl) + if(ssl) { Console.WriteLine("Make sure 'certificate.crt' and 'private.key' are provided in the " + "appropriate directory (see setup instructions)."); } } - _identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true); - MakeCerts(); + var identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true); + var certBuilder = new CertBuilder(domain, identityCertPassword, letsEncrypt, ssl); + var selfSignedSsl = certBuilder.BuildForInstall(); + ssl = certBuilder.Ssl; // Ssl prop can get flipped during the build - var url = _ssl ? $"https://{_domain}" : $"http://{_domain}"; - var nginxBuilder = new NginxConfigBuilder(_domain, _ssl, _selfSignedSsl, _letsEncrypt); + var url = ssl ? $"https://{domain}" : $"http://{domain}"; + var nginxBuilder = new NginxConfigBuilder(domain, ssl, selfSignedSsl, letsEncrypt); nginxBuilder.BuildForInstaller(); Console.Write("(!) Do you want to use push notifications? (y/n): "); @@ -85,8 +79,8 @@ namespace Bit.Setup var environmentFileBuilder = new EnvironmentFileBuilder { DatabasePassword = Helpers.SecureRandomString(32), - Domain = _domain, - IdentityCertPassword = _identityCertPassword, + Domain = domain, + IdentityCertPassword = identityCertPassword, InstallationId = _installationId, InstallationKey = _installationKey, OutputDirectory = outputDir, @@ -95,7 +89,7 @@ namespace Bit.Setup }; environmentFileBuilder.Build(); - var appSettingsBuilder = new AppSettingsBuilder(url, _domain); + var appSettingsBuilder = new AppSettingsBuilder(url, domain); appSettingsBuilder.Build(); var appIdBuilder = new AppIdBuilder(url); @@ -221,33 +215,6 @@ namespace Bit.Setup } } - private static void MakeCerts() - { - if(!_ssl) - { - Directory.CreateDirectory($"/bitwarden/ssl/self/{_domain}/"); - Console.WriteLine("Generating self signed SSL certificate."); - _ssl = _selfSignedSsl = true; - Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 365 " + - $"-keyout /bitwarden/ssl/self/{_domain}/private.key " + - $"-out /bitwarden/ssl/self/{_domain}/certificate.crt " + - $"-subj \"/C=US/ST=New York/L=New York/O=8bit Solutions LLC/OU=bitwarden/CN={_domain}\""); - } - - if(_letsEncrypt) - { - Directory.CreateDirectory($"/bitwarden/letsencrypt/live/{_domain}/"); - Exec($"openssl dhparam -out /bitwarden/letsencrypt/live/{_domain}/dhparam.pem 2048"); - } - - Console.WriteLine("Generating key for IdentityServer."); - Directory.CreateDirectory("/bitwarden/identity/"); - Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout identity.key " + - "-out identity.crt -subj \"/CN=bitwarden IdentityServer\" -days 10950"); - Exec("openssl pkcs12 -export -out /bitwarden/identity/identity.pfx -inkey identity.key " + - $"-in identity.crt -certfile identity.crt -passout pass:{_identityCertPassword}"); - } - private static void RebuildConfigs() { var url = Helpers.GetValueFronEnvFile("global", "globalSettings__baseServiceUri__vault"); @@ -284,36 +251,5 @@ namespace Bit.Setup return dict; } - - private static string Exec(string cmd) - { - var process = new Process - { - StartInfo = new ProcessStartInfo - { - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden - } - }; - - if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var escapedArgs = cmd.Replace("\"", "\\\""); - process.StartInfo.FileName = "/bin/bash"; - process.StartInfo.Arguments = $"-c \"{escapedArgs}\""; - } - else - { - process.StartInfo.FileName = "powershell"; - process.StartInfo.Arguments = cmd; - } - - process.Start(); - var result = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); - return result; - } } }