Esempio n. 1
0
        private void ImportMessageScopeProtectionPolicy(MetadataImporter importer, PolicyConversionContext policyContext)
        {
            MessagePartSpecification endpointSignedParts;
            MessagePartSpecification endpointEncryptedParts;
            bool isContractAssociatedWithAtLeastOneOtherBinding;
            ContractProtectionLevel otherBindingProtectionLevel = null;
            bool            hasContractProtectionLevel          = false;
            bool            isContractProtectionLevelUniform    = true;
            ProtectionLevel contractProtectionLevel             = ProtectionLevel.None;

            string contractAssociationName = String.Format("{0}:{1}:{2}", ContractProtectionLevelKey, policyContext.Contract.Name, policyContext.Contract.Namespace);

            if (importer.State.ContainsKey(contractAssociationName))
            {
                isContractAssociatedWithAtLeastOneOtherBinding = true;
                otherBindingProtectionLevel = (ContractProtectionLevel)importer.State[contractAssociationName];
            }
            else
            {
                isContractAssociatedWithAtLeastOneOtherBinding = false;
            }

            ICollection <XmlElement> endpointBindingAssertions = policyContext.GetBindingAssertions();

            this.ImportProtectionAssertions(endpointBindingAssertions, out endpointSignedParts, out endpointEncryptedParts);

            if (importer.State.ContainsKey(InSecureConversationBootstrapBindingImportMode))
            {
                // when importing secure conversation boostrap binding, add the endpoint scope protection requirements
                // to the importer state to be consumed in SecurityPolicy11.TryImportWsspBootrstapPolicyAssertion
                if (endpointEncryptedParts != null)
                {
                    importer.State[SecureConversationBootstrapEncryptionRequirements] = endpointEncryptedParts;
                }
                if (endpointSignedParts != null)
                {
                    importer.State[SecureConversationBootstrapSignatureRequirements] = endpointSignedParts;
                }
            }

            foreach (OperationDescription operation in policyContext.Contract.Operations)
            {
                MessagePartSpecification operationSignedParts;
                MessagePartSpecification operationEncryptedParts;

                ICollection <XmlElement> operationBindingAssertions = policyContext.GetOperationBindingAssertions(operation);
                this.ImportProtectionAssertions(operationBindingAssertions, out operationSignedParts, out operationEncryptedParts);
                this.AddParts(ref operationSignedParts, endpointSignedParts);
                this.AddParts(ref operationEncryptedParts, endpointEncryptedParts);

                MessagePartSpecification messageSignedParts;
                MessagePartSpecification messageEncryptedParts;
                bool            hasProtectionLevel       = false;
                bool            isProtectionLevelUniform = true;
                ProtectionLevel protectionLevel          = ProtectionLevel.None;

                // import application message protection requirements
                foreach (MessageDescription message in operation.Messages)
                {
                    ICollection <XmlElement> messageBindingAssertions = policyContext.GetMessageBindingAssertions(message);
                    this.ImportProtectionAssertions(messageBindingAssertions, out messageSignedParts, out messageEncryptedParts);
                    this.AddParts(ref messageSignedParts, operationSignedParts);
                    this.AddParts(ref messageEncryptedParts, operationEncryptedParts);

                    // validate or set body protection level
                    ProtectionLevel newProtectionLevel = GetProtectionLevel(messageSignedParts.IsBodyIncluded, messageEncryptedParts.IsBodyIncluded, message.Action);
                    if (OperationFormatter.IsValidReturnValue(message.Body.ReturnValue))
                    {
                        ValidateExistingOrSetNewProtectionLevel(message.Body.ReturnValue, message, operation, policyContext.Contract, newProtectionLevel);
                    }
                    foreach (MessagePartDescription body in message.Body.Parts)
                    {
                        ValidateExistingOrSetNewProtectionLevel(body, message, operation, policyContext.Contract, newProtectionLevel);
                    }
                    if (!OperationFormatter.IsValidReturnValue(message.Body.ReturnValue) || message.Body.Parts.Count == 0)
                    {
                        ValidateExistingOrSetNewProtectionLevel(null, message, operation, policyContext.Contract, newProtectionLevel);
                    }

                    if (hasProtectionLevel)
                    {
                        if (protectionLevel != newProtectionLevel)
                        {
                            isProtectionLevelUniform = false;
                        }
                    }
                    else
                    {
                        protectionLevel    = newProtectionLevel;
                        hasProtectionLevel = true;
                    }
                    if (hasContractProtectionLevel)
                    {
                        if (contractProtectionLevel != newProtectionLevel)
                        {
                            isContractProtectionLevelUniform = false;
                        }
                    }
                    else
                    {
                        contractProtectionLevel    = newProtectionLevel;
                        hasContractProtectionLevel = true;
                    }

                    // validate o set header protection level
                    foreach (MessageHeaderDescription header in message.Headers)
                    {
                        bool signed    = messageSignedParts.IsHeaderIncluded(header.Name, header.Namespace);
                        bool encrypted = messageEncryptedParts.IsHeaderIncluded(header.Name, header.Namespace);
                        newProtectionLevel = GetProtectionLevel(signed, encrypted, message.Action);
                        ValidateExistingOrSetNewProtectionLevel(header, message, operation, policyContext.Contract, newProtectionLevel);

                        if (hasProtectionLevel)
                        {
                            if (protectionLevel != newProtectionLevel)
                            {
                                isProtectionLevelUniform = false;
                            }
                        }
                        else
                        {
                            protectionLevel    = newProtectionLevel;
                            hasProtectionLevel = true;
                        }
                        if (hasContractProtectionLevel)
                        {
                            if (contractProtectionLevel != newProtectionLevel)
                            {
                                isContractProtectionLevelUniform = false;
                            }
                        }
                        else
                        {
                            contractProtectionLevel    = newProtectionLevel;
                            hasContractProtectionLevel = true;
                        }
                    }
                }

                // normalize protection level settings at the operation scope if possible to help avoid typed message generation
                if (hasProtectionLevel && isProtectionLevelUniform)
                {
                    // (hongmeig) remove the foreach message here
                    //  foreach (MessageDescription message in operation.Messages)

                    this.ResetProtectionLevelForMessages(operation);

                    operation.ProtectionLevel = protectionLevel;
                }

                // import fault protection requirements
                foreach (FaultDescription fault in operation.Faults)
                {
                    ICollection <XmlElement> faultBindingAssertions = policyContext.GetFaultBindingAssertions(fault);
                    this.ImportProtectionAssertions(faultBindingAssertions, out messageSignedParts, out messageEncryptedParts);
                    this.AddParts(ref messageSignedParts, operationSignedParts);
                    this.AddParts(ref messageEncryptedParts, operationEncryptedParts);

                    // validate or set fault protection level
                    ProtectionLevel newProtectionLevel = GetProtectionLevel(messageSignedParts.IsBodyIncluded, messageEncryptedParts.IsBodyIncluded, fault.Action);
                    if (fault.HasProtectionLevel)
                    {
                        if (fault.ProtectionLevel != newProtectionLevel)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(string.Format(SRServiceModel.CannotImportProtectionLevelForContract, policyContext.Contract.Name, policyContext.Contract.Namespace)));
                        }
                    }
                    else
                    {
                        fault.ProtectionLevel = newProtectionLevel;
                    }
                    if (hasContractProtectionLevel)
                    {
                        if (contractProtectionLevel != newProtectionLevel)
                        {
                            isContractProtectionLevelUniform = false;
                        }
                    }
                    else
                    {
                        contractProtectionLevel    = newProtectionLevel;
                        hasContractProtectionLevel = true;
                    }
                }
            }

            if (isContractAssociatedWithAtLeastOneOtherBinding)
            {
                if (hasContractProtectionLevel != otherBindingProtectionLevel.HasProtectionRequirements ||
                    isContractProtectionLevelUniform != otherBindingProtectionLevel.HasUniformProtectionLevel ||
                    contractProtectionLevel != otherBindingProtectionLevel.UniformProtectionLevel)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(string.Format(SRServiceModel.CannotImportProtectionLevelForContract, policyContext.Contract.Name, policyContext.Contract.Namespace)));
                }
            }
            else
            {
                if (hasContractProtectionLevel && isContractProtectionLevelUniform && contractProtectionLevel == ProtectionLevel.EncryptAndSign)
                {
                    // remove all explicitly set protection levels on the contract description, since they are uniform across the contract
                    // and match our binding's default of EncryptAndSign
                    foreach (OperationDescription operation in policyContext.Contract.Operations)
                    {
                        this.ResetProtectionLevelForMessages(operation);
                        foreach (FaultDescription fault in operation.Faults)
                        {
                            fault.ResetProtectionLevel();
                        }
                        operation.ResetProtectionLevel();
                    }
                }
                importer.State[contractAssociationName] = new ContractProtectionLevel(hasContractProtectionLevel, isContractProtectionLevelUniform, contractProtectionLevel);
            }
        }
        private void ImportMessageScopeProtectionPolicy(MetadataImporter importer, PolicyConversionContext policyContext)
        {
            MessagePartSpecification specification;
            MessagePartSpecification specification2;
            bool flag;
            ContractProtectionLevel level             = null;
            bool            hasProtectionRequirements = false;
            bool            hasUniformProtectionLevel = true;
            ProtectionLevel none = ProtectionLevel.None;
            string          key  = string.Format("{0}:{1}:{2}", "ContractProtectionLevelKey", policyContext.Contract.Name, policyContext.Contract.Namespace);

            if (importer.State.ContainsKey(key))
            {
                flag  = true;
                level = (ContractProtectionLevel)importer.State[key];
            }
            else
            {
                flag = false;
            }
            ICollection <XmlElement> bindingAssertions = policyContext.GetBindingAssertions();

            this.ImportProtectionAssertions(bindingAssertions, out specification, out specification2);
            if (importer.State.ContainsKey("InSecureConversationBootstrapBindingImportMode"))
            {
                if (specification2 != null)
                {
                    importer.State["SecureConversationBootstrapEncryptionRequirements"] = specification2;
                }
                if (specification != null)
                {
                    importer.State["SecureConversationBootstrapSignatureRequirements"] = specification;
                }
            }
            foreach (OperationDescription description in policyContext.Contract.Operations)
            {
                MessagePartSpecification specification3;
                MessagePartSpecification specification4;
                MessagePartSpecification specification5;
                MessagePartSpecification specification6;
                ICollection <XmlElement> operationBindingAssertions = policyContext.GetOperationBindingAssertions(description);
                this.ImportProtectionAssertions(operationBindingAssertions, out specification3, out specification4);
                this.AddParts(ref specification3, specification);
                this.AddParts(ref specification4, specification2);
                bool            flag4  = false;
                bool            flag5  = true;
                ProtectionLevel level3 = ProtectionLevel.None;
                foreach (MessageDescription description2 in description.Messages)
                {
                    ICollection <XmlElement> messageBindingAssertions = policyContext.GetMessageBindingAssertions(description2);
                    this.ImportProtectionAssertions(messageBindingAssertions, out specification5, out specification6);
                    this.AddParts(ref specification5, specification3);
                    this.AddParts(ref specification6, specification4);
                    ProtectionLevel newProtectionLevel = GetProtectionLevel(specification5.IsBodyIncluded, specification6.IsBodyIncluded, description2.Action);
                    if (OperationFormatter.IsValidReturnValue(description2.Body.ReturnValue))
                    {
                        this.ValidateExistingOrSetNewProtectionLevel(description2.Body.ReturnValue, description2, description, policyContext.Contract, newProtectionLevel);
                    }
                    foreach (MessagePartDescription description3 in description2.Body.Parts)
                    {
                        this.ValidateExistingOrSetNewProtectionLevel(description3, description2, description, policyContext.Contract, newProtectionLevel);
                    }
                    if (!OperationFormatter.IsValidReturnValue(description2.Body.ReturnValue) || (description2.Body.Parts.Count == 0))
                    {
                        this.ValidateExistingOrSetNewProtectionLevel(null, description2, description, policyContext.Contract, newProtectionLevel);
                    }
                    if (flag4)
                    {
                        if (level3 != newProtectionLevel)
                        {
                            flag5 = false;
                        }
                    }
                    else
                    {
                        level3 = newProtectionLevel;
                        flag4  = true;
                    }
                    if (hasProtectionRequirements)
                    {
                        if (none != newProtectionLevel)
                        {
                            hasUniformProtectionLevel = false;
                        }
                    }
                    else
                    {
                        none = newProtectionLevel;
                        hasProtectionRequirements = true;
                    }
                    foreach (MessageHeaderDescription description4 in description2.Headers)
                    {
                        bool signed    = specification5.IsHeaderIncluded(description4.Name, description4.Namespace);
                        bool encrypted = specification6.IsHeaderIncluded(description4.Name, description4.Namespace);
                        newProtectionLevel = GetProtectionLevel(signed, encrypted, description2.Action);
                        this.ValidateExistingOrSetNewProtectionLevel(description4, description2, description, policyContext.Contract, newProtectionLevel);
                        if (flag4)
                        {
                            if (level3 != newProtectionLevel)
                            {
                                flag5 = false;
                            }
                        }
                        else
                        {
                            level3 = newProtectionLevel;
                            flag4  = true;
                        }
                        if (hasProtectionRequirements)
                        {
                            if (none != newProtectionLevel)
                            {
                                hasUniformProtectionLevel = false;
                            }
                        }
                        else
                        {
                            none = newProtectionLevel;
                            hasProtectionRequirements = true;
                        }
                    }
                }
                if (flag4 && flag5)
                {
                    this.ResetProtectionLevelForMessages(description);
                    description.ProtectionLevel = level3;
                }
                foreach (FaultDescription description5 in description.Faults)
                {
                    ICollection <XmlElement> faultBindingAssertions = policyContext.GetFaultBindingAssertions(description5);
                    this.ImportProtectionAssertions(faultBindingAssertions, out specification5, out specification6);
                    this.AddParts(ref specification5, specification3);
                    this.AddParts(ref specification6, specification4);
                    ProtectionLevel level5 = GetProtectionLevel(specification5.IsBodyIncluded, specification6.IsBodyIncluded, description5.Action);
                    if (description5.HasProtectionLevel)
                    {
                        if (description5.ProtectionLevel != level5)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.ServiceModel.SR.GetString("CannotImportProtectionLevelForContract", new object[] { policyContext.Contract.Name, policyContext.Contract.Namespace })));
                        }
                    }
                    else
                    {
                        description5.ProtectionLevel = level5;
                    }
                    if (hasProtectionRequirements)
                    {
                        if (none != level5)
                        {
                            hasUniformProtectionLevel = false;
                        }
                    }
                    else
                    {
                        none = level5;
                        hasProtectionRequirements = true;
                    }
                }
            }
            if (flag)
            {
                if (((hasProtectionRequirements != level.HasProtectionRequirements) || (hasUniformProtectionLevel != level.HasUniformProtectionLevel)) || (none != level.UniformProtectionLevel))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.ServiceModel.SR.GetString("CannotImportProtectionLevelForContract", new object[] { policyContext.Contract.Name, policyContext.Contract.Namespace })));
                }
            }
            else
            {
                if ((hasProtectionRequirements && hasUniformProtectionLevel) && (none == ProtectionLevel.EncryptAndSign))
                {
                    foreach (OperationDescription description6 in policyContext.Contract.Operations)
                    {
                        this.ResetProtectionLevelForMessages(description6);
                        foreach (FaultDescription description7 in description6.Faults)
                        {
                            description7.ResetProtectionLevel();
                        }
                        description6.ResetProtectionLevel();
                    }
                }
                importer.State[key] = new ContractProtectionLevel(hasProtectionRequirements, hasUniformProtectionLevel, none);
            }
        }