// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { if (GlobalLog.IsEnabled) { GlobalLog.Enter("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes"); } var list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.Token)); } if (_channelBinding != null) { list.Add(new SecurityBuffer(_channelBinding)); } SecurityBuffer[] inSecurityBufferArray = null; if (list.Count > 0) { inSecurityBufferArray = list.ToArray(); } var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.Token); bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = NegotiateStreamPal.InitializeSecurityContext( _credentialsHandle, ref _securityContext, _spn, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { var inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, inSecurityBuffers); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } outSecurityBuffer.token = null; } } else { // Server session. statusCode = NegotiateStreamPal.AcceptSecurityContext( _credentialsHandle, ref _securityContext, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime && _credentialsHandle != null) { _credentialsHandle.Dispose(); } } if (NegoState.IsError(statusCode)) { CloseContext(); _isCompleted = true; if (throwOnError) { Exception exception = NegotiateStreamPal.CreateExceptionFromError(statusCode); if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception); } throw exception; } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value will tell us correctly if the handshake is over or not if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK) { // Success. _isCompleted = true; } else if (GlobalLog.IsEnabled) { // We need to continue. GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode.ErrorCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:" + LoggingHash.ObjectToString(_securityContext) + "]"); } if (GlobalLog.IsEnabled) { GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString()); } return(outSecurityBuffer.token); }
// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this, incomingBlob); } SecurityBuffer[] inSecurityBufferArray = null; if (incomingBlob != null && _channelBinding != null) { inSecurityBufferArray = new SecurityBuffer[2] { new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN), new SecurityBuffer(_channelBinding) }; } else if (incomingBlob != null) { inSecurityBufferArray = new SecurityBuffer[1] { new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN) }; } else if (_channelBinding != null) { inSecurityBufferArray = new SecurityBuffer[1] { new SecurityBuffer(_channelBinding) }; } var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.SECBUFFER_TOKEN); bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = NegotiateStreamPal.InitializeSecurityContext( _credentialsHandle, ref _securityContext, _spn, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"SSPIWrapper.InitializeSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { var inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, inSecurityBuffers); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"SSPIWrapper.CompleteAuthToken() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } outSecurityBuffer.token = null; } } else { // Server session. statusCode = NegotiateStreamPal.AcceptSecurityContext( _credentialsHandle, ref _securityContext, _requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"SSPIWrapper.AcceptSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime && _credentialsHandle != null) { _credentialsHandle.Dispose(); } } if (((int)statusCode.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory)) { CloseContext(); _isCompleted = true; if (throwOnError) { Exception exception = NegotiateStreamPal.CreateExceptionFromError(statusCode); if (NetEventSource.IsEnabled) { NetEventSource.Exit(this, exception); } throw exception; } if (NetEventSource.IsEnabled) { NetEventSource.Exit(this, $"null statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value will tell us correctly if the handshake is over or not if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK) { // Success. _isCompleted = true; } else if (NetEventSource.IsEnabled) { // We need to continue. if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"need continue statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode}) _securityContext:{_securityContext}"); } } if (NetEventSource.IsEnabled) { if (NetEventSource.IsEnabled) { NetEventSource.Exit(this, $"IsCompleted: {IsCompleted}"); } } return(outSecurityBuffer.token); }
internal byte[]? GetOutgoingBlob(ReadOnlySpan <byte> incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { _tokenBuffer ??= _tokenSize == 0 ? Array.Empty <byte>() : new byte[_tokenSize]; bool firstTime = _securityContext == null; int resultBlobLength; try { if (!_isServer) { // client session statusCode = NegotiateStreamPal.InitializeSecurityContext( ref _credentialsHandle !, ref _securityContext, _spn, _requestedContextFlags, incomingBlob, _channelBinding, ref _tokenBuffer, out resultBlobLength, ref _contextFlags); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.InitializeSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, _tokenBuffer.AsSpan(0, resultBlobLength)); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.CompleteAuthToken() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } resultBlobLength = 0; } } else { // Server session. statusCode = NegotiateStreamPal.AcceptSecurityContext( _credentialsHandle, ref _securityContext, _requestedContextFlags, incomingBlob, _channelBinding, ref _tokenBuffer, out resultBlobLength, ref _contextFlags); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.AcceptSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime) { _credentialsHandle?.Dispose(); } } if (((int)statusCode.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory)) { CloseContext(); _isCompleted = true; _tokenBuffer = null; if (throwOnError) { throw NegotiateStreamPal.CreateExceptionFromError(statusCode); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } byte[]? result = resultBlobLength == 0 || _tokenBuffer == null ? null : _tokenBuffer.Length == resultBlobLength ? _tokenBuffer : _tokenBuffer[0..resultBlobLength];
// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Interop.SecurityStatus statusCode) { GlobalLog.Enter("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes"); var list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.Token)); } if (_channelBinding != null) { list.Add(new SecurityBuffer(_channelBinding)); } SecurityBuffer[] inSecurityBufferArray = null; if (list.Count > 0) { inSecurityBufferArray = list.ToArray(); } var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.Token); bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = (Interop.SecurityStatus)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, _credentialsHandle, ref _securityContext, _spn, _requestedContextFlags, Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); if (statusCode == Interop.SecurityStatus.CompleteNeeded) { var inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = (Interop.SecurityStatus)SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref _securityContext, inSecurityBuffers); GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); outSecurityBuffer.token = null; } } else { // Server session. statusCode = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, _credentialsHandle, ref _securityContext, _requestedContextFlags, Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref _contextFlags); GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime && _credentialsHandle != null) { _credentialsHandle.Dispose(); } } if (((int)statusCode & unchecked ((int)0x80000000)) != 0) { CloseContext(); _isCompleted = true; if (throwOnError) { var exception = new Win32Exception((int)statusCode); GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception); throw exception; } GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value from SSPI will tell us correctly if the // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm // we also have to consider the case in which SSPI formed a new context, in this case we're done as well. if (statusCode == Interop.SecurityStatus.OK) { // Success. if ((statusCode == Interop.SecurityStatus.OK) && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", LoggingHash.HashString(this), (int)statusCode, statusCode, LoggingHash.HashString(_securityContext), LoggingHash.ObjectToString(_securityContext)); } _isCompleted = true; } else { // We need to continue. GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:" + LoggingHash.ObjectToString(_securityContext) + "]"); } GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString()); return(outSecurityBuffer.token); }
// Accepts an incoming binary security blob and returns an outgoing binary security blob. internal byte[]? GetOutgoingBlob(byte[]?incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { byte[]? result = new byte[_tokenSize]; bool firstTime = _securityContext == null; try { if (!_isServer) { // client session statusCode = NegotiateStreamPal.InitializeSecurityContext( ref _credentialsHandle !, ref _securityContext, _spn, _requestedContextFlags, incomingBlob, _channelBinding, ref result, ref _contextFlags); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.InitializeSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, result); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.CompleteAuthToken() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } result = null; } } else { // Server session. statusCode = NegotiateStreamPal.AcceptSecurityContext( _credentialsHandle, ref _securityContext, _requestedContextFlags, incomingBlob, _channelBinding, ref result, ref _contextFlags); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"SSPIWrapper.AcceptSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})"); } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successful the handle is physically destroyed here. // if (firstTime) { _credentialsHandle?.Dispose(); } } if (((int)statusCode.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory)) { CloseContext(); _isCompleted = true; if (throwOnError) { throw NegotiateStreamPal.CreateExceptionFromError(statusCode); } return(null); } else if (firstTime && _credentialsHandle != null) { // Cache until it is pushed out by newly incoming handles. SSPIHandleCache.CacheCredential(_credentialsHandle); } // The return value will tell us correctly if the handshake is over or not if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK || (_isServer && statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded)) { // Success. _isCompleted = true; } else { // We need to continue. if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"need continue statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode}) _securityContext:{_securityContext}"); } } return(result); }
internal string GetOutgoingDigestBlob(string incomingBlob, string requestMethod, string requestedUri, string realm, bool isClientPreAuth, bool throwOnError, out SecurityStatus statusCode) { SecurityBuffer[] inputBuffers = null; SecurityBuffer outputBuffer = new SecurityBuffer(this.m_TokenSize, isClientPreAuth ? BufferType.Parameters : BufferType.Token); bool flag = this.m_SecurityContext == null; try { if (!this.m_IsServer) { if (!isClientPreAuth) { if (incomingBlob != null) { List <SecurityBuffer> list = new List <SecurityBuffer>(5) { new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), 2), new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), 3), new SecurityBuffer(null, 3), new SecurityBuffer(Encoding.Unicode.GetBytes(this.m_Spn), 0x10) }; if (this.m_ChannelBinding != null) { list.Add(new SecurityBuffer(this.m_ChannelBinding)); } inputBuffers = list.ToArray(); } statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, requestedUri, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags); } else { statusCode = SecurityStatus.OK; } } else { List <SecurityBuffer> list2 = new List <SecurityBuffer>(6) { (incomingBlob == null) ? new SecurityBuffer(0, BufferType.Token) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), BufferType.Token), (requestMethod == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters), (requestedUri == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters), new SecurityBuffer(0, BufferType.Parameters), (realm == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(Encoding.Unicode.GetBytes(realm), BufferType.Parameters) }; if (this.m_ChannelBinding != null) { list2.Add(new SecurityBuffer(this.m_ChannelBinding)); } inputBuffers = list2.ToArray(); statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags); if (statusCode == SecurityStatus.CompleteNeeded) { inputBuffers[4] = outputBuffer; statusCode = (SecurityStatus)SSPIWrapper.CompleteAuthToken(GlobalSSPI.SSPIAuth, ref this.m_SecurityContext, inputBuffers); outputBuffer.token = null; } } } finally { if (flag && (this.m_CredentialsHandle != null)) { this.m_CredentialsHandle.Close(); } } if ((statusCode & ((SecurityStatus)(-2147483648))) != SecurityStatus.OK) { this.CloseContext(); if (throwOnError) { Win32Exception exception = new Win32Exception((int)statusCode); throw exception; } return(null); } if (flag && (this.m_CredentialsHandle != null)) { SSPIHandleCache.CacheCredential(this.m_CredentialsHandle); } if (statusCode == SecurityStatus.OK) { this.m_IsCompleted = true; } byte[] token = outputBuffer.token; string str = null; if ((token != null) && (token.Length > 0)) { str = WebHeaderCollection.HeaderEncoding.GetString(token, 0, outputBuffer.size); } return(str); }
internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatus statusCode) { List <SecurityBuffer> list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } if (this.m_ChannelBinding != null) { list.Add(new SecurityBuffer(this.m_ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } SecurityBuffer outputBuffer = new SecurityBuffer(this.m_TokenSize, BufferType.Token); bool flag = this.m_SecurityContext == null; try { if (!this.m_IsServer) { statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_Spn, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags); if (statusCode == SecurityStatus.CompleteNeeded) { SecurityBuffer[] bufferArray2 = new SecurityBuffer[] { outputBuffer }; statusCode = (SecurityStatus)SSPIWrapper.CompleteAuthToken(GlobalSSPI.SSPIAuth, ref this.m_SecurityContext, bufferArray2); outputBuffer.token = null; } } else { statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags); } } finally { if (flag && (this.m_CredentialsHandle != null)) { this.m_CredentialsHandle.Close(); } } if ((statusCode & ((SecurityStatus)(-2147483648))) != SecurityStatus.OK) { this.CloseContext(); this.m_IsCompleted = true; if (throwOnError) { Win32Exception exception = new Win32Exception((int)statusCode); throw exception; } return(null); } if (flag && (this.m_CredentialsHandle != null)) { SSPIHandleCache.CacheCredential(this.m_CredentialsHandle); } if (statusCode == SecurityStatus.OK) { this.m_IsCompleted = true; } return(outputBuffer.token); }