1 //------------------------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------------------------ 4 namespace System.ServiceModel.Configuration 5 { 6 using System; 7 using System.Collections.Generic; 8 using System.Configuration; 9 using System.Diagnostics; 10 using System.Reflection; 11 using System.Runtime; 12 using System.Runtime.Diagnostics; 13 using System.Security; 14 using System.Security.Permissions; 15 using System.ServiceModel; 16 using System.ServiceModel.Activation; 17 using System.ServiceModel.Diagnostics; 18 19 static class ConfigurationHelpers 20 { 21 /// Be sure to update UnsafeGetAssociatedBindingCollectionElement if you modify this method GetAssociatedBindingCollectionElement(ContextInformation evaluationContext, string bindingCollectionName)22 internal static BindingCollectionElement GetAssociatedBindingCollectionElement(ContextInformation evaluationContext, string bindingCollectionName) 23 { 24 BindingCollectionElement retVal = null; 25 BindingsSection bindingsSection = (BindingsSection)ConfigurationHelpers.GetAssociatedSection(evaluationContext, ConfigurationStrings.BindingsSectionGroupPath); 26 27 if (null != bindingsSection) 28 { 29 bindingsSection.UpdateBindingSections(evaluationContext); 30 try 31 { 32 retVal = bindingsSection[bindingCollectionName]; 33 } 34 catch (KeyNotFoundException) 35 { 36 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 37 new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingExtensionNotFound, 38 ConfigurationHelpers.GetBindingsSectionPath(bindingCollectionName)))); 39 } 40 catch (NullReferenceException) // System.Configuration.ConfigurationElement bug 41 { 42 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 43 new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingExtensionNotFound, 44 ConfigurationHelpers.GetBindingsSectionPath(bindingCollectionName)))); 45 } 46 } 47 48 return retVal; 49 } 50 51 // Be sure to update GetAssociatedBindingCollectionElement if you modify this method 52 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedSection which elevates.")] 53 [SecurityCritical] UnsafeGetAssociatedBindingCollectionElement(ContextInformation evaluationContext, string bindingCollectionName)54 internal static BindingCollectionElement UnsafeGetAssociatedBindingCollectionElement(ContextInformation evaluationContext, string bindingCollectionName) 55 { 56 BindingCollectionElement retVal = null; 57 BindingsSection bindingsSection = (BindingsSection)ConfigurationHelpers.UnsafeGetAssociatedSection(evaluationContext, ConfigurationStrings.BindingsSectionGroupPath); 58 59 if (null != bindingsSection) 60 { 61 bindingsSection.UpdateBindingSections(evaluationContext); 62 try 63 { 64 retVal = bindingsSection[bindingCollectionName]; 65 } 66 catch (KeyNotFoundException) 67 { 68 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 69 new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingExtensionNotFound, 70 ConfigurationHelpers.GetBindingsSectionPath(bindingCollectionName)))); 71 } 72 catch (NullReferenceException) // System.Configuration.ConfigurationElement bug 73 { 74 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 75 new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingExtensionNotFound, 76 ConfigurationHelpers.GetBindingsSectionPath(bindingCollectionName)))); 77 } 78 } 79 80 return retVal; 81 } 82 83 /// Be sure to update UnsafeGetAssociatedEndpointCollectionElement if you modify this method GetAssociatedEndpointCollectionElement(ContextInformation evaluationContext, string endpointCollectionName)84 internal static EndpointCollectionElement GetAssociatedEndpointCollectionElement(ContextInformation evaluationContext, string endpointCollectionName) 85 { 86 EndpointCollectionElement retVal = null; 87 StandardEndpointsSection endpointsSection = (StandardEndpointsSection)ConfigurationHelpers.GetAssociatedSection(evaluationContext, ConfigurationStrings.StandardEndpointsSectionPath); 88 89 if (null != endpointsSection) 90 { 91 endpointsSection.UpdateEndpointSections(evaluationContext); 92 try 93 { 94 retVal = (EndpointCollectionElement)endpointsSection[endpointCollectionName]; 95 } 96 catch (KeyNotFoundException) 97 { 98 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 99 new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointExtensionNotFound, 100 ConfigurationHelpers.GetEndpointsSectionPath(endpointCollectionName)))); 101 } 102 catch (NullReferenceException) // System.Configuration.ConfigurationElement bug 103 { 104 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 105 new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointExtensionNotFound, 106 ConfigurationHelpers.GetEndpointsSectionPath(endpointCollectionName)))); 107 } 108 } 109 110 return retVal; 111 } 112 113 // Be sure to update GetAssociatedEndpointCollectionElement if you modify this method 114 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedSection which elevates.")] 115 [SecurityCritical] UnsafeGetAssociatedEndpointCollectionElement(ContextInformation evaluationContext, string endpointCollectionName)116 internal static EndpointCollectionElement UnsafeGetAssociatedEndpointCollectionElement(ContextInformation evaluationContext, string endpointCollectionName) 117 { 118 EndpointCollectionElement retVal = null; 119 StandardEndpointsSection endpointsSection = (StandardEndpointsSection)ConfigurationHelpers.UnsafeGetAssociatedSection(evaluationContext, ConfigurationStrings.StandardEndpointsSectionPath); 120 121 if (null != endpointsSection) 122 { 123 endpointsSection.UpdateEndpointSections(evaluationContext); 124 try 125 { 126 retVal = (EndpointCollectionElement)endpointsSection[endpointCollectionName]; 127 } 128 catch (KeyNotFoundException) 129 { 130 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 131 new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointExtensionNotFound, 132 ConfigurationHelpers.GetEndpointsSectionPath(endpointCollectionName)))); 133 } 134 catch (NullReferenceException) // System.Configuration.ConfigurationElement bug 135 { 136 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 137 new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointExtensionNotFound, 138 ConfigurationHelpers.GetEndpointsSectionPath(endpointCollectionName)))); 139 } 140 } 141 142 return retVal; 143 } 144 145 /// Be sure to update UnsafeGetAssociatedSection if you modify this method GetAssociatedSection(ContextInformation evalContext, string sectionPath)146 internal static object GetAssociatedSection(ContextInformation evalContext, string sectionPath) 147 { 148 object retval = null; 149 if (evalContext != null) 150 { 151 retval = evalContext.GetSection(sectionPath); 152 } 153 else 154 { 155 retval = AspNetEnvironment.Current.GetConfigurationSection(sectionPath); 156 157 // Trace after call to underlying configuration system to 158 // insure that configuration system is initialized 159 if (DiagnosticUtility.ShouldTraceVerbose) 160 { 161 TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.GetConfigurationSection, 162 SR.GetString(SR.TraceCodeGetConfigurationSection), 163 new StringTraceRecord("ConfigurationSection", sectionPath), null, null); 164 } 165 } 166 if (retval == null) 167 { 168 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 169 new ConfigurationErrorsException(SR.GetString(SR.ConfigSectionNotFound, 170 sectionPath))); 171 } 172 return retval; 173 } 174 175 // Be sure to update GetAssociatedSection if you modify this method 176 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical methods which elevate.")] 177 [SecurityCritical] UnsafeGetAssociatedSection(ContextInformation evalContext, string sectionPath)178 internal static object UnsafeGetAssociatedSection(ContextInformation evalContext, string sectionPath) 179 { 180 object retval = null; 181 if (evalContext != null) 182 { 183 retval = UnsafeGetSectionFromContext(evalContext, sectionPath); 184 } 185 else 186 { 187 retval = AspNetEnvironment.Current.UnsafeGetConfigurationSection(sectionPath); 188 189 // Trace after call to underlying configuration system to 190 // insure that configuration system is initialized 191 if (DiagnosticUtility.ShouldTraceVerbose) 192 { 193 TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.GetConfigurationSection, 194 SR.GetString(SR.TraceCodeGetConfigurationSection), 195 new StringTraceRecord("ConfigurationSection", sectionPath), null, null); 196 } 197 } 198 if (retval == null) 199 { 200 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 201 new ConfigurationErrorsException(SR.GetString(SR.ConfigSectionNotFound, 202 sectionPath))); 203 } 204 205 return retval; 206 } 207 208 /// Be sure to update UnsafeGetBindingCollectionElement if you modify this method GetBindingCollectionElement(string bindingCollectionName)209 internal static BindingCollectionElement GetBindingCollectionElement(string bindingCollectionName) 210 { 211 return GetAssociatedBindingCollectionElement(null, bindingCollectionName); 212 } 213 214 // Be sure to update GetBindingCollectionElement if you modify this method 215 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedBindingCollectionElement which elevates.")] 216 [SecurityCritical] UnsafeGetBindingCollectionElement(string bindingCollectionName)217 internal static BindingCollectionElement UnsafeGetBindingCollectionElement(string bindingCollectionName) 218 { 219 return UnsafeGetAssociatedBindingCollectionElement(null, bindingCollectionName); 220 } 221 GetBindingsSectionPath(string sectionName)222 internal static string GetBindingsSectionPath(string sectionName) 223 { 224 return string.Concat(ConfigurationStrings.BindingsSectionGroupPath, "/", sectionName); 225 } 226 GetEndpointsSectionPath(string sectionName)227 internal static string GetEndpointsSectionPath(string sectionName) 228 { 229 return string.Concat(ConfigurationStrings.StandardEndpointsSectionName, "/", sectionName); 230 } 231 232 /// Be sure to update UnsafeGetEndpointCollectionElement if you modify this method GetEndpointCollectionElement(string endpointCollectionName)233 internal static EndpointCollectionElement GetEndpointCollectionElement(string endpointCollectionName) 234 { 235 return GetAssociatedEndpointCollectionElement(null, endpointCollectionName); 236 } 237 238 // Be sure to update GetEndpointCollectionElement if you modify this method 239 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedEndpointCollectionElement which elevates.")] 240 [SecurityCritical] UnsafeGetEndpointCollectionElement(string endpointCollectionName)241 internal static EndpointCollectionElement UnsafeGetEndpointCollectionElement(string endpointCollectionName) 242 { 243 return UnsafeGetAssociatedEndpointCollectionElement(null, endpointCollectionName); 244 } 245 246 /// Be sure to update UnsafeGetSection if you modify this method GetSection(string sectionPath)247 internal static object GetSection(string sectionPath) 248 { 249 return GetAssociatedSection(null, sectionPath); 250 } 251 252 // Be sure to update GetSection if you modify this method 253 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedSection which elevates.")] 254 [SecurityCritical] UnsafeGetSection(string sectionPath)255 internal static object UnsafeGetSection(string sectionPath) 256 { 257 return UnsafeGetAssociatedSection(null, sectionPath); 258 } 259 260 // Be sure to update UnsafeGetSection if you modify this method 261 [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetAssociatedSection which elevates.")] 262 [SecurityCritical] UnsafeGetSectionNoTrace(string sectionPath)263 internal static object UnsafeGetSectionNoTrace(string sectionPath) 264 { 265 object retval = AspNetEnvironment.Current.UnsafeGetConfigurationSection(sectionPath); 266 267 if (retval == null) 268 { 269 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 270 new ConfigurationErrorsException(SR.GetString(SR.ConfigSectionNotFound, 271 sectionPath))); 272 } 273 274 return retval; 275 } 276 277 [Fx.Tag.SecurityNote(Critical = "Asserts ConfigurationPermission in order to fetch config from ContextInformation," 278 + "caller must guard return value.")] 279 [SecurityCritical] 280 [ConfigurationPermission(SecurityAction.Assert, Unrestricted = true)] UnsafeGetSectionFromContext(ContextInformation evalContext, string sectionPath)281 internal static object UnsafeGetSectionFromContext(ContextInformation evalContext, string sectionPath) 282 { 283 return evalContext.GetSection(sectionPath); 284 } 285 GetSectionPath(string sectionName)286 internal static string GetSectionPath(string sectionName) 287 { 288 return string.Concat(ConfigurationStrings.SectionGroupName, "/", sectionName); 289 } 290 291 [Fx.Tag.SecurityNote(Critical = "Calls SetIsPresentWithAssert which elevates in order to set a property." 292 + "Caller must guard ConfigurationElement parameter, ie only pass 'this'.")] 293 [SecurityCritical] SetIsPresent(ConfigurationElement element)294 internal static void SetIsPresent(ConfigurationElement element) 295 { 296 // Work around for VSW 578830: ConfigurationElements that override DeserializeElement cannot set ElementInformation.IsPresent 297 PropertyInfo elementPresent = element.GetType().GetProperty("ElementPresent", BindingFlags.Instance | BindingFlags.NonPublic); 298 SetIsPresentWithAssert(elementPresent, element, true); 299 } 300 301 [Fx.Tag.SecurityNote(Critical = "Asserts full trust in order to set a private member in the ConfigurationElement." 302 + "Caller must guard parameters.")] 303 [SecurityCritical] 304 [PermissionSet(SecurityAction.Assert, Unrestricted = true)] SetIsPresentWithAssert(PropertyInfo elementPresent, ConfigurationElement element, bool value)305 static void SetIsPresentWithAssert(PropertyInfo elementPresent, ConfigurationElement element, bool value) 306 { 307 elementPresent.SetValue(element, value, null); 308 } 309 GetEvaluationContext(IConfigurationContextProviderInternal provider)310 internal static ContextInformation GetEvaluationContext(IConfigurationContextProviderInternal provider) 311 { 312 if (provider != null) 313 { 314 try 315 { 316 return provider.GetEvaluationContext(); 317 } 318 catch (ConfigurationErrorsException) 319 { 320 } 321 } 322 return null; 323 } 324 325 [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - The return value will be used for a security decision. if in doubt about the return value, " 326 + "it is safe to return null (caller will assume the worst case from a security perspective).")] GetOriginalEvaluationContext(IConfigurationContextProviderInternal provider)327 internal static ContextInformation GetOriginalEvaluationContext(IConfigurationContextProviderInternal provider) 328 { 329 if (provider != null) 330 { 331 // provider may not need this try/catch, but it doesn't hurt to do it 332 try 333 { 334 return provider.GetOriginalEvaluationContext(); 335 } 336 catch (ConfigurationErrorsException) 337 { 338 } 339 } 340 return null; 341 } 342 TraceExtensionTypeNotFound(ExtensionElement extensionElement)343 internal static void TraceExtensionTypeNotFound(ExtensionElement extensionElement) 344 { 345 if (DiagnosticUtility.ShouldTraceWarning) 346 { 347 Dictionary<string, string> values = new Dictionary<string, string>(2); 348 values.Add("ExtensionName", extensionElement.Name); 349 values.Add("ExtensionType", extensionElement.Type); 350 351 DictionaryTraceRecord traceRecord = new DictionaryTraceRecord(values); 352 TraceUtility.TraceEvent(TraceEventType.Warning, 353 TraceCode.ExtensionTypeNotFound, 354 SR.GetString(SR.TraceCodeExtensionTypeNotFound), 355 traceRecord, 356 null, 357 (Exception)null); 358 } 359 } 360 } 361 362 interface IConfigurationContextProviderInternal 363 { 364 /// <summary> 365 /// return the current ContextInformation (the protected property ConfigurationElement.EvaluationContext) 366 /// this may throw ConfigurationErrorsException, caller should guard (see ConfigurationHelpers.GetEvaluationContext) 367 /// </summary> 368 /// <returns>result of ConfigurationElement.EvaluationContext</returns> GetEvaluationContext()369 ContextInformation GetEvaluationContext(); 370 371 /// <summary> 372 /// return the ContextInformation that was present when the ConfigurationElement was first deserialized. 373 /// if Reset was called, this will be the value of parent.GetOriginalEvaluationContext() 374 /// if Reset was not called, this will be the value of this.GetEvaluationContext() 375 /// </summary> 376 /// <returns>result of parent's ConfigurationElement.EvaluationContext</returns> 377 [Fx.Tag.SecurityNote(Miscellaneous = 378 "RequiresReview - the return value will be used for a security decision. if in doubt about the return value, it " 379 + "is safe (from a security perspective) to return null (caller will assume the worst case).")] GetOriginalEvaluationContext()380 ContextInformation GetOriginalEvaluationContext(); 381 } 382 383 [Fx.Tag.SecurityNote(Critical = "Stores information used in a security decision.")] 384 #pragma warning disable 618 // have not moved to the v4 security model yet 385 [SecurityCritical(SecurityCriticalScope.Everything)] 386 #pragma warning restore 618 387 struct EvaluationContextHelper 388 { 389 bool reset; 390 ContextInformation inheritedContext; 391 OnResetSystem.ServiceModel.Configuration.EvaluationContextHelper392 internal void OnReset(ConfigurationElement parent) 393 { 394 this.reset = true; 395 this.inheritedContext = ConfigurationHelpers.GetOriginalEvaluationContext(parent as IConfigurationContextProviderInternal); 396 } 397 GetOriginalContextSystem.ServiceModel.Configuration.EvaluationContextHelper398 internal ContextInformation GetOriginalContext(IConfigurationContextProviderInternal owner) 399 { 400 if (this.reset) 401 { 402 // if reset, inherited context is authoritative, even if null 403 return this.inheritedContext; 404 } 405 else 406 { 407 // otherwise use current 408 return ConfigurationHelpers.GetEvaluationContext(owner); 409 } 410 } 411 } 412 } 413