SecurityUtils.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Misc / SecurityUtils.cs / 1305376 / SecurityUtils.cs

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

/* 
 */ 

 
#if [....]_NAMESPACE
    namespace System.Windows.Forms
#elif DRAWING_NAMESPACE
    namespace System.Drawing 
#elif [....]_PUBLIC_GRAPHICS_LIBRARY
    namespace System.Internal 
#elif SYSTEM_NAMESPACE 
    namespace System
#elif SYSTEM_WEB 
    namespace System.Web
#else
   namespace System.Windows.Forms
#endif 
{
    using System; 
    using System.Reflection; 
    using System.Diagnostics.CodeAnalysis;
    using System.Security; 
    using System.Security.Permissions;

    /// 
    ///     Useful methods to securely call 'dangerous' managed APIs (especially reflection). 
    ///     See http://wiki/default.aspx/Microsoft.Projects.DotNetClient.SecurityConcernsAroundReflection
    ///     for more information specifically about why we need to be careful about reflection invocations. 
    ///  
    internal static class SecurityUtils {
 
        private static ReflectionPermission memberAccessPermission = null;
        private static ReflectionPermission restrictedMemberAccessPermission = null;

        private static ReflectionPermission MemberAccessPermission 
        {
            get { 
                if (memberAccessPermission == null) { 
                    memberAccessPermission = new ReflectionPermission(ReflectionPermissionFlag.MemberAccess);
                } 
                return memberAccessPermission;
            }
        }
 
        private static ReflectionPermission RestrictedMemberAccessPermission {
            get { 
                if (restrictedMemberAccessPermission == null) { 
                    restrictedMemberAccessPermission = new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess);
                } 
                return restrictedMemberAccessPermission;
            }
        }
 
        private static void DemandReflectionAccess(Type type) {
            try { 
                MemberAccessPermission.Demand(); 
            }
            catch (SecurityException) { 
                DemandGrantSet(type.Assembly);
            }
        }
 
        [SecuritySafeCritical]
        private static void DemandGrantSet(Assembly assembly) { 
            PermissionSet targetGrantSet = assembly.PermissionSet; 
            targetGrantSet.AddPermission(RestrictedMemberAccessPermission);
            targetGrantSet.Demand(); 
        }

        private static bool HasReflectionPermission(Type type) {
            try { 
                DemandReflectionAccess(type);
                return true; 
            } 
            catch (SecurityException) {
            } 

            return false;
        }
 

        ///  
        ///     This helper method provides safe access to Activator.CreateInstance. 
        ///     NOTE: This overload will work only with public .ctors.
        ///  
        internal static object SecureCreateInstance(Type type) {
            return SecureCreateInstance(type, null, false);
        }
 

        ///  
        ///     This helper method provides safe access to Activator.CreateInstance. 
        ///     Set allowNonPublic to true if you want non public ctors to be used.
        ///  
        internal static object SecureCreateInstance(Type type, object[] args, bool allowNonPublic) {
            if (type == null) {
                throw new ArgumentNullException("type");
            } 

            BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance; 
 
            // if it's an internal type, we demand reflection permission.
            if (!type.IsVisible) { 
                DemandReflectionAccess(type);
            }
            else if (allowNonPublic && !HasReflectionPermission(type)) {
                // Someone is trying to instantiate a public type in *our* assembly, but does not 
                // have full reflection permission. We shouldn't pass BindingFlags.NonPublic in this case.
                // The reason we don't directly demand the permission here is because we don't know whether 
                // a public or non-public .ctor will be invoked. We want to allow the public .ctor case to 
                // succeed.
                allowNonPublic = false; 
            }

            if (allowNonPublic) {
                flags |= BindingFlags.NonPublic; 
            }
 
            return Activator.CreateInstance(type, flags, null, args, null); 
        }
 
#if (![....]_NAMESPACE)

        /// 
        ///     This helper method provides safe access to Activator.CreateInstance. 
        ///     NOTE: This overload will work only with public .ctors.
        ///  
        internal static object SecureCreateInstance(Type type, object[] args) { 
            return SecureCreateInstance(type, args, false);
        } 


        /// 
        ///     Helper method to safely invoke a .ctor. You should prefer SecureCreateInstance to this. 
        ///     Set allowNonPublic to true if you want non public ctors to be used.
        ///  
        internal static object SecureConstructorInvoke(Type type, Type[] argTypes, object[] args, bool allowNonPublic) { 
            return SecureConstructorInvoke(type, argTypes, args, allowNonPublic, BindingFlags.Default);
        } 

        /// 
        ///     Helper method to safely invoke a .ctor. You should prefer SecureCreateInstance to this.
        ///     Set allowNonPublic to true if you want non public ctors to be used. 
        ///     The 'extraFlags' parameter is used to pass in any other flags you need,
        ///     besides Public, NonPublic and Instance. 
        ///  
        internal static object SecureConstructorInvoke(Type type, Type[] argTypes, object[] args,
                                                       bool allowNonPublic, BindingFlags extraFlags) { 
            if (type == null) {
                throw new ArgumentNullException("type");
            }
 
            // if it's an internal type, we demand reflection permission.
            if (!type.IsVisible) { 
                DemandReflectionAccess(type); 
            }
            else if (allowNonPublic && !HasReflectionPermission(type)) { 
                // Someone is trying to invoke a ctor on a public type, but does not
                // have full reflection permission. We shouldn't pass BindingFlags.NonPublic in this case.
                allowNonPublic = false;
            } 

            BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | extraFlags; 
            if (!allowNonPublic) { 
                flags &= ~BindingFlags.NonPublic;
            } 

            ConstructorInfo ctor = type.GetConstructor(flags, null, argTypes, null);
            if (ctor != null) {
                return ctor.Invoke(args); 
            }
 
            return null; 
        }
 
        private static bool GenericArgumentsAreVisible(MethodInfo method) {
            if (method.IsGenericMethod) {
                Type[] parameterTypes = method.GetGenericArguments();
                foreach (Type type in parameterTypes) { 
                    if (!type.IsVisible) {
                        return false; 
                    } 
                }
            } 
            return true;
        }

        ///  
        ///     This helper method provides safe access to FieldInfo's GetValue method.
        ///  
        internal static object FieldInfoGetValue(FieldInfo field, object target) { 
            Type type = field.DeclaringType;
            if (type == null) { 
                // Type is null for Global fields.
                if (!field.IsPublic) {
                    DemandGrantSet(field.Module.Assembly);
                } 
            } else if (!(type != null && type.IsVisible && field.IsPublic)) {
                DemandReflectionAccess(type); 
            } 
            return field.GetValue(target);
        } 

        /// 
        ///     This helper method provides safe access to MethodInfo's Invoke method.
        ///  
        internal static object MethodInfoInvoke(MethodInfo method, object target, object[] args) {
            Type type = method.DeclaringType; 
            if (type == null) { 
                // Type is null for Global methods. In this case we would need to demand grant set on
                // the containing assembly for internal methods. 
                if (!(method.IsPublic && GenericArgumentsAreVisible(method))) {
                    DemandGrantSet(method.Module.Assembly);
                }
            } else if (!(type.IsVisible && method.IsPublic && GenericArgumentsAreVisible(method))) { 
                // this demand is required for internal types in system.dll and its friend assemblies.
                DemandReflectionAccess(type); 
            } 
            return method.Invoke(target, args);
        } 

        /// 
        ///     This helper method provides safe access to ConstructorInfo's Invoke method.
        ///     Constructors can't be generic, so we don't check if argument types are visible 
        /// 
        internal static object ConstructorInfoInvoke(ConstructorInfo ctor, object[] args) { 
            Type type = ctor.DeclaringType; 
            if ((type != null) && !(type.IsVisible && ctor.IsPublic)) {
                DemandReflectionAccess(type); 
            }
            return ctor.Invoke(args);
        }
 
        /// 
        ///     This helper method provides safe access to Array.CreateInstance. 
        ///  
        internal static object ArrayCreateInstance(Type type, int length) {
            if (!type.IsVisible) { 
                DemandReflectionAccess(type);
            }
            return Array.CreateInstance(type, length);
        } 
#endif
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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