SecurityChannelFactory.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 / Channels / SecurityChannelFactory.cs / 1 / SecurityChannelFactory.cs

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

namespace System.ServiceModel.Channels 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Security; 
    using System.ServiceModel;
    using System.ServiceModel.Dispatcher; 
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using ServiceModelActivity = System.ServiceModel.Diagnostics.ServiceModelActivity;
    using TraceUtility = System.ServiceModel.Diagnostics.TraceUtility; 

    sealed class SecurityChannelFactory 
        : LayeredChannelFactory 
    {
        ChannelBuilder channelBuilder; 
        SecurityProtocolFactory securityProtocolFactory;
        SecuritySessionClientSettings sessionClientSettings;
        bool sessionMode;
        MessageVersion messageVersion; 
        ISecurityCapabilities securityCapabilities;
 
        public SecurityChannelFactory(ISecurityCapabilities securityCapabilities, BindingContext context, 
            SecuritySessionClientSettings sessionClientSettings)
            : this(securityCapabilities, context, sessionClientSettings.ChannelBuilder, sessionClientSettings.CreateInnerChannelFactory()) 
        {
            this.sessionMode = true;
            this.sessionClientSettings = sessionClientSettings;
        } 

        public SecurityChannelFactory(ISecurityCapabilities securityCapabilities, BindingContext context, ChannelBuilder channelBuilder, SecurityProtocolFactory protocolFactory) 
            : this(securityCapabilities, context, channelBuilder, protocolFactory, channelBuilder.BuildChannelFactory()) 
        {
        } 

        public SecurityChannelFactory(ISecurityCapabilities securityCapabilities, BindingContext context, ChannelBuilder channelBuilder, SecurityProtocolFactory protocolFactory, IChannelFactory innerChannelFactory)
            : this(securityCapabilities, context, channelBuilder, innerChannelFactory)
        { 
            this.securityProtocolFactory = protocolFactory;
        } 
 
        SecurityChannelFactory(ISecurityCapabilities securityCapabilities, BindingContext context, ChannelBuilder channelBuilder, IChannelFactory innerChannelFactory)
            : base(context.Binding, innerChannelFactory) 
        {
            this.channelBuilder = channelBuilder;
            this.messageVersion = context.Binding.MessageVersion;
            this.securityCapabilities = securityCapabilities; 
        }
 
        // used by internal test code 
        internal SecurityChannelFactory(Binding binding, SecurityProtocolFactory protocolFactory, IChannelFactory innerChannelFactory)
            : base(binding, innerChannelFactory) 
        {
            this.securityProtocolFactory = protocolFactory;
        }
 
        public ChannelBuilder ChannelBuilder
        { 
            get 
            {
                return this.channelBuilder; 
            }
        }

        public SecurityProtocolFactory SecurityProtocolFactory 
        {
            get 
            { 
                return this.securityProtocolFactory;
            } 
        }

        public SecuritySessionClientSettings SessionClientSettings
        { 
            get
            { 
                Debug.Assert(SessionMode, "SessionClientSettings can only be used if SessionMode == true"); 
                return this.sessionClientSettings;
            } 
        }

        public bool SessionMode
        { 
            get
            { 
                return this.sessionMode; 
            }
        } 

        bool SupportsDuplex
        {
            get 
            {
                ThrowIfProtocolFactoryNotSet(); 
                return this.securityProtocolFactory.SupportsDuplex; 
            }
        } 

        bool SupportsRequestReply
        {
            get 
            {
                ThrowIfProtocolFactoryNotSet(); 
                return this.securityProtocolFactory.SupportsRequestReply; 
            }
        } 

        public MessageVersion MessageVersion
        {
            get 
            {
                return this.messageVersion; 
            } 
        }
 
        void CloseProtocolFactory(bool aborted, TimeSpan timeout)
        {
            if (this.securityProtocolFactory != null && !this.SessionMode)
            { 
                this.securityProtocolFactory.Close(aborted, timeout);
                this.securityProtocolFactory = null; 
            } 
        }
 
        public override T GetProperty()
        {
            if (this.SessionMode && (typeof(T) == typeof(IChannelSecureConversationSessionSettings)))
            { 
                return (T)(object)this.SessionClientSettings;
            } 
            else if (typeof(T) == typeof(ISecurityCapabilities)) 
            {
                return (T)(object)this.securityCapabilities; 
            }

            return base.GetProperty();
        } 

        protected override void OnAbort() 
        { 
            base.OnAbort();
            CloseProtocolFactory(true, TimeSpan.Zero); 
            if (this.sessionClientSettings != null)
            {
                this.sessionClientSettings.Abort();
            } 
        }
 
        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            List begins = new List(); 
            List ends = new List();
            begins.Add(new OperationWithTimeoutBeginCallback(base.OnBeginClose));
            ends.Add(new OperationEndCallback(base.OnEndClose));
 
            if (this.securityProtocolFactory != null && !this.SessionMode)
            { 
                begins.Add(new OperationWithTimeoutBeginCallback(this.securityProtocolFactory.BeginClose)); 
                ends.Add(new OperationEndCallback(this.securityProtocolFactory.EndClose));
            } 

            if (this.sessionClientSettings != null)
            {
                begins.Add(new OperationWithTimeoutBeginCallback(this.sessionClientSettings.BeginClose)); 
                ends.Add(new OperationEndCallback(this.sessionClientSettings.EndClose));
            } 
 
            return OperationWithTimeoutComposer.BeginComposeAsyncOperations(timeout, begins.ToArray(), ends.ToArray(), callback, state);
        } 

        protected override void OnEndClose(IAsyncResult result)
        {
            OperationWithTimeoutComposer.EndComposeAsyncOperations(result); 
        }
 
        protected override void OnClose(TimeSpan timeout) 
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 
            base.OnClose(timeout);
            CloseProtocolFactory(false, timeoutHelper.RemainingTime());
            if (this.sessionClientSettings != null)
            { 
                this.sessionClientSettings.Close(timeoutHelper.RemainingTime());
            } 
        } 

        protected override TChannel OnCreateChannel(EndpointAddress address, Uri via) 
        {
            ThrowIfDisposed();
            if (this.SessionMode)
            { 
                return this.sessionClientSettings.OnCreateChannel(address, via);
            } 
 
            if (typeof(TChannel) == typeof(IOutputChannel))
            { 
                return (TChannel)(object)new SecurityOutputChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via);
            }
            else if (typeof(TChannel) == typeof(IOutputSessionChannel))
            { 
                return (TChannel)(object)new SecurityOutputSessionChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via);
            } 
            else if (typeof(TChannel) == typeof(IDuplexChannel)) 
            {
                return (TChannel)(object)new SecurityDuplexChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via); 
            }
            else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
            {
                return (TChannel)(object)new SecurityDuplexSessionChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via); 
            }
            else if (typeof(TChannel) == typeof(IRequestChannel)) 
            { 
                return (TChannel)(object)new SecurityRequestChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via);
            } 

            //typeof(TChannel) == typeof(IRequestSessionChannel)
            return (TChannel)(object)new SecurityRequestSessionChannel(this, this.securityProtocolFactory, ((IChannelFactory)this.InnerChannelFactory).CreateChannel(address, via), address, via);
        } 

        protected override void OnOpen(TimeSpan timeout) 
        { 
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            OnOpenCore(timeoutHelper.RemainingTime()); 
            base.OnOpen(timeoutHelper.RemainingTime());
        }

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) 
        {
            return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnOpen), timeout, callback, state); 
        } 

        protected override void OnEndOpen(IAsyncResult result) 
        {
            OperationWithTimeoutAsyncResult.End(result);
        }
 
        void OnOpenCore(TimeSpan timeout)
        { 
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 
            if (this.SessionMode)
            { 
                this.SessionClientSettings.Open(this, this.InnerChannelFactory, this.ChannelBuilder, timeoutHelper.RemainingTime());
            }
            else
            { 
                ThrowIfProtocolFactoryNotSet();
                this.securityProtocolFactory.Open(true, timeoutHelper.RemainingTime()); 
            } 
        }
 
        void ThrowIfDuplexNotSupported()
        {
            if (!this.SupportsDuplex)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                    SR.GetString(SR.SecurityProtocolFactoryDoesNotSupportDuplex, this.securityProtocolFactory))); 
            } 
        }
 
        void ThrowIfProtocolFactoryNotSet()
        {
            if (this.securityProtocolFactory == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                    SR.GetString(SR.SecurityProtocolFactoryShouldBeSetBeforeThisOperation))); 
            } 
        }
 
        void ThrowIfRequestReplyNotSupported()
        {
            if (!this.SupportsRequestReply)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                    SR.GetString(SR.SecurityProtocolFactoryDoesNotSupportRequestReply, this.securityProtocolFactory))); 
            } 
        }
 

        abstract class ClientSecurityChannel : SecurityChannel
            where UChannel: class, IChannel
        { 
            EndpointAddress to;
            Uri via; 
            SecurityProtocolFactory securityProtocolFactory; 
            ChannelParameterCollection channelParameters;
 
            protected ClientSecurityChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory,
                UChannel innerChannel, EndpointAddress to, Uri via)
                : base(factory, innerChannel)
            { 
                this.to = to;
                this.via = via; 
                this.securityProtocolFactory = securityProtocolFactory; 
                this.channelParameters = new ChannelParameterCollection(this);
            } 

            protected SecurityProtocolFactory SecurityProtocolFactory
            {
                get { return this.securityProtocolFactory; } 
            }
 
            public EndpointAddress RemoteAddress 
            {
                get { return this.to; } 
            }

            public Uri Via
            { 
                get { return this.via; }
            } 
 
            protected bool TryGetSecurityFaultException(Message faultMessage, out Exception faultException)
            { 
                faultException = null;
                if (!faultMessage.IsFault)
                {
                    return false; 
                }
                MessageFault fault = MessageFault.CreateFault(faultMessage, TransportDefaults.MaxSecurityFaultSize); 
                faultException = SecurityUtils.CreateSecurityFaultException(fault); 
                return true;
            } 

            protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
            {
                return new OpenAsyncResult(this, timeout, callback, state); 
            }
 
            protected override void OnEndOpen(IAsyncResult result) 
            {
                OpenAsyncResult.End(result); 
            }

            protected override void OnOpen(TimeSpan timeout)
            { 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                SecurityProtocol securityProtocol = this.SecurityProtocolFactory.CreateSecurityProtocol( 
                    this.to, 
                    this.Via,
                    null, 
                    typeof(TChannel) == typeof(IRequestChannel),
                    timeoutHelper.RemainingTime());
                OnProtocolCreationComplete(securityProtocol);
                this.SecurityProtocol.Open(timeoutHelper.RemainingTime()); 
                base.OnOpen(timeoutHelper.RemainingTime());
            } 
 
            void OnProtocolCreationComplete(SecurityProtocol securityProtocol)
            { 
                this.SecurityProtocol = securityProtocol;
                this.SecurityProtocol.ChannelParameters = this.channelParameters;
            }
 
            public override T GetProperty()
            { 
                if (typeof(T) == typeof(ChannelParameterCollection)) 
                {
                    return (T)(object)this.channelParameters; 
                }

                return base.GetProperty();
            } 

            sealed class OpenAsyncResult : AsyncResult 
            { 
                readonly ClientSecurityChannel clientChannel;
                TimeoutHelper timeoutHelper; 
                static readonly AsyncCallback openInnerChannelCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OpenInnerChannelCallback));
                static readonly AsyncCallback openSecurityProtocolCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OpenSecurityProtocolCallback));

                public OpenAsyncResult(ClientSecurityChannel clientChannel, TimeSpan timeout, 
                    AsyncCallback callback, object state)
                    : base(callback, state) 
                { 
                    this.timeoutHelper = new TimeoutHelper(timeout);
                    this.clientChannel = clientChannel; 
                    SecurityProtocol securityProtocol = this.clientChannel.SecurityProtocolFactory.CreateSecurityProtocol(this.clientChannel.to,
                        this.clientChannel.Via,
                        null, typeof(TChannel) == typeof(IRequestChannel), timeoutHelper.RemainingTime());
                    bool completeSelf = this.OnCreateSecurityProtocolComplete(securityProtocol); 
                    if (completeSelf)
                    { 
                        Complete(true); 
                    }
                } 

                internal static void End(IAsyncResult result)
                {
                    AsyncResult.End(result); 
                }
 
                bool OnCreateSecurityProtocolComplete(SecurityProtocol securityProtocol) 
                {
                    this.clientChannel.OnProtocolCreationComplete(securityProtocol); 
                    IAsyncResult result = securityProtocol.BeginOpen(timeoutHelper.RemainingTime(), openSecurityProtocolCallback, this);
                    if (!result.CompletedSynchronously)
                    {
                        return false; 
                    }
                    securityProtocol.EndOpen(result); 
                    return this.OnSecurityProtocolOpenComplete(); 
                }
 
                static void OpenSecurityProtocolCallback(IAsyncResult result)
                {
                    if (result.CompletedSynchronously)
                    { 
                        return;
                    } 
                    OpenAsyncResult self = result.AsyncState as OpenAsyncResult; 
                    if (self == null)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.InvalidAsyncResult), "result"));
                    }
                    Exception completionException = null;
                    bool completeSelf = false; 
                    try
                    { 
                        self.clientChannel.SecurityProtocol.EndOpen(result); 
                        completeSelf = self.OnSecurityProtocolOpenComplete();
                    } 
#pragma warning suppress 56500 // covered by FxCOP
                    catch (Exception e)
                    {
                        if (Diagnostics.ExceptionUtility.IsFatal(e)) 
                            throw;
                        completionException = e; 
                        completeSelf = true; 
                    }
                    if (completeSelf) 
                    {
                        self.Complete(false, completionException);
                    }
                } 

                bool OnSecurityProtocolOpenComplete() 
                { 
                    IAsyncResult result = this.clientChannel.InnerChannel.BeginOpen(this.timeoutHelper.RemainingTime(), openInnerChannelCallback, this);
                    if (!result.CompletedSynchronously) 
                    {
                        return false;
                    }
                    this.clientChannel.InnerChannel.EndOpen(result); 
                    return true;
                } 
 
                static void OpenInnerChannelCallback(IAsyncResult result)
                { 
                    if (result == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("result"));
                    } 
                    if (result.CompletedSynchronously)
                    { 
                        return; 
                    }
                    OpenAsyncResult self = result.AsyncState as OpenAsyncResult; 
                    if (self == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.InvalidAsyncResult), "result"));
                    } 
                    Exception completionException = null;
                    try 
                    { 
                        self.clientChannel.InnerChannel.EndOpen(result);
                    } 
#pragma warning suppress 56500 // covered by FxCOP
                    catch (Exception e)
                    {
                        if (Diagnostics.ExceptionUtility.IsFatal(e)) 
                            throw;
                        completionException = e; 
                    } 
                    self.Complete(false, completionException);
                } 
            }
        }

        class SecurityOutputChannel : ClientSecurityChannel, IOutputChannel 
        {
            public SecurityOutputChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IOutputChannel innerChannel, EndpointAddress to, Uri via) 
                : base(factory, securityProtocolFactory, innerChannel, to, via) 
            {
            } 

            public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
            {
                return this.BeginSend(message, this.DefaultSendTimeout, callback, state); 
            }
 
            public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) 
            {
                ThrowIfFaulted(); 
                ThrowIfDisposedOrNotOpen(message);
                return new OutputChannelSendAsyncResult(message, this.SecurityProtocol, this.InnerChannel, timeout, callback, state);
            }
 
            public void EndSend(IAsyncResult result)
            { 
                OutputChannelSendAsyncResult.End(result); 
            }
 
            public void Send(Message message)
            {
                this.Send(message, this.DefaultSendTimeout);
            } 

            public void Send(Message message, TimeSpan timeout) 
            { 
                ThrowIfFaulted();
                ThrowIfDisposedOrNotOpen(message); 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                this.SecurityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime());
                this.InnerChannel.Send(message, timeoutHelper.RemainingTime());
            } 
        }
 
        sealed class SecurityOutputSessionChannel : SecurityOutputChannel, IOutputSessionChannel 
        {
            public SecurityOutputSessionChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IOutputSessionChannel innerChannel, EndpointAddress to, Uri via) 
                : base(factory, securityProtocolFactory, innerChannel, to, via)
            {
            }
 
            public IOutputSession Session
            { 
                get 
                {
                    return ((IOutputSessionChannel)this.InnerChannel).Session; 
                }
            }
        }
 
        class SecurityRequestChannel : ClientSecurityChannel, IRequestChannel
        { 
            public SecurityRequestChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IRequestChannel innerChannel, EndpointAddress to, Uri via) 
                : base(factory, securityProtocolFactory, innerChannel, to, via)
            { 
            }

            public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
            { 
                return this.BeginRequest(message, this.DefaultSendTimeout, callback, state);
            } 
 
            public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
            { 
                ThrowIfFaulted();
                ThrowIfDisposedOrNotOpen(message);
                return new RequestChannelSendAsyncResult(message, this.SecurityProtocol, this.InnerChannel, this, timeout, callback, state);
            } 

            public Message EndRequest(IAsyncResult result) 
            { 
                return RequestChannelSendAsyncResult.End(result);
            } 

            public Message Request(Message message)
            {
                return this.Request(message, this.DefaultSendTimeout); 
            }
 
            internal Message ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) 
            {
                if (reply != null) 
                {
                    if (DiagnosticUtility.ShouldUseActivity)
                    {
                        ServiceModelActivity replyActivity = TraceUtility.ExtractActivity(reply); 
                        if (replyActivity != null &&
                            correlationState != null && 
                            correlationState.Activity != null && 
                            replyActivity.Id != correlationState.Activity.Id)
                        { 
                            using (ServiceModelActivity.BoundOperation(replyActivity))
                            {
                                DiagnosticUtility.DiagnosticTrace.TraceTransfer(correlationState.Activity.Id);
                                replyActivity.Stop(); 
                            }
                        } 
                    } 
                    ServiceModelActivity activity = correlationState == null ? null : correlationState.Activity;
                    using (ServiceModelActivity.BoundOperation(activity)) 
                    {
                        if (DiagnosticUtility.ShouldUseActivity)
                        {
                            TraceUtility.SetActivity(reply, activity); 
                        }
                        Message unverifiedMessage = reply; 
                        Exception faultException = null; 
                        try
                        { 
                            this.SecurityProtocol.VerifyIncomingMessage(ref reply, timeout, correlationState);
                        }
                        catch (MessageSecurityException)
                        { 
                            TryGetSecurityFaultException(unverifiedMessage, out faultException);
                            if (faultException == null) 
                            { 
                                throw;
                            } 
                        }
                        if (faultException != null)
                        {
                            this.Fault(faultException); 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(faultException);
                        } 
                    } 
                }
                return reply; 
            }

            public Message Request(Message message, TimeSpan timeout)
            { 
                ThrowIfFaulted();
                ThrowIfDisposedOrNotOpen(message); 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 
                SecurityProtocolCorrelationState correlationState = this.SecurityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime(), null);
                Message reply = this.InnerChannel.Request(message, timeoutHelper.RemainingTime()); 
                return ProcessReply(reply, correlationState, timeoutHelper.RemainingTime());
            }
        }
 
        sealed class SecurityRequestSessionChannel : SecurityRequestChannel, IRequestSessionChannel
        { 
            public SecurityRequestSessionChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IRequestSessionChannel innerChannel, EndpointAddress to, Uri via) 
                : base(factory, securityProtocolFactory, innerChannel, to, via)
            { 
            }

            public IOutputSession Session
            { 
                get
                { 
                    return ((IRequestSessionChannel)this.InnerChannel).Session; 
                }
            } 
        }

        class SecurityDuplexChannel : SecurityOutputChannel, IDuplexChannel
        { 
            public SecurityDuplexChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IDuplexChannel innerChannel, EndpointAddress to, Uri via)
                : base(factory, securityProtocolFactory, innerChannel, to, via) 
            { 
            }
 
            internal IDuplexChannel InnerDuplexChannel
            {
                get { return (IDuplexChannel)this.InnerChannel; }
            } 

            public EndpointAddress LocalAddress 
            { 
                get
                { 
                    return this.InnerDuplexChannel.LocalAddress;
                }
            }
 
            internal virtual bool AcceptUnsecuredFaults
            { 
                get { return false; } 
            }
 
            public Message Receive()
            {
                return this.Receive(this.DefaultReceiveTimeout);
            } 

            public Message Receive(TimeSpan timeout) 
            { 
                return InputChannel.HelpReceive(this, timeout);
            } 

            public IAsyncResult BeginReceive(AsyncCallback callback, object state)
            {
                return this.BeginReceive(this.DefaultReceiveTimeout, callback, state); 
            }
 
            public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state) 
            {
                return InputChannel.HelpBeginReceive(this, timeout, callback, state); 
            }

            public Message EndReceive(IAsyncResult result)
            { 
                return InputChannel.HelpEndReceive(result);
            } 
 
            public virtual IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
            { 
                if (DoneReceivingInCurrentState())
                {
                    return new DoneReceivingAsyncResult(callback, state);
                } 

                ClientDuplexReceiveMessageAndVerifySecurityAsyncResult result = 
                    new ClientDuplexReceiveMessageAndVerifySecurityAsyncResult(this, this.InnerDuplexChannel, timeout, callback, state); 
                result.Start();
                return result; 
            }

            public virtual bool EndTryReceive(IAsyncResult result, out Message message)
            { 
                DoneReceivingAsyncResult doneRecevingResult = result as DoneReceivingAsyncResult;
                if (doneRecevingResult != null) 
                { 
                    return DoneReceivingAsyncResult.End(doneRecevingResult, out message);
                } 

                return ClientDuplexReceiveMessageAndVerifySecurityAsyncResult.End(result, out message);
            }
 
            internal Message ProcessMessage(Message message, TimeSpan timeout)
            { 
                if (message == null) 
                {
                    return null; 
                }
                Message unverifiedMessage = message;
                Exception faultException = null;
                try 
                {
                    this.SecurityProtocol.VerifyIncomingMessage(ref message, timeout); 
                } 
                catch (MessageSecurityException)
                { 
                    TryGetSecurityFaultException(unverifiedMessage, out faultException);
                    if (faultException == null)
                    {
                        throw; 
                    }
                } 
                if (faultException != null) 
                {
                    if (AcceptUnsecuredFaults) 
                    {
                        Fault(faultException);
                    }
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(faultException); 
                }
                return message; 
            } 

 
            public bool TryReceive(TimeSpan timeout, out Message message)
            {
                if (DoneReceivingInCurrentState())
                { 
                    message = null;
                    return true; 
                } 

                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 
                if (!this.InnerDuplexChannel.TryReceive(timeoutHelper.RemainingTime(), out message))
                {
                    return false;
                } 
                message = ProcessMessage(message, timeoutHelper.RemainingTime());
                return true; 
            } 

            public bool WaitForMessage(TimeSpan timeout) 
            {
                return this.InnerDuplexChannel.WaitForMessage(timeout);
            }
 
            public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
            { 
                return this.InnerDuplexChannel.BeginWaitForMessage(timeout, callback, state); 
            }
 
            public bool EndWaitForMessage(IAsyncResult result)
            {
                return this.InnerDuplexChannel.EndWaitForMessage(result);
            } 
        }
 
        sealed class SecurityDuplexSessionChannel : SecurityDuplexChannel, IDuplexSessionChannel 
        {
            public SecurityDuplexSessionChannel(ChannelManagerBase factory, SecurityProtocolFactory securityProtocolFactory, IDuplexSessionChannel innerChannel, EndpointAddress to, Uri via) 
                : base(factory, securityProtocolFactory, innerChannel, to, via)
            {
            }
 
            public IDuplexSession Session
            { 
                get 
                {
                    return ((IDuplexSessionChannel)this.InnerChannel).Session; 
                }
            }

            internal override bool AcceptUnsecuredFaults 
            {
                get { return true; } 
            } 
        }
 
        sealed class RequestChannelSendAsyncResult : ApplySecurityAndSendAsyncResult
        {
            Message reply;
            SecurityRequestChannel securityChannel; 

            public RequestChannelSendAsyncResult(Message message, SecurityProtocol protocol, IRequestChannel channel, SecurityRequestChannel securityChannel, TimeSpan timeout, 
                AsyncCallback callback, object state) 
                : base(protocol, channel, timeout, callback, state)
            { 
                this.securityChannel = securityChannel;
                this.Begin(message, null);
            }
 
            protected override IAsyncResult BeginSendCore(IRequestChannel channel, Message message, TimeSpan timeout, AsyncCallback callback, object state)
            { 
                return channel.BeginRequest(message, timeout, callback, state); 
            }
 
            internal static Message End(IAsyncResult result)
            {
                RequestChannelSendAsyncResult self = result as RequestChannelSendAsyncResult;
                OnEnd(self); 
                return self.reply;
            } 
 
            protected override void EndSendCore(IRequestChannel channel, IAsyncResult result)
            { 
                this.reply = channel.EndRequest(result);
            }

            protected override void OnSendCompleteCore(TimeSpan timeout) 
            {
                this.reply = securityChannel.ProcessReply(reply, this.CorrelationState, timeout); 
            } 
        }
 
        class ClientDuplexReceiveMessageAndVerifySecurityAsyncResult : ReceiveMessageAndVerifySecurityAsyncResultBase
        {
            SecurityDuplexChannel channel;
 
            public ClientDuplexReceiveMessageAndVerifySecurityAsyncResult(SecurityDuplexChannel channel, IDuplexChannel innerChannel, TimeSpan timeout, AsyncCallback callback, object state)
                : base(innerChannel, timeout, callback, state) 
            { 
                this.channel = channel;
            } 

            protected override bool OnInnerReceiveDone(ref Message message, TimeSpan timeout)
            {
                message = this.channel.ProcessMessage(message, timeout); 
                return true;
            } 
        } 
    }
} 

// 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