From 6384b2866defc264cfc82eba549780c52aa16ae7 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Fri, 11 Jun 2021 22:21:11 +0100 Subject: [PATCH 1/3] resolve conflicts --- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 154 +----------------- .../SqlClient/TdsParserStateObjectManaged.cs | 86 ++++++++-- 2 files changed, 76 insertions(+), 164 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 5823e7f44c..821bbc5661 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -32,38 +32,6 @@ internal class SspiClientContextResult internal static SNIProxy GetInstance() => s_singleton; - /// - /// Enable SSL on a connection - /// - /// Connection handle - /// - /// SNI error code - internal uint EnableSsl(SNIHandle handle, uint options) - { - try - { - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.EnableSsl | Info | Session Id {0}", handle?.ConnectionId); - return handle.EnableSsl(options); - } - catch (Exception e) - { - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.EnableSsl | Err | Session Id {0}, SNI Handshake failed with exception: {1}", handle?.ConnectionId, e?.Message); - return SNICommon.ReportSNIError(SNIProviders.SSL_PROV, SNICommon.HandshakeFailureError, e); - } - } - - /// - /// Disable SSL on a connection - /// - /// Connection handle - /// SNI error code - internal uint DisableSsl(SNIHandle handle) - { - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.DisableSsl | Info | Session Id {0}", handle?.ConnectionId); - handle.DisableSsl(); - return TdsEnums.SNI_SUCCESS; - } - /// /// Generate SSPI context /// @@ -72,7 +40,7 @@ internal uint DisableSsl(SNIHandle handle) /// Send buffer /// Service Principal Name buffer /// SNI error code - internal void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) + internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; @@ -165,83 +133,6 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode) errorCode != SecurityStatusPalErrorCode.Renegotiate; } - /// - /// Set connection buffer size - /// - /// SNI handle - /// Buffer size - /// SNI error code - internal uint SetConnectionBufferSize(SNIHandle handle, uint bufferSize) - { - handle.SetBufferSize((int)bufferSize); - return TdsEnums.SNI_SUCCESS; - } - - /// - /// Copies data in SNIPacket to given byte array parameter - /// - /// SNIPacket object containing data packets - /// Destination byte array where data packets are copied to - /// Length of data packets - /// SNI error status - internal uint PacketGetData(SNIPacket packet, byte[] inBuff, ref uint dataSize) - { - int dataSizeInt = 0; - packet.GetData(inBuff, ref dataSizeInt); - dataSize = (uint)dataSizeInt; - - return TdsEnums.SNI_SUCCESS; - } - - /// - /// Read synchronously - /// - /// SNI handle - /// SNI packet - /// Timeout - /// SNI error status - internal uint ReadSyncOverAsync(SNIHandle handle, out SNIPacket packet, int timeout) - { - return handle.Receive(out packet, timeout); - } - - /// - /// Get SNI connection ID - /// - /// SNI handle - /// Client connection ID - /// SNI error status - internal uint GetConnectionId(SNIHandle handle, ref Guid clientConnectionId) - { - clientConnectionId = handle.ConnectionId; - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.GetConnectionId | Info | Session Id {0}", clientConnectionId); - return TdsEnums.SNI_SUCCESS; - } - - /// - /// Send a packet - /// - /// SNI handle - /// SNI packet - /// true if synchronous, false if asynchronous - /// SNI error status - internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync) - { - uint result; - if (sync) - { - result = handle.Send(packet); - handle.ReturnPacket(packet); - } - else - { - result = handle.SendAsync(packet); - } - - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.WritePacket | Info | Session Id {0}, SendAsync Result {1}", handle?.ConnectionId, result); - return result; - } - /// /// Create a SNI connection handle /// @@ -258,7 +149,7 @@ internal uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync) /// Used for DNS Cache /// Used for DNS Cache /// SNI handle - internal SNIHandle CreateConnectionHandle(string fullServerName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer, + internal static SNIHandle CreateConnectionHandle(string fullServerName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer, bool flushCache, bool async, bool parallel, bool isIntegratedSecurity, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo) { instanceName = new byte[1]; @@ -380,7 +271,7 @@ private static byte[][] GetSqlServerSPNs(string hostNameOrAddress, string portOr /// Key for DNS Cache /// Used for DNS Cache /// SNITCPHandle - private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool parallel, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo) + private static SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool parallel, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo) { // TCP Format: // tcp:\ @@ -421,8 +312,6 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool return new SNITCPHandle(hostName, port, timerExpire, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo); } - - /// /// Creates an SNINpHandle object /// @@ -430,7 +319,7 @@ private SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool /// Timer expiration /// Should MultiSubnetFailover be used. Only returns an error for named pipes. /// SNINpHandle - private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, bool parallel) + private static SNINpHandle CreateNpHandle(DataSource details, long timerExpire, bool parallel) { if (parallel) { @@ -441,39 +330,6 @@ private SNINpHandle CreateNpHandle(DataSource details, long timerExpire, bool pa return new SNINpHandle(details.PipeHostName, details.PipeName, timerExpire); } - /// - /// Read packet asynchronously - /// - /// SNI handle - /// Packet - /// SNI error status - internal uint ReadAsync(SNIHandle handle, out SNIPacket packet) - { - packet = null; - return handle.ReceiveAsync(ref packet); - } - - /// - /// Set packet data - /// - /// SNI packet - /// Data - /// Length - internal void PacketSetData(SNIPacket packet, byte[] data, int length) - { - packet.AppendData(data, length); - } - - /// - /// Check SNI handle connection - /// - /// - /// SNI error status - internal uint CheckConnection(SNIHandle handle) - { - return handle.CheckConnection(); - } - /// /// Get last SNI error on this thread /// @@ -489,7 +345,7 @@ internal SNIError GetLastError() /// The data source /// Set true when an error occurred while getting LocalDB up /// - private string GetLocalDBDataSource(string fullServerName, out bool error) + private static string GetLocalDBDataSource(string fullServerName, out bool error) { string localDBConnectionString = null; bool isBadLocalDBDataSource; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs index 6bf08b0336..2a17b38c46 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -47,13 +47,18 @@ internal SNIMarsHandle CreateMarsSession(object callbackObject, bool async) return _marsConnection.CreateMarsSession(callbackObject, async); } - protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize) - => SNIProxy.GetInstance().PacketGetData(packet.ManagedPacket, _inBuff, ref dataSize); + protected override uint SNIPacketGetData(PacketHandle packet, byte[] inBuff, ref uint dataSize) + { + int dataSizeInt = 0; + packet.ManagedPacket.GetData(inBuff, ref dataSizeInt); + dataSize = (uint)dataSizeInt; + return TdsEnums.SNI_SUCCESS; + } internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer, bool flushCache, bool async, bool parallel, SqlConnectionIPAddressPreference iPAddressPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo, bool isIntegratedSecurity) { - _sessionHandle = SNIProxy.GetInstance().CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, + _sessionHandle = SNIProxy.CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity, iPAddressPreference, cachedFQDN, ref pendingDNSInfo); if (_sessionHandle == null) { @@ -162,7 +167,9 @@ internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint { throw ADP.ClosedConnectionError(); } - error = SNIProxy.GetInstance().ReadSyncOverAsync(handle, out SNIPacket packet, timeoutRemaining); + + error = handle.Receive(out SNIPacket packet, timeoutRemaining); + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.ReadSyncOverAsync | Info | State Object Id {0}, Session Id {1}", _objectID, _sessionHandle?.ConnectionId); #if DEBUG SqlClientEventSource.Log.TryAdvancedTraceEvent("TdsParserStateObjectManaged.ReadSyncOverAsync | TRC | State Object Id {0}, Session Id {1}, Packet {2} received, Packet owner Id {3}, Packet dataLeft {4}", _objectID, _sessionHandle?.ConnectionId, packet?._id, packet?._owner.ConnectionId, packet?.DataLeft); @@ -191,12 +198,14 @@ internal override void ReleasePacket(PacketHandle syncReadPacket) internal override uint CheckConnection() { SNIHandle handle = Handle; - return handle == null ? TdsEnums.SNI_SUCCESS : SNIProxy.GetInstance().CheckConnection(handle); + return handle == null ? TdsEnums.SNI_SUCCESS : handle.CheckConnection(); } internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) { - error = SNIProxy.GetInstance().ReadAsync(handle.ManagedHandle, out SNIPacket packet); + SNIPacket packet = null; + error = handle.ManagedHandle.ReceiveAsync(ref packet); + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.ReadAsync | Info | State Object Id {0}, Session Id {1}, Packet DataLeft {2}", _objectID, _sessionHandle?.ConnectionId, packet?.DataLeft); return PacketHandle.FromManagedPacket(packet); } @@ -214,8 +223,24 @@ internal override PacketHandle CreateAndSetAttentionPacket() return packetHandle; } - internal override uint WritePacket(PacketHandle packet, bool sync) => - SNIProxy.GetInstance().WritePacket(Handle, packet.ManagedPacket, sync); + internal override uint WritePacket(PacketHandle packetHandle, bool sync) + { + uint result; + SNIHandle handle = Handle; + SNIPacket packet = packetHandle.ManagedPacket; + if (sync) + { + result = handle.Send(packet); + handle.ReturnPacket(packet); + } + else + { + result = handle.SendAsync(packet); + } + + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.WritePacket | Info | Session Id {0}, SendAsync Result {1}", handle?.ConnectionId, result); + return result; + } // No- Op in managed SNI internal override PacketHandle AddPacketToPendingList(PacketHandle packet) => packet; @@ -246,11 +271,25 @@ internal override void ClearAllWritePackets() Debug.Assert(_asyncWriteCount == 0, "Should not clear all write packets if there are packets pending"); } - internal override void SetPacketData(PacketHandle packet, byte[] buffer, int bytesUsed) => SNIProxy.GetInstance().PacketSetData(packet.ManagedPacket, buffer, bytesUsed); + internal override void SetPacketData(PacketHandle packet, byte[] buffer, int bytesUsed) + { + packet.ManagedPacket.AppendData(buffer, bytesUsed); + } - internal override uint SniGetConnectionId(ref Guid clientConnectionId) => SNIProxy.GetInstance().GetConnectionId(Handle, ref clientConnectionId); + internal override uint SniGetConnectionId(ref Guid clientConnectionId) + { + clientConnectionId = Handle.ConnectionId; + SqlClientEventSource.Log.TryTraceEvent("SNIProxy.GetConnectionId | Info | Session Id {0}", clientConnectionId); + return TdsEnums.SNI_SUCCESS; + } - internal override uint DisableSsl() => SNIProxy.GetInstance().DisableSsl(Handle); + internal override uint DisableSsl() + { + SNIHandle handle = Handle; + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.DisableSsl | Info | Session Id {0}", handle?.ConnectionId); + handle.DisableSsl(); + return TdsEnums.SNI_SUCCESS; + } internal override uint EnableMars(ref uint info) { @@ -265,9 +304,26 @@ internal override uint EnableMars(ref uint info) return TdsEnums.SNI_ERROR; } - internal override uint EnableSsl(ref uint info) => SNIProxy.GetInstance().EnableSsl(Handle, info); + internal override uint EnableSsl(ref uint info) + { + SNIHandle handle = Handle; + try + { + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.EnableSsl | Info | Session Id {0}", handle?.ConnectionId); + return handle.EnableSsl(info); + } + catch (Exception e) + { + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.EnableSsl | Err | Session Id {0}, SNI Handshake failed with exception: {1}", handle?.ConnectionId, e?.Message); + return SNICommon.ReportSNIError(SNIProviders.SSL_PROV, SNICommon.HandshakeFailureError, e); + } + } - internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize) => SNIProxy.GetInstance().SetConnectionBufferSize(Handle, unsignedPacketSize); + internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize) + { + Handle.SetBufferSize((int)unsignedPacketSize); + return TdsEnums.SNI_SUCCESS; + } internal override uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { @@ -276,8 +332,8 @@ internal override uint GenerateSspiClientContext(byte[] receivedBuff, uint recei _sspiClientContextStatus = new SspiClientContextStatus(); } - SNIProxy.GetInstance().GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.GenerateSspiClientContext | Info | Session Id {0}", _sessionHandle?.ConnectionId); + SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _sessionHandle?.ConnectionId); sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); return 0; } From e289837c2b61ff8fd3bc8686f6db5d47df4b1f35 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Mon, 14 Jun 2021 21:16:12 +0100 Subject: [PATCH 2/3] address feedback --- .../src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 11 ++--------- .../src/Microsoft/Data/SqlClient/TdsParser.Windows.cs | 2 +- .../Data/SqlClient/TdsParserStateObjectManaged.cs | 9 ++++++++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 821bbc5661..24c8609876 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -21,16 +21,9 @@ internal class SNIProxy private const int DefaultSqlServerDacPort = 1434; private const string SqlServerSpnHeader = "MSSQLSvc"; - internal class SspiClientContextResult - { - internal const uint OK = 0; - internal const uint Failed = 1; - internal const uint KerberosTicketMissing = 2; - } - - internal static readonly SNIProxy s_singleton = new SNIProxy(); + private static readonly SNIProxy s_singleton = new SNIProxy(); - internal static SNIProxy GetInstance() => s_singleton; + internal static SNIProxy Instance => s_singleton; /// /// Generate SSPI context diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs index 07846127d7..f7a0363f27 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Windows.cs @@ -95,7 +95,7 @@ private SNIErrorDetails GetSniErrorDetails() if (TdsParserStateObjectFactory.UseManagedSNI) { - SNIError sniError = SNIProxy.GetInstance().GetLastError(); + SNIError sniError = SNIProxy.Instance.GetLastError(); details.sniErrorNumber = sniError.sniError; details.errorMessage = sniError.errorMessage; details.nativeError = sniError.nativeError; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs index 2a17b38c46..4c3ad107b4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -47,6 +47,13 @@ internal SNIMarsHandle CreateMarsSession(object callbackObject, bool async) return _marsConnection.CreateMarsSession(callbackObject, async); } + /// + /// Copies data in SNIPacket to given byte array parameter + /// + /// SNIPacket object containing data packets + /// Destination byte array where data packets are copied to + /// Length of data packets + /// SNI error status protected override uint SNIPacketGetData(PacketHandle packet, byte[] inBuff, ref uint dataSize) { int dataSizeInt = 0; @@ -279,7 +286,7 @@ internal override void SetPacketData(PacketHandle packet, byte[] buffer, int byt internal override uint SniGetConnectionId(ref Guid clientConnectionId) { clientConnectionId = Handle.ConnectionId; - SqlClientEventSource.Log.TryTraceEvent("SNIProxy.GetConnectionId | Info | Session Id {0}", clientConnectionId); + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GetConnectionId | Info | Session Id {0}", clientConnectionId); return TdsEnums.SNI_SUCCESS; } From f24e84188eeb8d949cf27baed375bf51d3a6623d Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Mon, 14 Jun 2021 21:41:38 +0100 Subject: [PATCH 3/3] fix unix --- .../netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs index 692633efd6..2f242a083f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.Unix.cs @@ -26,7 +26,7 @@ private void WaitForSSLHandShakeToComplete(ref uint error, ref int protocolVersi private SNIErrorDetails GetSniErrorDetails() { SNIErrorDetails details; - SNIError sniError = SNIProxy.GetInstance().GetLastError(); + SNIError sniError = SNIProxy.Instance.GetLastError(); details.sniErrorNumber = sniError.sniError; details.errorMessage = sniError.errorMessage; details.nativeError = sniError.nativeError;