Added ssl support (config file only)

pull/2/head
Mark McDowall 11 years ago
parent 48dbc127a7
commit 2b85b7f466

@ -20,6 +20,8 @@ namespace NzbDrone.Core.Configuration
void SaveConfigDictionary(Dictionary<string, object> configValues); void SaveConfigDictionary(Dictionary<string, object> configValues);
int Port { get; } int Port { get; }
int SslPort { get; }
bool EnableSsl { get; }
bool LaunchBrowser { get; } bool LaunchBrowser { get; }
bool AuthenticationEnabled { get; } bool AuthenticationEnabled { get; }
string Username { get; } string Username { get; }
@ -27,6 +29,7 @@ namespace NzbDrone.Core.Configuration
string LogLevel { get; } string LogLevel { get; }
string Branch { get; } string Branch { get; }
bool Torrent { get; } bool Torrent { get; }
string SslCertHash { get; }
} }
public class ConfigFileProvider : IConfigFileProvider public class ConfigFileProvider : IConfigFileProvider
@ -90,6 +93,16 @@ namespace NzbDrone.Core.Configuration
get { return GetValueInt("Port", 8989); } get { return GetValueInt("Port", 8989); }
} }
public int SslPort
{
get { return GetValueInt("SslPort", 9898); }
}
public bool EnableSsl
{
get { return GetValueBoolean("EnableSsl", false); }
}
public bool LaunchBrowser public bool LaunchBrowser
{ {
get { return GetValueBoolean("LaunchBrowser", true); } get { return GetValueBoolean("LaunchBrowser", true); }
@ -125,6 +138,11 @@ namespace NzbDrone.Core.Configuration
get { return GetValue("LogLevel", "Info"); } get { return GetValue("LogLevel", "Info"); }
} }
public string SslCertHash
{
get { return GetValue("SslCertHash", ""); }
}
public int GetValueInt(string key, int defaultValue) public int GetValueInt(string key, int defaultValue)
{ {
return Convert.ToInt32(GetValue(key, defaultValue)); return Convert.ToInt32(GetValue(key, defaultValue));

@ -0,0 +1,39 @@
using System;
using NLog;
using NzbDrone.Common.Processes;
namespace NzbDrone.Host.AccessControl
{
public interface INetshProvider
{
ProcessOutput Run(string arguments);
}
public class NetshProvider : INetshProvider
{
private readonly IProcessProvider _processProvider;
private readonly Logger _logger;
public NetshProvider(IProcessProvider processProvider, Logger logger)
{
_processProvider = processProvider;
_logger = logger;
}
public ProcessOutput Run(string arguments)
{
try
{
var output = _processProvider.StartAndCapture("netsh.exe", arguments);
return output;
}
catch (Exception ex)
{
_logger.WarnException("Error executing netsh with arguments: " + arguments, ex);
}
return null;
}
}
}

@ -0,0 +1,55 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Host.AccessControl
{
public interface ISslAdapter
{
void Register();
}
public class SslAdapter : ISslAdapter
{
private const string APP_ID = "C2172AF4-F9A6-4D91-BAEE-C2E4EE680613";
private readonly INetshProvider _netshProvider;
private readonly IConfigFileProvider _configFileProvider;
private readonly Logger _logger;
public SslAdapter(INetshProvider netshProvider, IConfigFileProvider configFileProvider, Logger logger)
{
_netshProvider = netshProvider;
_configFileProvider = configFileProvider;
_logger = logger;
}
public void Register()
{
if (!_configFileProvider.EnableSsl) return;
if (IsRegistered()) return;
if (String.IsNullOrWhiteSpace(_configFileProvider.SslCertHash))
{
_logger.Warn("Unable to enable SSL, SSL Cert Hash is required");
return;
}
var arguments = String.Format("netsh http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}", _configFileProvider.SslPort, _configFileProvider.SslCertHash, APP_ID);
_netshProvider.Run(arguments);
}
private bool IsRegistered()
{
var ipPort = "0.0.0.0:" + _configFileProvider.SslPort;
var arguments = String.Format("http show sslcert ipport={0}", ipPort);
var output = _netshProvider.Run(arguments);
if (output == null || !output.Standard.Any()) return false;
return output.Standard.Any(line => line.Contains(ipPort));
}
}
}

@ -1,9 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Processes;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
namespace NzbDrone.Host.AccessControl namespace NzbDrone.Host.AccessControl
@ -11,43 +9,50 @@ namespace NzbDrone.Host.AccessControl
public interface IUrlAclAdapter public interface IUrlAclAdapter
{ {
void ConfigureUrl(); void ConfigureUrl();
string UrlAcl { get; } string Url { get; }
string HttpsUrl { get; }
} }
public class UrlAclAdapter : IUrlAclAdapter public class UrlAclAdapter : IUrlAclAdapter
{ {
private const string URL_ACL = "http://{0}:{1}/"; private readonly INetshProvider _netshProvider;
private readonly IProcessProvider _processProvider;
private readonly IConfigFileProvider _configFileProvider; private readonly IConfigFileProvider _configFileProvider;
private readonly IRuntimeInfo _runtimeInfo; private readonly IRuntimeInfo _runtimeInfo;
private readonly Logger _logger; private readonly Logger _logger;
public string UrlAcl { get; private set; } public string Url { get; private set; }
public string HttpsUrl { get; private set; }
private string _localUrl; private string _localUrl;
private string _wildcardUrl; private string _wildcardUrl;
private string _localHttpsUrl;
private string _wildcardHttpsUrl;
public UrlAclAdapter(IProcessProvider processProvider, public UrlAclAdapter(INetshProvider netshProvider,
IConfigFileProvider configFileProvider, IConfigFileProvider configFileProvider,
IRuntimeInfo runtimeInfo, IRuntimeInfo runtimeInfo,
Logger logger) Logger logger)
{ {
_processProvider = processProvider; _netshProvider = netshProvider;
_configFileProvider = configFileProvider; _configFileProvider = configFileProvider;
_runtimeInfo = runtimeInfo; _runtimeInfo = runtimeInfo;
_logger = logger; _logger = logger;
_localUrl = String.Format(URL_ACL, "localhost", _configFileProvider.Port); _localUrl = String.Format("http://localhost:{0}/", _configFileProvider.Port);
_wildcardUrl = String.Format(URL_ACL, "*", _configFileProvider.Port); _wildcardUrl = String.Format("http://*:{0}/", _configFileProvider.Port);
_localHttpsUrl = String.Format("https://localhost:{0}/", _configFileProvider.SslPort);
_wildcardHttpsUrl = String.Format("https://*:{0}/", _configFileProvider.SslPort);
UrlAcl = _wildcardUrl; Url = _wildcardUrl;
HttpsUrl = _wildcardHttpsUrl;
} }
public void ConfigureUrl() public void ConfigureUrl()
{ {
if (!_runtimeInfo.IsAdmin && !IsRegistered) if (!_runtimeInfo.IsAdmin)
{ {
UrlAcl = _localUrl; if (!IsRegistered(_wildcardUrl)) Url = _localUrl;
if (!IsRegistered(_wildcardHttpsUrl)) HttpsUrl = _localHttpsUrl;
} }
if (_runtimeInfo.IsAdmin) if (_runtimeInfo.IsAdmin)
@ -61,42 +66,24 @@ namespace NzbDrone.Host.AccessControl
if (OsInfo.Version.Major < 6) if (OsInfo.Version.Major < 6)
return; return;
RegisterUrl(); RegisterUrl(Url);
RegisterUrl(HttpsUrl);
} }
private bool IsRegistered private bool IsRegistered(string urlAcl)
{ {
get var arguments = String.Format("http show urlacl {0}", urlAcl);
{ var output = _netshProvider.Run(arguments);
var arguments = String.Format("http show urlacl {0}", _wildcardUrl);
var output = RunNetsh(arguments);
if (output == null || !output.Standard.Any()) return false; if (output == null || !output.Standard.Any()) return false;
return output.Standard.Any(line => line.Contains(_wildcardUrl)); return output.Standard.Any(line => line.Contains(urlAcl));
}
}
private void RegisterUrl()
{
var arguments = String.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", UrlAcl);
RunNetsh(arguments);
} }
private ProcessOutput RunNetsh(string arguments) private void RegisterUrl(string urlAcl)
{ {
try var arguments = String.Format("http add urlacl {0} sddl=D:(A;;GX;;;S-1-1-0)", urlAcl);
{ _netshProvider.Run(arguments);
var output = _processProvider.StartAndCapture("netsh.exe", arguments);
return output;
}
catch (Exception ex)
{
_logger.WarnException("Error executing netsh with arguments: " + arguments, ex);
}
return null;
} }
} }
} }

@ -117,6 +117,8 @@
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs"> <Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link> <Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="AccessControl\NetshProvider.cs" />
<Compile Include="AccessControl\SslAdapter.cs" />
<Compile Include="ApplicationServer.cs"> <Compile Include="ApplicationServer.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>

@ -21,17 +21,24 @@ namespace NzbDrone.Host.Owin
private readonly IRuntimeInfo _runtimeInfo; private readonly IRuntimeInfo _runtimeInfo;
private readonly IUrlAclAdapter _urlAclAdapter; private readonly IUrlAclAdapter _urlAclAdapter;
private readonly IFirewallAdapter _firewallAdapter; private readonly IFirewallAdapter _firewallAdapter;
private readonly ISslAdapter _sslAdapter;
private readonly Logger _logger; private readonly Logger _logger;
private IDisposable _host; private IDisposable _host;
public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable<IOwinMiddleWare> owinMiddleWares, public OwinHostController(IConfigFileProvider configFileProvider,
IRuntimeInfo runtimeInfo, IUrlAclAdapter urlAclAdapter, IFirewallAdapter firewallAdapter, Logger logger) IEnumerable<IOwinMiddleWare> owinMiddleWares,
IRuntimeInfo runtimeInfo,
IUrlAclAdapter urlAclAdapter,
IFirewallAdapter firewallAdapter,
ISslAdapter sslAdapter,
Logger logger)
{ {
_configFileProvider = configFileProvider; _configFileProvider = configFileProvider;
_owinMiddleWares = owinMiddleWares; _owinMiddleWares = owinMiddleWares;
_runtimeInfo = runtimeInfo; _runtimeInfo = runtimeInfo;
_urlAclAdapter = urlAclAdapter; _urlAclAdapter = urlAclAdapter;
_firewallAdapter = firewallAdapter; _firewallAdapter = firewallAdapter;
_sslAdapter = sslAdapter;
_logger = logger; _logger = logger;
} }
@ -44,17 +51,24 @@ namespace NzbDrone.Host.Owin
if (_runtimeInfo.IsAdmin) if (_runtimeInfo.IsAdmin)
{ {
_firewallAdapter.MakeAccessible(); _firewallAdapter.MakeAccessible();
_sslAdapter.Register();
} }
_urlAclAdapter.ConfigureUrl(); _urlAclAdapter.ConfigureUrl();
} }
var options = new StartOptions(_urlAclAdapter.UrlAcl) var options = new StartOptions(_urlAclAdapter.Url)
{ {
ServerFactory = "Microsoft.Owin.Host.HttpListener" ServerFactory = "Microsoft.Owin.Host.HttpListener"
}; };
_logger.Info("starting server on {0}", _urlAclAdapter.UrlAcl); if (_configFileProvider.EnableSsl)
{
_logger.Trace("SSL enabled, listening on: {0}", _urlAclAdapter.HttpsUrl);
options.Urls.Add(_urlAclAdapter.HttpsUrl);
}
_logger.Info("starting server on {0}", _urlAclAdapter.Url);
try try
{ {

Loading…
Cancel
Save