| File: CodeDomFixup\EndpointSelector.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; namespace Microsoft.Tools.ServiceModel.Svcutil { internal class EndpointSelector : MetadataFixup { private static List<string> s_bindingValidationErrors = new List<string>(); public EndpointSelector(WsdlImporter importer, Collection<ServiceEndpoint> endpoints, Collection<Binding> bindings, Collection<ContractDescription> contracts) : base(importer, endpoints, bindings, contracts) { } public override void Fixup() { CollectionHelpers.MapList<ServiceEndpoint>(this.endpoints, EndpointSelector.SelectEndpoint, this.AddWarning); bindings.Clear(); foreach (ServiceEndpoint endpoint in endpoints) { bindings.Add(endpoint.Binding); } } private static bool SelectEndpoint(ServiceEndpoint endpoint) { return IsBindingSupported(endpoint.Binding); } private static bool IsBindingSupported(Binding binding) { s_bindingValidationErrors.Clear(); if (!(binding is BasicHttpBinding || binding is NetHttpBinding || binding is WSHttpBinding || binding is NetTcpBinding || binding is WSFederationHttpBinding || binding is NetNamedPipeBinding || binding is CustomBinding)) { s_bindingValidationErrors.Add(string.Format(SR.BindingTypeNotSupportedFormat, binding.GetType().FullName, typeof(BasicHttpBinding).FullName, typeof(NetHttpBinding).FullName, typeof(WSHttpBinding).FullName, typeof(NetTcpBinding).FullName, typeof(CustomBinding).FullName)); } else { WSHttpBinding wsHttpBinding = binding as WSHttpBinding; if (wsHttpBinding != null) { if (wsHttpBinding.TransactionFlow) { s_bindingValidationErrors.Add(SR.BindingTransactionFlowNotSupported); } if (wsHttpBinding.Security.Mode == SecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", wsHttpBinding.Security.Mode)); } } else { NetTcpBinding netTcpBinding = binding as NetTcpBinding; if (netTcpBinding != null) { if (netTcpBinding.TransactionFlow) { s_bindingValidationErrors.Add(SR.BindingTransactionFlowNotSupported); } if (netTcpBinding.Security.Mode == SecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", netTcpBinding.Security.Mode)); } } else { NetHttpBinding netHttpBinding = binding as NetHttpBinding; if (netHttpBinding != null) { if (netHttpBinding.Security.Mode == BasicHttpSecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", netHttpBinding.Security.Mode)); } } else { BasicHttpBinding basicHttpBinding = binding as BasicHttpBinding; if (basicHttpBinding != null && basicHttpBinding.Security.Mode == BasicHttpSecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", basicHttpBinding.Security.Mode)); } else { WS2007FederationHttpBinding ws2007FederationHttpBinding = binding as WS2007FederationHttpBinding; if (ws2007FederationHttpBinding != null && ws2007FederationHttpBinding.Security.Mode == WSFederationHttpSecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", ws2007FederationHttpBinding.Security.Mode)); } else { WSFederationHttpBinding wsFederationHttpBinding = binding as WSFederationHttpBinding; if (wsFederationHttpBinding != null && wsFederationHttpBinding.Security.Mode == WSFederationHttpSecurityMode.Message) { s_bindingValidationErrors.Add(string.Format(SRServiceModel.UnsupportedSecuritySetting, "Mode", wsFederationHttpBinding.Security.Mode)); } } } } } } ValidateBindingElements(binding); } return s_bindingValidationErrors.Count == 0; } private static void ValidateBindingElements(Binding binding) { BindingElementCollection bindingElements = binding.CreateBindingElements(); foreach (BindingElement bindingElement in bindingElements) { if (bindingElement is TransportBindingElement) { if (!(bindingElement is HttpTransportBindingElement || bindingElement is HttpsTransportBindingElement || bindingElement is TcpTransportBindingElement || bindingElement is NamedPipeTransportBindingElement)) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportTypeNotSupportedFormat, bindingElement.GetType().FullName, typeof(HttpTransportBindingElement).FullName, typeof(HttpsTransportBindingElement).FullName, typeof(TcpTransportBindingElement).FullName)); } } else if (bindingElement is MessageEncodingBindingElement) { if (!(bindingElement is BinaryMessageEncodingBindingElement || bindingElement is TextMessageEncodingBindingElement || bindingElement is MtomMessageEncodingBindingElement)) { s_bindingValidationErrors.Add(string.Format(SR.BindingMessageEncodingElementNotSupportedFormat, bindingElement.GetType().FullName, typeof(BinaryMessageEncodingBindingElement).FullName, typeof(TextMessageEncodingBindingElement).FullName)); } else { var binMsgEncodingElement = bindingElement as BinaryMessageEncodingBindingElement; if (binMsgEncodingElement != null) { if (binMsgEncodingElement.MessageVersion != MessageVersion.Soap12WSAddressing10) { s_bindingValidationErrors.Add(string.Format(SR.BindingBinaryMessageEncodingVersionNotSupportedFormat, binMsgEncodingElement.MessageVersion, MessageVersion.Soap12WSAddressing10)); } } else { var txtMsgEncodingElement = bindingElement as TextMessageEncodingBindingElement; if (txtMsgEncodingElement != null && txtMsgEncodingElement.MessageVersion != MessageVersion.None && txtMsgEncodingElement.MessageVersion != MessageVersion.Soap11 && txtMsgEncodingElement.MessageVersion != MessageVersion.Soap12 && txtMsgEncodingElement.MessageVersion != MessageVersion.Soap11WSAddressing10 && txtMsgEncodingElement.MessageVersion != MessageVersion.Soap12WSAddressing10) { s_bindingValidationErrors.Add(string.Format(SR.BindingTextMessageEncodingVersionNotSupportedFormat, txtMsgEncodingElement.MessageVersion, MessageVersion.None, MessageVersion.Soap11, MessageVersion.Soap12, MessageVersion.Soap11WSAddressing10, MessageVersion.Soap12WSAddressing10)); } else { var mtomMsgEncodingElement = bindingElement as MtomMessageEncodingBindingElement; if (mtomMsgEncodingElement != null && mtomMsgEncodingElement.MessageVersion != MessageVersion.Soap11 && mtomMsgEncodingElement.MessageVersion != MessageVersion.Soap12 && mtomMsgEncodingElement.MessageVersion != MessageVersion.Soap11WSAddressing10 && mtomMsgEncodingElement.MessageVersion != MessageVersion.Soap12WSAddressing10) { s_bindingValidationErrors.Add(string.Format(SR.BindingMtomMessageEncodingVersionNotSupportedFormat, mtomMsgEncodingElement.MessageVersion, MessageVersion.Soap11, MessageVersion.Soap12, MessageVersion.Soap11WSAddressing10, MessageVersion.Soap12WSAddressing10)); } } } } } else if (bindingElement is SslStreamSecurityBindingElement) { // do nothing } else if (bindingElement is WindowsStreamSecurityBindingElement) { // do nothing } else if (bindingElement is ReliableSessionBindingElement) { // do nothing } else if (bindingElement is TransactionFlowBindingElement) { if (binding is WSHttpBinding && ((WSHttpBinding)binding).TransactionFlow) { s_bindingValidationErrors.Add(SR.BindingTransactionFlowNotSupported); } if (binding is NetTcpBinding && ((NetTcpBinding)binding).TransactionFlow) { s_bindingValidationErrors.Add(SR.BindingTransactionFlowNotSupported); } } else if (bindingElement is TransportSecurityBindingElement) { ValidateTransportSecurityBindingElement(bindingElement as TransportSecurityBindingElement); } else { s_bindingValidationErrors.Add(string.Format(SR.BindingElementTypeNotSupportedFormat, bindingElement.GetType().FullName)); } } } private static void ValidateTransportSecurityBindingElement(TransportSecurityBindingElement transportSecurityBindingElement) { if (transportSecurityBindingElement.EndpointSupportingTokenParameters.Signed.Count != 0 || transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEndorsing.Count != 0) { s_bindingValidationErrors.Add(SR.BindingTransportSecurityTokenSignedOrSignedEndorsingNotSupported); } else if (transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Count == 1) { ValidateUserNamePasswordSecurityBindingElement(transportSecurityBindingElement); } else if (transportSecurityBindingElement.EndpointSupportingTokenParameters.Endorsing.Count == 1) { SecureConversationSecurityTokenParameters endorsingTokenParams = transportSecurityBindingElement.EndpointSupportingTokenParameters.Endorsing[0] as SecureConversationSecurityTokenParameters; if (endorsingTokenParams != null) { if (endorsingTokenParams.RequireDerivedKeys) { s_bindingValidationErrors.Add(SR.BindingTransportSecurityTokenParamsRequiringDerivedKeysNotSupported); } TransportSecurityBindingElement bootstrapElement = endorsingTokenParams.BootstrapSecurityBindingElement as TransportSecurityBindingElement; if (bootstrapElement == null) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityElementTypeNotSupportedFormat, endorsingTokenParams.BootstrapSecurityBindingElement.GetType().FullName, typeof(TransportSecurityBindingElement).FullName)); } else { ValidateTransportSecurityBindingElement(bootstrapElement); } } } if (!transportSecurityBindingElement.IncludeTimestamp) { s_bindingValidationErrors.Add(SR.BindingTransportSecurityMustIncludeTimestamp); } if (transportSecurityBindingElement.DefaultAlgorithmSuite != SecurityAlgorithmSuite.Default) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityDefaultAlgorithmSuiteNotSupportedFormat, transportSecurityBindingElement.DefaultAlgorithmSuite.GetType().FullName, SecurityAlgorithmSuite.Default.GetType().FullName)); } } private static void ValidateUserNamePasswordSecurityBindingElement(TransportSecurityBindingElement transportSecurityBindingElement) { bool singleSignedEncryptedParam = transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Count == 1; System.Diagnostics.Debug.Assert(singleSignedEncryptedParam, "Unexpected number of SignedEncrypted token parameters in transport security binding!"); if (!singleSignedEncryptedParam) { return; } if (transportSecurityBindingElement.MessageSecurityVersion != MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10 && transportSecurityBindingElement.MessageSecurityVersion != MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10 && transportSecurityBindingElement.MessageSecurityVersion != MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11 && transportSecurityBindingElement.MessageSecurityVersion != MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10) { string values = string.Format(CultureInfo.InvariantCulture, "'{0}', '{1}', '{2}'", MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11); s_bindingValidationErrors.Add(string.Format(SR.BindingTransportMessageSecurityVersionNotSupportedFormat, transportSecurityBindingElement.MessageSecurityVersion, values)); } if (transportSecurityBindingElement.DefaultAlgorithmSuite != SecurityAlgorithmSuite.Default) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityDefaultAlgorithmSuiteNotSupportedFormat, transportSecurityBindingElement.DefaultAlgorithmSuite.GetType().FullName, SecurityAlgorithmSuite.Default.GetType().FullName)); } var userNameParams = transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted[0] as UserNameSecurityTokenParameters; if (userNameParams != null) { if (userNameParams.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityTokenParamsInclusionModeValueNotSupportedFormat, userNameParams.InclusionMode, SecurityTokenInclusionMode.AlwaysToRecipient)); } if (userNameParams.ReferenceStyle != SecurityTokenReferenceStyle.Internal) { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityTokenParamsReferenceStyleNotSupportedFormat, userNameParams.ReferenceStyle, SecurityTokenReferenceStyle.Internal)); } if (userNameParams.RequireDerivedKeys != false) { s_bindingValidationErrors.Add(SR.BindingTransportSecurityTokenParamsRequiringDerivedKeysNotSupported); } } else { s_bindingValidationErrors.Add(string.Format(SR.BindingTransportSecurityTokenParamsTypeNotSupportedFormat, transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted[0].GetType().FullName, typeof(UserNameSecurityTokenParameters).FullName)); } } private void AddWarning(ServiceEndpoint endpoint, int i) { MetadataConversionError warning; foreach (var validationErrorMsg in s_bindingValidationErrors) { warning = new MetadataConversionError(validationErrorMsg, isWarning: true); if (!importer.Errors.Contains(warning)) { importer.Errors.Add(warning); } } string incompatEndpointMsg = string.Format(CultureInfo.InvariantCulture, SR.WrnIncompatibleEndpointFormat, endpoint.Name, endpoint.Address); warning = new MetadataConversionError(incompatEndpointMsg, isWarning: true); if (!importer.Errors.Contains(warning)) { importer.Errors.Add(warning); } } } }