Skip to content

Commit

Permalink
Merge pull request #2447 from win-acme/2.2.6
Browse files Browse the repository at this point in the history
2.2.6
  • Loading branch information
WouterTinus committed Sep 26, 2023
2 parents 0cb3afe + cf70ace commit 26328dd
Show file tree
Hide file tree
Showing 27 changed files with 192 additions and 47 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
@@ -1,4 +1,4 @@
version: 2.2.5.{build}
version: 2.2.6.{build}
image: Visual Studio 2022
platform: Any CPU
shallow_clone: true
Expand Down
44 changes: 34 additions & 10 deletions build/create-artifacts.ps1
Expand Up @@ -58,10 +58,40 @@ function PlatformRelease
$DbiZip = "mscordbi.v$Version.$PlatformShort.zip"
$DbiZipPath = "$Out\$DbiZip"
if (!(Test-Path $DbiZipPath)) {
Remove-Item $Temp\* -recurse
Copy-Item "$MainBin\mscordbi.dll" $Temp
[io.compression.zipfile]::CreateFromDirectory($Temp, $DbiZipPath)
CreateArtifact $MainBin @("mscordbi.dll") $DbiZipPath
}

# GnuTLS DLL for FluentFTP
if ($Platform -eq "win-x64") {
$GnuTlsZip = "gnutls.v$Version.$PlatformShort.zip"
$GnuTlsZipPath = "$Out\$GnuTlsZip"
$GnuTlsSrc = "$MainBin\Libs\Win64"
if (!(Test-Path $GnuTlsSrc))
{
$GnuTlsSrc = "$MainBin\publish"
}

if (!(Test-Path $GnuTlsZipPath)) {
CreateArtifact $GnuTlsSrc @(
"libgcc_s_seh-1.dll",
"libgmp-10.dll",
"libgnutls-30.dll",
"libhogweed-6.dll",
"libnettle-8.dll",
"libwinpthread-1.dll") $GnuTlsZipPath
}
}

}

function CreateArtifact {
param($Dir, $Files, $Target)

Remove-Item $Temp\* -recurse
foreach ($file in $files) {
Copy-Item "$Dir\$file" $Temp
}
[io.compression.zipfile]::CreateFromDirectory($Temp, $Target)
}

function PluginRelease
Expand All @@ -76,13 +106,7 @@ function PluginRelease
{
$PlugBin = "$Root\src\$Dir\bin\Any CPU\Release\net7.0\publish"
}
if (Test-Path $PlugBin)
{
foreach ($file in $files) {
Copy-Item "$PlugBin\$file" $Temp
}
[io.compression.zipfile]::CreateFromDirectory($Temp, $PlugZipPath)
}
CreateArtifact $PlugBin $Files $PlugZipPath
}

function NugetRelease
Expand Down
2 changes: 1 addition & 1 deletion src/ACMESharpCore
2 changes: 1 addition & 1 deletion src/main.lib/Clients/Acme/AcmeClient.cs
Expand Up @@ -53,7 +53,7 @@ internal class AcmeClient
{
_log = log;
_settings = settings;
var httpClient = proxy.GetHttpClient();
var httpClient = proxy.GetHttpClient(settings.Acme.ValidateServerCertificate != false);
httpClient.BaseAddress = settings.BaseUri;
_client = new AcmeProtocolClient(httpClient, usePostAsGet: _settings.Acme.PostAsGet)
{
Expand Down
30 changes: 30 additions & 0 deletions src/main.lib/Clients/Acme/OrderManager.cs
Expand Up @@ -99,6 +99,30 @@ private static string CacheKey(Order order, string accountId)
return await CreateOrder(cacheKey, client, order.Target);
}

/// <summary>
/// Delete all relevant files from the order cache
/// </summary>
/// <param name="cacheKey"></param>
private void DeleteFromCache(string cacheKey)
{
DeleteFile($"{cacheKey}.{_orderFileExtension}");
DeleteFile($"{cacheKey}.{_orderKeyExtension}");
}

/// <summary>
/// Delete a file from the order cache
/// </summary>
/// <param name="path"></param>
private void DeleteFile(string path)
{
var fileInfo = new FileInfo(Path.Combine(_orderPath.FullName, path));
if (fileInfo.Exists)
{
fileInfo.Delete();
_log.Debug("Deleted {fileInfo}", fileInfo.FullName);
}
}

/// <summary>
/// Get order from the cache
/// </summary>
Expand All @@ -116,8 +140,12 @@ private static string CacheKey(Order order, string accountId)

if (runLevel.HasFlag(RunLevel.NoCache))
{
// Delete previously cached order
// and previously cached key as well
// to ensure that it won't be used
_log.Warning("Cached order available but not used with --{switch} option.",
nameof(MainArguments.NoCache).ToLower());
DeleteFromCache(cacheKey);
return null;
}

Expand All @@ -129,13 +157,15 @@ private static string CacheKey(Order order, string accountId)
catch (Exception ex)
{
_log.Warning("Unable to refresh cached order: {ex}", ex.Message);
DeleteFromCache(cacheKey);
return null;
}

if (existingOrder.Payload.Status != AcmeClient.OrderValid &&
existingOrder.Payload.Status != AcmeClient.OrderReady)
{
_log.Warning("Cached order has status {status}, discarding", existingOrder.Payload.Status);
DeleteFromCache(cacheKey);
return null;
}

Expand Down
20 changes: 20 additions & 0 deletions src/main.lib/Clients/DNS/LookupClientWrapper.cs
Expand Up @@ -60,6 +60,10 @@ public async Task<IEnumerable<IPAddress>> GetNameServers(string host)
host = host.TrimEnd('.');
_log.Debug("Querying name servers for {part}", host);
var nsResponse = await _lookupClient.QueryAsync(host, QueryType.NS);
if (nsResponse.HasError)
{
_log.Verbose("Error from {server}: {message}", IpAddress, nsResponse.ErrorMessage);
}
var nsRecords = nsResponse.Answers.NsRecords();
var cnameRecords = nsResponse.Answers.CnameRecords();
if (!nsRecords.Any() && !cnameRecords.Any())
Expand Down Expand Up @@ -117,6 +121,10 @@ public async Task<bool> Connect()
public async Task<IEnumerable<string>> GetTxtRecords(string host)
{
var txtResult = await _lookupClient.QueryAsync(host, QueryType.TXT);
if (txtResult.HasError)
{
_log.Verbose("Error from {server}: {message}", IpAddress, txtResult.ErrorMessage);
}
return txtResult.Answers.TxtRecords().
Where(txtRecord => txtRecord != null).
SelectMany(txtRecord => txtRecord.EscapedText).
Expand All @@ -129,12 +137,20 @@ public async Task<IEnumerable<IPAddress>> GetIps(string host)
{
var ret = new List<IPAddress>();
var ipv4 = await _lookupClient.QueryAsync(host, QueryType.A);
if (ipv4.HasError)
{
_log.Verbose("Error from {server}: {message}", IpAddress, ipv4.ErrorMessage);
}
ret.AddRange(ipv4.Answers.ARecords().
Where(aRecord => aRecord != null).
Select(aRecord => aRecord.Address).
Where(ip => ip != null).
OfType<IPAddress>());
var ipv6 = await _lookupClient.QueryAsync(host, QueryType.AAAA);
if (ipv6.HasError)
{
_log.Verbose("Error from {server}: {message}", IpAddress, ipv6.ErrorMessage);
}
ret.AddRange(ipv6.Answers.AaaaRecords().
Where(aRecord => aRecord != null).
Select(aRecord => aRecord.Address).
Expand All @@ -146,6 +162,10 @@ public async Task<IEnumerable<IPAddress>> GetIps(string host)
public async Task<string?> GetCname(string host)
{
var cnames = await _lookupClient.QueryAsync(host, QueryType.CNAME);
if (cnames.HasError)
{
_log.Verbose("Error from {server}: {message}", IpAddress, cnames.ErrorMessage);
}
var cnameRecords = cnames.Answers.CnameRecords();
if (cnameRecords.Any())
{
Expand Down
18 changes: 15 additions & 3 deletions src/main.lib/Clients/FtpClient.cs
@@ -1,4 +1,5 @@
using FluentFTP;
using FluentFTP.GnuTLS;
using PKISharp.WACS.Configuration;
using PKISharp.WACS.Services;
using System;
Expand All @@ -14,12 +15,15 @@ internal class FtpClient
{
private NetworkCredential? Credential { get; set; }
private readonly ILogService _log;
private readonly ISettingsService _settings;

public FtpClient(
NetworkCredentialOptions? options,
NetworkCredentialOptions? options,
ISettingsService settings,
ILogService log,
SecretServiceManager secretService)
{
{
_settings = settings;
_log = log;
if (options != null)
{
Expand All @@ -37,8 +41,16 @@ private async Task<AsyncFtpClient> CreateClient(Uri uri)
var port = uri.Port == -1 ? 21 : uri.Port;
var options = new FtpConfig()
{
ValidateAnyCertificate = true,
ValidateAnyCertificate = true
};
if (_settings.Validation?.Ftp?.UseGnuTls == true)
{
#if PLUGGABLE
options.CustomStream = typeof(GnuTlsStream);
#else
_log.Warning("Unable to use GnuTLS with trimmed build of win-acme, please download a pluggable build.");
#endif
}
var client = new AsyncFtpClient(uri.Host, port, options)
{
Credentials = Credential
Expand Down
21 changes: 19 additions & 2 deletions src/main.lib/Configuration/Settings/Settings.cs
Expand Up @@ -88,7 +88,11 @@ public class AcmeSettings
/// <summary>
/// Use POST-as-GET request mode
/// </summary>
public bool PostAsGet { get; set; }
public bool PostAsGet { get; set; }
/// <summary>
/// Validate the server certificate
/// </summary>
public bool? ValidateServerCertificate { get; set; }
/// <summary>
/// Number of times wait for the ACME server to
/// handle validation and order processing
Expand Down Expand Up @@ -442,7 +446,20 @@ public class ValidationSettings
/// can lead to prevalidation failures when your Active Directory is
/// hosting a private version of the DNS zone for internal use.
/// </summary>
public List<string>? DnsServers { get; set; }
public List<string>? DnsServers { get; set; }
/// <summary>
/// Settings for FTP validation
/// </summary>
public FtpSettings? Ftp { get; set; }
}

/// <summary>
/// Settings for FTP validation
/// </summary>
public class FtpSettings
{
// Use GnuTls library for SSL, tradeoff: https://github.com/robinrodricks/FluentFTP/wiki/FTPS-Connection-using-GnuTLS
public bool? UseGnuTls { get; set; }
}

public class OrderSettings
Expand Down
6 changes: 3 additions & 3 deletions src/main.lib/Plugins/StorePlugins/CentralSsl/CentralSsl.cs
Expand Up @@ -54,12 +54,12 @@ internal class CentralSsl : IStorePlugin
}
}

private string PathForIdentifier(Identifier identifier) => Path.Combine(_path, $"{identifier.Value.Replace("*", "_")}.pfx");
private string PathForIdentifier(DnsIdentifier identifier) => Path.Combine(_path, $"{identifier.Unicode(true).Value.Replace("*", "_")}.pfx");

public async Task<StoreInfo?> Save(ICertificateInfo input)
{
_log.Information("Copying certificate to the CentralSsl store");
foreach (var identifier in input.SanNames)
foreach (var identifier in input.SanNames.OfType<DnsIdentifier>())
{
var dest = PathForIdentifier(identifier);
_log.Information("Saving certificate to CentralSsl location {dest}", dest);
Expand All @@ -81,7 +81,7 @@ internal class CentralSsl : IStorePlugin
public Task Delete(ICertificateInfo input)
{
_log.Information("Removing certificate from the CentralSsl store");
foreach (var identifier in input.SanNames)
foreach (var identifier in input.SanNames.OfType<DnsIdentifier>())
{
var dest = PathForIdentifier(identifier);
var fi = new FileInfo(dest);
Expand Down
2 changes: 1 addition & 1 deletion src/main.lib/Plugins/StorePlugins/PfxFile/PfxFile.cs
Expand Up @@ -97,7 +97,7 @@ internal class PfxFile : IStorePlugin
bcPfxOut.SetCertificateEntry(alias, bcPfxIn.GetCertificate(alias));
}
}
using var fs = new FileInfo(dest).OpenWrite();
using var fs = new FileInfo(dest).Open(FileMode.Create);
bcPfxOut.Save(fs, _password?.ToCharArray(), new Bc.Security.SecureRandom());
}
catch (Exception ex)
Expand Down
3 changes: 2 additions & 1 deletion src/main.lib/Plugins/ValidationPlugins/Http/Ftp/Ftp.cs
Expand Up @@ -20,10 +20,11 @@ internal class Ftp : HttpValidation<FtpOptions>
public Ftp(
FtpOptions options,
HttpValidationParameters pars,
ISettingsService settings,
RunLevel runLevel,
SecretServiceManager secretService) :
base(options, runLevel, pars) =>
_ftpClient = new FtpClient(_options.Credential, pars.LogService, secretService);
_ftpClient = new FtpClient(_options.Credential, settings, pars.LogService, secretService);

protected override char PathSeparator => '/';

Expand Down
4 changes: 2 additions & 2 deletions src/main.lib/RenewalManager.cs
Expand Up @@ -400,11 +400,11 @@ private async Task<IEnumerable<Renewal>> SortRenewalsMenu(IEnumerable<Renewal> c
var options = new List<Choice<Func<IEnumerable<Renewal>>>>
{
Choice.Create<Func<IEnumerable<Renewal>>>(
() => current.OrderBy(x => x.LastFriendlyName),
() => current.OrderBy(x => x.LastFriendlyName ?? ""),
"Sort by friendly name",
@default: true),
Choice.Create<Func<IEnumerable<Renewal>>>(
() => current.OrderByDescending(x => x.LastFriendlyName),
() => current.OrderByDescending(x => x.LastFriendlyName ?? ""),
"Sort by friendly name (descending)"),
Choice.Create<Func<IEnumerable<Renewal>>>(
() => current.OrderBy(x => _dueDate.DueDate(x)),
Expand Down
2 changes: 1 addition & 1 deletion src/main.lib/Services/TaskSchedulerService.cs
Expand Up @@ -26,7 +26,7 @@ internal class TaskSchedulerService
_input = input;
_log = log;
}
private string TaskName => $"{_settings.Client.ClientName} renew ({_settings.BaseUri.CleanUri()})";
private string TaskName => $"{_settings.Client.ClientName.CleanPath()} renew ({_settings.BaseUri.CleanUri()})";
private static string WorkingDirectory => Path.GetDirectoryName(VersionService.ExePath) ?? "";
private static string ExecutingFile => Path.GetFileName(VersionService.ExePath);

Expand Down
4 changes: 3 additions & 1 deletion src/main.lib/Wacs.cs
Expand Up @@ -67,7 +67,9 @@ internal class Wacs
{
try
{
Console.OutputEncoding = System.Text.Encoding.GetEncoding(_settings.UI.TextEncoding);
var encoding = System.Text.Encoding.GetEncoding(_settings.UI.TextEncoding);
Console.OutputEncoding = encoding;
Console.InputEncoding = encoding;
}
catch
{
Expand Down
11 changes: 6 additions & 5 deletions src/main.lib/wacs.lib.csproj
Expand Up @@ -33,20 +33,21 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="7.0.1" />
<PackageReference Include="Autofac" Version="7.1.0" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.2.1" />
<PackageReference Include="DnsClient" Version="1.7.0" />
<PackageReference Include="FluentFTP" Version="46.0.2" />
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="FluentFTP" Version="47.1.0" />
<PackageReference Include="FluentFTP.GnuTLS" Version="1.0.22" />
<PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Web.Administration" Version="11.1.0" />
<PackageReference Include="MorseCode.ITask" Version="2.0.3" />
<PackageReference Include="Nager.PublicSuffix" Version="2.4.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.AppSettings" Version="2.2.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.EventLog" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
Expand Down
6 changes: 3 additions & 3 deletions src/main.test/wacs.test.csproj
Expand Up @@ -25,9 +25,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down

0 comments on commit 26328dd

Please sign in to comment.