internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext?securityContext, string?spn, ContextFlagsPal requestedContextFlags, ReadOnlySpan <byte> incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, out int resultBlobLength, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, channelBinding, spn, requestedContextFlags, incomingBlob, out resultBlob, ref contextFlags); resultBlobLength = resultBlob?.Length ?? 0; return(status); }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } return(EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags)); }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential) : base(IntPtr.Zero) { Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext"); bool added = false; credential.DangerousAddRef(ref added); _credential = credential; _context = new SafeGssContextHandle(); }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string[] spns, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(Strings.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; SecurityStatusPal status = default; foreach (string spn in spns) { if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(Strings.net_nego_not_supported_empty_target_with_defaultcreds); } status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); if (status.ErrorCode != SecurityStatusPalErrorCode.InternalError) { break; // Successful case, exit the loop with current SPN. } else { securityContext = null; // Reset security context to be generated again for next SPN. } } // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(Strings.net_nego_protection_level_not_supported); } } return(status); }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName) : this(credential) { try { _targetName = SafeGssNameHandle.CreateTarget(targetName); } catch { Dispose(); throw; } }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName) : base(credential) { Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext"); try { _targetName = SafeGssNameHandle.CreatePrincipal(targetName); } catch { Dispose(); throw; } }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName) : base(credential) { Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext"); try { _targetNameKerberos = SafeGssNameHandle.CreateTarget(targetName, isNtlmTarget: false); _targetNameNtlm = SafeGssNameHandle.CreateTarget(targetName, isNtlmTarget: true); } catch { Dispose(); throw; } }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName) : this(credential) { try { // Convert any "SERVICE/HOST" style of targetName to use "SERVICE@HOST" style. // This is because the System.Net.Security.Native GSS-API layer uses // GSS_C_NT_HOSTBASED_SERVICE format for targetName. _targetName = SafeGssNameHandle.CreateTarget(targetName.Replace('/', '@')); } catch { Dispose(); throw; } }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityBuffer cbtBuffer = null; if ((inSecurityBufferArray != null) && (inSecurityBufferArray.Length > 1)) { Debug.Assert(inSecurityBufferArray[1].type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); cbtBuffer = inSecurityBufferArray[1]; } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, cbtBuffer, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); } } return(status); }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName) : base(IntPtr.Zero) { try { _targetName = SafeGssNameHandle.CreateTarget(targetName); _context = new SafeGssContextHandle(); } catch { Dispose(); throw; } _credential = credential; bool ignore = false; _credential.DangerousAddRef(ref ignore); }
internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext?securityContext, string?spn, ContextFlagsPal requestedContextFlags, byte[]?incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, channelBinding, spn, requestedContextFlags, incomingBlob, ref resultBlob, ref contextFlags); // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); } } return(status); }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential) : base(credential) { Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext"); _context = new SafeGssContextHandle(); }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, bool isNtlm, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { Debug.Assert(!isNtlm, "EstablishSecurityContext: NTLM is not yet supported"); if (context == null) { context = new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags); uint outputFlags; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = Interop.GssApi.EstablishSecurityContext( ref contextHandle, credential.GssCredential, isNtlm, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } SecurityStatusPalErrorCode errorCode = done ? SecurityStatusPalErrorCode.CompleteNeeded : SecurityStatusPalErrorCode.ContinueNeeded; return new SecurityStatusPal(errorCode); } catch(Exception ex) { //TODO (Issue #5890): Print exception until issue is fixed Debug.Write("Exception Caught. - " + ex); if (GlobalLog.IsEnabled) { GlobalLog.Print("Exception Caught. - " + ex); } return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex); } }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext?context, ChannelBinding?channelBinding, string?targetName, ContextFlagsPal inFlags, byte[]?incomingBlob, ref byte[]?resultBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; if (context == null) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : "SPNEGO"; NetEventSource.Info(context, $"requested protocol = {protocol}, target = {targetName}"); } context = new SafeDeleteNegoContext(credential, targetName !); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false); uint outputFlags; bool isNtlmUsed; SafeGssContextHandle?contextHandle = negoContext.GssContext; bool done = GssInitSecurityContext( ref contextHandle, credential.GssCredential, isNtlmOnly, channelBinding, negoContext.TargetName, inputFlags, incomingBlob, out resultBuffer, out outputFlags, out isNtlmUsed); if (done) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos"; NetEventSource.Info(context, $"actual protocol = {protocol}"); } // Populate protocol used for authentication negoContext.SetAuthenticationPackage(isNtlmUsed); } Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi"); outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop( (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle !); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && resultBuffer.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; if (context == null) { // Empty target name causes the failure on Linux, hence passing a non-empty string context = isNtlmOnly ? new SafeDeleteNegoContext(credential, credential.UserName) : new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false); uint outputFlags; int isNtlmUsed; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = GssInitSecurityContext( ref contextHandle, credential.GssCredential, isNtlmOnly, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags, out isNtlmUsed); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } // Populate protocol used for authentication if (done) { negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed)); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && outputBuffer.size > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { if (NetEventSource.IsEnabled) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential) : base(credential) { Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext"); }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; if (context == null) { // Empty target name causes the failure on Linux, hence passing a non-empty string context = isNtlmOnly ? new SafeDeleteNegoContext(credential, credential.UserName) : new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer:false); uint outputFlags; int isNtlmUsed; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = GssInitSecurityContext( ref contextHandle, credential.GssCredential, isNtlmOnly, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags, out isNtlmUsed); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags, isServer:false); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } // Populate protocol used for authentication if (done) { negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed)); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && outputBuffer.size > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return new SecurityStatusPal(errorCode); } catch(Exception ex) { if (NetEventSource.IsEnabled) NetEventSource.Error(null, ex); return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex); } }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, bool isNtlm, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { Debug.Assert(!isNtlm, "EstablishSecurityContext: NTLM is not yet supported"); if (context == null) { context = new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags); uint outputFlags; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = Interop.GssApi.EstablishSecurityContext( ref contextHandle, credential.GssCredential, isNtlm, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } SecurityStatusPalErrorCode errorCode = done ? SecurityStatusPalErrorCode.CompleteNeeded : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { //TODO (Issue #5890): Print exception until issue is fixed Debug.Write("Exception Caught. - " + ex); if (GlobalLog.IsEnabled) { GlobalLog.Print("Exception Caught. - " + ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext?context, ChannelBinding?channelBinding, string?targetName, ContextFlagsPal inFlags, ReadOnlySpan <byte> incomingBlob, out byte[]?resultBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; resultBuffer = null; if (context == null) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : "SPNEGO"; NetEventSource.Info(context, $"requested protocol = {protocol}, target = {targetName}"); } context = new SafeDeleteNegoContext(credential, targetName !); } Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer); Interop.NetSecurityNative.Status status; Interop.NetSecurityNative.Status minorStatus; SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; SafeGssContextHandle contextHandle = negoContext.GssContext; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false); uint outputFlags; bool isNtlmUsed; if (channelBinding != null) { // If a TLS channel binding token (cbt) is available then get the pointer // to the application specific data. int appDataOffset = Marshal.SizeOf <SecChannelBindings>(); Debug.Assert(appDataOffset < channelBinding.Size); IntPtr cbtAppData = channelBinding.DangerousGetHandle() + appDataOffset; int cbtAppDataSize = channelBinding.Size - appDataOffset; status = Interop.NetSecurityNative.InitSecContext(out minorStatus, credential.GssCredential, ref contextHandle, isNtlmOnly, cbtAppData, cbtAppDataSize, negoContext.TargetName, (uint)inputFlags, incomingBlob, ref token, out outputFlags, out isNtlmUsed); } else { status = Interop.NetSecurityNative.InitSecContext(out minorStatus, credential.GssCredential, ref contextHandle, isNtlmOnly, negoContext.TargetName, (uint)inputFlags, incomingBlob, ref token, out outputFlags, out isNtlmUsed); } if ((status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE) && (status != Interop.NetSecurityNative.Status.GSS_S_CONTINUE_NEEDED)) { if (negoContext.GssContext.IsInvalid) { context.Dispose(); } Interop.NetSecurityNative.GssApiException gex = new Interop.NetSecurityNative.GssApiException(status, minorStatus); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, gex); } resultBuffer = Array.Empty <byte>(); return(new SecurityStatusPal(GetErrorCode(gex), gex)); } resultBuffer = token.ToByteArray(); if (status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos"; NetEventSource.Info(context, $"actual protocol = {protocol}"); } // Populate protocol used for authentication negoContext.SetAuthenticationPackage(isNtlmUsed); } Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi"); outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop( (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false); SecurityStatusPalErrorCode errorCode = status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } finally { token.Dispose(); // Save the inner context handle for further calls to NetSecurity // // For the first call `negoContext.GssContext` is invalid and we expect the // inital handle to be returned from InitSecContext. For any subsequent // call the handle should stay the same or it can be destroyed by the native // InitSecContext call. Debug.Assert( negoContext.GssContext == contextHandle || negoContext.GssContext.IsInvalid || contextHandle.IsInvalid); negoContext.SetGssContext(contextHandle); } }