From 849628a0c011b60c4e86d23187a0023d49b1583e Mon Sep 17 00:00:00 2001 From: Michel Zehnder Date: Wed, 4 Dec 2024 07:42:37 +0100 Subject: [PATCH 1/3] Install SQL Certificate & Trust It Do not automatically trust the Certificate in the Test --- .../steps/configure-sql-server-win-step.yml | 38 +++++++++++++++++++ .../CertificateTest.cs | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml b/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml index f0c27e6152..35ff8cefe5 100644 --- a/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml +++ b/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml @@ -195,6 +195,44 @@ steps: displayName: 'Setup SQL Alias [Win]' condition: ${{parameters.condition }} +- powershell: | + # Create Certificate + $computerDnsName = [System.Net.Dns]::Resolve($null).HostName + $certificate = New-SelfSignedCertificate -DnsName $computerDnsName,localhost -CertStoreLocation cert:\LocalMachine\My -FriendlyName test99 -KeySpec KeyExchange + + # Get path to Private key (used later) + $keyPath = $certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName + $machineKeyPath = "$env:ProgramData\Microsoft\Crypto\RSA\MachineKeys\$keyPath" + + # Add certificate to trusted roots + $store = new-object System.Security.Cryptography.X509Certificates.X509Store( + [System.Security.Cryptography.X509Certificates.StoreName]::Root, + "localmachine" + ) + + $store.open("MaxAllowed") + $store.add($certificate) + $store.close() + + # Get SQL Server instances and add the Certificate + $instances = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' + foreach ($instance in $instances){ + $instance | ForEach-Object { + $_.PSObject.Properties | Where-Object { $_.Name -notmatch '^PS.*' } | ForEach-Object { + Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($_.Value)\MSSQLServer\SuperSocketNetLib" -Name Certificate -Value $certificate.Thumbprint.ToLower() + + # Grant read access to Private Key for SQL Service Account + if ($($_.Name) -eq "MSSQLSERVER") { + icacls $machineKeyPath /grant "NT Service\MSSQLSERVER:R" + } else { + icacls $machineKeyPath /grant "NT Service\MSSQL`$$($_.Name):R" + } + } + } + } + displayName: 'Add SQL Certificate [Win]' + condition: ${{parameters.condition }} + - powershell: | # You need to restart SQL Server for the change to persist # -Force takes care of any dependent services, like SQL Agent. diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs index d500391227..edfc507d6f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs @@ -166,7 +166,6 @@ public void OpeningConnectionWitHNICTest() } } - [ActiveIssue("31754")] [ConditionalFact(nameof(AreConnStringsSetup), nameof(UseManagedSNIOnWindows), nameof(IsNotAzureServer), nameof(IsLocalHost))] [PlatformSpecific(TestPlatforms.Windows)] public void RemoteCertificateNameMismatchErrorTest() @@ -175,6 +174,7 @@ public void RemoteCertificateNameMismatchErrorTest() { DataSource = GetLocalIpAddress(), Encrypt = SqlConnectionEncryptOption.Mandatory, + TrustServerCertificate = false, HostNameInCertificate = "BadHostName" }; using SqlConnection connection = new(builder.ConnectionString); From 057ec8c333d0f10eb78ca502c7c33cc82ca1488a Mon Sep 17 00:00:00 2001 From: Michel Zehnder Date: Wed, 4 Dec 2024 14:28:42 +0100 Subject: [PATCH 2/3] Remove Console output --- .../ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs index edfc507d6f..1a177c5c39 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs @@ -183,7 +183,6 @@ public void RemoteCertificateNameMismatchErrorTest() Assert.Equal(20, exception.Class); Assert.IsType(exception.InnerException); Assert.StartsWith("Certificate name mismatch. The provided 'DataSource' or 'HostNameInCertificate' does not match the name in the certificate.", exception.InnerException.Message); - Console.WriteLine(exception.Message); } private static void CreateValidCertificate(string script) From 88ad3263b4b002a4762b4294b5dc76679d0066ff Mon Sep 17 00:00:00 2001 From: Michel Zehnder Date: Wed, 4 Dec 2024 17:40:18 +0100 Subject: [PATCH 3/3] Restart default isntance as well if installed --- .../common/templates/steps/configure-sql-server-win-step.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml b/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml index 35ff8cefe5..28c7a6ba53 100644 --- a/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml +++ b/eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml @@ -248,6 +248,7 @@ steps: } Restart-Service -Name "$serviceName" -Force + Restart-Service -Name MSSQLSERVER* -Force displayName: 'Restart SQL Server [Win]' condition: ${{parameters.condition }}