Skip to content

Merge | Remove OS-specific TdsParser files #3469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
#if NET
using System.Security.Authentication;
#else
#if NETFRAMEWORK
using System.Runtime.CompilerServices;
#endif
using System.Text;
Expand Down Expand Up @@ -646,7 +645,13 @@ internal void EnableMars()
ThrowExceptionAndWarning(_physicalStateObj);
}

PostReadAsyncForMars();
error = _pMarsPhysicalConObj.PostReadAsyncForMars(_physicalStateObj);
if (error != TdsEnums.SNI_SUCCESS_IO_PENDING)
{
Debug.Assert(error != TdsEnums.SNI_SUCCESS, "Unexpected successful read async on physical connection before enabling MARS!");
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
ThrowExceptionAndWarning(_physicalStateObj);
}

_physicalStateObj = CreateSession(); // Create and open default MARS stateObj and connection.
}
Expand Down Expand Up @@ -902,8 +907,23 @@ private void EnableSsl(uint info, SqlConnectionEncryptOption encrypt, bool integ
ThrowExceptionAndWarning(_physicalStateObj);
}

int protocolVersion = 0;
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
uint protocolVersion = 0;

// in the case where an async connection is made, encryption is used and Windows Authentication is used,
// wait for SSL handshake to complete, so that the SSL context is fully negotiated before we try to use its
// Channel Bindings as part of the Windows Authentication context build (SSL handshake must complete
// before calling SNISecGenClientContext).
#if NET
if (OperatingSystem.IsWindows())
#endif
{
error = _physicalStateObj.WaitForSSLHandShakeToComplete(out protocolVersion);
if (error != TdsEnums.SNI_SUCCESS)
{
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
ThrowExceptionAndWarning(_physicalStateObj);
}
}

SslProtocols protocol = (SslProtocols)protocolVersion;
string warningMessage = protocol.GetProtocolWarning();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ namespace Microsoft.Data.SqlClient
{
internal sealed partial class TdsParser
{
internal struct SNIErrorDetails
{
public string errorMessage;
public uint nativeError;
public uint sniErrorNumber;
public int provider;
public uint lineNumber;
public string function;
public Exception exception;
}

internal static void FillGuidBytes(Guid guid, Span<byte> buffer) => guid.TryWriteBytes(buffer);

internal static void FillDoubleBytes(double value, Span<byte> buffer) => BinaryPrimitives.TryWriteInt64LittleEndian(buffer, BitConverter.DoubleToInt64Bits(value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ internal abstract void CreatePhysicalSNIHandle(

internal abstract uint EnableSsl(ref uint info, bool tlsFirst, string serverCertificateFilename);

internal abstract uint WaitForSSLHandShakeToComplete(out int protocolVersion);

internal abstract void Dispose();

internal abstract uint CheckConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ internal override uint EnableMars(ref uint info)
return TdsEnums.SNI_ERROR;
}

internal override uint PostReadAsyncForMars(TdsParserStateObject physicalStateObject) => TdsEnums.SNI_SUCCESS_IO_PENDING;

internal override uint EnableSsl(ref uint info, bool tlsFirst, string serverCertificateFilename)
{
SniHandle sessionHandle = GetSessionSNIHandleHandleOrThrow();
Expand All @@ -386,10 +388,10 @@ internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize)
return TdsEnums.SNI_SUCCESS;
}

internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
internal override uint WaitForSSLHandShakeToComplete(out uint protocolVersion)
{
protocolVersion = GetSessionSNIHandleHandleOrThrow().ProtocolVersion;
return 0;
protocolVersion = (uint)GetSessionSNIHandleHandleOrThrow().ProtocolVersion;
return TdsEnums.SNI_SUCCESS;
}

internal override SniErrorDetails GetErrorDetails()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,43 @@ internal override uint DisableSsl()
internal override uint EnableMars(ref uint info)
=> SniNativeWrapper.SniAddProvider(Handle, Provider.SMUX_PROV, ref info);

internal override uint PostReadAsyncForMars(TdsParserStateObject physicalStateObject)
{
// HACK HACK HACK - for Async only
// Have to post read to initialize MARS - will get callback on this when connection goes
// down or is closed.

PacketHandle temp = default;
uint error = TdsEnums.SNI_SUCCESS;

#if NETFRAMEWORK
RuntimeHelpers.PrepareConstrainedRegions();
#endif
try
{ }
finally
{
IncrementPendingCallbacks();
SessionHandle handle = SessionHandle;
// we do not need to consider partial packets when making this read because we
// expect this read to pend. a partial packet should not exist at setup of the
// parser
Debug.Assert(physicalStateObject.PartialPacket == null);
temp = ReadAsync(handle, out error);

Debug.Assert(temp.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");

if (temp.NativePointer != IntPtr.Zero)
{
// Be sure to release packet, otherwise it will be leaked by native.
ReleasePacket(temp);
}
}

Debug.Assert(IntPtr.Zero == temp.NativePointer, "unexpected syncReadPacket without corresponding SNIPacketRelease");
return error;
}

internal override uint EnableSsl(ref uint info, bool tlsFirst, string serverCertificateFilename)
{
AuthProviderInfo authInfo = new AuthProviderInfo();
Expand All @@ -399,43 +436,43 @@ internal override uint EnableSsl(ref uint info, bool tlsFirst, string serverCert
internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize)
=> SniNativeWrapper.SniSetInfo(Handle, QueryType.SNI_QUERY_CONN_BUFSIZE, ref unsignedPacketSize);

internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion)
internal override uint WaitForSSLHandShakeToComplete(out uint protocolVersion)
{
uint returnValue = SniNativeWrapper.SniWaitForSslHandshakeToComplete(Handle, GetTimeoutRemaining(), out uint nativeProtocolVersion);
var nativeProtocol = (NativeProtocols)nativeProtocolVersion;

#pragma warning disable CA5398 // Avoid hardcoded SslProtocols values
if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_2_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_2_SERVER))
{
protocolVersion = (int)SslProtocols.Tls12;
protocolVersion = (uint)SslProtocols.Tls12;
}
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_SERVER))
{
/* The SslProtocols.Tls13 is supported by netcoreapp3.1 and later */
protocolVersion = (int)SslProtocols.Tls13;
protocolVersion = (uint)SslProtocols.Tls13;
}
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_1_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_1_SERVER))
{
protocolVersion = (int)SslProtocols.Tls11;
protocolVersion = (uint)SslProtocols.Tls11;
}
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_0_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_0_SERVER))
{
protocolVersion = (int)SslProtocols.Tls;
protocolVersion = (uint)SslProtocols.Tls;
}
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_SERVER))
{
// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections
#pragma warning disable CS0618, CA5397
protocolVersion = (int)SslProtocols.Ssl3;
protocolVersion = (uint)SslProtocols.Ssl3;
}
else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_SERVER))
{
protocolVersion = (int)SslProtocols.Ssl2;
protocolVersion = (uint)SslProtocols.Ssl2;
#pragma warning restore CS0618, CA5397
}
else //if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE))
{
protocolVersion = (int)SslProtocols.None;
protocolVersion = (uint)SslProtocols.None;
}
#pragma warning restore CA5398 // Avoid hardcoded SslProtocols values
return returnValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
#if NET
using System.Security.Authentication;
#else
#if NETFRAMEWORK
using System.Runtime.CompilerServices;
#endif
using System.Text;
Expand Down Expand Up @@ -697,31 +696,10 @@ internal void EnableMars()
ThrowExceptionAndWarning(_physicalStateObj);
}

// HACK HACK HACK - for Async only
// Have to post read to intialize MARS - will get callback on this when connection goes
// down or is closed.

IntPtr temp = IntPtr.Zero;

RuntimeHelpers.PrepareConstrainedRegions();
try
{ }
finally
{
_pMarsPhysicalConObj.IncrementPendingCallbacks();

error = SniNativeWrapper.SniReadAsync(_pMarsPhysicalConObj.Handle, ref temp);

if (temp != IntPtr.Zero)
{
// Be sure to release packet, otherwise it will be leaked by native.
SniNativeWrapper.SniPacketRelease(temp);
}
}
Debug.Assert(IntPtr.Zero == temp, "unexpected syncReadPacket without corresponding SNIPacketRelease");
if (TdsEnums.SNI_SUCCESS_IO_PENDING != error)
error = _pMarsPhysicalConObj.PostReadAsyncForMars(_physicalStateObj);
if (error != TdsEnums.SNI_SUCCESS_IO_PENDING)
{
Debug.Assert(TdsEnums.SNI_SUCCESS != error, "Unexpected successful read async on physical connection before enabling MARS!");
Debug.Assert(error != TdsEnums.SNI_SUCCESS, "Unexpected successful read async on physical connection before enabling MARS!");
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
ThrowExceptionAndWarning(_physicalStateObj);
}
Expand Down Expand Up @@ -996,19 +974,26 @@ private void EnableSsl(uint info, SqlConnectionEncryptOption encrypt, bool integ
ThrowExceptionAndWarning(_physicalStateObj);
}

uint protocolVersion = 0;

// in the case where an async connection is made, encryption is used and Windows Authentication is used,
// wait for SSL handshake to complete, so that the SSL context is fully negotiated before we try to use its
// Channel Bindings as part of the Windows Authentication context build (SSL handshake must complete
// before calling SNISecGenClientContext).
error = SniNativeWrapper.SniWaitForSslHandshakeToComplete(_physicalStateObj.Handle, _physicalStateObj.GetTimeoutRemaining(), out uint protocolVersion);

if (error != TdsEnums.SNI_SUCCESS)
#if NET
if (OperatingSystem.IsWindows())
#endif
{
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
ThrowExceptionAndWarning(_physicalStateObj);
error = _physicalStateObj.WaitForSSLHandShakeToComplete(out protocolVersion);
if (error != TdsEnums.SNI_SUCCESS)
{
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
ThrowExceptionAndWarning(_physicalStateObj);
}
}

string warningMessage = ((System.Security.Authentication.SslProtocols)protocolVersion).GetProtocolWarning();
SslProtocols protocol = (SslProtocols)protocolVersion;
string warningMessage = protocol.GetProtocolWarning();
if (!string.IsNullOrEmpty(warningMessage))
{
if (!encrypt && LocalAppContextSwitches.SuppressInsecureTlsWarning)
Expand Down
Loading
Loading