PresentationAppDomainManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / AppModel / PresentationAppDomainManager.cs / 2 / PresentationAppDomainManager.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//      Implements a custom AppDomainManager. 
//
//--------------------------------------------------------------------------- 

using System;
using System.Net;
using System.Reflection; 
using System.Runtime.Remoting;
using System.Security; 
using System.Security.Permissions; 
using System.Security.Policy;
using System.Runtime.Hosting; 
using System.Text;
using MS.Win32;

using MS.Internal; 
using MS.Internal.AppModel;
using MS.Internal.Utility; 
using MS.Utility; 

namespace System.Windows.Interop 
{
    internal class PresentationHostSecurityManager : HostSecurityManager
    {
        ///  
        /// Critical - HostSecurityManager..ctor LinkDemand's. This class should not be called directly by PT'ed callers, since it can interfere with
        /// the privileges an AppDomain gets. 
        ///  
        [SecurityCritical]
        internal PresentationHostSecurityManager() 
        {
        }

        ///  
        ///     Critical - because this accesses critical data AppDomain.CurrentDomain.SetupInformation.ActivationArguments
        ///     and sets BrowserInteropHelper.IsViewer and .IsBrowserHosted. 
        ///     Safe - because this does not expose that string. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public override ApplicationTrust DetermineApplicationTrust(Evidence applicationEvidence, Evidence activatorEvidence, TrustManagerContext context)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            { 
                EventTrace.EventProvider.TraceEvent(
                    EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.DetermineApplicationTrustStart); 
            } 

            ApplicationTrust trust; 
            Uri activationUri = GetUriFromActivationData(0);
            bool isDebug = PresentationAppDomainManager.IsDebug ? true : GetBoolFromActivationData(1);
            bool isViewer = GetBoolFromActivationData(2);
 
            BrowserInteropHelper.SetBrowserHosted(true);
            BrowserInteropHelper.IsViewer = isViewer; 
 
            if (isDebug)
            { 
                context.IgnorePersistedDecision = true;
                context.Persist = false;
                context.KeepAlive = false;
                context.NoPrompt = true; 
                trust = base.DetermineApplicationTrust(applicationEvidence, activatorEvidence, context);
                Uri debugSecurityZoneURL = GetUriFromActivationData(3); 
                if (debugSecurityZoneURL != null) 
                {
                    PermissionSet permissions = trust.DefaultGrantSet.PermissionSet; 
                    trust.DefaultGrantSet.PermissionSet = AddPermissionForUri(permissions, debugSecurityZoneURL);
                }
            }
            else 
            {
                // Defense in depth. Should never get to this point and require this to be 
                // set, but just in case, we do this so that we will never get a trust 
                // prompt even if something goes wrong somewhere else.
                context.NoPrompt = true; 
                trust = base.DetermineApplicationTrust(applicationEvidence, activatorEvidence, context);

                if (isViewer)
                { 
                    PermissionSet permissions = trust.DefaultGrantSet.PermissionSet;
 
                    // Remove permissions to the site of origin of the viewer app 
                    permissions.RemovePermission(typeof(WebPermission));
                    permissions.RemovePermission(typeof(FileIOPermission)); 

                    // Remove IsolatedStorageFilePermission; it is not needed.
                    permissions.RemovePermission(typeof(IsolatedStorageFilePermission));
 
                    // If this is a viewer app, the ApplicationTrust returned by base.DetermineApplicationTrust will
                    // have the permissions appropriate to the viewer app, which is necessary for non-trivial viewer 
                    // apps to function properly. However, in order to access the viewed document, we will need to 
                    // add permission to access the path/URI where the viewed document comes from.
                    trust.DefaultGrantSet.PermissionSet = AddPermissionForUri(permissions, activationUri); 
                }
            }

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            {
                EventTrace.EventProvider.TraceEvent( 
                    EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.DetermineApplicationTrustEnd); 
            }
 
            return trust;
        }

        ///  
        ///     Critical - because adds permission to default permissionset granted by trustmanager.
        ///     Safe - Only gets called in debug and for loose xaml scenario permissions are removed too. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private PermissionSet AddPermissionForUri(PermissionSet originalPermSet, Uri srcUri) 
        {
            PermissionSet newPermSet = originalPermSet;
            if (srcUri != null)
            { 
                Evidence evidence = new Evidence();
                evidence.AddHost(new Url(BindUriHelper.UriToString(srcUri))); // important: the parameter must be a UrL object not a UrI object 
                IMembershipCondition membership = new UrlMembershipCondition(BindUriHelper.UriToString(srcUri)); 
                CodeGroup group = (srcUri.IsFile) ?
                    (CodeGroup)new FileCodeGroup(membership, FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery) 
                    :(CodeGroup)new NetCodeGroup(membership);
                PolicyStatement policy = group.Resolve(evidence);
                if (!policy.PermissionSet.IsEmpty())
                { 
                    newPermSet = originalPermSet.Union(policy.PermissionSet);
                } 
            } 
            return newPermSet;
        } 

        /// 
        ///     Critical - because this accesses critical data AppDomain.CurrentDomain.SetupInformation.ActivationArguments.
        ///     Safe - because this does not expose that string. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private bool GetBoolFromActivationData(int index) 
        {
            bool flag = false; // default 

            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments != null &&
                AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > index)
            { 
                if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[index] == true.ToString())
                { 
                    flag = true; 
                }
            } 

            return flag;
        }
 
        /// 
        ///     Critical - because this accesses critical data AppDomain.CurrentDomain.SetupInformation.ActivationArguments. 
        ///     Safe - because this does not expose that string. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private Uri GetUriFromActivationData(int index)
        {
            Uri uri = null;
 
            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments != null &&
                AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > index) 
            { 
                if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[index]))
                { 
                    uri = new UriBuilder(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[index]).Uri;
                }
            }
 
            return uri;
        } 
    } 

    // This is the custom ApplicationActivator that will be returned by 
    // the PresentationAppDomainManager.ApplicationActivator property.
    // CreateInstance will be called twice: the first time to create
    // the new AppDomain, and the second time to create the app inside
    // of the new AppDomain. 
    internal class PresentationApplicationActivator : System.Runtime.Hosting.ApplicationActivator
    { 
        ///  
        ///     Critical - because this does an elevation to get the ID string.
        ///     Safe - because this does not expose that string. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public override ObjectHandle CreateInstance(ActivationContext actCtx)
        { 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            { 
                EventTrace.EventProvider.TraceEvent( 
                    EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.ApplicationActivatorCreateInstanceStart,
                    PresentationAppDomainManager.ActivationUri != null ? PresentationAppDomainManager.ActivationUri.ToString() : string.Empty); 
            }

            ObjectHandle oh;
            if (PresentationAppDomainManager.ActivationUri != null) 
            {
                oh = base.CreateInstance( 
                    actCtx, 
                    new string[] {
                    BindUriHelper.UriToString(PresentationAppDomainManager.ActivationUri), 
                    PresentationAppDomainManager.IsDebug.ToString(),
                    PresentationAppDomainManager.IsViewer.ToString(),
                    (PresentationAppDomainManager.DebugSecurityZoneURL == null?
                        string.Empty 
                        : PresentationAppDomainManager.DebugSecurityZoneURL.ToString())});
            } 
            else 
            {
                oh = base.CreateInstance(actCtx); 
            }
            bool returnAppDomain = false;

            try 
            {
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert: 
                if (AppDomain.CurrentDomain.ActivationContext != null && 
                    AppDomain.CurrentDomain.ActivationContext.Identity.ToString().Equals(actCtx.Identity.ToString()))
                { 
                    returnAppDomain = true;
                }
            }
            finally 
            {
                CodeAccessPermission.RevertAssert(); 
            } 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.ApplicationActivatorCreateInstanceEnd);
            }
 
            if (returnAppDomain)
            { 
                // this is the server domain 
                return new ObjectHandle(AppDomain.CurrentDomain);
            } 
            else
            {
                return oh;
            } 
        }
    } 
 
    // This is a custom AppDomainManager class we're using.  We need to set the
    // assembly name and class name in the environment for CLR to use it.  We 
    // need to use this to detect new AppDomain creation.
    internal class PresentationAppDomainManager : AppDomainManager
    {
        ///  
        ///    Critical: Initializes Critical data
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        static PresentationAppDomainManager()
        { 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppDomainManagerCctor);
            } 

            _isViewer = new SecurityCriticalDataForSet(false); 
        } 

        ///  
        ///    Critical: Base class has link demnd and inheritance demand
        /// 
        [SecurityCritical]
        public PresentationAppDomainManager() 
        {
        } 
 
        public override ApplicationActivator ApplicationActivator
        { 
            get
            {
                if (_appActivator == null)
                    _appActivator = new PresentationApplicationActivator(); 
                return _appActivator;
            } 
        } 

        ///  
        ///     Critical: This hooks up the assembly filter which we want to prevent arbitrary code from doing.
        /// 
        [SecurityCritical]
        public override void InitializeNewDomain(AppDomainSetup appDomainInfo) 
        {
            //Hookup the assembly load event 
            _assemblyFilter = new AssemblyFilter(); 
            AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(_assemblyFilter.FilterCallback);
        } 

        /// 
        /// Critical - get: Discloses a HostSecurityManager object
        ///  
        public override HostSecurityManager HostSecurityManager
        { 
            [SecurityCritical] 
            get
            { 
                if (_hostsecuritymanager == null)
                {
                    _hostsecuritymanager = new PresentationHostSecurityManager();
                } 
                return _hostsecuritymanager;
            } 
        } 

        // Creates ApplicationProxyInternal.  Creating it from Default domain will 
        // cause a stack walk for ReflectionPermission which will fail for partial
        // trust apps.
        /// 
        /// Critical: This calls the critical ApplicationProxyInternal ctor 
        /// 
        [SecurityCritical] 
        internal ApplicationProxyInternal CreateApplicationProxyInternal() 
        {
            return new ApplicationProxyInternal(); 
        }

        internal static AppDomain NewAppDomain
        { 
            get { return _newAppDomain; }
            set { _newAppDomain = value; } 
        } 

        internal static bool SaveAppDomain 
        {
            get { return _saveAppDomain; }
            set
            { 
                _saveAppDomain = value;
 
                // Allow garbage collection to happen. 
                _newAppDomain = null;
            } 
        }

        internal static Uri ActivationUri
        { 
            get { return _activationUri; }
            set { _activationUri = value; } 
        } 

        internal static Uri DebugSecurityZoneURL 
        {
            get { return _debugSecurityZoneURL; }
            set { _debugSecurityZoneURL = value; }
        } 

        internal static bool IsDebug 
        { 
            get { return _isdebug; }
            set { _isdebug = value; } 
        }

        /// 
        /// Returns true if the app is a viewer app. 
        /// 
        ///  
        /// This is critical because setting the viewer status is a critical resource. 
        /// 
        internal static bool IsViewer 
        {
            get { return _isViewer.Value; }

            [SecurityCritical] 
            set { _isViewer.Value = value; }
        } 
 
        private static bool _isdebug = false;
        private static SecurityCriticalDataForSet _isViewer; 
        private ApplicationActivator _appActivator = null;


        ///  
        /// It holds a HostSecurityManager object, which is critical and can interfere with the permissions that are assigned to an AppDomain.
        ///  
        [SecurityCritical] 
        private HostSecurityManager _hostsecuritymanager = null;
 
        private static AppDomain _newAppDomain;
        private static bool _saveAppDomain;
        private static Uri _activationUri;
        private static Uri _debugSecurityZoneURL; 

        /// 
        ///    Critical: This should not be exposed since it can be used to bring down process 
        ///
        [SecurityCritical] 
        private AssemblyFilter _assemblyFilter;
    }
}

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