Skip to content

Commit 6fbb337

Browse files
Dev | Add support of the new authentication API with SSPI token on Managed SNI (#2063)
1 parent 20ab3b1 commit 6fbb337

File tree

4 files changed

+91
-63
lines changed

4 files changed

+91
-63
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ internal static partial class Libraries
99
internal const string Crypt32 = "crypt32.dll";
1010
internal const string Kernel32 = "kernel32.dll";
1111
internal const string NtDll = "ntdll.dll";
12+
#if !NET7_0_OR_GREATER
1213
internal const string SspiCli = "sspicli.dll";
14+
#endif
1315
}
1416
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
</Compile>
9090
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs">
9191
<Link>Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs</Link>
92-
</Compile>
92+
</Compile>
9393
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlNotificationRequest.cs">
9494
<Link>Microsoft\Data\Sql\SqlNotificationRequest.cs</Link>
9595
</Compile>
@@ -517,7 +517,7 @@
517517
</Compile>
518518
</ItemGroup>
519519
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetFramework)' == 'netstandard2.0'">
520-
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIStreams.Task.cs" />
520+
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIStreams.Task.cs" />
521521
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.NetStandard.cs" />
522522
<Compile Include="Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.NetStandard.cs" />
523523
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
@@ -622,7 +622,6 @@
622622
<Compile Include="Microsoft\Data\SqlClient\SNI\SNITcpHandle.cs" />
623623
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.cs" />
624624
<Compile Include="Microsoft\Data\SqlClient\SNI\SNICommon.cs" />
625-
<Compile Include="Microsoft\Data\SqlClient\SNI\SspiClientContextStatus.cs" />
626625
<Compile Include="Microsoft\Data\SqlClient\SNI\SSRP.cs" />
627626
<Compile Include="Microsoft\Data\SqlClient\SqlAppContextSwitchManager.NetCoreApp.cs" />
628627
<Compile Include="Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.cs" />
@@ -768,8 +767,35 @@
768767
</Compile>
769768
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Common.cs" />
770769
</ItemGroup>
771-
<!-- Windows dependencies for Integrated Authentication for MANAGED_SNI build -->
770+
<!-- Windows dependencies for MANAGED_SNI build -->
772771
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
772+
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
773+
<Link>Common\Interop\Windows\Interop.Libraries.cs</Link>
774+
</Compile>
775+
</ItemGroup>
776+
<!-- Common (Windows and Unix) dependencies for MANAGED_SNI build -->
777+
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS'">
778+
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
779+
<Link>Common\System\Net\InternalException.cs</Link>
780+
</Compile>
781+
<Compile Include="$(CommonPath)\System\Net\Logging\NetEventSource.Common.cs">
782+
<Link>Common\System\Net\Logging\NetEventSource.Common.cs</Link>
783+
</Compile>
784+
</ItemGroup>
785+
<!-- Unix dependencies for Managed_SNI build-->
786+
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
787+
<Compile Include="Microsoft\Data\Sql\SqlDataSourceEnumerator.Unix.cs" />
788+
<Compile Include="Interop\SNINativeMethodWrapper.Unix.cs" />
789+
<Compile Include="Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs" />
790+
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Unix.cs" />
791+
<Compile Include="Microsoft\Data\SqlClient\PacketHandle.Unix.cs" />
792+
<Compile Include="Microsoft\Data\SqlClient\SessionHandle.Unix.cs" />
793+
<Compile Include="Microsoft\Data\SqlClient\SNI\LocalDB.Unix.cs" />
794+
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
795+
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Unix.cs" />
796+
</ItemGroup>
797+
<!-- Windows dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
798+
<ItemGroup Condition="'$(TargetsWindows)' == 'true' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
773799
<Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs">
774800
<Link>Common\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs</Link>
775801
</Compile>
@@ -779,9 +805,6 @@
779805
<Compile Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.certificates_types.cs">
780806
<Link>Common\Interop\Windows\Crypt32\Interop.certificates_types.cs</Link>
781807
</Compile>
782-
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
783-
<Link>Common\Interop\Windows\Interop.Libraries.cs</Link>
784-
</Compile>
785808
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs">
786809
<Link>Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs</Link>
787810
</Compile>
@@ -791,6 +814,30 @@
791814
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs">
792815
<Link>Common\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs</Link>
793816
</Compile>
817+
<Compile Include="$(CommonPath)\System\Collections\Generic\BidirectionalDictionary.cs">
818+
<Link>Common\System\Collections\Generic\BidirectionalDictionary.cs</Link>
819+
</Compile>
820+
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Windows.cs">
821+
<Link>Common\System\Net\ContextFlagsAdapterPal.Windows.cs</Link>
822+
</Compile>
823+
<Compile Include="$(CommonPath)\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs">
824+
<Link>Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs</Link>
825+
</Compile>
826+
<Compile Include="$(CommonPath)\System\Net\Security\SecurityContextTokenHandle.cs">
827+
<Link>Common\System\Net\Security\SecurityContextTokenHandle.cs</Link>
828+
</Compile>
829+
<Compile Include="$(CommonPath)\System\Net\SecurityStatusAdapterPal.Windows.cs">
830+
<Link>Common\System\Net\SecurityStatusAdapterPal.Windows.cs</Link>
831+
</Compile>
832+
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Windows.cs">
833+
<Link>Common\System\Net\Security\NegotiateStreamPal.Windows.cs</Link>
834+
</Compile>
835+
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.cs">
836+
<Link>Common\System\Net\Security\NetEventSource.Security.cs</Link>
837+
</Compile>
838+
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.Windows.cs">
839+
<Link>Common\System\Net\Security\NetEventSource.Security.Windows.cs</Link>
840+
</Compile>
794841
<Compile Include="$(CommonPath)\Interop\Windows\sspicli\GlobalSSPI.cs">
795842
<Link>Common\Interop\Windows\sspicli\GlobalSSPI.cs</Link>
796843
</Compile>
@@ -836,33 +883,9 @@
836883
<Compile Include="$(CommonPath)\Interop\Windows\sspicli\SSPIWrapper.cs">
837884
<Link>Common\Interop\Windows\sspicli\SSPIWrapper.cs</Link>
838885
</Compile>
839-
<Compile Include="$(CommonPath)\System\Collections\Generic\BidirectionalDictionary.cs">
840-
<Link>Common\System\Collections\Generic\BidirectionalDictionary.cs</Link>
841-
</Compile>
842-
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Windows.cs">
843-
<Link>Common\System\Net\ContextFlagsAdapterPal.Windows.cs</Link>
844-
</Compile>
845-
<Compile Include="$(CommonPath)\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs">
846-
<Link>Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs</Link>
847-
</Compile>
848-
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Windows.cs">
849-
<Link>Common\System\Net\Security\NegotiateStreamPal.Windows.cs</Link>
850-
</Compile>
851-
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.cs">
852-
<Link>Common\System\Net\Security\NetEventSource.Security.cs</Link>
853-
</Compile>
854-
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.Windows.cs">
855-
<Link>Common\System\Net\Security\NetEventSource.Security.Windows.cs</Link>
856-
</Compile>
857-
<Compile Include="$(CommonPath)\System\Net\Security\SecurityContextTokenHandle.cs">
858-
<Link>Common\System\Net\Security\SecurityContextTokenHandle.cs</Link>
859-
</Compile>
860-
<Compile Include="$(CommonPath)\System\Net\SecurityStatusAdapterPal.Windows.cs">
861-
<Link>Common\System\Net\SecurityStatusAdapterPal.Windows.cs</Link>
862-
</Compile>
863886
</ItemGroup>
864-
<!-- Common (Windows and Unix) dependencies for MANAGED_SNI build -->
865-
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS'">
887+
<!-- Common (Windows and Unix) dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
888+
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
866889
<Compile Include="$(CommonPath)\System\Net\ContextFlagsPal.cs">
867890
<Link>Common\System\Net\ContextFlagsPal.cs</Link>
868891
</Compile>
@@ -872,15 +895,9 @@
872895
<Compile Include="$(CommonPath)\System\Net\DebugSafeHandle.cs">
873896
<Link>Common\System\Net\DebugSafeHandle.cs</Link>
874897
</Compile>
875-
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
876-
<Link>Common\System\Net\InternalException.cs</Link>
877-
</Compile>
878898
<Compile Include="$(CommonPath)\System\Net\Logging\DebugThreadTracking.cs">
879899
<Link>Common\System\Net\Logging\DebugThreadTracking.cs</Link>
880900
</Compile>
881-
<Compile Include="$(CommonPath)\System\Net\Logging\NetEventSource.Common.cs">
882-
<Link>Common\System\Net\Logging\NetEventSource.Common.cs</Link>
883-
</Compile>
884901
<Compile Include="$(CommonPath)\System\Net\NegotiationInfoClass.cs">
885902
<Link>Common\System\Net\NegotiationInfoClass.cs</Link>
886903
</Compile>
@@ -893,8 +910,10 @@
893910
<Compile Include="$(CommonPath)\System\Net\SecurityStatusPal.cs">
894911
<Link>Common\System\Net\SecurityStatusPal.cs</Link>
895912
</Compile>
913+
<Compile Include="Microsoft\Data\SqlClient\SNI\SspiClientContextStatus.cs" />
896914
</ItemGroup>
897-
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
915+
<!-- Unix dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
916+
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
898917
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
899918
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
900919
</Compile>
@@ -910,12 +929,6 @@
910929
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\GssSafeHandles.cs">
911930
<Link>Common\Microsoft\Win32\SafeHandles\GssSafeHandles.cs</Link>
912931
</Compile>
913-
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Unix.cs">
914-
<Link>Common\System\Net\ContextFlagsAdapterPal.Unix.cs</Link>
915-
</Compile>
916-
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Unix.cs">
917-
<Link>Common\System\Net\Security\NegotiateStreamPal.Unix.cs</Link>
918-
</Compile>
919932
<Compile Include="$(CommonPath)\System\Net\Security\Unix\SafeDeleteContext.cs">
920933
<Link>Common\System\Net\Security\Unix\SafeDeleteContext.cs</Link>
921934
</Compile>
@@ -928,15 +941,12 @@
928941
<Compile Include="$(CommonPath)\System\Net\Security\Unix\SafeFreeNegoCredentials.cs">
929942
<Link>Common\System\Net\Security\Unix\SafeFreeNegoCredentials.cs</Link>
930943
</Compile>
931-
<Compile Include="Microsoft\Data\Sql\SqlDataSourceEnumerator.Unix.cs" />
932-
<Compile Include="Interop\SNINativeMethodWrapper.Unix.cs" />
933-
<Compile Include="Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs" />
934-
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Unix.cs" />
935-
<Compile Include="Microsoft\Data\SqlClient\PacketHandle.Unix.cs" />
936-
<Compile Include="Microsoft\Data\SqlClient\SessionHandle.Unix.cs" />
937-
<Compile Include="Microsoft\Data\SqlClient\SNI\LocalDB.Unix.cs" />
938-
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
939-
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Unix.cs" />
944+
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Unix.cs">
945+
<Link>Common\System\Net\ContextFlagsAdapterPal.Unix.cs</Link>
946+
</Compile>
947+
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Unix.cs">
948+
<Link>Common\System\Net\Security\NegotiateStreamPal.Unix.cs</Link>
949+
</Compile>
940950
</ItemGroup>
941951
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(IsUAPAssembly)' == 'true'">
942952
<Reference Include="System.Collections.NonGeneric" />

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal class SNIProxy
2424
private static readonly SNIProxy s_singleton = new SNIProxy();
2525

2626
internal static SNIProxy Instance => s_singleton;
27-
27+
#if !NET7_0_OR_GREATER
2828
/// <summary>
2929
/// Generate SSPI context
3030
/// </summary>
@@ -105,11 +105,11 @@ internal static void GenSspiClientContext(SspiClientContextStatus sspiClientCont
105105
// so we don't need to check for a GssApiException here.
106106
if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError)
107107
{
108-
throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode);
108+
throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + Environment.NewLine + statusCode);
109109
}
110110
else
111111
{
112-
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode);
112+
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode);
113113
}
114114
}
115115
}
@@ -125,7 +125,7 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
125125
errorCode != SecurityStatusPalErrorCode.CredentialsNeeded &&
126126
errorCode != SecurityStatusPalErrorCode.Renegotiate;
127127
}
128-
128+
#endif
129129
/// <summary>
130130
/// Create a SNI connection handle
131131
/// </summary>

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
using System;
88
using System.Diagnostics;
99
using System.Diagnostics.CodeAnalysis;
10+
using System.Net.Security;
1011
using System.Runtime.CompilerServices;
12+
using System.Text;
1113
using System.Threading;
1214
using System.Threading.Tasks;
1315
using Microsoft.Data.Common;
@@ -18,8 +20,11 @@ internal sealed class TdsParserStateObjectManaged : TdsParserStateObject
1820
{
1921
private SNIMarsConnection? _marsConnection;
2022
private SNIHandle? _sessionHandle;
23+
#if NET7_0_OR_GREATER
24+
private NegotiateAuthentication? _negotiateAuth = null;
25+
#else
2126
private SspiClientContextStatus? _sspiClientContextStatus;
22-
27+
#endif
2328
public TdsParserStateObjectManaged(TdsParser parser) : base(parser) { }
2429

2530
internal TdsParserStateObjectManaged(TdsParser parser, TdsParserStateObject physicalConnection, bool async) :
@@ -384,15 +389,26 @@ internal override uint SetConnectionBufferSize(ref uint unsignedPacketSize)
384389
return TdsEnums.SNI_SUCCESS;
385390
}
386391

387-
internal override uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
392+
internal override uint GenerateSspiClientContext(byte[] receivedBuff,
393+
uint receivedLength,
394+
ref byte[] sendBuff,
395+
ref uint sendLength,
396+
byte[][] _sniSpnBuffer)
388397
{
389-
if (_sspiClientContextStatus is null)
398+
#if NET7_0_OR_GREATER
399+
_negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) });
400+
sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!;
401+
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _sessionHandle?.ConnectionId, statusCode);
402+
if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded)
390403
{
391-
_sspiClientContextStatus = new SspiClientContextStatus();
404+
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode);
392405
}
406+
#else
407+
_sspiClientContextStatus ??= new SspiClientContextStatus();
393408

394409
SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer);
395410
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _sessionHandle?.ConnectionId);
411+
#endif
396412
sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0);
397413
return 0;
398414
}

0 commit comments

Comments
 (0)