Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        //
        // 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);
        }
Esempio n. 3
0
        //
        // 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));
        }
Esempio n. 5
0
 internal void OperationReturnedSomething(string operation, Interop.SecurityStatus errorCode)
 {
     if (!s_log.IsEnabled())
     {
         return;
     }
     WriteEvent(OPERATION_RETURNED_SOMETHING_ID, operation, errorCode);
 }
Esempio n. 6
0
        internal void OperationReturnedSomething(string operation, Interop.SecurityStatus errorCode)
        {
            if (!s_log.IsEnabled())
            {
                return;
            }

            WriteEvent(OperationReturnedSomethingId, operation, errorCode);
        }
Esempio n. 7
0
 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));
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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());
            }
        }
Esempio n. 11
0
        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));
        }
Esempio n. 12
0
        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();
            }
        }
Esempio n. 14
0
        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);
            }
        }
Esempio n. 15
0
 internal ProtocolToken(byte[] data, Interop.SecurityStatus errorCode)
 {
     Status = errorCode;
     Payload = data;
     Size = data != null ? data.Length : 0;
 }
Esempio n. 16
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();
                        }
                    }
                }
            }
        }
Esempio n. 17
0
        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());
                }
            }
        }
Esempio n. 18
0
        //
        // 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);
        }
Esempio n. 19
0
        // 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);
        }
Esempio n. 20
0
        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);
            }
        }