MetabaseSettings.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 / Activation / MetabaseSettings.cs / 2 / MetabaseSettings.cs

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

namespace System.ServiceModel.Activation 
{
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.ServiceModel; 
    using System.ServiceModel.Channels;
    using System.Net;
    using System.Web;
    using System.Web.Hosting; 
    using System.Globalization;
    using Microsoft.Win32; 
    using System.Configuration; 
    using System.Security.Principal;
    using System.IdentityModel.Claims; 
    using System.IdentityModel.Policy;
    using System.ServiceModel.Security.Tokens;
    using System.Runtime.InteropServices;
    using System.ComponentModel; 
    using System.Security;
 
    abstract class MetabaseSettings 
    {
        internal const string LocalMachine = "localhost"; 

        List enabledProtocols;
        IDictionary bindingsTable;
 
        protected MetabaseSettings()
        { 
            enabledProtocols = new List(); 
            bindingsTable = new Dictionary();
        } 

        internal abstract string GetRealm(string virtualPath);
        internal abstract HttpAccessSslFlags GetAccessSslFlags(string virtualPath);
        internal abstract AuthenticationSchemes GetAuthenticationSchemes(string virtualPath); 

        protected List Protocols { get { return enabledProtocols; } set { enabledProtocols = value; } } 
        protected IDictionary Bindings { get { return bindingsTable; } set { bindingsTable = value; } } 

        internal bool GetAllowSslOnly(string virtualPath) 
        {
            HttpAccessSslFlags flags = this.GetAccessSslFlags(virtualPath);
            if ((flags & HttpAccessSslFlags.Ssl) != 0)
            { 
                return true;
            } 
            return false; 
        }
 
        internal string[] GetProtocols()
        {
            return enabledProtocols.ToArray();
        } 

        internal string[] GetBindings(string scheme) 
        { 
            return bindingsTable[scheme];
        } 
    }

    class MetabaseSettingsCassini : MetabaseSettings
    { 
        internal MetabaseSettingsCassini(HostedHttpRequestAsyncResult result)
            : base() 
        { 
            if (!ServiceHostingEnvironment.IsSimpleApplicationHost)
            { 
                DiagnosticUtility.DebugAssert("MetabaseSettingsCassini..ctor() Not a simple application host.");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(true);
            }
 
            // The hostName is hard-coded to "localhost" for Cassini.
            string binding = string.Format(CultureInfo.InvariantCulture, ":{0}:{1}", result.OriginalRequestUri.Port.ToString(NumberFormatInfo.InvariantInfo), MetabaseSettings.LocalMachine); 
            this.Bindings.Add(result.OriginalRequestUri.Scheme, new string[] { binding }); 
            this.Protocols.Add(result.OriginalRequestUri.Scheme);
        } 

        internal override string GetRealm(string virtualPath) { return string.Empty; }
        internal override HttpAccessSslFlags GetAccessSslFlags(string virtualPath) { return HttpAccessSslFlags.None; }
        internal override AuthenticationSchemes GetAuthenticationSchemes(string virtualPath) 
        {
            // Special casing Cassini so that Ntlm is supported since the request always has the identity of the 
            // logged on user. 
            return AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm;
        } 
    }

    abstract class MetabaseSettingsIis : MetabaseSettings
    { 
        IDictionary transportSettingsTable;
        internal const string NegotiateAuthProvider = "negotiate"; 
        internal const string NtlmAuthProvider = "ntlm"; 
        internal static string[] DefaultAuthProviders = { NegotiateAuthProvider, NtlmAuthProvider };
 
        protected MetabaseSettingsIis()
            : base()
        {
            if (ServiceHostingEnvironment.IsSimpleApplicationHost) 
            {
                DiagnosticUtility.DebugAssert("MetabaseSettingsIis..ctor() Is a simple application host."); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(true); 
            }
 
            transportSettingsTable = new Dictionary(StringComparer.OrdinalIgnoreCase);
        }

        object ThisLock { get { return this; } } 

        protected abstract HostedServiceTransportSettings CreateTransportSettings(string relativeVirtualPath); 
 
        internal override string GetRealm(string virtualPath)
        { 
            HostedServiceTransportSettings transportSettings = GetTransportSettings(virtualPath);
            return transportSettings.Realm;
        }
 
        internal override HttpAccessSslFlags GetAccessSslFlags(string virtualPath)
        { 
            HostedServiceTransportSettings transportSettings = GetTransportSettings(virtualPath); 
            return transportSettings.AccessSslFlags;
        } 

        internal override AuthenticationSchemes GetAuthenticationSchemes(string virtualPath)
        {
            HostedServiceTransportSettings transportSettings = GetTransportSettings(virtualPath); 
            return RemapAuthenticationSchemes(transportSettings.AuthFlags, transportSettings.AuthProviders);
        } 
 
        // IIS and NCL have different enums/values for the various settings
        // therefore we will have to remap. 
        AuthenticationSchemes RemapAuthenticationSchemes(AuthFlags flags, string[] providers)
        {
            // The default value for the authetication in IIS is anonymous
            AuthenticationSchemes retValue = AuthenticationSchemes.None; 
            if ((flags & AuthFlags.AuthAnonymous) != 0)
                retValue = retValue | AuthenticationSchemes.Anonymous; 
            if ((flags & AuthFlags.AuthBasic) != 0) 
                retValue = retValue | AuthenticationSchemes.Basic;
            if ((flags & AuthFlags.AuthMD5) != 0) 
                retValue = retValue | AuthenticationSchemes.Digest;

            if ((flags & AuthFlags.AuthNTLM) != 0)
            { 
                for (int i = 0; i < providers.Length; i++)
                { 
                    if (string.Compare(providers[i], NegotiateAuthProvider, StringComparison.OrdinalIgnoreCase) == 0) 
                    {
                        retValue = retValue | AuthenticationSchemes.Negotiate; 
                    }
                    else if (string.Compare(providers[i], NtlmAuthProvider, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        retValue = retValue | AuthenticationSchemes.Ntlm; 
                    }
                    else 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.Hosting_NotSupportedAuthScheme, providers[i])));
                    } 
                }
            }

            if ((flags & AuthFlags.AuthPassport) != 0) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.Hosting_NotSupportedAuthScheme, "Passport")));
            return retValue; 
        } 

        HostedServiceTransportSettings GetTransportSettings(string virtualPath) 
        {
            //Make sure we get relative virtual path.
            string relativeVirtualPath = VirtualPathUtility.ToAppRelative(virtualPath, HostingEnvironmentWrapper.ApplicationVirtualPath);
 
            HostedServiceTransportSettings transportSettings;
 
            if (!transportSettingsTable.TryGetValue(relativeVirtualPath, out transportSettings)) 
            {
                lock (ThisLock) 
                {
                    if (!transportSettingsTable.TryGetValue(relativeVirtualPath, out transportSettings))
                    {
                        transportSettings = CreateTransportSettings(relativeVirtualPath); 
                        transportSettingsTable.Add(relativeVirtualPath, transportSettings);
                    } 
                } 
            }
 
            return transportSettings;
        }
    }
 
    class MetabaseSettingsIis6 : MetabaseSettingsIis
    { 
        static class IISConstants 
        {
            internal const char AboPathDelimiter = '/'; 
            internal const string LMSegment = "/LM";
            internal const string RootSegment = "/Root";
            internal static char[] CommaSeparator = new char[] { ',' };
        } 

        ///  
        /// Critical - potentially protected data read from the IIS metabase under an elevation 
        /// 
        [SecurityCritical] 
        string siteAboPath;
        /// 
        /// Critical - potentially protected data read from the IIS metabase under an elevation
        ///  
        [SecurityCritical]
        string appAboPath; 
 
        // Application-level settings
        ///  
        /// Critical - A SecurityCritical field, caller must use care
        /// 
        [SecurityCritical]
        HostedServiceTransportSettings appTransportSettings; 

        ///  
        /// Critical - uses MetabaseReader (critical class) to read data from metabase 
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal MetabaseSettingsIis6()
            : base()
        { 
            if (Iis7Helper.IsIis7)
            { 
                DiagnosticUtility.DebugAssert("MetabaseSettingsIis6 constructor must not be called when running in IIS7"); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(true);
            } 

            SetApplicationInfo();
            using (MetabaseReader reader = new MetabaseReader())
            { 
                PopulateSiteProperties(reader);
                PopulateApplicationProperties(reader); 
            } 
        }
 
        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use
        ///        returns sanitized values (safe for read) 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override HostedServiceTransportSettings CreateTransportSettings(string relativeVirtualPath) 
        {
            HostedServiceTransportSettings transportSettings = new HostedServiceTransportSettings(); 
            using (MetabaseReader reader = new MetabaseReader())
            {
                transportSettings.Realm = GetRealm(reader, relativeVirtualPath);
                transportSettings.AccessSslFlags = GetAccessSslFlags(reader, relativeVirtualPath); 
                transportSettings.AuthFlags = GetAuthFlags(reader, relativeVirtualPath);
                transportSettings.AuthProviders = GetAuthProviders(reader, relativeVirtualPath); 
            } 

            return transportSettings; 
        }

        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase 
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use
        ///        returns sanitized values (safe for read) 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        string GetRealm(MetabaseReader reader, string relativeVirtualPath) 
        {
            object propertyValue = FindPropertyUnderAppRoot(reader, MetabasePropertyType.Realm, relativeVirtualPath);
            if (propertyValue != null)
            { 
                return (string)propertyValue;
            } 
 
            return appTransportSettings.Realm;
        } 

        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use 
        ///        returns sanitized values (safe for read)
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        HttpAccessSslFlags GetAccessSslFlags(MetabaseReader reader, string relativeVirtualPath)
        { 
            object propertyValue = FindPropertyUnderAppRoot(reader, MetabasePropertyType.AccessSslFlags, relativeVirtualPath);
            if (propertyValue != null)
            {
                return (HttpAccessSslFlags)(uint)propertyValue; 
            }
 
            return appTransportSettings.AccessSslFlags; 
        }
 
        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use
        ///        returns sanitized values (safe for read) 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        AuthFlags GetAuthFlags(MetabaseReader reader, string relativeVirtualPath) 
        {
            object propertyValue = FindPropertyUnderAppRoot(reader, MetabasePropertyType.AuthFlags, relativeVirtualPath); 
            if (propertyValue != null)
            {
                return (AuthFlags)(uint)propertyValue;
            } 

            return appTransportSettings.AuthFlags; 
        } 

        ///  
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use
        ///        returns sanitized values (safe for read)
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        string[] GetAuthProviders(MetabaseReader reader, string relativeVirtualPath) 
        { 
            object propertyValue = FindPropertyUnderAppRoot(reader, MetabasePropertyType.AuthProviders, relativeVirtualPath);
            if (propertyValue != null) 
            {
                string providersString = (string)propertyValue;
                string[] providers = providersString.Split(IISConstants.CommaSeparator, StringSplitOptions.RemoveEmptyEntries);
                if (providers != null && providers.Length > 0) 
                {
                    return providers; 
                } 
            }
 
            return appTransportSettings.AuthProviders;
        }

        ///  
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        void SetApplicationInfo() 
        {
            // find the first '/' after the /LM/W3SVC/
            // and get the substring before that
            string applicationID = HostingEnvironmentWrapper.UnsafeApplicationID; 
            int index = applicationID.IndexOf(IISConstants.AboPathDelimiter, ServiceHostingEnvironment.ISAPIApplicationIdPrefix.Length);
            siteAboPath = applicationID.Substring(IISConstants.LMSegment.Length, index - IISConstants.LMSegment.Length); 
 
            if (HostingEnvironmentWrapper.ApplicationVirtualPath.Length > 1)
            { 
                appAboPath = string.Concat(siteAboPath, IISConstants.RootSegment, HostingEnvironmentWrapper.ApplicationVirtualPath);
            }
            else
            { 
                if (HostingEnvironmentWrapper.ApplicationVirtualPath.Length != 1 || HostingEnvironmentWrapper.ApplicationVirtualPath[0] != IISConstants.AboPathDelimiter)
                { 
                    DiagnosticUtility.DebugAssert("ApplicationVirtualPath must be '/'."); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(true);
                } 
                appAboPath = string.Concat(siteAboPath, IISConstants.RootSegment);
            }
        }
 
        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase 
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        void PopulateSiteProperties(MetabaseReader reader)
        {
            // 1. ServerBindings
            object propertyValue = reader.GetData(siteAboPath, MetabasePropertyType.ServerBindings); 
            if (propertyValue != null)
            { 
                string[] serverBindings = (string[])propertyValue; 
                if (serverBindings.Length > 0)
                { 
                    this.Bindings.Add(Uri.UriSchemeHttp, serverBindings);
                }
            }
 
            // 2. SecureBindings
            propertyValue = reader.GetData(siteAboPath, MetabasePropertyType.SecureBindings); 
            if (propertyValue != null) 
            {
                string[] secureBindings = (string[])propertyValue; 
                if (secureBindings.Length > 0)
                {
                    this.Bindings.Add(Uri.UriSchemeHttps, secureBindings);
                } 
            }
 
            foreach (string scheme in this.Bindings.Keys) 
            {
                this.Protocols.Add(scheme); 
            }
        }

        ///  
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        /// Safe - only passes MetabaseReader instance to critical methods, discards after use 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        void PopulateApplicationProperties(MetabaseReader reader) 
        {
            int foundCount = 0;
            bool foundRealm = false;
            bool foundAuthFlags = false; 
            bool foundAccessSslFlags = !Bindings.ContainsKey(Uri.UriSchemeHttps);
            bool foundAuthProviders = false; 
 
            appTransportSettings = new HostedServiceTransportSettings();
 
            string endAboPath = appAboPath;
            object propertyValue = null;
            while (foundCount < 4 && endAboPath.Length >= siteAboPath.Length)
            { 
                // Realm
                if (!foundRealm && ((propertyValue = reader.GetData(endAboPath, MetabasePropertyType.Realm)) 
                    != null)) 
                {
                    appTransportSettings.Realm = (string)propertyValue; 
                    foundRealm = true;
                    foundCount++;
                }
 
                // AuthFlags
                if (!foundAuthFlags && ((propertyValue = reader.GetData(endAboPath, MetabasePropertyType.AuthFlags)) 
                    != null)) 
                {
                    appTransportSettings.AuthFlags = (AuthFlags)(uint)propertyValue; 
                    foundAuthFlags = true;
                    foundCount++;
                }
 
                // AccessSslFlags
                if (!foundAccessSslFlags && ((propertyValue = reader.GetData(endAboPath, MetabasePropertyType.AccessSslFlags)) 
                    != null)) 
                {
                    appTransportSettings.AccessSslFlags = (HttpAccessSslFlags)(uint)propertyValue; 
                    foundAccessSslFlags = true;
                    foundCount++;
                }
 
                // NTAuthProviders
                if (!foundAuthProviders && ((propertyValue = reader.GetData(endAboPath, MetabasePropertyType.AuthProviders)) 
                    != null)) 
                {
                    string providersString = (string)propertyValue; 
                    appTransportSettings.AuthProviders = providersString.Split(IISConstants.CommaSeparator, StringSplitOptions.RemoveEmptyEntries);
                    foundAuthProviders = true;
                    foundCount++;
                } 

                // Continue the search in the parent path 
                int index = endAboPath.LastIndexOf(IISConstants.AboPathDelimiter); 
                endAboPath = endAboPath.Substring(0, index);
            } 

            if (appTransportSettings.AuthProviders == null || appTransportSettings.AuthProviders.Length == 0)
            {
                appTransportSettings.AuthProviders = DefaultAuthProviders; 
            }
        } 
 
        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase 
        ///        caller must sanitize return value
        /// 
        [SecurityCritical]
        object FindPropertyUnderAppRoot(MetabaseReader reader, MetabasePropertyType propertyType, string relativeVirtualPath) 
        {
            string matchedPath; 
            return FindPropertyUnderAppRoot(reader, propertyType, relativeVirtualPath, out matchedPath); 
        }
 
        /// 
        /// Critical - uses MetabaseReader (critical class) to read data from metabase
        ///        caller must sanitize return value
        ///  
        [SecurityCritical]
        object FindPropertyUnderAppRoot(MetabaseReader reader, MetabasePropertyType propertyType, string relativeVirtualPath, out string matchedPath) 
        { 
            string endAboPath = appAboPath + relativeVirtualPath.Substring(1);
            int index = endAboPath.IndexOf(IISConstants.AboPathDelimiter, appAboPath.Length + 1); 

            string startAboPath;
            if (index == -1)
            { 
                startAboPath = endAboPath;
            } 
            else 
            {
                startAboPath = endAboPath.Substring(0, index); 
            }

            return FindHierarchicalProperty(reader, propertyType, startAboPath, endAboPath, out matchedPath);
        } 

        ///  
        /// Critical - uses MetabaseReader (critical class) to read data from metabase 
        ///        caller must sanitize return value
        ///  
        [SecurityCritical]
        object FindHierarchicalProperty(MetabaseReader reader, MetabasePropertyType propertyType, string startAboPath, string endAboPath, out string matchedPath)
        {
            matchedPath = null; 
            while (endAboPath.Length >= startAboPath.Length)
            { 
                object propertyValue = reader.GetData(endAboPath, propertyType); 
                if (propertyValue != null)
                { 
                    matchedPath = endAboPath;
                    return propertyValue;
                }
 
                // Continue the search in the parent
                int index = endAboPath.LastIndexOf(IISConstants.AboPathDelimiter); 
                endAboPath = endAboPath.Substring(0, index); 
            }
 
            return null;
        }
    }
 
    class HostedServiceTransportSettings
    { 
        internal string Realm = string.Empty; 
        internal HttpAccessSslFlags AccessSslFlags = HttpAccessSslFlags.None;
        internal AuthFlags AuthFlags = AuthFlags.None; 
        internal string[] AuthProviders = MetabaseSettingsIis.DefaultAuthProviders;
    }

    [Flags] 
    enum AuthFlags
    { 
        None = 0, 
        AuthAnonymous = 1,
        AuthBasic = 2, 
        AuthNTLM = 4,

        // Note: AuthMD5 means IIS AuthScheme is Digest. Not MD5 algorithm.
        AuthMD5 = 16, 
        AuthPassport = 64,
    } 
 
    [Flags]
    enum HttpAccessSslFlags 
    {
        None = 0x00000000,
        Ssl = 0x00000008,
        SslNegotiateCert = 0x00000020, 
        SslRequireCert = 0x00000040,
        SslMapCert = 0x00000080, 
        Ssl128 = 0x00000100 
    }
} 

// 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