btcpayserver/BTCPayServer/Configuration/BTCPayServerOptions.cs

207 lines
8.1 KiB
C#
Raw Normal View History

2020-06-29 04:44:35 +02:00
using System;
2017-09-13 08:47:34 +02:00
using System.IO;
2020-06-28 10:55:27 +02:00
using System.Linq;
2017-09-13 08:47:34 +02:00
using System.Net;
2020-06-28 10:55:27 +02:00
using BTCPayServer.Logging;
using BTCPayServer.SSH;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NBitcoin;
using Serilog.Events;
2017-09-13 08:47:34 +02:00
namespace BTCPayServer.Configuration
{
public class BTCPayServerOptions
{
public ChainName NetworkType
{
get; set;
}
public string ConfigurationFile
{
get;
private set;
2018-12-20 14:40:32 +01:00
}
public string LogFile
{
get;
private set;
}
public EndPoint SocksEndpoint { get; set; }
2020-06-28 10:55:27 +02:00
2018-01-12 08:00:31 +01:00
public bool DisableRegistration
{
get;
private set;
}
public static string GetDebugLog(IConfiguration configuration)
{
2019-11-14 10:49:04 +01:00
var logfile = configuration.GetValue<string>("debuglog", null);
if (!string.IsNullOrEmpty(logfile))
{
if (!Path.IsPathRooted(logfile))
{
logfile = Path.Combine(new DataDirectories().Configure(configuration).DataDir, logfile);
2019-11-14 10:49:04 +01:00
}
}
return logfile;
}
public static LogEventLevel GetDebugLogLevel(IConfiguration configuration)
{
var raw = configuration.GetValue("debugloglevel", nameof(LogEventLevel.Debug));
2018-12-20 14:40:32 +01:00
return (LogEventLevel)Enum.Parse(typeof(LogEventLevel), raw, true);
}
public void LoadArgs(IConfiguration conf)
{
2018-04-19 09:54:25 +02:00
NetworkType = DefaultConfiguration.GetNetworkType(conf);
2018-04-19 09:54:25 +02:00
Logs.Configuration.LogInformation("Network: " + NetworkType.ToString());
2017-09-13 08:47:34 +02:00
if (conf.GetOrDefault<bool>("launchsettings", false) && NetworkType != ChainName.Regtest)
throw new ConfigException($"You need to run BTCPayServer with the run.sh or run.ps1 script");
BundleJsCss = conf.GetOrDefault<bool>("bundlejscss", true);
DockerDeployment = conf.GetOrDefault<bool>("dockerdeployment", true);
AllowAdminRegistration = conf.GetOrDefault<bool>("allow-admin-registration", false);
TorrcFile = conf.GetOrDefault<string>("torrcfile", null);
TorServices = conf.GetOrDefault<string>("torservices", null)
?.Split(new[] {';', ','}, StringSplitOptions.RemoveEmptyEntries);
if (!string.IsNullOrEmpty(TorrcFile) && TorServices != null)
throw new ConfigException($"torrcfile or torservices should be provided, but not both");
2019-03-31 06:16:05 +02:00
var socksEndpointString = conf.GetOrDefault<string>("socksendpoint", null);
2020-06-28 10:55:27 +02:00
if (!string.IsNullOrEmpty(socksEndpointString))
2019-03-31 06:16:05 +02:00
{
if (!Utils.TryParseEndpoint(socksEndpointString, 9050, out var endpoint))
throw new ConfigException("Invalid value for socksendpoint");
SocksEndpoint = endpoint;
}
2020-06-28 10:55:27 +02:00
UpdateUrl = conf.GetOrDefault<Uri>("updateurl", null);
2018-04-05 08:50:23 +02:00
2018-08-13 02:43:59 +02:00
var sshSettings = ParseSSHConfiguration(conf);
2018-08-12 16:23:26 +02:00
if ((!string.IsNullOrEmpty(sshSettings.Password) || !string.IsNullOrEmpty(sshSettings.KeyFile)) && !string.IsNullOrEmpty(sshSettings.Server))
{
2018-08-13 02:43:59 +02:00
int waitTime = 0;
while (!string.IsNullOrEmpty(sshSettings.KeyFile) && !File.Exists(sshSettings.KeyFile))
{
if (waitTime++ < 5)
2018-08-13 02:43:59 +02:00
System.Threading.Thread.Sleep(1000);
else
throw new ConfigException($"sshkeyfile does not exist");
}
if (sshSettings.Port > ushort.MaxValue ||
sshSettings.Port < ushort.MinValue)
throw new ConfigException($"ssh port is invalid");
if (!string.IsNullOrEmpty(sshSettings.Password) && !string.IsNullOrEmpty(sshSettings.KeyFile))
throw new ConfigException($"sshpassword or sshkeyfile should be provided, but not both");
try
{
sshSettings.CreateConnectionInfo();
SSHSettings = sshSettings;
}
catch (NotSupportedException ex)
{
Logs.Configuration.LogWarning($"The SSH key is not supported ({ex.Message}), try to generate the key with ssh-keygen using \"-m PEM\". Skipping SSH configuration...");
}
catch
{
throw new ConfigException($"sshkeyfilepassword is invalid");
}
}
2018-08-12 16:23:26 +02:00
var fingerPrints = conf.GetOrDefault<string>("sshtrustedfingerprints", "");
if (!string.IsNullOrEmpty(fingerPrints))
{
2018-08-13 02:43:59 +02:00
foreach (var fingerprint in fingerPrints.Split(';', StringSplitOptions.RemoveEmptyEntries))
2018-08-12 16:23:26 +02:00
{
2018-08-13 02:43:59 +02:00
if (!SSHFingerprint.TryParse(fingerprint, out var f))
throw new ConfigException($"Invalid ssh fingerprint format {fingerprint}");
SSHSettings?.TrustedFingerprints.Add(f);
2018-08-12 16:23:26 +02:00
}
}
2018-04-05 08:50:23 +02:00
RootPath = conf.GetOrDefault<string>("rootpath", "/");
if (!RootPath.StartsWith("/", StringComparison.InvariantCultureIgnoreCase))
RootPath = "/" + RootPath;
2018-03-20 18:09:25 +01:00
var old = conf.GetOrDefault<Uri>("internallightningnode", null);
if (old != null)
throw new ConfigException($"internallightningnode is deprecated and should not be used anymore, use btclightning instead");
LogFile = GetDebugLog(conf);
if (!string.IsNullOrEmpty(LogFile))
{
Logs.Configuration.LogInformation("LogFile: " + LogFile);
Logs.Configuration.LogInformation("Log Level: " + GetDebugLogLevel(conf));
}
DisableRegistration = conf.GetOrDefault<bool>("disable-registration", true);
PluginRemote = conf.GetOrDefault("plugin-remote", "btcpayserver/btcpayserver-plugins");
RecommendedPlugins = conf.GetOrDefault("recommended-plugins", "").ToLowerInvariant().Split('\r','\n','\t',' ').Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray();
}
2018-08-12 16:23:26 +02:00
public string PluginRemote { get; set; }
public string[] RecommendedPlugins { get; set; }
2018-08-13 02:43:59 +02:00
private SSHSettings ParseSSHConfiguration(IConfiguration conf)
2018-08-12 16:23:26 +02:00
{
2018-08-13 02:43:59 +02:00
var settings = new SSHSettings();
settings.Server = conf.GetOrDefault<string>("sshconnection", null);
if (settings.Server != null)
2018-08-12 16:23:26 +02:00
{
2018-08-13 02:43:59 +02:00
var parts = settings.Server.Split(':');
if (parts.Length == 2 && int.TryParse(parts[1], out int port))
{
settings.Port = port;
settings.Server = parts[0];
}
else
{
settings.Port = 22;
}
2018-08-12 16:23:26 +02:00
2018-08-13 02:43:59 +02:00
parts = settings.Server.Split('@');
if (parts.Length == 2)
{
settings.Username = parts[0];
settings.Server = parts[1];
}
else
{
settings.Username = "root";
}
2018-08-12 16:23:26 +02:00
}
2018-08-13 02:43:59 +02:00
settings.Password = conf.GetOrDefault<string>("sshpassword", "");
settings.KeyFile = conf.GetOrDefault<string>("sshkeyfile", "");
settings.AuthorizedKeysFile = conf.GetOrDefault<string>("sshauthorizedkeys", "");
2018-08-13 02:43:59 +02:00
settings.KeyFilePassword = conf.GetOrDefault<string>("sshkeyfilepassword", "");
return settings;
2018-08-12 16:23:26 +02:00
}
2018-04-05 08:50:23 +02:00
public string RootPath { get; set; }
public bool DockerDeployment { get; set; }
public bool BundleJsCss
{
get;
set;
}
public bool AllowAdminRegistration { get; set; }
public SSHSettings SSHSettings
{
get;
set;
}
public string TorrcFile { get; set; }
public string[] TorServices { get; set; }
public Uri UpdateUrl { get; set; }
}
2017-09-13 08:47:34 +02:00
}