SecurityValidationBehavior.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / SecurityValidationBehavior.cs / 1 / SecurityValidationBehavior.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.ServiceModel.Channels;
    using System.ServiceModel; 
    using System.ServiceModel.Description; 
    using System.ServiceModel.Security;
    using System.ServiceModel.Security.Tokens; 
    using System.IdentityModel.Tokens;

    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Runtime.CompilerServices;
    using System.Net.Security; 
    using System.Security.Principal; 

    class SecurityValidationBehavior : IEndpointBehavior, IServiceBehavior 
    {
        static SecurityValidationBehavior instance;

        public static SecurityValidationBehavior Instance 
        {
            get 
            { 
                if (instance == null)
                    instance = new SecurityValidationBehavior(); 
                return instance;
            }
        }
 
        class ValidationBinding : Binding
        { 
            Binding binding; 
            BindingElementCollection elements;
 
            public ValidationBinding(Binding binding)
                : base(binding.Name, binding.Namespace)
            {
                this.binding = binding; 
            }
 
            public override string Scheme 
            {
                get { return this.binding.Scheme; } 
            }

            public override BindingElementCollection CreateBindingElements()
            { 
                if (this.elements == null)
                { 
                    this.elements = this.binding.CreateBindingElements(); 
                }
                return this.elements; 
            }

            public override IChannelFactory BuildChannelFactory(BindingParameterCollection parameters)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            } 
            public override IChannelListener BuildChannelListener(params object[] parameters) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            }

            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, params object[] parameters)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            } 
 
            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, string listenUriRelativeAddress, params object[] parameters)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            }

            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode, params object[] parameters) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            } 

            public override IChannelListener BuildChannelListener(BindingParameterCollection parameters) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            }
 
            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, BindingParameterCollection parameters)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            }
 
            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, string listenUriRelativeAddress, BindingParameterCollection parameters)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            } 

            public override IChannelListener BuildChannelListener(Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            } 

            public override bool CanBuildChannelFactory(BindingParameterCollection parameters)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            }
 
            public override bool CanBuildChannelListener(BindingParameterCollection parameters) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
            }
        }

        void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint) 
        {
            if (serviceEndpoint == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint"); 
            SecurityBindingElement sbe;
            Binding binding = new ValidationBinding(serviceEndpoint.Binding); 
            ValidateBinding(binding, serviceEndpoint.Contract, out sbe);
            RsaSHA256AlgorithmSuiteRule.ValidateClient(sbe, binding, serviceEndpoint.Behaviors);
        }
 
        void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection parameters)
        { 
        } 

        void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) 
        {
        }

        void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior) 
        {
        } 
 
        void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection parameters)
        { 
        }

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        { 
        }
 
        void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase) 
        {
            if (description == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");

            for (int i = 0; i < description.Endpoints.Count; i++)
            { 
                ServiceEndpoint endpoint = description.Endpoints[i];
                Binding binding = new ValidationBinding(endpoint.Binding); 
                SecurityBindingElement sbe; 
                ValidateBinding(binding, endpoint.Contract, out sbe);
                if (sbe != null) 
                {
                    SecurityTokenParameterInclusionModeRule.Validate(sbe, binding, endpoint.Contract, description.Behaviors);
                    RsaSHA256AlgorithmSuiteRule.ValidateService(sbe, binding, description.Behaviors);
                } 
            }
 
            WindowsIdentitySupportRule.Validate(description); 
            UsernameImpersonationRule.Validate(description);
            MissingClientCertificateRule.Validate(description); 
        }

        void ValidateBinding(Binding binding, ContractDescription contract, out SecurityBindingElement securityBindingElement)
        { 
            securityBindingElement = SecurityValidationBehavior.GetSecurityBinding(binding, contract);
            if (securityBindingElement != null) 
                ValidateSecurityBinding(securityBindingElement, binding, contract); 
            else
                ValidateNoSecurityBinding(binding, contract); 

        }

        void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
        {
            ContractProtectionRequirementsRule.ValidateSecurityBinding(sbe, binding, contract); 
            CookieAndSessionProtectionRequirementsRule.ValidateSecurityBinding(sbe, binding, contract); 
            SoapOverSecureTransportRequirementsRule.ValidateSecurityBinding(sbe, binding, contract);
            SecurityVersionSupportForEncryptedKeyBindingRule.ValidateSecurityBinding(sbe, binding, contract); 
            SecurityVersionSupportForThumbprintKeyIdentifierClauseRule.ValidateSecurityBinding(sbe, binding, contract);
            SecurityBindingSupportForOneWayOnlyRule.ValidateSecurityBinding(sbe, binding, contract);
            IssuedKeySizeCompatibilityWithAlgorithmSuiteRule.ValidateSecurityBinding(sbe, binding, contract);
            MessageSecurityAndManualAddressingRule.ValidateSecurityBinding(sbe, binding, contract); 
            NoStreamingWithSecurityRule.ValidateSecurityBinding(sbe, binding, contract);
            UnknownHeaderProtectionRequirementsRule.ValidateSecurityBinding(sbe, binding, contract); 
            BearerKeyTypeIssuanceRequirementRule.ValidateSecurityBinding(sbe, binding, contract); 
        }
 
        void ValidateNoSecurityBinding(Binding binding, ContractDescription contract)
        {
            ContractProtectionRequirementsRule.ValidateNoSecurityBinding(binding, contract);
            CookieAndSessionProtectionRequirementsRule.ValidateNoSecurityBinding(binding, contract); 
            SoapOverSecureTransportRequirementsRule.ValidateNoSecurityBinding(binding, contract);
            SecurityVersionSupportForEncryptedKeyBindingRule.ValidateNoSecurityBinding(binding, contract); 
            SecurityVersionSupportForThumbprintKeyIdentifierClauseRule.ValidateNoSecurityBinding(binding, contract); 
            SecurityBindingSupportForOneWayOnlyRule.ValidateNoSecurityBinding(binding, contract);
            IssuedKeySizeCompatibilityWithAlgorithmSuiteRule.ValidateNoSecurityBinding(binding, contract); 
            MessageSecurityAndManualAddressingRule.ValidateNoSecurityBinding(binding, contract);
            UnknownHeaderProtectionRequirementsRule.ValidateNoSecurityBinding(binding, contract);
            BearerKeyTypeIssuanceRequirementRule.ValidateNoSecurityBinding(binding, contract);
        } 

        static SecurityBindingElement GetSecurityBinding(Binding binding, ContractDescription contract) 
        { 
            SecurityBindingElement sbe = null;
            BindingElementCollection elements = binding.CreateBindingElements(); 
            for (int i = 0; i < elements.Count; i++)
            {
                BindingElement element = elements[i];
                if (element is SecurityBindingElement) 
                {
                    if (sbe != null) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                            SR.GetString(SR.MoreThanOneSecurityBindingElementInTheBinding, binding.Name, binding.Namespace, contract.Name, contract.Namespace)));
                    sbe = (SecurityBindingElement)element; 
                }
            }
            return sbe;
        } 

 
        internal void AfterBuildTimeValidation(ServiceDescription description) 
        {
            S4UImpersonationRule.Validate(description); 
        }

        // We do not allow streaming with message security which makes our service vulnerable
        // for example, GetWhitespace may be a problem if it�s called on unbounded data. 
        static class NoStreamingWithSecurityRule
        { 
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
            {
                // check to see if we are doing message security 
                // if transport security, the sbe would be transportsecuritybindingelement
                if (sbe is SymmetricSecurityBindingElement || sbe is AsymmetricSecurityBindingElement)
                {
                    // check to see if we are streaming 
                    // ([....] 53690): need to have a general way get the transfer Mode from the binding
                    // TransferMode transferMode = binding.GetProperty(new BindingParameterCollection()); 
                    if ( GetTransferMode(binding) != TransferMode.Buffered) 
                    {
                        // throw 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoStreamingWithSecurity, binding.Name, binding.Namespace)));
                    }
                }
            } 

            static TransferMode GetTransferMode(Binding binding) 
            { 
                TransferMode mode = TransferMode.Buffered;
 
                BindingElementCollection elements = binding.CreateBindingElements();
                TransportBindingElement element = elements.Find();

                if (element is ConnectionOrientedTransportBindingElement) 
                {
                    mode = ((ConnectionOrientedTransportBindingElement)element).TransferMode; 
                } 
                else if (element is HttpTransportBindingElement)
                { 
                    mode = ((HttpTransportBindingElement)element).TransferMode;
                }

                return mode; 
            }
        } 
 

        static class WindowsIdentitySupportRule 
        {
            static public void Validate(ServiceDescription description)
            {
                bool impersonateCallerForAllServiceMethods = false; 
                ServiceAuthorizationBehavior authorizationBehavior = description.Behaviors.Find();
                if (authorizationBehavior != null) 
                { 
                    impersonateCallerForAllServiceMethods = authorizationBehavior.ImpersonateCallerForAllOperations;
                } 
                else
                {
                    impersonateCallerForAllServiceMethods = false;
                } 
                for (int i = 0; i < description.Endpoints.Count; i++)
                { 
                    ServiceEndpoint endpoint = description.Endpoints[i]; 
                    if (ServiceMetadataBehavior.IsMetadataEndpoint(description, endpoint))
                    { 
                        continue;
                    }
                    for (int j = 0; j < endpoint.Contract.Operations.Count; j++)
                    { 
                        OperationDescription operation = endpoint.Contract.Operations[j];
                        OperationBehaviorAttribute operationBehavior = operation.Behaviors.Find(); 
                        if (impersonateCallerForAllServiceMethods && 
                            (operationBehavior == null || operationBehavior.Impersonation == ImpersonationOption.NotAllowed))
                        { 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.OperationDoesNotAllowImpersonation, operation.Name, endpoint.Contract.Name, endpoint.Contract.Namespace)));
                        }
                        if (impersonateCallerForAllServiceMethods || (operationBehavior != null && operationBehavior.Impersonation == ImpersonationOption.Required))
                        { 
                            ValidateWindowsIdentityCapability(endpoint.Binding, endpoint.Contract, operation);
                        } 
                    } 
                }
            } 

            static void ValidateWindowsIdentityCapability(Binding binding, ContractDescription contract, OperationDescription operation)
            {
                bool windowsIdentityProvided = false; 

                ISecurityCapabilities capabilities = binding.GetProperty(new BindingParameterCollection()); 
                if (capabilities != null && capabilities.SupportsClientWindowsIdentity) 
                {
                    windowsIdentityProvided = true; 
                }

                if (!windowsIdentityProvided)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                        SR.GetString(SR.BindingDoesNotSupportWindowsIdenityForImpersonation, operation.Name, binding.Name, binding.Namespace, contract.Name, contract.Namespace))); 
                } 
            }
        } 

        static class S4UImpersonationRule
        {
            const int WindowsServerMajorNumber = 5; 
            const int WindowsServerMinorNumber = 2;
 
            static bool IsS4URequiredForImpersonation(SecurityBindingElement sbe) 
            {
                foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true)) 
                {
                    if (stp is SecureConversationSecurityTokenParameters)
                    {
                        SecureConversationSecurityTokenParameters scstp = (SecureConversationSecurityTokenParameters)stp; 

                        if (scstp.RequireCancellation == false) 
                            return true; 

                        if (scstp.BootstrapSecurityBindingElement != null) 
                        {
                            return IsS4URequiredForImpersonation(scstp.BootstrapSecurityBindingElement);
                        }
                    } 

                    if (stp is SspiSecurityTokenParameters 
                        && ((SspiSecurityTokenParameters)stp).RequireCancellation == false) 
                        return true;
 
                    if (stp is X509SecurityTokenParameters)
                        return true;
                }
 
                return false;
            } 
 
            static public void Validate(ServiceDescription description)
            { 
                ServiceAuthorizationBehavior behavior = description.Behaviors.Find();
                bool impersonateCallerForAllMethods = (behavior != null) ? behavior.ImpersonateCallerForAllOperations : false;
                for (int i = 0; i < description.Endpoints.Count; i++)
                { 
                    ServiceEndpoint endpoint = description.Endpoints[i];
                    if (ServiceMetadataBehavior.IsMetadataEndpoint(description, endpoint)) 
                    { 
                        continue;
                    } 

                    bool isImpersonationRequested = impersonateCallerForAllMethods;
                    if (!isImpersonationRequested)
                    { 
                        isImpersonationRequested = ValidatorUtils.EndpointRequiresImpersonation(endpoint);
                    } 
                    if (isImpersonationRequested) 
                    {
                        ICollection bindingElements = endpoint.Binding.CreateBindingElements(); 
                        foreach (BindingElement element in bindingElements)
                        {
                            SecurityBindingElement sbe = (element as SecurityBindingElement);
                            if (sbe != null) 
                            {
                                if (IsS4URequiredForImpersonation(sbe)) 
                                { 
                                    Version osVersion = Environment.OSVersion.Version;
                                    if ((osVersion.Major < WindowsServerMajorNumber) 
                                        || ((osVersion.Major == WindowsServerMajorNumber) && (osVersion.Minor < WindowsServerMinorNumber)))
                                    {
                                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                            SR.GetString(SR.CannotPerformS4UImpersonationOnPlatform, endpoint.Binding.Name, endpoint.Binding.Namespace, endpoint.Contract.Name, endpoint.Contract.Namespace))); 
                                    }
                                } 
                                break; 
                            }
                        } 
                    }
                }
            }
        } 

        static class UnknownHeaderProtectionRequirementsRule 
        { 
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract)
            { 
                if (sbe is SymmetricSecurityBindingElement || sbe is AsymmetricSecurityBindingElement)
                    ValidateContract(binding, contract, sbe.GetIndividualProperty().SupportedRequestProtectionLevel, sbe.GetIndividualProperty().SupportedResponseProtectionLevel);
                else
                    ValidateContract(binding, contract, ProtectionLevel.None, ProtectionLevel.None); 
            }
 
            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
                ValidateContract(binding, contract, ProtectionLevel.None, ProtectionLevel.None); 
            }

            static void ValidateContract(Binding binding, ContractDescription contract, ProtectionLevel defaultRequestProtectionLevel, ProtectionLevel defaultResponseProtectionLevel)
            { 
                if (contract == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("contract")); 
 
                ProtectionLevel contractScopeDefaultRequestProtectionLevel;
                ProtectionLevel contractScopeDefaultResponseProtectionLevel; 
                if (contract.HasProtectionLevel)
                {
                    contractScopeDefaultRequestProtectionLevel = contract.ProtectionLevel;
                    contractScopeDefaultResponseProtectionLevel = contract.ProtectionLevel; 
                }
                else 
                { 
                    contractScopeDefaultRequestProtectionLevel = defaultRequestProtectionLevel;
                    contractScopeDefaultResponseProtectionLevel = defaultResponseProtectionLevel; 
                }

                foreach (OperationDescription operation in contract.Operations)
                { 
                    ProtectionLevel operationScopeDefaultRequestProtectionLevel;
                    ProtectionLevel operationScopeDefaultResponseProtectionLevel; 
                    if (operation.HasProtectionLevel) 
                    {
                        operationScopeDefaultRequestProtectionLevel = operation.ProtectionLevel; 
                        operationScopeDefaultResponseProtectionLevel = operation.ProtectionLevel;
                    }
                    else
                    { 
                        operationScopeDefaultRequestProtectionLevel = contractScopeDefaultRequestProtectionLevel;
                        operationScopeDefaultResponseProtectionLevel = contractScopeDefaultResponseProtectionLevel; 
                    } 
                    foreach (MessageDescription message in operation.Messages)
                    { 
                        ProtectionLevel messageScopeDefaultProtectionLevel;
                        if (message.HasProtectionLevel)
                        {
                            messageScopeDefaultProtectionLevel = message.ProtectionLevel; 
                        }
                        else if (message.Direction == MessageDirection.Input) 
                        { 
                            messageScopeDefaultProtectionLevel = operationScopeDefaultRequestProtectionLevel;
                        } 
                        else
                        {
                            messageScopeDefaultProtectionLevel = operationScopeDefaultResponseProtectionLevel;
                        } 

                        foreach (MessageHeaderDescription header in message.Headers) 
                        { 
                            ProtectionLevel headerScopeDefaultProtectionLevel;
 
                            if (header.HasProtectionLevel)
                                headerScopeDefaultProtectionLevel = header.ProtectionLevel;
                            else
                                headerScopeDefaultProtectionLevel = messageScopeDefaultProtectionLevel; 

                            // 
                            // Finally we figured out the protection level for the individual header. 
                            // We need to throw if the header is some unknown header, i.e., user can stick any Xml frag
                            // at the runtime, AND, its protection level is not ProtectionLevel.None 
                            //
                            if (header.IsUnknownHeaderCollection && headerScopeDefaultProtectionLevel != ProtectionLevel.None)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnknownHeaderCannotProtected, contract.Name, contract.Namespace, header.Name, header.Namespace))); 
                            }
                        } 
                    } 
                }
            } 
        }

        static class ContractProtectionRequirementsRule
        { 
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract)
            { 
                if (sbe is SymmetricSecurityBindingElement || sbe is AsymmetricSecurityBindingElement) 
                    ValidateContract(binding, contract, sbe.GetIndividualProperty().SupportedRequestProtectionLevel, sbe.GetIndividualProperty().SupportedResponseProtectionLevel);
                else 
                    ValidateContract(binding, contract, ProtectionLevel.None, ProtectionLevel.None);
            }

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
                ValidateContract(binding, contract, ProtectionLevel.None, ProtectionLevel.None); 
            } 

            static void ValidateContract(Binding binding, ContractDescription contract, ProtectionLevel defaultRequestProtectionLevel, ProtectionLevel defaultResponseProtectionLevel) 
            {
                ProtectionLevel requestProtectionLevel;
                ProtectionLevel responseProtectionLevel;
                GetRequiredProtectionLevels(contract, defaultRequestProtectionLevel,defaultResponseProtectionLevel,  out requestProtectionLevel, out responseProtectionLevel); 
                ValidateBindingProtectionCapability(binding, contract, requestProtectionLevel, responseProtectionLevel);
            } 
 
            static internal void GetRequiredProtectionLevels(ContractDescription contract, ProtectionLevel defaultRequestProtectionLevel, ProtectionLevel defaultResponseProtectionLevel, out ProtectionLevel request, out ProtectionLevel response)
            { 
                ChannelProtectionRequirements requirements = ChannelProtectionRequirements.CreateFromContract(contract, defaultRequestProtectionLevel, defaultResponseProtectionLevel, false);

                if (requirements.IncomingSignatureParts.IsEmpty())
                { 
                    request = ProtectionLevel.None;
                } 
                else if (requirements.IncomingEncryptionParts.IsEmpty()) 
                {
                    request = ProtectionLevel.Sign; 
                }
                else
                {
                    request = ProtectionLevel.EncryptAndSign; 
                }
 
                if (requirements.OutgoingSignatureParts.IsEmpty()) 
                {
                    response = ProtectionLevel.None; 
                }
                else if (requirements.OutgoingEncryptionParts.IsEmpty())
                {
                    response = ProtectionLevel.Sign; 
                }
                else 
                { 
                    response = ProtectionLevel.EncryptAndSign;
                } 
            }

            static void ValidateBindingProtectionCapability(Binding binding, ContractDescription contract, ProtectionLevel request, ProtectionLevel response)
            { 
                bool requestValidated = request == ProtectionLevel.None;
                bool responseValidated = response == ProtectionLevel.None; 
 
                if (!requestValidated || !responseValidated)
                { 
                    ISecurityCapabilities capabilities = binding.GetProperty(new BindingParameterCollection());
                    if (capabilities != null)
                    {
                        if (!requestValidated) 
                        {
                            requestValidated = ProtectionLevelHelper.IsStrongerOrEqual(capabilities.SupportedRequestProtectionLevel, request); 
                        } 
                        if (!responseValidated)
                        { 
                            responseValidated = ProtectionLevelHelper.IsStrongerOrEqual(capabilities.SupportedResponseProtectionLevel, response);
                        }
                    }
                } 

                if (!requestValidated) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                        SR.GetString(SR.AtLeastOneContractOperationRequestRequiresProtectionLevelNotSupportedByBinding, contract.Name, contract.Namespace, binding.Name, binding.Namespace))); 
                }
                if (!responseValidated)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                        SR.GetString(SR.AtLeastOneContractOperationResponseRequiresProtectionLevelNotSupportedByBinding, contract.Name, contract.Namespace, binding.Name, binding.Namespace)));
                } 
            } 
        }
 
        static class BearerKeyTypeIssuanceRequirementRule
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract)
            { 
                foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true))
                { 
                    if (stp is IssuedSecurityTokenParameters) 
                    {
                        IssuedSecurityTokenParameters issuedParameters = stp as IssuedSecurityTokenParameters; 
                        if (issuedParameters.KeyType == System.IdentityModel.Tokens.SecurityKeyType.BearerKey)
                        {
                            // The issued Bearer token cannot be used as the primary protection token and it cannot be
                            // used as a Endorsing or Signed Endorsing token. 
                            if ((sbe is SymmetricSecurityBindingElement) && IsBearerKeyType(((SymmetricSecurityBindingElement)sbe).ProtectionTokenParameters))
                            { 
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidBearerKeyUsage, binding.Name, binding.Namespace))); 
                            }
 
                            if ((sbe is AsymmetricSecurityBindingElement) && (IsBearerKeyType(((AsymmetricSecurityBindingElement)sbe).InitiatorTokenParameters) || IsBearerKeyType(((AsymmetricSecurityBindingElement)sbe).RecipientTokenParameters)))
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidBearerKeyUsage, binding.Name, binding.Namespace)));
                            } 

                            foreach (SecurityTokenParameters tokenParam in sbe.EndpointSupportingTokenParameters.Endorsing) 
                            { 
                                if (IsBearerKeyType(tokenParam))
                                { 
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidBearerKeyUsage, binding.Name, binding.Namespace)));
                                }
                            }
 
                            foreach (SecurityTokenParameters tokenParam in sbe.EndpointSupportingTokenParameters.SignedEndorsing)
                            { 
                                if (IsBearerKeyType(tokenParam)) 
                                {
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidBearerKeyUsage, binding.Name, binding.Namespace))); 
                                }
                            }
                        }
 
                        if (issuedParameters.IssuerBinding != null)
                        { 
                            SecurityBindingElement secBindingEle = SecurityValidationBehavior.GetSecurityBinding(issuedParameters.IssuerBinding, contract); 
                            if (secBindingEle != null)
                                ValidateSecurityBinding(secBindingEle, issuedParameters.IssuerBinding, contract); 
                        }
                    }
                    else if (stp is SecureConversationSecurityTokenParameters)
                    { 
                        SecureConversationSecurityTokenParameters scParameters = stp as SecureConversationSecurityTokenParameters;
                        ValidateSecurityBinding(scParameters.BootstrapSecurityBindingElement, binding, contract); 
                    } 
                }
            } 

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract)
            {
            } 

            static bool IsBearerKeyType(SecurityTokenParameters tokenParameters) 
            { 
                if (!(tokenParameters is IssuedSecurityTokenParameters))
                    return false; 

                return ((IssuedSecurityTokenParameters)tokenParameters).KeyType == SecurityKeyType.BearerKey;
            }
 
        }
 
        static class CookieAndSessionProtectionRequirementsRule 
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
            {
                if (!(sbe is TransportSecurityBindingElement))
                    foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true))
                    { 
                        SecureConversationSecurityTokenParameters scstp = stp as SecureConversationSecurityTokenParameters;
                        if (scstp != null) 
                        { 
                            ISecurityCapabilities bootstrapSecurityCapabilities = scstp.BootstrapSecurityBindingElement.GetIndividualProperty();
                            if (bootstrapSecurityCapabilities != null 
                                && bootstrapSecurityCapabilities.SupportedRequestProtectionLevel == ProtectionLevel.EncryptAndSign
                                && bootstrapSecurityCapabilities.SupportedResponseProtectionLevel == ProtectionLevel.EncryptAndSign)
                            {
                                continue; 
                            }
 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                                SR.GetString(SR.BindingDoesNotSupportProtectionForRst, binding.Name, binding.Namespace, contract.Name, contract.Namespace)));
                        } 
                    }
            }

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
            } 
        } 

        static class SoapOverSecureTransportRequirementsRule 
        {
            static public void ValidateSecurityBinding(SecurityBindingElement securityBindingElement, Binding binding, ContractDescription contract)
            {
                if (securityBindingElement is TransportSecurityBindingElement) 
                {
                    // ensure that if soap security cookie/session is configured, then the authentication mode supports encryption 
                    IEnumerable elements = binding.CreateBindingElements(); 
                    Collection bindingElementStack = new Collection();
                    bool isBelowSecurity = false; 
                    foreach (BindingElement element in elements)
                    {
                        SecurityBindingElement sbe = element as SecurityBindingElement;
                        if (sbe != null) 
                        {
                            isBelowSecurity = true; 
                        } 
                        else if (isBelowSecurity)
                        { 
                            bindingElementStack.Add(element);
                        }
                    }
                    bool isTransportProtected = false; 
                    if (bindingElementStack.Count != 0)
                    { 
                        BindingContext context = new BindingContext(new CustomBinding(bindingElementStack), new BindingParameterCollection()); 
                        ISecurityCapabilities transportCapabilities = context.GetInnerProperty();
                        if (transportCapabilities != null 
                            && transportCapabilities.SupportsServerAuthentication
                            && transportCapabilities.SupportedRequestProtectionLevel == ProtectionLevel.EncryptAndSign
                            && transportCapabilities.SupportedResponseProtectionLevel == ProtectionLevel.EncryptAndSign)
                        { 
                            isTransportProtected = true;
                        } 
                    } 

                    if (!isTransportProtected) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                            SR.GetString(SR.TransportDoesNotProtectMessage, binding.Name, binding.Namespace, contract.Name, contract.Namespace)));
                    } 
                }
            } 
 
            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract)
            { 
            }
        }

        static class IssuedKeySizeCompatibilityWithAlgorithmSuiteRule 
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
            { 
                SecurityAlgorithmSuite algorithmSuite = sbe.DefaultAlgorithmSuite;
                foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true)) 
                {
                    if (stp is IssuedSecurityTokenParameters)
                    {
                        IssuedSecurityTokenParameters issuedParameters = stp as IssuedSecurityTokenParameters; 
                        if (issuedParameters.KeySize != 0)
                        { 
                            bool isCompatible = true; 
                            if (issuedParameters.KeyType == System.IdentityModel.Tokens.SecurityKeyType.SymmetricKey &&
                                !sbe.DefaultAlgorithmSuite.IsSymmetricKeyLengthSupported(issuedParameters.KeySize)) 
                            {
                                isCompatible = false;

                            } 
                            else if (issuedParameters.KeyType == System.IdentityModel.Tokens.SecurityKeyType.AsymmetricKey &&
                                !sbe.DefaultAlgorithmSuite.IsAsymmetricKeyLengthSupported(issuedParameters.KeySize)) 
                            { 
                                isCompatible = false;
                            } 
                            if (!isCompatible)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuedKeySizeNotCompatibleWithAlgorithmSuite, binding.Name, binding.Namespace, sbe.DefaultAlgorithmSuite, issuedParameters.KeySize)));
                            } 
                        }
                    } 
                    else if (stp is SecureConversationSecurityTokenParameters) 
                    {
                        SecureConversationSecurityTokenParameters scParameters = stp as SecureConversationSecurityTokenParameters; 
                        ValidateSecurityBinding(scParameters.BootstrapSecurityBindingElement, binding, contract);
                    }
                }
            } 

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            { 
            }
        } 

        static class RsaSHA256AlgorithmSuiteRule
        {
            class AuthenticationSecurityTokenParametersEnumerable : IEnumerable 
            {
                SecurityBindingElement sbe; 
 
                public AuthenticationSecurityTokenParametersEnumerable(SecurityBindingElement sbe)
                { 
                    if (sbe == null)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sbe");
                    this.sbe = sbe;
                } 

                public IEnumerator GetEnumerator() 
                { 
                    if (this.sbe is SymmetricSecurityBindingElement)
                    { 
                        SymmetricSecurityBindingElement ssbe = (SymmetricSecurityBindingElement)sbe;
                        if (ssbe.ProtectionTokenParameters != null && ssbe.ProtectionTokenParameters is SecureConversationSecurityTokenParameters)
                            yield return ssbe.ProtectionTokenParameters;
                    } 
                    else if (this.sbe is AsymmetricSecurityBindingElement)
                    { 
                        AsymmetricSecurityBindingElement asbe = (AsymmetricSecurityBindingElement)sbe; 
                        if (asbe.InitiatorTokenParameters != null) // for request
                            yield return asbe.InitiatorTokenParameters; 
                        if (asbe.RecipientTokenParameters != null) // for response
                            yield return asbe.RecipientTokenParameters;
                    }
                    foreach (SecurityTokenParameters stp in this.sbe.EndpointSupportingTokenParameters.Endorsing) 
                        if (stp != null)
                            yield return stp; 
                    foreach (SecurityTokenParameters stp in this.sbe.EndpointSupportingTokenParameters.SignedEndorsing) 
                        if (stp != null)
                            yield return stp; 
                    foreach (SupportingTokenParameters str in this.sbe.OperationSupportingTokenParameters.Values)
                        if (str != null)
                        {
                            foreach (SecurityTokenParameters stp in str.Endorsing) 
                                if (stp != null)
                                    yield return stp; 
                            foreach (SecurityTokenParameters stp in str.SignedEndorsing) 
                                if (stp != null)
                                    yield return stp; 
                        }
                }

                System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); 
                } 
            }
 
            static public void ValidateService(SecurityBindingElement sbe, Binding binding, KeyedByTypeCollection behaviors)
            {
                //
                // Verify if the service credentials are not customized 
                //
                if (!behaviors.Contains(typeof(ServiceCredentials))) 
                    return; 

                ValidateSecurityBinding(sbe, binding); 
            }


            static public void ValidateClient(SecurityBindingElement sbe, Binding binding, KeyedByTypeCollection behaviors) 
            {
                // 
                // Verify if the client credentials are not customized 
                //
                if (!behaviors.Contains(typeof(ClientCredentials)) || (sbe == null)) 
                    return;

                ValidateSecurityBinding(sbe, binding);
            } 

            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding) 
            { 
                if ( sbe == null )
                    return; 

                bool hasAsymmetricKey = false;

                if (SecurityAlgorithmSuite.IsRsaSHA256(sbe.DefaultAlgorithmSuite)) 
                {
                    foreach (SecurityTokenParameters p in new AuthenticationSecurityTokenParametersEnumerable(sbe)) 
                    { 
                        if (p is SecureConversationSecurityTokenParameters)
                        { 
                            //
                            // For SCT with transport security element case
                            // Do we need to consider this case?
                            // 
                            SecureConversationSecurityTokenParameters scstp = p as SecureConversationSecurityTokenParameters;
                            ValidateSecurityBinding(scstp.BootstrapSecurityBindingElement, binding); 
                        } 

                        if (p.HasAsymmetricKey) 
                        {
                            //
                            // For the ultimate security binding that we need to check
                            // 
                            hasAsymmetricKey = true;
                            break; 
                        } 
                    }
 
                    if (hasAsymmetricKey)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RsaSHA256NotSupported, binding.Name, binding.Namespace, sbe.DefaultAlgorithmSuite)));

                } 
            }
        } 
 
        static class SecurityTokenParameterInclusionModeRule
        { 
            static void EnforceInclusionMode(Binding binding, SecurityTokenParameters stp, params SecurityTokenInclusionMode[] allowedInclusionModes)
            {
                bool isMatch = false;
                for (int i = 0; i < allowedInclusionModes.Length; ++i) 
                {
                    if (stp.InclusionMode == allowedInclusionModes[i]) 
                    { 
                        isMatch = true;
                        break; 
                    }
                }
                if (!isMatch)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityTokenParametersHasIncompatibleInclusionMode, binding.Name, binding.Namespace, stp.GetType(), stp.InclusionMode, allowedInclusionModes[0])));
                } 
            } 

            static public void Validate(SecurityBindingElement sbe, Binding binding, ContractDescription contract, KeyedByTypeCollection behaviors) 
            {
                if (behaviors != null)
                {
                    ServiceCredentials serviceCredentials = behaviors.Find(); 
                    if (serviceCredentials != null && serviceCredentials.GetType() != typeof(ServiceCredentials))
                    { 
                        // A custom service credentials has been plugged in. Dont validate the binding 
                        return;
                    } 
                }
                SymmetricSecurityBindingElement ssbe = (sbe as SymmetricSecurityBindingElement);
                AsymmetricSecurityBindingElement asbe = (sbe as AsymmetricSecurityBindingElement);
                foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true)) 
                {
                    if (stp is RsaSecurityTokenParameters) 
                    { 
                        // rsa keys can only be referred to using keyinfo. There's no wire format for
                        // serializing them 
                        EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.Never);
                        continue;
                    }
                    if (stp is SecureConversationSecurityTokenParameters) 
                    {
                        Validate(((SecureConversationSecurityTokenParameters)stp).BootstrapSecurityBindingElement, binding, contract, behaviors); 
                    } 
                    if (ssbe != null)
                    { 
                        // for the protection token, if it is asymmetric inclusion mode should be Never
                        // all other cases inclusion mode should be AlwaysToRecipient/Once
                        if (ssbe.ProtectionTokenParameters == stp && stp.HasAsymmetricKey)
                        { 
                            EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.Never);
                        } 
                        else 
                        {
                            EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.AlwaysToRecipient, SecurityTokenInclusionMode.Once); 
                        }
                    }
                    else if (asbe != null)
                    { 
                        if (asbe.InitiatorTokenParameters == stp && stp.HasAsymmetricKey)
                        { 
                            // allow AlwaysToRecipient, Once and AlwaysToInitiator in this case since the duplex binding 
                            // configures AlwaysToInitiator in this case
                            EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.AlwaysToRecipient, SecurityTokenInclusionMode.AlwaysToInitiator, SecurityTokenInclusionMode.Once); 
                        }
                        else
                        {
                            EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.AlwaysToRecipient, SecurityTokenInclusionMode.Once); 
                        }
 
                    } 
                    else
                    { 
                        EnforceInclusionMode(binding, stp, SecurityTokenInclusionMode.AlwaysToRecipient, SecurityTokenInclusionMode.Once);
                    }
                }
            } 
        }
 
        static class SecurityVersionSupportForEncryptedKeyBindingRule 
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
            {
                SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
                if (sbe.MessageSecurityVersion.SecurityVersion == SecurityVersion.WSSecurity10
                    && ssbe != null 
                    && ssbe.ProtectionTokenParameters != null
                    && ssbe.ProtectionTokenParameters.HasAsymmetricKey) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                        SR.GetString(SR.SecurityVersionDoesNotSupportEncryptedKeyBinding, binding.Name, binding.Namespace, contract.Name, contract.Namespace, SecurityVersion.WSSecurity11))); 
                }
            }

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
            } 
        } 

        static class SecurityVersionSupportForThumbprintKeyIdentifierClauseRule 
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract)
            {
                if (sbe.MessageSecurityVersion.SecurityVersion == SecurityVersion.WSSecurity10) 
                {
                    foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe)) 
                    { 
                        X509SecurityTokenParameters x509 = stp as X509SecurityTokenParameters;
                        if (x509 != null && x509.X509ReferenceStyle == X509KeyIdentifierClauseType.Thumbprint) 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                SR.GetString(SR.SecurityVersionDoesNotSupportThumbprintX509KeyIdentifierClause, binding.Name, binding.Namespace, contract.Name, contract.Namespace, SecurityVersion.WSSecurity11)));
                    }
                } 
            }
 
            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
            } 
        }

        static class MessageSecurityAndManualAddressingRule
        { 
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract)
            { 
                TransportBindingElement transport = binding.CreateBindingElements().Find(); 
                if (transport != null && transport.ManualAddressing)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                SR.GetString(SR.MessageSecurityDoesNotWorkWithManualAddressing, binding.Name, binding.Namespace)));
                }
            } 

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            { 
            }
        } 

        static class SecurityBindingSupportForOneWayOnlyRule
        {
            static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding binding, ContractDescription contract) 
            {
                if (sbe is AsymmetricSecurityBindingElement && ((AsymmetricSecurityBindingElement)sbe).IsCertificateSignatureBinding) 
                { 
                    for (int i = 0; i < contract.Operations.Count; i++)
                    { 
                        OperationDescription operation = contract.Operations[i];
                        if (!operation.IsOneWay)
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                SR.GetString(SR.SecurityBindingSupportsOneWayOnly, binding.Name, binding.Namespace, contract.Name, contract.Namespace))); 
                    }
                } 
            } 

            static public void ValidateNoSecurityBinding(Binding binding, ContractDescription contract) 
            {
            }
        }
 
        static class MissingClientCertificateRule
        { 
            static void ValidateCore(ServiceDescription description, ServiceCredentials credentials) 
            {
                for (int i = 0; i < description.Endpoints.Count; i++) 
                {
                    ServiceEndpoint endpoint = description.Endpoints[i];
                    BindingElementCollection elements = endpoint.Binding.CreateBindingElements();
 
                    SecurityBindingElement security = elements.Find();
                    CompositeDuplexBindingElement duplex = elements.Find(); 
                    if (security != null && duplex != null && SecurityBindingElement.IsMutualCertificateDuplexBinding(security)) 
                    {
                        // 
                        // We only throw when we have
                        // 1. a MutualCertificateDuplexBindingElement,
                        // 2. missing client certificate on the service side
                        // 3. The server will encrypt the response, or the message going from server to client 
                        //
                        if (credentials.ClientCertificate.Certificate == null) 
                        { 
                            ProtectionLevel requestProtectionLevel;
                            ProtectionLevel responseProtectionLevel; 
                            ContractProtectionRequirementsRule.GetRequiredProtectionLevels(endpoint.Contract, security.GetIndividualProperty().SupportedRequestProtectionLevel, security.GetIndividualProperty().SupportedResponseProtectionLevel,
                                out requestProtectionLevel, out responseProtectionLevel);

                            if ( responseProtectionLevel == ProtectionLevel.EncryptAndSign ) 
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoClientCertificate, endpoint.Binding.Name, endpoint.Binding.Namespace)));
 
                        } 
                    }
                } 
            }

            static public void Validate(ServiceDescription description)
            { 
                //
                // Verify if the service credentials are not customized 
                // 
                if ( !description.Behaviors.Contains(typeof(ServiceCredentials)))
                    return; 

                ValidateCore(description, description.Behaviors.Find());
            }
        } 

        static class UsernameImpersonationRule 
        { 
            [MethodImpl(MethodImplOptions.NoInlining)]
            static void ValidateCore(ServiceDescription description, ServiceCredentials credentials) 
            {
                if (credentials.UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidationMode.Windows)
                {
                    return; 
                }
 
                ServiceAuthorizationBehavior behavior = description.Behaviors.Find(); 
                bool impersonateCallerForAllMethods = (behavior != null) ? behavior.ImpersonateCallerForAllOperations : false;
                for (int i = 0; i < description.Endpoints.Count; i++) 
                {
                    ServiceEndpoint endpoint = description.Endpoints[i];
                    if (ServiceMetadataBehavior.IsMetadataEndpoint(description, endpoint))
                    { 
                        continue;
                    } 
 
                    if (ValidatorUtils.IsStandardBinding(endpoint.Binding))
                    { 
                        bool isImpersonationRequested = impersonateCallerForAllMethods;
                        if (!isImpersonationRequested)
                        {
                            isImpersonationRequested = ValidatorUtils.EndpointRequiresImpersonation(endpoint); 
                        }
                        if (isImpersonationRequested) 
                        { 
                            ICollection bindingElements = endpoint.Binding.CreateBindingElements();
                            foreach (BindingElement element in bindingElements) 
                            {
                                SecurityBindingElement sbe = (element as SecurityBindingElement);
                                if (sbe != null)
                                { 
                                    ValidateSecurityBindingElement(sbe, endpoint);
                                    break; 
                                } 
                            }
                        } 
                    }
                }
            }
 
            static public void Validate(ServiceDescription description)
            { 
                ServiceCredentials credentials = description.Behaviors.Find(); 
                if (credentials == null)
                    return; 
                ValidateCore(description, credentials);
            }

            static private void ValidateSecurityBindingElement(SecurityBindingElement sbe, ServiceEndpoint endpoint) 
            {
                if (sbe == null) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sbe"); 

                if (endpoint == null) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");

                foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(sbe, true))
                { 
                    if (stp is UserNameSecurityTokenParameters)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotPerformImpersonationOnUsernameToken, endpoint.Binding.Name, endpoint.Binding.Namespace, endpoint.Contract.Name, endpoint.Contract.Namespace))); 
                    }
                    else if (stp is SecureConversationSecurityTokenParameters) 
                    {
                        ValidateSecurityBindingElement(((SecureConversationSecurityTokenParameters)stp).BootstrapSecurityBindingElement, endpoint);
                    }
                } 
            }
 
        } 

        static class ValidatorUtils 
        {
            static public bool EndpointRequiresImpersonation(ServiceEndpoint endpoint)
            {
                if (endpoint == null) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
 
                for (int i = 0; i < endpoint.Contract.Operations.Count; ++i) 
                {
                    OperationDescription operation = endpoint.Contract.Operations[i]; 
                    OperationBehaviorAttribute operationBehavior = operation.Behaviors.Find();
                    if (operationBehavior != null && (operationBehavior.Impersonation == ImpersonationOption.Required))
                    {
                        return true; 
                    }
                } 
 
                return false;
            } 

            static public bool IsStandardBinding(Binding binding)
            {
                return (binding is BasicHttpBinding) || 
                    (binding is NetTcpBinding) ||
                    (binding is NetMsmqBinding) || 
                    (binding is NetNamedPipeBinding) || 
                    (binding is NetPeerTcpBinding) ||
                    (binding is WSDualHttpBinding) || 
                    (binding is WSFederationHttpBinding) ||
                    (binding is WSHttpBinding);
            }
        } 

    } 
} 

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


                        

Link Menu

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