MessageSecurityProtocol.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / MessageSecurityProtocol.cs / 1 / MessageSecurityProtocol.cs

                            //---------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Security 
{
    using System.IdentityModel.Policy; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel;
    using System.ServiceModel.Description; 
    using System.IdentityModel.Tokens;
    using System.IdentityModel.Selectors;
    using System.ServiceModel.Security.Tokens;
    using System.ServiceModel.Diagnostics; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Runtime.InteropServices; 

    abstract class MessageSecurityProtocol : SecurityProtocol 
    {
        readonly MessageSecurityProtocolFactory factory;
        SecurityToken identityVerifiedToken; // verified for the readonly target
 
        protected MessageSecurityProtocol(MessageSecurityProtocolFactory factory, EndpointAddress target, Uri via)
            : base(factory, target, via) 
        { 
            this.factory = factory;
        } 

        // Protocols that have more than one active, identity checked
        // token at any time should override this property and return
        // false 
        protected virtual bool CacheIdentityCheckResultForToken
        { 
            get { return true; } 
        }
 
        protected virtual bool DoAutomaticEncryptionMatch
        {
            get { return true; }
        } 

        protected virtual bool PerformIncomingAndOutgoingMessageExpectationChecks 
        { 
            get { return true; }
        } 

        protected bool RequiresIncomingSecurityProcessing
        {
            get 
            {
                bool requiresAppSecurity = this.factory.RequireIntegrity || this.factory.RequireConfidentiality || this.factory.DetectReplays; 
                return requiresAppSecurity || factory.ExpectSupportingTokens; 
            }
        } 

        protected bool RequiresOutgoingSecurityProcessing
        {
            get 
            {
                bool requiresAppSecurity = this.factory.ApplyIntegrity || this.factory.ApplyConfidentiality || this.factory.AddTimestamp; 
                return requiresAppSecurity || factory.ExpectSupportingTokens; 
            }
        } 

        protected MessageSecurityProtocolFactory MessageSecurityProtocolFactory
        {
            get { return this.factory; } 
        }
 
        public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state) 
        {
            try 
            {
                this.CommunicationObject.ThrowIfClosedOrNotOpen();
                ValidateOutgoingState(message);
                if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null) 
                {
                    return new TypedCompletedAsyncResult(message, callback, state); 
                } 
                return BeginSecureOutgoingMessageCore(message, timeout, null, callback, state);
            } 
            catch (Exception exception)
            {
                // Always immediately rethrow fatal exceptions.
                if (DiagnosticUtility.IsFatal(exception)) throw; 

                base.OnSecureOutgoingMessageFailure(message); 
                throw; 
            }
        } 

        public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
        {
            try 
            {
                this.CommunicationObject.ThrowIfClosedOrNotOpen(); 
                ValidateOutgoingState(message); 
                if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
                { 
                    return new TypedCompletedAsyncResult(message, callback, state);
                }
                return BeginSecureOutgoingMessageCore(message, timeout, correlationState, callback, state);
            } 
            catch (Exception exception)
            { 
                // Always immediately rethrow fatal exceptions. 
                if (DiagnosticUtility.IsFatal(exception)) throw;
 
                base.OnSecureOutgoingMessageFailure(message);
                throw;
            }
        } 

        protected abstract IAsyncResult BeginSecureOutgoingMessageCore(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state); 
 
        public override void EndSecureOutgoingMessage(IAsyncResult result, out Message message)
        { 
            if (result == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
            } 
            try
            { 
                SecurityProtocolCorrelationState newCorrelationState; 
                EndSecureOutgoingMessageCore(result, out message, out newCorrelationState);
                base.OnOutgoingMessageSecured(message); 
            }
            catch (Exception exception)
            {
                // Always immediately rethrow fatal exceptions. 
                if (DiagnosticUtility.IsFatal(exception)) throw;
 
                base.OnSecureOutgoingMessageFailure(null); 
                throw;
            } 
        }

        public override void EndSecureOutgoingMessage(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
        { 
            if (result == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result"); 
            }
            try 
            {
                EndSecureOutgoingMessageCore(result, out message, out newCorrelationState);
                base.OnOutgoingMessageSecured(message);
            } 
            catch (Exception exception)
            { 
                // Always immediately rethrow fatal exceptions. 
                if (DiagnosticUtility.IsFatal(exception)) throw;
 
                base.OnSecureOutgoingMessageFailure(null);
                throw;
            }
        } 

        protected abstract void EndSecureOutgoingMessageCore(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState); 
 
        // helper method for attaching the client claims in a symmetric security protocol
        protected void AttachRecipientSecurityProperty(Message message, SecurityToken protectionToken, bool isWrappedToken, IList basicTokens, IList endorsingTokens, 
           IList signedEndorsingTokens, IList signedTokens, Dictionary> tokenPoliciesMapping)
        {
            ReadOnlyCollection protectionTokenPolicies;
            if (isWrappedToken) 
            {
                protectionTokenPolicies = EmptyReadOnlyCollection.Instance; 
            } 
            else
            { 
                protectionTokenPolicies = tokenPoliciesMapping[protectionToken];
            }
            SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message);
            security.ProtectionToken = new SecurityTokenSpecification(protectionToken, protectionTokenPolicies); 
            AddSupportingTokenSpecification(security, basicTokens, endorsingTokens, signedEndorsingTokens, signedTokens, tokenPoliciesMapping);
            security.ServiceSecurityContext = new ServiceSecurityContext(security.GetInitiatorTokenAuthorizationPolicies()); 
        } 

        // helper method for attaching the server claims in a symmetric security protocol 
        protected void DoIdentityCheckAndAttachInitiatorSecurityProperty(Message message, SecurityToken protectionToken, ReadOnlyCollection protectionTokenPolicies)
        {
            AuthorizationContext protectionAuthContext = EnsureIncomingIdentity(message, protectionToken, protectionTokenPolicies);
            SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message); 
            security.ProtectionToken = new SecurityTokenSpecification(protectionToken, protectionTokenPolicies);
            security.ServiceSecurityContext = new ServiceSecurityContext(protectionAuthContext, protectionTokenPolicies ?? EmptyReadOnlyCollection.Instance); 
        } 

        protected AuthorizationContext EnsureIncomingIdentity(Message message, SecurityToken token, ReadOnlyCollection authorizationPolicies) 
        {
            if (token == null)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoSigningTokenAvailableToDoIncomingIdentityCheck)), message); 
            }
            AuthorizationContext authContext = (authorizationPolicies != null) ? AuthorizationContext.CreateDefaultAuthorizationContext(authorizationPolicies) : null; 
            if (this.factory.IdentityVerifier != null) 
            {
                if (this.Target == null) 
                {
                    throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoOutgoingEndpointAddressAvailableForDoingIdentityCheckOnReply)), message);
                }
 
                this.factory.IdentityVerifier.EnsureIncomingIdentity(this.Target, authContext);
            } 
            return authContext; 
        }
 
        protected void EnsureOutgoingIdentity(SecurityToken token, SecurityTokenAuthenticator authenticator)
        {
            if (object.ReferenceEquals(token, this.identityVerifiedToken))
            { 
                return;
            } 
            if (this.factory.IdentityVerifier == null) 
            {
                return; 
            }
            if (this.Target == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoOutgoingEndpointAddressAvailableForDoingIdentityCheck))); 
            }
            ReadOnlyCollection authzPolicies = authenticator.ValidateToken(token); 
            this.factory.IdentityVerifier.EnsureOutgoingIdentity(this.Target, authzPolicies); 
            if (this.CacheIdentityCheckResultForToken)
            { 
                this.identityVerifiedToken = token;
            }
        }
 
        protected SecurityProtocolCorrelationState GetCorrelationState(SecurityToken correlationToken)
        { 
            return new SecurityProtocolCorrelationState(correlationToken); 
        }
 
        protected SecurityProtocolCorrelationState GetCorrelationState(SecurityToken correlationToken, ReceiveSecurityHeader securityHeader)
        {
            SecurityProtocolCorrelationState result = new SecurityProtocolCorrelationState(correlationToken);
            if (securityHeader.MaintainSignatureConfirmationState && !this.factory.ActAsInitiator) 
            {
                result.SignatureConfirmations = securityHeader.GetSentSignatureValues(); 
            } 
            return result;
        } 

        protected SecurityToken GetCorrelationToken(SecurityProtocolCorrelationState[] correlationStates)
        {
            SecurityToken token = null; 
            if (correlationStates != null)
            { 
                for (int i = 0; i < correlationStates.Length; ++i) 
                {
                    if (correlationStates[i].Token == null) 
                        continue;
                    if (token == null)
                    {
                        token = correlationStates[i].Token; 
                    }
                    else if (!object.ReferenceEquals(token, correlationStates[i].Token)) 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MultipleCorrelationTokensFound)));
                    } 
                }
            }
            if (token == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoCorrelationTokenFound)));
            } 
            return token; 
        }
 

        protected SecurityToken GetCorrelationToken(SecurityProtocolCorrelationState correlationState)
        {
            if (correlationState == null || correlationState.Token == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.CannotFindCorrelationStateForApplyingSecurity))); 
            } 
            return correlationState.Token;
        } 

        protected static void EnsureNonWrappedToken(SecurityToken token, Message message)
        {
            if (token is WrappedKeySecurityToken) 
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenNotExpectedInSecurityHeader, token)), message); 
            } 
        }
 
        protected SecurityToken GetTokenAndEnsureOutgoingIdentity(SecurityTokenProvider provider, bool isEncryptionOn, TimeSpan timeout, SecurityTokenAuthenticator authenticator)
        {
            SecurityToken token = GetToken(provider, this.Target, timeout);
            if (isEncryptionOn) 
            {
                EnsureOutgoingIdentity(token, authenticator); 
            } 
            return token;
        } 

        protected SendSecurityHeader ConfigureSendSecurityHeader(Message message, string actor, IList supportingTokens, SecurityProtocolCorrelationState correlationState)
        {
            MessageSecurityProtocolFactory factory = this.MessageSecurityProtocolFactory; 
            SendSecurityHeader securityHeader = CreateSendSecurityHeader(message, actor, factory);
            securityHeader.SignThenEncrypt = factory.MessageProtectionOrder != MessageProtectionOrder.EncryptBeforeSign; 
            securityHeader.EncryptPrimarySignature = factory.MessageProtectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature; 
            if (factory.DoRequestSignatureConfirmation && correlationState != null)
            { 
                if (factory.ActAsInitiator)
                {
                    securityHeader.MaintainSignatureConfirmationState = true;
                    securityHeader.CorrelationState = correlationState; 
                }
                else if (correlationState.SignatureConfirmations != null) 
                { 
                    securityHeader.AddSignatureConfirmations(correlationState.SignatureConfirmations);
                } 
            }

            string action = message.Headers.Action;
            if (this.factory.ApplyIntegrity) 
            {
                securityHeader.SignatureParts = this.factory.GetOutgoingSignatureParts(action); 
            } 

            if (factory.ApplyConfidentiality) 
            {
                securityHeader.EncryptionParts = this.factory.GetOutgoingEncryptionParts(action);
            }
            AddSupportingTokens(securityHeader, supportingTokens); 
            return securityHeader;
        } 
 
        protected ReceiveSecurityHeader CreateSecurityHeader(Message message, string actor, MessageDirection transferDirection, SecurityStandardsManager standardsManager)
        { 
            standardsManager = standardsManager ?? this.factory.StandardsManager;
            ReceiveSecurityHeader securityHeader = standardsManager.CreateReceiveSecurityHeader(message, actor,
               this.factory.IncomingAlgorithmSuite, transferDirection);
            securityHeader.Layout = this.factory.SecurityHeaderLayout; 
            securityHeader.MaxReceivedMessageSize = factory.SecurityBindingElement.MaxReceivedMessageSize;
            securityHeader.ReaderQuotas = factory.SecurityBindingElement.ReaderQuotas; 
            if (this.factory.ExpectKeyDerivation) 
            {
                securityHeader.DerivedTokenAuthenticator = this.factory.DerivedKeyTokenAuthenticator; 
            }
            return securityHeader;
        }
 
        bool HasCorrelationState(SecurityProtocolCorrelationState[] correlationState)
        { 
            if (correlationState == null || correlationState.Length == 0) 
            {
                return false; 
            }
            else if (correlationState.Length == 1 && correlationState[0] == null)
            {
                return false; 
            }
            else 
            { 
                return true;
            } 
        }

        protected ReceiveSecurityHeader ConfigureReceiveSecurityHeader(Message message, string actor, SecurityProtocolCorrelationState[] correlationStates, out IList supportingAuthenticators)
        { 
            return ConfigureReceiveSecurityHeader(message, actor, correlationStates, null, out supportingAuthenticators);
        } 
 
        protected ReceiveSecurityHeader ConfigureReceiveSecurityHeader(Message message, string actor, SecurityProtocolCorrelationState[] correlationStates, SecurityStandardsManager standardsManager, out IList supportingAuthenticators)
        { 
            MessageSecurityProtocolFactory factory = this.MessageSecurityProtocolFactory;
            MessageDirection direction = factory.ActAsInitiator ? MessageDirection.Output : MessageDirection.Input;
            ReceiveSecurityHeader securityHeader = CreateSecurityHeader(message, actor, direction, standardsManager);
 
            string action = message.Headers.Action;
            supportingAuthenticators = GetSupportingTokenAuthenticatorsAndSetExpectationFlags(this.factory, message, securityHeader); 
            if (factory.RequireIntegrity || securityHeader.ExpectSignedTokens) 
            {
                securityHeader.RequiredSignatureParts = factory.GetIncomingSignatureParts(action); 
            }
            if (factory.RequireConfidentiality || securityHeader.ExpectBasicTokens)
            {
                securityHeader.RequiredEncryptionParts = factory.GetIncomingEncryptionParts(action); 
            }
 
            securityHeader.ExpectEncryption = factory.RequireConfidentiality || securityHeader.ExpectBasicTokens; 
            securityHeader.ExpectSignature = factory.RequireIntegrity || securityHeader.ExpectSignedTokens;
            securityHeader.SetRequiredProtectionOrder(factory.MessageProtectionOrder); 
            if (factory.ActAsInitiator && factory.DoRequestSignatureConfirmation && HasCorrelationState(correlationStates))
            {
                securityHeader.MaintainSignatureConfirmationState = true;
                securityHeader.ExpectSignatureConfirmation = true; 
            }
            else if (!factory.ActAsInitiator && factory.DoRequestSignatureConfirmation) 
            { 
                securityHeader.MaintainSignatureConfirmationState = true;
            } 
            else
            {
                securityHeader.MaintainSignatureConfirmationState = false;
            } 
            return securityHeader;
        } 
 
        protected void ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, ref Message message,
            SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) 
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            securityHeader.SetTimeParameters(this.factory.NonceCache, this.factory.ReplayWindow, this.factory.MaxClockSkew);
            securityHeader.Process(timeoutHelper.RemainingTime()); 
            if (this.factory.AddTimestamp && securityHeader.Timestamp == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.RequiredTimestampMissingInSecurityHeader))); 
            }
 
            if (requiredSigningToken != null && requiredSigningToken != securityHeader.SignatureToken)
            {
                throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.ReplyWasNotSignedWithRequiredSigningToken)), message);
            } 

            if (this.DoAutomaticEncryptionMatch) 
            { 
                SecurityUtils.EnsureExpectedSymmetricMatch(securityHeader.SignatureToken, securityHeader.EncryptionToken, message);
            } 

            if (securityHeader.MaintainSignatureConfirmationState && this.factory.ActAsInitiator)
            {
                CheckSignatureConfirmation(securityHeader, correlationStates); 
            }
 
            message = securityHeader.ProcessedMessage; 
        }
 
        protected void CheckSignatureConfirmation(ReceiveSecurityHeader securityHeader, SecurityProtocolCorrelationState[] correlationStates)
        {
            SignatureConfirmations receivedConfirmations = securityHeader.GetSentSignatureConfirmations();
            SignatureConfirmations sentSignatures = null; 
            if (correlationStates != null)
            { 
                for (int i = 0; i < correlationStates.Length; ++i) 
                {
                    if (correlationStates[i].SignatureConfirmations != null) 
                    {
                        sentSignatures = correlationStates[i].SignatureConfirmations;
                        break;
                    } 
                }
            } 
            if (sentSignatures == null) 
            {
                if (receivedConfirmations != null && receivedConfirmations.Count > 0) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.FoundUnexpectedSignatureConfirmations)));
                }
                return; 
            }
            bool allSignaturesConfirmed = false; 
            if (receivedConfirmations != null && sentSignatures.Count == receivedConfirmations.Count) 
            {
                bool[] matchingSigIndexes = new bool[sentSignatures.Count]; 
                for (int i = 0; i < sentSignatures.Count; ++i)
                {
                    byte[] sentSignature;
                    bool wasSentSigEncrypted; 
                    sentSignatures.GetConfirmation(i, out sentSignature, out wasSentSigEncrypted);
                    for (int j = 0; j < receivedConfirmations.Count; ++j) 
                    { 
                        byte[] receivedSignature;
                        bool wasReceivedSigEncrypted; 
                        if (matchingSigIndexes[j])
                        {
                            continue;
                        } 
                        receivedConfirmations.GetConfirmation(j, out receivedSignature, out wasReceivedSigEncrypted);
                        if ((wasReceivedSigEncrypted == wasSentSigEncrypted) && CryptoHelper.IsEqual(receivedSignature, sentSignature)) 
                        { 
                            matchingSigIndexes[j] = true;
                            break; 
                        }
                    }
                }
                int k; 
                for (k = 0; k < matchingSigIndexes.Length; ++k)
                { 
                    if (!matchingSigIndexes[k]) 
                    {
                        break; 
                    }
                }
                if (k == matchingSigIndexes.Length)
                { 
                    allSignaturesConfirmed = true;
                } 
            } 
            if (!allSignaturesConfirmed)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NotAllSignaturesConfirmed)));
            }
        }
 
        public override void SecureOutgoingMessage(ref Message message, TimeSpan timeout)
        { 
            try 
            {
                this.CommunicationObject.ThrowIfClosedOrNotOpen(); 
                ValidateOutgoingState(message);
                if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
                {
                    return; 
                }
 
                SecureOutgoingMessageCore(ref message, timeout, null); 
                base.OnOutgoingMessageSecured(message);
            } 
            catch (Exception exception)
            {
                // Always immediately rethrow fatal exceptions.
                if (DiagnosticUtility.IsFatal(exception)) throw; 

                base.OnSecureOutgoingMessageFailure(message); 
                throw; 
            }
        } 

        public override SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
        {
            try 
            {
                this.CommunicationObject.ThrowIfClosedOrNotOpen(); 
                ValidateOutgoingState(message); 
                if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
                { 
                    return null;
                }
                SecurityProtocolCorrelationState newCorrelationState = SecureOutgoingMessageCore(ref message, timeout, correlationState);
                base.OnOutgoingMessageSecured(message); 
                return newCorrelationState;
            } 
            catch (Exception exception) 
            {
                // Always immediately rethrow fatal exceptions. 
                if (DiagnosticUtility.IsFatal(exception)) throw;

                base.OnSecureOutgoingMessageFailure(message);
                throw; 
            }
        } 
 
        protected abstract SecurityProtocolCorrelationState SecureOutgoingMessageCore(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState);
 
        void ValidateOutgoingState(Message message)
        {
            if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !this.factory.ExpectOutgoingMessages)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessOutgoingMessages)));
            } 
            if (message == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 
            }
        }

        public override void VerifyIncomingMessage(ref Message message, TimeSpan timeout) 
        {
            try 
            { 
                this.CommunicationObject.ThrowIfClosedOrNotOpen();
                if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !factory.ExpectIncomingMessages) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessIncomingMessages)));
                }
                if (message == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 
                } 
                if (!this.RequiresIncomingSecurityProcessing)
                { 
                    return;
                }
                string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;
                VerifyIncomingMessageCore(ref message, actor, timeout, null); 
                base.OnIncomingMessageVerified(message);
            } 
            catch (MessageSecurityException e) 
            {
                base.OnVerifyIncomingMessageFailure(message, e); 
                throw;
            }
            catch (Exception e)
            { 
                // Always immediately rethrow fatal exceptions.
                if (DiagnosticUtility.IsFatal(e)) throw; 
 
                base.OnVerifyIncomingMessageFailure(message, e);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e)); 
            }
        }

        public override SecurityProtocolCorrelationState VerifyIncomingMessage(ref Message message, TimeSpan timeout, params SecurityProtocolCorrelationState[] correlationStates) 
        {
            try 
            { 
                this.CommunicationObject.ThrowIfClosedOrNotOpen();
                if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !factory.ExpectIncomingMessages) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessIncomingMessages)));
                }
                if (message == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 
                } 
                if (!this.RequiresIncomingSecurityProcessing)
                { 
                    return null;
                }
                string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;
                SecurityProtocolCorrelationState newCorrelationState = VerifyIncomingMessageCore(ref message, actor, timeout, correlationStates); 
                base.OnIncomingMessageVerified(message);
                return newCorrelationState; 
            } 
            catch (MessageSecurityException e)
            { 
                base.OnVerifyIncomingMessageFailure(message, e);
                throw;
            }
            catch (Exception e) 
            {
                // Always immediately rethrow fatal exceptions. 
                if (DiagnosticUtility.IsFatal(e)) throw; 

                base.OnVerifyIncomingMessageFailure(message, e); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e));
            }
        }
 
        protected abstract SecurityProtocolCorrelationState VerifyIncomingMessageCore(ref Message message, string actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates);
 
        internal SecurityProtocolCorrelationState GetSignatureConfirmationCorrelationState(SecurityProtocolCorrelationState oldCorrelationState, SecurityProtocolCorrelationState newCorrelationState) 
        {
            if (this.factory.ActAsInitiator) 
            {
                return newCorrelationState;
            }
            else 
            {
                return oldCorrelationState; 
            } 
        }
 
        protected abstract class GetOneTokenAndSetUpSecurityAsyncResult : GetSupportingTokensAsyncResult
        {
            readonly MessageSecurityProtocol binding;
            readonly SecurityTokenProvider provider; 
            Message message;
            readonly bool doIdentityChecks; 
            SecurityTokenAuthenticator identityCheckAuthenticator; 
            static AsyncCallback getTokenCompleteCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(GetTokenCompleteCallback));
            SecurityProtocolCorrelationState newCorrelationState; 
            SecurityProtocolCorrelationState oldCorrelationState;
            TimeoutHelper timeoutHelper;

            public GetOneTokenAndSetUpSecurityAsyncResult(Message m, MessageSecurityProtocol binding, SecurityTokenProvider provider, 
                bool doIdentityChecks, SecurityTokenAuthenticator identityCheckAuthenticator, SecurityProtocolCorrelationState oldCorrelationState, TimeSpan timeout, AsyncCallback callback, object state)
                : base(m, binding, timeout, callback, state) 
            { 
                this.message = m;
                this.binding = binding; 
                this.provider = provider;
                this.doIdentityChecks = doIdentityChecks;
                this.oldCorrelationState = oldCorrelationState;
                this.identityCheckAuthenticator = identityCheckAuthenticator; 
            }
 
            protected MessageSecurityProtocol Binding 
            {
                get { return this.binding; } 
            }

            protected SecurityProtocolCorrelationState NewCorrelationState
            { 
                get { return this.newCorrelationState; }
            } 
 
            protected SecurityProtocolCorrelationState OldCorrelationState
            { 
                get { return this.oldCorrelationState; }
            }

            internal static Message End(IAsyncResult result, out SecurityProtocolCorrelationState newCorrelationState) 
            {
                GetOneTokenAndSetUpSecurityAsyncResult self = AsyncResult.End(result); 
                newCorrelationState = self.newCorrelationState; 
                return self.message;
            } 

            bool OnGetTokenComplete(SecurityToken token)
            {
                if (token == null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target))); 
                } 
                if (this.doIdentityChecks)
                { 
                    this.binding.EnsureOutgoingIdentity(token, this.identityCheckAuthenticator);
                }
                OnGetTokenDone(ref this.message, token, timeoutHelper.RemainingTime());
                return true; 
            }
 
            protected abstract void OnGetTokenDone(ref Message message, SecurityToken token, TimeSpan timeout); 

            static void GetTokenCompleteCallback(IAsyncResult result) 
            {
                if (result == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result"); 
                }
                if (result.CompletedSynchronously) 
                { 
                    return;
                } 
                GetOneTokenAndSetUpSecurityAsyncResult self = result.AsyncState as GetOneTokenAndSetUpSecurityAsyncResult;
                if (self == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult)); 
                }
                Exception completionException = null; 
                bool completeSelf = false; 
                try
                { 
                    SecurityToken token = self.provider.EndGetToken(result);
                    completeSelf = self.OnGetTokenComplete(token);
                }
#pragma warning suppress 56500 // covered by FxCOP 
                catch (Exception e)
                { 
                    // Always immediately rethrow fatal exceptions. 
                    if (DiagnosticUtility.IsFatal(e)) throw;
 
                    completeSelf = true;
                    completionException = e;
                }
                if (completeSelf) 
                {
                    self.Complete(false, completionException); 
                } 
            }
 
            protected void SetCorrelationToken(SecurityToken token)
            {
                newCorrelationState = new SecurityProtocolCorrelationState(token);
            } 

            protected override bool OnGetSupportingTokensDone(TimeSpan timeout) 
            { 
                this.timeoutHelper = new TimeoutHelper(timeout);
                IAsyncResult result = this.provider.BeginGetToken(timeoutHelper.RemainingTime(), getTokenCompleteCallback, this); 
                if (!result.CompletedSynchronously)
                {
                    return false;
 
                }
                SecurityToken token = this.provider.EndGetToken(result); 
                return this.OnGetTokenComplete(token); 
            }
        } 

        // note: identity check done only on token obtained from first
        // token provider; either or both token providers may be null;
        // get token calls are skipped for null providers. 
        protected abstract class GetTwoTokensAndSetUpSecurityAsyncResult : GetSupportingTokensAsyncResult
        { 
            readonly MessageSecurityProtocol binding; 
            readonly SecurityTokenProvider primaryProvider;
            readonly SecurityTokenProvider secondaryProvider; 
            Message message;
            readonly bool doIdentityChecks;
            SecurityTokenAuthenticator identityCheckAuthenticator;
            SecurityToken primaryToken; 
            static readonly AsyncCallback getPrimaryTokenCompleteCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(GetPrimaryTokenCompleteCallback));
            static readonly AsyncCallback getSecondaryTokenCompleteCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(GetSecondaryTokenCompleteCallback)); 
            SecurityProtocolCorrelationState newCorrelationState; 
            SecurityProtocolCorrelationState oldCorrelationState;
            TimeoutHelper timeoutHelper; 

            public GetTwoTokensAndSetUpSecurityAsyncResult(Message m, MessageSecurityProtocol binding,
                SecurityTokenProvider primaryProvider, SecurityTokenProvider secondaryProvider, bool doIdentityChecks, SecurityTokenAuthenticator identityCheckAuthenticator,
                SecurityProtocolCorrelationState oldCorrelationState, 
                TimeSpan timeout,
                AsyncCallback callback, object state) 
                : base(m, binding, timeout, callback, state) 
            {
                this.message = m; 
                this.binding = binding;
                this.primaryProvider = primaryProvider;
                this.secondaryProvider = secondaryProvider;
                this.doIdentityChecks = doIdentityChecks; 
                this.identityCheckAuthenticator = identityCheckAuthenticator;
                this.oldCorrelationState = oldCorrelationState; 
            } 

            protected MessageSecurityProtocol Binding 
            {
                get { return this.binding; }
            }
 
            protected SecurityProtocolCorrelationState NewCorrelationState
            { 
                get { return this.newCorrelationState; } 
            }
 
            protected SecurityProtocolCorrelationState OldCorrelationState
            {
                get { return this.oldCorrelationState; }
            } 

            internal static Message End(IAsyncResult result, out SecurityProtocolCorrelationState newCorrelationState) 
            { 
                GetTwoTokensAndSetUpSecurityAsyncResult self = AsyncResult.End(result);
                newCorrelationState = self.newCorrelationState; 
                return self.message;
            }

            bool OnGetPrimaryTokenComplete(SecurityToken token) 
            {
                return OnGetPrimaryTokenComplete(token, false); 
            } 

            bool OnGetPrimaryTokenComplete(SecurityToken token, bool primaryCallSkipped) 
            {
                if (!primaryCallSkipped)
                {
                    if (token == null) 
                    {
                        throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target)), this.message); 
                    } 
                    if (this.doIdentityChecks)
                    { 
                        this.binding.EnsureOutgoingIdentity(token, this.identityCheckAuthenticator);
                    }
                }
                this.primaryToken = token; 

                if (this.secondaryProvider == null) 
                { 
                    return this.OnGetSecondaryTokenComplete(null, true);
                } 
                else
                {
                    IAsyncResult result = this.secondaryProvider.BeginGetToken(this.timeoutHelper.RemainingTime(), getSecondaryTokenCompleteCallback, this);
                    if (!result.CompletedSynchronously) 
                    {
                        return false; 
                    } 
                    SecurityToken token2 = this.secondaryProvider.EndGetToken(result);
                    return this.OnGetSecondaryTokenComplete(token2); 
                }
            }

            bool OnGetSecondaryTokenComplete(SecurityToken token) 
            {
                return OnGetSecondaryTokenComplete(token, false); 
            } 

            bool OnGetSecondaryTokenComplete(SecurityToken token, bool secondaryCallSkipped) 
            {
                if (!secondaryCallSkipped && token == null)
                {
                    throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target)), this.message); 
                }
                OnBothGetTokenCallsDone(ref this.message, this.primaryToken, token, timeoutHelper.RemainingTime()); 
                return true; 
            }
 
            protected abstract void OnBothGetTokenCallsDone(ref Message message, SecurityToken primaryToken, SecurityToken secondaryToken, TimeSpan timeout);

            static void GetPrimaryTokenCompleteCallback(IAsyncResult result)
            { 
                if (result == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result"); 
                }
                if (result.CompletedSynchronously) 
                {
                    return;
                }
                GetTwoTokensAndSetUpSecurityAsyncResult self = result.AsyncState as GetTwoTokensAndSetUpSecurityAsyncResult; 
                if (self == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult)); 
                }
                bool completeSelf = false; 
                Exception completionException = null;
                try
                {
                    SecurityToken token = self.primaryProvider.EndGetToken(result); 
                    completeSelf = self.OnGetPrimaryTokenComplete(token);
                } 
#pragma warning suppress 56500 // covered by FxCOP 
                catch (Exception e)
                { 
                    // Always immediately rethrow fatal exceptions.
                    if (DiagnosticUtility.IsFatal(e)) throw;

                    completeSelf = true; 
                    completionException = e;
                } 
                if (completeSelf) 
                {
                    self.Complete(false, completionException); 
                }
            }

            static void GetSecondaryTokenCompleteCallback(IAsyncResult result) 
            {
                if (result == null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
                } 
                if (result.CompletedSynchronously)
                {
                    return;
                } 
                GetTwoTokensAndSetUpSecurityAsyncResult self = result.AsyncState as GetTwoTokensAndSetUpSecurityAsyncResult;
                if (self == null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult));
                } 
                bool completeSelf = false;
                Exception completionException = null;
                try
                { 
                    SecurityToken token = self.secondaryProvider.EndGetToken(result);
                    completeSelf = self.OnGetSecondaryTokenComplete(token); 
                } 
#pragma warning suppress 56500 // covered by FxCOP
                catch (Exception e) 
                {
                    // Always immediately rethrow fatal exceptions.
                    if (DiagnosticUtility.IsFatal(e)) throw;
 
                    completeSelf = true;
                    completionException = e; 
                } 
                if (completeSelf)
                { 
                    self.Complete(false, completionException);
                }
            }
 
            protected void SetCorrelationToken(SecurityToken token)
            { 
                newCorrelationState = new SecurityProtocolCorrelationState(token); 
            }
 
            protected override bool OnGetSupportingTokensDone(TimeSpan timeout)
            {
                this.timeoutHelper = new TimeoutHelper(timeout);
                bool completeSelf = false; 
                if (this.primaryProvider == null)
                { 
                    completeSelf = this.OnGetPrimaryTokenComplete(null); 
                }
                else 
                {
                    IAsyncResult result = this.primaryProvider.BeginGetToken(this.timeoutHelper.RemainingTime(), getPrimaryTokenCompleteCallback, this);
                    if (result.CompletedSynchronously)
                    { 
                        SecurityToken token = this.primaryProvider.EndGetToken(result);
                        completeSelf = this.OnGetPrimaryTokenComplete(token); 
                    } 
                }
                return completeSelf; 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK