diff options
Diffstat (limited to 'src/main.lib/Plugins/TargetPlugins/IISBinding')
5 files changed, 204 insertions, 0 deletions
diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs new file mode 100644 index 0000000..b6125cc --- /dev/null +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBinding.cs @@ -0,0 +1,54 @@ +using PKISharp.WACS.Clients; +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; + +namespace PKISharp.WACS.Plugins.TargetPlugins +{ + internal class IISBinding : ITargetPlugin + { + private readonly ILogService _log; + private readonly IIISClient _iisClient; + private IISBindingOptions _options; + private readonly IISBindingHelper _helper; + + public IISBinding(ILogService logService, IIISClient iisClient, IISBindingHelper helper, IISBindingOptions options) + { + _iisClient = iisClient; + _log = logService; + _options = options; + _helper = helper; + } + + public Target Generate() + { + var allBindings = _helper.GetBindings(false); + 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 null; + } + 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 new Target() + { + FriendlyName = $"[{nameof(IISBinding)}] {_options.Host}", + CommonName = _options.Host, + Parts = new[] { + new TargetPart { + Identifiers = new List<string> { _options.Host }, + SiteId = _options.SiteId + } + } + }; + } + } +} diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs new file mode 100644 index 0000000..7340fb2 --- /dev/null +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArguments.cs @@ -0,0 +1,8 @@ +namespace PKISharp.WACS.Plugins.TargetPlugins +{ + 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 new file mode 100644 index 0000000..c93354e --- /dev/null +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingArgumentsProvider.cs @@ -0,0 +1,28 @@ +using Fclp; +using PKISharp.WACS.Configuration; + +namespace PKISharp.WACS.Plugins.TargetPlugins +{ + 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/IISBindingOptions.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptions.cs new file mode 100644 index 0000000..81b254e --- /dev/null +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptions.cs @@ -0,0 +1,30 @@ +using PKISharp.WACS.Plugins.Base; +using PKISharp.WACS.Plugins.Base.Options; +using PKISharp.WACS.Services; + +namespace PKISharp.WACS.Plugins.TargetPlugins +{ + [Plugin("2f5dd428-0f5d-4c8a-8fd0-56fc1b5985ce")] + class IISBindingOptions : TargetPluginOptions<IISBinding> + { + public override string Name => "IISBinding"; + public override string Description => "Single binding of an IIS website"; + + /// <summary> + /// Restrict search to a specific site + /// </summary> + public long SiteId { get; set; } + + /// <summary> + /// Host name of the binding to look for + /// </summary> + public string Host { get; set; } + + public override void Show(IInputService input) + { + base.Show(input); + input.Show("Host", Host, level: 1); + input.Show("SiteId", SiteId.ToString(), level: 1); + } + } +} diff --git a/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs new file mode 100644 index 0000000..f5f359b --- /dev/null +++ b/src/main.lib/Plugins/TargetPlugins/IISBinding/IISBindingOptionsFactory.cs @@ -0,0 +1,84 @@ +using PKISharp.WACS.Clients.IIS; +using PKISharp.WACS.Plugins.Base.Factories; +using PKISharp.WACS.Services; +using System.Linq; + +namespace PKISharp.WACS.Plugins.TargetPlugins +{ + internal class IISBindingOptionsFactory : TargetPluginOptionsFactory<IISBinding, IISBindingOptions> + { + public override bool Hidden => !_iisClient.HasWebSites; + protected IIISClient _iisClient; + protected IISBindingHelper _helper; + private ILogService _log; + private IArgumentsService _arguments; + + public IISBindingOptionsFactory( + ILogService log, IIISClient iisClient, + IISBindingHelper helper, IArgumentsService arguments) + { + _iisClient = iisClient; + _helper = helper; + _log = log; + _arguments = arguments; + } + + public override IISBindingOptions Aquire(IInputService inputService, RunLevel runLevel) + { + var ret = new IISBindingOptions(); + var bindings = _helper.GetBindings(_arguments.MainArguments.HideHttps).Where(x => !x.Hidden); + if (!bindings.Any()) + { + _log.Error($"No sites with named bindings have been configured in IIS. Add one or choose '{ManualOptions.DescriptionText}'."); + return null; + } + var chosenTarget = inputService.ChooseFromList( + "Choose binding", + bindings, + x => Choice.Create(x), + "Abort"); + if (chosenTarget != null) + { + ret.SiteId = chosenTarget.SiteId; + ret.Host = chosenTarget.HostUnicode; + return ret; + } + else + { + return null; + } + } + + public override 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(false); + if (!string.IsNullOrEmpty(rawSiteId)) + { + if (long.TryParse(rawSiteId, out long siteId)) + { + filterSet = filterSet.Where(x => x.SiteId == siteId).ToList(); + } + else + { + _log.Error("Invalid SiteId {siteId}", rawSiteId); + return null; + } + } + var chosenTarget = filterSet.Where(x => x.HostUnicode == hostName || x.HostPunycode == hostName).FirstOrDefault(); + if (chosenTarget != null) + { + ret.SiteId = chosenTarget.SiteId; + ret.Host = chosenTarget.HostUnicode; + return ret; + } + else + { + return null; + } + } + } +}
\ No newline at end of file |