Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SecuritySessionClientSettings.cs / 1 / SecuritySessionClientSettings.cs
//---------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Security { using System.Collections.Generic; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.ServiceModel.Diagnostics; using System.ServiceModel.Security.Tokens; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.IdentityModel.Claims; using System.IdentityModel.Policy; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Xml; using System.Threading; using System.Diagnostics; // Please use 'sdv //depot/devdiv/private/indigo_xws/ndp/indigo/src/ServiceModel/System/ServiceModel/Security/SecuritySessionChannelFactory.cs' // to see version history before the file was renamed // This class is named Settings since the only public APIs are for // settings; however, this class also manages all functionality // for session channels through internal APIs static class SecuritySessionClientSettings { internal const string defaultKeyRenewalIntervalString = "10:00:00"; internal const string defaultKeyRolloverIntervalString = "00:05:00"; internal static readonly TimeSpan defaultKeyRenewalInterval = TimeSpan.Parse(defaultKeyRenewalIntervalString); internal static readonly TimeSpan defaultKeyRolloverInterval = TimeSpan.Parse(defaultKeyRolloverIntervalString); internal const bool defaultTolerateTransportFailures = true; } sealed class SecuritySessionClientSettings: IChannelSecureConversationSessionSettings, ISecurityCommunicationObject { SecurityProtocolFactory sessionProtocolFactory; TimeSpan keyRenewalInterval; TimeSpan keyRolloverInterval; bool tolerateTransportFailures; SecurityChannelFactory securityChannelFactory; IChannelFactory innerChannelFactory; ChannelBuilder channelBuilder; WrapperSecurityCommunicationObject communicationObject; SecurityStandardsManager standardsManager; SecurityTokenParameters issuedTokenParameters; int issuedTokenRenewalThreshold; object thisLock = new object(); public SecuritySessionClientSettings() { this.keyRenewalInterval = SecuritySessionClientSettings.defaultKeyRenewalInterval; this.keyRolloverInterval = SecuritySessionClientSettings.defaultKeyRolloverInterval; this.tolerateTransportFailures = SecuritySessionClientSettings.defaultTolerateTransportFailures; this.communicationObject = new WrapperSecurityCommunicationObject(this); } IChannelFactory InnerChannelFactory { get { return this.innerChannelFactory; } } internal ChannelBuilder ChannelBuilder { get { return this.channelBuilder; } set { this.channelBuilder = value; } } SecurityChannelFactory SecurityChannelFactory { get { return this.securityChannelFactory; } } public SecurityProtocolFactory SessionProtocolFactory { get { return this.sessionProtocolFactory; } set { this.communicationObject.ThrowIfDisposedOrImmutable(); this.sessionProtocolFactory = value; } } public TimeSpan KeyRenewalInterval { get { return this.keyRenewalInterval; } set { if (value <= TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.TimeSpanMustbeGreaterThanTimeSpanZero))); } this.communicationObject.ThrowIfDisposedOrImmutable(); this.keyRenewalInterval = value; } } public TimeSpan KeyRolloverInterval { get { return this.keyRolloverInterval; } set { if (value <= TimeSpan.Zero) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.TimeSpanMustbeGreaterThanTimeSpanZero))); } this.communicationObject.ThrowIfDisposedOrImmutable(); this.keyRolloverInterval = value; } } public bool TolerateTransportFailures { get { return this.tolerateTransportFailures; } set { this.communicationObject.ThrowIfDisposedOrImmutable(); this.tolerateTransportFailures = value; } } public SecurityTokenParameters IssuedSecurityTokenParameters { get { return this.issuedTokenParameters; } set { this.communicationObject.ThrowIfDisposedOrImmutable(); this.issuedTokenParameters = value; } } public SecurityStandardsManager SecurityStandardsManager { get { return this.standardsManager; } set { this.communicationObject.ThrowIfDisposedOrImmutable(); this.standardsManager = value; } } // ISecurityCommunicationObject members public TimeSpan DefaultOpenTimeout { get { return ServiceDefaults.OpenTimeout; } } public TimeSpan DefaultCloseTimeout { get { return ServiceDefaults.CloseTimeout; } } internal IChannelFactory CreateInnerChannelFactory() { if (this.ChannelBuilder.CanBuildChannelFactory ()) { return this.ChannelBuilder.BuildChannelFactory (); } else if (this.ChannelBuilder.CanBuildChannelFactory ()) { return this.ChannelBuilder.BuildChannelFactory (); } else if (this.ChannelBuilder.CanBuildChannelFactory ()) { return this.ChannelBuilder.BuildChannelFactory (); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } } public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return this.communicationObject.BeginClose(timeout, callback, state); } public void EndClose(IAsyncResult result) { this.communicationObject.EndClose(result); } IAsyncResult ISecurityCommunicationObject.OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnClose), timeout, callback, state); } IAsyncResult ISecurityCommunicationObject.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnOpen), timeout, callback, state); } public void OnClosed() { } public void OnClosing() { } void ISecurityCommunicationObject.OnEndClose(IAsyncResult result) { OperationWithTimeoutAsyncResult.End(result); } void ISecurityCommunicationObject.OnEndOpen(IAsyncResult result) { OperationWithTimeoutAsyncResult.End(result); } public void OnFaulted() { } public void OnOpened() { } public void OnOpening() { } public void OnClose(TimeSpan timeout) { if (this.sessionProtocolFactory != null) { this.sessionProtocolFactory.Close(false, timeout); } } public void OnAbort() { if (this.sessionProtocolFactory != null) { this.sessionProtocolFactory.Close(true, TimeSpan.Zero); } } public void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); if (this.sessionProtocolFactory == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecuritySessionProtocolFactoryShouldBeSetBeforeThisOperation))); } if (this.standardsManager == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityStandardsManagerNotSet, this.GetType().ToString()))); } if (this.issuedTokenParameters == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuedSecurityTokenParametersNotSet, this.GetType()))); } if (this.keyRenewalInterval < this.keyRolloverInterval) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.KeyRolloverGreaterThanKeyRenewal))); } this.issuedTokenRenewalThreshold = this.sessionProtocolFactory.SecurityBindingElement.LocalClientSettings.CookieRenewalThresholdPercentage; this.ConfigureSessionProtocolFactory(); this.sessionProtocolFactory.Open(true, timeoutHelper.RemainingTime()); } internal void Close(TimeSpan timeout) { this.communicationObject.Close(timeout); } internal void Abort() { this.communicationObject.Abort(); } internal void Open(SecurityChannelFactory securityChannelFactory, IChannelFactory innerChannelFactory, ChannelBuilder channelBuilder, TimeSpan timeout) { this.securityChannelFactory = securityChannelFactory; this.innerChannelFactory = innerChannelFactory; this.channelBuilder = channelBuilder; this.communicationObject.Open(timeout); } internal TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via) { return OnCreateChannel(remoteAddress, via, null); } internal TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via, MessageFilter filter) { this.communicationObject.ThrowIfClosed(); if (filter != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } if (typeof(TChannel) == typeof(IRequestSessionChannel)) { return (TChannel)((object)(new SecurityRequestSessionChannel(this, remoteAddress, via))); } else if (typeof(TChannel) == typeof(IDuplexSessionChannel)) { // typeof(TChannel) == typeof(IDuplexSessionChannel) return (TChannel)((object)(new ClientSecurityDuplexSessionChannel(this, remoteAddress, via))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel")); } } void ConfigureSessionProtocolFactory() { if (this.sessionProtocolFactory is SessionSymmetricMessageSecurityProtocolFactory) { AddressingVersion addressing = MessageVersion.Default.Addressing; if (this.channelBuilder != null) { MessageEncodingBindingElement encoding = this.channelBuilder.Binding.Elements.Find (); if (encoding != null) { addressing = encoding.MessageVersion.Addressing; } } if (addressing != AddressingVersion.WSAddressing10 && addressing != AddressingVersion.WSAddressingAugust2004) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, addressing))); } SessionSymmetricMessageSecurityProtocolFactory symmetric = (SessionSymmetricMessageSecurityProtocolFactory)this.sessionProtocolFactory; if (!symmetric.ApplyIntegrity || !symmetric.RequireIntegrity) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecuritySessionRequiresMessageIntegrity))); MessagePartSpecification bodyPart = new MessagePartSpecification(true); symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction); symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseAction); symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, addressing.FaultAction); symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, addressing.DefaultFaultAction); symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, DotNetSecurityStrings.SecuritySessionFaultAction); symmetric.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseAction); symmetric.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction); if (symmetric.ApplyConfidentiality) { symmetric.ProtectionRequirements.IncomingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseAction); symmetric.ProtectionRequirements.IncomingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction); } if (symmetric.RequireConfidentiality) { symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction); symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseAction); symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, addressing.FaultAction); symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, addressing.DefaultFaultAction); symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, DotNetSecurityStrings.SecuritySessionFaultAction); } } else if (this.sessionProtocolFactory is SessionSymmetricTransportSecurityProtocolFactory) { SessionSymmetricTransportSecurityProtocolFactory transport = (SessionSymmetricTransportSecurityProtocolFactory)this.sessionProtocolFactory; transport.AddTimestamp = true; transport.SecurityTokenParameters.RequireDerivedKeys = false; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } } abstract class ClientSecuritySessionChannel : ChannelBase { EndpointAddress to; Uri via; IClientReliableChannelBinder channelBinder; ChannelParameterCollection channelParameters; SecurityToken currentSessionToken; SecurityToken previousSessionToken; DateTime keyRenewalTime; DateTime keyRolloverTime; SecurityProtocol securityProtocol; SecuritySessionClientSettings settings; SecurityTokenProvider sessionTokenProvider; bool isKeyRenewalOngoing = false; InterruptibleWaitObject keyRenewalCompletedEvent; bool sentClose; bool receivedClose; volatile bool isOutputClosed; volatile bool isInputClosed; InterruptibleWaitObject inputSessionClosedHandle = new InterruptibleWaitObject(false); bool sendCloseHandshake = false; MessageVersion messageVersion; bool isCompositeDuplexConnection; Message closeResponse; InterruptibleWaitObject outputSessionCloseHandle = new InterruptibleWaitObject(true); protected ClientSecuritySessionChannel(SecuritySessionClientSettings settings, EndpointAddress to, Uri via) : base(settings.SecurityChannelFactory) { this.settings = settings; this.to = to; this.via = via; this.keyRenewalCompletedEvent = new InterruptibleWaitObject(false); this.messageVersion = settings.SecurityChannelFactory.MessageVersion; this.channelParameters = new ChannelParameterCollection(this); this.InitializeChannelBinder(); } protected SecuritySessionClientSettings Settings { get { return this.settings; } } protected IClientReliableChannelBinder ChannelBinder { get { return this.channelBinder; } } public EndpointAddress RemoteAddress { get { return this.to; } } public Uri Via { get { return this.via; } } protected bool SendCloseHandshake { get { return this.sendCloseHandshake; } } protected EndpointAddress InternalLocalAddress { get { if (this.channelBinder != null) return this.channelBinder.LocalAddress; return null; } } protected virtual bool CanDoSecurityCorrelation { get { return false; } } public MessageVersion MessageVersion { get { return this.messageVersion; } } protected bool IsInputClosed { get { return isInputClosed; } } protected bool IsOutputClosed { get { return isOutputClosed; } } protected abstract bool ExpectClose { get; } protected abstract string SessionId { get; } public override T GetProperty () { if (typeof(T) == typeof(ChannelParameterCollection)) { return this.channelParameters as T; } if (typeof(T) == typeof(FaultConverter) && (this.channelBinder != null)) { return new SecurityChannelFaultConverter(this.channelBinder.Channel) as T; } T result = base.GetProperty (); if ((result == null) && (channelBinder != null) && (channelBinder.Channel != null)) { result = channelBinder.Channel.GetProperty (); } return result; } protected abstract void InitializeSession(SecurityToken sessionToken); void InitializeSecurityState(SecurityToken sessionToken) { InitializeSession(sessionToken); this.currentSessionToken = sessionToken; this.previousSessionToken = null; List incomingSessionTokens = new List (1); incomingSessionTokens.Add(sessionToken); ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIdentityCheckAuthenticator(new GenericXmlSecurityTokenAuthenticator()); ((IInitiatorSecuritySessionProtocol) this.securityProtocol).SetIncomingSessionTokens(incomingSessionTokens); ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetOutgoingSessionToken(sessionToken); if (this.CanDoSecurityCorrelation) { ((IInitiatorSecuritySessionProtocol)this.securityProtocol).ReturnCorrelationState = true; } this.keyRenewalTime = GetKeyRenewalTime(sessionToken); } void SetupSessionTokenProvider() { InitiatorServiceModelSecurityTokenRequirement requirement = new InitiatorServiceModelSecurityTokenRequirement(); this.Settings.IssuedSecurityTokenParameters.InitializeSecurityTokenRequirement(requirement); requirement.KeyUsage = SecurityKeyUsage.Signature; requirement.SupportSecurityContextCancellation = true; requirement.SecurityAlgorithmSuite = this.Settings.SessionProtocolFactory.OutgoingAlgorithmSuite; requirement.SecurityBindingElement = this.Settings.SessionProtocolFactory.SecurityBindingElement; requirement.TargetAddress = this.to; requirement.Via = this.Via; requirement.MessageSecurityVersion = this.Settings.SessionProtocolFactory.MessageSecurityVersion.SecurityTokenVersion; requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty] = this.Settings.SessionProtocolFactory.PrivacyNoticeUri; if (this.channelParameters != null) { requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = this.channelParameters; } requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty] = this.Settings.SessionProtocolFactory.PrivacyNoticeVersion; if (this.channelBinder.LocalAddress != null) { requirement.DuplexClientLocalAddress = this.channelBinder.LocalAddress; } this.sessionTokenProvider = this.Settings.SessionProtocolFactory.SecurityTokenManager.CreateSecurityTokenProvider(requirement); } void OpenCore(SecurityToken sessionToken, TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.securityProtocol = this.Settings.SessionProtocolFactory.CreateSecurityProtocol(this.to, this.Via, null, true, timeoutHelper.RemainingTime()); if (!(this.securityProtocol is IInitiatorSecuritySessionProtocol)) { DiagnosticUtility.DebugAssert("Security protocol must be IInitiatorSecuritySessionProtocol."); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProtocolMisMatch, "IInitiatorSecuritySessionProtocol", this.GetType().ToString()))); } this.securityProtocol.Open(timeoutHelper.RemainingTime()); this.channelBinder.Open(timeoutHelper.RemainingTime()); this.InitializeSecurityState(sessionToken); } protected override void OnFaulted() { this.AbortCore(); this.inputSessionClosedHandle.Fault(this); this.keyRenewalCompletedEvent.Fault(this); this.outputSessionCloseHandle.Fault(this); base.OnFaulted(); } protected override void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SetupSessionTokenProvider(); SecurityUtils.OpenTokenProviderIfRequired(this.sessionTokenProvider, timeoutHelper.RemainingTime()); using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecuritySetup), ActivityType.SecuritySetup); } SecurityToken sessionToken = this.sessionTokenProvider.GetToken(timeoutHelper.RemainingTime()); this.OpenCore(sessionToken, timeoutHelper.RemainingTime()); } } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateAsyncActivity() : null; using (ServiceModelActivity.BoundOperation(activity, true)) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecuritySetup), ActivityType.SecuritySetup); } return new OpenAsyncResult(this, timeout, callback, state); } } protected override void OnEndOpen(IAsyncResult result) { OpenAsyncResult.End(result); } void InitializeChannelBinder() { ChannelBuilder channelBuilder = this.Settings.ChannelBuilder; TolerateFaultsMode faultMode = this.Settings.TolerateTransportFailures ? TolerateFaultsMode.Always : TolerateFaultsMode.Never; if (channelBuilder.CanBuildChannelFactory ()) { this.channelBinder = ClientReliableChannelBinder .CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory )(object)this.Settings.InnerChannelFactory, MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout); } else if (channelBuilder.CanBuildChannelFactory ()) { this.channelBinder = ClientReliableChannelBinder .CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory )(object)this.Settings.InnerChannelFactory, MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout); this.isCompositeDuplexConnection = true; } else if (channelBuilder.CanBuildChannelFactory ()) { this.channelBinder = ClientReliableChannelBinder .CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory )(object)this.Settings.InnerChannelFactory, MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout); } else if (channelBuilder.CanBuildChannelFactory ()) { this.channelBinder = ClientReliableChannelBinder .CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory )(object)this.Settings.InnerChannelFactory, MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout); } this.channelBinder.Faulted += this.OnInnerFaulted; } void OnInnerFaulted(IReliableChannelBinder sender, Exception exception) { this.Fault(exception); } protected virtual bool OnCloseResponseReceived() { bool setInputSessionClosedHandle = false; bool isCloseResponseExpected = false; lock (ThisLock) { isCloseResponseExpected = this.sentClose; if (isCloseResponseExpected && !this.isInputClosed) { this.isInputClosed = true; setInputSessionClosedHandle = true; } } if (!isCloseResponseExpected) { this.Fault(new ProtocolException(SR.GetString(SR.UnexpectedSecuritySessionCloseResponse))); return false; } if (setInputSessionClosedHandle) { this.inputSessionClosedHandle.Set(); } return true; } protected virtual bool OnCloseReceived() { if (!ExpectClose) { this.Fault(new ProtocolException(SR.GetString(SR.UnexpectedSecuritySessionClose))); return false; } bool setInputSessionClosedHandle = false; lock (ThisLock) { if (!this.isInputClosed) { this.isInputClosed = true; this.receivedClose = true; setInputSessionClosedHandle = true; } } if (setInputSessionClosedHandle) { this.inputSessionClosedHandle.Set(); } return true; } Message PrepareCloseMessage() { SecurityToken tokenToClose; lock (ThisLock) { tokenToClose = this.currentSessionToken; } RequestSecurityToken rst = new RequestSecurityToken(this.Settings.SecurityStandardsManager); rst.RequestType = this.Settings.SecurityStandardsManager.TrustDriver.RequestTypeClose; rst.CloseTarget = this.Settings.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(tokenToClose, SecurityTokenReferenceStyle.External); rst.MakeReadOnly(); Message closeMessage = Message.CreateMessage(this.MessageVersion, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseAction, this.MessageVersion.Addressing), rst); RequestReplyCorrelator.PrepareRequest(closeMessage); if (this.InternalLocalAddress != null) { closeMessage.Headers.ReplyTo = this.InternalLocalAddress; } else { if (closeMessage.Version.Addressing == AddressingVersion.WSAddressing10) { closeMessage.Headers.ReplyTo = null; } else if (closeMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004) { closeMessage.Headers.ReplyTo = EndpointAddress.AnonymousAddress; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, closeMessage.Version.Addressing))); } } if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity) { TraceUtility.AddAmbientActivityToMessage(closeMessage); } return closeMessage; } protected SecurityProtocolCorrelationState SendCloseMessage(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SecurityProtocolCorrelationState closeCorrelationState; Message closeMessage = PrepareCloseMessage(); try { closeCorrelationState = this.securityProtocol.SecureOutgoingMessage(ref closeMessage, timeoutHelper.RemainingTime(), null); this.ChannelBinder.Send(closeMessage, timeoutHelper.RemainingTime()); } finally { closeMessage.Close(); } SecurityTraceRecordHelper.TraceCloseMessageSent(this.currentSessionToken, this.RemoteAddress); return closeCorrelationState; } protected void SendCloseResponseMessage(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); Message message = null; try { message = this.closeResponse; this.securityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime(), null); this.ChannelBinder.Send(message, timeoutHelper.RemainingTime()); SecurityTraceRecordHelper.TraceCloseResponseMessageSent(this.currentSessionToken, this.RemoteAddress); } finally { message.Close(); } } IAsyncResult BeginSendCloseMessage(TimeSpan timeout, AsyncCallback callback, object state) { using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup); } Message closeMessage = PrepareCloseMessage(); return new SecureSendAsyncResult(closeMessage, this, timeout, callback, state, true); } } SecurityProtocolCorrelationState EndSendCloseMessage(IAsyncResult result) { SecurityProtocolCorrelationState correlationState = SecureSendAsyncResult.End(result); SecurityTraceRecordHelper.TraceCloseMessageSent(this.currentSessionToken, this.RemoteAddress); return correlationState; } IAsyncResult BeginSendCloseResponseMessage(TimeSpan timeout, AsyncCallback callback, object state) { return new SecureSendAsyncResult(this.closeResponse, this, timeout, callback, state, true); } void EndSendCloseResponseMessage(IAsyncResult result) { SecureSendAsyncResult.End(result); SecurityTraceRecordHelper.TraceCloseResponseMessageSent(this.currentSessionToken, this.RemoteAddress); } MessageFault GetProtocolFault(ref Message message, out bool isKeyRenewalFault, out bool isSessionAbortedFault) { isKeyRenewalFault = false; isSessionAbortedFault = false; MessageFault result = null; using (MessageBuffer buffer = message.CreateBufferedCopy(int.MaxValue)) { message = buffer.CreateMessage(); Message copy = buffer.CreateMessage(); MessageFault fault = MessageFault.CreateFault(copy, TransportDefaults.MaxSecurityFaultSize); if (fault.Code.IsSenderFault) { FaultCode subCode = fault.Code.SubCode; if (subCode != null) { SecurityStandardsManager standardsManager = this.securityProtocol.SecurityProtocolFactory.StandardsManager; SecureConversationDriver scDriver = standardsManager.SecureConversationDriver; if (subCode.Namespace == scDriver.Namespace.Value && subCode.Name == scDriver.RenewNeededFaultCode.Value) { result = fault; isKeyRenewalFault = true; } else if (subCode.Namespace == DotNetSecurityStrings.Namespace && subCode.Name == DotNetSecurityStrings.SecuritySessionAbortedFault) { result = fault; isSessionAbortedFault = true; } } } } return result; } void ProcessKeyRenewalFault() { SecurityTraceRecordHelper.TraceSessionKeyRenewalFault(this.currentSessionToken, this.RemoteAddress); lock (ThisLock) { this.keyRenewalTime = DateTime.UtcNow; } } void ProcessSessionAbortedFault(MessageFault sessionAbortedFault) { SecurityTraceRecordHelper.TraceRemoteSessionAbortedFault(this.currentSessionToken, this.RemoteAddress); this.Fault(new FaultException(sessionAbortedFault)); } void ProcessCloseResponse(Message response) { // the close message may have been received by the channel after the channel factory has been closed if (response.Headers.Action != this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction.Value) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.InvalidCloseResponseAction, response.Headers.Action)), response); } RequestSecurityTokenResponse rstr = null; XmlDictionaryReader bodyReader = response.GetReaderAtBodyContents(); using (bodyReader) { if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005) rstr = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityTokenResponse(bodyReader); else if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13) { RequestSecurityTokenResponseCollection rstrc = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader); foreach (RequestSecurityTokenResponse rstrItem in rstrc.RstrCollection) { if (rstr != null) { // More than one RSTR is found. So throw an exception. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MoreThanOneRSTRInRSTRC))); } rstr = rstrItem; } } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } response.ReadFromBodyContentsToEnd(bodyReader); } if (!rstr.IsRequestedTokenClosed) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SessionTokenWasNotClosed)), response); } } void PrepareReply(Message request, Message reply) { if (request.Headers.ReplyTo != null) { request.Headers.ReplyTo.ApplyTo(reply); } else if (request.Headers.From != null) { request.Headers.From.ApplyTo(reply); } if (request.Headers.MessageId != null) { reply.Headers.RelatesTo = request.Headers.MessageId; } TraceUtility.CopyActivity(request, reply); if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity) { TraceUtility.AddActivityHeader(reply); } } bool DoesSkiClauseMatchSigningToken(SecurityContextKeyIdentifierClause skiClause, Message request) { if (this.SessionId == null) { return false; } return (skiClause.ContextId.ToString() == this.SessionId); } void ProcessCloseMessage(Message message) { RequestSecurityToken rst; XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents(); using (bodyReader) { rst = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityToken(bodyReader); message.ReadFromBodyContentsToEnd(bodyReader); } if (rst.RequestType != null && rst.RequestType != this.Settings.SecurityStandardsManager.TrustDriver.RequestTypeClose) { throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.InvalidRstRequestType, rst.RequestType)), message); } if (rst.CloseTarget == null) { throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.NoCloseTargetSpecified)), message); } SecurityContextKeyIdentifierClause sctSkiClause = rst.CloseTarget as SecurityContextKeyIdentifierClause; if (sctSkiClause == null || !DoesSkiClauseMatchSigningToken(sctSkiClause, message)) { throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.BadCloseTarget, rst.CloseTarget)), message); } // prepare the close response RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.Settings.SecurityStandardsManager); rstr.Context = rst.Context; rstr.IsRequestedTokenClosed = true; rstr.MakeReadOnly(); Message response = null; if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005) response = Message.CreateMessage(message.Version, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction, message.Version.Addressing), rstr); else if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13) { List rstrList = new List (); rstrList.Add(rstr); RequestSecurityTokenResponseCollection rstrCollection = new RequestSecurityTokenResponseCollection(rstrList, this.Settings.SecurityStandardsManager); response = Message.CreateMessage(message.Version, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction, message.Version.Addressing), rstrCollection); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } PrepareReply(message, response); this.closeResponse = response; } bool ShouldWrapException(Exception e) { return ((e is FormatException) || (e is XmlException)); } protected Message ProcessIncomingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, out MessageFault protocolFault) { protocolFault = null; lock (ThisLock) { DoKeyRolloverIfNeeded(); } try { VerifyIncomingMessage(ref message, timeout, correlationState); string action = message.Headers.Action; if (action == this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction.Value) { SecurityTraceRecordHelper.TraceCloseResponseReceived(this.currentSessionToken, this.RemoteAddress); this.ProcessCloseResponse(message); this.OnCloseResponseReceived(); } else if (action == this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseAction.Value) { SecurityTraceRecordHelper.TraceCloseMessageReceived(this.currentSessionToken, this.RemoteAddress); this.ProcessCloseMessage(message); this.OnCloseReceived(); } else if (action == DotNetSecurityStrings.SecuritySessionFaultAction) { bool isKeyRenewalFault; bool isSessionAbortedFault; protocolFault = GetProtocolFault(ref message, out isKeyRenewalFault, out isSessionAbortedFault); if (isKeyRenewalFault) { ProcessKeyRenewalFault(); } else if (isSessionAbortedFault) { ProcessSessionAbortedFault(protocolFault); } else { return message; } } else { return message; } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if ((e is CommunicationException) || (e is TimeoutException) || (DiagnosticUtility.IsFatal(e)) || !ShouldWrapException(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e)); } message.Close(); return null; } protected Message ProcessRequestContext(RequestContext requestContext, TimeSpan timeout, SecurityProtocolCorrelationState correlationState) { if (requestContext == null) { return null; } TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); Message message = requestContext.RequestMessage; Message unverifiedMessage = message; try { Exception faultException = null; try { MessageFault dummyProtocolFault; return ProcessIncomingMessage(message, timeoutHelper.RemainingTime(), correlationState, out dummyProtocolFault); } catch (MessageSecurityException e) { // if the message is an unsecured security fault from the other party over the same connection then fault the session if (!isCompositeDuplexConnection) { if (unverifiedMessage.IsFault) { MessageFault fault = MessageFault.CreateFault(unverifiedMessage, TransportDefaults.MaxSecurityFaultSize); if (SecurityUtils.IsSecurityFault(fault, this.settings.sessionProtocolFactory.StandardsManager)) { faultException = SecurityUtils.CreateSecurityFaultException(fault); } } else { faultException = e; } } } if (faultException != null) { this.Fault(faultException); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(faultException); } return null; } finally { requestContext.Close(timeoutHelper.RemainingTime()); } } /// /// This method removes the previous session key when the key rollover time is past. /// It must be called within a lock /// void DoKeyRolloverIfNeeded() { if (DateTime.UtcNow >= this.keyRolloverTime && this.previousSessionToken != null) { SecurityTraceRecordHelper.TracePreviousSessionKeyDiscarded(this.previousSessionToken, this.currentSessionToken, this.RemoteAddress); // forget the previous session token this.previousSessionToken = null; ListincomingTokens = new List (1); incomingTokens.Add(this.currentSessionToken); ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIncomingSessionTokens(incomingTokens); } } DateTime GetKeyRenewalTime(SecurityToken token) { TimeSpan tokenValidityInterval = TimeSpan.FromTicks((long)(((token.ValidTo.Ticks - token.ValidFrom.Ticks) * this.settings.issuedTokenRenewalThreshold) / 100)); DateTime keyRenewalTime1 = TimeoutHelper.Add(token.ValidFrom, tokenValidityInterval); DateTime keyRenewalTime2 = TimeoutHelper.Add(token.ValidFrom, this.settings.keyRenewalInterval); if (keyRenewalTime1 < keyRenewalTime2) { return keyRenewalTime1; } else { return keyRenewalTime2; } } /// /// This method returns true if key renewal is needed. /// It must be called within a lock /// bool IsKeyRenewalNeeded() { return (DateTime.UtcNow >= this.keyRenewalTime); } ////// When the new session token is obtained, mark the current token as previous and remove it /// after KeyRolloverTime. Mark the new current as pending and update the next key renewal time /// void UpdateSessionTokens(SecurityToken newToken) { lock (ThisLock) { this.previousSessionToken = this.currentSessionToken; this.keyRolloverTime = TimeoutHelper.Add(DateTime.UtcNow, this.Settings.KeyRolloverInterval); this.currentSessionToken = newToken; this.keyRenewalTime = GetKeyRenewalTime(newToken); ListincomingTokens = new List (2); incomingTokens.Add(this.previousSessionToken); incomingTokens.Add(this.currentSessionToken); ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIncomingSessionTokens(incomingTokens); ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetOutgoingSessionToken(this.currentSessionToken); SecurityTraceRecordHelper.TraceSessionKeyRenewed(this.currentSessionToken, this.previousSessionToken, this.RemoteAddress); } } void RenewKey(TimeSpan timeout) { bool startKeyRenewal; lock (ThisLock) { if (!this.isKeyRenewalOngoing) { this.isKeyRenewalOngoing = true; this.keyRenewalCompletedEvent.Reset(); startKeyRenewal = true; } else { startKeyRenewal = false; } } if (startKeyRenewal == true) { try { using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityRenew), ActivityType.SecuritySetup); } SecurityToken renewedToken = this.sessionTokenProvider.RenewToken(timeout, this.currentSessionToken); UpdateSessionTokens(renewedToken); } } finally { lock (ThisLock) { this.isKeyRenewalOngoing = false; this.keyRenewalCompletedEvent.Set(); } } } else { this.keyRenewalCompletedEvent.Wait(timeout); lock (ThisLock) { if (IsKeyRenewalNeeded()) { // the key renewal attempt failed. Throw an exception to the user throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SessionKeyExpiredException(SR.GetString(SR.UnableToRenewSessionKey))); } } } } bool CheckIfKeyRenewalNeeded() { bool doKeyRenewal = false; lock (ThisLock) { doKeyRenewal = IsKeyRenewalNeeded(); DoKeyRolloverIfNeeded(); } return doKeyRenewal; } protected IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state) { // if at least 1 app message is sent on the session, a close handshake should be done this.sendCloseHandshake = true; bool doKeyRenewal = CheckIfKeyRenewalNeeded(); if (!doKeyRenewal) { SecurityProtocolCorrelationState correlationState = this.securityProtocol.SecureOutgoingMessage(ref message, timeout, null); return new TypedCompletedAsyncResult (message, correlationState, callback, state); } else { return new KeyRenewalAsyncResult(message, this, timeout, callback, state); } } protected Message EndSecureOutgoingMessage(IAsyncResult result, out SecurityProtocolCorrelationState correlationState) { if (result is TypedCompletedAsyncResult ) { return TypedCompletedAsyncResult .End(result, out correlationState); } else { TimeSpan remainingTime; Message message = KeyRenewalAsyncResult.End(result, out remainingTime); correlationState = this.securityProtocol.SecureOutgoingMessage(ref message, remainingTime, null); return message; } } protected SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout) { // if at least 1 app message is sent on the session, a close handshake should be done this.sendCloseHandshake = true; bool doKeyRenewal = CheckIfKeyRenewalNeeded(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); if (doKeyRenewal) { RenewKey(timeoutHelper.RemainingTime()); } return this.securityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime(), null); } protected void VerifyIncomingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState) { this.securityProtocol.VerifyIncomingMessage(ref message, timeout, correlationState); } protected virtual void AbortCore() { if (this.channelBinder != null) { this.channelBinder.Abort(); } if (this.sessionTokenProvider != null) { SecurityUtils.AbortTokenProviderIfRequired(this.sessionTokenProvider); } } protected virtual void CloseCore(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); try { if (this.channelBinder != null) { this.channelBinder.Close(timeoutHelper.RemainingTime()); } if (this.sessionTokenProvider != null) { SecurityUtils.CloseTokenProviderIfRequired(this.sessionTokenProvider, timeoutHelper.RemainingTime()); } this.keyRenewalCompletedEvent.Abort(this); this.inputSessionClosedHandle.Abort(this); } catch (CommunicationObjectAbortedException) { if (this.State != CommunicationState.Closed) { throw; } } } protected virtual IAsyncResult BeginCloseCore(TimeSpan timeout, AsyncCallback callback, object state) { return new CloseCoreAsyncResult(this, timeout, callback, state); } protected virtual void EndCloseCore(IAsyncResult result) { CloseCoreAsyncResult.End(result); } protected IAsyncResult BeginReceiveInternal(TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state) { return new ReceiveAsyncResult(this, timeout, correlationState, callback, state); } protected Message EndReceiveInternal(IAsyncResult result) { return ReceiveAsyncResult.End(result); } protected Message ReceiveInternal(TimeSpan timeout, SecurityProtocolCorrelationState correlationState) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); while (!this.isInputClosed) { RequestContext requestContext; if (this.ChannelBinder.TryReceive(timeoutHelper.RemainingTime(), out requestContext)) { if (requestContext == null) { return null; } Message message = ProcessRequestContext(requestContext, timeoutHelper.RemainingTime(), correlationState); if (message != null) { return message; } } if (timeoutHelper.RemainingTimeExpireNegative() < TimeSpan.Zero) { // we timed out break; } } return null; } protected bool CloseSession(TimeSpan timeout, out bool wasAborted) { using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup); } TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); wasAborted = false; try { this.CloseOutputSession(timeoutHelper.RemainingTime()); return this.inputSessionClosedHandle.Wait(timeoutHelper.RemainingTime(), false); } catch (CommunicationObjectAbortedException) { if (this.State != CommunicationState.Closed) { throw; } wasAborted = true; } return false; } } protected IAsyncResult BeginCloseSession(TimeSpan timeout, AsyncCallback callback, object state) { using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateAsyncActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup); } return new CloseSessionAsyncResult(timeout, this, callback, state); } } protected bool EndCloseSession(IAsyncResult result, out bool wasAborted) { return CloseSessionAsyncResult.End(result, out wasAborted); } void DetermineCloseMessageToSend(out bool sendClose, out bool sendCloseResponse) { sendClose = false; sendCloseResponse = false; lock (ThisLock) { if (!this.isOutputClosed) { this.isOutputClosed = true; if (this.receivedClose) { sendCloseResponse = true; } else { sendClose = true; this.sentClose = true; } this.outputSessionCloseHandle.Reset(); } } } protected virtual SecurityProtocolCorrelationState CloseOutputSession(TimeSpan timeout) { ThrowIfFaulted(); if (!this.SendCloseHandshake) { return null; } bool sendClose; bool sendCloseResponse; DetermineCloseMessageToSend(out sendClose, out sendCloseResponse); if (sendClose || sendCloseResponse) { try { if (sendClose) { return this.SendCloseMessage(timeout); } else { this.SendCloseResponseMessage(timeout); return null; } } finally { this.outputSessionCloseHandle.Set(); } } else { return null; } } protected virtual IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state) { ThrowIfFaulted(); if (!this.SendCloseHandshake) { return new CompletedAsyncResult(callback, state); } bool sendClose; bool sendCloseResponse; DetermineCloseMessageToSend(out sendClose, out sendCloseResponse); if (sendClose || sendCloseResponse) { bool setOutputSessionCloseHandle = true; try { IAsyncResult result; if (sendClose) { result = this.BeginSendCloseMessage(timeout, callback, state); } else { result = this.BeginSendCloseResponseMessage(timeout, callback, state); } setOutputSessionCloseHandle = false; return result; } finally { if (setOutputSessionCloseHandle) { this.outputSessionCloseHandle.Set(); } } } else { return new CompletedAsyncResult(callback, state); } } protected virtual SecurityProtocolCorrelationState EndCloseOutputSession(IAsyncResult result) { if (result is CompletedAsyncResult) { CompletedAsyncResult.End(result); return null; } bool sentCloseLocal; lock (ThisLock) { sentCloseLocal = this.sentClose; } try { if (sentCloseLocal) { return this.EndSendCloseMessage(result); } else { this.EndSendCloseResponseMessage(result); return null; } } finally { this.outputSessionCloseHandle.Set(); } } protected void CheckOutputOpen() { ThrowIfClosedOrNotOpen(); lock (ThisLock) { if (isOutputClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new CommunicationException(SR.GetString(SR.OutputNotExpected))); } } } protected override void OnAbort() { this.AbortCore(); this.inputSessionClosedHandle.Abort(this); this.keyRenewalCompletedEvent.Abort(this); this.outputSessionCloseHandle.Abort(this); } protected override void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); if (this.SendCloseHandshake) { bool wasAborted; bool wasSessionClosed = this.CloseSession(timeout, out wasAborted); if (wasAborted) { return; } if (!wasSessionClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, timeout))); } // wait for any concurrent output session close to finish try { if (!this.outputSessionCloseHandle.Wait(timeoutHelper.RemainingTime(), false)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, timeoutHelper.OriginalTimeout))); } } catch (CommunicationObjectAbortedException) { if (this.State == CommunicationState.Closed) { return; } else { throw; } } } this.CloseCore(timeoutHelper.RemainingTime()); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new CloseAsyncResult(this, timeout, callback, state); } protected override void OnEndClose(IAsyncResult result) { CloseAsyncResult.End(result); } class CloseCoreAsyncResult : TraceAsyncResult { static AsyncCallback closeChannelBinderCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(ChannelBinderCloseCallback)); static AsyncCallback closeTokenProviderCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseTokenProviderCallback)); TimeoutHelper timeoutHelper; ClientSecuritySessionChannel channel; public CloseCoreAsyncResult(ClientSecuritySessionChannel channel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.channel = channel; this.timeoutHelper = new TimeoutHelper(timeout); bool completeSelf = false; if (channel.channelBinder != null) { try { IAsyncResult result = this.channel.channelBinder.BeginClose(timeoutHelper.RemainingTime(), closeChannelBinderCallback, this); if (!result.CompletedSynchronously) { return; } this.channel.channelBinder.EndClose(result); } catch (CommunicationObjectAbortedException) { if (this.channel.State != CommunicationState.Closed) { throw; } completeSelf = true; } } if (!completeSelf) { completeSelf = this.OnChannelBinderClosed(); } if (completeSelf) { Complete(true); } } static void ChannelBinderCloseCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseCoreAsyncResult self = (CloseCoreAsyncResult)(result.AsyncState); Exception completionException = null; bool completeSelf = false; try { try { self.channel.channelBinder.EndClose(result); } catch (CommunicationObjectAbortedException) { if (self.channel.State != CommunicationState.Closed) { throw; } completeSelf = true; } if (!completeSelf) { completeSelf = self.OnChannelBinderClosed(); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { self.Complete(false, completionException); } } bool OnChannelBinderClosed() { if (channel.sessionTokenProvider != null) { try { IAsyncResult result = SecurityUtils.BeginCloseTokenProviderIfRequired(this.channel.sessionTokenProvider, timeoutHelper.RemainingTime(), closeTokenProviderCallback, this); if (!result.CompletedSynchronously) { return false; } SecurityUtils.EndCloseTokenProviderIfRequired(result); } catch (CommunicationObjectAbortedException) { if (channel.State != CommunicationState.Closed) { throw; } return true; } } return this.OnTokenProviderClosed(); } static void CloseTokenProviderCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseCoreAsyncResult self = (CloseCoreAsyncResult)(result.AsyncState); Exception completionException = null; bool completeSelf = false; try { try { SecurityUtils.EndCloseTokenProviderIfRequired(result); } catch (CommunicationObjectAbortedException) { if (self.channel.State != CommunicationState.Closed) { throw; } completeSelf = true; } if (!completeSelf) { completeSelf = self.OnTokenProviderClosed(); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { self.Complete(false, completionException); } } bool OnTokenProviderClosed() { this.channel.keyRenewalCompletedEvent.Abort(this.channel); this.channel.inputSessionClosedHandle.Abort(this.channel); return true; } public static void End(IAsyncResult result) { AsyncResult.End (result); } } class ReceiveAsyncResult : TraceAsyncResult { static AsyncCallback onReceive = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnReceive)); ClientSecuritySessionChannel channel; Message message; SecurityProtocolCorrelationState correlationState; TimeoutHelper timeoutHelper; public ReceiveAsyncResult(ClientSecuritySessionChannel channel, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state) : base(callback, state) { this.channel = channel; this.correlationState = correlationState; this.timeoutHelper = new TimeoutHelper(timeout); IAsyncResult result = channel.ChannelBinder.BeginTryReceive(timeoutHelper.RemainingTime(), onReceive, this); if (!result.CompletedSynchronously) return; bool completedSynchronously = CompleteReceive(result); if (completedSynchronously) { Complete(true); } } bool CompleteReceive(IAsyncResult result) { while (!channel.isInputClosed) { RequestContext requestContext; if (channel.ChannelBinder.EndTryReceive(result, out requestContext)) { if (requestContext == null) break; message = channel.ProcessRequestContext(requestContext, timeoutHelper.RemainingTime(), this.correlationState); if (message != null || channel.isInputClosed) break; } TimeSpan timeout = timeoutHelper.RemainingTimeExpireNegative(); if (timeout < TimeSpan.Zero) { // we timed out break; } result = channel.ChannelBinder.BeginTryReceive(timeoutHelper.RemainingTime(), onReceive, this); if (!result.CompletedSynchronously) return false; } return true; } public static Message End(IAsyncResult result) { ReceiveAsyncResult receiveResult = AsyncResult.End (result); return receiveResult.message; } static void OnReceive(IAsyncResult result) { if (result.CompletedSynchronously) return; ReceiveAsyncResult self = (ReceiveAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { completeSelf = self.CompleteReceive(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { self.Complete(false, completionException); } } } class OpenAsyncResult : TraceAsyncResult { static readonly AsyncCallback getTokenCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(GetTokenCallback)); static readonly AsyncCallback openTokenProviderCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OpenTokenProviderCallback)); ClientSecuritySessionChannel sessionChannel; TimeoutHelper timeoutHelper; public OpenAsyncResult(ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.timeoutHelper = new TimeoutHelper(timeout); this.sessionChannel = sessionChannel; this.sessionChannel.SetupSessionTokenProvider(); IAsyncResult result = SecurityUtils.BeginOpenTokenProviderIfRequired(this.sessionChannel.sessionTokenProvider, timeoutHelper.RemainingTime(), openTokenProviderCallback, this); if (!result.CompletedSynchronously) { return; } SecurityUtils.EndOpenTokenProviderIfRequired(result); bool completeSelf = this.OnTokenProviderOpened(); if (completeSelf) { Complete(true); } } static void OpenTokenProviderCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } OpenAsyncResult thisAsyncResult = (OpenAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { SecurityUtils.EndOpenTokenProviderIfRequired(result); completeSelf = thisAsyncResult.OnTokenProviderOpened(); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisAsyncResult.Complete(false, completionException); } } bool OnTokenProviderOpened() { IAsyncResult result = this.sessionChannel.sessionTokenProvider.BeginGetToken(timeoutHelper.RemainingTime(), getTokenCallback, this); if (!result.CompletedSynchronously) { return false; } SecurityToken sessionToken = this.sessionChannel.sessionTokenProvider.EndGetToken(result); return this.OnTokenObtained(sessionToken); } bool OnTokenObtained(SecurityToken sessionToken) { this.sessionChannel.OpenCore(sessionToken, timeoutHelper.RemainingTime()); return true; } static void GetTokenCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } OpenAsyncResult thisAsyncResult = (OpenAsyncResult)result.AsyncState; try { using (ServiceModelActivity.BoundOperation(thisAsyncResult.CallbackActivity)) { bool completeSelf = false; Exception completionException = null; try { SecurityToken sessionToken = thisAsyncResult.sessionChannel.sessionTokenProvider.EndGetToken(result); completeSelf = thisAsyncResult.OnTokenObtained(sessionToken); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisAsyncResult.Complete(false, completionException); } } } finally { if (thisAsyncResult.CallbackActivity != null) { thisAsyncResult.CallbackActivity.Dispose(); } } } public static void End(IAsyncResult result) { AsyncResult.End (result); ServiceModelActivity.Stop(((OpenAsyncResult)result).CallbackActivity); } } class CloseSessionAsyncResult : TraceAsyncResult { static readonly AsyncCallback closeOutputSessionCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseOutputSessionCallback)); static readonly AsyncCallback shutdownWaitCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(ShutdownWaitCallback)); ClientSecuritySessionChannel sessionChannel; bool closeCompleted; bool wasAborted; TimeoutHelper timeoutHelper; public CloseSessionAsyncResult(TimeSpan timeout, ClientSecuritySessionChannel sessionChannel, AsyncCallback callback, object state) : base(callback, state) { this.timeoutHelper = new TimeoutHelper(timeout); this.sessionChannel = sessionChannel; bool completeSelf = false; try { IAsyncResult result = this.sessionChannel.BeginCloseOutputSession(timeoutHelper.RemainingTime(), closeOutputSessionCallback, this); if (!result.CompletedSynchronously) { return; } this.sessionChannel.EndCloseOutputSession(result); } catch (CommunicationObjectAbortedException) { if (this.sessionChannel.State != CommunicationState.Closed) { throw; } completeSelf = true; wasAborted = true; } if (!wasAborted) { completeSelf = this.OnOutputSessionClosed(); } if (completeSelf) { Complete(true); } } static void CloseOutputSessionCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseSessionAsyncResult thisResult = (CloseSessionAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { try { thisResult.sessionChannel.EndCloseOutputSession(result); } catch (CommunicationObjectAbortedException) { if (thisResult.sessionChannel.State != CommunicationState.Closed) { throw; } thisResult.wasAborted = true; completeSelf = true; } if (!thisResult.wasAborted) { completeSelf = thisResult.OnOutputSessionClosed(); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisResult.Complete(false, completionException); } } bool OnOutputSessionClosed() { try { IAsyncResult result = this.sessionChannel.inputSessionClosedHandle.BeginWait(this.timeoutHelper.RemainingTime(), true, shutdownWaitCallback, this); if (!result.CompletedSynchronously) { return false; } this.sessionChannel.inputSessionClosedHandle.EndWait(result); this.closeCompleted = true; } catch (CommunicationObjectAbortedException) { if (this.sessionChannel.State != CommunicationState.Closed) { throw; } // if the channel was aborted by a parallel thread, allow the Close to // complete cleanly this.wasAborted = true; } catch (TimeoutException) { this.closeCompleted = false; } return true; } static void ShutdownWaitCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseSessionAsyncResult thisResult = (CloseSessionAsyncResult)result.AsyncState; Exception completionException = null; try { thisResult.sessionChannel.inputSessionClosedHandle.EndWait(result); thisResult.closeCompleted = true; } catch (CommunicationObjectAbortedException) { if (thisResult.sessionChannel.State != CommunicationState.Closed) { throw; } thisResult.wasAborted = true; } catch (TimeoutException) { thisResult.closeCompleted = false; } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completionException = e; } thisResult.Complete(false, completionException); } public static bool End(IAsyncResult result, out bool wasAborted) { CloseSessionAsyncResult thisResult = AsyncResult.End (result); wasAborted = thisResult.wasAborted; ServiceModelActivity.Stop(thisResult.CallbackActivity); return thisResult.closeCompleted; } } class CloseAsyncResult : TraceAsyncResult { static readonly AsyncCallback closeSessionCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseSessionCallback)); static readonly AsyncCallback outputSessionClosedCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OutputSessionClosedCallback)); static readonly AsyncCallback closeCoreCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseCoreCallback)); ClientSecuritySessionChannel sessionChannel; TimeoutHelper timeoutHelper; public CloseAsyncResult(ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { sessionChannel.ThrowIfFaulted(); this.timeoutHelper = new TimeoutHelper(timeout); this.sessionChannel = sessionChannel; if (!sessionChannel.SendCloseHandshake) { if (this.CloseCore()) { Complete(true); } return; } bool wasClosed; bool wasAborted = false; IAsyncResult result = this.sessionChannel.BeginCloseSession(this.timeoutHelper.RemainingTime(), closeSessionCallback, this); if (!result.CompletedSynchronously) { return; } wasClosed = this.sessionChannel.EndCloseSession(result, out wasAborted); if (wasAborted) { Complete(true); return; } if (!wasClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, timeout))); } bool completeSelf = this.OnWaitForOutputSessionClose(out wasAborted); if (wasAborted || completeSelf) { Complete(true); } } static void CloseSessionCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseAsyncResult thisResult = (CloseAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { bool wasAborted; bool wasClosed = thisResult.sessionChannel.EndCloseSession(result, out wasAborted); if (wasAborted) { completeSelf = true; } else { if (!wasClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, thisResult.timeoutHelper.OriginalTimeout))); } completeSelf = thisResult.OnWaitForOutputSessionClose(out wasAborted); if (wasAborted) { completeSelf = true; } } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisResult.Complete(false, completionException); } } bool OnWaitForOutputSessionClose(out bool wasAborted) { wasAborted = false; bool wasOutputSessionClosed = false; // wait for pending output sessions to finish try { IAsyncResult result = this.sessionChannel.outputSessionCloseHandle.BeginWait(timeoutHelper.RemainingTime(), true, outputSessionClosedCallback, this); if (!result.CompletedSynchronously) { return false; } this.sessionChannel.outputSessionCloseHandle.EndWait(result); wasOutputSessionClosed = true; } catch (TimeoutException) { wasOutputSessionClosed = false; } catch (CommunicationObjectAbortedException) { if (this.sessionChannel.State == CommunicationState.Closed) { wasAborted = true; } else { throw; } } if (wasAborted) { return true; } if (!wasOutputSessionClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, timeoutHelper.OriginalTimeout))); } else { return this.CloseCore(); } } static void OutputSessionClosedCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseAsyncResult self = (CloseAsyncResult)(result.AsyncState); Exception completionException = null; bool completeSelf = false; try { bool wasOutputSessionClosed = false; bool wasAborted = false; try { self.sessionChannel.outputSessionCloseHandle.EndWait(result); wasOutputSessionClosed = true; } catch (TimeoutException) { wasOutputSessionClosed = false; } catch (CommunicationObjectFaultedException) { if (self.sessionChannel.State == CommunicationState.Closed) { wasAborted = true; } else { throw; } } if (!wasAborted) { if (!wasOutputSessionClosed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, self.timeoutHelper.OriginalTimeout))); } completeSelf = self.CloseCore(); } else { completeSelf = true; } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; completionException = e; completeSelf = true; } if (completeSelf) { self.Complete(false, completionException); } } bool CloseCore() { IAsyncResult result = this.sessionChannel.BeginCloseCore(timeoutHelper.RemainingTime(), closeCoreCallback, this); if (!result.CompletedSynchronously) { return false; } this.sessionChannel.EndCloseCore(result); return true; } static void CloseCoreCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseAsyncResult self = (CloseAsyncResult)(result.AsyncState); Exception completionException = null; try { self.sessionChannel.EndCloseCore(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) { throw; } completionException = e; } self.Complete(false, completionException); } public static void End(IAsyncResult result) { AsyncResult.End (result); } } class KeyRenewalAsyncResult : TraceAsyncResult { static readonly WaitCallback renewKeyCallback = new WaitCallback(RenewKeyCallback); Message message; ClientSecuritySessionChannel sessionChannel; TimeoutHelper timeoutHelper; public KeyRenewalAsyncResult(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { timeoutHelper = new TimeoutHelper(timeout); this.message = message; this.sessionChannel = sessionChannel; // its ok to start up a separate thread for this since this is a very rare event. IOThreadScheduler.ScheduleCallback(renewKeyCallback, this); } static void RenewKeyCallback(object state) { KeyRenewalAsyncResult thisResult = (KeyRenewalAsyncResult)state; Exception completionException = null; try { using (thisResult.CallbackActivity == null ? null : ServiceModelActivity.BoundOperation(thisResult.CallbackActivity)) { thisResult.sessionChannel.RenewKey(thisResult.timeoutHelper.RemainingTime()); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completionException = e; } thisResult.Complete(false, completionException); } public static Message End(IAsyncResult result, out TimeSpan remainingTime) { KeyRenewalAsyncResult thisResult = AsyncResult.End (result); remainingTime = thisResult.timeoutHelper.RemainingTime(); return thisResult.message; } } internal abstract class SecureSendAsyncResultBase : TraceAsyncResult { static readonly AsyncCallback secureOutgoingMessageCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(SecureOutgoingMessageCallback)); Message message; SecurityProtocolCorrelationState correlationState; ClientSecuritySessionChannel sessionChannel; bool didSecureOutgoingMessageCompleteSynchronously = false; TimeoutHelper timeoutHelper; protected SecureSendAsyncResultBase(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.message = message; this.sessionChannel = sessionChannel; this.timeoutHelper = new TimeoutHelper(timeout); IAsyncResult result = this.sessionChannel.BeginSecureOutgoingMessage(message, timeoutHelper.RemainingTime(), secureOutgoingMessageCallback, this); if (!result.CompletedSynchronously) { return; } this.message = this.sessionChannel.EndSecureOutgoingMessage(result, out this.correlationState); this.didSecureOutgoingMessageCompleteSynchronously = true; } protected bool DidSecureOutgoingMessageCompleteSynchronously { get { return this.didSecureOutgoingMessageCompleteSynchronously; } } protected TimeoutHelper TimeoutHelper { get { return this.timeoutHelper; } } protected IClientReliableChannelBinder ChannelBinder { get { return this.sessionChannel.ChannelBinder; } } protected Message Message { get { return this.message; } } protected SecurityProtocolCorrelationState SecurityCorrelationState { get { return this.correlationState; } } protected abstract bool OnMessageSecured(); static void SecureOutgoingMessageCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } SecureSendAsyncResultBase thisResult = (SecureSendAsyncResultBase)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { thisResult.message = thisResult.sessionChannel.EndSecureOutgoingMessage(result, out thisResult.correlationState); completeSelf = thisResult.OnMessageSecured(); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisResult.Complete(false, completionException); } } } internal sealed class SecureSendAsyncResult : SecureSendAsyncResultBase { static readonly AsyncCallback sendCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(SendCallback)); bool autoCloseMessage; public SecureSendAsyncResult(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state, bool autoCloseMessage) : base(message, sessionChannel, timeout, callback, state) { this.autoCloseMessage = autoCloseMessage; if (!this.DidSecureOutgoingMessageCompleteSynchronously) { return; } bool completeSelf = this.OnMessageSecured(); if (completeSelf) { Complete(true); } } protected override bool OnMessageSecured() { bool closeMessage = true; try { IAsyncResult result = this.ChannelBinder.BeginSend(this.Message, this.TimeoutHelper.RemainingTime(), sendCallback, this); if (!result.CompletedSynchronously) { closeMessage = false; return false; } this.ChannelBinder.EndSend(result); return true; } finally { if (closeMessage && this.autoCloseMessage && this.Message != null) { this.Message.Close(); } } } static void SendCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } SecureSendAsyncResult thisResult = (SecureSendAsyncResult)result.AsyncState; Exception completionException = null; try { thisResult.ChannelBinder.EndSend(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completionException = e; } finally { if (thisResult.autoCloseMessage && thisResult.Message != null) { thisResult.Message.Close(); } if (thisResult.CallbackActivity != null && DiagnosticUtility.ShouldUseActivity) { thisResult.CallbackActivity.Stop(); } } thisResult.Complete(false, completionException); } public static SecurityProtocolCorrelationState End(IAsyncResult result) { SecureSendAsyncResult thisResult = AsyncResult.End (result); return thisResult.SecurityCorrelationState; } } protected class SoapSecurityOutputSession : ISecureConversationSession, IOutputSession { ClientSecuritySessionChannel channel; EndpointIdentity remoteIdentity; UniqueId sessionId; SecurityKeyIdentifierClause sessionTokenIdentifier; SecurityStandardsManager standardsManager; public SoapSecurityOutputSession(ClientSecuritySessionChannel channel) { this.channel = channel; } internal void Initialize(SecurityToken sessionToken, SecuritySessionClientSettings settings) { if (sessionToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sessionToken"); } if (settings == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("settings"); } Claim identityClaim = SecurityUtils.GetPrimaryIdentityClaim(((GenericXmlSecurityToken)sessionToken).AuthorizationPolicies); if (identityClaim != null) { this.remoteIdentity = EndpointIdentity.CreateIdentity(identityClaim); } this.standardsManager = settings.SessionProtocolFactory.StandardsManager; this.sessionId = GetSessionId(sessionToken, this.standardsManager); this.sessionTokenIdentifier = settings.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(sessionToken, SecurityTokenReferenceStyle.External); } UniqueId GetSessionId(SecurityToken sessionToken, SecurityStandardsManager standardsManager) { GenericXmlSecurityToken gxt = sessionToken as GenericXmlSecurityToken; if (gxt == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SessionTokenIsNotGenericXmlToken, sessionToken, typeof(GenericXmlSecurityToken)))); } return standardsManager.SecureConversationDriver.GetSecurityContextTokenId(XmlDictionaryReader.CreateDictionaryReader(new XmlNodeReader(gxt.TokenXml))); } public string Id { get { if (this.sessionId == null) { // PreSharp Bug: Property get methods should not throw exceptions. #pragma warning suppress 56503 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelMustBeOpenedToGetSessionId))); } return this.sessionId.ToString(); } } public EndpointIdentity RemoteIdentity { get { return this.remoteIdentity; } } public void WriteSessionTokenIdentifier(XmlDictionaryWriter writer) { this.channel.ThrowIfDisposedOrNotOpen(); this.standardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, this.sessionTokenIdentifier); } public bool TryReadSessionTokenIdentifier(XmlReader reader) { this.channel.ThrowIfDisposedOrNotOpen(); if (!this.standardsManager.SecurityTokenSerializer.CanReadKeyIdentifierClause(reader)) { return false; } SecurityContextKeyIdentifierClause incomingTokenIdentifier = this.standardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(reader) as SecurityContextKeyIdentifierClause; return incomingTokenIdentifier != null && incomingTokenIdentifier.Matches(sessionId, null); } } } abstract class ClientSecuritySimplexSessionChannel : ClientSecuritySessionChannel { SoapSecurityOutputSession outputSession; protected ClientSecuritySimplexSessionChannel(SecuritySessionClientSettings settings, EndpointAddress to, Uri via) : base(settings, to, via) { this.outputSession = new SoapSecurityOutputSession(this); } public IOutputSession Session { get { return this.outputSession; } } protected override bool ExpectClose { get { return false; } } protected override string SessionId { get { return this.Session.Id; } } protected override void InitializeSession(SecurityToken sessionToken) { this.outputSession.Initialize(sessionToken, this.Settings); } } sealed class SecurityRequestSessionChannel : ClientSecuritySimplexSessionChannel, IRequestSessionChannel { public SecurityRequestSessionChannel(SecuritySessionClientSettings settings, EndpointAddress to, Uri via) : base(settings, to, via) { } protected override bool CanDoSecurityCorrelation { get { return true; } } protected override SecurityProtocolCorrelationState CloseOutputSession(TimeSpan timeout) { ThrowIfFaulted(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SecurityProtocolCorrelationState correlationState = base.CloseOutputSession(timeoutHelper.RemainingTime()); Message message = ReceiveInternal(timeoutHelper.RemainingTime(), correlationState); if (message != null) { using (message) { ProtocolException error = ProtocolException.ReceiveShutdownReturnedNonNull(message); throw TraceUtility.ThrowHelperWarning(error, message); } } return null; } protected override IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state) { ThrowIfFaulted(); return new CloseOutputSessionAsyncResult(this, timeout, callback, state); } protected override SecurityProtocolCorrelationState EndCloseOutputSession(IAsyncResult result) { CloseOutputSessionAsyncResult.End(result); return null; } IAsyncResult BeginBaseCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state) { return base.BeginCloseOutputSession(timeout, callback, state); } SecurityProtocolCorrelationState EndBaseCloseOutputSession(IAsyncResult result) { return base.EndCloseOutputSession(result); } public Message Request(Message message) { return this.Request(message, this.DefaultSendTimeout); } Message ProcessReply(Message reply, TimeSpan timeout, SecurityProtocolCorrelationState correlationState) { if (reply == null) { return null; } Message unverifiedReply = reply; Message processedReply = null; MessageFault protocolFault = null; Exception faultException = null; try { processedReply = this.ProcessIncomingMessage(reply, timeout, correlationState, out protocolFault); } catch (MessageSecurityException) { if (unverifiedReply.IsFault) { MessageFault fault = MessageFault.CreateFault(unverifiedReply, TransportDefaults.MaxSecurityFaultSize); if (SecurityUtils.IsSecurityFault(fault, this.Settings.standardsManager)) { faultException = SecurityUtils.CreateSecurityFaultException(fault); } } if (faultException == null) { throw; } } if (faultException != null) { Fault(faultException); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(faultException); } if (processedReply == null && protocolFault != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SecuritySessionFaultReplyWasSent), new FaultException(protocolFault))); } return processedReply; } public Message Request(Message message, TimeSpan timeout) { ThrowIfFaulted(); CheckOutputOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SecurityProtocolCorrelationState correlationState = this.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime()); Message reply = this.ChannelBinder.Request(message, timeoutHelper.RemainingTime()); return ProcessReply(reply, timeoutHelper.RemainingTime(), correlationState); } 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(); CheckOutputOpen(); return new SecureRequestAsyncResult(message, this, timeout, callback, state); } public Message EndRequest(IAsyncResult result) { SecurityProtocolCorrelationState requestCorrelationState; TimeSpan remainingTime; Message reply = SecureRequestAsyncResult.EndAsReply(result, out requestCorrelationState, out remainingTime); return ProcessReply(reply, remainingTime, requestCorrelationState); } sealed class SecureRequestAsyncResult : SecureSendAsyncResultBase { static readonly AsyncCallback requestCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(RequestCallback)); Message reply; public SecureRequestAsyncResult(Message request, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(request, sessionChannel, timeout, callback, state) { if (!this.DidSecureOutgoingMessageCompleteSynchronously) { return; } bool completeSelf = OnMessageSecured(); if (completeSelf) { Complete(true); } } protected override bool OnMessageSecured() { IAsyncResult result = this.ChannelBinder.BeginRequest(this.Message, this.TimeoutHelper.RemainingTime(), requestCallback, this); if (!result.CompletedSynchronously) { return false; } this.reply = this.ChannelBinder.EndRequest(result); return true; } static void RequestCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } SecureRequestAsyncResult thisAsyncResult = (SecureRequestAsyncResult)result.AsyncState; Exception completionException = null; try { thisAsyncResult.reply = thisAsyncResult.ChannelBinder.EndRequest(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completionException = e; } thisAsyncResult.Complete(false, completionException); } public static Message EndAsReply(IAsyncResult result, out SecurityProtocolCorrelationState correlationState, out TimeSpan remainingTime) { SecureRequestAsyncResult thisResult = AsyncResult.End (result); correlationState = thisResult.SecurityCorrelationState; remainingTime = thisResult.TimeoutHelper.RemainingTime(); return thisResult.reply; } } class CloseOutputSessionAsyncResult : TraceAsyncResult { static readonly AsyncCallback baseCloseOutputSessionCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(BaseCloseOutputSessionCallback)); static readonly AsyncCallback receiveInternalCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(ReceiveInternalCallback)); SecurityRequestSessionChannel requestChannel; SecurityProtocolCorrelationState correlationState; TimeoutHelper timeoutHelper; public CloseOutputSessionAsyncResult(SecurityRequestSessionChannel requestChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.timeoutHelper = new TimeoutHelper(timeout); this.requestChannel = requestChannel; IAsyncResult result = this.requestChannel.BeginBaseCloseOutputSession(timeoutHelper.RemainingTime(), baseCloseOutputSessionCallback, this); if (!result.CompletedSynchronously) { return; } this.correlationState = this.requestChannel.EndBaseCloseOutputSession(result); bool completeSelf = this.OnBaseOutputSessionClosed(); if (completeSelf) { Complete(true); } } static void BaseCloseOutputSessionCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseOutputSessionAsyncResult thisAsyncResult = (CloseOutputSessionAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { thisAsyncResult.correlationState = thisAsyncResult.requestChannel.EndBaseCloseOutputSession(result); completeSelf = thisAsyncResult.OnBaseOutputSessionClosed(); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisAsyncResult.Complete(false, completionException); } } bool OnBaseOutputSessionClosed() { IAsyncResult result = this.requestChannel.BeginReceiveInternal(this.timeoutHelper.RemainingTime(), this.correlationState, receiveInternalCallback, this); if (!result.CompletedSynchronously) { return false; } Message message = this.requestChannel.EndReceiveInternal(result); return this.OnMessageReceived(message); } static void ReceiveInternalCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseOutputSessionAsyncResult thisAsyncResult = (CloseOutputSessionAsyncResult)result.AsyncState; bool completeSelf = false; Exception completionException = null; try { Message message = thisAsyncResult.requestChannel.EndReceiveInternal(result); completeSelf = thisAsyncResult.OnMessageReceived(message); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Diagnostics.ExceptionUtility.IsFatal(e)) throw; completeSelf = true; completionException = e; } if (completeSelf) { thisAsyncResult.Complete(false, completionException); } } bool OnMessageReceived(Message message) { if (message != null) { using (message) { ProtocolException error = ProtocolException.ReceiveShutdownReturnedNonNull(message); throw TraceUtility.ThrowHelperWarning(error, message); } } return true; } public static void End(IAsyncResult result) { AsyncResult.End (result); } } } class ClientSecurityDuplexSessionChannel : ClientSecuritySessionChannel, IDuplexSessionChannel { static AsyncCallback onReceive = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnReceive)); SoapSecurityClientDuplexSession session; InputQueue queue; ItemDequeuedCallback startReceiving; WaitCallback completeLater; public ClientSecurityDuplexSessionChannel(SecuritySessionClientSettings settings, EndpointAddress to, Uri via) : base(settings, to, via) { this.session = new SoapSecurityClientDuplexSession(this); this.queue = new InputQueue (); this.startReceiving = new ItemDequeuedCallback(StartReceiving); this.completeLater = new WaitCallback(CompleteLater); } public EndpointAddress LocalAddress { get { return base.InternalLocalAddress; } } public IDuplexSession Session { get { return this.session; } } protected override bool ExpectClose { get { return true; } } protected override string SessionId { get { return this.session.Id; } } 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 IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state) { ThrowIfFaulted(); return queue.BeginDequeue(timeout, callback, state); } public bool EndTryReceive(IAsyncResult result, out Message message) { bool wasDequeued = queue.EndDequeue(result, out message); if (message == null) { // the channel could have faulted, shutting down the input queue ThrowIfFaulted(); } return wasDequeued; } protected override void OnOpened() { base.OnOpened(); StartReceiving(); } public bool TryReceive(TimeSpan timeout, out Message message) { ThrowIfFaulted(); bool wasDequeued = queue.Dequeue(timeout, out message); if (message == null) { // the channel could have faulted, shutting down the input queue ThrowIfFaulted(); } return wasDequeued; } public void Send(Message message) { this.Send(message, this.DefaultSendTimeout); } public void Send(Message message, TimeSpan timeout) { ThrowIfFaulted(); CheckOutputOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime()); this.ChannelBinder.Send(message, timeoutHelper.RemainingTime()); } 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(); CheckOutputOpen(); return new SecureSendAsyncResult(message, this, timeout, callback, state, false); } public void EndSend(IAsyncResult result) { SecureSendAsyncResult.End(result); } protected override void InitializeSession(SecurityToken sessionToken) { this.session.Initialize(sessionToken, this.Settings); } void StartReceiving() { IAsyncResult result = this.IssueReceive(); if (result != null && result.CompletedSynchronously) { IOThreadScheduler.ScheduleCallback(completeLater, result); } } IAsyncResult IssueReceive() { while (true) { // no need to receive anymore if in the closed state if (this.State == CommunicationState.Closed || this.State == CommunicationState.Faulted || this.IsInputClosed) { return null; } try { return this.BeginReceiveInternal(TimeoutHelper.Infinite, null, onReceive, this); } catch (CommunicationException e) { // BeginReceive failed. ignore the exception and start another receive if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } catch (TimeoutException e) { // BeginReceive failed. ignore the exception and start another receive if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } } } void CompleteLater(object obj) { CompleteReceive((IAsyncResult)obj); } static void OnReceive(IAsyncResult result) { if (result.CompletedSynchronously) return; ((ClientSecurityDuplexSessionChannel)result.AsyncState).CompleteReceive(result); } void CompleteReceive(IAsyncResult result) { Message message = null; bool issueAnotherReceive = false; try { message = this.EndReceiveInternal(result); issueAnotherReceive = true; } catch (MessageSecurityException) { // a messagesecurityexception will only be thrown if the channel received a fault // from the other side, in which case the channel would have faulted issueAnotherReceive = false; } catch (CommunicationException e) { issueAnotherReceive = true; // EndReceive failed. ignore the exception and start another receive if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } catch (TimeoutException e) { issueAnotherReceive = true; // EndReceive failed. ignore the exception and start another receive if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } IAsyncResult nextReceiveResult = null; if (issueAnotherReceive) { nextReceiveResult = this.IssueReceive(); if (nextReceiveResult != null && nextReceiveResult.CompletedSynchronously) { IOThreadScheduler.ScheduleCallback(completeLater, nextReceiveResult); } } if (message != null) { // since we may be dispatching to user code ignore non-fatal exceptions try { this.queue.EnqueueAndDispatch(message); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning); } } } protected override void AbortCore() { try { this.queue.Dispose(); } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } base.AbortCore(); } public bool WaitForMessage(TimeSpan timeout) { return this.queue.WaitForItem(timeout); } public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state) { return this.queue.BeginWaitForItem(timeout, callback, state); } public bool EndWaitForMessage(IAsyncResult result) { return this.queue.EndWaitForItem(result); } protected override void OnFaulted() { queue.Shutdown(this); base.OnFaulted(); } protected override bool OnCloseResponseReceived() { if (base.OnCloseResponseReceived()) { this.queue.Shutdown(); return true; } else { return false; } } protected override bool OnCloseReceived() { if (base.OnCloseReceived()) { this.queue.Shutdown(); return true; } else { return false; } } class SoapSecurityClientDuplexSession : SoapSecurityOutputSession, IDuplexSession { ClientSecurityDuplexSessionChannel channel; bool initialized = false; public SoapSecurityClientDuplexSession(ClientSecurityDuplexSessionChannel channel) : base(channel) { this.channel = channel; } internal new void Initialize(SecurityToken sessionToken, SecuritySessionClientSettings settings) { base.Initialize(sessionToken, settings); this.initialized = true; } void CheckInitialized() { if (!this.initialized) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelNotOpen))); } } public void CloseOutputSession() { this.CloseOutputSession(this.channel.DefaultCloseTimeout); } public void CloseOutputSession(TimeSpan timeout) { CheckInitialized(); this.channel.ThrowIfFaulted(); this.channel.ThrowIfNotOpened(); Exception pendingException = null; try { this.channel.CloseOutputSession(timeout); } catch (CommunicationObjectAbortedException) { if (this.channel.State != CommunicationState.Closed) { throw; } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; pendingException = e; } if (pendingException != null) { this.channel.Fault(pendingException); throw pendingException; } } public IAsyncResult BeginCloseOutputSession(AsyncCallback callback, object state) { return this.BeginCloseOutputSession(this.channel.DefaultCloseTimeout, callback, state); } public IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state) { CheckInitialized(); this.channel.ThrowIfFaulted(); this.channel.ThrowIfNotOpened(); Exception pendingException = null; try { return this.channel.BeginCloseOutputSession(timeout, callback, state); } catch (CommunicationObjectAbortedException) { if (this.channel.State != CommunicationState.Closed) { throw; } // another thread must have aborted the channel. Allow the close to complete // gracefully return new CompletedAsyncResult(callback, state); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; pendingException = e; } if (pendingException != null) { this.channel.Fault(pendingException); if (pendingException is CommunicationException) { throw pendingException; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(pendingException); } } // we should never reach here DiagnosticUtility.DebugAssert("Unexpected control flow"); return null; } public void EndCloseOutputSession(IAsyncResult result) { if (result is CompletedAsyncResult) { CompletedAsyncResult.End(result); return; } Exception pendingException = null; try { this.channel.EndCloseOutputSession(result); } catch (CommunicationObjectAbortedException) { if (this.channel.State != CommunicationState.Closed) { throw; } // another thread must have aborted the channel. Allow the close to complete // gracefully } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; pendingException = e; } if (pendingException != null) { this.channel.Fault(pendingException); if (pendingException is CommunicationException) { throw pendingException; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(pendingException); } } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GuidelineCollection.cs
- sqlser.cs
- AssociationType.cs
- BackgroundFormatInfo.cs
- QuaternionRotation3D.cs
- ByteStreamGeometryContext.cs
- DataRecordInfo.cs
- FactoryId.cs
- ClientFormsAuthenticationCredentials.cs
- XslUrlEditor.cs
- VirtualPathUtility.cs
- UserControlCodeDomTreeGenerator.cs
- PolicyValidationException.cs
- StackBuilderSink.cs
- OleDbFactory.cs
- Pointer.cs
- BrowserCapabilitiesCodeGenerator.cs
- CharEntityEncoderFallback.cs
- CompilationRelaxations.cs
- XmlPropertyBag.cs
- DataGridLinkButton.cs
- TagPrefixInfo.cs
- WebPartMinimizeVerb.cs
- EdmType.cs
- CounterCreationDataCollection.cs
- ProjectedSlot.cs
- InstanceContext.cs
- EncryptedData.cs
- Update.cs
- BitmapDecoder.cs
- RuntimeConfig.cs
- PointHitTestParameters.cs
- DefaultBindingPropertyAttribute.cs
- FileSecurity.cs
- RowUpdatedEventArgs.cs
- WorkflowRequestContext.cs
- Token.cs
- ImageListStreamer.cs
- TreeViewItemAutomationPeer.cs
- StoryFragments.cs
- Win32MouseDevice.cs
- ProcessThreadCollection.cs
- XPathSelectionIterator.cs
- SiblingIterators.cs
- HandlerFactoryCache.cs
- WinEventHandler.cs
- UndirectedGraph.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- UiaCoreTypesApi.cs
- ToolBar.cs
- Expression.cs
- ObjectListCommandCollection.cs
- OracleConnectionFactory.cs
- TrustManager.cs
- LayoutEvent.cs
- HtmlInputReset.cs
- CharacterMetricsDictionary.cs
- PeerName.cs
- LicenseManager.cs
- ToolStripItem.cs
- FilteredReadOnlyMetadataCollection.cs
- ConfigurationStrings.cs
- HostProtectionPermission.cs
- SplineKeyFrames.cs
- WebSysDisplayNameAttribute.cs
- DocumentPageHost.cs
- Token.cs
- DataBindingExpressionBuilder.cs
- SettingsAttributeDictionary.cs
- arc.cs
- UInt16Storage.cs
- ValidatingReaderNodeData.cs
- AutomationIdentifier.cs
- CreatingCookieEventArgs.cs
- cache.cs
- Propagator.Evaluator.cs
- WebServicesSection.cs
- CodeMemberField.cs
- FontDialog.cs
- TextProperties.cs
- AxDesigner.cs
- TemplateContent.cs
- SubstitutionList.cs
- EntityDataSourceDesigner.cs
- UIElementCollection.cs
- ObjectCacheSettings.cs
- IgnoreFlushAndCloseStream.cs
- EntityPropertyMappingAttribute.cs
- DbBuffer.cs
- UseLicense.cs
- ComboBox.cs
- SqlDuplicator.cs
- PackagePart.cs
- QilUnary.cs
- CounterCreationDataCollection.cs
- TableParagraph.cs
- SmtpSection.cs
- TdsRecordBufferSetter.cs
- TextProviderWrapper.cs
- FileInfo.cs