diff options
author | WouterTinus <wouter.tinus@gmail.com> | 2017-11-17 09:40:06 +0100 |
---|---|---|
committer | WouterTinus <wouter.tinus@gmail.com> | 2017-11-17 09:40:06 +0100 |
commit | 853a126bc54d6afa85c5ed985e72c691b9d36520 (patch) | |
tree | 24d64ce9a804ed082ad1921ace98f330233529b7 | |
parent | ae35ca50815c0cf7e4df315b58668d475952c1a6 (diff) | |
download | letsencrypt-win-simple-origin/install.zip letsencrypt-win-simple-origin/install.tar.gz letsencrypt-win-simple-origin/install.tar.bz2 |
Seperate target, validation and installer sitesorigin/install
20 files changed, 219 insertions, 86 deletions
diff --git a/letsencrypt-win-simple/Clients/IISClient.cs b/letsencrypt-win-simple/Clients/IISClient.cs index 9fa3a8a..09bf61d 100644 --- a/letsencrypt-win-simple/Clients/IISClient.cs +++ b/letsencrypt-win-simple/Clients/IISClient.cs @@ -1,4 +1,5 @@ using Autofac;
+using LetsEncrypt.ACME.Simple.Extensions;
using LetsEncrypt.ACME.Simple.Services;
using Microsoft.Web.Administration;
using Microsoft.Win32;
@@ -84,7 +85,8 @@ namespace LetsEncrypt.ACME.Simple.Clients public void PrepareSite(Target target)
{
var config = ServerManager.GetApplicationHostConfiguration();
- var site = GetSite(target);
+ var siteId = target.ValidationSiteId ?? target.TargetSiteId ?? -1;
+ var site = GetSite(siteId);
// Only do it for the .well-known folder, do not compromise security for other parts of the application
var wellKnown = "/.well-known";
@@ -176,7 +178,8 @@ namespace LetsEncrypt.ACME.Simple.Clients public void UnprepareSite(Target target)
{
var config = ServerManager.GetApplicationHostConfiguration();
- var site = GetSite(target);
+ var siteId = target.ValidationSiteId ?? target.TargetSiteId ?? -1;
+ var site = GetSite(siteId);
// Remove application
var rootApp = site.Applications.FirstOrDefault(x => x.Path == "/");
@@ -237,7 +240,7 @@ namespace LetsEncrypt.ACME.Simple.Clients // Find all hostnames which are not covered by any of the already updated
// bindings yet, because we will want to make sure that those are accessable
// in the target site
- var targetSite = GetSite(target);
+ var targetSite = GetSite(target.InstallationSiteId ?? target.TargetSiteId ?? -1);
IEnumerable<string> todo = target.GetHosts(true);
while (todo.Count() > 0)
{
@@ -522,13 +525,13 @@ namespace LetsEncrypt.ACME.Simple.Clients }
}
- private Site GetSite(Target target)
+ public Site GetSite(long id)
{
- foreach (var site in ServerManager.Sites)
+ foreach (var site in RunningWebsites())
{
- if (site.Id == target.SiteId) return site;
+ if (site.Id == id) return site;
}
- throw new Exception($"Unable to find IIS site ID #{target.SiteId} for binding {this}");
+ throw new Exception($"Unable to find IIS SiteId #{id}");
}
/// <summary>
@@ -548,13 +551,14 @@ namespace LetsEncrypt.ACME.Simple.Clients return IP;
}
- internal Target UpdateWebRoot(Target saved, Target match)
+ internal Target UpdateWebRoot(Target saved, Site match)
{
// Update web root path
- if (!string.Equals(saved.WebRootPath, match.WebRootPath, StringComparison.InvariantCultureIgnoreCase))
+ var newPath = match.WebRoot();
+ if (!string.Equals(saved.WebRootPath, newPath, StringComparison.InvariantCultureIgnoreCase))
{
- _log.Warning("- Change WebRootPath from {old} to {new}", saved.WebRootPath, match.WebRootPath);
- saved.WebRootPath = match.WebRootPath;
+ _log.Warning("- Change WebRootPath from {old} to {new}", saved.WebRootPath, newPath);
+ saved.WebRootPath = newPath;
}
return saved;
}
diff --git a/letsencrypt-win-simple/Configuration/Options.cs b/letsencrypt-win-simple/Configuration/Options.cs index 5048a08..b6e9338 100644 --- a/letsencrypt-win-simple/Configuration/Options.cs +++ b/letsencrypt-win-simple/Configuration/Options.cs @@ -32,7 +32,7 @@ namespace LetsEncrypt.ACME.Simple #region Target
- [Option(HelpText = "[--plugin iissite|iissites] Specify identifier for which site a plugin should run. For the iissites plugin this may be a comma separated list.")] + [Option(HelpText = "[--plugin iissite|iissites|iisbindings] Specify identifier for which site a plugin should run. For the iissites plugin this may be a comma separated list.")] public string SiteId { get; set; }
[Option(HelpText = "[--plugin iissite|iissites] Exclude bindings from being included in the certificate. This may be a comma separated list.")] @@ -54,6 +54,9 @@ namespace LetsEncrypt.ACME.Simple #region Validation
+ [Option(HelpText = "[--validation filesystem|iis] Specify site to use for handling validation requests. Defaults to --siteid.")] + public string ValidationSiteId { get; set; }
+
[Option(HelpText = "[--validationmode http-01] Warm up websites before attempting HTTP authorization.")] public bool Warmup { get; set; }
@@ -88,6 +91,9 @@ namespace LetsEncrypt.ACME.Simple #region Installation
+ [Option(HelpText = "[--installation iis] Specify site to install new bindings to. Defaults to --siteid.")] + public string InstallationSiteId { get; set; }
+
[Option(HelpText = "While renewing, do not remove the old certificates.")] public bool KeepExisting { get; set; }
diff --git a/letsencrypt-win-simple/Extensions/SiteExtensions.cs b/letsencrypt-win-simple/Extensions/SiteExtensions.cs new file mode 100644 index 0000000..353610d --- /dev/null +++ b/letsencrypt-win-simple/Extensions/SiteExtensions.cs @@ -0,0 +1,12 @@ +using Microsoft.Web.Administration; + +namespace LetsEncrypt.ACME.Simple.Extensions +{ + public static class SiteExtensions + { + public static string WebRoot(this Site site) + { + return site.Applications["/"].VirtualDirectories["/"].PhysicalPath; + } + } +} diff --git a/letsencrypt-win-simple/Plugins/InstallationPlugins/IISInstaller.cs b/letsencrypt-win-simple/Plugins/InstallationPlugins/IISInstaller.cs index 9a655a6..c7fb99f 100644 --- a/letsencrypt-win-simple/Plugins/InstallationPlugins/IISInstaller.cs +++ b/letsencrypt-win-simple/Plugins/InstallationPlugins/IISInstaller.cs @@ -57,42 +57,34 @@ namespace LetsEncrypt.ACME.Simple.Plugins.InstallationPlugins void IInstallationPlugin.Aquire(IOptionsService optionsService, IInputService inputService) { - if (_renewal.Binding.IIS == true && _renewal.Binding.SiteId > 0) + var ask = true; + if (_renewal.Binding.IIS == true) { - // No need to ask anything + ask = inputService.PromptYesNo("Use different site for installation?"); } - else + if (ask) { - var chosen = inputService.ChooseFromList("Choose site to install certificate", - _iisClient.RunningWebsites(), - x => new Choice<long>(x.Id) { Description = x.Name, Command = x.Id.ToString() }, - false); - _renewal.Binding.SiteId = chosen; + var chosen = inputService.ChooseFromList("Choose site to create new bindings", + _iisClient.RunningWebsites(), + x => new Choice<long>(x.Id) { Description = x.Name, Command = x.Id.ToString() }, + false); + _renewal.Binding.InstallationSiteId = chosen; } } void IInstallationPlugin.Default(IOptionsService optionsService) { - long siteId = _renewal.Binding.SiteId; - if (siteId == 0) + // IIS + var installationSiteId = optionsService.TryGetLong(nameof(optionsService.Options.InstallationSiteId), optionsService.Options.InstallationSiteId); + if (installationSiteId != null) { - var rawSiteId = optionsService.TryGetRequiredOption(nameof(optionsService.Options.SiteId), optionsService.Options.SiteId); - if (!long.TryParse(rawSiteId, out siteId)) - { - throw new Exception($"Invalid SiteId {optionsService.Options.SiteId}"); - } + var site = _iisClient.GetSite(installationSiteId.Value); // Throws exception when not found + _renewal.Binding.InstallationSiteId = site.Id; } - if (siteId > 0) + else if (_renewal.Binding.TargetSiteId == null) { - var found = _iisClient.RunningWebsites().FirstOrDefault(site => site.Id == siteId); - if (found != null) - { - _renewal.Binding.SiteId = found.Id; - } - else - { - throw new Exception($"Unable to find SiteId {siteId}"); - } + _log.Error("Missing parameter --{p}", nameof(optionsService.Options.InstallationSiteId).ToLower()); + throw new Exception($"Missing parameter --{nameof(optionsService.Options.InstallationSiteId).ToLower()}"); } } } diff --git a/letsencrypt-win-simple/Plugins/InstallationPlugins/IInstallationPlugin.cs b/letsencrypt-win-simple/Plugins/InstallationPlugins/IInstallationPlugin.cs index 7d1c27e..1d95bd8 100644 --- a/letsencrypt-win-simple/Plugins/InstallationPlugins/IInstallationPlugin.cs +++ b/letsencrypt-win-simple/Plugins/InstallationPlugins/IInstallationPlugin.cs @@ -30,7 +30,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.InstallationPlugins class NullInstallation : IInstallationPlugin { void IInstallationPlugin.Aquire(IOptionsService optionsService, IInputService inputService) { } - void IInstallationPlugin.Default(IOptionsService optionsService) { } + void IInstallationPlugin.Default( IOptionsService optionsService) { } void IInstallationPlugin.Install(CertificateInfo newCertificateInfo, CertificateInfo oldCertificateInfo) { } } diff --git a/letsencrypt-win-simple/Plugins/TargetPlugins/IISBinding.cs b/letsencrypt-win-simple/Plugins/TargetPlugins/IISBinding.cs index 014d22a..2930e49 100644 --- a/letsencrypt-win-simple/Plugins/TargetPlugins/IISBinding.cs +++ b/letsencrypt-win-simple/Plugins/TargetPlugins/IISBinding.cs @@ -1,4 +1,5 @@ using LetsEncrypt.ACME.Simple.Clients;
+using LetsEncrypt.ACME.Simple.Extensions;
using LetsEncrypt.ACME.Simple.Plugins.InstallationPlugins;
using LetsEncrypt.ACME.Simple.Services;
using Microsoft.Web.Administration;
@@ -32,7 +33,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins var filterSet = GetBindings(false, false);
if (long.TryParse(rawSiteId, out siteId))
{
- filterSet = filterSet.Where(x => x.SiteId == siteId).ToList();
+ filterSet = filterSet.Where(x => x.TargetSiteId == siteId).ToList();
}
return filterSet.
Where(x => x.Host == hostName).
@@ -43,7 +44,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins {
return inputService.ChooseFromList("Choose site",
GetBindings(optionsService.Options.HideHttps, true).Where(x => x.Hidden == false),
- x => Choice.Create(x, description: $"{x.Host} (SiteId {x.SiteId}) [@{x.WebRootPath}]"),
+ x => Choice.Create(x, description: $"{x.Host} (SiteId {x.TargetSiteId}) [@{x.WebRootPath}]"),
true);
}
@@ -51,7 +52,6 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins {
var match = GetBindings(false, false).FirstOrDefault(binding => string.Equals(binding.Host, scheduled.Host, StringComparison.InvariantCultureIgnoreCase));
if (match != null) {
- _iisClient.UpdateWebRoot(scheduled, match);
return scheduled;
}
_log.Error("Binding {host} not found", scheduled.Host);
@@ -89,12 +89,12 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins hidden = hidden.Contains(sb)
}).
Select(sbi => new Target {
- SiteId = sbi.site.Id,
+ TargetSiteId = sbi.site.Id,
Host = sbi.idn,
HostIsDns = true,
Hidden = sbi.hidden,
IIS = true,
- WebRootPath = sbi.site.Applications["/"].VirtualDirectories["/"].PhysicalPath
+ WebRootPath = sbi.site.WebRoot()
}).
DistinctBy(t => t.Host).
OrderBy(t => t.Host).
diff --git a/letsencrypt-win-simple/Plugins/TargetPlugins/IISSite.cs b/letsencrypt-win-simple/Plugins/TargetPlugins/IISSite.cs index f32e967..25170a4 100644 --- a/letsencrypt-win-simple/Plugins/TargetPlugins/IISSite.cs +++ b/letsencrypt-win-simple/Plugins/TargetPlugins/IISSite.cs @@ -1,5 +1,5 @@ using LetsEncrypt.ACME.Simple.Clients;
-using LetsEncrypt.ACME.Simple.Plugins.InstallationPlugins;
+using LetsEncrypt.ACME.Simple.Extensions;
using LetsEncrypt.ACME.Simple.Services;
using Microsoft.Web.Administration;
using System;
@@ -30,7 +30,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins long siteId = 0;
if (long.TryParse(rawSiteId, out siteId))
{
- var found = GetSites(false, false).FirstOrDefault(binding => binding.SiteId == siteId);
+ var found = GetSites(false, false).FirstOrDefault(binding => binding.TargetSiteId == siteId);
if (found != null)
{
found.ExcludeBindings = optionsService.Options.ExcludeBindings;
@@ -66,14 +66,13 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins Target ITargetPlugin.Refresh(Target scheduled)
{
- var match = GetSites(false, false).FirstOrDefault(binding => binding.SiteId == scheduled.SiteId);
+ var match = GetSites(false, false).FirstOrDefault(binding => binding.TargetSiteId == scheduled.TargetSiteId);
if (match != null)
{
- _iisClient.UpdateWebRoot(scheduled, match);
_iisClient.UpdateAlternativeNames(scheduled, match);
return scheduled;
}
- _log.Error("SiteId {id} not found", scheduled.SiteId);
+ _log.Error("SiteId {id} not found", scheduled.TargetSiteId);
return null;
}
@@ -100,11 +99,11 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins var targets = sites.
Select(site => new Target {
- SiteId = site.Id,
+ TargetSiteId = site.Id,
Host = site.Name,
HostIsDns = false,
Hidden = hidden.Contains(site),
- WebRootPath = site.Applications["/"].VirtualDirectories["/"].PhysicalPath,
+ WebRootPath = site.WebRoot(),
IIS = true,
AlternativeNames = GetHosts(site)
}).
diff --git a/letsencrypt-win-simple/Plugins/TargetPlugins/IISSites.cs b/letsencrypt-win-simple/Plugins/TargetPlugins/IISSites.cs index 7143abf..886b616 100644 --- a/letsencrypt-win-simple/Plugins/TargetPlugins/IISSites.cs +++ b/letsencrypt-win-simple/Plugins/TargetPlugins/IISSites.cs @@ -37,7 +37,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins int id = -1;
if (int.TryParse(idString, out id))
{
- var site = targets.Where(t => t.SiteId == id).FirstOrDefault();
+ var site = targets.Where(t => t.TargetSiteId == id).FirstOrDefault();
if (site != null)
{
siteList.Add(site);
@@ -60,11 +60,13 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins }
Target totalTarget = new Target
{
- Host = string.Join(",", siteList.Select(x => x.SiteId)),
+ Host = string.Join(",", siteList.Select(x => x.TargetSiteId)),
HostIsDns = false,
IIS = true,
WebRootPath = "x", // prevent validation plugin from trying to fetch it from options
- SiteId = -1, // prevent installation plugin from trying to fetch it from options
+ TargetSiteId = -1,
+ ValidationSiteId = -1,
+ InstallationSiteId = -1,
AlternativeNames = siteList.SelectMany(x => x.AlternativeNames).Distinct().ToList()
};
return totalTarget;
@@ -73,7 +75,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins Target ITargetPlugin.Aquire(IOptionsService optionsService, IInputService inputService)
{ List<Target> targets = GetSites(optionsService.Options.HideHttps, true).Where(x => x.Hidden == false).ToList(); - inputService.WritePagedList(targets.Select(x => Choice.Create(x, $"{x.Host} ({x.AlternativeNames.Count()} bindings) [@{x.WebRootPath}]", x.SiteId.ToString())).ToList()); + inputService.WritePagedList(targets.Select(x => Choice.Create(x, $"{x.Host} ({x.AlternativeNames.Count()} bindings) [@{x.WebRootPath}]", x.TargetSiteId.ToString())).ToList()); var sanInput = inputService.RequestString("Enter a comma separated list of site IDs, or 'S' to run for all sites").ToLower().Trim(); var totalTarget = GetCombinedTarget(targets, sanInput);
inputService.WritePagedList(totalTarget.AlternativeNames.Select(x => Choice.Create(x, "")));
@@ -95,9 +97,11 @@ namespace LetsEncrypt.ACME.Simple.Plugins.TargetPlugins {
List<Target> targets = GetSites(false, false); string[] siteIDs = scheduled.Host.Split(',');
- var filtered = targets.Where(t => siteIDs.Contains(t.SiteId.ToString())).ToList();
+ var filtered = targets.Where(t => siteIDs.Contains(t.TargetSiteId.ToString())).ToList();
filtered.ForEach(x => {
x.SSLPort = scheduled.SSLPort;
+ x.ValidationSiteId = scheduled.ValidationSiteId;
+ x.InstallationSiteId = scheduled.InstallationSiteId;
x.ExcludeBindings = scheduled.ExcludeBindings;
x.ValidationPluginName = scheduled.ValidationPluginName;
x.DnsAzureOptions = scheduled.DnsAzureOptions;
diff --git a/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/FileSystem.cs b/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/FileSystem.cs index 9bf8b09..70ab992 100644 --- a/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/FileSystem.cs +++ b/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/FileSystem.cs @@ -1,6 +1,8 @@ using ACMESharp;
+using LetsEncrypt.ACME.Simple.Clients;
using LetsEncrypt.ACME.Simple.Extensions;
using LetsEncrypt.ACME.Simple.Services;
+using Microsoft.Web.Administration;
using System;
using System.IO;
using System.Linq;
@@ -17,8 +19,13 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http class FileSystem : HttpValidation
{
- public FileSystem(ScheduledRenewal target, ILogService logService, IInputService inputService, ProxyService proxyService) :
- base(logService, inputService, proxyService, target) {}
+ protected IISClient _iisClient;
+
+ public FileSystem(ScheduledRenewal target, IISClient iisClient, ILogService logService, IInputService inputService, ProxyService proxyService) :
+ base(logService, inputService, proxyService, target)
+ {
+ _iisClient = iisClient;
+ }
public override void DeleteFile(string path)
{
@@ -53,6 +60,20 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http public override void Default(Target target, IOptionsService optionsService)
{
base.Default(target, optionsService);
+
+ // IIS
+ if (target.IIS == true && IISClient.Version.Major > 0)
+ {
+ var validationSiteId = optionsService.TryGetLong(nameof(optionsService.Options.ValidationSiteId), optionsService.Options.ValidationSiteId);
+ if (validationSiteId != null)
+ {
+ var site = _iisClient.GetSite(validationSiteId.Value); // Throws exception when not found
+ target.ValidationSiteId = validationSiteId;
+ target.WebRootPath = site.WebRoot();
+ }
+ }
+
+ // Manual
if (string.IsNullOrEmpty(target.WebRootPath))
{
do
@@ -66,13 +87,52 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http public override void Aquire(Target target, IOptionsService optionsService, IInputService inputService)
{
base.Aquire(target, optionsService, inputService);
+
+ // Choose alternative site for validation
+ if (target.IIS == true && IISClient.Version.Major > 0)
+ {
+ if (inputService.PromptYesNo("Use different site for validation?"))
+ {
+ var site = inputService.ChooseFromList("Validation site, must receive requests for all hosts on port 80",
+ _iisClient.RunningWebsites(),
+ x => new Choice<Site>(x) { Command = x.Id.ToString(), Description = x.Name }, true);
+ if (site != null)
+ {
+ target.ValidationSiteId = site.Id;
+ target.WebRootPath = site.WebRoot();
+ }
+ }
+ }
+
+ // Manual
if (string.IsNullOrEmpty(target.WebRootPath))
{
do
{
target.WebRootPath = optionsService.TryGetOption(optionsService.Options.WebRoot, _input, "Enter a site path (the web root of the host for http authentication)");
}
- while (!target.WebRootPath.ValidPath(_log));
+ while (!ValidateWebroot(target));
+ }
+ }
+
+ /// <summary>
+ /// Update webroot
+ /// </summary>
+ /// <param name="scheduled"></param>
+ public override void Refresh(Target scheduled)
+ {
+ // IIS
+ var siteId = scheduled.ValidationSiteId ?? scheduled.TargetSiteId;
+ if (siteId != null)
+ {
+ var site = _iisClient.GetSite(siteId.Value); // Throws exception when not found
+ _iisClient.UpdateWebRoot(scheduled, site);
+ }
+
+ // IIS & Manual
+ if (!ValidateWebroot(scheduled))
+ {
+ throw new Exception("Invalid WebRoot");
}
}
}
diff --git a/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/IIS.cs b/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/IIS.cs index d9e17f8..2af559a 100644 --- a/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/IIS.cs +++ b/letsencrypt-win-simple/Plugins/ValidationPlugins/Http/IIS.cs @@ -2,6 +2,7 @@ using ACMESharp.ACME; using LetsEncrypt.ACME.Simple.Clients; using LetsEncrypt.ACME.Simple.Services; +using Microsoft.Web.Administration; namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http { @@ -13,18 +14,14 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http AcmeProtocol.CHALLENGE_TYPE_HTTP) { } - public override bool CanValidate(Target target) => target.IIS == true && target.SiteId > 0; + public override bool CanValidate(Target target) => target.IIS == true && target.TargetSiteId > 0; } class IIS : FileSystem { - private IISClient _iisClient; public IIS(ScheduledRenewal target, IISClient iisClient, ILogService logService, IInputService inputService, ProxyService proxyService) : - base(target, logService, inputService, proxyService) - { - _iisClient = iisClient; - } + base(target, iisClient, logService, inputService, proxyService) { } public override void BeforeAuthorize(Target target, HttpChallenge challenge) { @@ -38,8 +35,26 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Http base.BeforeDelete(target, challenge); } - public override void Default(Target target, IOptionsService optionsService) { } + public override void Default(Target target, IOptionsService optionsService) + { + var validationSiteIdRaw = optionsService.Options.ValidationSiteId; + long validationSiteId; + if (long.TryParse(validationSiteIdRaw, out validationSiteId)) + { + _iisClient.GetSite(validationSiteId); // Throws exception when not found + target.ValidationSiteId = validationSiteId; + } + } + + public override void Aquire(Target target, IOptionsService optionsService, IInputService inputService) + { + if (inputService.PromptYesNo("Use different site for validation?")) + { + target.ValidationSiteId = inputService.ChooseFromList("Validation site, must receive requests for all hosts on port 80", + _iisClient.RunningWebsites(), + x => new Choice<long>(x.Id) { Command = x.Id.ToString(), Description = x.Name }, true); + } + } - public override void Aquire(Target target, IOptionsService optionsService, IInputService inputService) { } } } diff --git a/letsencrypt-win-simple/Plugins/ValidationPlugins/HttpValidation.cs b/letsencrypt-win-simple/Plugins/ValidationPlugins/HttpValidation.cs index ba4cef9..ea585e4 100644 --- a/letsencrypt-win-simple/Plugins/ValidationPlugins/HttpValidation.cs +++ b/letsencrypt-win-simple/Plugins/ValidationPlugins/HttpValidation.cs @@ -1,6 +1,5 @@ using ACMESharp;
using ACMESharp.ACME;
-using Autofac;
using LetsEncrypt.ACME.Simple.Services;
using System;
using System.Diagnostics;
@@ -33,6 +32,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins throw new ArgumentException(nameof(target.WebRootPath));
} var httpChallenge = challenge.Challenge as HttpChallenge; + Refresh(target); CreateAuthorizationFile(target, httpChallenge); BeforeAuthorize(target, httpChallenge);
@@ -259,11 +259,14 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins if (target.IIS == null)
{
target.IIS = optionsService.Options.ManualTargetIsIIS;
- if (target.IIS == null)
- {
- target.IIS = false;
- }
}
}
+
+ /// <summary>
+ /// Refresh
+ /// </summary>
+ /// <param name="scheduled"></param>
+ /// <returns></returns>
+ public virtual void Refresh(Target scheduled) { }
}
}
diff --git a/letsencrypt-win-simple/Plugins/ValidationPlugins/Tls/IIS.cs b/letsencrypt-win-simple/Plugins/ValidationPlugins/Tls/IIS.cs index 666ce80..5812a8d 100644 --- a/letsencrypt-win-simple/Plugins/ValidationPlugins/Tls/IIS.cs +++ b/letsencrypt-win-simple/Plugins/ValidationPlugins/Tls/IIS.cs @@ -33,10 +33,7 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins.Tls _storePlugin = store;
_iisClient = iisClient;
_optionsService = optionsService;
- if (target.Binding.IIS == true)
- {
- _tempSiteId = target.Binding.SiteId;
- }
+ _tempSiteId = target.Binding.ValidationSiteId ?? target.Binding.TargetSiteId;
}
public override bool CanValidate(Target target)
diff --git a/letsencrypt-win-simple/Plugins/ValidationPlugins/TlsValidation.cs b/letsencrypt-win-simple/Plugins/ValidationPlugins/TlsValidation.cs index 55769af..7b0c43c 100644 --- a/letsencrypt-win-simple/Plugins/ValidationPlugins/TlsValidation.cs +++ b/letsencrypt-win-simple/Plugins/ValidationPlugins/TlsValidation.cs @@ -68,15 +68,14 @@ namespace LetsEncrypt.ACME.Simple.Plugins.ValidationPlugins hash = GetHash(hash);
var san = string.Empty;
X509Certificate2 cert = null;
- try
+ do
{
- cert = GenerateCertificate(hash, out san);
- }
- catch (CryptographicException)
- {
- // Retry in case of unlucky random numbers
- cert = GenerateCertificate(hash, out san);
- }
+ try
+ {
+ cert = GenerateCertificate(hash, out san);
+ }
+ catch (CryptographicException) { }
+ } while (cert == null);
ret.Add(new CertificateInfo() { Certificate = cert });
}
return ret;
diff --git a/letsencrypt-win-simple/Program.cs b/letsencrypt-win-simple/Program.cs index a700e4a..cd66d79 100644 --- a/letsencrypt-win-simple/Program.cs +++ b/letsencrypt-win-simple/Program.cs @@ -236,6 +236,10 @@ namespace LetsEncrypt.ACME.Simple try
{
var installFactories = scope.Resolve<List<IInstallationPluginFactory>>();
+ if (installFactories.Count == 0)
+ {
+ // User cancelled, otherwise we would at least have the Null-installer
+ }
foreach (var installFactory in installFactories)
{
var installInstance = (IInstallationPlugin)scope.Resolve(installFactory.Instance);
@@ -503,7 +507,6 @@ namespace LetsEncrypt.ACME.Simple {
return new AuthorizationState { Status = "invalid" };
}
-
_log.Information("Authorizing {dnsIdentifier} using {challengeType} validation ({name})", identifier, validationPluginFactory.ChallengeType, validationPluginFactory.Name);
var challenge = client.Acme.DecodeChallenge(authzState, validationPluginFactory.ChallengeType);
var cleanUp = validationPlugin.PrepareChallenge(renewal, challenge, identifier);
diff --git a/letsencrypt-win-simple/ScheduledRenewal.cs b/letsencrypt-win-simple/ScheduledRenewal.cs index 77b8054..e279e38 100644 --- a/letsencrypt-win-simple/ScheduledRenewal.cs +++ b/letsencrypt-win-simple/ScheduledRenewal.cs @@ -110,6 +110,7 @@ namespace LetsEncrypt.ACME.Simple /// Get the most recent thumbprint
/// </summary>
/// <returns></returns>
+ [JsonIgnore]
public string Thumbprint
{
get
diff --git a/letsencrypt-win-simple/Services/Interfaces/IOptionsService.cs b/letsencrypt-win-simple/Services/Interfaces/IOptionsService.cs index f392808..5897cb6 100644 --- a/letsencrypt-win-simple/Services/Interfaces/IOptionsService.cs +++ b/letsencrypt-win-simple/Services/Interfaces/IOptionsService.cs @@ -7,5 +7,6 @@ string TryGetOption(string providedValue, IInputService input, string what, bool secret = false); string TryGetOption(string providedValue, IInputService input, string[] what, bool secret = false); string TryGetRequiredOption(string optionName, string providedValue); + long? TryGetLong(string optionName, string providedValue); } }
\ No newline at end of file diff --git a/letsencrypt-win-simple/Services/OptionsService.cs b/letsencrypt-win-simple/Services/OptionsService.cs index 34615e7..b64325c 100644 --- a/letsencrypt-win-simple/Services/OptionsService.cs +++ b/letsencrypt-win-simple/Services/OptionsService.cs @@ -109,5 +109,20 @@ namespace LetsEncrypt.ACME.Simple.Services } return providedValue; } + + public long? TryGetLong(string optionName, string providedValue) + { + if (string.IsNullOrEmpty(providedValue)) + { + return null; + } + long output; + if (long.TryParse(providedValue, out output)) + { + return output; + } + _log.Error("Invalid value for --{optionName}", optionName.ToLower()); + throw new Exception($"Invalid value for --{optionName.ToLower()}"); + } } } diff --git a/letsencrypt-win-simple/Services/RenewalService.cs b/letsencrypt-win-simple/Services/RenewalService.cs index 9a3efe9..bac01ff 100644 --- a/letsencrypt-win-simple/Services/RenewalService.cs +++ b/letsencrypt-win-simple/Services/RenewalService.cs @@ -163,6 +163,11 @@ namespace LetsEncrypt.ACME.Simple.Services result.Binding.IIS = !(result.Binding.PluginName == nameof(Manual)); } + if (result.Binding.TargetSiteId == null) + { + result.Binding.TargetSiteId = result.Binding.SiteId; + } + return result; } diff --git a/letsencrypt-win-simple/Target.cs b/letsencrypt-win-simple/Target.cs index e27fe71..8859fa4 100644 --- a/letsencrypt-win-simple/Target.cs +++ b/letsencrypt-win-simple/Target.cs @@ -44,9 +44,25 @@ namespace LetsEncrypt.ACME.Simple /// <summary>
/// Identify the IIS website that the target is based on
/// </summary> + [Obsolete] public long SiteId { get; set; } /// <summary>
+ /// Site used to get bindings from
+ /// </summary> + public long? TargetSiteId { get; set; } + + /// <summary>
+ /// Site used to handle validation requests
+ /// </summary> + public long? ValidationSiteId { get; set; } + + /// <summary>
+ /// Site used to install newly detected bindings
+ /// </summary> + public long? InstallationSiteId { get; set; } + + /// <summary>
/// Port to create new SSL bindings on
/// </summary> public int SSLPort { get; set; } @@ -108,9 +124,9 @@ namespace LetsEncrypt.ACME.Simple {
x.Append($"{Host} ");
}
- if (SiteId > 0)
+ if (TargetSiteId.HasValue)
{
- x.Append($"(SiteId {SiteId}) ");
+ x.Append($"(SiteId {TargetSiteId.Value}) ");
}
x.Append("[");
var num = AlternativeNames.Count();
diff --git a/letsencrypt-win-simple/letsencrypt-win-simple.csproj b/letsencrypt-win-simple/letsencrypt-win-simple.csproj index bc2bc62..b100234 100644 --- a/letsencrypt-win-simple/letsencrypt-win-simple.csproj +++ b/letsencrypt-win-simple/letsencrypt-win-simple.csproj @@ -242,6 +242,7 @@ <Compile Include="AutofacBuilder.cs" />
<Compile Include="Exceptions.cs" />
<Compile Include="Extensions\DateExtensions.cs" />
+ <Compile Include="Extensions\SiteExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="MainMenu.cs" />
<Compile Include="Plugins\IHasName.cs" />
|