diff options
author | Wouter Tinus <win.acme.simple@gmail.com> | 2019-12-08 22:44:01 +0100 |
---|---|---|
committer | Wouter Tinus <win.acme.simple@gmail.com> | 2019-12-08 22:44:01 +0100 |
commit | 8c2f653751338974e875ba75e47791271f62f1c5 (patch) | |
tree | 5ab024596602a9e43b4399d451f86c84ebc87947 /src | |
parent | 57e22a31264863f006d42341f5067e5029bee1c6 (diff) | |
download | letsencrypt-win-simple-8c2f653751338974e875ba75e47791271f62f1c5.zip letsencrypt-win-simple-8c2f653751338974e875ba75e47791271f62f1c5.tar.gz letsencrypt-win-simple-8c2f653751338974e875ba75e47791271f62f1c5.tar.bz2 |
progress with interactive mode
Diffstat (limited to 'src')
17 files changed, 188 insertions, 618 deletions
diff --git a/src/main.lib/Clients/IIS/IISHelper.cs b/src/main.lib/Clients/IIS/IISHelper.cs index 6847166..c714dde 100644 --- a/src/main.lib/Clients/IIS/IISHelper.cs +++ b/src/main.lib/Clients/IIS/IISHelper.cs @@ -12,21 +12,27 @@ namespace PKISharp.WACS.Clients.IIS { internal class IISBindingOption { + public IISBindingOption(string hostUnicode, string hostPunycode) + { + HostUnicode = hostUnicode; + HostPunycode = hostPunycode; + } + public long SiteId { get; set; } public bool Https { get; set; } - public string HostUnicode { get; set; } - public string HostPunycode { get; set; } + public string HostUnicode { get; private set; } + public string HostPunycode { get; private set; } public int Port { get; set; } - public string Protocol { get; set; } + public string? Protocol { get; set; } public override string ToString() { if ((Protocol == "http" && Port != 80) || (Protocol == "https" && Port != 443)) { - return $"{HostUnicode}:{Port} (SiteId {SiteId}, {Protocol})"; + return $"{HostUnicode}:{Port} (Site {SiteId}, {Protocol})"; } - return $"{HostUnicode} (SiteId {SiteId})"; + return $"{HostUnicode} (Site {SiteId})"; } } @@ -80,11 +86,9 @@ namespace PKISharp.WACS.Clients.IIS sb.binding, https = https.Contains(sb) }). - Select(sbi => new IISBindingOption + Select(sbi => new IISBindingOption(sbi.host, _idnMapping.GetAscii(sbi.host)) { SiteId = sbi.site.Id, - HostUnicode = sbi.host, - HostPunycode = _idnMapping.GetAscii(sbi.host), Port = sbi.binding.Port, Protocol = sbi.binding.Protocol, Https = sbi.https @@ -130,10 +134,9 @@ namespace PKISharp.WACS.Clients.IIS return targets; } - internal List<IISBindingOption> FilterBindings(IISBindingsOptions options) + internal List<IISBindingOption> FilterBindings(List<IISBindingOption> bindings, IISBindingsOptions options) { // Check if we have any bindings - var bindings = GetBindings(); _log.Verbose("{0} named bindings found in IIS", bindings.Count()); if (options.IncludeSiteIds != null && options.IncludeSiteIds.Any()) { @@ -168,7 +171,7 @@ namespace PKISharp.WACS.Clients.IIS // Check if we have anything left _log.Verbose("{0} matching bindings found", bindings.Count()); - return bindings; + return bindings.OrderBy(x => x.HostUnicode).ThenBy(x => x.SiteId).ToList(); } internal bool Matches(IISBindingOption binding, Regex regex) diff --git a/src/main.lib/DomainObjects/Target.cs b/src/main.lib/DomainObjects/Target.cs index b0df48d..48d3dd9 100644 --- a/src/main.lib/DomainObjects/Target.cs +++ b/src/main.lib/DomainObjects/Target.cs @@ -33,12 +33,12 @@ namespace PKISharp.WACS.DomainObjects /// <summary> /// The CSR used to request the certificate /// </summary> - public byte[] CsrBytes { get; set; } + public byte[]? CsrBytes { get; set; } /// <summary> /// The Private Key corresponding to the CSR /// </summary> - public AsymmetricKeyParameter PrivateKey { get; set; } + public AsymmetricKeyParameter? PrivateKey { get; set; } /// <summary> /// Pretty print information about the target @@ -48,7 +48,7 @@ namespace PKISharp.WACS.DomainObjects { var x = new StringBuilder(); x.Append(CommonName); - var alternativeNames = Parts.SelectMany(p => p.Identifiers); + var alternativeNames = Parts.SelectMany(p => p.Identifiers).Distinct(); if (alternativeNames.Count() > 1) { x.Append($" and {alternativeNames.Count() - 1} alternatives"); diff --git a/src/main.lib/Plugins/TargetPlugins/Csr/CsrOptions.cs b/src/main.lib/Plugins/TargetPlugins/Csr/CsrOptions.cs index 50507f9..009d820 100644 --- a/src/main.lib/Plugins/TargetPlugins/Csr/CsrOptions.cs +++ b/src/main.lib/Plugins/TargetPlugins/Csr/CsrOptions.cs @@ -8,8 +8,8 @@ namespace PKISharp.WACS.Plugins.TargetPlugins { public static string NameLabel => "CSR"; public override string Name => NameLabel; - public override string Description => "Read a CSR created by another program"; - public string CsrFile { get; set; } - public string PkFile { get; set; } + public override string Description => "CSR created by another program"; + public string? CsrFile { get; set; } + public string? PkFile { get; set; } } } diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs deleted file mode 100644 index c3d14ce..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs +++ /dev/null @@ -1,59 +0,0 @@ -//using PKISharp.WACS.Clients.IIS; -//using PKISharp.WACS.DomainObjects; -//using PKISharp.WACS.Plugins.Interfaces; -//using PKISharp.WACS.Services; -//using System.Collections.Generic; -//using System.Linq; -//using System.Threading.Tasks; - -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISBinding : ITargetPlugin -// { -// private readonly ILogService _log; -// private readonly IISBindingOptions _options; -// private readonly IISBindingHelper _helper; -// private readonly UserRoleService _userRoleService; - -// public IISBinding( -// ILogService logService, UserRoleService roleService, -// IISBindingHelper helper, IISBindingOptions options) -// { -// _log = logService; -// _options = options; -// _helper = helper; -// _userRoleService = roleService; -// } - -// public Task<Target> Generate() -// { -// var allBindings = _helper.GetBindings(); -// var matchingBindings = allBindings.Where(x => x.HostUnicode == _options.Host); -// if (matchingBindings.Count() == 0) -// { -// _log.Error("Binding {binding} not yet found in IIS, create it or use the Manual target plugin instead", _options.Host); -// return Task.FromResult(default(Target)); -// } -// else if (!matchingBindings.Any(b => b.SiteId == _options.SiteId)) -// { -// var newMatch = matchingBindings.First(); -// _log.Warning("Binding {binding} moved from site {a} to site {b}", _options.Host, _options.SiteId, newMatch.SiteId); -// _options.SiteId = newMatch.SiteId; -// } -// return Task.FromResult(new Target() -// { -// FriendlyName = $"[{nameof(IISBinding)}] {_options.Host}", -// CommonName = _options.Host, -// Parts = new[] { -// new TargetPart { -// Identifiers = new List<string> { _options.Host }, -// SiteId = _options.SiteId -// } -// } -// }); -// } - -// bool IPlugin.Disabled => Disabled(_userRoleService); -// internal static bool Disabled(UserRoleService userRoleService) => !userRoleService.AllowIIS; -// } -//} diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs deleted file mode 100644 index ab669c8..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs +++ /dev/null @@ -1,8 +0,0 @@ -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISBindingArguments -// { -// public string SiteId { get; set; } -// public string Host { get; set; } -// } -//} diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArgumentsProvider.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArgumentsProvider.cs deleted file mode 100644 index 728e16c..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArgumentsProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -//using Fclp; -//using PKISharp.WACS.Configuration; - -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISBindingArgumentsProvider : BaseArgumentsProvider<IISBindingArguments> -// { -// public override string Name => "IIS Binding plugin"; -// public override string Group => "Target"; -// public override string Condition => "--target iisbinding"; - -// public override bool Active(IISBindingArguments current) -// { -// return !string.IsNullOrEmpty(current.SiteId) || -// !string.IsNullOrEmpty(current.Host); -// } - -// public override void Configure(FluentCommandLineParser<IISBindingArguments> parser) -// { -// parser.Setup(o => o.SiteId) -// .As("siteid") -// .WithDescription("Id of the site where the binding should be found (optional)."); -// parser.Setup(o => o.Host) -// .As("host") -// .WithDescription("Host of the binding to get a certificate for."); -// } -// } -//} diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs index 01133f1..b662ec9 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs @@ -9,24 +9,6 @@ //{ // internal class IISBindingOptionsFactory : TargetPluginOptionsFactory<IISBinding, IISBindingOptions> // { -// private readonly IISBindingHelper _helper; -// private readonly ILogService _log; -// private readonly IArgumentsService _arguments; - -// public IISBindingOptionsFactory( -// ILogService log, IIISClient iisClient, -// IISBindingHelper helper, IArgumentsService arguments, -// UserRoleService userRoleService) -// { -// _helper = helper; -// _log = log; -// _arguments = arguments; -// Hidden = !(iisClient.Version.Major > 6); -// Disabled = IISBinding.Disabled(userRoleService); -// } - -// public override int Order => 1; - // public override async Task<IISBindingOptions> Aquire(IInputService inputService, RunLevel runLevel) // { // var ret = new IISBindingOptions(); @@ -49,37 +31,5 @@ // } // return null; // } - -// public override Task<IISBindingOptions> Default() -// { -// var ret = new IISBindingOptions(); -// var args = _arguments.GetArguments<IISBindingArguments>(); -// var hostName = _arguments.TryGetRequiredArgument(nameof(args.Host), args.Host).ToLower(); -// var rawSiteId = args.SiteId; -// var filterSet = _helper.GetBindings(); -// if (!string.IsNullOrEmpty(rawSiteId)) -// { -// if (long.TryParse(rawSiteId, out var siteId)) -// { -// filterSet = filterSet.Where(x => x.SiteId == siteId).ToList(); -// } -// else -// { -// _log.Error("Invalid SiteId {siteId}", rawSiteId); -// return Task.FromResult(default(IISBindingOptions)); -// } -// } -// var chosenTarget = filterSet.Where(x => x.HostUnicode == hostName || x.HostPunycode == hostName).FirstOrDefault(); -// if (chosenTarget != null) -// { -// ret.SiteId = chosenTarget.SiteId; -// ret.Host = chosenTarget.HostUnicode; -// return Task.FromResult(ret); -// } -// else -// { -// return Task.FromResult(default(IISBindingOptions)); -// } -// } // } //}
\ No newline at end of file diff --git a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindings.cs b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindings.cs index f743a65..95b0837 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindings.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindings.cs @@ -2,9 +2,7 @@ using PKISharp.WACS.DomainObjects; using PKISharp.WACS.Plugins.Interfaces; using PKISharp.WACS.Services; -using System.Collections.Generic; using System.Linq; -using System.Text.RegularExpressions; using System.Threading.Tasks; namespace PKISharp.WACS.Plugins.TargetPlugins @@ -29,8 +27,9 @@ namespace PKISharp.WACS.Plugins.TargetPlugins public async Task<Target?> Generate() { // Check if we have any bindings - var bindings = _helper.FilterBindings(_options); - if (bindings.Count() == 0) + var allBindings = _helper.GetBindings(); + var filteredBindings = _helper.FilterBindings(allBindings, _options); + if (filteredBindings.Count() == 0) { return null; } @@ -68,7 +67,7 @@ namespace PKISharp.WACS.Plugins.TargetPlugins // Handle common name var cn = _options.CommonName ?? ""; var cnDefined = !string.IsNullOrWhiteSpace(cn); - var cnValid = cnDefined && bindings.Any(x => x.HostUnicode == cn); + var cnValid = cnDefined && filteredBindings.Any(x => x.HostUnicode == cn); if (cnDefined && !cnValid) { _log.Warning("Specified common name {cn} not valid", cn); @@ -78,8 +77,8 @@ namespace PKISharp.WACS.Plugins.TargetPlugins var result = new Target() { FriendlyName = friendlyNameSuggestion, - CommonName = cnValid ? cn : bindings.First().HostUnicode, - Parts = bindings. + CommonName = cnValid ? cn : filteredBindings.First().HostUnicode, + Parts = filteredBindings. GroupBy(x => x.SiteId). Select(group => new TargetPart { diff --git a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptions.cs b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptions.cs index 2f68c12..8ac609d 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptions.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptions.cs @@ -73,6 +73,10 @@ namespace PKISharp.WACS.Plugins.TargetPlugins else if (IncludeHosts != null && IncludeHosts.Any()) { input.Show("Hosts", string.Join(',', IncludeHosts), level: 1); + } + else + { + input.Show("Hosts", "All", level: 1); } // Last-minute exclude diff --git a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptionsFactory.cs index 1899a36..4193d3e 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptionsFactory.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISBindings/IISBindingsOptionsFactory.cs @@ -47,97 +47,129 @@ namespace PKISharp.WACS.Plugins.TargetPlugins public override async Task<IISBindingsOptions?> Aquire(IInputService input, RunLevel runLevel) { - var ret = new IISBindingsOptions(); - return ret; - //var bindings = _helper.GetBindings().Where(x => !_arguments.MainArguments.HideHttps || x.Https == false); - - //if (!bindings.Any()) - //{ - // _log.Error($"No sites with named bindings have been configured in IIS. Add one or choose '{ManualOptions.DescriptionText}'."); - // return null; - //} + var allSites = _iisHelper.GetSites(true).Where(x => x.Hosts.Any()).ToList(); + if (!allSites.Any()) + { + _log.Error($"No sites with named bindings have been configured in IIS. " + + $"Add one in the IIS Manager or choose the plugin '{ManualOptions.DescriptionText}' " + + $"instead."); + return null; + } - //var chosenTarget = await input.ChooseFromList( - // "Choose selection mode", - // new[] { - // Choice.Create(IISBindingsSearchMode.Csv, "Enter host names separated by commas"), - // Choice.Create(IISBindingsSearchMode.Pattern, "Enter a search string using * and ? as placeholders"), - // Choice.Create(IISBindingsSearchMode.Regex, "Enter a regular expression"), - // }, - // x => x, - // "Abort"); + var visibleSites = allSites.Where(x => !_arguments.MainArguments.HideHttps || x.Https == false).ToList(); + if (!visibleSites.Any()) + { + _log.Error("No sites with named bindings remain after applying the --{hidehttps} filter. " + + "It looks like all your websites are already configured for https!", "hidehttps"); + return null; + } - //Regex regEx; - //string search; - //await input.WritePagedList(bindings.Select(x => - // Choice.Create( - // x, - // command: "", - // color: x.Https ? ConsoleColor.Gray : (ConsoleColor?)null))); + // Scan all bindings + do + { + var allBindings = _iisHelper.GetBindings(); + var visibleBindings = allBindings.Where(x => !_arguments.MainArguments.HideHttps || x.Https == false).ToList(); + var ret = await TryAquireSettings(input, allBindings, visibleBindings, allSites, visibleSites); + if (ret != null) + { + var filtered = _iisHelper.FilterBindings(allBindings, ret); + await ListBindings(input, filtered, ret); + if (await input.PromptYesNo("Accept this filter?", true)) + { + return ret; + } + } + if (!await input.PromptYesNo("Try again?", true)) + { + return null; + } + } + while (true); + } - //switch (chosenTarget) - //{ - // case IISBindingsSearchMode.Csv: - // { + private async Task<IISBindingsOptions?> TryAquireSettings( + IInputService input, + List<IISHelper.IISBindingOption> allBindings, + List<IISHelper.IISBindingOption> visibleBindings, + List<IISHelper.IISSiteOption> allSites, + List<IISHelper.IISSiteOption> visibleSites) + { + input.Show(null, "Please select which website(s) should be scanned for host names. " + + "You may input one or more site identifiers (comma separated) to filter by those sites, " + + "or alternatively leave the input empty to scan *all* websites.", true); - // do - // { - // search = await input.RequestString("Enter a comma seperated string of host names"); - // if (search != null) - // { - // regEx = TryParseRegEx(HostsToRegex(search.ParseCsv())); - // } - // } while (!await ListMatchingBindings(bindings, regEx, input)); - // return new IISBindingsOptions { IncludeHosts = search }; - // } + var ret = new IISBindingsOptions(); + await input.WritePagedList( + visibleSites.Select(x => Choice.Create( + item: x, + description: $"{x.Name} ({x.Hosts.Count()} binding{(x.Hosts.Count() == 1 ? "" : "s")})", + command: x.Id.ToString(), + color: x.Https ? ConsoleColor.DarkGray : (ConsoleColor?)null))); + var csv = await input.RequestString("Site identifier(s) or <ENTER> to choose all"); + if (!ParseSiteOptions(csv, allSites, ret)) + { + return null; + } - // case IISBindingsSearchMode.Pattern: - // { - // do - // { - // search = await input.RequestString("Enter a search string using * and ? as placeholders"); - // regEx = TryParseRegEx(PatternToRegex(search)); - // } while (!await ListMatchingBindings(bindings, regEx, input)); - // return new IISBindingsOptions { IncludePattern = search }; - // } + input.Show(null, "You may either choose to include all host names found at the selected" + + " sites(s) or you filter by host name to target only a specific set of bindings, or" + + " even just a single one.", true); - // case IISBindingsSearchMode.Regex: - // { - // do - // { - // search = await input.RequestString("Enter a regular expression"); - // regEx = TryParseRegEx(search); - // } while (!await ListMatchingBindings(bindings, regEx, input)); - // return new IISBindingsOptions { IncludeRegex = regEx }; - // } + var choice = await input.ChooseFromList("Filter", new List<Choice<string>>() + { + Choice.Create("a", "Pick specific bindings from a list"), + Choice.Create("b", "Use simple pattern matching"), + Choice.Create("c", "Use a regular expression (experts only!)"), + Choice.Create("d", "None", @default: true) + }); + switch (choice) + { + case "a": + // "Pick specific bindings from a list" + var filtered = _iisHelper.FilterBindings(allBindings, ret); + await ListBindings(input, filtered, ret); + do + { + csv = await input.RequestString("List of host names to include"); + if (!string.IsNullOrEmpty(csv)) + { + // Magically replace binding identifiers by their proper host names + csv = string.Join(",", csv.ParseCsv().Select(x => + { + if (int.TryParse(x, out int id)) + { + if (id > 0 && id <= filtered.Count()) + { + return filtered[id - 1].HostUnicode; + } + } + return x; + })); + } + } + while (!ParseHostOptions(csv, allBindings, ret)); + break; + case "b": + // "Use simple pattern matching" + break; + case "c": + // "Use a regular expression (experts only!)" + break; + case "d": + // "None" + break; + } - // default: - // return null; - //} + return ret; } - //private async Task<bool> ListMatchingBindings(IEnumerable<IISBindingHelper.IISBindingOption> bindings, Regex regEx, IInputService input) - //{ - // if (regEx == null) - // { - // return false; - // } - // var matches = bindings.Where(binding => help.Matches(binding, regEx)); - // if (matches.Any()) - // { - // await input.WritePagedList(matches.Select(x => - // Choice.Create( - // x, - // command: "", - // color: x.Https ? ConsoleColor.Gray : (ConsoleColor?)null))); - // } - // else - // { - // input.Show(null, "No matching hosts found."); - // } - - // return await input.PromptYesNo("Should the search pattern be used?", matches.Any()); - //} + private async Task ListBindings(IInputService input, List<IISHelper.IISBindingOption> bindings, IISBindingsOptions options) + { + await input.WritePagedList( + bindings.Select(x => Choice.Create( + item: x, + color: x.Https ? ConsoleColor.DarkGray : (ConsoleColor?)null))); + } private Regex? TryParseRegEx(string pattern) { @@ -176,19 +208,25 @@ namespace PKISharp.WACS.Plugins.TargetPlugins return null; } - if (!DefaultHostOptions(args, options)) + var allSites = _iisHelper.GetSites(false); + if (!ParseSiteOptions(args.SiteId, allSites, options)) + { + return null; + } + + var allBindings = _iisHelper.GetBindings(); + if (!DefaultExcludeOptions(args, allBindings, options)) { return null; } - if (!DefaultSiteOptions(args, options)) + if (!ParseHostOptions(args.Host, allBindings, options)) { return null; } - - var filterSet = _iisHelper.FilterBindings(options); + var filterSet = _iisHelper.FilterBindings(allBindings, options); if (!filterSet.Any()) { - _log.Error("No matching hosts found with selected filters"); + _log.Error("No bindings found within selected filters"); return null; } @@ -200,6 +238,17 @@ namespace PKISharp.WACS.Plugins.TargetPlugins return options; } + private bool DefaultExcludeOptions(IISBindingsArguments args, List<IISHelper.IISBindingOption> allBindings, IISBindingsOptions ret) + { + // First process excludes + ret.ExcludeHosts = args.ExcludeBindings.ParseCsv(); + if (ret.ExcludeHosts != null) + { + ret.ExcludeHosts = ret.ExcludeHosts.Select(x => x.ConvertPunycode()).ToList(); + } + return true; + } + /// <summary> /// Host filtering options in unattended mode /// </summary> @@ -207,39 +256,38 @@ namespace PKISharp.WACS.Plugins.TargetPlugins /// <param name="bindings"></param> /// <param name="ret"></param> /// <returns></returns> - private bool DefaultHostOptions(IISBindingsArguments args, IISBindingsOptions ret) + private bool ParseHostOptions(string? input, List<IISHelper.IISBindingOption> allBindings, IISBindingsOptions ret) { - var specifiedHosts = args.Host.ParseCsv(); + var specifiedHosts = input.ParseCsv(); if (specifiedHosts != null) { - var bindings = _iisHelper.GetBindings(); + var filteredBindings = _iisHelper.FilterBindings(allBindings, ret); foreach (var specifiedHost in specifiedHosts) { - var binding = bindings.FirstOrDefault( - x => x.HostUnicode == specifiedHost || - x.HostPunycode == specifiedHost); - if (binding != null) + var filteredBinding = filteredBindings.FirstOrDefault(x => x.HostUnicode == specifiedHost || x.HostPunycode == specifiedHost); + var binding = allBindings.FirstOrDefault(x => x.HostUnicode == specifiedHost || x.HostPunycode == specifiedHost); + if (filteredBinding != null) { if (ret.IncludeHosts == null) { ret.IncludeHosts = new List<string>(); } - ret.IncludeHosts.Add(binding.HostUnicode); + ret.IncludeHosts.Add(filteredBinding.HostUnicode); + } + else if (binding != null) + { + + _log.Error("Binding {specifiedHost} is excluded by another filter", specifiedHost); + return false; } else { - _log.Error("Unable to find binding {specifiedHost}", specifiedHost); + _log.Error("Binding {specifiedHost} not found", specifiedHost); return false; } } } - ret.ExcludeHosts = args.ExcludeBindings.ParseCsv(); - if (ret.ExcludeHosts != null) - { - ret.ExcludeHosts = ret.ExcludeHosts.Select(x => x.ConvertPunycode()).ToList(); - } - return true; } @@ -275,43 +323,42 @@ namespace PKISharp.WACS.Plugins.TargetPlugins /// <param name="args"></param> /// <param name="options"></param> /// <returns></returns> - private bool DefaultSiteOptions(IISBindingsArguments args, IISBindingsOptions options) + private bool ParseSiteOptions(string? input, List<IISHelper.IISSiteOption> sites, IISBindingsOptions options) { - if (string.IsNullOrEmpty(args.SiteId)) + if (string.IsNullOrEmpty(input)) { return true; } - if (string.Equals(args.SiteId, "s", StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(input, "s", StringComparison.CurrentCultureIgnoreCase)) { return true; } - var identifiers = args.SiteId.ParseCsv(); + var identifiers = input.ParseCsv(); if (identifiers == null) { throw new InvalidOperationException(); } var ret = new List<long>(); - var siteList = _iisHelper.GetSites(false); foreach (var identifierString in identifiers) { if (long.TryParse(identifierString, out var id)) { - var site = siteList.Where(t => t.Id == id).FirstOrDefault(); + var site = sites.Where(t => t.Id == id).FirstOrDefault(); if (site != null) { ret.Add(site.Id); } else { - _log.Error($"SiteId '{id}' not found"); + _log.Error("Site identifier '{id}' not found", id); return false; } } else { - _log.Error($"Invalid SiteId '{id}', should be a number"); + _log.Error("Invalid site identifier '{identifierString}', should be a number", identifierString); return false; } } diff --git a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSite.cs b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSite.cs deleted file mode 100644 index d4d315b..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSite.cs +++ /dev/null @@ -1,62 +0,0 @@ -//using PKISharp.WACS.DomainObjects; -//using PKISharp.WACS.Plugins.Interfaces; -//using PKISharp.WACS.Services; -//using System.Linq; -//using System.Threading.Tasks; - -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISSite : ITargetPlugin -// { -// private readonly ILogService _log; -// private readonly IISSiteHelper _helper; -// private readonly IISSiteOptions _options; -// private readonly UserRoleService _userRoleService; - -// public IISSite( -// ILogService logService, UserRoleService roleService, -// IISSiteHelper helper, IISSiteOptions options) -// { -// _log = logService; -// _helper = helper; -// _options = options; -// _userRoleService = roleService; -// } - -// public Task<Target> Generate() -// { -// var site = _helper.GetSites(false).FirstOrDefault(s => s.Id == _options.SiteId); -// if (site == null) -// { -// _log.Error($"SiteId {_options.SiteId} not found"); -// return Task.FromResult(default(Target)); -// } -// var hosts = site.Hosts; -// if (_options.ExcludeBindings != null) -// { -// hosts = hosts.Except(_options.ExcludeBindings).ToList(); -// } -// var cn = _options.CommonName; -// var cnDefined = !string.IsNullOrWhiteSpace(cn); -// var cnValid = cnDefined && hosts.Contains(cn); -// if (cnDefined && !cnValid) -// { -// _log.Warning("Specified common name {cn} not valid", cn); -// } -// return Task.FromResult(new Target() -// { -// FriendlyName = $"[{nameof(IISSite)}] {site.Name}", -// CommonName = cnValid ? cn : hosts.FirstOrDefault(), -// Parts = new[] { -// new TargetPart() { -// Identifiers = hosts, -// SiteId = site.Id -// } -// } -// }); -// } - -// bool IPlugin.Disabled => Disabled(_userRoleService); -// internal static bool Disabled(UserRoleService userRoleService) => !userRoleService.AllowIIS; -// } -//}
\ No newline at end of file diff --git a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArguments.cs b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArguments.cs deleted file mode 100644 index ac653e8..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArguments.cs +++ /dev/null @@ -1,9 +0,0 @@ -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISSiteArguments -// { -// public string SiteId { get; set; } -// public string CommonName { get; set; } -// public string ExcludeBindings { get; set; } -// } -//} diff --git a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArgumentsProvider.cs b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArgumentsProvider.cs deleted file mode 100644 index a6ff443..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteArgumentsProvider.cs +++ /dev/null @@ -1,31 +0,0 @@ -//using Fclp; -//using PKISharp.WACS.Configuration; - -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISSiteArgumentsProvider : BaseArgumentsProvider<IISSiteArguments> -// { -// public override string Name => "IIS Site(s) plugin"; -// public override string Group => "Target"; -// public override string Condition => "--target iissite|iissites"; -// public override bool Active(IISSiteArguments current) -// { -// return !string.IsNullOrEmpty(current.SiteId) || -// !string.IsNullOrEmpty(current.CommonName) || -// !string.IsNullOrEmpty(current.ExcludeBindings); -// } - -// public override void Configure(FluentCommandLineParser<IISSiteArguments> parser) -// { -// parser.Setup(o => o.SiteId) -// .As("siteid") -// .WithDescription("Identifier of the site that the plugin should create the target from. For iissites this may be a comma separated list."); -// parser.Setup(o => o.CommonName) -// .As("commonname") -// .WithDescription("Specify the common name of the certificate that should be requested for the target. By default this will be the first binding that is enumerated."); -// parser.Setup(o => o.ExcludeBindings) -// .As("excludebindings") -// .WithDescription("Exclude host names from the certificate. This may be a comma separated list."); -// } -// } -//} diff --git a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsFactory.cs index f57f561..4cc0022 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsFactory.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsFactory.cs @@ -9,28 +9,6 @@ //{ // internal class IISSiteOptionsFactory : TargetPluginOptionsFactory<IISBindings, IISSiteOptions> // { -// protected IIISClient _iisClient; -// protected IISSiteHelper _siteHelper; -// protected IISSiteOptionsHelper _optionsHelper; -// private readonly ILogService _log; -// private readonly IArgumentsService _arguments; - -// public IISSiteOptionsFactory( -// ILogService log, IIISClient iisClient, -// IISSiteHelper helper, IArgumentsService arguments, -// UserRoleService userRoleService) -// { -// _iisClient = iisClient; -// _siteHelper = helper; -// _optionsHelper = new IISSiteOptionsHelper(log); -// _log = log; -// _arguments = arguments; -// Hidden = !(iisClient.Version.Major > 6); -// Disabled = IsDisabled(userRoleService); -// } - -// public override int Order => 3; - // public async override Task<IISSiteOptions> Aquire(IInputService input, RunLevel runLevel) // { // var ret = new IISSiteOptions(); @@ -62,34 +40,4 @@ // } // return null; // } -// internal static bool IsDisabled(UserRoleService userRoleService) => !userRoleService.AllowIIS; - -// public override Task<IISSiteOptions> Default() -// { -// var ret = new IISSiteOptions(); -// var args = _arguments.GetArguments<IISSiteArguments>(); -// var rawSiteId = _arguments.TryGetRequiredArgument(nameof(args.SiteId), args.SiteId); -// if (long.TryParse(rawSiteId, out var siteId)) -// { -// var site = _siteHelper.GetSites(false).FirstOrDefault(binding => binding.Id == siteId); -// if (site != null) -// { -// ret.SiteId = site.Id; -// if (_optionsHelper.DefaultAdvancedOptions(args, site.Hosts, ret)) -// { -// return Task.FromResult(ret); -// } -// } -// else -// { -// _log.Error("Unable to find SiteId {siteId}", siteId); -// } -// } -// else -// { -// _log.Error("Invalid SiteId {siteId}", args.SiteId); -// } -// return Task.FromResult(default(IISSiteOptions)); -// } -// } //} diff --git a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsHelper.cs b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsHelper.cs index 7bbc257..f236c12 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsHelper.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISSite/IISSiteOptionsHelper.cs @@ -8,10 +8,6 @@ //{ // internal class IISSiteOptionsHelper // { -// private readonly ILogService _log; - -// public IISSiteOptionsHelper(ILogService log) => _log = log; - // public async Task<bool> AquireAdvancedOptions(IInputService input, IEnumerable<string> chosen, RunLevel runLevel, IIISSiteOptions ret) // { // if (runLevel.HasFlag(RunLevel.Advanced)) @@ -42,13 +38,4 @@ // } // return true; // } - - -// } - -// public interface IIISSiteOptions -// { -// List<string>? ExcludeBindings { get; set; } -// string? CommonName { get; set; } -// } -//} +// }
\ No newline at end of file diff --git a/src/main.lib/Plugins/TargetPlugins/IISSites/IISSites.cs b/src/main.lib/Plugins/TargetPlugins/IISSites/IISSites.cs deleted file mode 100644 index e8cfe57..0000000 --- a/src/main.lib/Plugins/TargetPlugins/IISSites/IISSites.cs +++ /dev/null @@ -1,75 +0,0 @@ -//using PKISharp.WACS.DomainObjects; -//using PKISharp.WACS.Plugins.Interfaces; -//using PKISharp.WACS.Services; -//using System.Collections.Generic; -//using System.Linq; -//using System.Threading.Tasks; - -//namespace PKISharp.WACS.Plugins.TargetPlugins -//{ -// internal class IISSites : ITargetPlugin -// { -// private readonly ILogService _log; -// private readonly IISSiteHelper _helper; -// private readonly IISSitesOptions _options; -// private readonly UserRoleService _userRoleService; - -// public IISSites( -// ILogService log, UserRoleService roleService, -// IISSiteHelper helper, IISSitesOptions options) -// { -// _log = log; -// _helper = helper; -// _options = options; -// _userRoleService = roleService; -// } - -// public Task<Target> Generate() -// { -// var sites = _helper.GetSites(false); -// var filtered = new List<IISSiteHelper.IISSiteOption>(); -// if (_options.All == true) -// { -// filtered = sites; -// } -// else -// { -// foreach (var id in _options.SiteIds) -// { -// var site = sites.FirstOrDefault(s => s.Id == id); -// if (site != null) -// { -// filtered.Add(site); -// } -// else -// { -// _log.Warning("SiteId {Id} not found", id); -// } -// } -// } -// var allHosts = filtered.SelectMany(x => x.Hosts); -// var exclude = _options.ExcludeBindings ?? new List<string>(); -// allHosts = allHosts.Except(exclude).ToList(); -// var cn = _options.CommonName; -// var cnDefined = !string.IsNullOrWhiteSpace(cn); -// var cnValid = cnDefined && allHosts.Contains(cn); -// if (cnDefined && !cnValid) -// { -// _log.Warning("Specified common name {cn} not valid", cn); -// } -// return Task.FromResult(new Target() -// { -// FriendlyName = $"[{nameof(IISSites)}] {(_options.All == true ? "All" : string.Join(",", _options.SiteIds))}", -// CommonName = cnValid ? cn : allHosts.FirstOrDefault(), -// Parts = filtered.Select(site => new TargetPart -// { -// Identifiers = site.Hosts.Except(exclude).ToList(), -// SiteId = site.Id -// }) -// }); -// } - -// bool IPlugin.Disabled => Disabled(_userRoleService); -// internal static bool Disabled(UserRoleService userRoleService) => !userRoleService.AllowIIS; -// } -//}
\ No newline at end of file diff --git a/src/main.lib/Plugins/TargetPlugins/IISSites/IISSitesOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IISSites/IISSitesOptionsFactory.cs index 9bfdde5..d600a06 100644 --- a/src/main.lib/Plugins/TargetPlugins/IISSites/IISSitesOptionsFactory.cs +++ b/src/main.lib/Plugins/TargetPlugins/IISSites/IISSitesOptionsFactory.cs @@ -11,27 +11,6 @@ //{ // internal class IISSitesOptionsFactory : TargetPluginOptionsFactory<IISSites, IISSitesOptions> // { -// protected IIISClient _iisClient; -// protected IISSiteHelper _siteHelper; -// protected IISSiteOptionsHelper _optionsHelper; -// private readonly ILogService _log; -// private readonly IArgumentsService _arguments; - -// public IISSitesOptionsFactory(ILogService log, IIISClient iisClient, -// IISSiteHelper helper, IArgumentsService arguments, -// UserRoleService userRoleService) -// { -// _iisClient = iisClient; -// _siteHelper = helper; -// _log = log; -// _arguments = arguments; -// _optionsHelper = new IISSiteOptionsHelper(log); -// Hidden = !(iisClient.Version.Major > 6); -// Disabled = IISSites.Disabled(userRoleService); -// } - -// public override int Order => 4; - // public override async Task<IISSitesOptions> Aquire(IInputService input, RunLevel runLevel) // { // var ret = new IISSitesOptions(); @@ -63,80 +42,5 @@ // } // return null; // } - -// public override Task<IISSitesOptions> Default() -// { -// var ret = new IISSitesOptions(); -// var args = _arguments.GetArguments<IISSiteArguments>(); -// var sites = _siteHelper.GetSites(false); -// var rawSiteIds = _arguments.TryGetRequiredArgument(nameof(args.SiteId), args.SiteId); -// sites = ProcessSiteIds(ret, sites, rawSiteIds); -// if (sites != null) -// { -// if (_optionsHelper.DefaultAdvancedOptions(args, sites.SelectMany(s => s.Hosts), ret)) -// { -// return Task.FromResult(ret); -// } -// } -// return Task.FromResult(default(IISSitesOptions)); -// } - -// private List<IISSiteHelper.IISSiteOption> ProcessSiteIds(IISSitesOptions options, List<IISSiteHelper.IISSiteOption> sites, string sanInput) -// { -// if (string.Equals(sanInput, "s", StringComparison.InvariantCultureIgnoreCase)) -// { -// options.All = true; -// } -// else -// { -// sites = FilterOptions(sites, sanInput); -// if (sites == null) -// { -// return null; -// } -// options.SiteIds = sites.Select(x => x.Id).OrderBy(x => x).ToList(); -// } -// return sites; -// } - -// private List<IISSiteHelper.IISSiteOption> FilterOptions(List<IISSiteHelper.IISSiteOption> targets, string sanInput) -// { -// var siteList = new List<IISSiteHelper.IISSiteOption>(); -// if (string.Equals(sanInput, "s", StringComparison.InvariantCultureIgnoreCase)) -// { -// return targets; -// } -// else -// { -// var siteIDs = sanInput.ParseCsv(); -// foreach (var idString in siteIDs) -// { -// if (int.TryParse(idString, out var id)) -// { -// var site = targets.Where(t => t.Id == id).FirstOrDefault(); -// if (site != null) -// { -// siteList.Add(site); -// } -// else -// { -// _log.Error($"SiteId '{idString}' not found"); -// return null; -// } -// } -// else -// { -// _log.Error($"Invalid SiteId '{idString}', should be a number"); -// return null; -// } -// } -// if (siteList.Count == 0) -// { -// _log.Warning($"No valid sites selected"); -// return null; -// } -// } -// return siteList; -// } // } //} |