1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 namespace System.ServiceModel.Dispatcher 5 { 6 using System.ServiceModel.Channels; 7 using System.ServiceModel; 8 using System.ServiceModel.Description; 9 using System.Collections.ObjectModel; 10 using System.Collections.Generic; 11 using System.Xml; 12 using System.Security; 13 using System.Security.Permissions; 14 using System.ServiceModel.MsmqIntegration; 15 using System.Runtime; 16 17 class PartialTrustValidationBehavior : IServiceBehavior, IEndpointBehavior 18 { 19 static PartialTrustValidationBehavior instance = null; 20 21 internal static PartialTrustValidationBehavior Instance 22 { 23 get 24 { 25 // no need to synchronize -- it's ok if two are created 26 if (instance == null) 27 { 28 instance = new PartialTrustValidationBehavior(); 29 } 30 return instance; 31 } 32 } 33 ValidateEndpoint(ServiceEndpoint endpoint)34 void ValidateEndpoint(ServiceEndpoint endpoint) 35 { 36 Binding binding = endpoint.Binding; 37 if (binding != null) 38 { 39 new BindingValidator(endpoint.Binding).Validate(); 40 } 41 } 42 43 #region IEndpointBehavior Members 44 IEndpointBehavior.Validate(ServiceEndpoint endpoint)45 void IEndpointBehavior.Validate(ServiceEndpoint endpoint) 46 { 47 if (endpoint == null) 48 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint"); 49 50 ValidateEndpoint(endpoint); 51 } 52 IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)53 void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)54 void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)55 void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } 56 57 #endregion 58 59 #region IServiceBehavior Members 60 Validate(ServiceDescription description, ServiceHostBase serviceHostBase)61 public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase) 62 { 63 if (description == null) 64 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description"); 65 for (int i = 0; i < description.Endpoints.Count; i++) 66 { 67 ServiceEndpoint endpoint = description.Endpoints[i]; 68 if (endpoint != null) 69 { 70 ValidateEndpoint(endpoint); 71 } 72 } 73 } 74 AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)75 public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)76 public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } 77 78 #endregion 79 80 struct BindingValidator 81 { 82 static Type[] unsupportedBindings = new Type[] 83 { 84 typeof(NetNamedPipeBinding), 85 typeof(WSDualHttpBinding), 86 typeof(WS2007FederationHttpBinding), 87 typeof(WSFederationHttpBinding), 88 typeof(NetMsmqBinding), 89 #pragma warning disable 0618 90 typeof(NetPeerTcpBinding), 91 #pragma warning restore 0618 92 typeof(MsmqIntegrationBinding), 93 }; 94 95 static Type[] unsupportedBindingElements = new Type[] 96 { 97 typeof(AsymmetricSecurityBindingElement), 98 typeof(CompositeDuplexBindingElement), 99 typeof(MsmqTransportBindingElement), 100 typeof(NamedPipeTransportBindingElement), 101 typeof(OneWayBindingElement), 102 #pragma warning disable 0618 103 typeof(PeerCustomResolverBindingElement), 104 typeof(PeerTransportBindingElement), 105 typeof(PnrpPeerResolverBindingElement), 106 #pragma warning restore 0618 107 typeof(ReliableSessionBindingElement), 108 typeof(SymmetricSecurityBindingElement), 109 typeof(TransportSecurityBindingElement), 110 typeof(MtomMessageEncodingBindingElement), 111 }; 112 113 Binding binding; BindingValidatorSystem.ServiceModel.Dispatcher.PartialTrustValidationBehavior.BindingValidator114 internal BindingValidator(Binding binding) 115 { 116 this.binding = binding; 117 } 118 ValidateSystem.ServiceModel.Dispatcher.PartialTrustValidationBehavior.BindingValidator119 internal void Validate() 120 { 121 Fx.Assert(binding != null, "BindingValidator was not constructed with a valid Binding instance"); 122 123 Type bindingType = binding.GetType(); 124 if (IsUnsupportedBindingType(bindingType)) 125 { 126 UnsupportedSecurityCheck(SR.FullTrustOnlyBindingSecurityCheck1, bindingType); 127 } 128 129 // special-case error message for WSHttpBindings 130 bool isWSHttpBinding = typeof(WSHttpBinding).IsAssignableFrom(bindingType); 131 string sr = isWSHttpBinding ? SR.FullTrustOnlyBindingElementSecurityCheckWSHttpBinding1 : SR.FullTrustOnlyBindingElementSecurityCheck1; 132 133 BindingElementCollection elements = binding.CreateBindingElements(); 134 foreach (BindingElement element in elements) 135 { 136 Type bindingElementType = element.GetType(); 137 if (element != null && IsUnsupportedBindingElementType(bindingElementType)) 138 { 139 UnsupportedSecurityCheck(sr, bindingElementType); 140 } 141 } 142 } 143 IsUnsupportedBindingTypeSystem.ServiceModel.Dispatcher.PartialTrustValidationBehavior.BindingValidator144 bool IsUnsupportedBindingType(Type bindingType) 145 { 146 for (int i = 0; i < unsupportedBindings.Length; i++) 147 { 148 if (unsupportedBindings[i] == bindingType) 149 return true; 150 } 151 return false; 152 } 153 IsUnsupportedBindingElementTypeSystem.ServiceModel.Dispatcher.PartialTrustValidationBehavior.BindingValidator154 bool IsUnsupportedBindingElementType(Type bindingElementType) 155 { 156 for (int i = 0; i < unsupportedBindingElements.Length; i++) 157 { 158 if (unsupportedBindingElements[i] == bindingElementType) 159 return true; 160 } 161 return false; 162 } 163 164 static readonly PermissionSet fullTrust = new PermissionSet(PermissionState.Unrestricted); UnsupportedSecurityCheckSystem.ServiceModel.Dispatcher.PartialTrustValidationBehavior.BindingValidator165 void UnsupportedSecurityCheck(string resource, Type type) 166 { 167 try 168 { 169 fullTrust.Demand(); 170 } 171 catch (SecurityException) 172 { 173 throw new InvalidOperationException(SR.GetString(resource, binding.Name, type)); 174 } 175 } 176 177 } 178 } 179 180 } 181