From 53cc74f7327a7b8e1449bc28cd46d501991cd0c5 Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Wed, 28 Jul 2021 13:17:10 -0700 Subject: [PATCH] Add support the switch --- BUILDGUIDE.md | 6 ++++ .../Interop/SNINativeMethodWrapper.Windows.cs | 4 +-- .../Microsoft/Data/SqlClient/SNI/SNIHandle.cs | 3 +- .../Interop/SNINativeManagedWrapperX64.cs | 2 +- .../Interop/SNINativeManagedWrapperX86.cs | 2 +- .../Data/Interop/SNINativeMethodWrapper.cs | 8 +++--- .../Data/SqlClient/LocalAppContextSwitches.cs | 28 +++++++++++++++---- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index cc9a60e538..818b1964fe 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -257,6 +257,12 @@ To use this feature, you must enable the following AppContext switch at applicat **"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"** +## Enabling OS secure protocols preference + +Tls 1.3 has been taken out in view of the fact that the driver lacks full support. To jump back on the OS preferences as same as earlier, you must enable the following AppContext switch on application's startup: + +**"Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS"** + ## 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/Interop/SNINativeMethodWrapper.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs index 20159ca382..7a2050fe09 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs @@ -264,7 +264,7 @@ internal struct SNI_Error private static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] - private static extern uint SNIInitialize([In] IntPtr pmo); + private static extern uint SNIInitialize([In] bool enableSecureProtocolsByOS, [In] IntPtr pmo); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] private static extern uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn); @@ -340,7 +340,7 @@ internal static uint SniGetConnectionIPString(SNIHandle pConn, ref string connIP internal static uint SNIInitialize() { - return SNIInitialize(IntPtr.Zero); + return SNIInitialize(LocalAppContextSwitches.EnableSecureProtocolsByOS, IntPtr.Zero); } internal static unsafe uint SNIOpenMarsSession(ConsumerInfo consumerInfo, SNIHandle parent, ref IntPtr pConn, bool fSync, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs index 972ac7aee3..6a60c3f436 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs @@ -15,7 +15,8 @@ internal abstract class SNIHandle /// /// Exclude Tls 1.3 (not fully supported). /// - protected readonly SslProtocols SupportedProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls + protected readonly SslProtocols SupportedProtocols = LocalAppContextSwitches.EnableSecureProtocolsByOS ? SslProtocols.None : SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls + //protected readonly SslProtocols SupportedProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls #pragma warning disable CS0618 // Type or member is obsolete | SslProtocols.Ssl2 | SslProtocols.Ssl3 #pragma warning restore CS0618 // Type or member is obsolete diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs index b28c736977..f389e479a0 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs @@ -89,7 +89,7 @@ internal static class SNINativeManagedWrapperX64 internal static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIInitialize")] - internal static extern uint SNIInitialize([In] IntPtr pmo); + internal static extern uint SNIInitialize([In] bool enableSecureProtocolsByOS, [In] IntPtr pmo); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] internal static extern uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs index 2dc215ad36..0132dc04e1 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs @@ -89,7 +89,7 @@ internal static class SNINativeManagedWrapperX86 internal static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIInitialize")] - internal static extern uint SNIInitialize([In] IntPtr pmo); + internal static extern uint SNIInitialize([In] bool enableSecureProtocolsByOS, [In] IntPtr pmo); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] internal static extern uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs index 19dd12587a..2b38c52844 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs @@ -585,11 +585,11 @@ private static uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapp SNINativeManagedWrapperX86.SNIGetInfoWrapper(pConn, QType, out provNum); } - private static uint SNIInitialize([In] IntPtr pmo) + private static uint SNIInitialize([In] bool enableSecureProtocolsByOS, [In] IntPtr pmo) { return s_is64bitProcess ? - SNINativeManagedWrapperX64.SNIInitialize(pmo) : - SNINativeManagedWrapperX86.SNIInitialize(pmo); + SNINativeManagedWrapperX64.SNIInitialize(enableSecureProtocolsByOS, pmo) : + SNINativeManagedWrapperX86.SNIInitialize(enableSecureProtocolsByOS, pmo); } private static uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn) @@ -757,7 +757,7 @@ internal static uint SniGetConnectionIPString(SNIHandle pConn, ref string connIP internal static uint SNIInitialize() { - return SNIInitialize(IntPtr.Zero); + return SNIInitialize(LocalAppContextSwitches.EnableSecureProtocolsByOS, IntPtr.Zero); } internal static unsafe uint SNIOpenMarsSession(ConsumerInfo consumerInfo, SNIHandle parent, ref IntPtr pConn, bool fSync, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) 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 9d2111ac24..e6f7030b4e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -13,11 +13,13 @@ internal static partial class LocalAppContextSwitches private const string TypeName = nameof(LocalAppContextSwitches); internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking"; internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"; + internal const string EnableSecureProtocolsByOSString = @"Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS"; // safety switch internal const string EnableRetryLogicSwitch = "Switch.Microsoft.Data.SqlClient.EnableRetryLogic"; private static bool _makeReadAsyncBlocking; private static bool? s_LegacyRowVersionNullBehavior; + private static bool? s_EnableSecureProtocolsByOS; private static bool? s_isRetryEnabled = null; #if !NETFRAMEWORK @@ -70,15 +72,29 @@ public static bool LegacyRowVersionNullBehavior { if (s_LegacyRowVersionNullBehavior is null) { - bool value = false; - if (AppContext.TryGetSwitch(LegacyRowVersionNullString, out bool providedValue)) - { - value = providedValue; - } - s_LegacyRowVersionNullBehavior = value; + bool result; + result = AppContext.TryGetSwitch(LegacyRowVersionNullString, out result) ? result : false; + s_LegacyRowVersionNullBehavior = result; } return s_LegacyRowVersionNullBehavior.Value; } } + + /// + /// For backward compatibility, this switch can be on to jump back on OS preferences. + /// + public static bool EnableSecureProtocolsByOS + { + get + { + if (s_EnableSecureProtocolsByOS is null) + { + bool result; + result = AppContext.TryGetSwitch(EnableSecureProtocolsByOSString, out result) ? result : false; + s_EnableSecureProtocolsByOS = result; + } + return s_EnableSecureProtocolsByOS.Value; + } + } } }