682 lines
34 KiB
C#
682 lines
34 KiB
C#
// ==++==
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ==--==
|
|
// <OWNER>[....]</OWNER>
|
|
//
|
|
|
|
//
|
|
// SecurityManager.cs
|
|
//
|
|
// The SecurityManager class provides a general purpose API for interacting
|
|
// with the security system.
|
|
//
|
|
|
|
namespace System.Security {
|
|
using System;
|
|
using System.Security.Util;
|
|
using System.Security.Policy;
|
|
using System.Security.Permissions;
|
|
using System.Collections;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.CompilerServices;
|
|
#if FEATURE_CLICKONCE
|
|
using System.Runtime.Hosting;
|
|
#endif // FEATURE_CLICKONCE
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Reflection;
|
|
using System.IO;
|
|
using System.Globalization;
|
|
using System.Runtime.Versioning;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
[Serializable]
|
|
[System.Runtime.InteropServices.ComVisible(true)]
|
|
public enum PolicyLevelType
|
|
{
|
|
User = 0,
|
|
Machine = 1,
|
|
Enterprise = 2,
|
|
AppDomain = 3
|
|
}
|
|
|
|
[System.Runtime.InteropServices.ComVisible(true)]
|
|
static public class SecurityManager {
|
|
#if FEATURE_CAS_POLICY
|
|
private static volatile SecurityPermission executionSecurityPermission = null;
|
|
|
|
private static PolicyManager polmgr = new PolicyManager();
|
|
internal static PolicyManager PolicyManager {
|
|
get {
|
|
return polmgr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Public APIs
|
|
//
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
|
|
[Obsolete("IsGranted is obsolete and will be removed in a future release of the .NET Framework. Please use the PermissionSet property of either AppDomain or Assembly instead.")]
|
|
public static bool IsGranted( IPermission perm )
|
|
{
|
|
if (perm == null)
|
|
return true;
|
|
|
|
PermissionSet granted = null, denied = null;
|
|
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
|
|
GetGrantedPermissions( JitHelpers.GetObjectHandleOnStack(ref granted),
|
|
JitHelpers.GetObjectHandleOnStack(ref denied),
|
|
JitHelpers.GetStackCrawlMarkHandle(ref stackMark) );
|
|
return granted.Contains( perm ) && (denied == null || !denied.Contains( perm ));
|
|
}
|
|
|
|
// Get a sandbox permission set that the CLR considers safe to grant an application with the given
|
|
// evidence. Note that this API is not a policy API, but rather a host helper API so that a host can
|
|
// determine if an application's requested permission set is reasonable. This is esentially just a
|
|
// hard coded mapping of Zone -> Sandbox and is not configurable in any way.
|
|
public static PermissionSet GetStandardSandbox(Evidence evidence)
|
|
{
|
|
if (evidence == null)
|
|
throw new ArgumentNullException("evidence");
|
|
Contract.EndContractBlock();
|
|
|
|
//
|
|
// The top-level switch for grant set is based upon Zone
|
|
// MyComputer -> FullTrust
|
|
// Intranet -> LocalIntranet
|
|
// Trusted -> Internet
|
|
// Internet -> Internet
|
|
// All else -> Nothing
|
|
//
|
|
// Both the Internet and LocalIntranet zones can have permission set extensions applied to them
|
|
// if there is Activation.
|
|
//
|
|
|
|
Zone zone = evidence.GetHostEvidence<Zone>();
|
|
if (zone == null)
|
|
{
|
|
return new PermissionSet(PermissionState.None);
|
|
}
|
|
#if FEATURE_CAS_POLICY
|
|
else if (zone.SecurityZone == SecurityZone.MyComputer)
|
|
{
|
|
return new PermissionSet(PermissionState.Unrestricted);
|
|
}
|
|
else if (zone.SecurityZone == SecurityZone.Intranet)
|
|
{
|
|
PermissionSet intranetGrantSet = BuiltInPermissionSets.LocalIntranet;
|
|
|
|
// We also need to add in same site web and file IO permission
|
|
PolicyStatement webPolicy =
|
|
new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
|
|
PolicyStatement filePolicy =
|
|
new FileCodeGroup(new AllMembershipCondition(), FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery).Resolve(evidence);
|
|
|
|
if (webPolicy != null)
|
|
{
|
|
intranetGrantSet.InplaceUnion(webPolicy.PermissionSet);
|
|
}
|
|
if (filePolicy != null)
|
|
{
|
|
intranetGrantSet.InplaceUnion(filePolicy.PermissionSet);
|
|
}
|
|
|
|
return intranetGrantSet;
|
|
}
|
|
else if (zone.SecurityZone == SecurityZone.Internet ||
|
|
zone.SecurityZone == SecurityZone.Trusted)
|
|
{
|
|
PermissionSet internetGrantSet = BuiltInPermissionSets.Internet;
|
|
|
|
// We also need to add in same site web permission
|
|
PolicyStatement webPolicy =
|
|
new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
|
|
|
|
if (webPolicy != null)
|
|
{
|
|
internetGrantSet.InplaceUnion(webPolicy.PermissionSet);
|
|
}
|
|
|
|
return internetGrantSet;
|
|
}
|
|
#endif // FEATURE_CAS_POLICY
|
|
else
|
|
{
|
|
return new PermissionSet(PermissionState.None);
|
|
}
|
|
}
|
|
|
|
/// <internalonly/>
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
|
|
static public void GetZoneAndOrigin( out ArrayList zone, out ArrayList origin )
|
|
{
|
|
StackCrawlMark mark = StackCrawlMark.LookForMyCaller;
|
|
CodeAccessSecurityEngine.GetZoneAndOrigin( ref mark, out zone, out origin );
|
|
}
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public PolicyLevel LoadPolicyLevelFromFile(string path, PolicyLevelType type)
|
|
{
|
|
if (path == null)
|
|
throw new ArgumentNullException( "path" );
|
|
Contract.EndContractBlock();
|
|
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
// We need to retain V1.x compatibility by throwing the same exception type.
|
|
if (!File.InternalExists(path))
|
|
throw new ArgumentException( Environment.GetResourceString("Argument_PolicyFileDoesNotExist"));
|
|
|
|
String fullPath = Path.GetFullPath( path );
|
|
|
|
FileIOPermission perm = new FileIOPermission( PermissionState.None );
|
|
perm.AddPathList( FileIOPermissionAccess.Read, fullPath );
|
|
perm.AddPathList( FileIOPermissionAccess.Write, fullPath );
|
|
perm.Demand();
|
|
|
|
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
|
|
using (StreamReader reader = new StreamReader(stream)) {
|
|
return LoadPolicyLevelFromStringHelper(reader.ReadToEnd(), path, type);
|
|
}
|
|
}
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public PolicyLevel LoadPolicyLevelFromString(string str, PolicyLevelType type)
|
|
{
|
|
return LoadPolicyLevelFromStringHelper(str, null, type);
|
|
}
|
|
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
private static PolicyLevel LoadPolicyLevelFromStringHelper (string str, string path, PolicyLevelType type)
|
|
{
|
|
if (str == null)
|
|
throw new ArgumentNullException( "str" );
|
|
Contract.EndContractBlock();
|
|
|
|
PolicyLevel level = new PolicyLevel(type, path);
|
|
|
|
Parser parser = new Parser( str );
|
|
SecurityElement elRoot = parser.GetTopElement();
|
|
if (elRoot == null)
|
|
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "configuration" ) );
|
|
|
|
SecurityElement elMscorlib = elRoot.SearchForChildByTag( "mscorlib" );
|
|
if (elMscorlib == null)
|
|
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "mscorlib" ) );
|
|
|
|
SecurityElement elSecurity = elMscorlib.SearchForChildByTag( "security" );
|
|
if (elSecurity == null)
|
|
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "security" ) );
|
|
|
|
SecurityElement elPolicy = elSecurity.SearchForChildByTag( "policy" );
|
|
if (elPolicy == null)
|
|
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "policy" ) );
|
|
|
|
SecurityElement elPolicyLevel = elPolicy.SearchForChildByTag( "PolicyLevel" );
|
|
if (elPolicyLevel != null)
|
|
level.FromXml( elPolicyLevel );
|
|
else
|
|
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "PolicyLevel" ) );
|
|
|
|
return level;
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public void SavePolicyLevel( PolicyLevel level )
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
PolicyManager.EncodeLevel( level );
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public PermissionSet ResolvePolicy(Evidence evidence,
|
|
PermissionSet reqdPset,
|
|
PermissionSet optPset,
|
|
PermissionSet denyPset,
|
|
out PermissionSet denied)
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
return ResolvePolicy(evidence, reqdPset, optPset, denyPset, out denied, true);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public PermissionSet ResolvePolicy(Evidence evidence)
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
// If we aren't passed any evidence, just make an empty object
|
|
if (evidence == null)
|
|
{
|
|
evidence = new Evidence();
|
|
}
|
|
|
|
return polmgr.Resolve(evidence);
|
|
}
|
|
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public PermissionSet ResolvePolicy( Evidence[] evidences )
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
if (evidences == null || evidences.Length == 0)
|
|
evidences = new Evidence[] { null };
|
|
|
|
PermissionSet retval = ResolvePolicy( evidences[0] );
|
|
if (retval == null)
|
|
return null;
|
|
|
|
for (int i = 1; i < evidences.Length; ++i)
|
|
{
|
|
retval = retval.Intersect( ResolvePolicy( evidences[i] ) );
|
|
if (retval == null || retval.IsEmpty())
|
|
return retval;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
#if FEATURE_CAS_POLICY
|
|
// Determine if the current thread would require a security context capture if the security state of
|
|
// the thread needs to be re-created at a later point in time. This can be used, for instance, if
|
|
// sensitive data is being obtained after security demands succeed, and that data is to be cached.
|
|
// If there is an Assert up the stack, then we wouldn't want to cache the data without capturing the
|
|
// corresponding security context to go along with it - otherwise we risk leaking data obtained
|
|
// under an assert to code which may no longer be running with that assert in place.
|
|
//
|
|
// A return value of false indicates that the CLR guarantees all of the following conditions are true:
|
|
// 1. No partial trust AppDomains are on the stack
|
|
// 2. No partial trust assemblies are on the stack
|
|
// 3. There are no currently active PermitOnly or Deny modifiers on the stack
|
|
//
|
|
// A return value of true means only that the CLR cannot guarantee that all of the conditions are
|
|
// true, and not that one of the conditions really is false.
|
|
//
|
|
// IMPORTANT: The above means is only reliable in the false return case. If we say that the thread
|
|
// does not require a context capture, then that answer is guaranteed to be correct. However, we may
|
|
// say that the thread does require a capture when it does not actually strictly need to capture the
|
|
// state. This is fine, as being overly conservative when capturing context will not lead to
|
|
// security holes; being overly agresssive in avoding the capture could lead to holes however.
|
|
//
|
|
// This API is SecurityCritical because its main use is to optimize away unnecessary security
|
|
// context captures, which means that the code using it is security sensitive and needs to be audited.
|
|
[SecurityCritical]
|
|
public static bool CurrentThreadRequiresSecurityContextCapture()
|
|
{
|
|
// If we know that the thread is not made up of entirely full trust code, and that there are no
|
|
// security stack modifiers on the thread, then there is no need to capture a security context.
|
|
return !CodeAccessSecurityEngine.QuickCheckForAllDemands();
|
|
}
|
|
#endif // FEATURE_CAS_POLICY
|
|
|
|
//
|
|
// This method resolves the policy for the specified evidence, but it
|
|
// ignores the AppDomain level even when one is available in the current policy.
|
|
//
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
public static PermissionSet ResolveSystemPolicy (Evidence evidence)
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
if (PolicyManager.IsGacAssembly(evidence))
|
|
{
|
|
return new PermissionSet(PermissionState.Unrestricted);
|
|
}
|
|
|
|
return polmgr.CodeGroupResolve(evidence, true);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
static public IEnumerator ResolvePolicyGroups(Evidence evidence)
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
return polmgr.ResolveCodeGroups(evidence);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
public static IEnumerator PolicyHierarchy()
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
return polmgr.PolicyHierarchy();
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
|
|
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
|
|
public static void SavePolicy()
|
|
{
|
|
if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
|
|
{
|
|
throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
|
|
}
|
|
|
|
polmgr.Save();
|
|
}
|
|
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
private static PermissionSet ResolveCasPolicy(Evidence evidence,
|
|
PermissionSet reqdPset,
|
|
PermissionSet optPset,
|
|
PermissionSet denyPset,
|
|
out PermissionSet denied,
|
|
out int securitySpecialFlags,
|
|
bool checkExecutionPermission)
|
|
{
|
|
Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
|
|
|
|
CodeAccessPermission.Assert(true);
|
|
|
|
PermissionSet granted = ResolvePolicy(evidence,
|
|
reqdPset,
|
|
optPset,
|
|
denyPset,
|
|
out denied,
|
|
checkExecutionPermission);
|
|
|
|
securitySpecialFlags = SecurityManager.GetSpecialFlags(granted, denied);
|
|
return granted;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
static private PermissionSet ResolvePolicy(Evidence evidence,
|
|
PermissionSet reqdPset,
|
|
PermissionSet optPset,
|
|
PermissionSet denyPset,
|
|
out PermissionSet denied,
|
|
bool checkExecutionPermission)
|
|
{
|
|
Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
|
|
|
|
if (executionSecurityPermission == null)
|
|
executionSecurityPermission = new SecurityPermission(SecurityPermissionFlag.Execution);
|
|
|
|
PermissionSet requested = null;
|
|
PermissionSet optional;
|
|
PermissionSet allowed;
|
|
|
|
Exception savedException = null;
|
|
|
|
// We don't want to recurse back into here as a result of a
|
|
// stackwalk during resolution. So simply assert full trust (this
|
|
// implies that custom permissions cannot use any permissions that
|
|
// don't implement IUnrestrictedPermission.
|
|
// PermissionSet.s_fullTrust.Assert();
|
|
|
|
// The requested set is the union of the minimal request and the
|
|
// optional request. Minimal request defaults to empty, optional
|
|
// is "AllPossible" (includes any permission that can be defined)
|
|
// which is symbolized by null.
|
|
optional = optPset;
|
|
|
|
if (reqdPset == null)
|
|
requested = optional;
|
|
else
|
|
// If optional is null, the requested set becomes null/"AllPossible".
|
|
requested = optional == null ? null : reqdPset.Union(optional);
|
|
|
|
// Make sure that the right to execute is requested (if this feature is
|
|
// enabled).
|
|
|
|
if (requested != null && !requested.IsUnrestricted())
|
|
requested.AddPermission( executionSecurityPermission );
|
|
|
|
// If we aren't passed any evidence, just make an empty object
|
|
if (evidence == null)
|
|
{
|
|
evidence = new Evidence();
|
|
}
|
|
|
|
allowed = polmgr.Resolve(evidence);
|
|
// Intersect the grant with the RequestOptional
|
|
if (requested != null)
|
|
allowed.InplaceIntersect(requested);
|
|
|
|
// Check that we were granted the right to execute.
|
|
if (checkExecutionPermission)
|
|
{
|
|
if (!allowed.Contains(executionSecurityPermission) ||
|
|
(denyPset != null && denyPset.Contains(executionSecurityPermission)))
|
|
{
|
|
throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
|
|
System.__HResults.CORSEC_E_NO_EXEC_PERM,
|
|
savedException);
|
|
}
|
|
}
|
|
|
|
// Check that we were granted at least the minimal set we asked for. Do
|
|
// this before pruning away any overlap with the refused set so that
|
|
// users have the flexability of defining minimal permissions that are
|
|
// only expressable as set differences (e.g. allow access to "C:\" but
|
|
// disallow "C:\Windows").
|
|
if (reqdPset != null && !reqdPset.IsSubsetOf(allowed))
|
|
{
|
|
BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
|
|
throw new PolicyException(Environment.GetResourceString( "Policy_NoRequiredPermission" ),
|
|
System.__HResults.CORSEC_E_MIN_GRANT_FAIL,
|
|
savedException );
|
|
}
|
|
|
|
// Remove any granted permissions that are safe subsets of some denied
|
|
// permission. The remaining denied permissions (if any) are returned
|
|
// along with the modified grant set for use in checks.
|
|
if (denyPset != null)
|
|
{
|
|
BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
|
|
denied = denyPset.Copy();
|
|
allowed.MergeDeniedSet(denied);
|
|
if (denied.IsEmpty())
|
|
denied = null;
|
|
}
|
|
else
|
|
denied = null;
|
|
|
|
allowed.IgnoreTypeLoadFailures = true;
|
|
|
|
return allowed;
|
|
}
|
|
|
|
[Obsolete("Because execution permission checks can no longer be turned off, the CheckExecutionRights property no longer has any effect.")]
|
|
static public bool CheckExecutionRights
|
|
{
|
|
get { return true; }
|
|
|
|
set
|
|
{
|
|
// The setter for this property is a no-op since execution checking can no longer be turned off
|
|
}
|
|
}
|
|
|
|
[Obsolete("Because security can no longer be turned off, the SecurityEnabled property no longer has any effect.")]
|
|
public static bool SecurityEnabled
|
|
{
|
|
get { return true; }
|
|
|
|
set
|
|
{
|
|
// The setter for this property is a no-op since security cannot be turned off
|
|
}
|
|
}
|
|
#endif // #if FEATURE_CAS_POLICY
|
|
|
|
private static int[][] s_BuiltInPermissionIndexMap = {
|
|
new int[] { BuiltInPermissionIndex.EnvironmentPermissionIndex, (int) PermissionType.EnvironmentPermission },
|
|
new int[] { BuiltInPermissionIndex.FileDialogPermissionIndex, (int) PermissionType.FileDialogPermission },
|
|
new int[] { BuiltInPermissionIndex.FileIOPermissionIndex, (int) PermissionType.FileIOPermission },
|
|
new int[] { BuiltInPermissionIndex.ReflectionPermissionIndex, (int) PermissionType.ReflectionPermission },
|
|
new int[] { BuiltInPermissionIndex.SecurityPermissionIndex, (int) PermissionType.SecurityPermission },
|
|
new int[] { BuiltInPermissionIndex.UIPermissionIndex, (int) PermissionType.UIPermission }
|
|
};
|
|
|
|
private static CodeAccessPermission[] s_UnrestrictedSpecialPermissionMap = {
|
|
new EnvironmentPermission(PermissionState.Unrestricted),
|
|
new FileDialogPermission(PermissionState.Unrestricted),
|
|
new FileIOPermission(PermissionState.Unrestricted),
|
|
new ReflectionPermission(PermissionState.Unrestricted),
|
|
new SecurityPermission(PermissionState.Unrestricted),
|
|
new UIPermission(PermissionState.Unrestricted)
|
|
};
|
|
|
|
internal static int GetSpecialFlags (PermissionSet grantSet, PermissionSet deniedSet) {
|
|
if ((grantSet != null && grantSet.IsUnrestricted()) && (deniedSet == null || deniedSet.IsEmpty())) {
|
|
return -1;
|
|
}
|
|
else {
|
|
SecurityPermission securityPermission = null;
|
|
#pragma warning disable 618
|
|
SecurityPermissionFlag securityPermissionFlags = SecurityPermissionFlag.NoFlags;
|
|
#pragma warning restore 618
|
|
ReflectionPermission reflectionPermission = null;
|
|
ReflectionPermissionFlag reflectionPermissionFlags = ReflectionPermissionFlag.NoFlags;
|
|
|
|
CodeAccessPermission[] specialPermissions = new CodeAccessPermission[6];
|
|
if (grantSet != null) {
|
|
if (grantSet.IsUnrestricted()) {
|
|
securityPermissionFlags = SecurityPermissionFlag.AllFlags;
|
|
reflectionPermissionFlags = ReflectionPermission.AllFlagsAndMore;
|
|
for (int i = 0; i < specialPermissions.Length; i++) {
|
|
specialPermissions[i] = s_UnrestrictedSpecialPermissionMap[i];
|
|
}
|
|
}
|
|
else {
|
|
securityPermission = grantSet.GetPermission(BuiltInPermissionIndex.SecurityPermissionIndex) as SecurityPermission;
|
|
if (securityPermission != null)
|
|
securityPermissionFlags = securityPermission.Flags;
|
|
reflectionPermission = grantSet.GetPermission(BuiltInPermissionIndex.ReflectionPermissionIndex) as ReflectionPermission;
|
|
if (reflectionPermission != null)
|
|
reflectionPermissionFlags = reflectionPermission.Flags;
|
|
for (int i = 0; i < specialPermissions.Length; i++) {
|
|
specialPermissions[i] = grantSet.GetPermission(s_BuiltInPermissionIndexMap[i][0]) as CodeAccessPermission;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (deniedSet != null) {
|
|
if (deniedSet.IsUnrestricted()) {
|
|
securityPermissionFlags = SecurityPermissionFlag.NoFlags;
|
|
reflectionPermissionFlags = ReflectionPermissionFlag.NoFlags;
|
|
for (int i = 0; i < s_BuiltInPermissionIndexMap.Length; i++) {
|
|
specialPermissions[i] = null;
|
|
}
|
|
}
|
|
else {
|
|
securityPermission = deniedSet.GetPermission(BuiltInPermissionIndex.SecurityPermissionIndex) as SecurityPermission;
|
|
if (securityPermission != null)
|
|
securityPermissionFlags &= ~securityPermission.Flags;
|
|
reflectionPermission = deniedSet.GetPermission(BuiltInPermissionIndex.ReflectionPermissionIndex) as ReflectionPermission;
|
|
if (reflectionPermission != null)
|
|
reflectionPermissionFlags &= ~reflectionPermission.Flags;
|
|
for (int i = 0; i < s_BuiltInPermissionIndexMap.Length; i++) {
|
|
CodeAccessPermission deniedSpecialPermission = deniedSet.GetPermission(s_BuiltInPermissionIndexMap[i][0]) as CodeAccessPermission;
|
|
if (deniedSpecialPermission != null && !deniedSpecialPermission.IsSubsetOf(null))
|
|
specialPermissions[i] = null; // we don't care about the exact value here.
|
|
}
|
|
}
|
|
}
|
|
int flags = MapToSpecialFlags(securityPermissionFlags, reflectionPermissionFlags);
|
|
if (flags != -1) {
|
|
for (int i = 0; i < specialPermissions.Length; i++) {
|
|
if (specialPermissions[i] != null && ((IUnrestrictedPermission) specialPermissions[i]).IsUnrestricted())
|
|
flags |= (1 << (int) s_BuiltInPermissionIndexMap[i][1]);
|
|
}
|
|
}
|
|
return flags;
|
|
}
|
|
}
|
|
|
|
#pragma warning disable 618
|
|
private static int MapToSpecialFlags (SecurityPermissionFlag securityPermissionFlags, ReflectionPermissionFlag reflectionPermissionFlags) {
|
|
#pragma warning restore 618
|
|
int flags = 0;
|
|
#pragma warning disable 618
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.UnmanagedCode) == SecurityPermissionFlag.UnmanagedCode)
|
|
#pragma warning restore 618
|
|
flags |= (1 << (int) PermissionType.SecurityUnmngdCodeAccess);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.SkipVerification) == SecurityPermissionFlag.SkipVerification)
|
|
flags |= (1 << (int) PermissionType.SecuritySkipVerification);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.Assertion) == SecurityPermissionFlag.Assertion)
|
|
flags |= (1 << (int) PermissionType.SecurityAssert);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.SerializationFormatter) == SecurityPermissionFlag.SerializationFormatter)
|
|
flags |= (1 << (int) PermissionType.SecuritySerialization);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.BindingRedirects) == SecurityPermissionFlag.BindingRedirects)
|
|
flags |= (1 << (int) PermissionType.SecurityBindingRedirects);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.ControlEvidence) == SecurityPermissionFlag.ControlEvidence)
|
|
flags |= (1 << (int) PermissionType.SecurityControlEvidence);
|
|
if ((securityPermissionFlags & SecurityPermissionFlag.ControlPrincipal) == SecurityPermissionFlag.ControlPrincipal)
|
|
flags |= (1 << (int) PermissionType.SecurityControlPrincipal);
|
|
|
|
if ((reflectionPermissionFlags & ReflectionPermissionFlag.RestrictedMemberAccess) == ReflectionPermissionFlag.RestrictedMemberAccess)
|
|
flags |= (1 << (int)PermissionType.ReflectionRestrictedMemberAccess);
|
|
if ((reflectionPermissionFlags & ReflectionPermissionFlag.MemberAccess) == ReflectionPermissionFlag.MemberAccess)
|
|
flags |= (1 << (int) PermissionType.ReflectionMemberAccess);
|
|
|
|
return flags;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
|
|
[SuppressUnmanagedCodeSecurity]
|
|
internal static extern bool IsSameType(String strLeft, String strRight);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[MethodImplAttribute(MethodImplOptions.InternalCall)]
|
|
internal static extern bool _SetThreadSecurity(bool bThreadSecurity);
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
|
|
[SuppressUnmanagedCodeSecurity]
|
|
internal static extern void GetGrantedPermissions(ObjectHandleOnStack retGranted, ObjectHandleOnStack retDenied, StackCrawlMarkHandle stackMark);
|
|
}
|
|
}
|