ConfigLoader.cs 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Description
  5. {
  6. using System;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.Configuration;
  11. using System.Diagnostics;
  12. using System.IdentityModel.Selectors;
  13. using System.Reflection;
  14. using System.Runtime;
  15. using System.Runtime.Diagnostics;
  16. using System.Security;
  17. using System.Security.Cryptography.X509Certificates;
  18. using System.ServiceModel.Activation;
  19. using System.ServiceModel.Channels;
  20. using System.ServiceModel.Configuration;
  21. using System.ServiceModel.Diagnostics;
  22. using System.ServiceModel.Security;
  23. using System.Text;
  24. using System.Runtime.CompilerServices;
  25. class ConfigLoader
  26. {
  27. //resolvedBindings will be initialized to null on all threads
  28. //ThreadStatic gives each thread own copy of object
  29. [ThreadStatic]
  30. static List<string> resolvedBindings;
  31. //resolvedEndpoints will be initialized to null on all threads
  32. //ThreadStatic gives each thread own copy of object
  33. [ThreadStatic]
  34. static List<string> resolvedEndpoints;
  35. static readonly object[] emptyObjectArray = new object[] { };
  36. static readonly Type[] emptyTypeArray = new Type[] { };
  37. Dictionary<string, Binding> bindingTable;
  38. IContractResolver contractResolver;
  39. ContextInformation configurationContext;
  40. public ConfigLoader()
  41. : this((IContractResolver)null)
  42. {
  43. }
  44. public ConfigLoader(ContextInformation configurationContext)
  45. : this((IContractResolver)null)
  46. {
  47. this.configurationContext = configurationContext;
  48. }
  49. public ConfigLoader(IContractResolver contractResolver)
  50. {
  51. this.contractResolver = contractResolver;
  52. this.bindingTable = new Dictionary<string, Binding>();
  53. }
  54. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  55. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  56. [SecuritySafeCritical]
  57. internal static EndpointIdentity LoadIdentity(IdentityElement element)
  58. {
  59. EndpointIdentity identity = null;
  60. PropertyInformationCollection properties = element.ElementInformation.Properties;
  61. if (properties[ConfigurationStrings.UserPrincipalName].ValueOrigin != PropertyValueOrigin.Default)
  62. {
  63. identity = EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
  64. }
  65. else if (properties[ConfigurationStrings.ServicePrincipalName].ValueOrigin != PropertyValueOrigin.Default)
  66. {
  67. identity = EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
  68. }
  69. else if (properties[ConfigurationStrings.Dns].ValueOrigin != PropertyValueOrigin.Default)
  70. {
  71. identity = EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
  72. }
  73. else if (properties[ConfigurationStrings.Rsa].ValueOrigin != PropertyValueOrigin.Default)
  74. {
  75. identity = EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
  76. }
  77. else if (properties[ConfigurationStrings.Certificate].ValueOrigin != PropertyValueOrigin.Default)
  78. {
  79. X509Certificate2Collection collection = new X509Certificate2Collection();
  80. collection.Import(Convert.FromBase64String(element.Certificate.EncodedValue));
  81. if (collection.Count == 0)
  82. {
  83. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToLoadCertificateIdentity)));
  84. }
  85. // We assume the first certificate in the list is the primary
  86. // certificate.
  87. X509Certificate2 primaryCert = collection[0];
  88. collection.RemoveAt(0);
  89. identity = EndpointIdentity.CreateX509CertificateIdentity(primaryCert, collection);
  90. }
  91. else if (properties[ConfigurationStrings.CertificateReference].ValueOrigin != PropertyValueOrigin.Default)
  92. {
  93. X509CertificateStore store = new X509CertificateStore(element.CertificateReference.StoreName, element.CertificateReference.StoreLocation);
  94. X509Certificate2Collection collection = null;
  95. try
  96. {
  97. store.Open(OpenFlags.ReadOnly);
  98. collection = store.Find(element.CertificateReference.X509FindType, element.CertificateReference.FindValue, false);
  99. if (collection.Count == 0)
  100. {
  101. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToLoadCertificateIdentity)));
  102. }
  103. // Just select the first certificate.
  104. X509Certificate2 primaryCert = new X509Certificate2(collection[0]);
  105. if (element.CertificateReference.IsChainIncluded)
  106. {
  107. // Build the chain.
  108. X509Chain chain = new X509Chain();
  109. chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
  110. chain.Build(primaryCert);
  111. identity = EndpointIdentity.CreateX509CertificateIdentity(chain);
  112. }
  113. else
  114. {
  115. identity = EndpointIdentity.CreateX509CertificateIdentity(primaryCert);
  116. }
  117. }
  118. finally
  119. {
  120. SecurityUtils.ResetAllCertificates(collection);
  121. store.Close();
  122. }
  123. }
  124. return identity;
  125. }
  126. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  127. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  128. [SecuritySafeCritical]
  129. internal void LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, string configurationName)
  130. {
  131. ServiceEndpoint standardEndpoint;
  132. bool wildcard = IsWildcardMatch(configurationName);
  133. ChannelEndpointElement channelElement = LookupChannel(this.configurationContext, configurationName, serviceEndpoint.Contract, null, wildcard, false, out standardEndpoint);
  134. if (channelElement == null)
  135. {
  136. if (wildcard)
  137. {
  138. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigContractNotFound, serviceEndpoint.Contract.ConfigurationName)));
  139. }
  140. else
  141. {
  142. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigChannelConfigurationNotFound, configurationName, serviceEndpoint.Contract.ConfigurationName)));
  143. }
  144. }
  145. if (serviceEndpoint.Binding == null && !string.IsNullOrEmpty(channelElement.Binding))
  146. {
  147. serviceEndpoint.Binding = ConfigLoader.LookupBinding(channelElement.Binding, channelElement.BindingConfiguration, ConfigurationHelpers.GetEvaluationContext(channelElement));
  148. }
  149. if (serviceEndpoint.Address == null && channelElement.Address != null && channelElement.Address.OriginalString.Length > 0)
  150. {
  151. serviceEndpoint.Address = new EndpointAddress(channelElement.Address, LoadIdentity(channelElement.Identity), channelElement.Headers.Headers);
  152. }
  153. CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(ConfigurationHelpers.GetEvaluationContext(channelElement));
  154. if (commonBehaviors != null && commonBehaviors.EndpointBehaviors != null)
  155. {
  156. LoadBehaviors<IEndpointBehavior>(commonBehaviors.EndpointBehaviors, serviceEndpoint.Behaviors, true/*commonBehaviors*/);
  157. }
  158. EndpointBehaviorElement behaviorElement = ConfigLoader.LookupEndpointBehaviors(channelElement.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(channelElement));
  159. if (behaviorElement != null)
  160. {
  161. LoadBehaviors<IEndpointBehavior>(behaviorElement, serviceEndpoint.Behaviors, false/*commonBehaviors*/);
  162. }
  163. }
  164. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  165. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  166. [SecuritySafeCritical]
  167. internal void LoadCommonClientBehaviors(ServiceEndpoint serviceEndpoint)
  168. {
  169. // just load commonBehaviors
  170. CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(this.configurationContext);
  171. if (commonBehaviors != null && commonBehaviors.EndpointBehaviors != null)
  172. {
  173. LoadBehaviors<IEndpointBehavior>(commonBehaviors.EndpointBehaviors, serviceEndpoint.Behaviors, true/*commonBehaviors*/);
  174. }
  175. }
  176. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  177. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  178. [SecuritySafeCritical]
  179. static void LoadBehaviors<T>(ServiceModelExtensionCollectionElement<BehaviorExtensionElement> behaviorElement, KeyedByTypeCollection<T> behaviors, bool commonBehaviors)
  180. {
  181. Nullable<bool> isPT = new Nullable<bool>();
  182. KeyedByTypeCollection<T> tempBehaviors = new KeyedByTypeCollection<T>();
  183. for (int i = 0; i < behaviorElement.Count; i++)
  184. {
  185. BehaviorExtensionElement behaviorExtension = behaviorElement[i];
  186. object behaviorObject = behaviorExtension.CreateBehavior();
  187. if (behaviorObject == null)
  188. {
  189. continue;
  190. }
  191. Type type = behaviorObject.GetType();
  192. if (!typeof(T).IsAssignableFrom(type))
  193. {
  194. TraceBehaviorWarning(behaviorExtension, TraceCode.SkipBehavior, SR.GetString(SR.TraceCodeSkipBehavior), type, typeof(T));
  195. continue;
  196. }
  197. if (commonBehaviors)
  198. {
  199. if (ShouldSkipCommonBehavior(type, ref isPT))
  200. {
  201. TraceBehaviorWarning(behaviorExtension, TraceCode.SkipBehavior, SR.GetString(SR.TraceCodeSkipBehavior), type, typeof(T));
  202. continue;
  203. }
  204. }
  205. // if, at this scope, we try to add same type of behavior twice, throw
  206. tempBehaviors.Add((T)behaviorObject);
  207. // but if the same type of behavior was present from an old scope, just remove the old one
  208. if (behaviors.Contains(type))
  209. {
  210. TraceBehaviorWarning(behaviorExtension, TraceCode.RemoveBehavior, SR.GetString(SR.TraceCodeRemoveBehavior), type, typeof(T));
  211. behaviors.Remove(type);
  212. }
  213. behaviors.Add((T)behaviorObject);
  214. }
  215. }
  216. // special processing for common behaviors:
  217. // if:
  218. // 1. the behavior type (returned from the config element) is in a signed, non-APTCA assembly
  219. // 2. the caller stack does not have ConfigurationPermission(Unrestricted)
  220. // .. exclude the behavior from the collection and trace a warning
  221. [Fx.Tag.SecurityNote(Critical = "Calls SecurityCritical helpers, makes a security decision.")]
  222. [SecurityCritical]
  223. static bool ShouldSkipCommonBehavior(Type behaviorType, ref Nullable<bool> isPT)
  224. {
  225. bool skip = false;
  226. if (!isPT.HasValue)
  227. {
  228. if (!PartialTrustHelpers.IsTypeAptca(behaviorType))
  229. {
  230. isPT = !ThreadHasConfigurationPermission();
  231. skip = isPT.Value;
  232. }
  233. }
  234. else if (isPT.Value)
  235. {
  236. skip = !PartialTrustHelpers.IsTypeAptca(behaviorType);
  237. }
  238. return skip;
  239. }
  240. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  241. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  242. [SecuritySafeCritical]
  243. static void TraceBehaviorWarning(BehaviorExtensionElement behaviorExtension, int traceCode, string traceDescription, Type type, Type behaviorType)
  244. {
  245. if (DiagnosticUtility.ShouldTraceWarning)
  246. {
  247. Hashtable h = new Hashtable(3)
  248. {
  249. { "ConfigurationElementName", behaviorExtension.ConfigurationElementName },
  250. { "ConfigurationType", type.AssemblyQualifiedName },
  251. { "BehaviorType", behaviorType.AssemblyQualifiedName }
  252. };
  253. TraceUtility.TraceEvent(TraceEventType.Warning, traceCode, traceDescription,
  254. new DictionaryTraceRecord(h), null, null);
  255. }
  256. }
  257. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  258. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  259. [SecuritySafeCritical]
  260. static void LoadChannelBehaviors(EndpointBehaviorElement behaviorElement, KeyedByTypeCollection<IEndpointBehavior> channelBehaviors)
  261. {
  262. if (behaviorElement != null)
  263. {
  264. LoadBehaviors<IEndpointBehavior>(behaviorElement, channelBehaviors, false/*commonBehaviors*/
  265. );
  266. }
  267. }
  268. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  269. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  270. [SecuritySafeCritical]
  271. internal static void LoadChannelBehaviors(string behaviorName, ContextInformation context, KeyedByTypeCollection<IEndpointBehavior> channelBehaviors)
  272. {
  273. LoadChannelBehaviors(
  274. LookupEndpointBehaviors(behaviorName, context),
  275. channelBehaviors
  276. );
  277. }
  278. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  279. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  280. [SecuritySafeCritical]
  281. internal static Collection<IWsdlImportExtension> LoadWsdlImporters(WsdlImporterElementCollection wsdlImporterElements, ContextInformation context)
  282. {
  283. Collection<IWsdlImportExtension> wsdlImporters = new Collection<IWsdlImportExtension>();
  284. foreach (WsdlImporterElement wsdlImporterElement in wsdlImporterElements)
  285. {
  286. // Verify that the type implements IWsdlImporter
  287. Type wsdlImporterType = Type.GetType(wsdlImporterElement.Type, true, true);
  288. if (!typeof(IWsdlImportExtension).IsAssignableFrom(wsdlImporterType))
  289. {
  290. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidWsdlExtensionTypeInConfig, wsdlImporterType.AssemblyQualifiedName)));
  291. }
  292. // Verify that the type has a default constructor
  293. ConstructorInfo constructorInfo = wsdlImporterType.GetConstructor(emptyTypeArray);
  294. if (constructorInfo == null)
  295. {
  296. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlExtensionTypeRequiresDefaultConstructor, wsdlImporterType.AssemblyQualifiedName)));
  297. }
  298. wsdlImporters.Add((IWsdlImportExtension)constructorInfo.Invoke(emptyObjectArray));
  299. }
  300. return wsdlImporters;
  301. }
  302. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  303. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  304. [SecuritySafeCritical]
  305. internal static Collection<IPolicyImportExtension> LoadPolicyImporters(PolicyImporterElementCollection policyImporterElements, ContextInformation context)
  306. {
  307. Collection<IPolicyImportExtension> policyImporters = new Collection<IPolicyImportExtension>();
  308. foreach (PolicyImporterElement policyImporterElement in policyImporterElements)
  309. {
  310. // Verify that the type implements IPolicyImporter
  311. Type policyImporterType = Type.GetType(policyImporterElement.Type, true, true);
  312. if (!typeof(IPolicyImportExtension).IsAssignableFrom(policyImporterType))
  313. {
  314. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidPolicyExtensionTypeInConfig, policyImporterType.AssemblyQualifiedName)));
  315. }
  316. // Verify that the type has a default constructor
  317. ConstructorInfo constructorInfo = policyImporterType.GetConstructor(emptyTypeArray);
  318. if (constructorInfo == null)
  319. {
  320. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.PolicyExtensionTypeRequiresDefaultConstructor, policyImporterType.AssemblyQualifiedName)));
  321. }
  322. policyImporters.Add((IPolicyImportExtension)constructorInfo.Invoke(emptyObjectArray));
  323. }
  324. return policyImporters;
  325. }
  326. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  327. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  328. [SecuritySafeCritical]
  329. internal static EndpointAddress LoadEndpointAddress(EndpointAddressElementBase element)
  330. {
  331. return new EndpointAddress(element.Address, LoadIdentity(element.Identity), element.Headers.Headers);
  332. }
  333. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  334. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  335. [SecuritySafeCritical]
  336. public void LoadHostConfig(ServiceElement serviceElement, ServiceHostBase host, System.Action<Uri> addBaseAddress)
  337. {
  338. HostElement hostElement = serviceElement.Host;
  339. if (hostElement != null)
  340. {
  341. if (!AspNetEnvironment.Enabled)
  342. {
  343. foreach (BaseAddressElement bae in hostElement.BaseAddresses)
  344. {
  345. string cookedAddress = null;
  346. string rawAddress = bae.BaseAddress;
  347. int colonIndex = rawAddress.IndexOf(':');
  348. if (colonIndex != -1 && rawAddress.Length >= colonIndex + 4)
  349. {
  350. if (rawAddress[colonIndex + 1] == '/' &&
  351. rawAddress[colonIndex + 2] == '/' &&
  352. rawAddress[colonIndex + 3] == '*')
  353. {
  354. string beforeAsterisk = rawAddress.Substring(0, colonIndex + 3);
  355. string rest = rawAddress.Substring(colonIndex + 4);
  356. StringBuilder sb = new StringBuilder(beforeAsterisk);
  357. sb.Append(System.Net.Dns.GetHostName());
  358. sb.Append(rest);
  359. cookedAddress = sb.ToString();
  360. }
  361. }
  362. if (cookedAddress == null)
  363. {
  364. cookedAddress = rawAddress;
  365. }
  366. Uri uri;
  367. if (!Uri.TryCreate(cookedAddress, UriKind.Absolute, out uri))
  368. {
  369. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.BaseAddressMustBeAbsolute)));
  370. }
  371. addBaseAddress(uri);
  372. }
  373. }
  374. HostTimeoutsElement hte = hostElement.Timeouts;
  375. if (hte != null)
  376. {
  377. if (hte.OpenTimeout != TimeSpan.Zero)
  378. {
  379. host.OpenTimeout = hte.OpenTimeout;
  380. }
  381. if (hte.CloseTimeout != TimeSpan.Zero)
  382. {
  383. host.CloseTimeout = hte.CloseTimeout;
  384. }
  385. }
  386. }
  387. }
  388. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  389. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  390. [SecuritySafeCritical]
  391. public void LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, System.Action<Uri> addBaseAddress, bool skipHost = false)
  392. {
  393. CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(
  394. serviceElement == null ? null : ConfigurationHelpers.GetEvaluationContext(serviceElement));
  395. if (commonBehaviors != null && commonBehaviors.ServiceBehaviors != null)
  396. {
  397. LoadBehaviors<IServiceBehavior>(commonBehaviors.ServiceBehaviors, description.Behaviors, true/*commonBehaviors*/);
  398. }
  399. string behaviorConfigurationName = ConfigurationStrings.DefaultName;
  400. if (serviceElement != null)
  401. {
  402. if (!skipHost)
  403. {
  404. this.LoadHostConfig(serviceElement, host, addBaseAddress);
  405. }
  406. behaviorConfigurationName = serviceElement.BehaviorConfiguration;
  407. }
  408. ServiceBehaviorElement behaviorElement = ConfigLoader.LookupServiceBehaviors(behaviorConfigurationName, ConfigurationHelpers.GetEvaluationContext(serviceElement));
  409. if (behaviorElement != null)
  410. {
  411. LoadBehaviors<IServiceBehavior>(behaviorElement, description.Behaviors, false/*commonBehaviors*/);
  412. }
  413. ServiceHostBase.ServiceAndBehaviorsContractResolver resolver = this.contractResolver as ServiceHostBase.ServiceAndBehaviorsContractResolver;
  414. if (resolver != null)
  415. {
  416. resolver.AddBehaviorContractsToResolver(description.Behaviors);
  417. }
  418. if (serviceElement != null)
  419. {
  420. foreach (ServiceEndpointElement endpointElement in serviceElement.Endpoints)
  421. {
  422. if (String.IsNullOrEmpty(endpointElement.Kind))
  423. {
  424. ContractDescription contract = LookupContract(endpointElement.Contract, description.Name);
  425. // binding
  426. Binding binding;
  427. string bindingKey = endpointElement.Binding + ":" + endpointElement.BindingConfiguration;
  428. if (bindingTable.TryGetValue(bindingKey, out binding) == false)
  429. {
  430. binding = ConfigLoader.LookupBinding(endpointElement.Binding, endpointElement.BindingConfiguration, ConfigurationHelpers.GetEvaluationContext(serviceElement));
  431. bindingTable.Add(bindingKey, binding);
  432. }
  433. if (!string.IsNullOrEmpty(endpointElement.BindingName))
  434. {
  435. binding.Name = endpointElement.BindingName;
  436. }
  437. if (!string.IsNullOrEmpty(endpointElement.BindingNamespace))
  438. {
  439. binding.Namespace = endpointElement.BindingNamespace;
  440. }
  441. // address
  442. Uri address = endpointElement.Address;
  443. ServiceEndpoint serviceEndpoint;
  444. if (null == address)
  445. {
  446. serviceEndpoint = new ServiceEndpoint(contract);
  447. serviceEndpoint.Binding = binding;
  448. }
  449. else
  450. {
  451. Uri via = ServiceHost.MakeAbsoluteUri(address, binding, host.InternalBaseAddresses);
  452. serviceEndpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(via, LoadIdentity(endpointElement.Identity), endpointElement.Headers.Headers));
  453. serviceEndpoint.UnresolvedAddress = endpointElement.Address;
  454. }
  455. if (endpointElement.ListenUri != null)
  456. {
  457. serviceEndpoint.ListenUri = ServiceHost.MakeAbsoluteUri(endpointElement.ListenUri, binding, host.InternalBaseAddresses);
  458. serviceEndpoint.UnresolvedListenUri = endpointElement.ListenUri;
  459. }
  460. serviceEndpoint.ListenUriMode = endpointElement.ListenUriMode;
  461. if (!string.IsNullOrEmpty(endpointElement.Name))
  462. {
  463. serviceEndpoint.Name = endpointElement.Name;
  464. }
  465. KeyedByTypeCollection<IEndpointBehavior> behaviors = serviceEndpoint.Behaviors;
  466. EndpointBehaviorElement behaviorEndpointElement = ConfigLoader.LookupEndpointBehaviors(endpointElement.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(endpointElement));
  467. if (behaviorEndpointElement != null)
  468. {
  469. LoadBehaviors<IEndpointBehavior>(behaviorEndpointElement, behaviors, false/*commonBehaviors*/);
  470. }
  471. if (endpointElement.ElementInformation.Properties[ConfigurationStrings.IsSystemEndpoint].ValueOrigin != PropertyValueOrigin.Default)
  472. {
  473. serviceEndpoint.IsSystemEndpoint = endpointElement.IsSystemEndpoint;
  474. }
  475. description.Endpoints.Add(serviceEndpoint);
  476. }
  477. else
  478. {
  479. ServiceEndpoint endpoint = LookupEndpoint(endpointElement, ConfigurationHelpers.GetEvaluationContext(serviceElement), host, description);
  480. description.Endpoints.Add(endpoint);
  481. }
  482. }
  483. }
  484. }
  485. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  486. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  487. [SecuritySafeCritical]
  488. public static void LoadDefaultEndpointBehaviors(ServiceEndpoint endpoint)
  489. {
  490. EndpointBehaviorElement behaviorEndpointElement = ConfigLoader.LookupEndpointBehaviors(ConfigurationStrings.DefaultName, ConfigurationHelpers.GetEvaluationContext(null));
  491. if (behaviorEndpointElement != null)
  492. {
  493. LoadBehaviors<IEndpointBehavior>(behaviorEndpointElement, endpoint.Behaviors, false);
  494. }
  495. }
  496. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.")]
  497. [SecurityCritical]
  498. static EndpointCollectionElement LookupEndpointCollectionElement(string endpointSectionName, ContextInformation context)
  499. {
  500. if (string.IsNullOrEmpty(endpointSectionName))
  501. {
  502. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointTypeCannotBeNullOrEmpty)));
  503. }
  504. EndpointCollectionElement endpointCollectionElement = null;
  505. if (context == null)
  506. {
  507. // If no context is passed in, assume that the caller can consume the AppDomain's
  508. // current configuration file.
  509. endpointCollectionElement = (EndpointCollectionElement)ConfigurationHelpers.UnsafeGetEndpointCollectionElement(endpointSectionName);
  510. }
  511. else
  512. {
  513. // Use the configuration file associated with the passed in context.
  514. // This may or may not be the same as the file for the current AppDomain.
  515. endpointCollectionElement = (EndpointCollectionElement)ConfigurationHelpers.UnsafeGetAssociatedEndpointCollectionElement(context, endpointSectionName);
  516. }
  517. return endpointCollectionElement;
  518. }
  519. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  520. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  521. [SecuritySafeCritical]
  522. internal static ServiceEndpoint LookupEndpoint(string configurationName, EndpointAddress address, ContractDescription contract)
  523. {
  524. return LookupEndpoint(configurationName, address, contract, null);
  525. }
  526. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  527. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  528. [SecuritySafeCritical]
  529. internal static ServiceEndpoint LookupEndpoint(string configurationName, EndpointAddress address, ContractDescription contract, ContextInformation configurationContext)
  530. {
  531. bool wildcard = IsWildcardMatch(configurationName);
  532. ServiceEndpoint serviceEndpoint;
  533. LookupChannel(configurationContext, configurationName, contract, address, wildcard, true, out serviceEndpoint);
  534. return serviceEndpoint;
  535. }
  536. internal static ServiceEndpoint LookupEndpoint(ChannelEndpointElement channelEndpointElement, ContextInformation context)
  537. {
  538. return LookupEndpoint(channelEndpointElement, context, null /*address*/, null /*contractDescription*/);
  539. }
  540. // This method should only return null when endpointConfiguration is specified on the ChannelEndpointElement and no ChannelEndpointElement matching the
  541. // endpointConfiguration name is found. All other error conditions should throw.
  542. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  543. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  544. [SecuritySafeCritical]
  545. static ServiceEndpoint LookupEndpoint(ChannelEndpointElement channelEndpointElement, ContextInformation context, EndpointAddress address, ContractDescription contract)
  546. {
  547. EndpointCollectionElement endpointCollectionElement = LookupEndpointCollectionElement(channelEndpointElement.Kind, context);
  548. ServiceEndpoint retval = null;
  549. string endpointConfiguration = channelEndpointElement.EndpointConfiguration ?? String.Empty;
  550. // We are looking for a specific instance, not the default.
  551. bool configuredEndpointFound = false;
  552. // The Endpoints property is always public
  553. foreach (StandardEndpointElement standardEndpointElement in endpointCollectionElement.ConfiguredEndpoints)
  554. {
  555. if (standardEndpointElement.Name.Equals(endpointConfiguration, StringComparison.Ordinal))
  556. {
  557. if (null == ConfigLoader.resolvedEndpoints)
  558. {
  559. ConfigLoader.resolvedEndpoints = new List<string>();
  560. }
  561. string resolvedEndpointID = channelEndpointElement.Kind + "/" + endpointConfiguration;
  562. if (ConfigLoader.resolvedEndpoints.Contains(resolvedEndpointID))
  563. {
  564. ConfigurationElement configErrorElement = (ConfigurationElement)standardEndpointElement;
  565. System.Text.StringBuilder detectedCycle = new System.Text.StringBuilder();
  566. foreach (string resolvedEndpoint in ConfigLoader.resolvedEndpoints)
  567. {
  568. detectedCycle = detectedCycle.AppendFormat("{0}, ", resolvedEndpoint);
  569. }
  570. detectedCycle = detectedCycle.Append(resolvedEndpointID);
  571. // Clear list in case application is written to handle exception
  572. // by not starting up channel, etc...
  573. ConfigLoader.resolvedEndpoints = null;
  574. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointReferenceCycleDetected, detectedCycle.ToString()),
  575. configErrorElement.ElementInformation.Source,
  576. configErrorElement.ElementInformation.LineNumber));
  577. }
  578. try
  579. {
  580. CheckAccess(standardEndpointElement as IConfigurationContextProviderInternal);
  581. ConfigLoader.resolvedEndpoints.Add(resolvedEndpointID);
  582. ConfigureEndpoint(standardEndpointElement, channelEndpointElement, address, context, contract, out retval);
  583. ConfigLoader.resolvedEndpoints.Remove(resolvedEndpointID);
  584. }
  585. catch
  586. {
  587. // Clear list in case application is written to handle exception
  588. // by not starting up channel, etc...
  589. if (null != ConfigLoader.resolvedEndpoints)
  590. {
  591. ConfigLoader.resolvedBindings = null;
  592. }
  593. throw;
  594. }
  595. if (null != ConfigLoader.resolvedEndpoints &&
  596. 0 == ConfigLoader.resolvedEndpoints.Count)
  597. {
  598. ConfigLoader.resolvedEndpoints = null;
  599. }
  600. configuredEndpointFound = true;
  601. }
  602. }
  603. if (!configuredEndpointFound)
  604. {
  605. // We expected to find an instance, but didn't.
  606. // Return null.
  607. retval = null;
  608. }
  609. if (retval == null && String.IsNullOrEmpty(endpointConfiguration))
  610. {
  611. StandardEndpointElement standardEndpointElement = endpointCollectionElement.GetDefaultStandardEndpointElement();
  612. ConfigureEndpoint(standardEndpointElement, channelEndpointElement, address, context, contract, out retval);
  613. }
  614. if (DiagnosticUtility.ShouldTraceVerbose)
  615. {
  616. Dictionary<string, object> values = new Dictionary<string, object>(3);
  617. values["FoundEndpoint"] = retval != null;
  618. bool usingDefault = string.IsNullOrEmpty(endpointConfiguration);
  619. int traceCode;
  620. string traceDescription;
  621. if (usingDefault)
  622. {
  623. traceCode = TraceCode.GetDefaultConfiguredEndpoint;
  624. traceDescription = SR.GetString(SR.TraceCodeGetDefaultConfiguredEndpoint);
  625. }
  626. else
  627. {
  628. traceCode = TraceCode.GetConfiguredEndpoint;
  629. traceDescription = SR.GetString(SR.TraceCodeGetConfiguredEndpoint);
  630. values["Name"] = endpointConfiguration;
  631. }
  632. values["Endpoint"] = channelEndpointElement.Kind;
  633. TraceUtility.TraceEvent(TraceEventType.Verbose, traceCode, traceDescription,
  634. new DictionaryTraceRecord(values), null, null);
  635. }
  636. if (retval != null)
  637. {
  638. retval.IsFullyConfigured = true;
  639. }
  640. return retval;
  641. }
  642. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  643. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  644. [SecuritySafeCritical]
  645. static void ConfigureEndpoint(StandardEndpointElement standardEndpointElement, ChannelEndpointElement channelEndpointElement,
  646. EndpointAddress address, ContextInformation context, ContractDescription contract, out ServiceEndpoint endpoint)
  647. {
  648. // copy channelEndpointElement so that it can potentially be modified by the StandardEndpointElement
  649. // the properties collection of the instance seviceEndpointElement created by System.Configuration is read-only.
  650. // keeping original serviceEndpointElement so that its context can be used for the lookups.
  651. ChannelEndpointElement channelEndpointElementCopy = new ChannelEndpointElement();
  652. channelEndpointElementCopy.Copy(channelEndpointElement);
  653. standardEndpointElement.InitializeAndValidate(channelEndpointElementCopy);
  654. endpoint = standardEndpointElement.CreateServiceEndpoint(contract);
  655. if (endpoint == null)
  656. {
  657. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ConfigNoEndpointCreated, standardEndpointElement.GetType().AssemblyQualifiedName,
  658. (standardEndpointElement.EndpointType == null) ? string.Empty : standardEndpointElement.EndpointType.AssemblyQualifiedName)));
  659. }
  660. //binding
  661. if (!string.IsNullOrEmpty(channelEndpointElementCopy.Binding))
  662. {
  663. endpoint.Binding = ConfigLoader.LookupBinding(channelEndpointElementCopy.Binding, channelEndpointElementCopy.BindingConfiguration, ConfigurationHelpers.GetEvaluationContext(channelEndpointElement));
  664. }
  665. //name
  666. if (!string.IsNullOrEmpty(channelEndpointElementCopy.Name))
  667. {
  668. endpoint.Name = channelEndpointElementCopy.Name;
  669. }
  670. //address
  671. if (address != null)
  672. {
  673. endpoint.Address = address;
  674. }
  675. if (endpoint.Address == null && channelEndpointElementCopy.Address != null && channelEndpointElementCopy.Address.OriginalString.Length > 0)
  676. {
  677. endpoint.Address = new EndpointAddress(channelEndpointElementCopy.Address, LoadIdentity(channelEndpointElementCopy.Identity), channelEndpointElementCopy.Headers.Headers);
  678. }
  679. //behaviors
  680. CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(ConfigurationHelpers.GetEvaluationContext(channelEndpointElement));
  681. if (commonBehaviors != null && commonBehaviors.EndpointBehaviors != null)
  682. {
  683. LoadBehaviors<IEndpointBehavior>(commonBehaviors.EndpointBehaviors, endpoint.Behaviors, true/*commonBehaviors*/);
  684. }
  685. EndpointBehaviorElement behaviorElement = ConfigLoader.LookupEndpointBehaviors(channelEndpointElementCopy.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(channelEndpointElement));
  686. if (behaviorElement != null)
  687. {
  688. LoadBehaviors<IEndpointBehavior>(behaviorElement, endpoint.Behaviors, false/*commonBehaviors*/);
  689. }
  690. standardEndpointElement.ApplyConfiguration(endpoint, channelEndpointElementCopy);
  691. }
  692. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  693. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  694. [SecuritySafeCritical]
  695. internal ServiceEndpoint LookupEndpoint(ServiceEndpointElement serviceEndpointElement, ContextInformation context,
  696. ServiceHostBase host, ServiceDescription description, bool omitSettingEndpointAddress = false)
  697. {
  698. EndpointCollectionElement endpointCollectionElement = LookupEndpointCollectionElement(serviceEndpointElement.Kind, context);
  699. ServiceEndpoint retval = null;
  700. string endpointConfiguration = serviceEndpointElement.EndpointConfiguration ?? String.Empty;
  701. // We are looking for a specific instance, not the default.
  702. bool configuredEndpointFound = false;
  703. // The Endpoints property is always public
  704. foreach (StandardEndpointElement standardEndpointElement in endpointCollectionElement.ConfiguredEndpoints)
  705. {
  706. if (standardEndpointElement.Name.Equals(endpointConfiguration, StringComparison.Ordinal))
  707. {
  708. if (null == ConfigLoader.resolvedEndpoints)
  709. {
  710. ConfigLoader.resolvedEndpoints = new List<string>();
  711. }
  712. string resolvedEndpointID = serviceEndpointElement.Kind + "/" + endpointConfiguration;
  713. if (ConfigLoader.resolvedEndpoints.Contains(resolvedEndpointID))
  714. {
  715. ConfigurationElement configErrorElement = (ConfigurationElement)standardEndpointElement;
  716. System.Text.StringBuilder detectedCycle = new System.Text.StringBuilder();
  717. foreach (string resolvedEndpoint in ConfigLoader.resolvedEndpoints)
  718. {
  719. detectedCycle = detectedCycle.AppendFormat("{0}, ", resolvedEndpoint);
  720. }
  721. detectedCycle = detectedCycle.Append(resolvedEndpointID);
  722. // Clear list in case application is written to handle exception
  723. // by not starting up channel, etc...
  724. ConfigLoader.resolvedEndpoints = null;
  725. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigEndpointReferenceCycleDetected, detectedCycle.ToString()),
  726. configErrorElement.ElementInformation.Source,
  727. configErrorElement.ElementInformation.LineNumber));
  728. }
  729. try
  730. {
  731. CheckAccess(standardEndpointElement as IConfigurationContextProviderInternal);
  732. ConfigLoader.resolvedEndpoints.Add(resolvedEndpointID);
  733. ConfigureEndpoint(standardEndpointElement, serviceEndpointElement, context, host, description, out retval);
  734. ConfigLoader.resolvedEndpoints.Remove(resolvedEndpointID);
  735. }
  736. catch
  737. {
  738. // Clear list in case application is written to handle exception
  739. // by not starting up channel, etc...
  740. if (null != ConfigLoader.resolvedEndpoints)
  741. {
  742. ConfigLoader.resolvedBindings = null;
  743. }
  744. throw;
  745. }
  746. if (null != ConfigLoader.resolvedEndpoints &&
  747. 0 == ConfigLoader.resolvedEndpoints.Count)
  748. {
  749. ConfigLoader.resolvedEndpoints = null;
  750. }
  751. configuredEndpointFound = true;
  752. }
  753. }
  754. if (!configuredEndpointFound)
  755. {
  756. // We expected to find an instance, but didn't.
  757. // Return null.
  758. retval = null;
  759. }
  760. if (retval == null && String.IsNullOrEmpty(endpointConfiguration))
  761. {
  762. StandardEndpointElement standardEndpointElement = endpointCollectionElement.GetDefaultStandardEndpointElement();
  763. ConfigureEndpoint(standardEndpointElement, serviceEndpointElement, context, host, description, out retval, omitSettingEndpointAddress);
  764. }
  765. if (DiagnosticUtility.ShouldTraceVerbose)
  766. {
  767. Dictionary<string, object> values = new Dictionary<string, object>(3);
  768. values["FoundEndpoint"] = retval != null;
  769. bool usingDefault = string.IsNullOrEmpty(endpointConfiguration);
  770. int traceCode;
  771. string traceDescription;
  772. if (usingDefault)
  773. {
  774. traceCode = TraceCode.GetDefaultConfiguredEndpoint;
  775. traceDescription = SR.GetString(SR.TraceCodeGetDefaultConfiguredEndpoint);
  776. }
  777. else
  778. {
  779. traceCode = TraceCode.GetConfiguredEndpoint;
  780. traceDescription = SR.GetString(SR.TraceCodeGetConfiguredEndpoint);
  781. values["Name"] = endpointConfiguration;
  782. }
  783. values["Endpoint"] = serviceEndpointElement.Kind;
  784. TraceUtility.TraceEvent(TraceEventType.Verbose, traceCode, traceDescription,
  785. new DictionaryTraceRecord(values), null, null);
  786. }
  787. return retval;
  788. }
  789. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  790. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  791. [SecuritySafeCritical]
  792. void ConfigureEndpoint(StandardEndpointElement standardEndpointElement, ServiceEndpointElement serviceEndpointElement,
  793. ContextInformation context, ServiceHostBase host, ServiceDescription description, out ServiceEndpoint endpoint, bool omitSettingEndpointAddress = false)
  794. {
  795. // copy serviceEndpointElement so that it can potentially be modified by the StandardEndpointElement
  796. // the properties collection of the instance seviceEndpointElement created by System.Configuration is read-only.
  797. // keeping original serviceEndpointElement so that its context can be used to lookup endpoint behaviors.
  798. ServiceEndpointElement serviceEndpointElementCopy = new ServiceEndpointElement();
  799. serviceEndpointElementCopy.Copy(serviceEndpointElement);
  800. standardEndpointElement.InitializeAndValidate(serviceEndpointElementCopy);
  801. //contract
  802. ContractDescription contract = null;
  803. if (!string.IsNullOrEmpty(serviceEndpointElementCopy.Contract))
  804. {
  805. contract = LookupContractForStandardEndpoint(serviceEndpointElementCopy.Contract, description.Name);
  806. }
  807. endpoint = standardEndpointElement.CreateServiceEndpoint(contract);
  808. if (endpoint == null)
  809. {
  810. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ConfigNoEndpointCreated, standardEndpointElement.GetType().AssemblyQualifiedName,
  811. (standardEndpointElement.EndpointType == null) ? string.Empty : standardEndpointElement.EndpointType.AssemblyQualifiedName)));
  812. }
  813. //binding
  814. Binding binding = null;
  815. if (!string.IsNullOrEmpty(serviceEndpointElementCopy.Binding))
  816. {
  817. string bindingKey = serviceEndpointElementCopy.Binding + ":" + serviceEndpointElementCopy.BindingConfiguration;
  818. if (bindingTable.TryGetValue(bindingKey, out binding) == false)
  819. {
  820. binding = ConfigLoader.LookupBinding(serviceEndpointElementCopy.Binding, serviceEndpointElementCopy.BindingConfiguration, context);
  821. bindingTable.Add(bindingKey, binding);
  822. }
  823. }
  824. else
  825. {
  826. binding = endpoint.Binding;
  827. }
  828. if (binding != null)
  829. {
  830. if (!string.IsNullOrEmpty(serviceEndpointElementCopy.BindingName))
  831. {
  832. binding.Name = serviceEndpointElementCopy.BindingName;
  833. }
  834. if (!string.IsNullOrEmpty(serviceEndpointElementCopy.BindingNamespace))
  835. {
  836. binding.Namespace = serviceEndpointElementCopy.BindingNamespace;
  837. }
  838. endpoint.Binding = binding;
  839. if (!omitSettingEndpointAddress)
  840. {
  841. ConfigureEndpointAddress(serviceEndpointElementCopy, host, endpoint);
  842. ConfigureEndpointListenUri(serviceEndpointElementCopy, host, endpoint);
  843. }
  844. }
  845. //listenUriMode
  846. endpoint.ListenUriMode = serviceEndpointElementCopy.ListenUriMode;
  847. //name
  848. if (!string.IsNullOrEmpty(serviceEndpointElementCopy.Name))
  849. {
  850. endpoint.Name = serviceEndpointElementCopy.Name;
  851. }
  852. //behaviors
  853. KeyedByTypeCollection<IEndpointBehavior> behaviors = endpoint.Behaviors;
  854. EndpointBehaviorElement behaviorEndpointElement = ConfigLoader.LookupEndpointBehaviors(serviceEndpointElementCopy.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(serviceEndpointElement));
  855. if (behaviorEndpointElement != null)
  856. {
  857. LoadBehaviors<IEndpointBehavior>(behaviorEndpointElement, behaviors, false/*commonBehaviors*/);
  858. }
  859. //isSystemEndpoint
  860. if (serviceEndpointElementCopy.ElementInformation.Properties[ConfigurationStrings.IsSystemEndpoint].ValueOrigin != PropertyValueOrigin.Default)
  861. {
  862. endpoint.IsSystemEndpoint = serviceEndpointElementCopy.IsSystemEndpoint;
  863. }
  864. standardEndpointElement.ApplyConfiguration(endpoint, serviceEndpointElementCopy);
  865. }
  866. internal static void ConfigureEndpointAddress(ServiceEndpointElement serviceEndpointElement, ServiceHostBase host, ServiceEndpoint endpoint)
  867. {
  868. Fx.Assert(endpoint.Binding != null, "The endpoint must be set by the caller.");
  869. if (serviceEndpointElement.Address != null)
  870. {
  871. Uri via = ServiceHost.MakeAbsoluteUri(serviceEndpointElement.Address, endpoint.Binding, host.InternalBaseAddresses);
  872. endpoint.Address = new EndpointAddress(via, LoadIdentity(serviceEndpointElement.Identity), serviceEndpointElement.Headers.Headers);
  873. endpoint.UnresolvedAddress = serviceEndpointElement.Address;
  874. }
  875. }
  876. internal static void ConfigureEndpointListenUri(ServiceEndpointElement serviceEndpointElement, ServiceHostBase host, ServiceEndpoint endpoint)
  877. {
  878. Fx.Assert(endpoint.Binding != null, "The endpoint must be set by the caller.");
  879. if (serviceEndpointElement.ListenUri != null)
  880. {
  881. endpoint.ListenUri = ServiceHost.MakeAbsoluteUri(serviceEndpointElement.ListenUri, endpoint.Binding, host.InternalBaseAddresses);
  882. endpoint.UnresolvedListenUri = serviceEndpointElement.ListenUri;
  883. }
  884. }
  885. internal static Binding LookupBinding(string bindingSectionName, string configurationName)
  886. {
  887. return ConfigLoader.LookupBinding(bindingSectionName, configurationName, null);
  888. }
  889. internal static ComContractElement LookupComContract(Guid contractIID)
  890. {
  891. ComContractsSection comContracts = (ComContractsSection)ConfigurationHelpers.GetSection(ConfigurationStrings.ComContractsSectionPath);
  892. foreach (ComContractElement contract in comContracts.ComContracts)
  893. {
  894. Guid interfaceID;
  895. if (DiagnosticUtility.Utility.TryCreateGuid(contract.Contract, out interfaceID))
  896. {
  897. if (interfaceID == contractIID)
  898. {
  899. return contract;
  900. }
  901. }
  902. }
  903. return null;
  904. }
  905. /// <SecurityNote>
  906. /// Critical - handles config objects, which should not be leaked
  907. /// Safe - doesn't leak config objects out of SecurityCritical code
  908. /// </SecurityNote>
  909. [SecuritySafeCritical]
  910. internal static ProtocolMappingItem LookupProtocolMapping(String scheme)
  911. {
  912. ProtocolMappingSection protocolMapping = (ProtocolMappingSection)ConfigurationHelpers.UnsafeGetSection(ConfigurationStrings.ProtocolMappingSectionPath);
  913. foreach (ProtocolMappingElement pm in protocolMapping.ProtocolMappingCollection)
  914. {
  915. if (pm.Scheme == scheme)
  916. {
  917. return new ProtocolMappingItem(pm.Binding, pm.BindingConfiguration);
  918. }
  919. }
  920. return null;
  921. }
  922. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  923. [SecurityCritical]
  924. static BindingCollectionElement GetBindingCollectionElement(string bindingSectionName, ContextInformation context)
  925. {
  926. if (string.IsNullOrEmpty(bindingSectionName))
  927. {
  928. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingTypeCannotBeNullOrEmpty)));
  929. }
  930. if (context == null)
  931. {
  932. // If no context is passed in, assume that the caller can consume the AppDomain's
  933. // current configuration file.
  934. return (BindingCollectionElement)ConfigurationHelpers.UnsafeGetBindingCollectionElement(bindingSectionName);
  935. }
  936. else
  937. {
  938. // Use the configuration file associated with the passed in context.
  939. // This may or may not be the same as the file for the current AppDomain.
  940. return (BindingCollectionElement)ConfigurationHelpers.UnsafeGetAssociatedBindingCollectionElement(context, bindingSectionName);
  941. }
  942. }
  943. // This method should only return null when bindingConfiguration is specified on the BindingElement and no BindingElement matching the
  944. // bindingConfiguration name is found. All other error conditions should throw.
  945. [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.",
  946. Safe = "Doesn't leak config objects out of SecurityCritical code.")]
  947. [SecuritySafeCritical]
  948. internal static Binding LookupBinding(string bindingSectionName, string configurationName, ContextInformation context)
  949. {
  950. BindingCollectionElement bindingCollectionElement = GetBindingCollectionElement(bindingSectionName, context);
  951. Binding retval;
  952. if (configurationName == null)
  953. {
  954. retval = bindingCollectionElement.GetDefault();
  955. }
  956. else
  957. {
  958. Binding defaultBinding = bindingCollectionElement.GetDefault();
  959. retval = LookupBinding(bindingSectionName, configurationName, bindingCollectionElement, defaultBinding);
  960. if (retval == null && configurationName == ConfigurationStrings.DefaultName)
  961. {
  962. retval = defaultBinding;
  963. }
  964. }
  965. if (DiagnosticUtility.ShouldTraceVerbose)
  966. {
  967. Dictionary<string, object> values = new Dictionary<string, object>(3);
  968. values["FoundBinding"] = retval != null;
  969. bool usingDefault = string.IsNullOrEmpty(configurationName);
  970. int traceCode;
  971. string traceDescription;
  972. if (usingDefault)
  973. {
  974. traceCode = TraceCode.GetDefaultConfiguredBinding;
  975. traceDescription = SR.GetString(SR.TraceCodeGetDefaultConfiguredBinding);
  976. }
  977. else
  978. {
  979. traceCode = TraceCode.GetConfiguredBinding;
  980. traceDescription = SR.GetString(SR.TraceCodeGetConfiguredBinding);
  981. values["Name"] = string.IsNullOrEmpty(configurationName) ?
  982. SR.GetString(SR.Default) : configurationName;
  983. }
  984. values["Binding"] = bindingSectionName;
  985. TraceUtility.TraceEvent(TraceEventType.Verbose, traceCode, traceDescription,
  986. new DictionaryTraceRecord(values), null, null);
  987. }
  988. return retval;
  989. }
  990. static Binding LookupBinding(string bindingSectionName, string configurationName, BindingCollectionElement bindingCollectionElement, Binding defaultBinding)
  991. {
  992. Binding retval = defaultBinding;
  993. if (configurationName != null)
  994. {
  995. // We are looking for a specific instance, not the default.
  996. bool configuredBindingFound = false;
  997. // The Bindings property is always public
  998. foreach (object configElement in bindingCollectionElement.ConfiguredBindings)
  999. {
  1000. IBindingConfigurationElement bindingElement = configElement as IBindingConfigurationElement;
  1001. if (bindingElement != null)
  1002. {
  1003. if (bindingElement.Name.Equals(configurationName, StringComparison.Ordinal))
  1004. {
  1005. if (null == ConfigLoader.resolvedBindings)
  1006. {
  1007. ConfigLoader.resolvedBindings = new List<string>();
  1008. }
  1009. string resolvedBindingID = bindingSectionName + "/" + configurationName;
  1010. if (ConfigLoader.resolvedBindings.Contains(resolvedBindingID))
  1011. {
  1012. ConfigurationElement configErrorElement = (ConfigurationElement)configElement;
  1013. System.Text.StringBuilder detectedCycle = new System.Text.StringBuilder();
  1014. foreach (string resolvedBinding in ConfigLoader.resolvedBindings)
  1015. {
  1016. detectedCycle = detectedCycle.AppendFormat("{0}, ", resolvedBinding);
  1017. }
  1018. detectedCycle = detectedCycle.Append(resolvedBindingID);
  1019. // Clear list in case application is written to handle exception
  1020. // by not starting up channel, etc...
  1021. ConfigLoader.resolvedBindings = null;
  1022. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingReferenceCycleDetected, detectedCycle.ToString()),
  1023. configErrorElement.ElementInformation.Source,
  1024. configErrorElement.ElementInformation.LineNumber));
  1025. }
  1026. try
  1027. {
  1028. CheckAccess(configElement as IConfigurationContextProviderInternal);
  1029. ConfigLoader.resolvedBindings.Add(resolvedBindingID);
  1030. bindingElement.ApplyConfiguration(retval);
  1031. ConfigLoader.resolvedBindings.Remove(resolvedBindingID);
  1032. }
  1033. catch
  1034. {
  1035. // Clear list in case application is written to handle exception
  1036. // by not starting up channel, etc...
  1037. if (null != ConfigLoader.resolvedBindings)
  1038. {
  1039. ConfigLoader.resolvedBindings = null;
  1040. }
  1041. throw;
  1042. }
  1043. if (null != ConfigLoader.resolvedBindings &&
  1044. 0 == ConfigLoader.resolvedBindings.Count)
  1045. {
  1046. ConfigLoader.resolvedBindings = null;
  1047. }
  1048. configuredBindingFound = true;
  1049. }
  1050. }
  1051. }
  1052. if (!configuredBindingFound)
  1053. {
  1054. // We expected to find an instance, but didn't.
  1055. // Return null.
  1056. retval = null;
  1057. }
  1058. }
  1059. return retval;
  1060. }
  1061. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  1062. [SecurityCritical]
  1063. static EndpointBehaviorElement LookupEndpointBehaviors(string behaviorName, ContextInformation context)
  1064. {
  1065. EndpointBehaviorElement retval = null;
  1066. if (behaviorName != null)
  1067. {
  1068. if (DiagnosticUtility.ShouldTraceVerbose)
  1069. {
  1070. TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.GetBehaviorElement,
  1071. SR.GetString(SR.TraceCodeGetBehaviorElement),
  1072. new StringTraceRecord("BehaviorName", behaviorName), null, null);
  1073. }
  1074. BehaviorsSection behaviors = null;
  1075. if (context == null)
  1076. {
  1077. behaviors = BehaviorsSection.UnsafeGetSection();
  1078. }
  1079. else
  1080. {
  1081. behaviors = BehaviorsSection.UnsafeGetAssociatedSection(context);
  1082. }
  1083. if (behaviors.EndpointBehaviors.ContainsKey(behaviorName))
  1084. {
  1085. retval = behaviors.EndpointBehaviors[behaviorName];
  1086. }
  1087. }
  1088. if (retval != null)
  1089. {
  1090. CheckAccess(retval);
  1091. }
  1092. return retval;
  1093. }
  1094. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  1095. [SecurityCritical]
  1096. static ServiceBehaviorElement LookupServiceBehaviors(string behaviorName, ContextInformation context)
  1097. {
  1098. ServiceBehaviorElement retval = null;
  1099. if (behaviorName != null)
  1100. {
  1101. if (DiagnosticUtility.ShouldTraceVerbose)
  1102. {
  1103. TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.GetBehaviorElement,
  1104. SR.GetString(SR.TraceCodeGetBehaviorElement),
  1105. new StringTraceRecord("BehaviorName", behaviorName), null, null);
  1106. }
  1107. BehaviorsSection behaviors = null;
  1108. if (context == null)
  1109. {
  1110. behaviors = BehaviorsSection.UnsafeGetSection();
  1111. }
  1112. else
  1113. {
  1114. behaviors = BehaviorsSection.UnsafeGetAssociatedSection(context);
  1115. }
  1116. if (behaviors.ServiceBehaviors.ContainsKey(behaviorName))
  1117. {
  1118. retval = behaviors.ServiceBehaviors[behaviorName];
  1119. }
  1120. }
  1121. if (retval != null)
  1122. {
  1123. CheckAccess(retval);
  1124. }
  1125. return retval;
  1126. }
  1127. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  1128. [SecurityCritical]
  1129. static CommonBehaviorsSection LookupCommonBehaviors(ContextInformation context)
  1130. {
  1131. if (DiagnosticUtility.ShouldTraceVerbose)
  1132. {
  1133. TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.GetCommonBehaviors,
  1134. SR.GetString(SR.TraceCodeGetCommonBehaviors), (object)null);
  1135. }
  1136. return context == null
  1137. ? CommonBehaviorsSection.UnsafeGetSection()
  1138. : CommonBehaviorsSection.UnsafeGetAssociatedSection(context);
  1139. }
  1140. static bool IsChannelElementMatch(ChannelEndpointElement channelElement, ContractDescription contract, EndpointAddress address, bool useChannelElementKind, out ServiceEndpoint serviceEndpoint)
  1141. {
  1142. serviceEndpoint = null;
  1143. if (string.IsNullOrEmpty(channelElement.Kind))
  1144. {
  1145. return channelElement.Contract == contract.ConfigurationName;
  1146. }
  1147. if (useChannelElementKind)
  1148. {
  1149. serviceEndpoint = LookupEndpoint(channelElement, null, address, contract);
  1150. if (serviceEndpoint != null)
  1151. {
  1152. if (serviceEndpoint.Contract.ConfigurationName == contract.ConfigurationName &&
  1153. (string.IsNullOrEmpty(channelElement.Contract) || contract.ConfigurationName == channelElement.Contract))
  1154. {
  1155. return true;
  1156. }
  1157. else
  1158. {
  1159. serviceEndpoint = null;
  1160. return false;
  1161. }
  1162. }
  1163. else
  1164. {
  1165. return false; // this should not happen with a valid client section since serviceEndpoint will never be null.
  1166. }
  1167. }
  1168. else
  1169. {
  1170. // A standard endpoint should not be returned in the case of useChannelElementKind = false.
  1171. // This is because useChannelElementKind = false only when this method is called by
  1172. // LoadChannelBehaviors (the overload that takes a ServiceEndpoint and a string(configurationName)).
  1173. // LoadChannelBehaviors is called for the purposes of applying channel behaviors to a newly created service endpoint.
  1174. // In the case of standard endpoints, the service endpoints are already fully configured.
  1175. // Reapplying behaviors would not only be redundant but may cause exceptions to be thrown.
  1176. return false;
  1177. }
  1178. }
  1179. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  1180. [SecurityCritical]
  1181. static ChannelEndpointElement LookupChannel(ContextInformation configurationContext, string configurationName, ContractDescription contract,
  1182. EndpointAddress address, bool wildcard, bool useChannelElementKind, out ServiceEndpoint serviceEndpoint)
  1183. {
  1184. serviceEndpoint = null;
  1185. ClientSection clientSection = (configurationContext == null ? ClientSection.UnsafeGetSection() : ClientSection.UnsafeGetSection(configurationContext));
  1186. ChannelEndpointElement retval = null;
  1187. ServiceEndpoint standardEndpoint;
  1188. foreach (ChannelEndpointElement channelElement in clientSection.Endpoints)
  1189. {
  1190. if (IsChannelElementMatch(channelElement, contract, address, useChannelElementKind, out standardEndpoint))
  1191. {
  1192. if (channelElement.Name == configurationName || wildcard) // match name (or wildcard)
  1193. {
  1194. if (retval != null) // oops: >1
  1195. {
  1196. if (wildcard)
  1197. {
  1198. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigLoaderMultipleEndpointMatchesWildcard1, contract.ConfigurationName)));
  1199. }
  1200. else
  1201. {
  1202. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigLoaderMultipleEndpointMatchesSpecified2, contract.ConfigurationName, configurationName)));
  1203. }
  1204. }
  1205. retval = channelElement;
  1206. serviceEndpoint = standardEndpoint;
  1207. }
  1208. }
  1209. }
  1210. if (retval != null)
  1211. {
  1212. CheckAccess(retval);
  1213. }
  1214. if (DiagnosticUtility.ShouldTraceInformation)
  1215. {
  1216. Dictionary<string, object> values = new Dictionary<string, object>(8);
  1217. values["FoundChannelElement"] = retval != null;
  1218. values["Name"] = configurationName;
  1219. values["ContractName"] = contract.ConfigurationName;
  1220. if (null != retval)
  1221. {
  1222. if (!string.IsNullOrEmpty(retval.Binding))
  1223. {
  1224. values["Binding"] = retval.Binding;
  1225. }
  1226. if (!string.IsNullOrEmpty(retval.BindingConfiguration))
  1227. {
  1228. values["BindingConfiguration"] = retval.BindingConfiguration;
  1229. }
  1230. if (retval.Address != null)
  1231. {
  1232. values["RemoteEndpointUri"] = retval.Address.ToString();
  1233. }
  1234. if (!string.IsNullOrEmpty(retval.ElementInformation.Source))
  1235. {
  1236. values["ConfigurationFileSource"] = retval.ElementInformation.Source;
  1237. values["ConfigurationFileLineNumber"] = retval.ElementInformation.LineNumber;
  1238. }
  1239. }
  1240. TraceUtility.TraceEvent(TraceEventType.Information,
  1241. TraceCode.GetChannelEndpointElement,
  1242. SR.GetString(SR.TraceCodeGetChannelEndpointElement),
  1243. new DictionaryTraceRecord(values), null, null);
  1244. }
  1245. return retval;
  1246. }
  1247. internal ContractDescription LookupContract(string contractName, string serviceName)
  1248. {
  1249. ContractDescription contract = LookupContractForStandardEndpoint(contractName, serviceName);
  1250. if (contract == null)
  1251. {
  1252. if (contractName == String.Empty)
  1253. {
  1254. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFoundEmpty, serviceName)));
  1255. }
  1256. else
  1257. {
  1258. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFound2, contractName, serviceName)));
  1259. }
  1260. }
  1261. return contract;
  1262. }
  1263. internal ContractDescription LookupContractForStandardEndpoint(string contractName, string serviceName)
  1264. {
  1265. ContractDescription contract = contractResolver.ResolveContract(contractName);
  1266. if (contract == null)
  1267. {
  1268. if (contractName == ServiceMetadataBehavior.MexContractName)
  1269. {
  1270. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFoundIMetadataExchange, serviceName)));
  1271. }
  1272. }
  1273. return contract;
  1274. }
  1275. [Fx.Tag.SecurityNote(Critical = "Leaks config objects, caller must ensure that these don't leak to user code.")]
  1276. [SecurityCritical]
  1277. public ServiceElement LookupService(string serviceConfigurationName)
  1278. {
  1279. ServicesSection servicesSection = ServicesSection.UnsafeGetSection();
  1280. return LookupService(serviceConfigurationName, servicesSection);
  1281. }
  1282. public ServiceElement LookupService(string serviceConfigurationName, ServicesSection servicesSection)
  1283. {
  1284. ServiceElement retval = null;
  1285. ServiceElementCollection services = servicesSection.Services;
  1286. for (int i = 0; i < services.Count; i++)
  1287. {
  1288. ServiceElement serviceElement = services[i];
  1289. if (serviceElement.Name == serviceConfigurationName)
  1290. {
  1291. retval = serviceElement;
  1292. }
  1293. }
  1294. if (retval != null)
  1295. {
  1296. CheckAccess(retval);
  1297. }
  1298. if (DiagnosticUtility.ShouldTraceInformation)
  1299. {
  1300. TraceUtility.TraceEvent(TraceEventType.Information,
  1301. TraceCode.GetServiceElement,
  1302. SR.GetString(SR.TraceCodeGetServiceElement),
  1303. new ServiceConfigurationTraceRecord(retval), null, null);
  1304. }
  1305. return retval;
  1306. }
  1307. static bool IsWildcardMatch(string endpointConfigurationName)
  1308. {
  1309. return String.Equals(endpointConfigurationName, "*", StringComparison.Ordinal);
  1310. }
  1311. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - used in a security decision.")]
  1312. static bool IsConfigAboveApplication(ContextInformation contextInformation)
  1313. {
  1314. if (contextInformation != null)
  1315. {
  1316. if (contextInformation.IsMachineLevel)
  1317. {
  1318. return true;
  1319. }
  1320. bool isAppConfig = contextInformation.HostingContext is ExeContext;
  1321. if (isAppConfig)
  1322. {
  1323. return false; // for app.config, the only higher-scope config file is machine.config
  1324. }
  1325. else
  1326. {
  1327. return IsWebConfigAboveApplication(contextInformation);
  1328. }
  1329. }
  1330. return true; // err on the safe side: absent context information assume a PT app doesn't have access
  1331. }
  1332. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - used in a security decision.")]
  1333. [MethodImpl(MethodImplOptions.NoInlining)]
  1334. static bool IsWebConfigAboveApplication(ContextInformation contextInformation)
  1335. {
  1336. return AspNetEnvironment.Current.IsWebConfigAboveApplication(contextInformation.HostingContext);
  1337. }
  1338. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - enforces a security decision.")]
  1339. static void CheckAccess(IConfigurationContextProviderInternal element)
  1340. {
  1341. if (IsConfigAboveApplication(ConfigurationHelpers.GetOriginalEvaluationContext(element)))
  1342. {
  1343. ConfigurationPermission.Demand();
  1344. }
  1345. }
  1346. [Fx.Tag.SecurityNote(Critical = "Used in a security decision.")]
  1347. [SecurityCritical]
  1348. static ConfigurationPermission configurationPermission;
  1349. static ConfigurationPermission ConfigurationPermission
  1350. {
  1351. [Fx.Tag.SecurityNote(Critical = "Inits the configurationPermission field.",
  1352. Safe = "Safe for readonly access.")]
  1353. [SecuritySafeCritical]
  1354. get
  1355. {
  1356. if (configurationPermission == null)
  1357. {
  1358. configurationPermission = new ConfigurationPermission(System.Security.Permissions.PermissionState.Unrestricted);
  1359. }
  1360. return configurationPermission;
  1361. }
  1362. }
  1363. [Fx.Tag.SecurityNote(Critical = "Uses critical field configurationPermission.")]
  1364. [SecurityCritical]
  1365. static bool ThreadHasConfigurationPermission()
  1366. {
  1367. try
  1368. {
  1369. ConfigurationPermission.Demand();
  1370. }
  1371. catch (SecurityException)
  1372. {
  1373. return false;
  1374. }
  1375. return true;
  1376. }
  1377. }
  1378. class ProtocolMappingItem
  1379. {
  1380. public ProtocolMappingItem(string binding, string bindingConfiguration)
  1381. {
  1382. this.Binding = binding;
  1383. this.BindingConfiguration = bindingConfiguration;
  1384. }
  1385. public string Binding { get; set; }
  1386. public string BindingConfiguration { get; set; }
  1387. }
  1388. }