Skip to content

Commit

Permalink
Dev | Add support of the new authentication API with SSPI token on Ma…
Browse files Browse the repository at this point in the history
…naged SNI (#2063)
  • Loading branch information
DavoudEshtehari authored Jun 29, 2023
1 parent 20ab3b1 commit 6fbb337
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ internal static partial class Libraries
internal const string Crypt32 = "crypt32.dll";
internal const string Kernel32 = "kernel32.dll";
internal const string NtDll = "ntdll.dll";
#if !NET7_0_OR_GREATER
internal const string SspiCli = "sspicli.dll";
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
</Compile>
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs">
<Link>Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs</Link>
</Compile>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlNotificationRequest.cs">
<Link>Microsoft\Data\Sql\SqlNotificationRequest.cs</Link>
</Compile>
Expand Down Expand Up @@ -517,7 +517,7 @@
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetFramework)' == 'netstandard2.0'">
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIStreams.Task.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIStreams.Task.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.NetStandard.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.NetStandard.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
Expand Down Expand Up @@ -622,7 +622,6 @@
<Compile Include="Microsoft\Data\SqlClient\SNI\SNITcpHandle.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNICommon.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SspiClientContextStatus.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SSRP.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlAppContextSwitchManager.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.cs" />
Expand Down Expand Up @@ -768,8 +767,35 @@
</Compile>
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Common.cs" />
</ItemGroup>
<!-- Windows dependencies for Integrated Authentication for MANAGED_SNI build -->
<!-- Windows dependencies for MANAGED_SNI build -->
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
<Link>Common\Interop\Windows\Interop.Libraries.cs</Link>
</Compile>
</ItemGroup>
<!-- Common (Windows and Unix) dependencies for MANAGED_SNI build -->
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS'">
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
<Link>Common\System\Net\InternalException.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Logging\NetEventSource.Common.cs">
<Link>Common\System\Net\Logging\NetEventSource.Common.cs</Link>
</Compile>
</ItemGroup>
<!-- Unix dependencies for Managed_SNI build-->
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
<Compile Include="Microsoft\Data\Sql\SqlDataSourceEnumerator.Unix.cs" />
<Compile Include="Interop\SNINativeMethodWrapper.Unix.cs" />
<Compile Include="Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\PacketHandle.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SessionHandle.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\LocalDB.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Unix.cs" />
</ItemGroup>
<!-- Windows dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
<ItemGroup Condition="'$(TargetsWindows)' == 'true' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
<Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs">
<Link>Common\CoreLib\Interop\Windows\Kernel32\Interop.CloseHandle.cs</Link>
</Compile>
Expand All @@ -779,9 +805,6 @@
<Compile Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.certificates_types.cs">
<Link>Common\Interop\Windows\Crypt32\Interop.certificates_types.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
<Link>Common\Interop\Windows\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs">
<Link>Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs</Link>
</Compile>
Expand All @@ -791,6 +814,30 @@
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs">
<Link>Common\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Collections\Generic\BidirectionalDictionary.cs">
<Link>Common\System\Collections\Generic\BidirectionalDictionary.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Windows.cs">
<Link>Common\System\Net\ContextFlagsAdapterPal.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs">
<Link>Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\SecurityContextTokenHandle.cs">
<Link>Common\System\Net\Security\SecurityContextTokenHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\SecurityStatusAdapterPal.Windows.cs">
<Link>Common\System\Net\SecurityStatusAdapterPal.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Windows.cs">
<Link>Common\System\Net\Security\NegotiateStreamPal.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.cs">
<Link>Common\System\Net\Security\NetEventSource.Security.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.Windows.cs">
<Link>Common\System\Net\Security\NetEventSource.Security.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\sspicli\GlobalSSPI.cs">
<Link>Common\Interop\Windows\sspicli\GlobalSSPI.cs</Link>
</Compile>
Expand Down Expand Up @@ -836,33 +883,9 @@
<Compile Include="$(CommonPath)\Interop\Windows\sspicli\SSPIWrapper.cs">
<Link>Common\Interop\Windows\sspicli\SSPIWrapper.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Collections\Generic\BidirectionalDictionary.cs">
<Link>Common\System\Collections\Generic\BidirectionalDictionary.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Windows.cs">
<Link>Common\System\Net\ContextFlagsAdapterPal.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs">
<Link>Common\System\Net\DebugCriticalHandleZeroOrMinusOneIsInvalid.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Windows.cs">
<Link>Common\System\Net\Security\NegotiateStreamPal.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.cs">
<Link>Common\System\Net\Security\NetEventSource.Security.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NetEventSource.Security.Windows.cs">
<Link>Common\System\Net\Security\NetEventSource.Security.Windows.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\SecurityContextTokenHandle.cs">
<Link>Common\System\Net\Security\SecurityContextTokenHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\SecurityStatusAdapterPal.Windows.cs">
<Link>Common\System\Net\SecurityStatusAdapterPal.Windows.cs</Link>
</Compile>
</ItemGroup>
<!-- Common (Windows and Unix) dependencies for MANAGED_SNI build -->
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS'">
<!-- Common (Windows and Unix) dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
<Compile Include="$(CommonPath)\System\Net\ContextFlagsPal.cs">
<Link>Common\System\Net\ContextFlagsPal.cs</Link>
</Compile>
Expand All @@ -872,15 +895,9 @@
<Compile Include="$(CommonPath)\System\Net\DebugSafeHandle.cs">
<Link>Common\System\Net\DebugSafeHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
<Link>Common\System\Net\InternalException.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Logging\DebugThreadTracking.cs">
<Link>Common\System\Net\Logging\DebugThreadTracking.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Logging\NetEventSource.Common.cs">
<Link>Common\System\Net\Logging\NetEventSource.Common.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\NegotiationInfoClass.cs">
<Link>Common\System\Net\NegotiationInfoClass.cs</Link>
</Compile>
Expand All @@ -893,8 +910,10 @@
<Compile Include="$(CommonPath)\System\Net\SecurityStatusPal.cs">
<Link>Common\System\Net\SecurityStatusPal.cs</Link>
</Compile>
<Compile Include="Microsoft\Data\SqlClient\SNI\SspiClientContextStatus.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
<!-- Unix dependencies for Integrated Authentication (SSPI) and MANAGED_SNI build before .NET 7.0-->
<ItemGroup Condition="'$(TargetsWindows)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND ($(TargetGroup)=='netstandard' OR '$(TargetFramework)' == 'net6.0')">
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
Expand All @@ -910,12 +929,6 @@
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\GssSafeHandles.cs">
<Link>Common\Microsoft\Win32\SafeHandles\GssSafeHandles.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Unix.cs">
<Link>Common\System\Net\ContextFlagsAdapterPal.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Unix.cs">
<Link>Common\System\Net\Security\NegotiateStreamPal.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\Unix\SafeDeleteContext.cs">
<Link>Common\System\Net\Security\Unix\SafeDeleteContext.cs</Link>
</Compile>
Expand All @@ -928,15 +941,12 @@
<Compile Include="$(CommonPath)\System\Net\Security\Unix\SafeFreeNegoCredentials.cs">
<Link>Common\System\Net\Security\Unix\SafeFreeNegoCredentials.cs</Link>
</Compile>
<Compile Include="Microsoft\Data\Sql\SqlDataSourceEnumerator.Unix.cs" />
<Compile Include="Interop\SNINativeMethodWrapper.Unix.cs" />
<Compile Include="Microsoft\Data\ProviderBase\DbConnectionPoolIdentity.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\PacketHandle.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SessionHandle.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\LocalDB.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Managed.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.Unix.cs" />
<Compile Include="$(CommonPath)\System\Net\ContextFlagsAdapterPal.Unix.cs">
<Link>Common\System\Net\ContextFlagsAdapterPal.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Net\Security\NegotiateStreamPal.Unix.cs">
<Link>Common\System\Net\Security\NegotiateStreamPal.Unix.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(IsUAPAssembly)' == 'true'">
<Reference Include="System.Collections.NonGeneric" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal class SNIProxy
private static readonly SNIProxy s_singleton = new SNIProxy();

internal static SNIProxy Instance => s_singleton;

#if !NET7_0_OR_GREATER
/// <summary>
/// Generate SSPI context
/// </summary>
Expand Down Expand Up @@ -105,11 +105,11 @@ internal static void GenSspiClientContext(SspiClientContextStatus sspiClientCont
// so we don't need to check for a GssApiException here.
if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError)
{
throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode);
throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + Environment.NewLine + statusCode);
}
else
{
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode);
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode);
}
}
}
Expand All @@ -125,7 +125,7 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
errorCode != SecurityStatusPalErrorCode.CredentialsNeeded &&
errorCode != SecurityStatusPalErrorCode.Renegotiate;
}

#endif
/// <summary>
/// Create a SNI connection handle
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.Security;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Common;
Expand All @@ -18,8 +20,11 @@ internal sealed class TdsParserStateObjectManaged : TdsParserStateObject
{
private SNIMarsConnection? _marsConnection;
private SNIHandle? _sessionHandle;
#if NET7_0_OR_GREATER
private NegotiateAuthentication? _negotiateAuth = null;
#else
private SspiClientContextStatus? _sspiClientContextStatus;

#endif
public TdsParserStateObjectManaged(TdsParser parser) : base(parser) { }

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

internal override uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer)
internal override uint GenerateSspiClientContext(byte[] receivedBuff,
uint receivedLength,
ref byte[] sendBuff,
ref uint sendLength,
byte[][] _sniSpnBuffer)
{
if (_sspiClientContextStatus is null)
#if NET7_0_OR_GREATER
_negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) });
sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!;
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _sessionHandle?.ConnectionId, statusCode);
if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded)
{
_sspiClientContextStatus = new SspiClientContextStatus();
throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode);
}
#else
_sspiClientContextStatus ??= new SspiClientContextStatus();

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

0 comments on commit 6fbb337

Please sign in to comment.