diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 7420a4033f..da552a37c6 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -60,6 +60,7 @@ + diff --git a/src/ServiceControl.Config/Framework/Modules/InstallerModule.cs b/src/ServiceControl.Config/Framework/Modules/InstallerModule.cs index fed25576ef..531997dba8 100644 --- a/src/ServiceControl.Config/Framework/Modules/InstallerModule.cs +++ b/src/ServiceControl.Config/Framework/Modules/InstallerModule.cs @@ -66,7 +66,6 @@ internal async Task Add(ServiceControlInstallableBase details, IProg try { progress.Report(5, 9, "Registering URL ACLs..."); - instanceInstaller.RegisterUrlAcl(); progress.Report(6, 9, "Instance setup in progress, this could take several minutes..."); instanceInstaller.SetupInstance(); } @@ -87,10 +86,6 @@ internal async Task Add(ServiceControlInstallableBase details, IProg instanceInstaller.ReportCard.Warnings.Add($"New instance did not startup - please check configuration for {instance.Name}"); } } - else - { - instanceInstaller.RemoveUrlAcl(); - } instanceInstaller.ReportCard.SetStatus(); return instanceInstaller.ReportCard; @@ -193,7 +188,7 @@ internal async Task Update(ServiceControlBaseService instance, bool internal ReportCard Delete(string instanceName, bool removeDB, bool removeLogs, IProgress progress = null) { progress ??= new Progress(); - progress.Report(0, 7, "Stopping instance..."); + progress.Report(0, 6, "Stopping instance..."); var instance = InstanceFinder.FindServiceControlInstance(instanceName); instance.ReportCard = new ReportCard(); @@ -208,27 +203,24 @@ internal ReportCard Delete(string instanceName, bool removeDB, bool removeLogs, instance.BackupAppConfig(); - progress.Report(1, 7, "Disabling startup..."); + progress.Report(1, 6, "Disabling startup..."); instance.Service.SetStartupMode("Disabled"); - progress.Report(2, 7, "Deleting service..."); + progress.Report(2, 6, "Deleting service..."); instance.Service.Delete(); - progress.Report(3, 7, "Removing URL ACL..."); - instance.RemoveUrlAcl(); - - progress.Report(4, 7, "Deleting install..."); + progress.Report(3, 6, "Deleting install..."); instance.RemoveBinFolder(); if (removeLogs) { - progress.Report(5, 7, "Deleting logs..."); + progress.Report(4, 6, "Deleting logs..."); instance.RemoveLogsFolder(); } if (removeDB) { - progress.Report(6, 7, "Deleting database..."); + progress.Report(5, 6, "Deleting database..."); instance.RemoveDataBaseFolder(); } @@ -268,8 +260,6 @@ internal async Task Add(MonitoringNewInstance details, IProgress Add(MonitoringNewInstance details, IProgress Update(MonitoringInstance instance, bool startSe internal ReportCard Delete(string instanceName, bool removeLogs, IProgress progress = null) { progress ??= new Progress(); - progress.Report(0, 7, "Stopping instance..."); + progress.Report(0, 5, "Stopping instance..."); var instance = InstanceFinder.FindMonitoringInstance(instanceName); instance.ReportCard = new ReportCard(); @@ -401,21 +387,18 @@ internal ReportCard Delete(string instanceName, bool removeLogs, IProgress(); - - foreach (var user in Users) - { - try - { - var account = new NTAccount(user); - var sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier)); - sidList.Add(sid); - } - catch (Exception ex) - { - WriteError(new ErrorRecord(ex, "Failed to parse account name", ErrorCategory.InvalidData, user)); - return; - } - } - - UrlReservation.Create(new UrlReservation(Url, sidList.ToArray())); - } - [ValidateNotNullOrEmpty] [Parameter(Mandatory = true, Position = 1, HelpMessage = "The user or group to assign to this URLACL")] public string[] Users; diff --git a/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/GetUrlAcls.cs b/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/GetUrlAcls.cs index 2057bc0bd4..ca1d6c3c9c 100644 --- a/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/GetUrlAcls.cs +++ b/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/GetUrlAcls.cs @@ -1,14 +1,11 @@ namespace ServiceControl.Management.PowerShell { + using System; using System.Management.Automation; - using ServiceControlInstaller.Engine.UrlAcl; + using Particular.Obsoletes; + [ObsoleteMetadata(Message = "ServiceControl no longer requires URL reservations, so this command no longer functions", ReplacementTypeOrMember = "netsh http show urlacl", TreatAsErrorFromVersion = "7", RemoveInVersion = "8")] + [Obsolete("ServiceControl no longer requires URL reservations, so this command no longer functions. Use 'netsh http show urlacl' instead. Will be treated as an error from version 7.0.0. Will be removed in version 8.0.0.", false)] [Cmdlet(VerbsCommon.Get, "UrlAcls")] - public class GetUrlAcls : PSCmdlet - { - protected override void ProcessRecord() - { - WriteObject(UrlReservation.GetAll(), true); - } - } + public class GetUrlAcls : PSCmdlet; } \ No newline at end of file diff --git a/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/RemoveUrlAcl.cs b/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/RemoveUrlAcl.cs index cadca4a512..19855324eb 100644 --- a/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/RemoveUrlAcl.cs +++ b/src/ServiceControl.Management.PowerShell/Cmdlets/UrlAcls/RemoveUrlAcl.cs @@ -1,26 +1,11 @@ namespace ServiceControl.Management.PowerShell { + using System; using System.Management.Automation; - using ServiceControlInstaller.Engine.UrlAcl; + using Particular.Obsoletes; + [ObsoleteMetadata(Message = "ServiceControl no longer requires URL reservations, so this command no longer functions", ReplacementTypeOrMember = "netsh http delete urlacl", TreatAsErrorFromVersion = "7", RemoveInVersion = "8")] + [Obsolete("ServiceControl no longer requires URL reservations, so this command no longer functions. Use 'netsh http delete urlacl' instead. Will be treated as an error from version 7.0.0. Will be removed in version 8.0.0.", false)] [Cmdlet(VerbsCommon.Remove, "UrlAcl")] - public class RemoveUrlAcl : PSCmdlet - { - [ValidateNotNull] - [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, HelpMessage = "Specify the URLACL to remove")] - public UrlReservation[] UrlAcl { get; set; } - - protected override void BeginProcessing() - { - Account.TestIfAdmin(); - } - - protected override void ProcessRecord() - { - foreach (var entry in UrlAcl) - { - UrlReservation.Delete(entry); - } - } - } + public class RemoveUrlAcl : PSCmdlet; } \ No newline at end of file diff --git a/src/ServiceControl.Management.PowerShell/ServiceControl.Management.PowerShell.csproj b/src/ServiceControl.Management.PowerShell/ServiceControl.Management.PowerShell.csproj index 2bf24380a9..c3a794f355 100644 --- a/src/ServiceControl.Management.PowerShell/ServiceControl.Management.PowerShell.csproj +++ b/src/ServiceControl.Management.PowerShell/ServiceControl.Management.PowerShell.csproj @@ -30,6 +30,10 @@ + + + + diff --git a/src/ServiceControlInstaller.Engine.UnitTests/UrlAcl/UrlReservationTest.cs b/src/ServiceControlInstaller.Engine.UnitTests/UrlAcl/UrlReservationTest.cs deleted file mode 100644 index 46c8dfa13e..0000000000 --- a/src/ServiceControlInstaller.Engine.UnitTests/UrlAcl/UrlReservationTest.cs +++ /dev/null @@ -1,162 +0,0 @@ -namespace ServiceControlInstaller.Engine.UnitTests.UrlAcl -{ - using System; - using System.Linq; - using System.Security.Principal; - using Engine.UrlAcl; - using NUnit.Framework; - - [TestFixture] - public class UrlReservationTests - { - [Test] - public void GetAllResults() - { - var reservations = UrlReservation.GetAll(); - Assert.Multiple(() => - { - Assert.That(reservations.Count > 0, Is.True, "No UrlAcls found"); - Assert.That(reservations.All(p => !string.IsNullOrWhiteSpace(p.Url)), Is.True, "UrlAcls found with empty URLs"); - Assert.That(reservations.All(p => p.Users.Count > 0), Is.True, "UrlAcls found with empty delegations"); - }); - - foreach (var x in reservations) - { - Console.Write(x.Url); - Console.WriteLine(string.Join(", ", x.Users)); - } - } - - [Test] - public void ThrowIfCreateInvalidUrlAcl() - { - //Try Adding a UrlAcl without a SecurityIdentifier - var reservation = new UrlReservation(url); - if (UrlReservation.GetAll().Any(p => p.Url.Equals(reservation.Url, StringComparison.OrdinalIgnoreCase))) - { - UrlReservation.Delete(reservation); - Assert.That(UrlReservation.GetAll().Any(p => p.Url.Equals(reservation.Url, StringComparison.OrdinalIgnoreCase)), Is.False, "UrlAcl exists after deletion"); - } - - Assert.Throws(() => UrlReservation.Create(reservation), "UrlAcl incorrectly created with empty delegation"); - } - - [Test] - public void AddAndDeleteUrlAcl() - { - var reservation = new UrlReservation(url, new SecurityIdentifier(WellKnownSidType.WorldSid, null)); - reservation.Create(); - Assert.That(UrlReservation.GetAll().Any(p => p.Url.Equals(url)), Is.True, "UrlAcl doesn't exist after creation"); - reservation.Delete(); - Assert.That(UrlReservation.GetAll().Count(p => p.Url.Equals(url)) == 0, Is.True, "UrlAcl exists after deletion"); - } - - [Test] - public void ClobberUrlAcl() - { - //Make Reservation - foreach (var r in UrlReservation.GetAll().Where(p => p.Url.Equals(url))) - { - r.Delete(); - } - - var reservation = new UrlReservation(url, new SecurityIdentifier(WellKnownSidType.WorldSid, null)); - reservation.Create(); - - //Overwrite Reservation - var newSid = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null); - var account = (NTAccount)newSid.Translate(typeof(NTAccount)); - var reservation2 = new UrlReservation(url, newSid); - reservation2.Create(); - - var actual = UrlReservation.GetAll().First(p => p.Url == reservation.Url); - Assert.Multiple(() => - { - Assert.That(actual.Users.Count == 1, Is.True, "user count is incorrect"); - Assert.That(actual.Users.Contains(account.Value, StringComparer.OrdinalIgnoreCase), Is.True, "wrong user found"); - }); - } - - [Test] - public void AddUsersToUrlAcl() - { - var reservation = new UrlReservation(url, new SecurityIdentifier(WellKnownSidType.WorldSid, null)); - reservation.Create(); - - // Read Back the URL - reservation = UrlReservation.GetAll().First(p => p.Url == reservation.Url); - Assert.That(reservation.Users.Count, Is.EqualTo(1), "User count is not 1"); - Assert.That(reservation.Users.First().Equals("Everyone", StringComparison.OrdinalIgnoreCase), Is.True, "User is not 'Everyone'"); - - var newAccountSid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); - reservation.AddSecurityIdentifier(newAccountSid); - reservation.Create(); - - var account = (NTAccount)newAccountSid.Translate(typeof(NTAccount)); - reservation = UrlReservation.GetAll().First(p => p.Url == reservation.Url); - Assert.That(reservation.Users.Count, Is.EqualTo(2), "User count is not 2"); - Assert.That(reservation.Users.Contains(account.Value, StringComparer.OrdinalIgnoreCase), Is.True, "Added User not found"); - } - - [Test] - public void CheckPatternMatching() - { - var testUrl = new UrlReservation("http://localhost/"); - Assert.Multiple(() => - { - Assert.That(testUrl.HTTPS, Is.False); - Assert.That(testUrl.HostName == "localhost", Is.True); - Assert.That(testUrl.Port == 80, Is.True); - Assert.That(testUrl.VirtualDirectory == string.Empty, Is.True); - }); - - testUrl = new UrlReservation("https://localhost:8000/"); - Assert.Multiple(() => - { - Assert.That(testUrl.HTTPS, Is.True); - Assert.That(testUrl.HostName == "localhost", Is.True); - Assert.That(testUrl.Port == 8000, Is.True); - Assert.That(testUrl.VirtualDirectory == string.Empty, Is.True); - }); - - testUrl = new UrlReservation("https://localhost:8000/foo/api/"); - Assert.Multiple(() => - { - Assert.That(testUrl.HTTPS, Is.True); - Assert.That(testUrl.HostName == "localhost", Is.True); - Assert.That(testUrl.Port == 8000, Is.True); - Assert.That(testUrl.VirtualDirectory == "foo/api", Is.True); - }); - - testUrl = new UrlReservation("https://localhost/foo/api/"); - Assert.Multiple(() => - { - Assert.That(testUrl.HTTPS, Is.True); - Assert.That(testUrl.HostName == "localhost", Is.True); - Assert.That(testUrl.Port == 443, Is.True); - Assert.That(testUrl.VirtualDirectory == "foo/api", Is.True); - }); - - testUrl = new UrlReservation("https://[::1]:10253/"); - Assert.Multiple(() => - { - Assert.That(testUrl.HTTPS, Is.True); - Assert.That(testUrl.HostName == "[::1]", Is.True); - Assert.That(testUrl.Port == 10253, Is.True); - }); - - Assert.Throws(() => new UrlReservation("https://localhost:8000/foo/api"), "UrlAcl is invalid without trailing /"); - } - - [TearDown] - public void TearDown() - { - foreach (var urlReservation in UrlReservation.GetAll().Where(p => p.Url.Equals(url, StringComparison.OrdinalIgnoreCase))) - { - urlReservation.Delete(); - } - } - - const string url = "http://bogushostname:12345/"; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/Instances/MonitoringInstance.cs b/src/ServiceControlInstaller.Engine/Instances/MonitoringInstance.cs index 7a1be79145..7770296479 100644 --- a/src/ServiceControlInstaller.Engine/Instances/MonitoringInstance.cs +++ b/src/ServiceControlInstaller.Engine/Instances/MonitoringInstance.cs @@ -3,7 +3,6 @@ using System; using System.Configuration; using System.IO; - using System.Linq; using System.Security.AccessControl; using System.Security.Principal; using System.Threading.Tasks; @@ -14,7 +13,6 @@ using ReportCard; using Services; using Setup; - using UrlAcl; using Validation; public class MonitoringInstance : BaseService, IMonitoringInstance @@ -161,7 +159,6 @@ public void ApplyConfigChange() var fileSystemChanged = !string.Equals(oldSettings.LogPath, LogPath, StringComparison.OrdinalIgnoreCase); var queueNamesChanged = !string.Equals(oldSettings.ErrorQueue, ErrorQueue, StringComparison.OrdinalIgnoreCase); - RecreateUrlAcl(oldSettings); if (fileSystemChanged) { @@ -202,28 +199,6 @@ public void ApplyConfigChange() } } - void RecreateUrlAcl(MonitoringInstance oldSettings) - { - oldSettings.RemoveUrlAcl(); - var reservation = new UrlReservation(Url, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Create(); - } - - public void RemoveUrlAcl() - { - foreach (var urlReservation in UrlReservation.GetAll().Where(p => p.Url.StartsWith(Url, StringComparison.OrdinalIgnoreCase))) - { - try - { - urlReservation.Delete(); - } - catch - { - ReportCard.Warnings.Add($"Failed to remove the URLACL for {Url} - Please remove manually via Netsh.exe"); - } - } - } - public void RemoveBinFolder() { try diff --git a/src/ServiceControlInstaller.Engine/Instances/MonitoringNewInstance.cs b/src/ServiceControlInstaller.Engine/Instances/MonitoringNewInstance.cs index 6af1986df6..3339de8823 100644 --- a/src/ServiceControlInstaller.Engine/Instances/MonitoringNewInstance.cs +++ b/src/ServiceControlInstaller.Engine/Instances/MonitoringNewInstance.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Security.AccessControl; using System.Security.Principal; using System.Threading.Tasks; @@ -11,10 +10,9 @@ using Configuration.Monitoring; using FileSystem; using NuGet.Versioning; - using Setup; using ReportCard; using Services; - using UrlAcl; + using Setup; using Validation; public class MonitoringNewInstance : IMonitoringInstance @@ -132,18 +130,6 @@ public void RegisterService() RemoveFlagFiles(); } - public void RegisterUrlAcl() - { - var reservation = new UrlReservation(Url, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Create(); - } - - public void RemoveUrlAcl() - { - var reservation = new UrlReservation(Url, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Delete(); - } - public void SetupInstance() { try @@ -188,15 +174,6 @@ public async Task Validate(Func> promptToProceed) ReportCard.Errors.Add(ex.Message); } - try - { - CheckForConflictingUrlAclReservations(); - } - catch (EngineValidationException ex) - { - ReportCard.Errors.Add(ex.Message); - } - try { ServiceAccountValidation.Validate(this); @@ -212,19 +189,6 @@ public async Task Validate(Func> promptToProceed) } } - void CheckForConflictingUrlAclReservations() - { - foreach (var reservation in UrlReservation.GetAll().Where(p => p.Port == Port)) - { - // exclusive or of reservation and instance - if only one of them has "localhost" then the UrlAcl will clash - if ((reservation.HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && !HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase)) || - (!reservation.HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase))) - { - throw new EngineValidationException($"Conflicting UrlAcls found - {Url} vs {reservation.Url}"); - } - } - } - void RemoveFlagFiles() { foreach (var flagFile in FlagFiles) diff --git a/src/ServiceControlInstaller.Engine/Instances/ServiceControlBaseService.cs b/src/ServiceControlInstaller.Engine/Instances/ServiceControlBaseService.cs index b15aa10c8f..eb9e8f8f97 100644 --- a/src/ServiceControlInstaller.Engine/Instances/ServiceControlBaseService.cs +++ b/src/ServiceControlInstaller.Engine/Instances/ServiceControlBaseService.cs @@ -14,7 +14,6 @@ namespace ServiceControlInstaller.Engine.Instances using NuGet.Versioning; using ReportCard; using Services; - using UrlAcl; using Validation; using AppConfig = Configuration.ServiceControl.AppConfig; @@ -142,21 +141,6 @@ protected string ReadConnectionString() protected abstract TransportInfo DetermineTransportPackage(); - protected void RecreateUrlAcl(ServiceControlBaseService oldSettings) - { - oldSettings.RemoveUrlAcl(); - var reservation = new UrlReservation(AclUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Create(); - - if (oldSettings.Version.Major < 2) //Maintenance port was introduced in Version 2 - { - return; - } - - var maintanceReservation = new UrlReservation(AclMaintenanceUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - maintanceReservation.Create(); - } - protected string DefaultDBPath() { var host = HostName == "*" ? "%" : HostName; @@ -183,37 +167,6 @@ protected string DefaultLogPath() return Path.Combine(profilePath, $@"AppData\Local\Particular\{BaseServiceName}\logs"); } - public void RemoveUrlAcl() - { - //This is an old aclurl registration for embedded RavenDB instance that includes the hostname. - //We need that to make sure we can clean-up old registration when removing instances created - //by previous versions of ServiceControl - - //pre 4.17 versions of ServiceControl were using hostnames in all cases - var pre417LegacyAclMaintenanceUrl = $"http://{HostName}:{DatabaseMaintenancePort}/"; - - //pre 4.21 version of ServiceControl were using + in all cases - var pre421LegacyAclMaintenanceUlr = $"http://+:{DatabaseMaintenancePort}"; - - bool IsServiceControlAclUrl(UrlReservation r) => - r.Url.StartsWith(AclUrl, StringComparison.OrdinalIgnoreCase) || - r.Url.StartsWith(AclMaintenanceUrl, StringComparison.OrdinalIgnoreCase) || - r.Url.StartsWith(pre417LegacyAclMaintenanceUrl, StringComparison.OrdinalIgnoreCase) || - r.Url.StartsWith(pre421LegacyAclMaintenanceUlr, StringComparison.OrdinalIgnoreCase); - - foreach (var urlReservation in UrlReservation.GetAll().Where(IsServiceControlAclUrl)) - { - try - { - urlReservation.Delete(); - } - catch - { - ReportCard.Warnings.Add($"Failed to remove the URLACL for {Url} - Please remove manually via Netsh.exe"); - } - } - } - /// /// Returns false if a reboot is required to complete deletion /// @@ -274,8 +227,6 @@ public void ApplyConfigChange() && oldSettings.ForwardErrorMessages == ForwardErrorMessages && oldSettings.ForwardAuditMessages == ForwardAuditMessages); - RecreateUrlAcl(oldSettings); - if (fileSystemChanged) { var account = new NTAccount(accountName); diff --git a/src/ServiceControlInstaller.Engine/Instances/ServiceControlInstallableBase.cs b/src/ServiceControlInstaller.Engine/Instances/ServiceControlInstallableBase.cs index be5ebb7775..6f237b1803 100644 --- a/src/ServiceControlInstaller.Engine/Instances/ServiceControlInstallableBase.cs +++ b/src/ServiceControlInstaller.Engine/Instances/ServiceControlInstallableBase.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Security.AccessControl; using System.Security.Principal; using System.Threading.Tasks; @@ -13,7 +12,6 @@ using NuGet.Versioning; using ReportCard; using Services; - using UrlAcl; using Validation; public abstract class ServiceControlInstallableBase : IHttpInstance, IServiceControlPaths, ITransportConfig @@ -198,24 +196,6 @@ protected List GetServiceDependencies() protected abstract void RunSetup(); - public void RegisterUrlAcl() - { - var reservation = new UrlReservation(AclUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Create(); - - var maintenanceReservation = new UrlReservation(AclMaintenanceUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - maintenanceReservation.Create(); - } - - public void RemoveUrlAcl() - { - var reservation = new UrlReservation(AclUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - reservation.Delete(); - - var maintenanceReservation = new UrlReservation(AclMaintenanceUrl, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null)); - maintenanceReservation.Delete(); - } - public void SetupInstance() { try @@ -253,7 +233,6 @@ public async Task Validate(Func> promptToProceed) } RunValidation(ValidateQueueNames); - RunValidation(CheckForConflictingUrlAclReservations); RunValidation(ValidateServiceAccount); RunValidation(ValidateConnectionString); } @@ -308,19 +287,6 @@ protected virtual void ValidateTransport() } } - void CheckForConflictingUrlAclReservations() - { - foreach (var reservation in UrlReservation.GetAll().Where(p => p.Port == Port || p.Port == DatabaseMaintenancePort)) - { - // exclusive or of reservation and instance - if only one of them has "localhost" then the UrlAcl will clash - if ((reservation.HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && !HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase)) || - (!reservation.HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase) && HostName.Equals("localhost", StringComparison.OrdinalIgnoreCase))) - { - throw new EngineValidationException($"Conflicting UrlAcls found - {Url} vs {reservation.Url}"); - } - } - } - void RemoveFlagFiles() { foreach (var flagFile in FlagFiles) diff --git a/src/ServiceControlInstaller.Engine/Unattended/UnattendAuditInstaller.cs b/src/ServiceControlInstaller.Engine/Unattended/UnattendAuditInstaller.cs index b10b2002f6..7d7eca55c2 100644 --- a/src/ServiceControlInstaller.Engine/Unattended/UnattendAuditInstaller.cs +++ b/src/ServiceControlInstaller.Engine/Unattended/UnattendAuditInstaller.cs @@ -45,7 +45,6 @@ public async Task Add(ServiceControlAuditNewInstance details, Func Add(ServiceControlAuditNewInstance details, Func Add(MonitoringNewInstance details, Func Add(MonitoringNewInstance details, Func Add(ServiceControlNewInstance details, Func Add(ServiceControlNewInstance details, Func new HttpApiVersion(1, 0); - public const uint InitializeConfig = 0x00000002; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpApiVersion.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpApiVersion.cs deleted file mode 100644 index 550792b6a4..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpApiVersion.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, Pack = 2)] - struct HttpApiVersion - { - public ushort Major; - public ushort Minor; - - public HttpApiVersion(ushort majorVersion, ushort minorVersion) - { - Major = majorVersion; - Minor = minorVersion; - } - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenParam.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenParam.cs deleted file mode 100644 index a94c9b1bec..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenParam.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System; - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential)] - struct HttpServiceConfigIPListenParam - { - public ushort AddressLength; - public IntPtr Address; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenQuery.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenQuery.cs deleted file mode 100644 index ae832e151f..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigIPListenQuery.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System; - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential)] - struct HttpServiceConfigIPListenQuery - { - public int AddressCount; - public IntPtr AddressList; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigId.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigId.cs deleted file mode 100644 index 6ae7a0d60f..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigId.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - enum HttpServiceConfigId - { - HttpServiceConfigIPListenList, - HttpServiceConfigSSLCertInfo, - HttpServiceConfigUrlAclInfo, - HttpServiceConfigMax - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigQueryType.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigQueryType.cs deleted file mode 100644 index f9c051211d..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigQueryType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - enum HttpServiceConfigQueryType - { - HttpServiceConfigQueryExact, - HttpServiceConfigQueryNext, - HttpServiceConfigQueryMax - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslKey.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslKey.cs deleted file mode 100644 index 5c2967661c..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslKey.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System; - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential)] - struct HttpServiceConfigSslKey - { - /// - /// Pointer to the port for the IP address. - /// - public IntPtr IPPort; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslParam.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslParam.cs deleted file mode 100644 index a0a385ac42..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslParam.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System; - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - struct HttpServiceConfigSslParam - { - public int SslHashLength; - - public IntPtr SslHash; - - public Guid AppId; - - public string SslCertStoreName; - - public uint DefaultCertCheckMode; - - public int DefaultRevocationFreshnessTime; - - public int DefaultRevocationUrlRetrievalTimeout; - - [MarshalAs(UnmanagedType.LPWStr)] - public string DefaultSslCtlIdentifier; - - [MarshalAs(UnmanagedType.LPWStr)] - public string DefaultSslCtlStoreName; - - public uint DefaultFlags; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslQuery.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslQuery.cs deleted file mode 100644 index 3f068ce967..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslQuery.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential)] - struct HttpServiceConfigSslQuery - { - public HttpServiceConfigQueryType QueryDesc; - - public HttpServiceConfigSslKey KeyDesc; - - public uint Token; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslSet.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslSet.cs deleted file mode 100644 index e31fcc663f..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigSslSet.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential)] - struct HttpServiceConfigSslSet - { - public HttpServiceConfigSslKey KeyDesc; - - public HttpServiceConfigSslParam ParamDesc; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclKey.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclKey.cs deleted file mode 100644 index d9ac4e39d1..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclKey.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - struct HttpServiceConfigUrlAclKey - { - [MarshalAs(UnmanagedType.LPWStr)] - public string UrlPrefix; - - public HttpServiceConfigUrlAclKey(string urlPrefix) - { - UrlPrefix = urlPrefix; - } - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclParam.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclParam.cs deleted file mode 100644 index 18980122ab..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclParam.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - struct HttpServiceConfigUrlAclParam - { - [MarshalAs(UnmanagedType.LPWStr)] - public string StringSecurityDescriptor; - - public HttpServiceConfigUrlAclParam(string securityDescriptor) - { - StringSecurityDescriptor = securityDescriptor; - } - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclQuery.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclQuery.cs deleted file mode 100644 index ea3662dc2d..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclQuery.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - struct HttpServiceConfigUrlAclQuery - { - public HttpServiceConfigQueryType QueryDesc; - - public HttpServiceConfigUrlAclKey KeyDesc; - - public uint Token; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclSet.cs b/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclSet.cs deleted file mode 100644 index 05ff74e8c3..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/Api/HttpServiceConfigUrlAclSet.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl.Api -{ - using System.Runtime.InteropServices; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - struct HttpServiceConfigUrlAclSet - { - public HttpServiceConfigUrlAclKey KeyDesc; - - public HttpServiceConfigUrlAclParam ParamDesc; - } -} \ No newline at end of file diff --git a/src/ServiceControlInstaller.Engine/UrlAcl/UrlReservation.cs b/src/ServiceControlInstaller.Engine/UrlAcl/UrlReservation.cs deleted file mode 100644 index fdcbb7a030..0000000000 --- a/src/ServiceControlInstaller.Engine/UrlAcl/UrlReservation.cs +++ /dev/null @@ -1,319 +0,0 @@ -namespace ServiceControlInstaller.Engine.UrlAcl -{ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.ComponentModel; - using System.Linq; - using System.Runtime.InteropServices; - using System.Security.AccessControl; - using System.Security.Principal; - using System.Text.RegularExpressions; - using Api; - - public class UrlReservation - { - public UrlReservation(string url, params SecurityIdentifier[] securityIdentifiers) - { - if (!url.EndsWith("/")) - { - throw new ArgumentException("UrlAcl is invalid - it must have a trailing /"); - } - - var matchResults = urlPattern.Match(url); - if (matchResults.Success) - { - HTTPS = matchResults.Groups["protocol"].Value.Equals("https", StringComparison.OrdinalIgnoreCase); - HostName = matchResults.Groups["hostname"].Value; - if (string.IsNullOrEmpty(matchResults.Groups["port"].Value)) - { - Port = HTTPS ? 443 : 80; - } - else - { - Port = int.Parse(matchResults.Groups["port"].Value); - } - - VirtualDirectory = matchResults.Groups["virtual"].Value; - Url = url; - } - else - { - throw new ArgumentException("UrlAcl is invalid"); - } - - if (securityIdentifiers != null) - { - this.securityIdentifiers.AddRange(securityIdentifiers); - } - } - - public string Url { get; } - - public ReadOnlyCollection Users - { - get - { - var users = securityIdentifiers.Select(sec => ((NTAccount)sec.Translate(typeof(NTAccount))).Value).ToList(); - return new ReadOnlyCollection(users); - } - } - - public int Port { get; } - public string HostName { get; } - public string VirtualDirectory { get; } - public bool HTTPS { get; } - - public void AddUser(string user) - { - var account = new NTAccount(user); - var sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier)); - AddSecurityIdentifier(sid); - } - - public void AddSecurityIdentifier(SecurityIdentifier sid) - { - securityIdentifiers.Add(sid); - } - - public void ClearUsers() - { - securityIdentifiers.Clear(); - } - - public void Create() - { - Create(this); - } - - public void Delete() - { - Delete(this); - } - - public static ReadOnlyCollection GetAll() - { - var reservations = new List(); - - var retVal = HttpApi.HttpInitialize(HttpApiConstants.Version1, HttpApiConstants.InitializeConfig, IntPtr.Zero); - - if (retVal == ErrorCode.Success) - { - var inputConfigInfoSet = new HttpServiceConfigUrlAclQuery - { - QueryDesc = HttpServiceConfigQueryType.HttpServiceConfigQueryNext - }; - - var i = 0; - while (retVal == 0) - { - inputConfigInfoSet.Token = (uint)i; - var pInputConfigInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HttpServiceConfigUrlAclQuery))); - Marshal.StructureToPtr(inputConfigInfoSet, pInputConfigInfo, false); - - var pOutputConfigInfo = Marshal.AllocHGlobal(0); - var returnLength = 0; - retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - pOutputConfigInfo, - returnLength, - out returnLength, - IntPtr.Zero); - - if (retVal == ErrorCode.InsufficientBuffer) - { - Marshal.FreeHGlobal(pOutputConfigInfo); - pOutputConfigInfo = Marshal.AllocHGlobal(Convert.ToInt32(returnLength)); - - retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - pOutputConfigInfo, - returnLength, - out _, - IntPtr.Zero); - } - - if (retVal == ErrorCode.Success) - { - var outputConfigInfo = (HttpServiceConfigUrlAclSet)Marshal.PtrToStructure(pOutputConfigInfo, typeof(HttpServiceConfigUrlAclSet)); - var rev = new UrlReservation(outputConfigInfo.KeyDesc.UrlPrefix, SecurityIdentifiersFromSecurityDescriptor(outputConfigInfo.ParamDesc.StringSecurityDescriptor).ToArray()); - reservations.Add(rev); - } - - Marshal.FreeHGlobal(pOutputConfigInfo); - Marshal.FreeHGlobal(pInputConfigInfo); - i++; - } - - retVal = HttpApi.HttpTerminate(HttpApiConstants.InitializeConfig, IntPtr.Zero); - } - - if (retVal != ErrorCode.Success) - { - throw new Win32Exception(Convert.ToInt32(retVal)); - } - - return new ReadOnlyCollection(reservations); - } - - public static void Create(UrlReservation urlReservation) - { - if (urlReservation.securityIdentifiers.Count == 0) - { - throw new Exception("No SecurityIdentifiers have been assigned to the URLACL"); - } - - var sddl = GenerateSecurityDescriptor(urlReservation.securityIdentifiers); - ReserveUrl(urlReservation.Url, sddl); - } - - static void ReserveUrl(string networkURL, string securityDescriptor) - { - var retVal = HttpApi.HttpInitialize(HttpApiConstants.Version1, HttpApiConstants.InitializeConfig, IntPtr.Zero); - if (retVal == ErrorCode.Success) - { - var keyDesc = new HttpServiceConfigUrlAclKey(networkURL); - var paramDesc = new HttpServiceConfigUrlAclParam(securityDescriptor); - - var inputConfigInfoSet = new HttpServiceConfigUrlAclSet - { - KeyDesc = keyDesc, - ParamDesc = paramDesc - }; - - var pInputConfigInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HttpServiceConfigUrlAclSet))); - Marshal.StructureToPtr(inputConfigInfoSet, pInputConfigInfo, false); - - retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - IntPtr.Zero); - - if (retVal == ErrorCode.AlreadyExists) - { - retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - IntPtr.Zero); - - if (retVal == ErrorCode.Success) - { - retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - pInputConfigInfo, - Marshal.SizeOf(inputConfigInfoSet), - IntPtr.Zero); - } - } - - Marshal.FreeHGlobal(pInputConfigInfo); - HttpApi.HttpTerminate(HttpApiConstants.InitializeConfig, IntPtr.Zero); - } - - if (retVal != ErrorCode.Success) - { - throw new Win32Exception(Convert.ToInt32(retVal)); - } - } - - public static void Delete(UrlReservation urlReservation) - { - var securityDescriptor = GenerateSecurityDescriptor(urlReservation.securityIdentifiers); - FreeURL(urlReservation.Url, securityDescriptor); - } - - static void FreeURL(string networkURL, string securityDescriptor) - { - var retVal = HttpApi.HttpInitialize(HttpApiConstants.Version1, HttpApiConstants.InitializeConfig, IntPtr.Zero); - if (retVal == ErrorCode.Success) - { - var urlAclKey = new HttpServiceConfigUrlAclKey(networkURL); - var urlAclParam = new HttpServiceConfigUrlAclParam(securityDescriptor); - - var urlAclSet = new HttpServiceConfigUrlAclSet - { - KeyDesc = urlAclKey, - ParamDesc = urlAclParam - }; - - var configInformation = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HttpServiceConfigUrlAclSet))); - Marshal.StructureToPtr(urlAclSet, configInformation, false); - var configInformationSize = Marshal.SizeOf(urlAclSet); - retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero, - HttpServiceConfigId.HttpServiceConfigUrlAclInfo, - configInformation, - configInformationSize, - IntPtr.Zero); - - Marshal.FreeHGlobal(configInformation); - HttpApi.HttpTerminate(HttpApiConstants.InitializeConfig, IntPtr.Zero); - } - - if (retVal is not ErrorCode.Success and not ErrorCode.NotFound) - { - throw new Win32Exception(Convert.ToInt32(retVal)); - } - } - - static IEnumerable SecurityIdentifiersFromSecurityDescriptor(string securityDescriptor) - { - var commonSecurityDescriptor = new CommonSecurityDescriptor(false, false, securityDescriptor); - var discretionaryAcl = commonSecurityDescriptor.DiscretionaryAcl; - return discretionaryAcl.Cast().Select(ace => ace.SecurityIdentifier); - } - - static DiscretionaryAcl GetDiscretionaryAcl(List securityIdentifiers) - { - var discretionaryAcl = new DiscretionaryAcl(false, false, 16); - foreach (var securityIdentifier in securityIdentifiers) - { - discretionaryAcl.AddAccess(AccessControlType.Allow, securityIdentifier, GENERIC_EXECUTE, InheritanceFlags.None, PropagationFlags.None); - } - - return discretionaryAcl; - } - - static CommonSecurityDescriptor GetSecurityDescriptor(List securityIdentifiers) - { - var discretionaryAcl = GetDiscretionaryAcl(securityIdentifiers); - var securityDescriptor = new CommonSecurityDescriptor(false, false, - ControlFlags.GroupDefaulted | - ControlFlags.OwnerDefaulted | - ControlFlags.DiscretionaryAclPresent, - null, null, null, discretionaryAcl); - return securityDescriptor; - } - - static string GenerateSecurityDescriptor(List securityIdentifiers) - { - return GetSecurityDescriptor(securityIdentifiers).GetSddlForm(AccessControlSections.Access); - } - - public byte[] ToDiscretionaryAclBytes() - { - var discretionaryAcl = GetDiscretionaryAcl(securityIdentifiers); - var bytes = new byte[discretionaryAcl.BinaryLength]; - discretionaryAcl.GetBinaryForm(bytes, 0); - return bytes; - } - - public byte[] ToSystemAclBytes() - { - var systemAcl = new SystemAcl(false, false, 0); - var bytes = new byte[systemAcl.BinaryLength]; - systemAcl.GetBinaryForm(bytes, 0); - return bytes; - } - - List securityIdentifiers = []; - - const int GENERIC_EXECUTE = 536870912; - static Regex urlPattern = new Regex(@"^(?https?)://(?([^/]*?))(:(?\d{0,5}))?(/(?[^:]*))?/$", RegexOptions.Compiled | RegexOptions.IgnoreCase); - } -} \ No newline at end of file