diff --git a/CHANGELOG.md b/CHANGELOG.md index 7469403..d42cdaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +2.6.4 +* Fixed an issue with SSL Flags greater than 3 were not being applied correctly to newer IIS servers. 2.6.3 * Fixed re-enrollment or ODKG job when RDN Components contained escaped commas. * Updated renewal job for IIS Certs to delete the old cert if not bound or used by other web sites. diff --git a/IISU/PowerShellScripts/WinCertScripts.ps1 b/IISU/PowerShellScripts/WinCertScripts.ps1 index 00f7fdf..b5d2058 100644 --- a/IISU/PowerShellScripts/WinCertScripts.ps1 +++ b/IISU/PowerShellScripts/WinCertScripts.ps1 @@ -11,6 +11,7 @@ # 08/29/25 Fixed the add cert to store function to return the correct thumbprint # Made changes to the IIS Binding logic, breaking it into manageable pieces to aid in debugging issues # 09/16/25 Updated the Get CSP function to handle null values when reading hybrid certificates +# 11/17/25 Fixed issue with SSL Flags not being applied correctly to IIS bindings (2.6.4) # Set preferences globally at the script level $DebugPreference = "Continue" @@ -388,17 +389,12 @@ function New-KFIISSiteBinding { param ( [Parameter(Mandatory = $true)] [string]$SiteName, - [string]$IPAddress = "*", - [int]$Port = 443, - [AllowEmptyString()] [string]$Hostname = "", - [ValidateSet("http", "https")] [string]$Protocol = "https", - [ValidateScript({ if ($Protocol -eq 'https' -and [string]::IsNullOrEmpty($_)) { throw "Thumbprint is required when Protocol is 'https'" @@ -406,56 +402,97 @@ function New-KFIISSiteBinding { $true })] [string]$Thumbprint, - [string]$StoreName = "My", - [int]$SslFlags = 0 ) Write-Information "Entering PowerShell Script: New-KFIISSiteBinding" -InformationAction SilentlyContinue - Write-Verbose "Function: New-KFIISSiteBinding" Write-Verbose "Parameters: $(($PSBoundParameters.GetEnumerator() | ForEach-Object { "$($_.Key): '$($_.Value)'" }) -join ', ')" try { - # This function mimics IIS Manager behavior: - # - Replaces exact binding matches (same IP:Port:Hostname) - # - Allows multiple bindings with different hostnames (SNI) - # - Lets IIS handle true conflicts rather than pre-checking - - # Step 1: Verify site exists and get management approach + # Step 1: Perform verifications and get management info + # Check SslFlags + if (-not (Test-ValidSslFlags -SslFlags $SslFlags)) { + return New-ResultObject -Status Error 400 -Step "Validation" -ErrorMessage "Invalid SSL Flag bit configuration ($SslFlags)" + } + $managementInfo = Get-IISManagementInfo -SiteName $SiteName if (-not $managementInfo.Success) { return $managementInfo.Result } - # Step 2: Remove existing HTTPS bindings for this exact binding information - # This mimics IIS behavior: replace exact matches, allow different hostnames + # Step 2: Remove existing HTTPS bindings for this binding info $searchBindings = "${IPAddress}:${Port}:${Hostname}" Write-Verbose "Removing existing HTTPS bindings for: $searchBindings" - + $removalResult = Remove-ExistingIISBinding -SiteName $SiteName -BindingInfo $searchBindings -UseIISDrive $managementInfo.UseIISDrive if ($removalResult.Status -eq 'Error') { return $removalResult } - # Step 3: Add new binding with SSL certificate - Write-Verbose "Adding new binding with SSL certificate" - + # Step 3: Determine SslFlags supported by Microsoft.Web.Administration + if ($SslFlags -gt 3) { + Write-Verbose "SslFlags value $SslFlags exceeds managed API range (0–3). Applying reduced flags for creation." + $SslFlagsApplied = ($SslFlags -band 3) + } else { + $SslFlagsApplied = $SslFlags + } + + # Step 4: Add the new binding with the reduced flag set + Write-Verbose "Adding new binding with SSL certificate (SslFlagsApplied=$SslFlagsApplied)" + $addParams = @{ - SiteName = $SiteName - Protocol = $Protocol - IPAddress = $IPAddress - Port = $Port - Hostname = $Hostname - Thumbprint = $Thumbprint - StoreName = $StoreName - SslFlags = $SslFlags + SiteName = $SiteName + Protocol = $Protocol + IPAddress = $IPAddress + Port = $Port + Hostname = $Hostname + Thumbprint = $Thumbprint + StoreName = $StoreName + SslFlags = $SslFlagsApplied UseIISDrive = $managementInfo.UseIISDrive } - + $addResult = Add-IISBindingWithSSL @addParams - return $addResult + if ($addResult.Status -eq 'Error') { + return $addResult + } + + # Step 5: If extended flags, update via appcmd.exe + if ($SslFlags -gt 3) { + Write-Verbose "Applying full SslFlags=$SslFlags via appcmd" + + $appcmd = Join-Path $env:windir "System32\inetsrv\appcmd.exe" + + # Escape any single quotes in hostname + $safeHostname = $Hostname -replace "'", "''" + $bindingInfo = "${IPAddress}:${Port}:${safeHostname}" + + # Quote site name only if it contains spaces + if ($SiteName -match '\s') { + $siteArg = "/site.name:`"$SiteName`"" + } else { + $siteArg = "/site.name:$SiteName" + } + + # Build binding argument for appcmd + $bindingArg = "/bindings.[protocol='https',bindingInformation='$bindingInfo'].sslFlags:$SslFlags" + + Write-Verbose "Running appcmd: $appcmd $siteArg $bindingArg" + $appcmdOutput = & $appcmd set site $siteArg $bindingArg 2>&1 + Write-Verbose "appcmd output: $appcmdOutput" + + #& $appcmd set site $siteArg $bindingArg | Out-Null + + if ($LASTEXITCODE -ne 0) { + Write-Warning "appcmd failed to set extended SslFlags ($SslFlags) for binding $bindingInfo." + } else { + Write-Verbose "Successfully updated SslFlags to $SslFlags via appcmd." + } + } + + return $addResult } catch { $errorMessage = "Unexpected error in New-KFIISSiteBinding: $($_.Exception.Message)" @@ -1464,6 +1501,15 @@ function Parse-DNSubject { return $subjectString } +function Test-ValidSslFlags { + param([int]$SslFlags) + + $validBits = 1,2,4,8,32,64,128 + $invalidBits = $SslFlags -bxor ($SslFlags -band ($validBits | Measure-Object -Sum).Sum) + + return ($invalidBits -eq 0) +} + # Note: Removed Test-IISBindingConflict function - we now mimic IIS behavior # IIS replaces exact matches and allows multiple hostnames (SNI) on same IP:Port function Get-IISManagementInfo { diff --git a/README.md b/README.md index 95cf76d..47e710c 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,18 @@ the Keyfactor Command Portal ![WinCert Entry Parameters Tab](docsource/images/WinCert-entry-parameters-store-type-dialog.png) + + ##### ProviderName + + ![WinCert Entry Parameter - ProviderName](docsource/images/WinCert-entry-parameters-store-type-dialog-ProviderName.png) + + + ##### SAN + + ![WinCert Entry Parameter - SAN](docsource/images/WinCert-entry-parameters-store-type-dialog-SAN.png) + + + @@ -426,6 +438,48 @@ the Keyfactor Command Portal ![IISU Entry Parameters Tab](docsource/images/IISU-entry-parameters-store-type-dialog.png) + + ##### Port + + ![IISU Entry Parameter - Port](docsource/images/IISU-entry-parameters-store-type-dialog-Port.png) + + + ##### IPAddress + + ![IISU Entry Parameter - IPAddress](docsource/images/IISU-entry-parameters-store-type-dialog-IPAddress.png) + + + ##### HostName + + ![IISU Entry Parameter - HostName](docsource/images/IISU-entry-parameters-store-type-dialog-HostName.png) + + + ##### SiteName + + ![IISU Entry Parameter - SiteName](docsource/images/IISU-entry-parameters-store-type-dialog-SiteName.png) + + + ##### SniFlag + + ![IISU Entry Parameter - SniFlag](docsource/images/IISU-entry-parameters-store-type-dialog-SniFlag.png) + + + ##### Protocol + + ![IISU Entry Parameter - Protocol](docsource/images/IISU-entry-parameters-store-type-dialog-Protocol.png) + + + ##### ProviderName + + ![IISU Entry Parameter - ProviderName](docsource/images/IISU-entry-parameters-store-type-dialog-ProviderName.png) + + + ##### SAN + + ![IISU Entry Parameter - SAN](docsource/images/IISU-entry-parameters-store-type-dialog-SAN.png) + + + @@ -549,6 +603,23 @@ the Keyfactor Command Portal ![WinSql Entry Parameters Tab](docsource/images/WinSql-entry-parameters-store-type-dialog.png) + + ##### InstanceName + + ![WinSql Entry Parameter - InstanceName](docsource/images/WinSql-entry-parameters-store-type-dialog-InstanceName.png) + + + ##### ProviderName + + ![WinSql Entry Parameter - ProviderName](docsource/images/WinSql-entry-parameters-store-type-dialog-ProviderName.png) + + + ##### SAN + + ![WinSql Entry Parameter - SAN](docsource/images/WinSql-entry-parameters-store-type-dialog-SAN.png) + + + diff --git a/docsource/images/IISU-advanced-store-type-dialog.png b/docsource/images/IISU-advanced-store-type-dialog.png index eab1385..2d6fca8 100644 Binary files a/docsource/images/IISU-advanced-store-type-dialog.png and b/docsource/images/IISU-advanced-store-type-dialog.png differ diff --git a/docsource/images/IISU-basic-store-type-dialog.png b/docsource/images/IISU-basic-store-type-dialog.png index 17be4a5..fa4e029 100644 Binary files a/docsource/images/IISU-basic-store-type-dialog.png and b/docsource/images/IISU-basic-store-type-dialog.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-HostName.png b/docsource/images/IISU-entry-parameters-store-type-dialog-HostName.png new file mode 100644 index 0000000..4db52c1 Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-HostName.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-IPAddress.png b/docsource/images/IISU-entry-parameters-store-type-dialog-IPAddress.png new file mode 100644 index 0000000..3ca535d Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-IPAddress.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-Port.png b/docsource/images/IISU-entry-parameters-store-type-dialog-Port.png new file mode 100644 index 0000000..0ef992b Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-Port.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-Protocol.png b/docsource/images/IISU-entry-parameters-store-type-dialog-Protocol.png new file mode 100644 index 0000000..e23c4d3 Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-Protocol.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-ProviderName.png b/docsource/images/IISU-entry-parameters-store-type-dialog-ProviderName.png new file mode 100644 index 0000000..9598bd5 Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-ProviderName.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-SAN.png b/docsource/images/IISU-entry-parameters-store-type-dialog-SAN.png new file mode 100644 index 0000000..9aaf92a Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-SAN.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-SiteName.png b/docsource/images/IISU-entry-parameters-store-type-dialog-SiteName.png new file mode 100644 index 0000000..0fc1a73 Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-SiteName.png differ diff --git a/docsource/images/IISU-entry-parameters-store-type-dialog-SniFlag.png b/docsource/images/IISU-entry-parameters-store-type-dialog-SniFlag.png new file mode 100644 index 0000000..616108b Binary files /dev/null and b/docsource/images/IISU-entry-parameters-store-type-dialog-SniFlag.png differ diff --git a/docsource/images/WinCert-advanced-store-type-dialog.png b/docsource/images/WinCert-advanced-store-type-dialog.png index 8b43572..9000147 100644 Binary files a/docsource/images/WinCert-advanced-store-type-dialog.png and b/docsource/images/WinCert-advanced-store-type-dialog.png differ diff --git a/docsource/images/WinCert-entry-parameters-store-type-dialog-ProviderName.png b/docsource/images/WinCert-entry-parameters-store-type-dialog-ProviderName.png new file mode 100644 index 0000000..9cde9d3 Binary files /dev/null and b/docsource/images/WinCert-entry-parameters-store-type-dialog-ProviderName.png differ diff --git a/docsource/images/WinCert-entry-parameters-store-type-dialog-SAN.png b/docsource/images/WinCert-entry-parameters-store-type-dialog-SAN.png new file mode 100644 index 0000000..d97892a Binary files /dev/null and b/docsource/images/WinCert-entry-parameters-store-type-dialog-SAN.png differ diff --git a/docsource/images/WinCert-entry-parameters-store-type-dialog.png b/docsource/images/WinCert-entry-parameters-store-type-dialog.png index df44b2b..c42176f 100644 Binary files a/docsource/images/WinCert-entry-parameters-store-type-dialog.png and b/docsource/images/WinCert-entry-parameters-store-type-dialog.png differ diff --git a/docsource/images/WinSql-advanced-store-type-dialog.png b/docsource/images/WinSql-advanced-store-type-dialog.png index 8b43572..9000147 100644 Binary files a/docsource/images/WinSql-advanced-store-type-dialog.png and b/docsource/images/WinSql-advanced-store-type-dialog.png differ diff --git a/docsource/images/WinSql-basic-store-type-dialog.png b/docsource/images/WinSql-basic-store-type-dialog.png index c276ba9..80d4687 100644 Binary files a/docsource/images/WinSql-basic-store-type-dialog.png and b/docsource/images/WinSql-basic-store-type-dialog.png differ diff --git a/docsource/images/WinSql-entry-parameters-store-type-dialog-InstanceName.png b/docsource/images/WinSql-entry-parameters-store-type-dialog-InstanceName.png new file mode 100644 index 0000000..5810e3e Binary files /dev/null and b/docsource/images/WinSql-entry-parameters-store-type-dialog-InstanceName.png differ diff --git a/docsource/images/WinSql-entry-parameters-store-type-dialog-ProviderName.png b/docsource/images/WinSql-entry-parameters-store-type-dialog-ProviderName.png new file mode 100644 index 0000000..b5287bb Binary files /dev/null and b/docsource/images/WinSql-entry-parameters-store-type-dialog-ProviderName.png differ diff --git a/docsource/images/WinSql-entry-parameters-store-type-dialog-SAN.png b/docsource/images/WinSql-entry-parameters-store-type-dialog-SAN.png new file mode 100644 index 0000000..ea23ade Binary files /dev/null and b/docsource/images/WinSql-entry-parameters-store-type-dialog-SAN.png differ