diff --git a/build/Build.cs b/build/Build.cs index e7e0281ea..54a1e903e 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -117,7 +117,9 @@ public Build() Lazy NugetVersion { get; } Target CheckForbiddenWords => - _ => _.Executes(() => + _ => _ + .OnlyWhenStatic(() => !IsLocalBuild) + .Executes(() => { Log.Information("Checking codebase for forbidden words"); @@ -169,6 +171,18 @@ public Build() { Log.Information("Compiling Calamari v{CalamariVersion}", NugetVersion.Value); + DotNetBuild(_ => _.SetProjectFile(SourceDirectory / "Calamari.FullFrameworkTools"/ "Calamari.FullFrameworkTools.csproj") + .SetConfiguration(Configuration) + .DisableNoRestore() + .SetVersion(NugetVersion.Value) + .SetInformationalVersion(GitVersionInfo?.InformationalVersion)); + + DotNetBuild(_ => _.SetProjectFile(SourceDirectory / "Calamari.FullFrameworkTools.Tests"/ "Calamari.FullFrameworkTools.Tests.csproj") + .SetConfiguration(Configuration) + .DisableNoRestore() + .SetVersion(NugetVersion.Value) + .SetInformationalVersion(GitVersionInfo?.InformationalVersion)); + DotNetBuild(_ => _.SetProjectFile(Solution) .SetConfiguration(Configuration) .SetNoRestore(true) @@ -219,11 +233,32 @@ public Build() nugetVersion, FixedRuntimes.Cloud); - // Create the self-contained Calamari packages for each runtime ID defined in Calamari.csproj - foreach (var rid in GetRuntimeIdentifiers(Solution.GetProject(RootProjectName)!)!) - DoPublish(RootProjectName, Frameworks.Net60, nugetVersion, rid); - }); + if (OperatingSystem.IsWindows()) + { + var path = SourceDirectory / "Calamari.FullFrameworkTools" / "bin" / Configuration / Frameworks.Net462 ; + CopyDirectoryRecursively(path, (PublishDirectory / "Calamari" / Frameworks.Net462 / "Calamari.FullFrameworkTools"), DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite); + CopyDirectoryRecursively(path, (PublishDirectory / "Calamari" / Frameworks.Net60 / "Calamari.FullFrameworkTools"), DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite); + } + + // Create the self-contained Calamari packages for each runtime ID defined in Calamari.csproj + foreach (var rid in GetRuntimeIdentifiers(Solution.GetProject(RootProjectName)!)!) + { + var publishPath = DoPublish(RootProjectName, Frameworks.Net60, nugetVersion, rid); + + if (rid == FixedRuntimes.Windows && OperatingSystem.IsWindows()) + { + CopyFullFrameworkFiles(publishPath); + } + } + }); + + void CopyFullFrameworkFiles(AbsolutePath targetPath) + { + var path = SourceDirectory / "Calamari.FullFrameworkTools" / "bin" / Configuration / Frameworks.Net462; + CopyDirectoryRecursively(path, (targetPath / "Calamari.FullFrameworkTools"), DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite); + } + Target PublishCalamariFlavourProjects => _ => _ .DependsOn(Compile) @@ -329,7 +364,7 @@ void PublishPackage(CalamariPackageMetadata calamariPackageMetadata) File.Copy(RootDirectory / "global.json", outputDirectory / "global.json"); } - + static void StageLegacyCalamariAssemblies(CalamariPackageMetadata[] packagesToPublish) { if (!OperatingSystem.IsWindows()) @@ -340,7 +375,7 @@ static void StageLegacyCalamariAssemblies(CalamariPackageMetadata[] packagesToPu } packagesToPublish - //We only need to bundle executable (not tests or libraries) full framework projects + //We only need to bundle executable (not tests or libraries) full framework projects .Where(d => d.Framework == Frameworks.Net462 && d.Project.GetOutputType() == "Exe") .ForEach(calamariPackageMetadata => { @@ -434,6 +469,8 @@ void CompressCalamariProject(Project project) var defaultTarget = OperatingSystem.IsWindows() ? Frameworks.Net462 : Frameworks.Net60; AbsolutePath binFolder = SourceDirectory / "Calamari.Tests" / "bin" / Configuration / defaultTarget; Directory.Exists(binFolder); + + CopyFullFrameworkFiles(binFolder); var actions = new List { () => diff --git a/build/_build.csproj b/build/_build.csproj index 6819c0d13..8862ec4eb 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -19,19 +19,19 @@ - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + diff --git a/source/Calamari.FullFrameworkTools.Tests/IisCommandTests.cs b/source/Calamari.FullFrameworkTools.Tests/IisCommandTests.cs index 80ffe2a68..6cec676c3 100644 --- a/source/Calamari.FullFrameworkTools.Tests/IisCommandTests.cs +++ b/source/Calamari.FullFrameworkTools.Tests/IisCommandTests.cs @@ -26,7 +26,7 @@ public void GivenOneParameter_ThenException() var iisServer = Substitute.For(); var cmd = new IisCommand(iisServer); - Assert.Throws(() => cmd.Execute(new string[] { Guid.NewGuid().ToString()})); + Assert.Throws(() => cmd.Execute(new string[] { Guid.NewGuid().ToString()})); } [Test] @@ -35,7 +35,7 @@ public void GivenNoParameter_ThenException() var iisServer = Substitute.For(); var cmd = new IisCommand(iisServer); - Assert.Throws(() => cmd.Execute(Array.Empty())); + Assert.Throws(() => cmd.Execute(Array.Empty())); } } } \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/Calamari.FullFrameworkTools.csproj b/source/Calamari.FullFrameworkTools/Calamari.FullFrameworkTools.csproj index 1e2e2b3fd..60bb1b3db 100644 --- a/source/Calamari.FullFrameworkTools/Calamari.FullFrameworkTools.csproj +++ b/source/Calamari.FullFrameworkTools/Calamari.FullFrameworkTools.csproj @@ -28,6 +28,7 @@ $(DefineConstants);DEBUG + diff --git a/source/Calamari.FullFrameworkTools/Command/CommandHandler.cs b/source/Calamari.FullFrameworkTools/Command/CommandHandler.cs index 091efb8ba..d9af2edab 100644 --- a/source/Calamari.FullFrameworkTools/Command/CommandHandler.cs +++ b/source/Calamari.FullFrameworkTools/Command/CommandHandler.cs @@ -2,6 +2,7 @@ using System; using Calamari.FullFrameworkTools.Iis; using Calamari.FullFrameworkTools.WindowsCertStore; +using Calamari.FullFrameworkTools.WindowsCertStore.Contracts; namespace Calamari.FullFrameworkTools.Command; @@ -9,7 +10,8 @@ public interface ICommandHandler { object Handle(IRequest obj); } -public class CommandHandler: ICommandHandler + +public class CommandHandler : ICommandHandler { readonly IWindowsX509CertificateStore certificateStore; readonly IInternetInformationServer internetInformationServer; @@ -25,17 +27,25 @@ public object Handle(IRequest obj) return obj switch { null => throw new NotImplementedException(), - + //IIS Comments OverwriteHomeDirectoryRequest req => req.DoIt(internetInformationServer), - + // Windows Cert Commands FindCertificateStoreRequest req => req.DoIt(certificateStore), ImportCertificateToStoreByUserRequest req => req.DoIt(certificateStore), ImportCertificateToStoreByLocationRequest req => req.DoIt(certificateStore), AddPrivateKeyAccessRulesRequest req => req.DoIt(certificateStore), - + _ => throw new ArgumentOutOfRangeException($"Unknown Request {obj.GetType().Name}"), }; } -} \ No newline at end of file +} + +public interface IFullFrameworkToolResponse + { + } + + public class StringResponse : IFullFrameworkToolResponse { public string? Value { get; set; } } + public class VoidResponse : IFullFrameworkToolResponse { } + public class BoolResponse : IFullFrameworkToolResponse { public bool Value { get; set; } } diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/AddPrivateKeyAccessRulesRequest.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/AddPrivateKeyAccessRulesRequest.cs new file mode 100644 index 000000000..6b111961c --- /dev/null +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/AddPrivateKeyAccessRulesRequest.cs @@ -0,0 +1,38 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using Calamari.FullFrameworkTools.Command; + +namespace Calamari.FullFrameworkTools.WindowsCertStore.Contracts; + +public class AddPrivateKeyAccessRulesRequest : IRequest +{ + public AddPrivateKeyAccessRulesRequest(string thumbprint, StoreLocation storeLocation, string storeName, List privateKeyAccessRules) + { + this.Thumbprint = thumbprint; + StoreName = storeName; + PrivateKeyAccessRules = privateKeyAccessRules; + StoreLocation = storeLocation; + } + + public string Thumbprint { get; set; } + public StoreLocation StoreLocation { get; set; } + public string StoreName { get; set; } + public List PrivateKeyAccessRules { get; set; } + + + public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) + { + if (string.IsNullOrEmpty(StoreName)) + { + certificateStore.AddPrivateKeyAccessRules(Thumbprint, StoreLocation, PrivateKeyAccessRules); + } + else + { + certificateStore.AddPrivateKeyAccessRules(Thumbprint, StoreLocation, StoreName, PrivateKeyAccessRules); + } + + return new VoidResponse(); + } +} \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/FindCertificateStoreRequest.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/FindCertificateStoreRequest.cs new file mode 100644 index 000000000..594725bda --- /dev/null +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/FindCertificateStoreRequest.cs @@ -0,0 +1,24 @@ +#nullable enable +using System; +using System.Security.Cryptography.X509Certificates; +using Calamari.FullFrameworkTools.Command; + +namespace Calamari.FullFrameworkTools.WindowsCertStore.Contracts; + +public class FindCertificateStoreRequest : IRequest +{ + public FindCertificateStoreRequest(string thumbprint, StoreLocation storeLocation) + { + Thumbprint = thumbprint; + StoreLocation = storeLocation; + } + + public string Thumbprint { get; } + public StoreLocation StoreLocation { get; } + + public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) + { + certificateStore.FindCertificateStore(Thumbprint, StoreLocation); + return new VoidResponse(); + } +} \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByLocationRequest.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByLocationRequest.cs new file mode 100644 index 000000000..abbbd6610 --- /dev/null +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByLocationRequest.cs @@ -0,0 +1,30 @@ +#nullable enable +using System; +using System.Security.Cryptography.X509Certificates; +using Calamari.FullFrameworkTools.Command; + +namespace Calamari.FullFrameworkTools.WindowsCertStore.Contracts; + +public class ImportCertificateToStoreByLocationRequest : IRequest +{ + public ImportCertificateToStoreByLocationRequest(byte[] pfxBytes, string password, StoreLocation storeLocation,string storeName, bool privateKeyExportable) + { + PfxBytes = pfxBytes; + Password = password; + StoreLocation = storeLocation; + StoreName = storeName; + PrivateKeyExportable = privateKeyExportable; + } + + public byte[] PfxBytes { get; set; } + public string Password { get; set; } + public StoreLocation StoreLocation { get; set; } + public string StoreName { get; set; } + public bool PrivateKeyExportable { get; set; } + + public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) + { + certificateStore.ImportCertificateToStore(PfxBytes, Password, StoreLocation, StoreName, PrivateKeyExportable); + return new VoidResponse(); + } +} \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByUserRequest.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByUserRequest.cs new file mode 100644 index 000000000..4ed62d144 --- /dev/null +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/ImportCertificateToStoreByUserRequest.cs @@ -0,0 +1,29 @@ +#nullable enable +using System; +using Calamari.FullFrameworkTools.Command; + +namespace Calamari.FullFrameworkTools.WindowsCertStore.Contracts; + +public class ImportCertificateToStoreByUserRequest : IRequest +{ + public ImportCertificateToStoreByUserRequest(byte[] pfxBytes, string password, string userName, string storeName, bool privateKeyExportable) + { + PfxBytes = pfxBytes; + Password = password; + UserName = userName; + StoreName = storeName; + PrivateKeyExportable = privateKeyExportable; + } + + public byte[] PfxBytes { get; set; } + public string Password { get; set; } + public string UserName { get; set; } + public string StoreName { get; set; } + public bool PrivateKeyExportable { get; set; } + + public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) + { + certificateStore.ImportCertificateToStore(PfxBytes, Password, UserName, StoreName, PrivateKeyExportable); + return new VoidResponse(); + } +} \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/OverwriteHomeDirectoryRequest.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/OverwriteHomeDirectoryRequest.cs new file mode 100644 index 000000000..d4b57436f --- /dev/null +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/Contracts/OverwriteHomeDirectoryRequest.cs @@ -0,0 +1,26 @@ +#nullable enable +using System; +using Calamari.FullFrameworkTools.Command; +using Calamari.FullFrameworkTools.Iis; + +namespace Calamari.FullFrameworkTools.WindowsCertStore.Contracts; + +public class OverwriteHomeDirectoryRequest : IRequest +{ + public OverwriteHomeDirectoryRequest(string iisWebSiteName, string path, bool legacySupport) + { + IisWebSiteName = iisWebSiteName; + Path = path; + LegacySupport = legacySupport; + } + + public string IisWebSiteName { get; set; } + public string Path { get; set; } + public bool LegacySupport { get; set; } + + public BoolResponse DoIt(IInternetInformationServer certificateStore) + { + certificateStore.OverwriteHomeDirectory(IisWebSiteName, Path, LegacySupport); + return new BoolResponse(); + } +} \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/IWindowsX509CertificateStore.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/IWindowsX509CertificateStore.cs index 5c74e9914..00e61e29d 100644 --- a/source/Calamari.FullFrameworkTools/WindowsCertStore/IWindowsX509CertificateStore.cs +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/IWindowsX509CertificateStore.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; using System.Security.Cryptography.X509Certificates; -using Calamari.FullFrameworkTools.Iis; -using Calamari.FullFrameworkTools.WindowsCertStore.WindowsNative; namespace Calamari.FullFrameworkTools.WindowsCertStore; @@ -31,124 +29,4 @@ void ImportCertificateToStore(byte[] pfxBytes, string userName, string storeName, bool privateKeyExportable); -} - - - -public class FindCertificateStoreRequest : IRequest -{ - public FindCertificateStoreRequest(string thumbprint, StoreLocation storeLocation) - { - Thumbprint = thumbprint; - StoreLocation = storeLocation; - } - - public string Thumbprint { get; } - public StoreLocation StoreLocation { get; } - - public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) - { - certificateStore.FindCertificateStore(Thumbprint, StoreLocation); - return new VoidResponse(); - } -} - - -public class ImportCertificateToStoreByUserRequest : IRequest -{ - public ImportCertificateToStoreByUserRequest(byte[] pfxBytes, string password, string userName, string storeName, bool privateKeyExportable) - { - PfxBytes = pfxBytes; - Password = password; - UserName = userName; - StoreName = storeName; - PrivateKeyExportable = privateKeyExportable; - } - - public byte[] PfxBytes { get; set; } - public string Password { get; set; } - public string UserName { get; set; } - public string StoreName { get; set; } - public bool PrivateKeyExportable { get; set; } - - public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) - { - certificateStore.ImportCertificateToStore(PfxBytes, Password, UserName, StoreName, PrivateKeyExportable); - return new VoidResponse(); - } -} - -public class ImportCertificateToStoreByLocationRequest : IRequest -{ - public ImportCertificateToStoreByLocationRequest(byte[] pfxBytes, string password, StoreLocation storeLocation,string storeName, bool privateKeyExportable) - { - PfxBytes = pfxBytes; - Password = password; - StoreLocation = storeLocation; - StoreName = storeName; - PrivateKeyExportable = privateKeyExportable; - } - - public byte[] PfxBytes { get; set; } - public string Password { get; set; } - public StoreLocation StoreLocation { get; set; } - public string StoreName { get; set; } - public bool PrivateKeyExportable { get; set; } - - public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) - { - certificateStore.ImportCertificateToStore(PfxBytes, Password, StoreLocation, StoreName, PrivateKeyExportable); - return new VoidResponse(); - } -} - -public class AddPrivateKeyAccessRulesRequest : IRequest -{ - public AddPrivateKeyAccessRulesRequest(string thumbprint, StoreLocation storeLocation, string storeName, List privateKeyAccessRules) - { - this.Thumbprint = thumbprint; - StoreName = storeName; - PrivateKeyAccessRules = privateKeyAccessRules; - StoreLocation = storeLocation; - } - - public string Thumbprint { get; set; } - public StoreLocation StoreLocation { get; set; } - public string StoreName { get; set; } - public List PrivateKeyAccessRules { get; set; } - - - public VoidResponse DoIt(IWindowsX509CertificateStore certificateStore) - { - if (string.IsNullOrEmpty(StoreName)) - { - certificateStore.AddPrivateKeyAccessRules(Thumbprint, StoreLocation, PrivateKeyAccessRules); - } - else - { - certificateStore.AddPrivateKeyAccessRules(Thumbprint, StoreLocation, StoreName, PrivateKeyAccessRules); - } - - return new VoidResponse(); - } -} - -public class OverwriteHomeDirectoryRequest : IRequest -{ - public OverwriteHomeDirectoryRequest(string iisWebSiteName, string path, bool legacySupport) - { - IisWebSiteName = iisWebSiteName; - Path = path; - LegacySupport = legacySupport; - } - - public string IisWebSiteName { get; set; } - public string Path { get; set; } - public bool LegacySupport { get; set; } - - public BoolResponse DoIt(IInternetInformationServer certificateStore) - { - certificateStore.OverwriteHomeDirectory(IisWebSiteName, Path, LegacySupport); - return new BoolResponse(); - } } \ No newline at end of file diff --git a/source/Calamari.FullFrameworkTools/WindowsCertStore/WindowsNative/WindowsX509Native.cs b/source/Calamari.FullFrameworkTools/WindowsCertStore/WindowsNative/WindowsX509Native.cs index 42f174a00..165d9a1eb 100644 --- a/source/Calamari.FullFrameworkTools/WindowsCertStore/WindowsNative/WindowsX509Native.cs +++ b/source/Calamari.FullFrameworkTools/WindowsCertStore/WindowsNative/WindowsX509Native.cs @@ -6,15 +6,6 @@ namespace Calamari.FullFrameworkTools.WindowsCertStore.WindowsNative { - - public interface IFullFrameworkToolResponse - { - } - - public class StringResponse : IFullFrameworkToolResponse { public string Valus { get; set; } } - public class VoidResponse : IFullFrameworkToolResponse { } - public class BoolResponse : IFullFrameworkToolResponse { public bool Value { get; set; } } - internal static class WindowsX509Native { [DllImport("Crypt32.dll", SetLastError = true)] diff --git a/source/Calamari.Shared/Integration/Certificates/NoOpWindowsX509CertificateStore.cs b/source/Calamari.Shared/Integration/Certificates/NoOpWindowsX509CertificateStore.cs index 5a2023955..9c9b9a107 100644 --- a/source/Calamari.Shared/Integration/Certificates/NoOpWindowsX509CertificateStore.cs +++ b/source/Calamari.Shared/Integration/Certificates/NoOpWindowsX509CertificateStore.cs @@ -4,6 +4,29 @@ namespace Calamari.Integration.Certificates { + public interface ILegacyFrameworkInvoker + { + TResponse Invoke(TRequest cmd); + } + /*public class LegacyWindowsX509CertificateStore : IWindowsX509CertificateStore + { + readonly ILegacyFrameworkInvoker processInvoker; + //readonly InProcessInvoker processInvoker; + + public LegacyWindowsX509CertificateStore(ILegacyFrameworkInvoker processInvoker) + { + this.processInvoker = processInvoker; + } + + public bool OverwriteHomeDirectory(string iisWebSiteName, string path, bool legacySupport) + { + var cmd = new OverwriteHomeDirectoryRequest(iisWebSiteName, path, legacySupport); + var response = processInvoker.Invoke(cmd); + return response.Value; + } + }*/ + + /// /// Stand in replacement for IWindowsX509CertificateStore that will be registered for non Windows machines. /// This should never end up being called. If it is, something has gone wrong somewhere else diff --git a/source/Calamari.Tests/Calamari.Tests.csproj b/source/Calamari.Tests/Calamari.Tests.csproj index 0aeed4500..c4e970cbd 100644 --- a/source/Calamari.Tests/Calamari.Tests.csproj +++ b/source/Calamari.Tests/Calamari.Tests.csproj @@ -278,10 +278,12 @@ + + diff --git a/source/Calamari.Tests/Fixtures/Deployment/DeployPackageFixture.cs b/source/Calamari.Tests/Fixtures/Deployment/DeployPackageFixture.cs index 41891a955..577d82c34 100644 --- a/source/Calamari.Tests/Fixtures/Deployment/DeployPackageFixture.cs +++ b/source/Calamari.Tests/Fixtures/Deployment/DeployPackageFixture.cs @@ -48,7 +48,7 @@ protected CalamariResult DeployPackage(string packageName) { Variables.Save(variablesFile.FilePath); - return InvokeInProcess(Calamari() + return Invoke(Calamari() .Action("deploy-package") .Argument("package", packageName) .Argument("variables", variablesFile.FilePath)); diff --git a/source/Calamari.sln b/source/Calamari.sln index 8ca19dbb5..c3cdb2052 100644 --- a/source/Calamari.sln +++ b/source/Calamari.sln @@ -86,6 +86,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calamari.FullFrameworkTools EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calamari.FullFrameworkTools.Tests", "Calamari.FullFrameworkTools.Tests\Calamari.FullFrameworkTools.Tests.csproj", "{EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Full Framework Tools", "Full Framework Tools", "{35F9AC75-DAC6-4ADF-B2D7-2EFCE5CB54E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -150,10 +152,6 @@ Global {0EA7711F-34D3-44C6-BBCC-D4EA1A6B9D2C}.Debug|Any CPU.Build.0 = Debug|Any CPU {0EA7711F-34D3-44C6-BBCC-D4EA1A6B9D2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {0EA7711F-34D3-44C6-BBCC-D4EA1A6B9D2C}.Release|Any CPU.Build.0 = Release|Any CPU - {71B996DD-409B-4EB6-AB1A-D7469B0A7A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {71B996DD-409B-4EB6-AB1A-D7469B0A7A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {71B996DD-409B-4EB6-AB1A-D7469B0A7A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {71B996DD-409B-4EB6-AB1A-D7469B0A7A8A}.Release|Any CPU.Build.0 = Release|Any CPU {BFE038E8-6F46-40DA-AD40-C00ED25C1FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BFE038E8-6F46-40DA-AD40-C00ED25C1FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU {BFE038E8-6F46-40DA-AD40-C00ED25C1FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -211,11 +209,9 @@ Global {D8DEC40C-948F-4806-AE87-1A7502E41A06}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8DEC40C-948F-4806-AE87-1A7502E41A06}.Release|Any CPU.Build.0 = Release|Any CPU {D1F10B67-71EF-4024-8F71-178CE48E901F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1F10B67-71EF-4024-8F71-178CE48E901F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D1F10B67-71EF-4024-8F71-178CE48E901F}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1F10B67-71EF-4024-8F71-178CE48E901F}.Release|Any CPU.Build.0 = Release|Any CPU {EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection @@ -225,4 +221,8 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {429833DB-66EA-49BA-9444-6F1B047F50FC} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D1F10B67-71EF-4024-8F71-178CE48E901F} = {35F9AC75-DAC6-4ADF-B2D7-2EFCE5CB54E3} + {EC26DBFD-A364-4AF9-BFEF-F8ABCA2656FA} = {35F9AC75-DAC6-4ADF-B2D7-2EFCE5CB54E3} + EndGlobalSection EndGlobal diff --git a/source/Calamari/Calamari.csproj b/source/Calamari/Calamari.csproj index 0f89d3cc5..36cf3fa0c 100644 --- a/source/Calamari/Calamari.csproj +++ b/source/Calamari/Calamari.csproj @@ -72,7 +72,6 @@ - @@ -108,13 +107,40 @@ + + + + + + + + + + + + + + + + + + true + false + + + - + + + + diff --git a/source/Calamari/Commands/DeployPackageCommand.cs b/source/Calamari/Commands/DeployPackageCommand.cs index f8b31a76d..898418060 100644 --- a/source/Calamari/Commands/DeployPackageCommand.cs +++ b/source/Calamari/Commands/DeployPackageCommand.cs @@ -26,6 +26,7 @@ using Calamari.Deployment.Conventions; using Calamari.Deployment.Features; using Calamari.Integration.Certificates; +using Calamari.Integration.FullFramework; using Calamari.Integration.Iis; using Calamari.Integration.Nginx; @@ -90,8 +91,8 @@ public override int Execute(string[] commandLineArguments) var transformFileLocator = new TransformFileLocator(fileSystem, log); var embeddedResources = new AssemblyEmbeddedResources(); #if IIS_SUPPORT - var iis = OctopusFeatureToggles.FullFrameworkTasksExternalProcess.IsEnabled(variables) ? - new InternetInformationServer(): (IInternetInformationServer)new LegacyInternetInformationServer(new InProcessInvoker()); + var iis = !OctopusFeatureToggles.FullFrameworkTasksExternalProcess.IsEnabled(variables) ? + new InternetInformationServer(): (IInternetInformationServer)new LegacyInternetInformationServer(new LegacyFrameworkInvoker()); featureClasses.AddRange(new IFeature[] { new IisWebSiteBeforeDeployFeature(windowsX509CertificateStore), new IisWebSiteAfterPostDeployFeature(windowsX509CertificateStore) }); #endif if (!CalamariEnvironment.IsRunningOnWindows) diff --git a/source/Calamari/Integration/FullFramework/AddPrivateKeyAccessRulesRequest.cs b/source/Calamari/Integration/FullFramework/AddPrivateKeyAccessRulesRequest.cs new file mode 100644 index 000000000..942d2c070 --- /dev/null +++ b/source/Calamari/Integration/FullFramework/AddPrivateKeyAccessRulesRequest.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using Calamari.Integration.Certificates; + +namespace Calamari.Integration.FullFramework +{ + + public interface IRequest + { + } + + public class AddPrivateKeyAccessRulesRequest : IRequest + { + public AddPrivateKeyAccessRulesRequest(string thumbprint, StoreLocation storeLocation, string storeName, List privateKeyAccessRules) + { + this.Thumbprint = thumbprint; + StoreName = storeName; + PrivateKeyAccessRules = privateKeyAccessRules; + StoreLocation = storeLocation; + } + + public string Thumbprint { get; set; } + public StoreLocation StoreLocation { get; set; } + public string StoreName { get; set; } + public List PrivateKeyAccessRules { get; set; } + } +} \ No newline at end of file diff --git a/source/Calamari/Integration/FullFramework/FindCertificateStoreRequest.cs b/source/Calamari/Integration/FullFramework/FindCertificateStoreRequest.cs new file mode 100644 index 000000000..1433f3faf --- /dev/null +++ b/source/Calamari/Integration/FullFramework/FindCertificateStoreRequest.cs @@ -0,0 +1,18 @@ +using System; +using System.Security.Cryptography.X509Certificates; + +namespace Calamari.Integration.FullFramework +{ + + public class FindCertificateStoreRequest : IRequest + { + public FindCertificateStoreRequest(string thumbprint, StoreLocation storeLocation) + { + Thumbprint = thumbprint; + StoreLocation = storeLocation; + } + + public string Thumbprint { get; } + public StoreLocation StoreLocation { get; } + } +} \ No newline at end of file diff --git a/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByLocationRequest.cs b/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByLocationRequest.cs new file mode 100644 index 000000000..2ece0b4ee --- /dev/null +++ b/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByLocationRequest.cs @@ -0,0 +1,24 @@ +using System; +using System.Security.Cryptography.X509Certificates; + +namespace Calamari.Integration.FullFramework { + +public class ImportCertificateToStoreByLocationRequest : IRequest +{ + public ImportCertificateToStoreByLocationRequest(byte[] pfxBytes, string password, StoreLocation storeLocation,string storeName, bool privateKeyExportable) + { + PfxBytes = pfxBytes; + Password = password; + StoreLocation = storeLocation; + StoreName = storeName; + PrivateKeyExportable = privateKeyExportable; + } + + public byte[] PfxBytes { get; set; } + public string Password { get; set; } + public StoreLocation StoreLocation { get; set; } + public string StoreName { get; set; } + public bool PrivateKeyExportable { get; set; } + +} +} \ No newline at end of file diff --git a/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByUserRequest.cs b/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByUserRequest.cs new file mode 100644 index 000000000..5dadf2c39 --- /dev/null +++ b/source/Calamari/Integration/FullFramework/ImportCertificateToStoreByUserRequest.cs @@ -0,0 +1,28 @@ +using System; + +namespace Calamari.Integration.FullFramework +{ + + public class ImportCertificateToStoreByUserRequest : IRequest + { + public ImportCertificateToStoreByUserRequest(byte[] pfxBytes, + string password, + string userName, + string storeName, + bool privateKeyExportable) + { + PfxBytes = pfxBytes; + Password = password; + UserName = userName; + StoreName = storeName; + PrivateKeyExportable = privateKeyExportable; + } + + public byte[] PfxBytes { get; set; } + public string Password { get; set; } + public string UserName { get; set; } + public string StoreName { get; set; } + public bool PrivateKeyExportable { get; set; } + + } +} \ No newline at end of file diff --git a/source/Calamari/Integration/Iis/LegacyFrameworkInvoker.cs b/source/Calamari/Integration/FullFramework/LegacyFrameworkInvoker.cs similarity index 81% rename from source/Calamari/Integration/Iis/LegacyFrameworkInvoker.cs rename to source/Calamari/Integration/FullFramework/LegacyFrameworkInvoker.cs index cea7e4bd3..4b04ebe8c 100644 --- a/source/Calamari/Integration/Iis/LegacyFrameworkInvoker.cs +++ b/source/Calamari/Integration/FullFramework/LegacyFrameworkInvoker.cs @@ -1,24 +1,16 @@ -#if IIS_SUPPORT -using System; -using System.Collections.Generic; +using System; using System.IO; -using System.Security.Cryptography.X509Certificates; +using System.Reflection; using Calamari.Common.Features.Processes; +using Calamari.Common.Plumbing.Extensions; using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; -using Calamari.FullFrameworkTools.Command; -using Calamari.FullFrameworkTools.Utils; -using Calamari.FullFrameworkTools.WindowsCertStore; -using Calamari.FullFrameworkTools.WindowsCertStore.WindowsNative; +using Calamari.Integration.Certificates; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Calamari.Integration.Iis +namespace Calamari.Integration.FullFramework { - public interface ILegacyFrameworkInvoker - { - TResponse Invoke(TRequest cmd); - } public class LegacyFrameworkInvoker: ILegacyFrameworkInvoker { readonly ICalamariFileSystem fileSystem; @@ -35,7 +27,7 @@ public LegacyFrameworkInvoker(ICalamariFileSystem fileSystem) public TResponse Invoke(TRequest cmd) { - var path = @"C:\Development\OctopusDeploy\calamari-second\source\Calamari.FullFrameworkTools\bin\Debug\net462\out\Calamari.FullFrameworkTools.exe"; + var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Calamari.FullFrameworkTools", "Calamari.FullFrameworkTools.exe"); var json = JsonConvert.SerializeObject(cmd); using (var tempDir = TemporaryDirectory.Create()) @@ -107,27 +99,5 @@ enum LogLevel Fatal, // Used for Exceptions Result, // Special Response } - - - - - } - - public class InProcessInvoker: ILegacyFrameworkInvoker - { - public TResponse Invoke(TRequest cmd) - { - var log = new InnerLog(); - var commandLocator = new RequestTypeLocator(); - var commandHandler = new CommandHandler(null, new Calamari.FullFrameworkTools.Iis.InternetInformationServer()); - var requestInvoker = new CommandRequestInvoker(commandLocator, commandHandler); - - var json = JsonConvert.SerializeObject(cmd); - - var result = requestInvoker.Run(nameof(OverwriteHomeDirectoryRequest), json); - return (TResponse)result; - } } - -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/source/Calamari/Integration/FullFramework/OverwriteHomeDirectoryRequest.cs b/source/Calamari/Integration/FullFramework/OverwriteHomeDirectoryRequest.cs new file mode 100644 index 000000000..24e559b5a --- /dev/null +++ b/source/Calamari/Integration/FullFramework/OverwriteHomeDirectoryRequest.cs @@ -0,0 +1,19 @@ +using System; + +namespace Calamari.Integration.FullFramework +{ + + public class OverwriteHomeDirectoryRequest : IRequest + { + public OverwriteHomeDirectoryRequest(string iisWebSiteName, string path, bool legacySupport) + { + IisWebSiteName = iisWebSiteName; + Path = path; + LegacySupport = legacySupport; + } + + public string IisWebSiteName { get; set; } + public string Path { get; set; } + public bool LegacySupport { get; set; } + } +} \ No newline at end of file diff --git a/source/Calamari/Integration/Iis/LegacyInternetInformationServer.cs b/source/Calamari/Integration/Iis/LegacyInternetInformationServer.cs index db1c7e0e0..6070950a0 100644 --- a/source/Calamari/Integration/Iis/LegacyInternetInformationServer.cs +++ b/source/Calamari/Integration/Iis/LegacyInternetInformationServer.cs @@ -3,46 +3,22 @@ using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; -using Calamari.Common.Plumbing.Logging; -using Calamari.FullFrameworkTools.WindowsCertStore; -using Calamari.FullFrameworkTools.WindowsCertStore.WindowsNative; -using ILog = Calamari.FullFrameworkTools.Command.ILog; +using Calamari.Integration.Certificates; +using Calamari.Integration.FullFramework; namespace Calamari.Integration.Iis { - class InnerLog : ILog - { - public void Verbose(string message) - { - Log.Verbose(message); - } - - public void Error(string message) - { - Log.Error(message); - } - - public void Info(string message) - { - Log.Info(message); - } - - public void Fatal(Exception exception) - { - throw new NotImplementedException("This should not be handled in-process"); - } - - public void Result(object response) - { - throw new NotImplementedException("This should not be handled in-process"); - } - } - + + public class StringResponse { public string Value { get; set; } } + public class VoidResponse { } + + public class BoolResponse { public bool Value { get; set; } } + public class LegacyInternetInformationServer : IInternetInformationServer { - readonly InProcessInvoker processInvoker; + readonly ILegacyFrameworkInvoker processInvoker; - public LegacyInternetInformationServer(InProcessInvoker processInvoker) + public LegacyInternetInformationServer(ILegacyFrameworkInvoker processInvoker) { this.processInvoker = processInvoker; } @@ -55,12 +31,11 @@ public bool OverwriteHomeDirectory(string iisWebSiteName, string path, bool lega } } - public class LegacyWindowsX509CertificateStore : IWindowsX509CertificateStore { - readonly InProcessInvoker processInvoker; + readonly ILegacyFrameworkInvoker processInvoker; - public LegacyWindowsX509CertificateStore(InProcessInvoker processInvoker) + public LegacyWindowsX509CertificateStore(ILegacyFrameworkInvoker processInvoker) { this.processInvoker = processInvoker; } @@ -69,7 +44,7 @@ public string FindCertificateStore(string thumbprint, StoreLocation storeLocatio { var cmd = new FindCertificateStoreRequest(thumbprint, storeLocation); var response = processInvoker.Invoke(cmd); - return response.Valus; + return response.Value; } public void ImportCertificateToStore(byte[] pfxBytes, @@ -78,13 +53,15 @@ public void ImportCertificateToStore(byte[] pfxBytes, string storeName, bool privateKeyExportable) { - + var cmd = new ImportCertificateToStoreByLocationRequest(pfxBytes, password, storeLocation, storeName, privateKeyExportable); + processInvoker.Invoke(cmd); } public void AddPrivateKeyAccessRules(string thumbprint, StoreLocation storeLocation, ICollection privateKeyAccessRules) { - throw new NotImplementedException(); + var cmd = new AddPrivateKeyAccessRulesRequest(thumbprint, storeLocation, null, privateKeyAccessRules.ToList()); + processInvoker.Invoke(cmd); } public void AddPrivateKeyAccessRules(string thumbprint, StoreLocation storeLocation, string storeName, ICollection privateKeyAccessRules) diff --git a/source/Calamari/Program.cs b/source/Calamari/Program.cs index 9202f3777..837b19177 100644 --- a/source/Calamari/Program.cs +++ b/source/Calamari/Program.cs @@ -26,6 +26,8 @@ using IContainer = Autofac.IContainer; using Calamari.Aws.Deployment; using Calamari.Azure.Kubernetes.Discovery; +using Calamari.Integration.FullFramework; +using Calamari.Integration.Iis; using Calamari.Kubernetes.Commands.Executors; namespace Calamari @@ -71,10 +73,15 @@ protected override void ConfigureContainer(ContainerBuilder builder, CommonOptio builder.RegisterType().As().SingleInstance(); builder.RegisterType().AsSelf(); builder.RegisterType().As().SingleInstance(); - + + //TODO: Once this runs on both netcore and full framework, this can be converted to a runtime conditional check #if WINDOWS_CERTIFICATE_STORE_SUPPORT - builder.RegisterType().As().SingleInstance(); + + builder.RegisterType().As().SingleInstance(); + + //builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); #else builder.RegisterType().As().SingleInstance(); #endif