ConfigLoader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Description / ConfigLoader.cs / 2 / ConfigLoader.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Description 
{
    using System; 
    using System.Text; 
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher; 
    using System.Configuration;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ServiceModel; 
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Security; 
    using System.Security.Cryptography.X509Certificates; 
    using System.Collections;
    using System.Reflection; 

    using X509CertificateStore = System.IdentityModel.Selectors.X509CertificateStore;
    using System.Security;
    using System.Web.Configuration; 
    using System.Runtime.CompilerServices;
    using System.ServiceModel.Diagnostics; 
 
    internal class ConfigLoader
    { 
        //resolvedBindings will be initialized to null on all threads
        //ThreadStatic gives each thread own copy of object
        [ThreadStatic]
        static List resolvedBindings; 

        static readonly object[] emptyObjectArray = new object[] { }; 
        static readonly Type[] emptyTypeArray = new Type[] { }; 

        Dictionary bindingTable; 
        IContractResolver contractResolver;

        public ConfigLoader() : this(null)
        { 
        }
 
        public ConfigLoader(IContractResolver contractResolver) 
        {
            this.contractResolver = contractResolver; 
            this.bindingTable = new Dictionary();
        }

        ///  
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal static EndpointIdentity LoadIdentity(IdentityElement element) 
        {
            EndpointIdentity identity = null;

            PropertyInformationCollection properties = element.ElementInformation.Properties; 
            if (properties[ConfigurationStrings.UserPrincipalName].ValueOrigin != PropertyValueOrigin.Default)
            { 
                identity = EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value); 
            }
            else if (properties[ConfigurationStrings.ServicePrincipalName].ValueOrigin != PropertyValueOrigin.Default) 
            {
                identity = EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
            }
            else if (properties[ConfigurationStrings.Dns].ValueOrigin != PropertyValueOrigin.Default) 
            {
                identity = EndpointIdentity.CreateDnsIdentity(element.Dns.Value); 
            } 
            else if (properties[ConfigurationStrings.Rsa].ValueOrigin != PropertyValueOrigin.Default)
            { 
                identity = EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
            }
            else if (properties[ConfigurationStrings.Certificate].ValueOrigin != PropertyValueOrigin.Default)
            { 
                X509Certificate2Collection collection = new X509Certificate2Collection();
                collection.Import(Convert.FromBase64String(element.Certificate.EncodedValue)); 
 
                if (collection.Count == 0)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToLoadCertificateIdentity)));
                }

                // We assume the first certificate in the list is the primary 
                // certificate.
                X509Certificate2 primaryCert = collection[0]; 
                collection.RemoveAt(0); 
                identity = EndpointIdentity.CreateX509CertificateIdentity(primaryCert, collection);
            } 
            else if (properties[ConfigurationStrings.CertificateReference].ValueOrigin != PropertyValueOrigin.Default)
            {
                X509CertificateStore store = new X509CertificateStore(element.CertificateReference.StoreName, element.CertificateReference.StoreLocation);
                X509Certificate2Collection collection = null; 
                try
                { 
                    store.Open(OpenFlags.ReadOnly); 
                    collection = store.Find(element.CertificateReference.X509FindType, element.CertificateReference.FindValue, false);
 
                    if (collection.Count == 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToLoadCertificateIdentity)));
                    } 

                    // Just select the first certificate. 
                    X509Certificate2 primaryCert = new X509Certificate2(collection[0]); 
                    if (element.CertificateReference.IsChainIncluded)
                    { 
                        // Build the chain.
                        X509Chain chain = new X509Chain();
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                        chain.Build(primaryCert); 

                        identity = EndpointIdentity.CreateX509CertificateIdentity(chain); 
                    } 
                    else
                    { 
                        identity = EndpointIdentity.CreateX509CertificateIdentity(primaryCert);
                    }
                }
                finally 
                {
                    SecurityUtils.ResetAllCertificates(collection); 
                    store.Close(); 
                }
            } 

            return identity;
        }
 
        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, string configurationName)
        {
            bool wildcard = IsWildcardMatch(configurationName);
            ChannelEndpointElement channelElement = LookupChannel(configurationName, serviceEndpoint.Contract.ConfigurationName, wildcard); 
            if (channelElement == null)
            { 
                if (wildcard) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigContractNotFound, serviceEndpoint.Contract.ConfigurationName))); 
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigChannelConfigurationNotFound, configurationName, serviceEndpoint.Contract.ConfigurationName))); 
                }
            } 
 
            if (serviceEndpoint.Binding == null && !string.IsNullOrEmpty(channelElement.Binding))
            { 
                serviceEndpoint.Binding = ConfigLoader.LookupBinding(channelElement.Binding, channelElement.BindingConfiguration, ConfigurationHelpers.GetEvaluationContext(channelElement));
            }

            if (serviceEndpoint.Address == null && channelElement.Address != null && channelElement.Address.OriginalString.Length > 0) 
            {
                serviceEndpoint.Address = new EndpointAddress(channelElement.Address, LoadIdentity(channelElement.Identity), channelElement.Headers.Headers); 
            } 

            CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(ConfigurationHelpers.GetEvaluationContext(channelElement)); 
            if (commonBehaviors != null && commonBehaviors.EndpointBehaviors != null)
            {
                LoadBehaviors(commonBehaviors.EndpointBehaviors, serviceEndpoint.Behaviors, true/*commonBehaviors*/);
            } 

            EndpointBehaviorElement behaviorElement = ConfigLoader.LookupEndpointBehaviors(channelElement.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(channelElement)); 
            if (behaviorElement != null) 
            {
                LoadBehaviors(behaviorElement, serviceEndpoint.Behaviors, false/*commonBehaviors*/); 
            }
        }

        ///  
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal void LoadCommonClientBehaviors(ServiceEndpoint serviceEndpoint) 
        {
            // just load commonBehaviors
            CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(null);
            if (commonBehaviors != null && commonBehaviors.EndpointBehaviors != null) 
            {
                LoadBehaviors(commonBehaviors.EndpointBehaviors, serviceEndpoint.Behaviors, true/*commonBehaviors*/); 
            } 
        }
 
        /// 
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        static void LoadBehaviors(ServiceModelExtensionCollectionElement behaviorElement, KeyedByTypeCollection behaviors, bool commonBehaviors) 
        { 
            Nullable isPT = new Nullable();
 
            KeyedByTypeCollection tempBehaviors = new KeyedByTypeCollection();
            for (int i = 0; i < behaviorElement.Count; i++)
            {
                BehaviorExtensionElement behaviorExtension = behaviorElement[i]; 

                object behaviorObject = behaviorExtension.CreateBehavior(); 
                if (behaviorObject == null) 
                {
                    continue; 
                }

                Type type = behaviorObject.GetType();
                if (!typeof(T).IsAssignableFrom(type)) 
                {
                    TraceBehaviorWarning(behaviorExtension, TraceCode.SkipBehavior, type, typeof(T)); 
                    continue; 
                }
 
                if (commonBehaviors)
                {
                    if (ShouldSkipCommonBehavior(type, ref isPT))
                    { 
                        TraceBehaviorWarning(behaviorExtension, TraceCode.SkipBehavior, type, typeof(T));
                        continue; 
                    } 
                }
 
                // if, at this scope, we try to add same type of behavior twice, throw
                tempBehaviors.Add((T)behaviorObject);
                // but if the same type of behavior was present from an old scope, just remove the old one
                if (behaviors.Contains(type)) 
                {
                    TraceBehaviorWarning(behaviorExtension, TraceCode.RemoveBehavior, type, typeof(T)); 
                    behaviors.Remove(type); 
                }
                behaviors.Add((T)behaviorObject); 
            }
        }

        // special processing for common behaviors: 
        // if:
        //   1. the behavior type (returned from the config element) is in a signed, non-APTCA assembly 
        //   2. the caller stack does not have ConfigurationPermission(Unrestricted) 
        // .. exclude the behavior from the collection and trace a warning
 
        /// 
        /// Critical - calls SecurityCritical helpers, makes a security decision
        /// 
        [SecurityCritical] 
        static bool ShouldSkipCommonBehavior(Type behaviorType, ref Nullable isPT)
        { 
            bool skip = false; 

            if (!isPT.HasValue) 
            {
                if (!PartialTrustHelpers.IsTypeAptca(behaviorType))
                {
                    isPT = !ThreadHasConfigurationPermission(); 
                    skip = isPT.Value;
                } 
            } 
            else if (isPT.Value)
            { 
                skip = !PartialTrustHelpers.IsTypeAptca(behaviorType);
            }

            return skip; 
        }
 
        ///  
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private static void TraceBehaviorWarning(BehaviorExtensionElement behaviorExtension, TraceCode traceCode, Type type, Type behaviorType)
        { 
            if (DiagnosticUtility.ShouldTraceWarning)
            { 
                Hashtable h = new Hashtable(3); 
                h.Add("ConfigurationElementName", behaviorExtension.ConfigurationElementName);
                h.Add("ConfigurationType", type.AssemblyQualifiedName); 
                h.Add("BehaviorType", behaviorType.AssemblyQualifiedName);
                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Warning,
                                    traceCode,
                                    new DictionaryTraceRecord(h), null, null); 
            }
        } 
 
        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        static void LoadChannelBehaviors(EndpointBehaviorElement behaviorElement, KeyedByTypeCollection channelBehaviors) 
        {
            if (behaviorElement != null) 
            { 
                LoadBehaviors(behaviorElement, channelBehaviors, false/*commonBehaviors*/
                                                                                                                               ); 
            }
        }

        ///  
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal static void LoadChannelBehaviors(string behaviorName, ContextInformation context, KeyedByTypeCollection channelBehaviors) 
        {
            LoadChannelBehaviors(
                LookupEndpointBehaviors(behaviorName, context),
                channelBehaviors 
            );
        } 
 
        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal static Collection LoadWsdlImporters(WsdlImporterElementCollection wsdlImporterElements, ContextInformation context) 
        {
            Collection wsdlImporters = new Collection(); 
 
            foreach (WsdlImporterElement wsdlImporterElement in wsdlImporterElements)
            { 
                // Verify that the type implements IWsdlImporter
                Type wsdlImporterType = Type.GetType(wsdlImporterElement.Type, true, true);
                if (!typeof(IWsdlImportExtension).IsAssignableFrom(wsdlImporterType))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidWsdlExtensionTypeInConfig, wsdlImporterType.AssemblyQualifiedName)));
                } 
 
                // Verify that the type has a default constructor
                ConstructorInfo constructorInfo = wsdlImporterType.GetConstructor(emptyTypeArray); 
                if(constructorInfo == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlExtensionTypeRequiresDefaultConstructor, wsdlImporterType.AssemblyQualifiedName)));
                } 

                wsdlImporters.Add((IWsdlImportExtension)constructorInfo.Invoke(emptyObjectArray)); 
            } 

            return wsdlImporters; 
        }

        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static Collection LoadPolicyImporters(PolicyImporterElementCollection policyImporterElements, ContextInformation context)
        { 
            Collection policyImporters = new Collection();

            foreach (PolicyImporterElement policyImporterElement in policyImporterElements)
            { 
                // Verify that the type implements IPolicyImporter
                Type policyImporterType = Type.GetType(policyImporterElement.Type, true, true); 
                if (!typeof(IPolicyImportExtension).IsAssignableFrom(policyImporterType)) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidPolicyExtensionTypeInConfig, policyImporterType.AssemblyQualifiedName))); 
                }

                // Verify that the type has a default constructor
                ConstructorInfo constructorInfo = policyImporterType.GetConstructor(emptyTypeArray); 
                if (constructorInfo == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.PolicyExtensionTypeRequiresDefaultConstructor, policyImporterType.AssemblyQualifiedName))); 
                }
 
                policyImporters.Add((IPolicyImportExtension)constructorInfo.Invoke(emptyObjectArray));
            }

            return policyImporters; 
        }
 
        ///  
        /// Critical - handles config objects, which should not be leaked
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal static EndpointAddress LoadEndpointAddress(EndpointAddressElementBase element)
        { 
            return new EndpointAddress(element.Address, LoadIdentity(element.Identity), element.Headers.Headers);
        } 
 
        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        void LoadHostConfig(ServiceElement serviceElement, ServiceHostBase host, System.Action addBaseAddress) 
        {
            HostElement hostElement = serviceElement.Host; 
            if (hostElement != null) 
            {
                if (!ServiceHostingEnvironment.IsHosted) 
                {
                    foreach (BaseAddressElement bae in hostElement.BaseAddresses)
                    {
                        string cookedAddress = null; 
                        string rawAddress = bae.BaseAddress;
                        int colonIndex = rawAddress.IndexOf(':'); 
                        if (colonIndex != -1 && rawAddress.Length >= colonIndex+4) 
                        {
                            if (rawAddress[colonIndex+1] == '/' && 
                                rawAddress[colonIndex+2] == '/' &&
                                rawAddress[colonIndex+3] == '*')
                            {
                                string beforeAsterisk = rawAddress.Substring(0,colonIndex+3); 
                                string rest = rawAddress.Substring(colonIndex+4);
                                StringBuilder sb = new StringBuilder(beforeAsterisk); 
                                sb.Append(System.Net.Dns.GetHostName()); 
                                sb.Append(rest);
                                cookedAddress = sb.ToString(); 
                            }
                        }
                        if (cookedAddress == null)
                        { 
                            cookedAddress = rawAddress;
                        } 
                        Uri uri; 
                        if (!Uri.TryCreate(cookedAddress, UriKind.Absolute, out uri))
                        { 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.BaseAddressMustBeAbsolute)));
                        }
                        addBaseAddress(uri);
                    } 
                }
                HostTimeoutsElement hte = hostElement.Timeouts; 
                if (hte != null) 
                {
                    if (hte.OpenTimeout != TimeSpan.Zero) 
                    {
                        host.OpenTimeout = hte.OpenTimeout;
                    }
                    if (hte.CloseTimeout != TimeSpan.Zero) 
                    {
                        host.CloseTimeout = hte.CloseTimeout; 
                    } 
                }
            } 
        }

        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        public void LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, System.Action addBaseAddress)
        { 
            CommonBehaviorsSection commonBehaviors = ConfigLoader.LookupCommonBehaviors(
                serviceElement == null ? null : ConfigurationHelpers.GetEvaluationContext(serviceElement));
            if (commonBehaviors != null && commonBehaviors.ServiceBehaviors != null)
            { 
                LoadBehaviors(commonBehaviors.ServiceBehaviors, description.Behaviors, true/*commonBehaviors*/);
            } 
 
            if (serviceElement != null)
            { 
                this.LoadHostConfig(serviceElement, host, addBaseAddress);
                ServiceBehaviorElement behaviorElement = ConfigLoader.LookupServiceBehaviors(serviceElement.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(serviceElement));
                if (behaviorElement != null)
                { 
                    LoadBehaviors(behaviorElement, description.Behaviors, false/*commonBehaviors*/);
                } 
 
                ServiceHostBase.ServiceAndBehaviorsContractResolver resolver = this.contractResolver as ServiceHostBase.ServiceAndBehaviorsContractResolver;
                if (resolver != null) 
                {
                    resolver.AddBehaviorContractsToResolver(description.Behaviors);
                }
 
                foreach (ServiceEndpointElement endpointElement in serviceElement.Endpoints)
                { 
                    ContractDescription contract = LookupContract(endpointElement.Contract, description.Name); 

                    // binding 
                    Binding binding;
                    string bindingKey = endpointElement.Binding + ":" + endpointElement.BindingConfiguration;
                    if (bindingTable.TryGetValue(bindingKey, out binding) == false)
                    { 
                        binding = ConfigLoader.LookupBinding(endpointElement.Binding, endpointElement.BindingConfiguration, ConfigurationHelpers.GetEvaluationContext(serviceElement));
                        bindingTable.Add(bindingKey, binding); 
                    } 

                    if (!string.IsNullOrEmpty(endpointElement.BindingName)) 
                    {
                        binding.Name = endpointElement.BindingName;
                    }
                    if (!string.IsNullOrEmpty(endpointElement.BindingNamespace)) 
                    {
                        binding.Namespace = endpointElement.BindingNamespace; 
                    } 

                    // address 
                    Uri address = endpointElement.Address;

                    ServiceEndpoint serviceEndpoint;
                    if (null == address) 
                    {
                        serviceEndpoint = new ServiceEndpoint(contract); 
                        serviceEndpoint.Binding = binding; 
                    }
                    else 
                    {
                        Uri via = ServiceHost.MakeAbsoluteUri(address, binding, host.InternalBaseAddresses);
                        serviceEndpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(via, LoadIdentity(endpointElement.Identity), endpointElement.Headers.Headers));
                    } 
                    if (endpointElement.ListenUri != null)
                    { 
                        serviceEndpoint.ListenUri = ServiceHost.MakeAbsoluteUri(endpointElement.ListenUri, binding, host.InternalBaseAddresses); 
                    }
                    serviceEndpoint.ListenUriMode = endpointElement.ListenUriMode; 

                    if (!string.IsNullOrEmpty(endpointElement.Name))
                    {
                        serviceEndpoint.Name = endpointElement.Name; 
                    }
 
                    KeyedByTypeCollection behaviors = serviceEndpoint.Behaviors; 

                    EndpointBehaviorElement behaviorEndpointElement = ConfigLoader.LookupEndpointBehaviors(endpointElement.BehaviorConfiguration, ConfigurationHelpers.GetEvaluationContext(endpointElement)); 
                    if (behaviorEndpointElement != null)
                    {
                        LoadBehaviors(behaviorEndpointElement, behaviors, false/*commonBehaviors*/);
                    } 
                    description.Endpoints.Add(serviceEndpoint);
                } 
            } 
        }
 
        internal static Binding LookupBinding(string bindingSectionName, string configurationName)
        {
            return ConfigLoader.LookupBinding(bindingSectionName, configurationName, null);
        } 

        internal static ComContractElement LookupComContract(Guid contractIID) 
        { 
            ComContractsSection comContracts = (ComContractsSection)ConfigurationHelpers.GetSection(ConfigurationStrings.ComContractsSectionPath);
            foreach (ComContractElement contract in comContracts.ComContracts) 
            {
                Guid interfaceID;
                if ( DiagnosticUtility.Utility.TryCreateGuid(contract.Contract, out interfaceID))
                { 
                    if (interfaceID == contractIID)
                    { 
                        return contract; 
                    }
                } 
            }
            return null;
        }
 
        /// 
        /// Critical - handles config objects, which should not be leaked 
        /// Safe - doesn't leak config objects out of SecurityCritical code 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static Binding LookupBinding(string bindingSectionName, string configurationName, ContextInformation context)
        {
            if (string.IsNullOrEmpty(bindingSectionName))
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingTypeCannotBeNullOrEmpty)));
            } 
            BindingCollectionElement bindingCollectionElement = null; 
            if (context == null)
            { 
                // If no context is passed in, assume that the caller can consume the AppDomain's
                // current configuration file.
                bindingCollectionElement = (BindingCollectionElement)ConfigurationHelpers.UnsafeGetBindingCollectionElement(bindingSectionName);
            } 
            else
            { 
                // Use the configuration file associated with the passed in context. 
                // This may or may not be the same as the file for the current AppDomain.
                bindingCollectionElement = (BindingCollectionElement)ConfigurationHelpers.UnsafeGetAssociatedBindingCollectionElement(context, bindingSectionName); 
            }
            Binding retval = bindingCollectionElement.GetDefault();
            if (!string.IsNullOrEmpty(configurationName))
            { 
                // We are looking for a specific instance, not the default.
                bool configuredBindingFound = false; 
                // The Bindings property is always public 
                foreach (object configElement in bindingCollectionElement.ConfiguredBindings)
                { 
                    IBindingConfigurationElement bindingElement = configElement as IBindingConfigurationElement;
                    if (bindingElement != null)
                    {
                        if (bindingElement.Name.Equals(configurationName, StringComparison.Ordinal)) 
                        {
                            if (null == ConfigLoader.resolvedBindings) 
                            { 
                                ConfigLoader.resolvedBindings = new List();
                            } 

                            string resolvedBindingID = bindingSectionName + "/" + configurationName;
                            if (ConfigLoader.resolvedBindings.Contains(resolvedBindingID))
                            { 
                                ConfigurationElement configErrorElement = (ConfigurationElement)configElement;
                                System.Text.StringBuilder detectedCycle = new System.Text.StringBuilder(); 
                                foreach (string resolvedBinding in ConfigLoader.resolvedBindings) 
                                {
                                    detectedCycle = detectedCycle.AppendFormat("{0}, ", resolvedBinding); 
                                }

                                detectedCycle = detectedCycle.Append(resolvedBindingID);
 
                                // Clear list in case application is written to handle exception
                                // by not starting up channel, etc... 
                                ConfigLoader.resolvedBindings = null; 

                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigBindingReferenceCycleDetected, detectedCycle.ToString()), 
                                    configErrorElement.ElementInformation.Source,
                                    configErrorElement.ElementInformation.LineNumber));
                            }
 
                            try
                            { 
                                CheckAccess(configElement as IConfigurationContextProviderInternal); 

                                ConfigLoader.resolvedBindings.Add(resolvedBindingID); 
                                bindingElement.ApplyConfiguration(retval);
                                ConfigLoader.resolvedBindings.Remove(resolvedBindingID);
                            }
                            catch 
                            {
                                // Clear list in case application is written to handle exception 
                                // by not starting up channel, etc... 
                                if (null != ConfigLoader.resolvedBindings)
                                { 
                                    ConfigLoader.resolvedBindings = null;
                                }
                                throw;
                            } 

                            if (null != ConfigLoader.resolvedBindings && 
                                0 == ConfigLoader.resolvedBindings.Count) 
                            {
                                ConfigLoader.resolvedBindings = null; 
                            }

                            configuredBindingFound = true;
                        } 
                    }
                } 
                if (!configuredBindingFound) 
                {
                    // We expected to find an instance, but didn't. 
                    // Return null.
                    retval = null;
                }
            } 

            if (DiagnosticUtility.ShouldTraceVerbose) 
            { 
                Dictionary values = new Dictionary(3);
                values["FoundBinding"] = retval != null; 
                bool usingDefault = string.IsNullOrEmpty(configurationName);
                TraceCode traceCode = TraceCode.GetConfiguredBinding;
                if (usingDefault)
                { 
                    traceCode = TraceCode.GetDefaultConfiguredBinding;
                } 
                else 
                {
                    values["Name"] = string.IsNullOrEmpty(configurationName) ? 
                        SR.GetString(SR.Default) : configurationName;
                }
                values["Binding"] = bindingSectionName;
                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 
                    traceCode,
                    new DictionaryTraceRecord(values), null, null); 
            } 
            return retval;
        } 

        /// 
        /// Critical - leaks config objects, caller must ensure that these don't leak to user code
        ///  
        [SecurityCritical]
        static EndpointBehaviorElement LookupEndpointBehaviors(string behaviorName, ContextInformation context) 
        { 
            EndpointBehaviorElement retval = null;
            if (!string.IsNullOrEmpty(behaviorName)) 
            {
                if (DiagnosticUtility.ShouldTraceVerbose)
                {
                    TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 
                        TraceCode.GetBehaviorElement,
                        new StringTraceRecord("BehaviorName", behaviorName), null, null); 
                } 
                BehaviorsSection behaviors = null;
                if (context == null) 
                {
                    behaviors = BehaviorsSection.UnsafeGetSection();
                }
                else 
                {
                    behaviors = BehaviorsSection.UnsafeGetAssociatedSection(context); 
                } 
                if (behaviors.EndpointBehaviors.ContainsKey(behaviorName))
                { 
                    retval = behaviors.EndpointBehaviors[behaviorName];
                }
            }
            if (retval != null) 
            {
                CheckAccess(retval); 
            } 
            return retval;
        } 

        /// 
        /// Critical - leaks config objects, caller must ensure that these don't leak to user code
        ///  
        [SecurityCritical]
        static ServiceBehaviorElement LookupServiceBehaviors(string behaviorName, ContextInformation context) 
        { 
            ServiceBehaviorElement retval = null;
            if (!string.IsNullOrEmpty(behaviorName)) 
            {
                if (DiagnosticUtility.ShouldTraceVerbose)
                {
                    TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 
                        TraceCode.GetBehaviorElement,
                        new StringTraceRecord("BehaviorName", behaviorName), null, null); 
                } 
                BehaviorsSection behaviors = null;
                if (context == null) 
                {
                    behaviors = BehaviorsSection.UnsafeGetSection();
                }
                else 
                {
                    behaviors = BehaviorsSection.UnsafeGetAssociatedSection(context); 
                } 
                if (behaviors.ServiceBehaviors.ContainsKey(behaviorName))
                { 
                    retval = behaviors.ServiceBehaviors[behaviorName];
                }
            }
            if (retval != null) 
            {
                CheckAccess(retval); 
            } 
            return retval;
        } 

        /// 
        /// Critical - leaks config objects, caller must ensure that these don't leak to user code
        ///  
        [SecurityCritical]
        static CommonBehaviorsSection LookupCommonBehaviors(ContextInformation context) 
        { 
            if (DiagnosticUtility.ShouldTraceVerbose)
            { 
                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Verbose,
                    TraceCode.GetCommonBehaviors, null);
            }
            return context == null 
                ? CommonBehaviorsSection.UnsafeGetSection()
                : CommonBehaviorsSection.UnsafeGetAssociatedSection(context) 
                ; 
        }
 
        /// 
        /// Critical - leaks config objects, caller must ensure that these don't leak to user code
        /// 
        [SecurityCritical] 
        ChannelEndpointElement LookupChannel(string configurationName, string contractName, bool wildcard)
        { 
            ClientSection clientSection = ClientSection.UnsafeGetSection(); 
            ChannelEndpointElement retval = null;
 
            foreach (ChannelEndpointElement channelElement in clientSection.Endpoints)
            {
                if (channelElement.Contract == contractName) // match contract
                { 
                    if (channelElement.Name == configurationName || wildcard) // match name (or wildcard)
                    { 
                        if (retval != null) // oops: >1 
                        {
                            if (wildcard) 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigLoaderMultipleEndpointMatchesWildcard1, contractName)));
                            }
                            else 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxConfigLoaderMultipleEndpointMatchesSpecified2, contractName, configurationName))); 
                            } 
                        }
                        retval = channelElement; 
                    }
                }
            }
 
            if (retval != null)
            { 
                CheckAccess(retval); 
            }
 
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                Dictionary values = new Dictionary(8);
                values["FoundChannelElement"] = retval != null; 
                values["Name"] = configurationName;
                values["ContractName"] = contractName; 
 
                if (null != retval)
                { 
                    if (!string.IsNullOrEmpty(retval.Binding))
                    {
                        values["Binding"] = retval.Binding;
                    } 
                    if (!string.IsNullOrEmpty(retval.BindingConfiguration))
                    { 
                        values["BindingConfiguration"] = retval.BindingConfiguration; 
                    }
                    if (retval.Address != null) 
                    {
                        values["RemoteEndpointUri"] = retval.Address.ToString();
                    }
                    if (!string.IsNullOrEmpty(retval.ElementInformation.Source)) 
                    {
                        values["ConfigurationFileSource"] = retval.ElementInformation.Source; 
                        values["ConfigurationFileLineNumber"] = retval.ElementInformation.LineNumber; 
                    }
                } 

                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Information,
                    TraceCode.GetChannelEndpointElement,
                    new DictionaryTraceRecord(values), null, null); 
            }
 
            return retval; 
        }
 
        internal ContractDescription LookupContract(string contractName, string serviceName)
        {
            ContractDescription contract = contractResolver.ResolveContract(contractName);
            if (contract == null) 
            {
                if (contractName == ServiceMetadataBehavior.MexContractName) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFoundIMetadataExchange, serviceName)));
                } 
                else if (contractName == String.Empty)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFoundEmpty, serviceName)));
                } 
                else
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFound2, contractName, serviceName))); 
                }
            } 

            return contract;
        }
 
        /// 
        /// Critical - leaks config objects, caller must ensure that these don't leak to user code 
        ///  
        [SecurityCritical]
        public ServiceElement LookupService(string serviceConfigurationName) 
        {
            ServicesSection servicesSection = ServicesSection.UnsafeGetSection();
            ServiceElement retval = null;
 
            ServiceElementCollection services = servicesSection.Services;
            for (int i = 0; i < services.Count; i++) 
            { 
                ServiceElement serviceElement = services[i];
                if (serviceElement.Name == serviceConfigurationName) 
                {
                    retval = serviceElement;
                }
            } 

            if (retval != null) 
            { 
                CheckAccess(retval);
            } 

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Information, 
                    TraceCode.GetServiceElement,
                    new ServiceConfigurationTraceRecord(retval), null, null); 
            } 
            return retval;
        } 

        bool IsWildcardMatch(string endpointConfigurationName)
        {
            return String.Equals(endpointConfigurationName, "*", StringComparison.Ordinal); 
        }
 
        ///  
        ///  RequiresReview - used in a security decision
        ///  
        [SecurityRequiresReview]
        static bool IsConfigAboveApplication(ContextInformation contextInformation)
        {
            if (contextInformation != null) 
            {
                if (contextInformation.IsMachineLevel) 
                { 
                    return true;
                } 

                bool isAppConfig = contextInformation.HostingContext is ExeContext;
                if (isAppConfig)
                { 
                    return false; // for app.config, the only higher-scope config file is machine.config
                } 
                else 
                {
                    return IsWebConfigAboveApplication(contextInformation); 
                }
            }

            return true; // err on the safe side: absent context information assume a PT app doesn't have access 
        }
 
        ///  
        ///  RequiresReview - used in a security decision
        ///  
        [SecurityRequiresReview]
        [MethodImpl(MethodImplOptions.NoInlining)]
        static bool IsWebConfigAboveApplication(ContextInformation contextInformation)
        { 
            WebContext context = contextInformation.HostingContext as WebContext;
            if (context != null) 
            { 
                return context.ApplicationLevel == WebApplicationLevel.AboveApplication;
            } 

            return false; // if we don't recognize the context we can't enforce the special web.config logic
        }
 
        /// 
        ///  RequiresReview - enforces a security decision 
        ///  
        [SecurityRequiresReview]
        static void CheckAccess(IConfigurationContextProviderInternal element) 
        {
            if (IsConfigAboveApplication(ConfigurationHelpers.GetOriginalEvaluationContext(element)))
            {
                ConfigurationPermission.Demand(); 
            }
        } 
 
        /// 
        ///  Critical - used in a security decision 
        /// 
        [SecurityCritical]
        static ConfigurationPermission configurationPermission;
 
        static ConfigurationPermission ConfigurationPermission
        { 
            ///  
            ///  Critical - inits the configurationPermission field
            ///  Safe - safe for readonly access 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get
            { 
                if (configurationPermission == null)
                { 
                    configurationPermission = new ConfigurationPermission(System.Security.Permissions.PermissionState.Unrestricted); 
                }
                return configurationPermission; 
            }
        }

        ///  
        ///  Critical - uses critical field configurationPermission
        ///  
        [SecurityCritical] 
        static bool ThreadHasConfigurationPermission()
        { 
            try
            {
                ConfigurationPermission.Demand();
            } 
            catch (SecurityException)
            { 
                return false; 
            }
            return true; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK