Skip to content

Commit 8b77c49

Browse files
Fix | Exclude unsupported protocols (#1168)
1 parent dab5ca0 commit 8b77c49

File tree

10 files changed

+50
-22
lines changed

10 files changed

+50
-22
lines changed

BUILDGUIDE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ To use this feature, you must enable the following AppContext switch at applicat
257257

258258
**"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"**
259259

260+
## Enabling OS secure protocols preference
261+
262+
TLS 1.3 has been excluded due to the fact that the driver lacks full support. To enable OS preferences as before, enable the following AppContext switch on application startup:
263+
264+
**"Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS"**
265+
260266
## Debugging SqlClient on Linux from Windows
261267

262268
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.

src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ internal struct SNI_Error
264264
private static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum);
265265

266266
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl)]
267-
private static extern uint SNIInitialize([In] IntPtr pmo);
267+
private static extern uint SNIInitialize([In] bool useSystemDefaultSecureProtocols, [In] IntPtr pmo);
268268

269269
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl)]
270270
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
340340

341341
internal static uint SNIInitialize()
342342
{
343-
return SNIInitialize(IntPtr.Zero);
343+
return SNIInitialize(LocalAppContextSwitches.UseSystemDefaultSecureProtocols, IntPtr.Zero);
344344
}
345345

346346
internal static unsafe uint SNIOpenMarsSession(ConsumerInfo consumerInfo, SNIHandle parent, ref IntPtr pConn, bool fSync, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo)

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIHandle.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Security.Authentication;
67

78
namespace Microsoft.Data.SqlClient.SNI
89
{
@@ -11,6 +12,16 @@ namespace Microsoft.Data.SqlClient.SNI
1112
/// </summary>
1213
internal abstract class SNIHandle
1314
{
15+
/// <summary>
16+
/// Exclude TLS 1.3 (not fully supported).
17+
/// </summary>
18+
protected readonly SslProtocols SupportedProtocols = LocalAppContextSwitches.UseSystemDefaultSecureProtocols ? SslProtocols.None : SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
19+
//protected readonly SslProtocols SupportedProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
20+
#pragma warning disable CS0618 // Type or member is obsolete
21+
| SslProtocols.Ssl2 | SslProtocols.Ssl3
22+
#pragma warning restore CS0618 // Type or member is obsolete
23+
;
24+
1425
/// <summary>
1526
/// Dispose class
1627
/// </summary>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,7 @@ public override uint EnableSsl(uint options)
312312
_validateCert = (options & TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE) != 0;
313313
try
314314
{
315-
316-
_sslStream.AuthenticateAsClient(_targetServer);
315+
_sslStream.AuthenticateAsClient(_targetServer, null, SupportedProtocols, true);
317316
_sslOverTdsStream.FinishHandshake();
318317
}
319318
catch (AuthenticationException aue)

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ public override uint EnableSsl(uint options)
582582

583583
try
584584
{
585-
_sslStream.AuthenticateAsClient(_targetServer);
585+
_sslStream.AuthenticateAsClient(_targetServer, null, SupportedProtocols, true);
586586
_sslOverTdsStream.FinishHandshake();
587587
}
588588
catch (AuthenticationException aue)

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,10 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
421421
protocolVersion = (int)SslProtocols.Ssl2;
422422
#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated
423423
}
424-
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE))
424+
else //if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE))
425425
{
426426
protocolVersion = (int)SslProtocols.None;
427427
}
428-
else
429-
{
430-
throw new ArgumentException(StringsHelper.Format(StringsHelper.net_invalid_enum, nameof(NativeProtocols)), nameof(NativeProtocols));
431-
}
432428
return returnValue;
433429
}
434430

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal static class SNINativeManagedWrapperX64
8989
internal static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum);
9090

9191
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIInitialize")]
92-
internal static extern uint SNIInitialize([In] IntPtr pmo);
92+
internal static extern uint SNIInitialize([In] bool useSystemDefaultSecureProtocols, [In] IntPtr pmo);
9393

9494
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl)]
9595
internal static extern uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn);

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal static class SNINativeManagedWrapperX86
8989
internal static extern uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapper.QTypes QType, out ProviderEnum provNum);
9090

9191
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIInitialize")]
92-
internal static extern uint SNIInitialize([In] IntPtr pmo);
92+
internal static extern uint SNIInitialize([In] bool useSystemDefaultSecureProtocols, [In] IntPtr pmo);
9393

9494
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl)]
9595
internal static extern uint SNIOpenSyncExWrapper(ref SNI_CLIENT_CONSUMER_INFO pClientConsumerInfo, out IntPtr ppConn);

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,11 +585,11 @@ private static uint SNIGetInfoWrapper([In] SNIHandle pConn, SNINativeMethodWrapp
585585
SNINativeManagedWrapperX86.SNIGetInfoWrapper(pConn, QType, out provNum);
586586
}
587587

588-
private static uint SNIInitialize([In] IntPtr pmo)
588+
private static uint SNIInitialize([In] bool useSystemDefaultSecureProtocols, [In] IntPtr pmo)
589589
{
590590
return s_is64bitProcess ?
591-
SNINativeManagedWrapperX64.SNIInitialize(pmo) :
592-
SNINativeManagedWrapperX86.SNIInitialize(pmo);
591+
SNINativeManagedWrapperX64.SNIInitialize(useSystemDefaultSecureProtocols, pmo) :
592+
SNINativeManagedWrapperX86.SNIInitialize(useSystemDefaultSecureProtocols, pmo);
593593
}
594594

595595
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
757757

758758
internal static uint SNIInitialize()
759759
{
760-
return SNIInitialize(IntPtr.Zero);
760+
return SNIInitialize(LocalAppContextSwitches.UseSystemDefaultSecureProtocols, IntPtr.Zero);
761761
}
762762

763763
internal static unsafe uint SNIOpenMarsSession(ConsumerInfo consumerInfo, SNIHandle parent, ref IntPtr pConn, bool fSync, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo)

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ internal static partial class LocalAppContextSwitches
1313
private const string TypeName = nameof(LocalAppContextSwitches);
1414
internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking";
1515
internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior";
16+
internal const string UseSystemDefaultSecureProtocolsString = @"Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols";
1617
// safety switch
1718
internal const string EnableRetryLogicSwitch = "Switch.Microsoft.Data.SqlClient.EnableRetryLogic";
1819

1920
private static bool _makeReadAsyncBlocking;
2021
private static bool? s_LegacyRowVersionNullBehavior;
22+
private static bool? s_UseSystemDefaultSecureProtocols;
2123
private static bool? s_isRetryEnabled = null;
2224

2325
#if !NETFRAMEWORK
@@ -70,15 +72,29 @@ public static bool LegacyRowVersionNullBehavior
7072
{
7173
if (s_LegacyRowVersionNullBehavior is null)
7274
{
73-
bool value = false;
74-
if (AppContext.TryGetSwitch(LegacyRowVersionNullString, out bool providedValue))
75-
{
76-
value = providedValue;
77-
}
78-
s_LegacyRowVersionNullBehavior = value;
75+
bool result;
76+
result = AppContext.TryGetSwitch(LegacyRowVersionNullString, out result) ? result : false;
77+
s_LegacyRowVersionNullBehavior = result;
7978
}
8079
return s_LegacyRowVersionNullBehavior.Value;
8180
}
8281
}
82+
83+
/// <summary>
84+
/// For backward compatibility, this switch can be on to jump back on OS preferences.
85+
/// </summary>
86+
public static bool UseSystemDefaultSecureProtocols
87+
{
88+
get
89+
{
90+
if (s_UseSystemDefaultSecureProtocols is null)
91+
{
92+
bool result;
93+
result = AppContext.TryGetSwitch(UseSystemDefaultSecureProtocolsString, out result) ? result : false;
94+
s_UseSystemDefaultSecureProtocols = result;
95+
}
96+
return s_UseSystemDefaultSecureProtocols.Value;
97+
}
98+
}
8399
}
84100
}

0 commit comments

Comments
 (0)