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); } }