From 5ec7bacdfea4e44217d2fc29d6b31ebfa83e8e07 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Tue, 29 May 2018 16:27:16 -0700 Subject: [PATCH] Lower severity of AuthenticationException logs from SslStream handshake (#2614) --- .../Internal/HttpsConnectionAdapter.cs | 3 +- test/Kestrel.FunctionalTests/HttpsTests.cs | 58 +++++++++++++------ test/Kestrel.FunctionalTests/RequestTests.cs | 2 +- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs b/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs index 301c9c7a23..95ee435b43 100644 --- a/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs +++ b/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Net.Security; +using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -186,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal sslStream.Dispose(); return _closedAdaptedConnection; } - catch (IOException ex) + catch (Exception ex) when (ex is IOException || ex is AuthenticationException) { _logger?.LogDebug(1, ex, CoreStrings.AuthenticationFailed); sslStream.Dispose(); diff --git a/test/Kestrel.FunctionalTests/HttpsTests.cs b/test/Kestrel.FunctionalTests/HttpsTests.cs index 30ae3470ed..be9e9fe623 100644 --- a/test/Kestrel.FunctionalTests/HttpsTests.cs +++ b/test/Kestrel.FunctionalTests/HttpsTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Security; using System.Net.Sockets; @@ -235,15 +236,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"); await sslStream.WriteAsync(request, 0, request.Length); - // Temporary workaround for a deadlock when reading from an aborted client SslStream on Mac and Linux. - if (TestPlatformHelper.IsWindows) - { - await sslStream.ReadAsync(new byte[32], 0, 32); - } - else - { - await stream.ReadAsync(new byte[32], 0, 32); - } + await sslStream.ReadAsync(new byte[32], 0, 32); } } @@ -295,15 +288,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"); await sslStream.WriteAsync(request, 0, request.Length); - // Temporary workaround for a deadlock when reading from an aborted client SslStream on Mac and Linux. - if (TestPlatformHelper.IsWindows) - { - await sslStream.ReadAsync(new byte[32], 0, 32); - } - else - { - await stream.ReadAsync(new byte[32], 0, 32); - } + await sslStream.ReadAsync(new byte[32], 0, 32); } } @@ -415,6 +400,43 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel); } + [Fact] + public async Task ClientAttemptingToUseUnsupportedProtocolIsLoggedAsDebug() + { + var loggerProvider = new HandshakeErrorLoggerProvider(); + LoggerFactory.AddProvider(loggerProvider); + var hostBuilder = TransportSelector.GetWebHostBuilder() + .UseKestrel(options => + { + options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions => + { + listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + }); + }) + .ConfigureServices(AddTestLogging) + .Configure(app => app.Run(httpContext => Task.CompletedTask)); + + using (var host = hostBuilder.Build()) + { + host.Start(); + + using (var socket = await HttpClientSlim.GetSocket(new Uri($"https://127.0.0.1:{host.GetPort()}/"))) + using (var stream = new NetworkStream(socket, ownsSocket: false)) + using (var sslStream = new SslStream(stream, true, (sender, certificate, chain, errors) => true)) + { + // SslProtocols.Tls is TLS 1.0 which isn't supported by Kestrel by default. + await Assert.ThrowsAsync(() => + sslStream.AuthenticateAsClientAsync("127.0.0.1", clientCertificates: null, + enabledSslProtocols: SslProtocols.Tls, + checkCertificateRevocation: false)); + } + } + + await loggerProvider.FilterLogger.LogTcs.Task.TimeoutAfter(TestConstants.DefaultTimeout); + Assert.Equal(1, loggerProvider.FilterLogger.LastEventId); + Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel); + } + private class HandshakeErrorLoggerProvider : ILoggerProvider { public HttpsConnectionFilterLogger FilterLogger { get; } = new HttpsConnectionFilterLogger(); diff --git a/test/Kestrel.FunctionalTests/RequestTests.cs b/test/Kestrel.FunctionalTests/RequestTests.cs index 7d01075fc4..d8d78fd6d8 100644 --- a/test/Kestrel.FunctionalTests/RequestTests.cs +++ b/test/Kestrel.FunctionalTests/RequestTests.cs @@ -1266,7 +1266,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } }; - var scratchBuffer = new byte[maxRequestBufferSize * 2 + 1]; + var scratchBuffer = new byte[maxRequestBufferSize * 8]; using (var server = new TestServer(async context => {