2023-01-10 21:58:41 +01:00
|
|
|
|
using Microsoft.Data.SqlClient;
|
2017-10-24 04:45:59 +02:00
|
|
|
|
|
|
|
|
|
namespace Bit.Setup;
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2017-10-24 04:45:59 +02:00
|
|
|
|
public class EnvironmentFileBuilder
|
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
private readonly Context _context;
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2017-11-07 04:55:15 +01:00
|
|
|
|
private IDictionary<string, string> _globalValues;
|
2017-10-24 04:45:59 +02:00
|
|
|
|
private IDictionary<string, string> _mssqlValues;
|
2018-08-30 17:35:44 +02:00
|
|
|
|
private IDictionary<string, string> _globalOverrideValues;
|
2021-11-16 18:52:02 +01:00
|
|
|
|
private IDictionary<string, string> _mssqlOverrideValues;
|
|
|
|
|
private IDictionary<string, string> _keyConnectorOverrideValues;
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2017-10-24 04:45:59 +02:00
|
|
|
|
public EnvironmentFileBuilder(Context context)
|
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
_context = context;
|
|
|
|
|
_globalValues = new Dictionary<string, string>
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["ASPNETCORE_ENVIRONMENT"] = "Production",
|
|
|
|
|
["globalSettings__selfHosted"] = "true",
|
|
|
|
|
["globalSettings__baseServiceUri__vault"] = "http://localhost",
|
|
|
|
|
["globalSettings__pushRelayBaseUri"] = "https://push.bitwarden.com",
|
2022-08-29 22:06:55 +02:00
|
|
|
|
};
|
2018-08-30 17:35:44 +02:00
|
|
|
|
_mssqlValues = new Dictionary<string, string>
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["ACCEPT_EULA"] = "Y",
|
|
|
|
|
["MSSQL_PID"] = "Express",
|
|
|
|
|
["SA_PASSWORD"] = "SECRET",
|
2022-08-29 22:06:55 +02:00
|
|
|
|
};
|
|
|
|
|
}
|
2018-08-30 17:35:44 +02:00
|
|
|
|
|
|
|
|
|
public void BuildForInstaller()
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2021-11-16 18:52:02 +01:00
|
|
|
|
Directory.CreateDirectory("/bitwarden/env/");
|
|
|
|
|
Init();
|
2022-08-29 22:06:55 +02:00
|
|
|
|
Build();
|
|
|
|
|
}
|
2017-11-07 04:55:15 +01:00
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
public void BuildForUpdater()
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
|
|
|
|
Init();
|
2018-08-30 17:35:44 +02:00
|
|
|
|
LoadExistingValues(_globalOverrideValues, "/bitwarden/env/global.override.env");
|
|
|
|
|
LoadExistingValues(_mssqlOverrideValues, "/bitwarden/env/mssql.override.env");
|
|
|
|
|
LoadExistingValues(_keyConnectorOverrideValues, "/bitwarden/env/key-connector.override.env");
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
if (_context.Config.PushNotifications &&
|
|
|
|
|
_globalOverrideValues.ContainsKey("globalSettings__pushRelayBaseUri") &&
|
|
|
|
|
_globalOverrideValues["globalSettings__pushRelayBaseUri"] == "REPLACE")
|
|
|
|
|
{
|
|
|
|
|
_globalOverrideValues.Remove("globalSettings__pushRelayBaseUri");
|
|
|
|
|
}
|
2017-10-24 04:45:59 +02:00
|
|
|
|
|
2024-10-31 17:13:57 +01:00
|
|
|
|
if (_globalOverrideValues.TryGetValue("globalSettings__baseServiceUri__vault", out var vaultUri) && vaultUri != _context.Config.Url)
|
|
|
|
|
{
|
|
|
|
|
_globalOverrideValues["globalSettings__baseServiceUri__vault"] = _context.Config.Url;
|
|
|
|
|
Helpers.WriteLine(_context, "Updated globalSettings__baseServiceUri__vault to match value in config.yml");
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-07 04:55:15 +01:00
|
|
|
|
Build();
|
2022-08-29 22:06:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-11-07 04:55:15 +01:00
|
|
|
|
private void Init()
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2017-11-07 04:55:15 +01:00
|
|
|
|
var dbPassword = _context.Stub ? "RANDOM_DATABASE_PASSWORD" : Helpers.SecureRandomString(32);
|
2018-11-01 04:32:22 +01:00
|
|
|
|
var dbConnectionString = new SqlConnectionStringBuilder
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-11-01 04:32:22 +01:00
|
|
|
|
DataSource = "tcp:mssql,1433",
|
2021-07-02 19:08:53 +02:00
|
|
|
|
InitialCatalog = _context.Install?.Database ?? "vault",
|
2018-11-01 04:32:22 +01:00
|
|
|
|
UserID = "sa",
|
|
|
|
|
Password = dbPassword,
|
2017-11-07 04:55:15 +01:00
|
|
|
|
MultipleActiveResultSets = false,
|
2018-11-01 04:32:22 +01:00
|
|
|
|
Encrypt = true,
|
|
|
|
|
ConnectTimeout = 30,
|
|
|
|
|
TrustServerCertificate = true,
|
2017-11-07 04:55:15 +01:00
|
|
|
|
PersistSecurityInfo = false
|
2018-11-01 04:32:22 +01:00
|
|
|
|
}.ConnectionString;
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
_globalOverrideValues = new Dictionary<string, string>
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["globalSettings__baseServiceUri__vault"] = _context.Config.Url,
|
2023-07-31 19:14:33 +02:00
|
|
|
|
["globalSettings__baseServiceUri__cloudRegion"] = _context.Install?.CloudRegion.ToString(),
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["globalSettings__sqlServer__connectionString"] = $"\"{dbConnectionString.Replace("\"", "\\\"")}\"",
|
2017-11-07 04:55:15 +01:00
|
|
|
|
["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword,
|
|
|
|
|
["globalSettings__internalIdentityKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :
|
2019-03-15 16:19:52 +01:00
|
|
|
|
Helpers.SecureRandomString(64, alpha: true, numeric: true),
|
2020-07-16 14:01:39 +02:00
|
|
|
|
["globalSettings__oidcIdentityClientKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :
|
|
|
|
|
Helpers.SecureRandomString(64, alpha: true, numeric: true),
|
2019-03-15 16:19:52 +01:00
|
|
|
|
["globalSettings__duo__aKey"] = _context.Stub ? "RANDOM_DUO_AKEY" :
|
|
|
|
|
Helpers.SecureRandomString(64, alpha: true, numeric: true),
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["globalSettings__installation__id"] = _context.Install?.InstallationId.ToString(),
|
|
|
|
|
["globalSettings__installation__key"] = _context.Install?.InstallationKey,
|
2017-11-07 04:55:15 +01:00
|
|
|
|
["globalSettings__yubico__clientId"] = "REPLACE",
|
|
|
|
|
["globalSettings__yubico__key"] = "REPLACE",
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["globalSettings__mail__replyToEmail"] = $"no-reply@{_context.Config.Domain}",
|
2017-11-07 04:55:15 +01:00
|
|
|
|
["globalSettings__mail__smtp__host"] = "REPLACE",
|
2019-01-23 03:28:56 +01:00
|
|
|
|
["globalSettings__mail__smtp__port"] = "587",
|
|
|
|
|
["globalSettings__mail__smtp__ssl"] = "false",
|
2017-11-07 04:55:15 +01:00
|
|
|
|
["globalSettings__mail__smtp__username"] = "REPLACE",
|
|
|
|
|
["globalSettings__mail__smtp__password"] = "REPLACE",
|
|
|
|
|
["globalSettings__disableUserRegistration"] = "false",
|
2019-07-23 03:24:04 +02:00
|
|
|
|
["globalSettings__hibpApiKey"] = "REPLACE",
|
2018-03-28 16:45:30 +02:00
|
|
|
|
["adminSettings__admins"] = string.Empty,
|
2022-08-29 22:06:55 +02:00
|
|
|
|
};
|
|
|
|
|
|
2017-11-07 04:55:15 +01:00
|
|
|
|
if (!_context.Config.PushNotifications)
|
2017-10-24 04:45:59 +02:00
|
|
|
|
{
|
|
|
|
|
_globalOverrideValues.Add("globalSettings__pushRelayBaseUri", "REPLACE");
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_mssqlOverrideValues = new Dictionary<string, string>
|
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["SA_PASSWORD"] = dbPassword,
|
2023-05-25 22:57:47 +02:00
|
|
|
|
["DATABASE"] = _context.Install?.Database ?? "vault"
|
2018-08-30 17:35:44 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_keyConnectorOverrideValues = new Dictionary<string, string>
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["keyConnectorSettings__webVaultUri"] = _context.Config.Url,
|
2021-11-16 18:52:02 +01:00
|
|
|
|
["keyConnectorSettings__identityServerUri"] = "http://identity:5000",
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["keyConnectorSettings__database__provider"] = "json",
|
|
|
|
|
["keyConnectorSettings__database__jsonFilePath"] = "/etc/bitwarden/key-connector/data.json",
|
|
|
|
|
["keyConnectorSettings__rsaKey__provider"] = "certificate",
|
|
|
|
|
["keyConnectorSettings__certificate__provider"] = "filesystem",
|
2021-11-16 18:52:02 +01:00
|
|
|
|
["keyConnectorSettings__certificate__filesystemPath"] = "/etc/bitwarden/key-connector/bwkc.pfx",
|
2018-08-30 17:35:44 +02:00
|
|
|
|
["keyConnectorSettings__certificate__filesystemPassword"] = Helpers.SecureRandomString(32, alpha: true, numeric: true),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 19:36:37 +01:00
|
|
|
|
private void LoadExistingValues(IDictionary<string, string> _values, string file)
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2017-11-07 04:55:15 +01:00
|
|
|
|
if (!File.Exists(file))
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2020-03-27 19:36:37 +01:00
|
|
|
|
return;
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
var fileLines = File.ReadAllLines(file);
|
|
|
|
|
foreach (var line in fileLines)
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
|
|
|
|
if (!line.Contains("="))
|
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
continue;
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
var value = string.Empty;
|
|
|
|
|
var lineParts = line.Split("=", 2);
|
|
|
|
|
if (lineParts.Length < 1)
|
2017-10-24 04:45:59 +02:00
|
|
|
|
{
|
2017-11-07 04:55:15 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-11-16 18:52:02 +01:00
|
|
|
|
|
|
|
|
|
if (lineParts.Length > 1)
|
|
|
|
|
{
|
|
|
|
|
value = lineParts[1];
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_values.ContainsKey(lineParts[0]))
|
|
|
|
|
{
|
|
|
|
|
_values[lineParts[0]] = value;
|
|
|
|
|
}
|
2020-03-27 19:36:37 +01:00
|
|
|
|
else
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
|
|
|
|
_values.Add(lineParts[0], value.Replace("\\\"", "\""));
|
2017-10-24 04:45:59 +02:00
|
|
|
|
}
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
2022-08-29 22:06:55 +02:00
|
|
|
|
}
|
2017-10-24 04:45:59 +02:00
|
|
|
|
|
2017-11-07 04:55:15 +01:00
|
|
|
|
private void Build()
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
var template = Helpers.ReadTemplate("EnvironmentFile");
|
2022-08-29 22:06:55 +02:00
|
|
|
|
|
2019-03-12 15:26:14 +01:00
|
|
|
|
Helpers.WriteLine(_context, "Building docker environment files.");
|
2017-11-07 04:55:15 +01:00
|
|
|
|
Directory.CreateDirectory("/bitwarden/docker/");
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/docker/global.env"))
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
sw.Write(template(new TemplateModel(_globalValues)));
|
2022-08-29 22:06:55 +02:00
|
|
|
|
}
|
2018-08-30 17:35:44 +02:00
|
|
|
|
Helpers.Exec("chmod 600 /bitwarden/docker/global.env");
|
|
|
|
|
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/docker/mssql.env"))
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
sw.Write(template(new TemplateModel(_mssqlValues)));
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
2017-12-21 04:31:30 +01:00
|
|
|
|
Helpers.Exec("chmod 600 /bitwarden/docker/mssql.env");
|
|
|
|
|
|
2020-03-27 19:36:37 +01:00
|
|
|
|
Helpers.WriteLine(_context, "Building docker environment override files.");
|
2018-08-30 17:35:44 +02:00
|
|
|
|
Directory.CreateDirectory("/bitwarden/env/");
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/env/global.override.env"))
|
2017-10-24 04:45:59 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
sw.Write(template(new TemplateModel(_globalOverrideValues)));
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
2017-12-21 04:31:30 +01:00
|
|
|
|
Helpers.Exec("chmod 600 /bitwarden/env/global.override.env");
|
|
|
|
|
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/env/mssql.override.env"))
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
sw.Write(template(new TemplateModel(_mssqlOverrideValues)));
|
2017-11-07 04:55:15 +01:00
|
|
|
|
}
|
2017-12-21 04:31:30 +01:00
|
|
|
|
Helpers.Exec("chmod 600 /bitwarden/env/mssql.override.env");
|
|
|
|
|
|
2021-11-16 18:52:02 +01:00
|
|
|
|
if (_context.Config.EnableKeyConnector)
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/env/key-connector.override.env"))
|
2017-11-07 04:55:15 +01:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
sw.Write(template(new TemplateModel(_keyConnectorOverrideValues)));
|
2017-10-24 04:45:59 +02:00
|
|
|
|
}
|
2018-03-27 21:23:02 +02:00
|
|
|
|
|
2018-08-30 17:35:44 +02:00
|
|
|
|
Helpers.Exec("chmod 600 /bitwarden/env/key-connector.override.env");
|
2022-08-29 21:53:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-27 21:23:02 +02:00
|
|
|
|
// Empty uid env file. Only used on Linux hosts.
|
2020-03-27 19:36:37 +01:00
|
|
|
|
if (!File.Exists("/bitwarden/env/uid.env"))
|
2018-05-31 18:05:26 +02:00
|
|
|
|
{
|
2020-03-27 19:36:37 +01:00
|
|
|
|
using (var sw = File.CreateText("/bitwarden/env/uid.env")) { }
|
2017-10-24 04:45:59 +02:00
|
|
|
|
}
|
2022-08-29 22:06:55 +02:00
|
|
|
|
}
|
2018-08-30 17:35:44 +02:00
|
|
|
|
|
|
|
|
|
public class TemplateModel
|
2022-08-29 22:06:55 +02:00
|
|
|
|
{
|
2018-08-30 17:35:44 +02:00
|
|
|
|
public TemplateModel(IEnumerable<KeyValuePair<string, string>> variables)
|
|
|
|
|
{
|
|
|
|
|
Variables = variables.Select(v => new Kvp { Key = v.Key, Value = v.Value });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<Kvp> Variables { get; set; }
|
|
|
|
|
|
|
|
|
|
public class Kvp
|
|
|
|
|
{
|
|
|
|
|
public string Key { get; set; }
|
|
|
|
|
public string Value { get; set; }
|
|
|
|
|
}
|
2017-10-24 04:45:59 +02:00
|
|
|
|
}
|
|
|
|
|
}
|