Added ssl support (config file only)

This commit is contained in:
Mark McDowall 2013-09-22 12:57:03 -07:00
parent 48dbc127a7
commit 2b85b7f466
6 changed files with 166 additions and 51 deletions

View File

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

View File

@ -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;
}
}
}

View File

@ -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));
}
}
}

View File

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

View File

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

View File

@ -21,17 +21,24 @@ namespace NzbDrone.Host.Owin
private readonly IRuntimeInfo _runtimeInfo;
private readonly IUrlAclAdapter _urlAclAdapter;
private readonly IFirewallAdapter _firewallAdapter;
private readonly ISslAdapter _sslAdapter;
private readonly Logger _logger;
private IDisposable _host;
public OwinHostController(IConfigFileProvider configFileProvider, IEnumerable<IOwinMiddleWare> owinMiddleWares,
IRuntimeInfo runtimeInfo, IUrlAclAdapter urlAclAdapter, IFirewallAdapter firewallAdapter, Logger logger)
public OwinHostController(IConfigFileProvider configFileProvider,
IEnumerable<IOwinMiddleWare> owinMiddleWares,
IRuntimeInfo runtimeInfo,
IUrlAclAdapter urlAclAdapter,
IFirewallAdapter firewallAdapter,
ISslAdapter sslAdapter,
Logger logger)
{
_configFileProvider = configFileProvider;
_owinMiddleWares = owinMiddleWares;
_runtimeInfo = runtimeInfo;
_urlAclAdapter = urlAclAdapter;
_firewallAdapter = firewallAdapter;
_sslAdapter = sslAdapter;
_logger = logger;
}
@ -44,17 +51,24 @@ namespace NzbDrone.Host.Owin
if (_runtimeInfo.IsAdmin)
{
_firewallAdapter.MakeAccessible();
_sslAdapter.Register();
}
_urlAclAdapter.ConfigureUrl();
}
var options = new StartOptions(_urlAclAdapter.UrlAcl)
var options = new StartOptions(_urlAclAdapter.Url)
{
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
{