summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWouter Tinus <wouter.tinus@gmail.com>2020-06-17 20:48:31 +0200
committerWouter Tinus <wouter.tinus@gmail.com>2020-06-17 20:48:31 +0200
commitc21744bac5c93aa52ce879166abde2cee6f45e3d (patch)
tree290b51de68c9c09d3a023f13f5884889fca44c4f /src
parent8edfefc8fe0ce3c145a7370df9fa26ce7e167bca (diff)
downloadletsencrypt-win-simple-c21744bac5c93aa52ce879166abde2cee6f45e3d.zip
letsencrypt-win-simple-c21744bac5c93aa52ce879166abde2cee6f45e3d.tar.gz
letsencrypt-win-simple-c21744bac5c93aa52ce879166abde2cee6f45e3d.tar.bz2
don't attempt to validate orders which are already valid
Diffstat (limited to 'src')
-rw-r--r--src/main.lib/Context/ValidationContext.cs14
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs48
-rw-r--r--src/main.lib/RenewalExecutor.cs2
-rw-r--r--src/main.lib/RenewalValidator.cs55
-rw-r--r--src/main.test/Mock/MockContainer.cs1
-rw-r--r--src/main.test/Tests/RenewalTests/RenewalServiceTests.cs5
6 files changed, 94 insertions, 31 deletions
diff --git a/src/main.lib/Context/ValidationContext.cs b/src/main.lib/Context/ValidationContext.cs
index c5c9544..4dddb76 100644
--- a/src/main.lib/Context/ValidationContext.cs
+++ b/src/main.lib/Context/ValidationContext.cs
@@ -11,19 +11,21 @@ namespace PKISharp.WACS.Context
{
public ValidationContextParameters(
Authorization authorization,
- TargetPart? targetPart,
+ TargetPart targetPart,
string challengeType,
- string pluginName)
+ string pluginName,
+ bool orderValid)
{
TargetPart = targetPart;
Authorization = authorization;
ChallengeType = challengeType;
PluginName = pluginName;
+ OrderValid = orderValid;
}
-
+ public bool OrderValid { get; }
public string ChallengeType { get; }
public string PluginName { get; }
- public TargetPart? TargetPart { get; }
+ public TargetPart TargetPart { get; }
public Authorization Authorization { get; }
}
@@ -40,6 +42,10 @@ namespace PKISharp.WACS.Context
ChallengeType = parameters.ChallengeType;
PluginName = parameters.PluginName;
ValidationPlugin = scope.Resolve<IValidationPlugin>();
+ if (parameters.OrderValid)
+ {
+ Success = true;
+ }
}
public ILifetimeScope Scope { get; }
public string Identifier { get; }
diff --git a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
index 768fcce..ee6a996 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Http/HttpValidation.cs
@@ -21,7 +21,7 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
where TOptions : HttpValidationOptions<TPlugin>
where TPlugin : IValidationPlugin
{
- private readonly List<string> _filesWritten = new List<string>();
+ private readonly List<string> _filesWritten = new List<string>();
protected TOptions _options;
protected ILogService _log;
@@ -190,12 +190,16 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
var destination = CombinePath(_path, challenge.HttpResourcePath.Replace(partialPath, "web.config"));
if (!_filesWritten.Contains(destination))
{
- _log.Debug("Writing web.config");
- var content = GetWebConfig();
- WriteFile(destination, content);
- _filesWritten.Add(destination);
+ var content = GetWebConfig().Value;
+ if (content != null)
+ {
+ _log.Debug("Writing web.config");
+ WriteFile(destination, content);
+ _filesWritten.Add(destination);
+ }
+
}
- }
+ }
catch (Exception ex)
{
_log.Warning("Unable to write web.config: {ex}", ex.Message); ;
@@ -207,7 +211,16 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
/// Get the template for the web.config
/// </summary>
/// <returns></returns>
- private string GetWebConfig() => File.ReadAllText(TemplateWebConfig);
+ private Lazy<string?> GetWebConfig() => new Lazy<string?>(() => {
+ try
+ {
+ return File.ReadAllText(TemplateWebConfig);
+ }
+ catch
+ {
+ return null;
+ }
+ });
/// <summary>
/// Combine root path with relative path
@@ -287,20 +300,29 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
{
if (_path != null)
{
+ var folders = new List<string>();
foreach (var file in _filesWritten)
{
- _log.Debug("Deleting answer");
+ _log.Debug("Deleting files");
await DeleteFile(file);
- if (_settings.Validation.CleanupFolders)
+ var folder = file.Substring(0, file.LastIndexOf(PathSeparator));
+ if (!folders.Contains(folder))
+ {
+ folders.Add(folder);
+ }
+ }
+ if (_settings.Validation.CleanupFolders)
+ {
+ _log.Debug("Deleting empty folders");
+ foreach (var folder in folders)
{
- var folder = file.Substring(0, file.LastIndexOf(PathSeparator));
if (await DeleteFolderIfEmpty(folder))
{
- var idx = file.LastIndexOf(PathSeparator);
+ var idx = folder.LastIndexOf(PathSeparator);
if (idx >= 0)
{
- folder = folder.Substring(0, folder.LastIndexOf(PathSeparator));
- await DeleteFolderIfEmpty(folder);
+ var parent = folder.Substring(0, folder.LastIndexOf(PathSeparator));
+ await DeleteFolderIfEmpty(parent);
}
}
}
diff --git a/src/main.lib/RenewalExecutor.cs b/src/main.lib/RenewalExecutor.cs
index fb70a28..5f17bef 100644
--- a/src/main.lib/RenewalExecutor.cs
+++ b/src/main.lib/RenewalExecutor.cs
@@ -172,7 +172,7 @@ namespace PKISharp.WACS
var context = new ExecutionContext(execute, order, runLevel, result);
// Authorize the order (validation)
- await _validator.AuthorizeOrder(context);
+ await _validator.AuthorizeOrder(context, runLevel);
if (context.Result.Success)
{
// Execute final steps (CSR, store, install)
diff --git a/src/main.lib/RenewalValidator.cs b/src/main.lib/RenewalValidator.cs
index 65a0919..5f44ef8 100644
--- a/src/main.lib/RenewalValidator.cs
+++ b/src/main.lib/RenewalValidator.cs
@@ -1,4 +1,5 @@
-using Autofac;
+using ACMESharp.Protocol.Resources;
+using Autofac;
using PKISharp.WACS.Clients.Acme;
using PKISharp.WACS.Context;
using PKISharp.WACS.DomainObjects;
@@ -9,6 +10,7 @@ using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Security.Policy;
using System.Threading.Tasks;
namespace PKISharp.WACS
@@ -38,7 +40,7 @@ namespace PKISharp.WACS
/// <param name="result"></param>
/// <param name="runLevel"></param>
/// <returns></returns>
- public async Task AuthorizeOrder(ExecutionContext context)
+ public async Task AuthorizeOrder(ExecutionContext context, RunLevel runLevel)
{
// Sanity check
if (context.Order.Details == null)
@@ -47,6 +49,22 @@ namespace PKISharp.WACS
return;
}
+ // Maybe validation is not needed at all
+ var orderValid = false;
+ if (context.Order.Details.Payload.Status == AcmeClient.OrderReady ||
+ context.Order.Details.Payload.Status == AcmeClient.OrderValid)
+ {
+ if (!runLevel.HasFlag(RunLevel.Test) &&
+ !runLevel.HasFlag(RunLevel.IgnoreCache))
+ {
+ return;
+ }
+ else
+ {
+ orderValid = true;
+ }
+ }
+
// Get validation plugin
var options = context.Renewal.ValidationPluginOptions;
var validationScope = _scopeBuilder.Validation(context.Scope, options);
@@ -54,25 +72,23 @@ namespace PKISharp.WACS
if (validationPlugin == null)
{
_log.Error("Validation plugin not found or not created");
- context.Result.AddErrorMessage("Validation plugin not found or not created");
+ context.Result.AddErrorMessage("Validation plugin not found or not created", !orderValid);
return;
}
var (disabled, disabledReason) = validationPlugin.Disabled;
if (disabled)
{
_log.Error($"Validation plugin is not available. {disabledReason}");
- context.Result.AddErrorMessage("Validation plugin is not available");
+ context.Result.AddErrorMessage("Validation plugin is not available", !orderValid);
return;
}
// Get authorization details
var authorizations = context.Order.Details.Payload.Authorizations.ToList();
- var contextParamTasks = authorizations.Select(authorizationUri => GetValidationContextParameters(context, authorizationUri, options));
- var contextParams = (await Task.WhenAll(contextParamTasks)).ToList();
- var missingTarget = contextParams.FirstOrDefault(x => x.TargetPart == null);
- if (missingTarget != null)
+ var contextParamTasks = authorizations.Select(authorizationUri => GetValidationContextParameters(context, authorizationUri, options, orderValid));
+ var contextParams = (await Task.WhenAll(contextParamTasks)).OfType<ValidationContextParameters>().ToList();
+ if (!context.Result.Success)
{
- context.Result.AddErrorMessage($"Unable to match challenge {missingTarget.Authorization.Identifier.Value} to target");
return;
}
@@ -201,18 +217,33 @@ namespace PKISharp.WACS
/// <param name="authorizationUri"></param>
/// <param name="options"></param>
/// <returns></returns>
- private async Task<ValidationContextParameters> GetValidationContextParameters(ExecutionContext context, string authorizationUri, ValidationPluginOptions options)
+ private async Task<ValidationContextParameters?> GetValidationContextParameters(ExecutionContext context, string authorizationUri, ValidationPluginOptions options, bool orderValid)
{
// Get authorization challenge details from server
var client = context.Scope.Resolve<AcmeClient>();
- var authorization = await client.GetAuthorizationDetails(authorizationUri);
+ var authorization = default(Authorization);
+ try
+ {
+ authorization = await client.GetAuthorizationDetails(authorizationUri);
+ }
+ catch
+ {
+ context.Result.AddErrorMessage($"Unable to get authorization details from {authorizationUri}", !orderValid);
+ return null;
+ }
// Find a targetPart that matches the challenge
var targetPart = context.Target.Parts.
FirstOrDefault(tp => tp.GetHosts(false).
Any(h => authorization.Identifier.Value == h.Replace("*.", "")));
- return new ValidationContextParameters(authorization, targetPart, options.ChallengeType, options.Name);
+ if (targetPart == null)
+ {
+ context.Result.AddErrorMessage($"Unable to match challenge {authorization.Identifier.Value} to target", !orderValid);
+ return null;
+ }
+
+ return new ValidationContextParameters(authorization, targetPart, options.ChallengeType, options.Name, orderValid);
}
/// <summary>
diff --git a/src/main.test/Mock/MockContainer.cs b/src/main.test/Mock/MockContainer.cs
index 1e06ebb..76560ae 100644
--- a/src/main.test/Mock/MockContainer.cs
+++ b/src/main.test/Mock/MockContainer.cs
@@ -57,6 +57,7 @@ namespace PKISharp.WACS.UnitTests.Mock
_ = builder.RegisterType<mock.CertificateService>().As<real.ICertificateService>().SingleInstance();
_ = builder.RegisterType<real.TaskSchedulerService>().SingleInstance();
_ = builder.RegisterType<real.NotificationService>().SingleInstance();
+ _ = builder.RegisterType<RenewalValidator>().SingleInstance();
_ = builder.RegisterType<RenewalExecutor>().SingleInstance();
_ = builder.RegisterType<RenewalManager>().SingleInstance();
_ = builder.Register(c => c.Resolve<real.IArgumentsService>().MainArguments).SingleInstance();
diff --git a/src/main.test/Tests/RenewalTests/RenewalServiceTests.cs b/src/main.test/Tests/RenewalTests/RenewalServiceTests.cs
index 82b805a..6c17610 100644
--- a/src/main.test/Tests/RenewalTests/RenewalServiceTests.cs
+++ b/src/main.test/Tests/RenewalTests/RenewalServiceTests.cs
@@ -22,8 +22,11 @@ namespace PKISharp.WACS.UnitTests.Tests.RenewalTests
{
var container = new MockContainer().TestScope();
var renewalStore = container.Resolve<real.IRenewalStore>();
+ var renewalValidator = container.Resolve<RenewalValidator>(
+ new TypedParameter(typeof(IContainer), container));
var renewalExecutor = container.Resolve<RenewalExecutor>(
- new TypedParameter(typeof(IContainer), container));
+ new TypedParameter(typeof(RenewalValidator), renewalValidator),
+ new TypedParameter(typeof(IContainer), container));
var renewalManager = container.Resolve<RenewalManager>(
new TypedParameter(typeof(IContainer), container),
new TypedParameter(typeof(RenewalExecutor), renewalExecutor));