diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 7335c61cda..dcb2257745 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -319,6 +319,12 @@ TLS 1.3 has been excluded due to the fact that the driver lacks full support. To `Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS` +## Suppressing TLS security warning + +When connecting to a server, if a protocol lower than TLS 1.2 is negotiated, a security warning is output to the console. This warning can be suppressed on SQL connections with `Encrypt = false` by enabling the following AppContext switch on application startup: + +`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning` + ## Debugging SqlClient on Linux from Windows For enhanced developer experience, we support debugging SqlClient on Linux from Windows, using the project "**Microsoft.Data.SqlClient.DockerLinuxTest**" that requires "Container Tools" to be enabled in Visual Studio. You may import configuration: [VS19Components.vsconfig](./tools/vsconfig/VS19Components.vsconfig) if not enabled already. diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index aae80fc871..6b77e98c2e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -10,7 +10,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; -using System.Reflection; using System.Security.Authentication; using System.Text; using System.Threading; @@ -960,8 +959,16 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus string warningMessage = protocol.GetProtocolWarning(); if (!string.IsNullOrEmpty(warningMessage)) { - // This logs console warning of insecure protocol in use. - _logger.LogWarning(GetType().Name, MethodBase.GetCurrentMethod().Name, warningMessage); + if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning) + { + // Skip console warning + SqlClientEventSource.Log.TryTraceEvent("{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage); + } + else + { + // This logs console warning of insecure protocol in use. + _logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage); + } } // create a new packet encryption changes the internal packet size diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 46900770b9..f0e2512372 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -9,7 +9,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; -using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -1339,8 +1338,16 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod string warningMessage = SslProtocolsHelper.GetProtocolWarning(protocolVersion); if (!string.IsNullOrEmpty(warningMessage)) { - // This logs console warning of insecure protocol in use. - _logger.LogWarning(GetType().Name, MethodBase.GetCurrentMethod().Name, warningMessage); + if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning) + { + // Skip console warning + SqlClientEventSource.Log.TryTraceEvent("{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage); + } + else + { + // This logs console warning of insecure protocol in use. + _logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage); + } } // Validate server certificate diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index c0d7295944..8e390b21d6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -14,10 +14,12 @@ internal static partial class LocalAppContextSwitches internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking"; internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"; internal const string UseSystemDefaultSecureProtocolsString = @"Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols"; + internal const string SuppressInsecureTLSWarningString = @"Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning"; - private static bool _makeReadAsyncBlocking; + private static bool s_makeReadAsyncBlocking; private static bool? s_LegacyRowVersionNullBehavior; private static bool? s_UseSystemDefaultSecureProtocols; + private static bool? s_SuppressInsecureTLSWarning; #if !NETFRAMEWORK static LocalAppContextSwitches() @@ -35,12 +37,26 @@ static LocalAppContextSwitches() } #endif + public static bool SuppressInsecureTLSWarning + { + get + { + if (s_SuppressInsecureTLSWarning is null) + { + bool result; + result = AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out result) ? result : false; + s_SuppressInsecureTLSWarning = result; + } + return s_SuppressInsecureTLSWarning.Value; + } + } + public static bool MakeReadAsyncBlocking { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out _makeReadAsyncBlocking) ? _makeReadAsyncBlocking : false; + return AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out s_makeReadAsyncBlocking) ? s_makeReadAsyncBlocking : false; } }