Fix up TLS settings for pwsh bootstrapping (#86594)

On some Windows hosts the TLS policies don't allow TLS 1.2 or newer by
default. We add some code to the bootstrapping code to enable PowerShell
to use the OS policies rather than the outdated .NET ones.

This has only appeared on Azure 2016 based hosts, AWS on 2016 seems to
configure the server to use the OS policies some other way. 2019+ by
default aren't affected.
pull/86596/head
Jordan Borean 2 months ago committed by GitHub
parent 8a07f8963d
commit 8e9ce75266
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,4 +1,6 @@
using namespace System.IO
using namespace System.Net
using namespace System.Reflection
using namespace System.Text
[CmdletBinding()]
@ -26,6 +28,39 @@ if (Test-Path -LiteralPath $pwshExe) {
$zipFilename = "PowerShell-$PowerShellVersion.zip"
$zipPath = [Path]::Combine([Path]::GetTempPath(), $zipFilename)
$currentProtocol = [ServicePointManager]::SecurityProtocol
if ([SecurityProtocolType].GetMember("Tls13")) {
# If the Tls13 member is present we are on .NET Framework 4.8+ so using
# the SystemDefault setting will use the OS policies. If it's not set
# to SystemDefault already we are running in a PSRemoting WSMan host
# and need some reflection to reconfigure the policies to get it to use
# the OS policies.
if ($currentProtocol -ne 'SystemDefault') {
# https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls#switchsystemnetdontenablesystemdefaulttlsversions
$disableSystemTlsField = [ServicePointManager].GetField(
's_disableSystemDefaultTlsVersions',
[BindingFlags]'NonPublic, Static')
if ($disableSystemTlsField -and $disableSystemTlsField.GetValue($null)) {
$disableSystemTlsField.SetValue($null, $false)
}
[ServicePointManager]::SecurityProtocol = [SecurityProtocolType]::SystemDefault
}
}
else {
# We are on .NET 4.7 or older, as TLS 1.2 is the max version we can
# use here regardless of the OS, manually enable the protocols known to
# the runtime.
if ([SecurityProtocolType].GetMember("Tls11")) {
$currentProtocol = $currentProtocol -bor [SecurityProtocolType]::Tls11
}
if ([SecurityProtocolType].GetMember("Tls12")) {
$currentProtocol = $currentProtocol -bor [SecurityProtocolType]::Tls12
}
[ServicePointManager]::SecurityProtocol = $currentProtocol
}
if (-not (Test-Path -LiteralPath $zipPath)) {
$attempts = 0

Loading…
Cancel
Save