summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWouter Tinus <win.acme.simple@gmail.com>2020-04-28 19:42:31 +0200
committerGitHub <noreply@github.com>2020-04-28 19:42:31 +0200
commitec86a9425274a60af6d9d3c55ab4ed2f34be46fb (patch)
treeb92ab9525522b1151dc2560dc12c6db8b74c3204 /src
parent85d69f9ddb45671fc0082676ea40b0a9c7f0a4f2 (diff)
parent2de989799eaf2659838783e0b792511f5ccce532 (diff)
downloadletsencrypt-win-simple-ec86a9425274a60af6d9d3c55ab4ed2f34be46fb.zip
letsencrypt-win-simple-ec86a9425274a60af6d9d3c55ab4ed2f34be46fb.tar.gz
letsencrypt-win-simple-ec86a9425274a60af6d9d3c55ab4ed2f34be46fb.tar.bz2
Merge branch '2.1.7' into azure-environment-agnostic
Diffstat (limited to 'src')
-rw-r--r--src/main.lib/Clients/IIS/IISSiteWrapper.cs17
-rw-r--r--src/main.lib/Plugins/InstallationPlugins/IISWeb/IISWebOptionsFactory.cs11
-rw-r--r--src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs6
-rw-r--r--src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs1
-rw-r--r--src/main.lib/RenewalManager.cs11
-rwxr-xr-xsrc/plugin.validation.dns.azure/AzureArgumentsProvider.cs14
-rw-r--r--src/plugin.validation.dns.luadns/luadns.cs145
-rw-r--r--src/plugin.validation.dns.luadns/luadnsArguments.cs8
-rw-r--r--src/plugin.validation.dns.luadns/luadnsArgumentsProvider.cs22
-rw-r--r--src/plugin.validation.dns.luadns/luadnsOptions.cs19
-rw-r--r--src/plugin.validation.dns.luadns/luadnsOptionsFactory.cs39
-rw-r--r--src/plugin.validation.dns.luadns/wacs.validation.dns.luadns.csproj13
-rw-r--r--src/wacs.sln8
13 files changed, 284 insertions, 30 deletions
diff --git a/src/main.lib/Clients/IIS/IISSiteWrapper.cs b/src/main.lib/Clients/IIS/IISSiteWrapper.cs
index 9bc204b..c0b96f7 100644
--- a/src/main.lib/Clients/IIS/IISSiteWrapper.cs
+++ b/src/main.lib/Clients/IIS/IISSiteWrapper.cs
@@ -50,7 +50,22 @@ namespace PKISharp.WACS.Clients.IIS
}
}
}
- public byte[] CertificateHash => Binding.CertificateHash;
+
+ public byte[]? CertificateHash
+ {
+ get
+ {
+ try
+ {
+ return Binding.CertificateHash;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+ }
+
public string CertificateStoreName => Binding.CertificateStoreName;
public string BindingInformation => Binding.NormalizedBindingInformation();
public SSLFlags SSLFlags => Binding.SSLFlags();
diff --git a/src/main.lib/Plugins/InstallationPlugins/IISWeb/IISWebOptionsFactory.cs b/src/main.lib/Plugins/InstallationPlugins/IISWeb/IISWebOptionsFactory.cs
index 5ac813b..4bb9431 100644
--- a/src/main.lib/Plugins/InstallationPlugins/IISWeb/IISWebOptionsFactory.cs
+++ b/src/main.lib/Plugins/InstallationPlugins/IISWeb/IISWebOptionsFactory.cs
@@ -32,14 +32,9 @@ namespace PKISharp.WACS.Plugins.InstallationPlugins
var ask = true;
if (target.IIS)
{
- if (runLevel.HasFlag(RunLevel.Advanced))
- {
- ask = await inputService.PromptYesNo("Use different site for installation?", false);
- }
- else
- {
- ask = false;
- }
+ ask = runLevel.HasFlag(RunLevel.Advanced) ?
+ await inputService.PromptYesNo("Use different site for installation?", false) :
+ false;
}
if (ask)
{
diff --git a/src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs b/src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs
index fdd8782..45b0282 100644
--- a/src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs
+++ b/src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs
@@ -51,8 +51,10 @@ namespace PKISharp.WACS.Plugins.StorePlugins
_log.Information("Saving certificate to Central SSL location {dest}", dest);
try
{
- var collection = new X509Certificate2Collection();
- collection.Add(input.Certificate);
+ var collection = new X509Certificate2Collection
+ {
+ input.Certificate
+ };
collection.AddRange(input.Chain.ToArray());
File.WriteAllBytes(dest, collection.Export(X509ContentType.Pfx, _password));
}
diff --git a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
index 4470890..d43d58b 100644
--- a/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
+++ b/src/main.lib/Plugins/ValidationPlugins/Tls/SelfHosting/SelfHosting.cs
@@ -26,7 +26,6 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins.Tls
private readonly IUserRoleService _userRoleService;
private readonly CancellationTokenSource _tokenSource = new CancellationTokenSource();
- private bool HasListener => _listener != null;
private TcpListener Listener
{
get
diff --git a/src/main.lib/RenewalManager.cs b/src/main.lib/RenewalManager.cs
index 424e1fe..66de9cd 100644
--- a/src/main.lib/RenewalManager.cs
+++ b/src/main.lib/RenewalManager.cs
@@ -359,17 +359,6 @@ namespace PKISharp.WACS
return await chosen.Invoke();
}
- /// <summary>
- /// Filter specific renewals by list index
- /// </summary>
- /// <param name="current"></param>
- /// <returns></returns>
- private async Task<IEnumerable<Renewal>> FilterRenewalsById(IEnumerable<Renewal> current)
- {
- var rawInput = await _input.RequestString("Please input the list index of the renewal(s) you'd like to select");
- return await FilterRenewalsById(current, rawInput);
- }
-
private async Task<IEnumerable<Renewal>> FilterRenewalsById(IEnumerable<Renewal> current, string input)
{
var parts = input.ParseCsv();
diff --git a/src/plugin.validation.dns.azure/AzureArgumentsProvider.cs b/src/plugin.validation.dns.azure/AzureArgumentsProvider.cs
index f27f37a..7716fd2 100755
--- a/src/plugin.validation.dns.azure/AzureArgumentsProvider.cs
+++ b/src/plugin.validation.dns.azure/AzureArgumentsProvider.cs
@@ -10,25 +10,25 @@ namespace PKISharp.WACS.Plugins.ValidationPlugins
public override string Condition => "--validationmode dns-01 --validation azure";
public override void Configure(FluentCommandLineParser<AzureArguments> parser)
{
- parser.Setup(o => o.AzureEnvironment)
+ _ = parser.Setup(o => o.AzureEnvironment)
.As("azureenvironment")
.WithDescription("Public Azure service instance endpoint");
- parser.Setup(o => o.AzureUseMsi)
+ _ = parser.Setup(o => o.AzureUseMsi)
.As("azureusemsi")
.WithDescription("Use Managed Service Identity for authentication.");
- parser.Setup(o => o.AzureTenantId)
+ _ = parser.Setup(o => o.AzureTenantId)
.As("azuretenantid")
.WithDescription("Tenant ID to login into Microsoft Azure.");
- parser.Setup(o => o.AzureClientId)
+ _ = parser.Setup(o => o.AzureClientId)
.As("azureclientid")
.WithDescription("Client ID to login into Microsoft Azure.");
- parser.Setup(o => o.AzureSecret)
+ _ = parser.Setup(o => o.AzureSecret)
.As("azuresecret")
.WithDescription("Secret to login into Microsoft Azure.");
- parser.Setup(o => o.AzureSubscriptionId)
+ _ = parser.Setup(o => o.AzureSubscriptionId)
.As("azuresubscriptionid")
.WithDescription("Subscription ID to login into Microsoft Azure DNS.");
- parser.Setup(o => o.AzureResourceGroupName)
+ _ = parser.Setup(o => o.AzureResourceGroupName)
.As("azureresourcegroupname")
.WithDescription("The name of the resource group within Microsoft Azure DNS.");
}
diff --git a/src/plugin.validation.dns.luadns/luadns.cs b/src/plugin.validation.dns.luadns/luadns.cs
new file mode 100644
index 0000000..2cd561c
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/luadns.cs
@@ -0,0 +1,145 @@
+using PKISharp.WACS.Clients.DNS;
+using PKISharp.WACS.Services;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
+{
+ internal sealed class LUADNS : DnsValidation<LUADNS>
+ {
+ private class ZoneData
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+ }
+
+ private class RecordData
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ [JsonPropertyName("zone_id")]
+ public int ZoneId { get; set; }
+
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ [JsonPropertyName("type")]
+ public string Type { get; set; }
+
+ [JsonPropertyName("content")]
+ public string Content { get; set; }
+
+ [JsonPropertyName("ttl")]
+ public int TTL { get; set; }
+ }
+
+ private static readonly Uri _luaDNSApiEndpoint = new Uri("https://api.luadns.com/v1/", UriKind.Absolute);
+ private static readonly Dictionary<string, RecordData> _recordsMap = new Dictionary<string, RecordData>();
+
+ private readonly DomainParseService _domainParser;
+ private readonly ProxyService _proxyService;
+
+ private readonly string _userName;
+ private readonly string _apiKey;
+
+ public LUADNS(
+ LookupClientProvider dnsClient,
+ DomainParseService domainParser,
+ ProxyService proxy,
+ ILogService log,
+ ISettingsService settings,
+ LUADNSOptions options)
+ : base(dnsClient, log, settings)
+ {
+ _domainParser = domainParser;
+ _proxyService = proxy;
+
+ _userName = options.Username;
+ _apiKey = options.APIKey.Value;
+ }
+
+ public override async Task CreateRecord(string recordName, string token)
+ {
+ _log.Information("Creating LUADNS verification record");
+
+ using (var client = GetClient())
+ {
+ var response = await client.GetAsync(new Uri(_luaDNSApiEndpoint, "zones"));
+ if (!response.IsSuccessStatusCode)
+ {
+ _log.Information("Failed to get DNS zones list for account. Aborting.");
+ return;
+ }
+
+ var payload = await response.Content.ReadAsStringAsync();
+ var zones = JsonSerializer.Deserialize<ZoneData[]>(payload);
+ var targetZone = zones.Where(d => recordName.EndsWith(d.Name, StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(d => d.Name.Length).FirstOrDefault();
+ if (targetZone == null)
+ {
+ _log.Information("No matching zone found in LUADNS account. Aborting");
+ return;
+ }
+
+ var newRecord = new RecordData { Name = $"{recordName}.", Type = "TXT", Content = token, TTL = 300 };
+ payload = JsonSerializer.Serialize(newRecord);
+
+ response = await client.PostAsync(new Uri(_luaDNSApiEndpoint, $"zones/{targetZone.Id}/records"), new StringContent(payload, Encoding.UTF8, "application/json"));
+ if (!response.IsSuccessStatusCode)
+ {
+ _log.Information("Failed to create DNS verification record");
+ return;
+ }
+
+ payload = await response.Content.ReadAsStringAsync();
+ newRecord = JsonSerializer.Deserialize<RecordData>(payload);
+
+ _recordsMap[recordName] = newRecord;
+
+ _log.Information("DNS Record created. Waiting 30 seconds to allow propagation.");
+ await Task.Delay(30000);
+ }
+ }
+
+ public override async Task DeleteRecord(string recordName, string token)
+ {
+ if (!_recordsMap.ContainsKey(recordName))
+ {
+ _log.Information($"No record with name {recordName} was created");
+ return;
+ }
+
+ _log.Information("Deleting LUADNS verification record");
+
+ using (var client = GetClient())
+ {
+ var response = await client.DeleteAsync(new Uri(_luaDNSApiEndpoint, $"zones/{_recordsMap[recordName].ZoneId}/records/{_recordsMap[recordName].Id}"));
+ if (!response.IsSuccessStatusCode)
+ {
+ _log.Information("Failed to delete DNS verification record");
+ return;
+ }
+
+ _recordsMap.Remove(recordName);
+ }
+ }
+
+ private HttpClient GetClient()
+ {
+ var client = _proxyService.GetHttpClient();
+ client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_userName}:{_apiKey}")));
+ client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ return client;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/plugin.validation.dns.luadns/luadnsArguments.cs b/src/plugin.validation.dns.luadns/luadnsArguments.cs
new file mode 100644
index 0000000..13ab07d
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/luadnsArguments.cs
@@ -0,0 +1,8 @@
+namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
+{
+ public sealed class LUADNSArguments
+ {
+ public string LUADNSUsername { get; set; }
+ public string LUADNSAPIKey { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/plugin.validation.dns.luadns/luadnsArgumentsProvider.cs b/src/plugin.validation.dns.luadns/luadnsArgumentsProvider.cs
new file mode 100644
index 0000000..9cdf9e6
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/luadnsArgumentsProvider.cs
@@ -0,0 +1,22 @@
+using Fclp;
+using PKISharp.WACS.Configuration;
+
+namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
+{
+ public sealed class LUADNSArgumentsProvider : BaseArgumentsProvider<LUADNSArguments>
+ {
+ public override string Name { get; } = "LUADNS";
+ public override string Group { get; } = "Validation";
+ public override string Condition { get; } = "--validationmode dns-01 --validation luadns";
+ public override void Configure(FluentCommandLineParser<LUADNSArguments> parser)
+ {
+ parser.Setup(_ => _.LUADNSUsername)
+ .As("LUADNSUsername")
+ .WithDescription("LUADN account useername (email address)");
+
+ parser.Setup(_ => _.LUADNSAPIKey)
+ .As("LUADNSAPIKey")
+ .WithDescription("LUADNS API Key");
+ }
+ }
+} \ No newline at end of file
diff --git a/src/plugin.validation.dns.luadns/luadnsOptions.cs b/src/plugin.validation.dns.luadns/luadnsOptions.cs
new file mode 100644
index 0000000..348b4bd
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/luadnsOptions.cs
@@ -0,0 +1,19 @@
+using Newtonsoft.Json;
+using PKISharp.WACS.Plugins.Base;
+using PKISharp.WACS.Plugins.Base.Options;
+using PKISharp.WACS.Services.Serialization;
+
+namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
+{
+ [Plugin("3b0c3cca-db98-40b7-b678-b34791070d42")]
+ internal sealed class LUADNSOptions : ValidationPluginOptions<LUADNS>
+ {
+ public override string Name { get; } = "LUADNS";
+ public override string Description { get; } = "Create verification records in LUADNS";
+ public override string ChallengeType { get; } = Constants.Dns01ChallengeType;
+
+ public string Username { get; set; }
+ [JsonProperty(propertyName: "APIKeySafe")]
+ public ProtectedString APIKey { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/plugin.validation.dns.luadns/luadnsOptionsFactory.cs b/src/plugin.validation.dns.luadns/luadnsOptionsFactory.cs
new file mode 100644
index 0000000..c6357cd
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/luadnsOptionsFactory.cs
@@ -0,0 +1,39 @@
+using ACMESharp.Authorizations;
+using PKISharp.WACS.DomainObjects;
+using PKISharp.WACS.Plugins.Base.Factories;
+using PKISharp.WACS.Services;
+using PKISharp.WACS.Services.Serialization;
+using System.Threading.Tasks;
+
+namespace PKISharp.WACS.Plugins.ValidationPlugins.Dns
+{
+ internal sealed class LUADNSOptionsFactory : ValidationPluginOptionsFactory<LUADNS, LUADNSOptions>
+ {
+ private readonly IArgumentsService _arguments;
+ public LUADNSOptionsFactory(IArgumentsService arguments) : base(Dns01ChallengeValidationDetails.Dns01ChallengeType) => _arguments = arguments;
+
+ public override async Task<LUADNSOptions> Aquire(Target target, IInputService input, RunLevel runLevel)
+ {
+ var args = _arguments.GetArguments<LUADNSArguments>();
+ var opts = new LUADNSOptions
+ {
+ Username = await _arguments.TryGetArgument(args.LUADNSUsername, input, "LUADNS Account username"),
+ APIKey = new ProtectedString(await _arguments.TryGetArgument(args.LUADNSAPIKey, input, "LUADNS API key", true))
+ };
+ return opts;
+ }
+
+ public override Task<LUADNSOptions> Default(Target target)
+ {
+ var args = _arguments.GetArguments<LUADNSArguments>();
+ var opts = new LUADNSOptions
+ {
+ Username = _arguments.TryGetRequiredArgument(nameof(args.LUADNSUsername), args.LUADNSUsername),
+ APIKey = new ProtectedString(_arguments.TryGetRequiredArgument(nameof(args.LUADNSAPIKey), args.LUADNSAPIKey))
+ };
+ return Task.FromResult(opts);
+ }
+
+ public override bool CanValidate(Target target) => true;
+ }
+}
diff --git a/src/plugin.validation.dns.luadns/wacs.validation.dns.luadns.csproj b/src/plugin.validation.dns.luadns/wacs.validation.dns.luadns.csproj
new file mode 100644
index 0000000..3749682
--- /dev/null
+++ b/src/plugin.validation.dns.luadns/wacs.validation.dns.luadns.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
+ <AssemblyName>PKISharp.WACS.Plugins.ValidationPlugins.LUADNS</AssemblyName>
+ <RootNamespace>PKISharp.WACS.Plugins.ValidationPlugins</RootNamespace>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\main.lib\wacs.lib.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/wacs.sln b/src/wacs.sln
index aef64b5..fe889a8 100644
--- a/src/wacs.sln
+++ b/src/wacs.sln
@@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1FD6
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wacs.validation.dns.cloudflare", "plugin.validation.dns.cloudflare\wacs.validation.dns.cloudflare.csproj", "{DB1D4461-5563-425E-8D5E-D57893015D73}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wacs.validation.dns.luadns", "plugin.validation.dns.luadns\wacs.validation.dns.luadns.csproj", "{424630AC-3029-4188-B78A-A630316A4B99}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -97,6 +99,12 @@ Global
{DB1D4461-5563-425E-8D5E-D57893015D73}.Release|Any CPU.Build.0 = Release|Any CPU
{DB1D4461-5563-425E-8D5E-D57893015D73}.ReleasePluggable|Any CPU.ActiveCfg = Release|Any CPU
{DB1D4461-5563-425E-8D5E-D57893015D73}.ReleasePluggable|Any CPU.Build.0 = Release|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.ReleasePluggable|Any CPU.ActiveCfg = Release|Any CPU
+ {424630AC-3029-4188-B78A-A630316A4B99}.ReleasePluggable|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE