ConfigurationHelpers.cs 19 KB

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