From 5de1ad276fac81f287e4c3621a04b26cc2f711c2 Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Fri, 3 Nov 2017 10:17:58 -0500 Subject: [PATCH 01/10] [Feature] Add SslProtocol Support to WebCmdlets * Adds `-SslProtocol` parameter to Web Cmdlets * Adds WebSslProtocol Enum to support limited subset of SslProtocol enum supported by HttpClientHandler * Adds TLS 1.1 and TLS 1.0 listening ports to WebListener * Adds 100% test coverage for new feature --- .../Common/WebRequestPSCmdlet.Common.cs | 34 +++++++++ .../CoreCLR/WebRequestPSCmdlet.CoreClr.cs | 6 ++ .../WebCmdlets.Tests.ps1 | 75 +++++++++++++++++++ test/tools/Modules/WebListener/README.md | 2 +- .../Modules/WebListener/WebListener.psm1 | 26 ++++++- test/tools/WebListener/Program.cs | 26 ++++++- test/tools/WebListener/README.md | 6 +- 7 files changed, 166 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 00828fec4b9..5e02b458e62 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -11,6 +11,7 @@ using System.Collections; using System.Globalization; using System.Security; +using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; #if !CORECLR @@ -46,6 +47,33 @@ public enum WebAuthenticationType OAuth, } + /// + /// The valid values for the -SslProtocol parameter for Invoke-RestMethod and Invoke-WebRequest + /// + [Flags] + public enum WebSslProtocol + { + /// + /// No SSL protocol will be set and the system defaults will be used. + /// + Default = 0, + + /// + /// Specifies the TLS 1.0 security protocol. The TLS protocol is defined in IETF RFC 2246. + /// + Tls = SslProtocols.Tls, + + /// + /// Specifies the TLS 1.1 security protocol. The TLS protocol is defined in IETF RFC 4346. + /// + Tls11 = SslProtocols.Tls11, + + /// + /// Specifies the TLS 1.2 security protocol. The TLS protocol is defined in IETF RFC 5246 + /// + Tls12 = SslProtocols.Tls12 + } + /// /// Base class for Invoke-RestMethod and Invoke-WebRequest commands. /// @@ -137,6 +165,12 @@ public abstract partial class WebRequestPSCmdlet : PSCmdlet [Parameter] public virtual SwitchParameter SkipCertificateCheck { get; set; } + /// + /// Gets or sets the TLS/SSL protocol used by the Web Cmdlet + /// + [Parameter] + public virtual WebSslProtocol SslProtocol { get; set; } = WebSslProtocol.Default; + /// /// Gets or sets the Token property. Token is required by Authentication OAuth and Bearer. /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs index f5322ddc129..ca5d7ab7f57 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs @@ -13,6 +13,7 @@ using System.Text; using System.Collections; using System.Globalization; +using System.Security.Authentication; using System.Security.Cryptography; using System.Threading; using System.Xml; @@ -192,6 +193,11 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) } } + // Set The SslProtocol. WebSslProtocol is used because not all SslProtocols are supported by HttpClientHandler. + // Also SslProtocols.Default is not the "default" for HttpClientHandler as SslProtocols.Ssl3 is not supported. + handler.SslProtocols = (SslProtocols)SslProtocol; + + HttpClient httpClient = new HttpClient(handler); // check timeout setting (in seconds instead of milliseconds as in HttpWebRequest) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 8dc1b1aaaef..b87bef22cfd 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -1414,6 +1414,44 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { } } + Context "Invoke-WebRequest -SslProtocol Test" { + It "Verifies Invoke-WebRequest -SslProtocol " -TestCases @( + @{SslProtocol = 'Default'} + @{SslProtocol = 'Tls'} + @{SslProtocol = 'Tls11'} + @{SslProtocol = 'Tls12'} + ) { + param($SslProtocol) + $params = @{ + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $SslProtocol + SslProtocol = $SslProtocol + SkipCertificateCheck = $true + } + $response = Invoke-WebRequest @params + $result = $Response.Content | ConvertFrom-Json + + $result.headers.Host | Should Be $params.Uri.Authority + } + + It "Verifies Invoke-WebRequest -SslProtocol -SslProtocol fails on a only connection" -TestCases @( + @{IntendedProtocol = 'Tls'; ActualProtocol = 'Tls12'} + @{IntendedProtocol = 'Tls'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls12'} + @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + ) { + param( $IntendedProtocol, $ActualProtocol) + $params = @{ + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $ActualProtocol + SslProtocol = $IntendedProtocol + SkipCertificateCheck = $true + ErrorAction = 'Stop' + } + { Invoke-WebRequest @params } | ShouldBeErrorId 'WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand' + } + } + BeforeEach { if ($env:http_proxy) { $savedHttpProxy = $env:http_proxy @@ -2332,6 +2370,43 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { } } + Context "Invoke-RestMethod -SslProtocol Test" { + It "Verifies Invoke-RestMethod -SslProtocol " -TestCases @( + @{SslProtocol = 'Default'} + @{SslProtocol = 'Tls'} + @{SslProtocol = 'Tls11'} + @{SslProtocol = 'Tls12'} + ) { + param($SslProtocol) + $params = @{ + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $SslProtocol + SslProtocol = $SslProtocol + SkipCertificateCheck = $true + } + $result = Invoke-RestMethod @params + + $result.headers.Host | Should Be $params.Uri.Authority + } + + It "Verifies Invoke-RestMethod -SslProtocol fails on a only connection" -TestCases @( + @{IntendedProtocol = 'Tls'; ActualProtocol = 'Tls12'} + @{IntendedProtocol = 'Tls'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls12'} + @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + ) { + param( $IntendedProtocol, $ActualProtocol) + $params = @{ + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $ActualProtocol + SslProtocol = $IntendedProtocol + SkipCertificateCheck = $true + ErrorAction = 'Stop' + } + { Invoke-RestMethod @params } | ShouldBeErrorId 'WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand' + } + } + BeforeEach { if ($env:http_proxy) { $savedHttpProxy = $env:http_proxy diff --git a/test/tools/Modules/WebListener/README.md b/test/tools/Modules/WebListener/README.md index f66d94b2c16..ba2b5759b4a 100644 --- a/test/tools/Modules/WebListener/README.md +++ b/test/tools/Modules/WebListener/README.md @@ -7,7 +7,7 @@ A PowerShell module for managing the WebListener App. The included SelF-Signed C ```powershell Import-Module .\build.psm1 Publish-PSTestTools -$Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084 +$Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084 -Tls11Port 8085 -TlsPort 8086 ``` # Stopping WebListener diff --git a/test/tools/Modules/WebListener/WebListener.psm1 b/test/tools/Modules/WebListener/WebListener.psm1 index a3125d07c6b..2b09bef5d9b 100644 --- a/test/tools/Modules/WebListener/WebListener.psm1 +++ b/test/tools/Modules/WebListener/WebListener.psm1 @@ -2,6 +2,8 @@ Class WebListener { [int]$HttpPort [int]$HttpsPort + [int]$Tls11Port + [int]$TlsPort [System.Management.Automation.Job]$Job WebListener () { } @@ -36,7 +38,13 @@ function Start-WebListener [int]$HttpPort = 8083, [ValidateRange(1,65535)] - [int]$HttpsPort = 8084 + [int]$HttpsPort = 8084, + + [ValidateRange(1,65535)] + [int]$Tls11Port = 8085, + + [ValidateRange(1,65535)] + [int]$TlsPort = 8086 ) process @@ -58,11 +66,13 @@ function Start-WebListener $Job = Start-Job { $path = Split-Path -parent (get-command WebListener).Path Push-Location $path - dotnet $using:appDll $using:serverPfxPath $using:serverPfxPassword $using:HttpPort $using:HttpsPort + dotnet $using:appDll $using:serverPfxPath $using:serverPfxPassword $using:HttpPort $using:HttpsPort $using:Tls11Port $using:TlsPort } $Script:WebListener = [WebListener]@{ HttpPort = $HttpPort HttpsPort = $HttpsPort + Tls11Port = $Tls11Port + TlsPort = $TlsPort Job = $Job } # Wait until the app is running or until the initTimeoutSeconds have been reached @@ -112,6 +122,10 @@ function Get-WebListenerUrl { [OutputType([Uri])] param ( [switch]$Https, + + [ValidateSet('Default', 'Tls12', 'Tls11', 'Tls')] + [string]$SslProtocol = 'Default', + [ValidateSet( 'Cert', 'Compression', @@ -140,9 +154,15 @@ function Get-WebListenerUrl { $Uri.Host = 'localhost' $Uri.Port = $runningListener.HttpPort $Uri.Scheme = 'Http' + if ($Https.IsPresent) { - $Uri.Port = $runningListener.HttpsPort + switch ($SslProtocol) + { + 'Tls11' { $Uri.Port = $runningListener.Tls11Port } + 'Tls' { $Uri.Port = $runningListener.TlsPort } + default { $Uri.Port = $runningListener.HttpsPort } + } $Uri.Scheme = 'Https' } diff --git a/test/tools/WebListener/Program.cs b/test/tools/WebListener/Program.cs index 124f28f7e8d..e0706c9a374 100644 --- a/test/tools/WebListener/Program.cs +++ b/test/tools/WebListener/Program.cs @@ -20,9 +20,9 @@ public class Program { public static void Main(string[] args) { - if (args.Count() != 4) + if (args.Count() != 6) { - System.Console.WriteLine("Required: "); + System.Console.WriteLine("Required: "); Environment.Exit(1); } BuildWebHost(args).Run(); @@ -44,6 +44,28 @@ public static IWebHost BuildWebHost(string[] args) => httpsOption.ServerCertificate = certificate; listenOptions.UseHttps(httpsOption); }); + options.Listen(IPAddress.Loopback, int.Parse(args[4]), listenOptions => + { + var certificate = new X509Certificate2(args[0], args[1]); + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); + httpsOption.SslProtocols = SslProtocols.Tls11; + httpsOption.ClientCertificateMode = ClientCertificateMode.AllowCertificate; + httpsOption.ClientCertificateValidation = (inCertificate, inChain, inPolicy) => {return true;}; + httpsOption.CheckCertificateRevocation = false; + httpsOption.ServerCertificate = certificate; + listenOptions.UseHttps(httpsOption); + }); + options.Listen(IPAddress.Loopback, int.Parse(args[5]), listenOptions => + { + var certificate = new X509Certificate2(args[0], args[1]); + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); + httpsOption.SslProtocols = SslProtocols.Tls; + httpsOption.ClientCertificateMode = ClientCertificateMode.AllowCertificate; + httpsOption.ClientCertificateValidation = (inCertificate, inChain, inPolicy) => {return true;}; + httpsOption.CheckCertificateRevocation = false; + httpsOption.ServerCertificate = certificate; + listenOptions.UseHttps(httpsOption); + }); }) .Build(); } diff --git a/test/tools/WebListener/README.md b/test/tools/WebListener/README.md index 04dbd20ccb5..bc9b623c68b 100644 --- a/test/tools/WebListener/README.md +++ b/test/tools/WebListener/README.md @@ -8,10 +8,10 @@ ASP.NET Core 2.0 app for testing HTTP and HTTPS Requests. dotnet restore dotnet publish --output bin --configuration Release cd bin -dotnet WebListener.dll ServerCert.pfx password 8083 8084 +dotnet WebListener.dll ServerCert.pfx password 8083 8084 8085 8086 ``` -The test site can then be accessed via `http://localhost:8083/` or `https://localhost:8084/`. +The test site can then be accessed via `http://localhost:8083/`, `https://localhost:8084/`, `https://localhost:8085/`, or `https://localhost:8086/`. The `WebListener.dll` takes 4 arguments: @@ -25,7 +25,7 @@ The `WebListener.dll` takes 4 arguments: ```powershell Import-Module .\build.psm1 Publish-PSTestTools -$Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084 +$Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084 -Tls11Port 8085 -TlsPort = 8086 ``` # Tests From e95b81f8ea9ce2ab389bd540133285d110188bfe Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Fri, 3 Nov 2017 15:45:04 -0500 Subject: [PATCH 02/10] [Feature] Re-run CI From b69e4efa34aefdd53f1f7f2fcf80e9019d91d183 Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Wed, 8 Nov 2017 15:55:16 -0600 Subject: [PATCH 03/10] [Feature] Address PR Feedback --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 ++ .../utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs | 3 +-- test/tools/Modules/WebListener/README.md | 2 +- test/tools/WebListener/README.md | 6 ++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 5e02b458e62..a79e40f492c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -47,6 +47,8 @@ public enum WebAuthenticationType OAuth, } + // WebSslProtocol is used because not all SslProtocols are supported by HttpClientHandler. + // Also SslProtocols.Default is not the "default" for HttpClientHandler as SslProtocols.Ssl3 is not supported. /// /// The valid values for the -SslProtocol parameter for Invoke-RestMethod and Invoke-WebRequest /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs index ca5d7ab7f57..dfb51f9a194 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs @@ -193,8 +193,7 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) } } - // Set The SslProtocol. WebSslProtocol is used because not all SslProtocols are supported by HttpClientHandler. - // Also SslProtocols.Default is not the "default" for HttpClientHandler as SslProtocols.Ssl3 is not supported. + // Set The SslProtocol. handler.SslProtocols = (SslProtocols)SslProtocol; diff --git a/test/tools/Modules/WebListener/README.md b/test/tools/Modules/WebListener/README.md index ba2b5759b4a..dd6780b488d 100644 --- a/test/tools/Modules/WebListener/README.md +++ b/test/tools/Modules/WebListener/README.md @@ -1,6 +1,6 @@ # WebListener Module -A PowerShell module for managing the WebListener App. The included SelF-Signed Certificate `ServerCert.pfx` has the password set to `password` and is issued for the Client and Server Authentication key usages. This certificate is used by the WebListener App for SSL/TLS. The included SelF-Signed Certificate `ClientCert.pfx` has the password set to `password` and has not been issued for any specific key usage. This Certificate is used for Client Certificate Authentication with the WebListener App. +A PowerShell module for managing the WebListener App. The included SelF-Signed Certificate `ServerCert.pfx` has the password set to `password` and is issued for the Client and Server Authentication key usages. This certificate is used by the WebListener App for SSL/TLS. The included SelF-Signed Certificate `ClientCert.pfx` has the password set to `password` and has not been issued for any specific key usage. This Certificate is used for Client Certificate Authentication with the WebListener App. The port used for `-HttpsPort` will use TLS 2.0. # Running WebListener diff --git a/test/tools/WebListener/README.md b/test/tools/WebListener/README.md index bc9b623c68b..2d5755496d2 100644 --- a/test/tools/WebListener/README.md +++ b/test/tools/WebListener/README.md @@ -13,12 +13,14 @@ dotnet WebListener.dll ServerCert.pfx password 8083 8084 8085 8086 The test site can then be accessed via `http://localhost:8083/`, `https://localhost:8084/`, `https://localhost:8085/`, or `https://localhost:8086/`. -The `WebListener.dll` takes 4 arguments: +The `WebListener.dll` takes 6 arguments: * The path to the Server Certificate * The Server Certificate Password * The TCP Port to bind on for HTTP -* The TCP Port to bind on for HTTPS +* The TCP Port to bind on for HTTPS using TLS 2.0 +* The TCP Port to bind on for HTTPS using TLS 1.1 +* The TCP Port to bind on for HTTPS using TLS 1.0 # Run With WebListener Module From f8492cc7aa746b00ef75bfbaea194e71cef81ad6 Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Thu, 9 Nov 2017 04:08:02 -0600 Subject: [PATCH 04/10] [Feature] Address PR Feedback --- test/tools/Modules/WebListener/WebListener.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/test/tools/Modules/WebListener/WebListener.psm1 b/test/tools/Modules/WebListener/WebListener.psm1 index 2b09bef5d9b..6f003e69694 100644 --- a/test/tools/Modules/WebListener/WebListener.psm1 +++ b/test/tools/Modules/WebListener/WebListener.psm1 @@ -161,6 +161,7 @@ function Get-WebListenerUrl { { 'Tls11' { $Uri.Port = $runningListener.Tls11Port } 'Tls' { $Uri.Port = $runningListener.TlsPort } + # The base HTTPs port is configured for Tls2 only default { $Uri.Port = $runningListener.HttpsPort } } $Uri.Scheme = 'Https' From 8a0c0c0b0c8c4eff1cd58487a93d3f0938b2689b Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Thu, 9 Nov 2017 05:05:46 -0600 Subject: [PATCH 05/10] Address PR feedback * TLSO 2.0 -> TLS 1.2 * remove onbvious comment --- .../utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs | 1 - test/tools/Modules/WebListener/README.md | 2 +- test/tools/Modules/WebListener/WebListener.psm1 | 2 +- test/tools/WebListener/README.md | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs index dfb51f9a194..630f66804c6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs @@ -193,7 +193,6 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) } } - // Set The SslProtocol. handler.SslProtocols = (SslProtocols)SslProtocol; diff --git a/test/tools/Modules/WebListener/README.md b/test/tools/Modules/WebListener/README.md index dd6780b488d..0bb257d8f09 100644 --- a/test/tools/Modules/WebListener/README.md +++ b/test/tools/Modules/WebListener/README.md @@ -1,6 +1,6 @@ # WebListener Module -A PowerShell module for managing the WebListener App. The included SelF-Signed Certificate `ServerCert.pfx` has the password set to `password` and is issued for the Client and Server Authentication key usages. This certificate is used by the WebListener App for SSL/TLS. The included SelF-Signed Certificate `ClientCert.pfx` has the password set to `password` and has not been issued for any specific key usage. This Certificate is used for Client Certificate Authentication with the WebListener App. The port used for `-HttpsPort` will use TLS 2.0. +A PowerShell module for managing the WebListener App. The included SelF-Signed Certificate `ServerCert.pfx` has the password set to `password` and is issued for the Client and Server Authentication key usages. This certificate is used by the WebListener App for SSL/TLS. The included SelF-Signed Certificate `ClientCert.pfx` has the password set to `password` and has not been issued for any specific key usage. This Certificate is used for Client Certificate Authentication with the WebListener App. The port used for `-HttpsPort` will use TLS 1.2. # Running WebListener diff --git a/test/tools/Modules/WebListener/WebListener.psm1 b/test/tools/Modules/WebListener/WebListener.psm1 index 6f003e69694..1e4ea444bf2 100644 --- a/test/tools/Modules/WebListener/WebListener.psm1 +++ b/test/tools/Modules/WebListener/WebListener.psm1 @@ -161,7 +161,7 @@ function Get-WebListenerUrl { { 'Tls11' { $Uri.Port = $runningListener.Tls11Port } 'Tls' { $Uri.Port = $runningListener.TlsPort } - # The base HTTPs port is configured for Tls2 only + # The base HTTPs port is configured for Tls12 only default { $Uri.Port = $runningListener.HttpsPort } } $Uri.Scheme = 'Https' diff --git a/test/tools/WebListener/README.md b/test/tools/WebListener/README.md index 2d5755496d2..2a26200b826 100644 --- a/test/tools/WebListener/README.md +++ b/test/tools/WebListener/README.md @@ -18,7 +18,7 @@ The `WebListener.dll` takes 6 arguments: * The path to the Server Certificate * The Server Certificate Password * The TCP Port to bind on for HTTP -* The TCP Port to bind on for HTTPS using TLS 2.0 +* The TCP Port to bind on for HTTPS using TLS 1.2 * The TCP Port to bind on for HTTPS using TLS 1.1 * The TCP Port to bind on for HTTPS using TLS 1.0 From 2f5c3117db9f9ee2f2114a71849dcc6ae11f74b0 Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Fri, 10 Nov 2017 12:11:12 -0600 Subject: [PATCH 06/10] [Feature] Add Multi-protocol selection tests --- .../WebCmdlets.Tests.ps1 | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index b87bef22cfd..a542d732644 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -1415,15 +1415,25 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { } Context "Invoke-WebRequest -SslProtocol Test" { - It "Verifies Invoke-WebRequest -SslProtocol " -TestCases @( - @{SslProtocol = 'Default'} - @{SslProtocol = 'Tls'} - @{SslProtocol = 'Tls11'} - @{SslProtocol = 'Tls12'} + It "Verifies Invoke-WebRequest -SslProtocol works on " -TestCases @( + @{SslProtocol = 'Default'; ActualProtocol = 'Default'} + @{SslProtocol = 'Tls'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + ) { - param($SslProtocol) + param($SslProtocol, $ActualProtocol) $params = @{ - Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $SslProtocol + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $ActualProtocol SslProtocol = $SslProtocol SkipCertificateCheck = $true } @@ -1440,6 +1450,9 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} ) { param( $IntendedProtocol, $ActualProtocol) $params = @{ @@ -1450,6 +1463,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { } { Invoke-WebRequest @params } | ShouldBeErrorId 'WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand' } + } BeforeEach { @@ -2371,15 +2385,25 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { } Context "Invoke-RestMethod -SslProtocol Test" { - It "Verifies Invoke-RestMethod -SslProtocol " -TestCases @( - @{SslProtocol = 'Default'} - @{SslProtocol = 'Tls'} - @{SslProtocol = 'Tls11'} - @{SslProtocol = 'Tls12'} + It "Verifies Invoke-RestMethod -SslProtocol works on " -TestCases @( + @{SslProtocol = 'Default'; ActualProtocol = 'Default'} + @{SslProtocol = 'Tls'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + ) { - param($SslProtocol) + param($SslProtocol, $ActualProtocol) $params = @{ - Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $SslProtocol + Uri = Get-WebListenerUrl -Test 'Get' -Https -SslProtocol $ActualProtocol SslProtocol = $SslProtocol SkipCertificateCheck = $true } @@ -2394,7 +2418,10 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls12'} @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} - @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} ) { param( $IntendedProtocol, $ActualProtocol) $params = @{ @@ -2405,6 +2432,8 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { } { Invoke-RestMethod @params } | ShouldBeErrorId 'WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand' } + + } BeforeEach { From 796569e47439485c70681dd7016f7a5e74ef498a Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Fri, 10 Nov 2017 14:37:01 -0600 Subject: [PATCH 07/10] [Feature] Disable multi-protocol test on macOS --- .../WebCmdlets.Tests.ps1 | 68 +++++++++++-------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index a542d732644..a2d8f4364d8 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -1420,16 +1420,19 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { @{SslProtocol = 'Tls'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} - + # macOS does not support multiple SslProtocols + if (-not $IsMacOS) + { + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + } ) { param($SslProtocol, $ActualProtocol) $params = @{ @@ -1450,9 +1453,13 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} - @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} - @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} - @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} + # macOS does not support multiple SslProtocols + if (-not $IsMacOS) + { + @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} + } ) { param( $IntendedProtocol, $ActualProtocol) $params = @{ @@ -2390,16 +2397,19 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { @{SslProtocol = 'Tls'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} - @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} - + # macOS does not support multiple SslProtocols + if (-not $IsMacOS) + { + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} + @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + } ) { param($SslProtocol, $ActualProtocol) $params = @{ @@ -2418,10 +2428,14 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls12'} @{IntendedProtocol = 'Tls11'; ActualProtocol = 'Tls'} @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls'} - @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} - @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} - @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} - @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} + @{IntendedProtocol = 'Tls12'; ActualProtocol = 'Tls11'} + # macOS does not support multiple SslProtocols + if (-not $IsMacOS) + { + @{IntendedProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls'} + @{IntendedProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls11'} + @{IntendedProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls12'} + } ) { param( $IntendedProtocol, $ActualProtocol) $params = @{ From 3228acf1d827abde522902b938d37759e6dcb7ca Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Fri, 10 Nov 2017 17:43:47 -0600 Subject: [PATCH 08/10] [Feature] Run 'Tls, Tls12' test only on Windows Possible CoreFX bug where `Tls, Tls12` does not honor the Tls12 on a Tls12 endpoint. --- .../WebCmdlets.Tests.ps1 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index a2d8f4364d8..e2812d1227f 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -1430,9 +1430,13 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} } + # macOS does not support multiple SslProtocols and possible CoreFX for this combo on Linux + if($IsWindows) + { + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + } ) { param($SslProtocol, $ActualProtocol) $params = @{ @@ -2407,9 +2411,13 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} } + # macOS does not support multiple SslProtocols and possible CoreFX for this combo on Linux + if($IsWindows) + { + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + } ) { param($SslProtocol, $ActualProtocol) $params = @{ From b4ed8e5c8fb4ce5769328d2861effdcdacda1df5 Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Sat, 11 Nov 2017 10:03:34 -0600 Subject: [PATCH 09/10] [Feature] Rerun CI From e06419618cbfbc23d2c38a21c89c8a87fb51cc4e Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Sat, 11 Nov 2017 11:05:13 -0600 Subject: [PATCH 10/10] [Feature] Move correct test to be skipped --- .../Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index e2812d1227f..fa5b15e8c24 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -1425,17 +1425,18 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { { @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} } # macOS does not support multiple SslProtocols and possible CoreFX for this combo on Linux if($IsWindows) { - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} } ) { param($SslProtocol, $ActualProtocol) @@ -2406,17 +2407,17 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { { @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls12'} @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls12'} - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls11, Tls12'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls11'} @{SslProtocol = 'Tls, Tls11, Tls12'; ActualProtocol = 'Tls'} @{SslProtocol = 'Tls, Tls11'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} } # macOS does not support multiple SslProtocols and possible CoreFX for this combo on Linux if($IsWindows) { - @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls'} + @{SslProtocol = 'Tls, Tls12'; ActualProtocol = 'Tls12'} } ) { param($SslProtocol, $ActualProtocol)