Skip to content

Commit fd52753

Browse files
committed
Use ReadOnlyMemory in
1 parent bc2a834 commit fd52753

11 files changed

+55
-35
lines changed

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ private static extern uint SNIOpenWrapper(
315315
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl)]
316316
private static extern unsafe uint SNISecGenClientContextWrapper(
317317
[In] SNIHandle pConn,
318-
[In, Out] byte[] pIn,
318+
[In, Out] byte* pIn,
319319
uint cbIn,
320320
[In, Out] byte[] pOut,
321321
[In] ref uint pcbOut,
@@ -471,15 +471,16 @@ internal static unsafe void SNIPacketSetData(SNIPacket packet, byte[] data, int
471471
}
472472
}
473473

474-
internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName)
474+
internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan<byte> inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName)
475475
{
476476
fixed (byte* pin_serverUserName = &serverUserName[0])
477+
fixed (byte* pInBuff = inBuff)
477478
{
478479
bool local_fDone;
479480
return SNISecGenClientContextWrapper(
480481
pConnectionObject,
481-
inBuff,
482-
receivedLength,
482+
pInBuff,
483+
(uint)inBuff.Length,
483484
OutBuff,
484485
ref sendLength,
485486
out local_fDone,

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

+19-2
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.Buffers;
67
using System.Diagnostics;
78
using System.IO;
89
using System.Net;
@@ -34,7 +35,23 @@ internal class SNIProxy
3435
/// <param name="sendBuff">Send buffer</param>
3536
/// <param name="serverName">Service Principal Name buffer</param>
3637
/// <returns>SNI error code</returns>
37-
internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName)
38+
internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, ReadOnlyMemory<byte> receivedBuff, ref byte[] sendBuff, byte[][] serverName)
39+
{
40+
// TODO: this should use ReadOnlyMemory all the way through
41+
var array = ArrayPool<byte>.Shared.Rent(receivedBuff.Length);
42+
43+
try
44+
{
45+
receivedBuff.CopyTo(array);
46+
GenSspiClientContext(sspiClientContextStatus, array, receivedBuff.Length, ref sendBuff, serverName);
47+
}
48+
finally
49+
{
50+
ArrayPool<byte>.Shared.Return(array);
51+
}
52+
}
53+
54+
private static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, int receivedBuffLength, ref byte[] sendBuff, byte[][] serverName)
3855
{
3956
SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext;
4057
ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags;
@@ -189,7 +206,7 @@ internal static SNIHandle CreateConnectionHandle(
189206
case DataSource.Protocol.TCP:
190207
sniHandle = CreateTcpHandle(details, timeout, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo,
191208
tlsFirst, hostNameInCertificate, serverCertificateFilename);
192-
break;
209+
break;
193210
case DataSource.Protocol.NP:
194211
sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst);
195212
break;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper(
116116
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")]
117117
internal static extern unsafe uint SNISecGenClientContextWrapper(
118118
[In] SNIHandle pConn,
119-
[In, Out] byte[] pIn,
119+
[In, Out] byte* pIn,
120120
uint cbIn,
121121
[In, Out] byte[] pOut,
122122
[In] ref uint pcbOut,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper(
116116
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")]
117117
internal static extern unsafe uint SNISecGenClientContextWrapper(
118118
[In] SNIHandle pConn,
119-
[In, Out] byte[] pIn,
119+
[In, Out] byte* pIn,
120120
uint cbIn,
121121
[In, Out] byte[] pOut,
122122
[In] ref uint pcbOut,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper(
116116
[DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")]
117117
internal static extern unsafe uint SNISecGenClientContextWrapper(
118118
[In] SNIHandle pConn,
119-
[In, Out] byte[] pIn,
119+
[In, Out] byte* pIn,
120120
uint cbIn,
121121
[In, Out] byte[] pOut,
122122
[In] ref uint pcbOut,

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

+14-13
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@ private static unsafe void SNIPacketSetData(SNIPacket pPacket, [In] byte* pbBuf,
889889

890890
private static unsafe uint SNISecGenClientContextWrapper(
891891
[In] SNIHandle pConn,
892-
[In, Out] byte[] pIn,
893-
uint cbIn,
892+
[In, Out] ReadOnlySpan<byte> pIn,
894893
[In, Out] byte[] pOut,
895894
[In] ref uint pcbOut,
896895
[MarshalAsAttribute(UnmanagedType.Bool)] out bool pfDone,
@@ -899,16 +898,19 @@ private static unsafe uint SNISecGenClientContextWrapper(
899898
[MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszUserName,
900899
[MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszPassword)
901900
{
902-
switch (s_architecture)
901+
fixed (byte* pInPtr = pIn)
903902
{
904-
case System.Runtime.InteropServices.Architecture.Arm64:
905-
return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
906-
case System.Runtime.InteropServices.Architecture.X64:
907-
return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
908-
case System.Runtime.InteropServices.Architecture.X86:
909-
return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
910-
default:
911-
throw ADP.SNIPlatformNotSupported(s_architecture.ToString());
903+
switch (s_architecture)
904+
{
905+
case System.Runtime.InteropServices.Architecture.Arm64:
906+
return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
907+
case System.Runtime.InteropServices.Architecture.X64:
908+
return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
909+
case System.Runtime.InteropServices.Architecture.X86:
910+
return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword);
911+
default:
912+
throw ADP.SNIPlatformNotSupported(s_architecture.ToString());
913+
}
912914
}
913915
}
914916

@@ -1378,15 +1380,14 @@ Int32[] passwordOffsets // Offset into data buffer where the password to be w
13781380
}
13791381
}
13801382

1381-
internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName)
1383+
internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan<byte> inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName)
13821384
{
13831385
fixed (byte* pin_serverUserName = &serverUserName[0])
13841386
{
13851387
bool local_fDone;
13861388
return SNISecGenClientContextWrapper(
13871389
pConnectionObject,
13881390
inBuff,
1389-
receivedLength,
13901391
OutBuff,
13911392
ref sendLength,
13921393
out local_fDone,

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#if !NETFRAMEWORK && !NET7_0_OR_GREATER
22

3+
using System;
34
using Microsoft.Data.SqlClient.SNI;
45

56
#nullable enable
@@ -10,11 +11,11 @@ internal sealed class ManagedSSPIContextProvider : SSPIContextProvider
1011
{
1112
private SspiClientContextStatus? _sspiClientContextStatus;
1213

13-
internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
14+
internal override void GenerateSspiClientContext(ReadOnlyMemory<byte> received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
1415
{
1516
_sspiClientContextStatus ??= new SspiClientContextStatus();
1617

17-
SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer);
18+
SNIProxy.GenSspiClientContext(_sspiClientContextStatus, received, ref sendBuff, _sniSpnBuffer);
1819
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _physicalStateObj.SessionId);
1920
sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0);
2021
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ private void LoadSSPILibrary()
5050
}
5151
}
5252

53-
internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
53+
internal override void GenerateSspiClientContext(ReadOnlyMemory<byte> receivedBuff, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
5454
{
5555
#if NETFRAMEWORK
5656
SNIHandle handle = _physicalStateObj.Handle;
5757
#else
5858
Debug.Assert(_physicalStateObj.SessionHandle.Type == SessionHandle.NativeHandleType);
5959
SNIHandle handle = _physicalStateObj.SessionHandle.NativeHandle;
6060
#endif
61-
if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer[0]))
61+
if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff.Span, sendBuff, ref sendLength, _sniSpnBuffer[0]))
6262
{
6363
throw new InvalidOperationException(SQLMessage.SSPIGenerateError());
6464
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ internal sealed class NegotiateSSPIContextProvider : SSPIContextProvider
1212
{
1313
private NegotiateAuthentication? _negotiateAuth = null;
1414

15-
internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
15+
internal override void GenerateSspiClientContext(ReadOnlyMemory<byte> received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
1616
{
1717
_negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) });
18-
sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!;
18+
sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out NegotiateAuthenticationStatusCode statusCode)!;
1919
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _physicalStateObj.SessionId, statusCode);
2020
if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded)
2121
{

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ private protected virtual void Initialize()
2727
{
2828
}
2929

30-
internal abstract void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer);
30+
internal abstract void GenerateSspiClientContext(ReadOnlyMemory<byte> input, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer);
3131

32-
internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer)
33-
=> SSPIData(receivedBuff, receivedLength, ref sendBuff, ref sendLength, new[] { sniSpnBuffer });
32+
internal void SSPIData(ReadOnlyMemory<byte> receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer)
33+
=> SSPIData(receivedBuff, ref sendBuff, ref sendLength, new[] { sniSpnBuffer });
3434

35-
internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer)
35+
internal void SSPIData(ReadOnlyMemory<byte> receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer)
3636
{
3737
try
3838
{
39-
GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, sniSpnBuffer);
39+
GenerateSspiClientContext(receivedBuff, ref sendBuff, ref sendLength, sniSpnBuffer);
4040
}
4141
catch (Exception e)
4242
{

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal void ProcessSSPI(int receivedLength)
3131
uint sendLength = _authenticationProvider.MaxSSPILength;
3232

3333
// make call for SSPI data
34-
_authenticationProvider.SSPIData(receivedBuff, (uint)receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer);
34+
_authenticationProvider.SSPIData(receivedBuff.AsMemory(0, receivedLength), ref sendBuff, ref sendLength, _sniSpnBuffer);
3535

3636
// DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA!
3737
_physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0);
@@ -194,7 +194,7 @@ internal void TdsLogin(
194194
// byte[] buffer and 0 for the int length.
195195
Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'");
196196
_physicalStateObj.SniContext = SniContext.Snix_LoginSspi;
197-
_authenticationProvider.SSPIData(Array.Empty<byte>(), 0, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer);
197+
_authenticationProvider.SSPIData(Array.Empty<byte>(), ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer);
198198

199199
if (outSSPILength > int.MaxValue)
200200
{

0 commit comments

Comments
 (0)