From d45c5f19ae005ca2a42f9d1bb715b8649fcbc52d Mon Sep 17 00:00:00 2001 From: Jonathan landry Date: Wed, 26 Apr 2023 14:28:02 -0400 Subject: [PATCH 1/4] Support if a different number of empty lines is provided by the outupt of netsh. Also support if there is more than one certificate. fix #919 --- .../AppCmdOnTargetMachines.ps1 | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 index 27e173cf8..243dd6c6a 100644 --- a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 +++ b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 @@ -183,8 +183,12 @@ function Add-SslCert Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" $result = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $isItSameBinding = $result.Get(4).Contains([string]::Format("{0}:{1}", $hostname, $port)) - + $result = $result | where {$_.TrimStart().StartsWith("IP:port") -and $_.Contains([string]::Format("{0}:{1}", $ipAddress, $port))} + if($result) + { + $isItSameBinding = $true + } + $addCertCmd = [string]::Format("http add sslcert hostnameport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $hostname, $port, $certhash, [System.Guid]::NewGuid().toString()) } else @@ -193,8 +197,12 @@ function Add-SslCert Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" $result = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $isItSameBinding = $result.Get(4).Contains([string]::Format("{0}:{1}", $ipAddress, $port)) - + $result = $result | where {$_.TrimStart().StartsWith("IP:port") -and $_.Contains([string]::Format("{0}:{1}", $ipAddress, $port))} + if($result) + { + $isItSameBinding = $true + } + $addCertCmd = [string]::Format("http add sslcert ipport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $ipAddress, $port, $certhash, [System.Guid]::NewGuid().toString()) } From dd5e1b99c72c196d5d154da79637869e0beffed0 Mon Sep 17 00:00:00 2001 From: Jonathan landry Date: Wed, 26 Apr 2023 14:49:13 -0400 Subject: [PATCH 2/4] Error when copy pasting --- .../TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 index 243dd6c6a..4bf539f6b 100644 --- a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 +++ b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 @@ -183,7 +183,7 @@ function Add-SslCert Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" $result = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $result = $result | where {$_.TrimStart().StartsWith("IP:port") -and $_.Contains([string]::Format("{0}:{1}", $ipAddress, $port))} + $result = $result | where {$_.TrimStart().StartsWith("Hostname:port") -and $_.Contains([string]::Format("{0}:{1}", $hostname, $port))} if($result) { $isItSameBinding = $true From 509c35c4b6cc2747c2b03b5d0ceb3f86197d5231 Mon Sep 17 00:00:00 2001 From: Jonathan landry Date: Mon, 10 Jul 2023 10:37:11 -0400 Subject: [PATCH 3/4] Correction for certificate comparison. --- .../AppCmdOnTargetMachines.ps1 | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 index 4bf539f6b..2d5ff38f4 100644 --- a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 +++ b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 @@ -172,8 +172,8 @@ function Add-SslCert $ipAddress = "0.0.0.0" } - $result = $null - $isItSameBinding = $false + $netshResult = $null + $matchingBinding = $null $addCertCmd = [string]::Empty #SNI is supported IIS 8 and above. To enable SNI hostnameport option should be used @@ -182,12 +182,8 @@ function Add-SslCert $showCertCmd = [string]::Format("http show sslcert hostnameport={0}:{1}", $hostname, $port) Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" - $result = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $result = $result | where {$_.TrimStart().StartsWith("Hostname:port") -and $_.Contains([string]::Format("{0}:{1}", $hostname, $port))} - if($result) - { - $isItSameBinding = $true - } + $netshResult = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd + $matchingBinding = $netshResult | where {$_.TrimStart().StartsWith("Hostname:port") -and $_.EndsWith([string]::Format(": {0}:{1}", $hostname, $port))} $addCertCmd = [string]::Format("http add sslcert hostnameport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $hostname, $port, $certhash, [System.Guid]::NewGuid().toString()) } @@ -196,22 +192,22 @@ function Add-SslCert $showCertCmd = [string]::Format("http show sslcert ipport={0}:{1}", $ipAddress, $port) Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" - $result = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $result = $result | where {$_.TrimStart().StartsWith("IP:port") -and $_.Contains([string]::Format("{0}:{1}", $ipAddress, $port))} - if($result) - { - $isItSameBinding = $true - } + $netshResult = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd + $matchingBinding = $netshResult | where {$_.TrimStart().StartsWith("IP:port") -and $_.EndsWith([string]::Format(": {0}:{1}", $ipAddress, $port))} $addCertCmd = [string]::Format("http add sslcert ipport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $ipAddress, $port, $certhash, [System.Guid]::NewGuid().toString()) } - $isItSameCert = $result.Get(5).ToLower().Contains($certhash.ToLower()) - - if($isItSameBinding -and $isItSameCert) + if($matchingBinding) #a certificate with the same binding is found { - Write-Verbose "SSL cert binding is already present. Returning" - return + $matchingBindingIndex = $netshResult.IndexOf($matchingBinding) + $isItSameCert = $netshResult.Get($matchingBindingIndex + 1).ToLower().Contains($certhash.ToLower()) #The certificate hash is on the next line + + if($isItSameCert) + { + Write-Verbose "SSL cert binding is already present. Returning" + return + } } Write-Verbose "Setting SslCert for website." From 4173f750c650e4936bde8ce472c97ea4ea81b82b Mon Sep 17 00:00:00 2001 From: Vladyslav Horbachov Date: Wed, 26 Jul 2023 17:18:28 +0200 Subject: [PATCH 4/4] Refactored Add-SslCert --- .../AppCmdOnTargetMachines.ps1 | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 index 2d5ff38f4..e2a52c492 100644 --- a/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 +++ b/TaskModules/powershell/TaskModuleIISManageUtility/AppCmdOnTargetMachines.ps1 @@ -150,6 +150,35 @@ function Enable-SNI Invoke-VstsTool -Filename $appCmdPath -Arguments $appCmdArgs -RequireExitCodeZero } +function ShowCertBinding +{ + param( + [string]$bindingType, + [string]$bindingValue, + [string]$port + ) + + $showCertCmd = "http show sslcert {0}={1}:{2}" -f $bindingType, $bindingValue, $port + Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" + + $netshResult = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd + $matchingBinding = $netshResult | Where-Object { $_.TrimStart().StartsWith("{0} :" -f $bindingType) -and $_.EndsWith(": {0}:{1}" -f $bindingValue, $port)} + return $matchingBinding, $netshResult +} + +function AddCertBinding +{ + param( + [string]$bindingType, + [string]$bindingValue, + [string]$port, + [string]$certhash + ) + + $addCertCmd = "http add sslcert {0}={1}:{2} certhash={3} appid={{{4}}} certstorename=MY" -f $bindingType, $bindingValue, $port, $certhash, [System.Guid]::NewGuid().toString() + Invoke-VstsTool -Filename "netsh" -Arguments $addCertCmd -RequireExitCodeZero +} + function Add-SslCert { param( @@ -172,36 +201,16 @@ function Add-SslCert $ipAddress = "0.0.0.0" } - $netshResult = $null - $matchingBinding = $null - $addCertCmd = [string]::Empty - - #SNI is supported IIS 8 and above. To enable SNI hostnameport option should be used - if($sni -eq "true" -and $iisVersion -ge 8 -and -not [string]::IsNullOrWhiteSpace($hostname)) - { - $showCertCmd = [string]::Format("http show sslcert hostnameport={0}:{1}", $hostname, $port) - Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" - - $netshResult = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $matchingBinding = $netshResult | where {$_.TrimStart().StartsWith("Hostname:port") -and $_.EndsWith([string]::Format(": {0}:{1}", $hostname, $port))} - - $addCertCmd = [string]::Format("http add sslcert hostnameport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $hostname, $port, $certhash, [System.Guid]::NewGuid().toString()) - } - else - { - $showCertCmd = [string]::Format("http show sslcert ipport={0}:{1}", $ipAddress, $port) - Write-Verbose "Checking if SslCert binding is already present. Running command : netsh $showCertCmd" + $isSniEnabled = $sni -eq "true" -and $iisVersion -ge 8 -and -not [string]::IsNullOrWhiteSpace($hostname) + $bindingType = if ($isSniEnabled) { "hostnameport" } else { "ipport" } + $bindingValue = if ($isSniEnabled) { $hostname } else { $ipAddress } - $netshResult = Invoke-VstsTool -Filename "netsh" -Arguments $showCertCmd - $matchingBinding = $netshResult | where {$_.TrimStart().StartsWith("IP:port") -and $_.EndsWith([string]::Format(": {0}:{1}", $ipAddress, $port))} - - $addCertCmd = [string]::Format("http add sslcert ipport={0}:{1} certhash={2} appid={{{3}}} certstorename=MY", $ipAddress, $port, $certhash, [System.Guid]::NewGuid().toString()) - } + $matchingBinding, $netshResult = ShowCertBinding -bindingType $bindingType -bindingValue $bindingValue -port $port - if($matchingBinding) #a certificate with the same binding is found + if($matchingBinding) # A certificate with the same binding is found { $matchingBindingIndex = $netshResult.IndexOf($matchingBinding) - $isItSameCert = $netshResult.Get($matchingBindingIndex + 1).ToLower().Contains($certhash.ToLower()) #The certificate hash is on the next line + $isItSameCert = $netshResult[$matchingBindingIndex + 1].ToLower().Contains($certhash.ToLower()) # The certificate hash is on the next line if($isItSameCert) { @@ -211,7 +220,7 @@ function Add-SslCert } Write-Verbose "Setting SslCert for website." - Invoke-VstsTool -Filename "netsh" -Arguments $addCertCmd -RequireExitCodeZero + AddCertBinding -bindingType $bindingType -bindingValue $bindingValue -port $port -certhash $certhash } function Add-Website