// This will return a client token when conducted authentication on server side. // This token can be used for impersonation. We use it to create a WindowsIdentity and hand it out to the server app. internal SecurityContextTokenHandle GetContextToken(out Interop.SecurityStatus status) { if ((IsCompleted && IsValidContext) && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetContextToken|Should be called only when completed with success, currently is not!", LoggingHash.HashString(this)); } if (IsServer && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetContextToken|The method must not be called by the client side!", LoggingHash.HashString(this)); } if (!IsValidContext) { throw new Win32Exception((int)Interop.SecurityStatus.InvalidHandle); } SecurityContextTokenHandle token = null; status = (Interop.SecurityStatus)SSPIWrapper.QuerySecurityContextToken( GlobalSSPI.SSPIAuth, _securityContext, out token); return(token); }
// // readBytes == SSL Data Payload size on input or 0 on EOF // private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (readBytes == 0) { // EOF throw new IOException(SR.net_io_eof); } // Set readBytes to total number of received bytes. readBytes += SecureChannel.ReadHeaderSize; // Decrypt into internal buffer, change "readBytes" to count now _Decrypted Bytes_. int data_offset = 0; Interop.SecurityStatus errorCode = _SslState.DecryptData(InternalBuffer, ref data_offset, ref readBytes); if (errorCode != Interop.SecurityStatus.OK) { byte[] extraBuffer = null; if (readBytes != 0) { extraBuffer = new byte[readBytes]; Buffer.BlockCopy(InternalBuffer, data_offset, extraBuffer, 0, readBytes); } // Reset internal buffer count. SkipBytes(InternalBufferCount); return(ProcessReadErrorCode(errorCode, buffer, offset, count, asyncRequest, extraBuffer)); } if (readBytes == 0 && count != 0) { // Read again since remote side has sent encrypted 0 bytes. SkipBytes(InternalBufferCount); return(-1); } // Decrypted data start from "data_offset" offset, the total count can be shrunk after decryption. EnsureInternalBufferSize(0, data_offset + readBytes); SkipBytes(data_offset); if (readBytes > count) { readBytes = count; } Buffer.BlockCopy(InternalBuffer, InternalOffset, buffer, offset, readBytes); // This will adjust both the remaining internal buffer count and the offset. SkipBytes(readBytes); _SslState.FinishRead(null); if (asyncRequest != null) { asyncRequest.CompleteUser((object)readBytes); } return(readBytes); }
// // Only processing SEC_I_RENEGOTIATE. // private int ProcessReadErrorCode(Interop.SecurityStatus errorCode, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest, byte[] extraBuffer) { // ERROR - examine what kind ProtocolToken message = new ProtocolToken(null, errorCode); GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::***Processing an error Status = " + message.Status.ToString()); if (message.Renegotiate) { _SslState.ReplyOnReAuthentication(extraBuffer); // Loop on read. return(-1); } if (message.CloseConnection) { _SslState.FinishRead(null); if (asyncRequest != null) { asyncRequest.CompleteUser((object)0); } return(0); } throw new IOException(SR.net_io_decrypt, message.GetException()); }
public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext, byte[] buffer, ref int offset, ref int count) { // Decryption using SCHANNEL requires four buffers. SecurityBuffer[] decspc = new SecurityBuffer[4]; decspc[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.Data); decspc[1] = new SecurityBuffer(null, SecurityBufferType.Empty); decspc[2] = new SecurityBuffer(null, SecurityBufferType.Empty); decspc[3] = new SecurityBuffer(null, SecurityBufferType.Empty); Interop.SecurityStatus errorCode = (Interop.SecurityStatus)SSPIWrapper.DecryptMessage( GlobalSSPI.SSPISecureChannel, securityContext, decspc, 0); count = 0; for (int i = 0; i < decspc.Length; i++) { // Successfully decoded data and placed it at the following position in the buffer, if ((errorCode == Interop.SecurityStatus.OK && decspc[i].type == SecurityBufferType.Data) // or we failed to decode the data, here is the encoded data. || (errorCode != Interop.SecurityStatus.OK && decspc[i].type == SecurityBufferType.Extra)) { offset = decspc[i].offset; count = decspc[i].size; break; } } return(GetSecurityStatusPalFromInterop(errorCode)); }
internal void OperationReturnedSomething(string operation, Interop.SecurityStatus errorCode) { if (!s_log.IsEnabled()) { return; } WriteEvent(OPERATION_RETURNED_SOMETHING_ID, operation, errorCode); }
internal void OperationReturnedSomething(string operation, Interop.SecurityStatus errorCode) { if (!s_log.IsEnabled()) { return; } WriteEvent(OperationReturnedSomethingId, operation, errorCode); }
internal static SecurityStatusPal CompleteAuthToken( ref SafeDeleteContext securityContext, SecurityBuffer[] inSecurityBufferArray) { Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref securityContext, inSecurityBufferArray); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal static SecurityStatusPal GetSecurityStatusPalFromInterop(Interop.SecurityStatus win32SecurityStatus) { SecurityStatusPalErrorCode statusCode; if (!s_statusDictionary.TryGetForward(win32SecurityStatus, out statusCode)) { Debug.Fail("Unknown Interop.SecurityStatus value: " + win32SecurityStatus); throw new InternalException(); } return(new SecurityStatusPal(statusCode)); }
internal static IIdentity GetIdentity(NTAuthentication context) { IIdentity result = null; string name = context.IsServer ? context.AssociatedName : context.Spn; string protocol = context.ProtocolName; if (context.IsServer) { SecurityContextTokenHandle token = null; try { SecurityStatusPal status; SafeDeleteContext securityContext = context.GetContext(out status); if (status.ErrorCode != SecurityStatusPalErrorCode.OK) { throw new Win32Exception((int)SecurityStatusAdapterPal.GetInteropFromSecurityStatusPal(status)); } // This will return a client token when conducted authentication on server side. // This token can be used for impersonation. We use it to create a WindowsIdentity and hand it out to the server app. Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.QuerySecurityContextToken( GlobalSSPI.SSPIAuth, securityContext, out token); if (winStatus != Interop.SecurityStatus.OK) { throw new Win32Exception((int)winStatus); } string authtype = context.ProtocolName; // TODO #5241: // The following call was also specifying WindowsAccountType.Normal, true. // WindowsIdentity.IsAuthenticated is no longer supported in CoreFX. result = new WindowsIdentity(token.DangerousGetHandle(), authtype); return(result); } catch (SecurityException) { // Ignore and construct generic Identity if failed due to security problem. } finally { if (token != null) { token.Dispose(); } } } // On the client we don't have access to the remote side identity. result = new GenericIdentity(name, protocol); return(result); }
private SecurityStatus MapToSecurityStatus(Interop.SecurityStatus secStatus) { SecurityStatus retStatus; if (SecurityStatus.TryParse(secStatus.ToString(), out retStatus)) { return(retStatus); } else { throw new Win32Exception("Coulbd not map from Interop.SecurityStatus to SecurityStatus. Interop.SecurityStatus value:" + secStatus.ToString()); } }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal unsafe static SafeFreeCredentials AcquireCredentialsHandle(string package, bool isServer, NetworkCredential credential) { SafeSspiAuthDataHandle authData = null; try { Interop.SecurityStatus result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity( credential.UserName, credential.Domain, credential.Password, out authData); if (result != Interop.SecurityStatus.OK) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.PrintError( NetEventSource.ComponentType.Security, SR.Format( SR.net_log_operation_failed_with_error, "SspiEncodeStringsAsAuthIdentity()", String.Format(CultureInfo.CurrentCulture, "0x{0:X}", (int)result))); } throw new Win32Exception((int)result); } return(SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPIAuth, package, (isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound), ref authData)); } finally { if (authData != null) { authData.Dispose(); } } }
private static SecurityStatusPal GetSecurityStatusPalFromInterop(Interop.SecurityStatus win32SecurityStatus) { switch (win32SecurityStatus) { case Interop.SecurityStatus.OK: return(SecurityStatusPal.OK); case Interop.SecurityStatus.ContinueNeeded: return(SecurityStatusPal.ContinueNeeded); case Interop.SecurityStatus.CompleteNeeded: return(SecurityStatusPal.CompleteNeeded); case Interop.SecurityStatus.CompAndContinue: return(SecurityStatusPal.CompAndContinue); case Interop.SecurityStatus.ContextExpired: return(SecurityStatusPal.ContextExpired); case Interop.SecurityStatus.CredentialsNeeded: return(SecurityStatusPal.CredentialsNeeded); case Interop.SecurityStatus.Renegotiate: return(SecurityStatusPal.Renegotiate); case Interop.SecurityStatus.OutOfMemory: return(SecurityStatusPal.OutOfMemory); case Interop.SecurityStatus.InvalidHandle: return(SecurityStatusPal.InvalidHandle); case Interop.SecurityStatus.Unsupported: return(SecurityStatusPal.Unsupported); case Interop.SecurityStatus.TargetUnknown: return(SecurityStatusPal.TargetUnknown); case Interop.SecurityStatus.InternalError: return(SecurityStatusPal.InternalError); case Interop.SecurityStatus.PackageNotFound: return(SecurityStatusPal.PackageNotFound); case Interop.SecurityStatus.NotOwner: return(SecurityStatusPal.NotOwner); case Interop.SecurityStatus.CannotInstall: return(SecurityStatusPal.CannotInstall); case Interop.SecurityStatus.InvalidToken: return(SecurityStatusPal.InvalidToken); case Interop.SecurityStatus.CannotPack: return(SecurityStatusPal.CannotPack); case Interop.SecurityStatus.QopNotSupported: return(SecurityStatusPal.QopNotSupported); case Interop.SecurityStatus.NoImpersonation: return(SecurityStatusPal.NoImpersonation); case Interop.SecurityStatus.LogonDenied: return(SecurityStatusPal.LogonDenied); case Interop.SecurityStatus.UnknownCredentials: return(SecurityStatusPal.UnknownCredentials); case Interop.SecurityStatus.NoCredentials: return(SecurityStatusPal.NoCredentials); case Interop.SecurityStatus.MessageAltered: return(SecurityStatusPal.MessageAltered); case Interop.SecurityStatus.OutOfSequence: return(SecurityStatusPal.OutOfSequence); case Interop.SecurityStatus.NoAuthenticatingAuthority: return(SecurityStatusPal.NoAuthenticatingAuthority); case Interop.SecurityStatus.IncompleteMessage: return(SecurityStatusPal.IncompleteMessage); case Interop.SecurityStatus.IncompleteCredentials: return(SecurityStatusPal.IncompleteCredentials); case Interop.SecurityStatus.BufferNotEnough: return(SecurityStatusPal.BufferNotEnough); case Interop.SecurityStatus.WrongPrincipal: return(SecurityStatusPal.WrongPrincipal); case Interop.SecurityStatus.TimeSkew: return(SecurityStatusPal.TimeSkew); case Interop.SecurityStatus.UntrustedRoot: return(SecurityStatusPal.UntrustedRoot); case Interop.SecurityStatus.IllegalMessage: return(SecurityStatusPal.IllegalMessage); case Interop.SecurityStatus.CertUnknown: return(SecurityStatusPal.CertUnknown); case Interop.SecurityStatus.CertExpired: return(SecurityStatusPal.CertExpired); case Interop.SecurityStatus.AlgorithmMismatch: return(SecurityStatusPal.AlgorithmMismatch); case Interop.SecurityStatus.SecurityQosFailed: return(SecurityStatusPal.SecurityQosFailed); case Interop.SecurityStatus.SmartcardLogonRequired: return(SecurityStatusPal.SmartcardLogonRequired); case Interop.SecurityStatus.UnsupportedPreauth: return(SecurityStatusPal.UnsupportedPreauth); case Interop.SecurityStatus.BadBinding: return(SecurityStatusPal.BadBinding); default: Debug.Fail("Unknown Interop.SecurityStatus value: " + win32SecurityStatus); throw new InternalException(); } }
internal unsafe void SecurityContextInputBuffer(string context, int inputBufferSize, int outputBufferSize, Interop.SecurityStatus errorCode) { if (!s_log.IsEnabled()) { return; } fixed(char *arg1Ptr = context) { const int SIZEDATA = 4; EventData *dataDesc = stackalloc EventSource.EventData[SIZEDATA]; dataDesc[0].DataPointer = (IntPtr)(arg1Ptr); dataDesc[0].Size = (context.Length + 1) * sizeof(char); dataDesc[1].DataPointer = (IntPtr)(&inputBufferSize); dataDesc[1].Size = sizeof(int); dataDesc[2].DataPointer = (IntPtr)(&outputBufferSize); dataDesc[2].Size = sizeof(int); dataDesc[3].DataPointer = (IntPtr)(&errorCode); dataDesc[3].Size = sizeof(int); WriteEventCore(SECURITY_CONTEXT_INPUT_BUFFER_ID, SIZEDATA, dataDesc); } }
internal ProtocolToken(byte[] data, Interop.SecurityStatus errorCode) { Status = errorCode; Payload = data; Size = data != null ? data.Length : 0; }
private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, Interop.SspiCli.ContextFlags requestedContextFlags, ChannelBinding channelBinding) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor() package:" + LoggingHash.ObjectToString(package) + " spn:" + LoggingHash.ObjectToString(spn) + " flags :" + requestedContextFlags.ToString()); _tokenSize = SSPIWrapper.GetVerifyPackageInfo(GlobalSSPI.SSPIAuth, package, true).MaxToken; _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; GlobalLog.Print("Peer SPN-> '" + _spn + "'"); // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor(): using DefaultCredentials"); _credentialsHandle = SSPIWrapper.AcquireDefaultCredential( GlobalSSPI.SSPIAuth, package, (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound)); } else { unsafe { SafeSspiAuthDataHandle authData = null; try { Interop.SecurityStatus result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity( credential.UserName, credential.Domain, credential.Password, out authData); if (result != Interop.SecurityStatus.OK) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.PrintError( NetEventSource.ComponentType.Security, SR.Format( SR.net_log_operation_failed_with_error, "SspiEncodeStringsAsAuthIdentity()", String.Format(CultureInfo.CurrentCulture, "0x{0:X}", (int)result))); } throw new Win32Exception((int)result); } _credentialsHandle = SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPIAuth, package, (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound), ref authData); } finally { if (authData != null) { authData.Dispose(); } } } } }
private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (asyncRequest != null) { asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback); } // We loop to this method from the callback. // If the last chunk was just completed from async callback (count < 0), we complete user request. if (count >= 0) { byte[] outBuffer = null; if (_PinnableOutputBufferInUse == null) { if (_PinnableOutputBuffer == null) { _PinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer(); } _PinnableOutputBufferInUse = buffer; outBuffer = _PinnableOutputBuffer; if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); } } else { if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.StartWriting BufferInUse", this.GetHashCode(), count); } } do { // Request a write IO slot. if (_SslState.CheckEnqueueWrite(asyncRequest)) { // Operation is async and has been queued, return. return; } int chunkBytes = Math.Min(count, _SslState.MaxDataSize); int encryptedBytes; Interop.SecurityStatus errorCode = _SslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes); if (errorCode != Interop.SecurityStatus.OK) { ProtocolToken message = new ProtocolToken(null, errorCode); throw new IOException(SR.net_io_encrypt, message.GetException()); } if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Got Encrypted Buffer", this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); } if (asyncRequest != null) { // Prepare for the next request. asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback); IAsyncResult ar = _SslState.InnerStreamAPM.BeginWrite(outBuffer, 0, encryptedBytes, s_writeCallback, asyncRequest); if (!ar.CompletedSynchronously) { return; } _SslState.InnerStreamAPM.EndWrite(ar); } else { _SslState.InnerStream.Write(outBuffer, 0, encryptedBytes); } offset += chunkBytes; count -= chunkBytes; // Release write IO slot. _SslState.FinishWrite(); } while (count != 0); } if (asyncRequest != null) { asyncRequest.CompleteUser(); } if (buffer == _PinnableOutputBufferInUse) { _PinnableOutputBufferInUse = null; if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWriting Freeing buffer.", this.GetHashCode()); } } }
// // Client side starts here, but server also loops through this method. // private void StartSendBlob(byte[] incoming, int count, AsyncProtocolRequest asyncRequest) { ProtocolToken message = Context.NextMessage(incoming, 0, count); _securityStatus = message.Status; if (message.Size != 0) { if (Context.IsServer && _CachedSession == CachedSessionStatus.Unknown) { // //[Schannel] If the first call to ASC returns a token less than 200 bytes, // then it's a reconnect (a handshake based on a cache entry). // _CachedSession = message.Size < 200 ? CachedSessionStatus.IsCached : CachedSessionStatus.IsNotCached; } if (_Framing == Framing.Unified) { _Framing = DetectFraming(message.Payload, message.Payload.Length); } if (asyncRequest == null) { InnerStream.Write(message.Payload, 0, message.Size); } else { asyncRequest.AsyncState = message; IAsyncResult ar = InnerStreamAPM.BeginWrite(message.Payload, 0, message.Size, s_writeCallback, asyncRequest); if (!ar.CompletedSynchronously) { #if DEBUG asyncRequest._DebugAsyncChain = ar; #endif return; } InnerStreamAPM.EndWrite(ar); } } CheckCompletionBeforeNextReceive(message, asyncRequest); }
// 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); }
internal unsafe void SecurityContextInputBuffers(string context, int inputBuffersSize, int outputBufferSize, Interop.SecurityStatus errorCode) { if (!s_log.IsEnabled()) { return; } fixed(char *arg1Ptr = context) { const int SizeData = 4; EventData *dataDesc = stackalloc EventSource.EventData[SizeData]; dataDesc[0].DataPointer = (IntPtr)(arg1Ptr); dataDesc[0].Size = (context.Length + 1) * sizeof(char); dataDesc[1].DataPointer = (IntPtr)(&inputBuffersSize); dataDesc[1].Size = sizeof(int); dataDesc[2].DataPointer = (IntPtr)(&outputBufferSize); dataDesc[2].Size = sizeof(int); dataDesc[3].DataPointer = (IntPtr)(&errorCode); dataDesc[3].Size = sizeof(int); WriteEventCore(SecurityContextInputBuffersId, SizeData, dataDesc); } }