summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWouter Tinus <wouter.tinus@gmail.com>2020-06-13 21:02:06 +0200
committerWouter Tinus <wouter.tinus@gmail.com>2020-06-13 21:02:06 +0200
commit07b22bf0c9252b1dd31baed18b0dbfcab8e9ca5f (patch)
treeaffd2bdb435a61059ec295bc361fad11402b9878
parentadc9ee46a8035538e4ac713aa34069697e5bc886 (diff)
downloadletsencrypt-win-simple-07b22bf0c9252b1dd31baed18b0dbfcab8e9ca5f.zip
letsencrypt-win-simple-07b22bf0c9252b1dd31baed18b0dbfcab8e9ca5f.tar.gz
letsencrypt-win-simple-07b22bf0c9252b1dd31baed18b0dbfcab8e9ca5f.tar.bz2
refactor validation plugisn to remove challenge specific items, allowing them to handle multiple challenges, which is required for parallel validation
-rw-r--r--src/main.lib/Clients/EmailClient.cs3
-rw-r--r--src/main.lib/Plugins/Interfaces/IValidationPlugin.cs18
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Dns/Acme/Acme.cs12
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Dns/DnsValidation.cs24
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Dns/Manual/Manual.cs17
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs18
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs5
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs60
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/HttpValidationParameters.cs8
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs7
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/WebDav/WebDav.cs8
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs20
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Validation.cs36
-rw-r--r--src/main.lib/RenewalExecutor.cs18
-rw-r--r--src/main.lib/Services/AutofacBuilder.cs11
-rw-r--r--src/main.lib/Services/Interfaces/IAutofacBuilder.cs2
-rwxr-xr-xsrc/plugin.validation.dns.azure/Azure.cs13
-rw-r--r--src/plugin.validation.dns.cloudflare/Cloudflare.cs8
-rw-r--r--src/plugin.validation.dns.dreamhost/DreamhostDnsValidation.cs5
-rw-r--r--src/plugin.validation.dns.luadns/luadns.cs5
-rw-r--r--src/plugin.validation.dns.route53/Route53.cs12
21 files changed, 149 insertions, 161 deletions
diff --git a/src/main.lib/Clients/EmailClient.cs b/src/main.lib/Clients/EmailClient.cs
index 5c98239..4f77115 100644
--- a/src/main.lib/Clients/EmailClient.cs
+++ b/src/main.lib/Clients/EmailClient.cs
@@ -122,6 +122,7 @@ namespace PKISharp.WACS.Clients
bodyBuilder.HtmlBody = content + $"<p>Sent by win-acme version {_version} from {_computerName}</p>";
message.Body = bodyBuilder.ToMessageBody();
await client.SendAsync(message);
+ await client.DisconnectAsync(true);
}
}
catch (Exception ex)
@@ -130,7 +131,7 @@ namespace PKISharp.WACS.Clients
}
finally
{
- await client.DisconnectAsync(true);
+
}
}
}
diff --git a/src/main.lib/Plugins/Interfaces/IValidationPlugin.cs b/src/main.lib/Plugins/Interfaces/IValidationPlugin.cs
index ba899db..df5746e 100644
--- a/src/main.lib/Plugins/Interfaces/IValidationPlugin.cs
+++ b/src/main.lib/Plugins/Interfaces/IValidationPlugin.cs
@@ -1,5 +1,5 @@
using ACMESharp.Authorizations;
-using System;
+using PKISharp.WACS.DomainObjects;
using System.Threading.Tasks;
namespace PKISharp.WACS.Plugins.Interfaces
@@ -16,11 +16,23 @@ namespace PKISharp.WACS.Plugins.Interfaces
/// <param name="target"></param>
/// <param name="challenge"></param>
/// <returns></returns>
- Task PrepareChallenge(IChallengeValidationDetails challengeDetails);
+ Task PrepareChallenge(ValidationContext context, IChallengeValidationDetails challenge);
/// <summary>
/// Clean up after validation attempt
/// </summary>
- Task CleanUp();
+ Task CleanUp(ValidationContext context, IChallengeValidationDetails challenge);
}
+
+ public class ValidationContext
+ {
+ public ValidationContext(string identifier, TargetPart targetPart)
+ {
+ Identifier = identifier;
+ TargetPart = targetPart;
+ }
+ public string Identifier { get; set; }
+ public TargetPart TargetPart { get; set; }
+ }
+
}
diff --git a/src/main.lib/Plugins/ValidationPlugins/Dns/Acme/Acme.cs b/src/main.lib/Plugins/ValidationPlugins/Dns/Acme/Acme.cs
index ddcff59..b24cc38 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Dns/Acme/Acme.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Dns/Acme/Acme.cs
@@ -1,5 +1,6 @@
using PKISharp.WACS.Clients;
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Threading.Tasks;
@@ -11,7 +12,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
private readonly IInputService _input;
private readonly ProxyService _proxy;
private readonly AcmeOptions _options;
- private readonly string _identifier;
public Acme(
LookupClientProvider dnsClient,
@@ -19,12 +19,10 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
ISettingsService settings,
IInputService input,
ProxyService proxy,
- AcmeOptions options,
- string identifier) :
+ AcmeOptions options) :
base(dnsClient, log, settings)
{
_options = options;
- _identifier = identifier;
_input = input;
_proxy = proxy;
}
@@ -34,12 +32,12 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
/// </summary>
/// <param name="recordName"></param>
/// <param name="token"></param>
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
var client = new AcmeDnsClient(_dnsClient, _proxy, _log, _settings, _input, new Uri(_options.BaseUri));
- return await client.Update(_identifier, token);
+ return await client.Update(context.Identifier, token);
}
- public override Task DeleteRecord(string recordName, string token) => Task.CompletedTask;
+ public override Task DeleteRecord(ValidationContext context, string recordName, string token) => Task.CompletedTask;
}
}
diff --git a/src/main.lib/Plugins/ValidationPlugins/Dns/DnsValidation.cs b/src/main.lib/Plugins/ValidationPlugins/Dns/DnsValidation.cs
index 87e5273..d88cc47 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Dns/DnsValidation.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Dns/DnsValidation.cs
@@ -1,5 +1,7 @@
using ACMESharp.Authorizations;
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.DomainObjects;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
@@ -30,17 +32,17 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
_settings = settings;
}
- public override async Task PrepareChallenge()
+ public override async Task PrepareChallenge(ValidationContext context, Dns01ChallengeValidationDetails challenge)
{
// Check for substitute domains
_authority = await _dnsClient.GetAuthority(
- Challenge.DnsRecordName,
+ challenge.DnsRecordName,
followCnames: _settings.Validation.AllowDnsSubstitution);
var success = false;
while (!success)
{
- success = await CreateRecord(_authority.Domain, Challenge.DnsRecordValue);
+ success = await CreateRecord(context, _authority.Domain, challenge.DnsRecordValue);
if (!success)
{
if (_authority.From == null)
@@ -61,7 +63,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
var retrySeconds = _settings.Validation.PreValidateDnsRetryInterval;
while (_settings.Validation.PreValidateDns)
{
- if (await PreValidate())
+ if (await PreValidate(challenge.DnsRecordValue))
{
break;
}
@@ -82,7 +84,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
}
}
- protected async Task<bool> PreValidate()
+ protected async Task<bool> PreValidate(string expectedValue)
{
try
{
@@ -100,7 +102,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
_log.Warning("Preliminary validation failed: no TXT records found");
return false;
}
- if (!answers.Contains(Challenge.DnsRecordValue))
+ if (!answers.Contains(expectedValue))
{
_log.Debug("Preliminary validation found values: {answers}", answers);
_log.Warning("Preliminary validation failed: incorrect TXT record(s) found");
@@ -121,13 +123,13 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// <summary>
/// Delete record when we're done
/// </summary>
- public override async Task CleanUp()
+ public override async Task CleanUp(ValidationContext context, Dns01ChallengeValidationDetails challenge)
{
- if (HasChallenge && _authority != null)
+ if (_authority != null)
{
try
{
- await DeleteRecord(_authority.Domain, Challenge.DnsRecordValue);
+ await DeleteRecord(context, _authority.Domain, challenge.DnsRecordValue);
}
catch (Exception ex)
{
@@ -140,14 +142,14 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// Delete validation record
/// </summary>
/// <param name="recordName">Name of the record</param>
- public abstract Task DeleteRecord(string recordName, string token);
+ public abstract Task DeleteRecord(ValidationContext context, string recordName, string token);
/// <summary>
/// Create validation record
/// </summary>
/// <param name="recordName">Name of the record</param>
/// <param name="token">Contents of the record</param>
- public abstract Task<bool> CreateRecord(string recordName, string token);
+ public abstract Task<bool> CreateRecord(ValidationContext context, string recordName, string token);
/// <summary>
/// Match DNS zone to use from a list of all zones
diff --git a/src/main.lib/Plugins/ValidationPlugins/Dns/Manual/Manual.cs b/src/main.lib/Plugins/ValidationPlugins/Dns/Manual/Manual.cs
index c584efb..b65ea07 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Dns/Manual/Manual.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Dns/Manual/Manual.cs
@@ -1,4 +1,5 @@
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System.Threading.Tasks;
@@ -7,28 +8,24 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
internal class Manual : DnsValidation<Manual>
{
private readonly IInputService _input;
- private readonly string _identifier;
public Manual(
LookupClientProvider dnsClient,
ILogService log,
IInputService input,
- ISettingsService settings,
- string identifier)
- : base(dnsClient, log, settings)
+ ISettingsService settings) : base(dnsClient, log, settings)
{
// Usually it's a big no-no to rely on user input in validation plugin
// because this should be able to run unattended. This plugin is for testing
// only and therefor we will allow it. Future versions might be more advanced,
// e.g. shoot an email to an admin and complete the order later.
_input = input;
- _identifier = identifier;
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
_input.CreateSpace();
- _input.Show("Domain", _identifier);
+ _input.Show("Domain", context.Identifier);
_input.Show("Record", recordName);
_input.Show("Type", "TXT");
_input.Show("Content", $"\"{token}\"");
@@ -42,7 +39,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
// Pre-pre-validate, allowing the manual user to correct mistakes
while (true)
{
- if (await PreValidate())
+ if (await PreValidate(token))
{
return true;
}
@@ -61,10 +58,10 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
}
}
- public override Task DeleteRecord(string recordName, string token)
+ public override Task DeleteRecord(ValidationContext context, string recordName, string token)
{
_input.CreateSpace();
- _input.Show("Domain", _identifier);
+ _input.Show("Domain", context.Identifier);
_input.Show("Record", recordName);
_input.Show("Type", "TXT");
_input.Show("Content", $"\"{token}\"");
diff --git a/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs b/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs
index 80ece5e..0f2c6f4 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Dns/Script/Script.cs
@@ -1,5 +1,6 @@
using PKISharp.WACS.Clients;
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System.Threading.Tasks;
@@ -9,7 +10,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
{
private readonly ScriptClient _scriptClient;
private readonly ScriptOptions _options;
- private readonly string _identifier;
internal const string DefaultCreateArguments = "create {Identifier} {RecordName} {Token}";
internal const string DefaultDeleteArguments = "delete {Identifier} {RecordName} {Token}";
@@ -19,16 +19,14 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
LookupClientProvider dnsClient,
ScriptClient client,
ILogService log,
- ISettingsService settings,
- string identifier) :
+ ISettingsService settings) :
base(dnsClient, log, settings)
{
- _identifier = identifier;
_options = options;
_scriptClient = client;
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
var script = _options.Script ?? _options.CreateScript;
if (!string.IsNullOrWhiteSpace(script))
@@ -38,7 +36,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
{
args = _options.CreateScriptArguments;
}
- await _scriptClient.RunScript(script, ProcessArguments(recordName, token, args, script.EndsWith(".ps1")));
+ await _scriptClient.RunScript(script, ProcessArguments(context.Identifier, recordName, token, args, script.EndsWith(".ps1")));
return true;
}
else
@@ -48,7 +46,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
}
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
var script = _options.Script ?? _options.DeleteScript;
if (!string.IsNullOrWhiteSpace(script))
@@ -58,7 +56,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
{
args = _options.DeleteScriptArguments;
}
- await _scriptClient.RunScript(script, ProcessArguments(recordName, token, args, script.EndsWith(".ps1")));
+ await _scriptClient.RunScript(script, ProcessArguments(context.Identifier, recordName, token, args, script.EndsWith(".ps1")));
}
else
{
@@ -66,10 +64,10 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
}
}
- private string ProcessArguments(string recordName, string token, string args, bool escapeToken)
+ private string ProcessArguments(string identifier, string recordName, string token, string args, bool escapeToken)
{
var ret = args;
- ret = ret.Replace("{Identifier}", _identifier);
+ ret = ret.Replace("{Identifier}", identifier);
ret = ret.Replace("{RecordName}", recordName);
// Some tokens start with - which confuses Powershell. We did not want to
// make a breaking change for .bat or .exe files, so instead escape the
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs
index f8d5b0b..ff23950 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/FileSystem/FileSystem.cs
@@ -1,4 +1,5 @@
using PKISharp.WACS.Clients.IIS;
+using PKISharp.WACS.DomainObjects;
using System;
using System.IO;
using System.Linq;
@@ -56,12 +57,12 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http
/// Update webroot
/// </summary>
/// <param name="scheduled"></param>
- protected override void Refresh()
+ protected override void Refresh(TargetPart targetPart)
{
if (string.IsNullOrEmpty(_options.Path))
{
// Update web root path
- var siteId = _options.SiteId ?? _targetPart.SiteId;
+ var siteId = _options.SiteId ?? targetPart.SiteId;
if (siteId > 0)
{
_path = _iisClient.GetWebSite(siteId.Value).Path;
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
index bc811fe..844b92e 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
@@ -42,13 +42,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
private readonly ProxyService _proxy;
/// <summary>
- /// Current TargetPart that we are working on. A TargetPart is mainly used by
- /// the IISSites TargetPlugin to indicate that we are working with different
- /// IIS sites
- /// </summary>
- protected TargetPart _targetPart;
-
- /// <summary>
/// Where to find the template for the web.config that's copied to the webroot
/// </summary>
protected string TemplateWebConfig => Path.Combine(Path.GetDirectoryName(_settings.ExePath), "web_config.xml");
@@ -79,25 +72,24 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
_proxy = pars.ProxyService;
_settings = pars.Settings;
_renewal = pars.Renewal;
- _targetPart = pars.TargetPart;
}
/// <summary>
/// Handle http challenge
/// </summary>
- public async override Task PrepareChallenge()
+ public async override Task PrepareChallenge(ValidationContext context, Http01ChallengeValidationDetails challenge)
{
- Refresh();
- WriteAuthorizationFile();
- WriteWebConfig();
- _log.Information("Answer should now be browsable at {answerUri}", Challenge.HttpResourceUrl);
+ Refresh(context.TargetPart);
+ WriteAuthorizationFile(challenge);
+ WriteWebConfig(challenge);
+ _log.Information("Answer should now be browsable at {answerUri}", challenge.HttpResourceUrl);
if (_runLevel.HasFlag(RunLevel.Test) && _renewal.New)
{
if (await _input.PromptYesNo("[--test] Try in default browser?", false))
{
Process.Start(new ProcessStartInfo
{
- FileName = Challenge.HttpResourceUrl,
+ FileName = challenge.HttpResourceUrl,
UseShellExecute = true
});
await _input.Wait();
@@ -107,8 +99,8 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
string? foundValue = null;
try
{
- var value = await WarmupSite();
- if (Equals(value, Challenge.HttpResourceValue))
+ var value = await WarmupSite(challenge);
+ if (Equals(value, challenge.HttpResourceValue))
{
_log.Information("Preliminary validation looks good, but the ACME server will be more thorough");
}
@@ -116,7 +108,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
{
_log.Warning("Preliminary validation failed, the server answered '{value}' instead of '{expected}'. The ACME server might have a different perspective",
foundValue ?? "(null)",
- Challenge.HttpResourceValue);
+ challenge.HttpResourceValue);
}
}
catch (HttpRequestException hrex)
@@ -135,10 +127,10 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// Mostly relevant to classic FileSystem validation
/// </summary>
/// <param name="uri"></param>
- private async Task<string> WarmupSite()
+ private async Task<string> WarmupSite(Http01ChallengeValidationDetails challenge)
{
using var client = _proxy.GetHttpClient(false);
- var response = await client.GetAsync(Challenge.HttpResourceUrl);
+ var response = await client.GetAsync(challenge.HttpResourceUrl);
return await response.Content.ReadAsStringAsync();
}
@@ -147,13 +139,13 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// </summary>
/// <param name="answerPath">where the answerFile should be located</param>
/// <param name="fileContents">the contents of the file to write</param>
- private void WriteAuthorizationFile()
+ private void WriteAuthorizationFile(Http01ChallengeValidationDetails challenge)
{
if (_path == null)
{
throw new InvalidOperationException();
}
- WriteFile(CombinePath(_path, Challenge.HttpResourcePath), Challenge.HttpResourceValue);
+ WriteFile(CombinePath(_path, challenge.HttpResourcePath), challenge.HttpResourceValue);
_challengeWritten = true;
}
@@ -163,7 +155,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// <param name="target"></param>
/// <param name="answerPath"></param>
/// <param name="token"></param>
- private void WriteWebConfig()
+ private void WriteWebConfig(Http01ChallengeValidationDetails challenge)
{
if (_path == null)
{
@@ -174,8 +166,8 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
try
{
_log.Debug("Writing web.config");
- var partialPath = Challenge.HttpResourcePath.Split('/').Last();
- var destination = CombinePath(_path, Challenge.HttpResourcePath.Replace(partialPath, "web.config"));
+ var partialPath = challenge.HttpResourcePath.Split('/').Last();
+ var destination = CombinePath(_path, challenge.HttpResourcePath.Replace(partialPath, "web.config"));
var content = GetWebConfig();
WriteFile(destination, content);
_webConfigWritten = true;
@@ -199,7 +191,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// <param name="target"></param>
/// <param name="answerPath"></param>
/// <param name="token"></param>
- private void DeleteWebConfig()
+ private void DeleteWebConfig(Http01ChallengeValidationDetails challenge)
{
if (_path == null)
{
@@ -208,8 +200,8 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
if (_webConfigWritten)
{
_log.Debug("Deleting web.config");
- var partialPath = Challenge.HttpResourcePath.Split('/').Last();
- var destination = CombinePath(_path, Challenge.HttpResourcePath.Replace(partialPath, "web.config"));
+ var partialPath = challenge.HttpResourcePath.Split('/').Last();
+ var destination = CombinePath(_path, challenge.HttpResourcePath.Replace(partialPath, "web.config"));
DeleteFile(destination);
}
}
@@ -221,15 +213,15 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// <param name="token">the token</param>
/// <param name="webRootPath">the website root path</param>
/// <param name="filePath">the file path for the authorization file</param>
- private void DeleteAuthorization()
+ private void DeleteAuthorization(Http01ChallengeValidationDetails challenge)
{
try
{
if (_path != null && _challengeWritten)
{
_log.Debug("Deleting answer");
- var path = CombinePath(_path, Challenge.HttpResourcePath);
- var partialPath = Challenge.HttpResourcePath.Split('/').Last();
+ var path = CombinePath(_path, challenge.HttpResourcePath);
+ var partialPath = challenge.HttpResourcePath.Split('/').Last();
DeleteFile(path);
if (_settings.Validation.CleanupFolders)
{
@@ -319,15 +311,15 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// </summary>
/// <param name="scheduled"></param>
/// <returns></returns>
- protected virtual void Refresh() { }
+ protected virtual void Refresh(TargetPart targetPart) { }
/// <summary>
/// Dispose
/// </summary>
- public override Task CleanUp()
+ public override Task CleanUp(ValidationContext context, Http01ChallengeValidationDetails challenge)
{
- DeleteWebConfig();
- DeleteAuthorization();
+ DeleteWebConfig(challenge);
+ DeleteAuthorization(challenge);
return Task.CompletedTask;
}
}
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidationParameters.cs b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidationParameters.cs
index b1958b4..7092cdd 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidationParameters.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidationParameters.cs
@@ -7,9 +7,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
{
public ISettingsService Settings { get; private set; }
public Renewal Renewal { get; private set; }
- public TargetPart TargetPart { get; private set; }
public RunLevel RunLevel { get; private set; }
- public string Identifier { get; private set; }
public ILogService LogService { get; private set; }
public IInputService InputService { get; private set; }
public ProxyService ProxyService { get; private set; }
@@ -20,14 +18,10 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
ISettingsService settings,
ProxyService proxy,
Renewal renewal,
- TargetPart target,
- RunLevel runLevel,
- string identifier)
+ RunLevel runLevel)
{
Renewal = renewal;
- TargetPart = target;
RunLevel = runLevel;
- Identifier = identifier;
Settings = settings;
ProxyService = proxy;
LogService = log;
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs b/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs
index 6e165af..ad3d3be 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/SelfHosting/SelfHosting.cs
@@ -1,4 +1,5 @@
using ACMESharp.Authorizations;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
@@ -61,7 +62,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http
}
}
- public override Task CleanUp()
+ public override Task CleanUp(ValidationContext context, Http01ChallengeValidationDetails challenge)
{
if (HasListener)
{
@@ -77,9 +78,9 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http
return Task.CompletedTask;
}
- public override Task PrepareChallenge()
+ public override Task PrepareChallenge(ValidationContext context, Http01ChallengeValidationDetails challenge)
{
- _files.Add("/" + Challenge.HttpResourcePath, Challenge.HttpResourceValue);
+ _files.Add("/" + challenge.HttpResourcePath, challenge.HttpResourceValue);
var protocol = _options.Https == true ? "https" : "http";
var port = _options.Port ?? (_options.Https == true ?
DefaultHttpsValidationPort :
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/WebDav/WebDav.cs b/src/main.lib/Plugins/ValidationPlugins/Http/WebDav/WebDav.cs
index 990f338..9afd9d1 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/WebDav/WebDav.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/WebDav/WebDav.cs
@@ -1,4 +1,6 @@
-using PKISharp.WACS.Client;
+using ACMESharp.Authorizations;
+using PKISharp.WACS.Client;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System.Threading.Tasks;
@@ -22,9 +24,9 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Http
protected override char PathSeparator => '/';
protected override void WriteFile(string path, string content) => _webdavClient.Upload(path, content);
- public override Task CleanUp()
+ public override Task CleanUp(ValidationContext context, Http01ChallengeValidationDetails challenge)
{
- base.CleanUp();
+ base.CleanUp(context, challenge);
_webdavClient.Dispose();
return Task.CompletedTask;
}
diff --git a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
index d43d58b..baefd16 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
@@ -1,5 +1,7 @@
using ACMESharp.Authorizations;
using Org.BouncyCastle.Asn1;
+using PKISharp.WACS.DomainObjects;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
@@ -20,7 +22,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
internal const int DefaultValidationPort = 443;
private TcpListener? _listener;
private X509Certificate2? _certificate;
- private readonly string _identifier;
private readonly SelfHostingOptions _options;
private readonly ILogService _log;
private readonly IUserRoleService _userRoleService;
@@ -39,9 +40,8 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
set => _listener = value;
}
- public SelfHosting(ILogService log, string identifier, SelfHostingOptions options, IUserRoleService userRoleService)
+ public SelfHosting(ILogService log, SelfHostingOptions options, IUserRoleService userRoleService)
{
- _identifier = identifier;
_log = log;
_options = options;
_userRoleService = userRoleService;
@@ -69,7 +69,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
}
}
- public override Task CleanUp()
+ public override Task CleanUp(ValidationContext context, TlsAlpn01ChallengeValidationDetails challenge)
{
try
{
@@ -82,12 +82,12 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
return Task.CompletedTask;
}
- public override Task PrepareChallenge()
+ public override Task PrepareChallenge(ValidationContext context, TlsAlpn01ChallengeValidationDetails challenge)
{
try
{
using var rsa = RSA.Create(2048);
- var name = new X500DistinguishedName($"CN={_identifier}");
+ var name = new X500DistinguishedName($"CN={context.Identifier}");
var request = new CertificateRequest(
name,
@@ -96,7 +96,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
RSASignaturePadding.Pkcs1);
using var sha = SHA256.Create();
- var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(Challenge.TokenValue));
+ var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(challenge.TokenValue));
request.CertificateExtensions.Add(
new X509Extension(
new AsnEncodedData("1.3.6.1.5.5.7.1.31",
@@ -104,7 +104,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
true));
var sanBuilder = new SubjectAlternativeNameBuilder();
- sanBuilder.AddDnsName(_identifier);
+ sanBuilder.AddDnsName(context.Identifier);
request.CertificateExtensions.Add(sanBuilder.Build());
_certificate = request.CreateSelfSigned(
@@ -112,8 +112,8 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
new DateTimeOffset(DateTime.UtcNow.AddDays(1)));
_certificate = new X509Certificate2(
- _certificate.Export(X509ContentType.Pfx, _identifier),
- _identifier,
+ _certificate.Export(X509ContentType.Pfx, context.Identifier),
+ context.Identifier,
X509KeyStorageFlags.MachineKeySet);
_listener = new TcpListener(IPAddress.Any, _options.Port ?? DefaultValidationPort);
diff --git a/src/main.lib/Plugins/ValidationPlugins/Validation.cs b/src/main.lib/Plugins/ValidationPlugins/Validation.cs
index cb9da68..10906eb 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Validation.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Validation.cs
@@ -10,31 +10,15 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// </summary>
public abstract class Validation<TChallenge> : IValidationPlugin where TChallenge : class, IChallengeValidationDetails
{
- public bool HasChallenge => _challenge != null;
- public TChallenge Challenge
- {
- get
- {
- if (_challenge == null)
- {
- throw new InvalidOperationException();
- }
- return _challenge;
- }
- }
- private TChallenge? _challenge;
-
-
/// <summary>
/// Handle the challenge
/// </summary>
/// <param name="challenge"></param>
- public async Task PrepareChallenge(IChallengeValidationDetails challenge)
+ public async Task PrepareChallenge(ValidationContext context, IChallengeValidationDetails challenge)
{
if (challenge is TChallenge typed)
{
- _challenge = typed;
- await PrepareChallenge();
+ await PrepareChallenge(context, typed);
}
else
{
@@ -46,12 +30,24 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// Handle the challenge
/// </summary>
/// <param name="challenge"></param>
- public abstract Task PrepareChallenge();
+ public abstract Task PrepareChallenge(ValidationContext context, TChallenge typed);
/// <summary>
/// Clean up after validation
/// </summary>
- public abstract Task CleanUp();
+ public async Task CleanUp(ValidationContext context, IChallengeValidationDetails challenge)
+ {
+ if (challenge is TChallenge typed)
+ {
+ await CleanUp(context, typed);
+ }
+ else
+ {
+ throw new InvalidOperationException("Unexpected challenge type");
+ }
+ }
+
+ public abstract Task CleanUp(ValidationContext context, TChallenge typed);
/// <summary>
/// Is the plugin currently disabled
diff --git a/src/main.lib/RenewalExecutor.cs b/src/main.lib/RenewalExecutor.cs
index aa38dca..68b4ff7 100644
--- a/src/main.lib/RenewalExecutor.cs
+++ b/src/main.lib/RenewalExecutor.cs
@@ -1,4 +1,5 @@
-using Autofac;
+using ACMESharp.Authorizations;
+using Autofac;
using PKISharp.WACS.Clients.Acme;
using PKISharp.WACS.Configuration;
using PKISharp.WACS.DomainObjects;
@@ -407,8 +408,10 @@ namespace PKISharp.WACS
var client = context.Scope.Resolve<AcmeClient>();
var identifier = authorization.Identifier.Value;
var options = context.Renewal.ValidationPluginOptions;
+ IChallengeValidationDetails? challengeDetails = null;
IValidationPlugin? validationPlugin = null;
- using var validation = _scopeBuilder.Validation(context.Scope, options, targetPart, identifier);
+ ValidationContext? validationContext = null;
+ using var validation = _scopeBuilder.Validation(context.Scope, options);
try
{
if (authorization.Status == AcmeClient.AuthorizationValid)
@@ -495,8 +498,9 @@ namespace PKISharp.WACS
options.Name);
try
{
- var details = await client.DecodeChallengeValidation(authorization, challenge);
- await validationPlugin.PrepareChallenge(details);
+ var challengeValidationDetails = await client.DecodeChallengeValidation(authorization, challenge);
+ validationContext = new ValidationContext(identifier, targetPart);
+ await validationPlugin.PrepareChallenge(validationContext, challengeValidationDetails);
}
catch (Exception ex)
{
@@ -531,12 +535,14 @@ namespace PKISharp.WACS
}
finally
{
- if (validationPlugin != null)
+ if (validationPlugin != null &&
+ challengeDetails != null &&
+ validationContext != null)
{
try
{
_log.Verbose("Starting post-validation cleanup");
- await validationPlugin.CleanUp();
+ await validationPlugin.CleanUp(validationContext, challengeDetails);
_log.Verbose("Post-validation cleanup was succesful");
}
catch (Exception ex)
diff --git a/src/main.lib/Services/AutofacBuilder.cs b/src/main.lib/Services/AutofacBuilder.cs
index 5a5e4f9..00080fd 100644
--- a/src/main.lib/Services/AutofacBuilder.cs
+++ b/src/main.lib/Services/AutofacBuilder.cs
@@ -202,19 +202,12 @@ namespace PKISharp.WACS.Services
/// <param name="target"></param>
/// <param name="identifier"></param>
/// <returns></returns>
- public ILifetimeScope Validation(ILifetimeScope execution, ValidationPluginOptions options, TargetPart target, string identifier)
+ public ILifetimeScope Validation(ILifetimeScope execution, ValidationPluginOptions options)
{
return execution.BeginLifetimeScope(builder =>
{
- builder.RegisterType<HttpValidationParameters>().
- WithParameters(new[] {
- new TypedParameter(typeof(string), identifier),
- new TypedParameter(typeof(TargetPart), target)
- });
+ builder.RegisterType<HttpValidationParameters>();
builder.RegisterType(options.Instance).
- WithParameters(new[] {
- new TypedParameter(typeof(string), identifier),
- }).
As<IValidationPlugin>().
SingleInstance();
});
diff --git a/src/main.lib/Services/Interfaces/IAutofacBuilder.cs b/src/main.lib/Services/Interfaces/IAutofacBuilder.cs
index c2a3893..eb11a39 100644
--- a/src/main.lib/Services/Interfaces/IAutofacBuilder.cs
+++ b/src/main.lib/Services/Interfaces/IAutofacBuilder.cs
@@ -50,6 +50,6 @@ namespace PKISharp.WACS.Services
/// <param name="target"></param>
/// <param name="identifier"></param>
/// <returns></returns>
- ILifetimeScope Validation(ILifetimeScope execution, ValidationPluginOptions options, TargetPart target, string identifier);
+ ILifetimeScope Validation(ILifetimeScope execution, ValidationPluginOptions options);
}
}
diff --git a/src/plugin.validation.dns.azure/Azure.cs b/src/plugin.validation.dns.azure/Azure.cs
index 2d8c1e0..f3bffd3 100755
--- a/src/plugin.validation.dns.azure/Azure.cs
+++ b/src/plugin.validation.dns.azure/Azure.cs
@@ -4,6 +4,7 @@ using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;
using Microsoft.Rest.Azure.Authentication;
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
@@ -16,24 +17,20 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
internal class Azure : DnsValidation<Azure>
{
private DnsManagementClient _azureDnsClient;
- private readonly DomainParseService _domainParser;
private readonly ProxyService _proxyService;
-
private readonly AzureOptions _options;
+
public Azure(AzureOptions options,
- DomainParseService domainParser,
LookupClientProvider dnsClient,
ProxyService proxyService,
ILogService log,
- ISettingsService settings)
- : base(dnsClient, log, settings)
+ ISettingsService settings) : base(dnsClient, log, settings)
{
_options = options;
- _domainParser = domainParser;
_proxyService = proxyService;
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
var client = await GetClient();
var zone = await GetHostedZone(recordName);
@@ -128,7 +125,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
return null;
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
var client = await GetClient();
var zone = await GetHostedZone(recordName);
diff --git a/src/plugin.validation.dns.cloudflare/Cloudflare.cs b/src/plugin.validation.dns.cloudflare/Cloudflare.cs
index e770735..fb6a69a 100644
--- a/src/plugin.validation.dns.cloudflare/Cloudflare.cs
+++ b/src/plugin.validation.dns.cloudflare/Cloudflare.cs
@@ -3,6 +3,7 @@ using FluentCloudflare.Api;
using FluentCloudflare.Api.Entities;
using FluentCloudflare.Extensions;
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Linq;
@@ -23,8 +24,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
ProxyService proxyService,
LookupClientProvider dnsClient,
ILogService log,
- ISettingsService settings)
- : base(dnsClient, log, settings)
+ ISettingsService settings) : base(dnsClient, log, settings)
{
_options = options;
_hc = proxyService.GetHttpClient();
@@ -54,7 +54,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
return zonesResp.Unpack().First();
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
var ctx = GetContext();
var zone = await GetHostedZone(ctx, recordName).ConfigureAwait(false);
@@ -105,7 +105,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
var ctx = GetContext();
var zone = await GetHostedZone(ctx, recordName).ConfigureAwait(false);
diff --git a/src/plugin.validation.dns.dreamhost/DreamhostDnsValidation.cs b/src/plugin.validation.dns.dreamhost/DreamhostDnsValidation.cs
index 2e6e5db..4d5f0b2 100644
--- a/src/plugin.validation.dns.dreamhost/DreamhostDnsValidation.cs
+++ b/src/plugin.validation.dns.dreamhost/DreamhostDnsValidation.cs
@@ -1,4 +1,5 @@
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Plugins.ValidationPlugins.Dreamhost;
using PKISharp.WACS.Services;
using System;
@@ -18,7 +19,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
: base(dnsClient, logService, settings)
=> _client = new DnsManagementClient(options.ApiKey.Value, logService);
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
try
{
@@ -31,7 +32,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
}
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
try
{
diff --git a/src/plugin.validation.dns.luadns/luadns.cs b/src/plugin.validation.dns.luadns/luadns.cs
index 4935681..c03fbd7 100644
--- a/src/plugin.validation.dns.luadns/luadns.cs
+++ b/src/plugin.validation.dns.luadns/luadns.cs
@@ -1,4 +1,5 @@
using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Plugins.Interfaces;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
@@ -64,7 +65,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
_apiKey = options.APIKey.Value;
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
_log.Information("Creating LuaDNS verification record");
@@ -101,7 +102,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
return true;
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
if (!_recordsMap.ContainsKey(recordName))
{
diff --git a/src/plugin.validation.dns.route53/Route53.cs b/src/plugin.validation.dns.route53/Route53.cs
index b8bdeaf..ea0c2a2 100644
--- a/src/plugin.validation.dns.route53/Route53.cs
+++ b/src/plugin.validation.dns.route53/Route53.cs
@@ -8,23 +8,20 @@ using PKISharp.WACS.Services;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using System.Data.Common;
+using PKISharp.WACS.Plugins.Interfaces;
namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
{
internal sealed class Route53 : DnsValidation<Route53>
{
private readonly IAmazonRoute53 _route53Client;
- private readonly DomainParseService _domainParser;
public Route53(
LookupClientProvider dnsClient,
- DomainParseService domainParser,
ILogService log,
ProxyService proxy,
ISettingsService settings,
- Route53Options options)
- : base(dnsClient, log, settings)
+ Route53Options options) : base(dnsClient, log, settings)
{
var region = RegionEndpoint.USEast1;
var config = new AmazonRoute53Config() { RegionEndpoint = region };
@@ -34,7 +31,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
: !string.IsNullOrWhiteSpace(options.AccessKeyId) && !string.IsNullOrWhiteSpace(options.SecretAccessKey.Value)
? new AmazonRoute53Client(options.AccessKeyId, options.SecretAccessKey.Value, config)
: new AmazonRoute53Client(config);
- _domainParser = domainParser;
}
private static ResourceRecordSet CreateResourceRecordSet(string name, string value)
@@ -49,7 +45,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
};
}
- public override async Task<bool> CreateRecord(string recordName, string token)
+ public override async Task<bool> CreateRecord(ValidationContext context, string recordName, string token)
{
try
{
@@ -80,7 +76,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
}
}
- public override async Task DeleteRecord(string recordName, string token)
+ public override async Task DeleteRecord(ValidationContext context, string recordName, string token)
{
var hostedZoneIds = await GetHostedZoneIds(recordName);
_log.Information($"Deleting TXT record {recordName} with value {token}");