// (C) Ximian, Inc. http://www.ximian.com
// Copyright (C) 2001 Nick Drochak, All Rights Reserved
// Portions (C) 2004 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Security.Permissions;
+using System.Threading;
namespace System.Security {
[Serializable]
+ [SecurityPermission (SecurityAction.InheritanceDemand, ControlEvidence = true, ControlPolicy = true)]
+ [ComVisible (true)]
+ [MonoTODO ("CAS support is experimental (and unsupported).")]
public abstract class CodeAccessPermission : IPermission, ISecurityEncodable, IStackWalk {
- internal enum StackModifier {
- Assert = 1,
- Deny = 2,
- PermitOnly = 3
- }
protected CodeAccessPermission ()
{
}
- // LAMESPEC: Documented as virtual
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public void Assert ()
{
- // Not everyone can assert freely so we must check for
- // System.Security.Permissions.SecurityPermissionFlag.Assertion
- new SecurityPermission (SecurityPermissionFlag.Assertion).Demand ();
-
- // we must have the permission to assert it to others
- if (SecurityManager.IsGranted (this)) {
- SetCurrentFrame (StackModifier.Assert, this.Copy ());
- }
- }
-
-#if NET_2_0
- public virtual
-#else
- internal
-#endif
- bool CheckAssert (CodeAccessPermission asserted)
- {
- if (asserted == null)
- return false;
- if (asserted.GetType () != this.GetType ())
- return false;
- return IsSubsetOf (asserted);
- }
-
-#if NET_2_0
- public virtual
-#else
- internal
-#endif
- bool CheckDemand (CodeAccessPermission target)
- {
- if (target == null)
- return false;
- if (target.GetType () != this.GetType ())
- return false;
- return IsSubsetOf (target);
- }
-
-#if NET_2_0
- public virtual
-#else
- internal
-#endif
- bool CheckDeny (CodeAccessPermission denied)
- {
- if (denied == null)
- return true;
- if (denied.GetType () != this.GetType ())
- return true;
- return (Intersect (denied) == null);
- }
-
-#if NET_2_0
- public
-#else
- internal
-#endif
- virtual bool CheckPermitOnly (CodeAccessPermission target)
- {
- if (target == null)
- return false;
- if (target.GetType () != this.GetType ())
- return false;
- return IsSubsetOf (target);
+ new PermissionSet (this).Assert ();
}
public abstract IPermission Copy ();
- // LAMESPEC: Documented as virtual
- [MonoTODO ("Assert, Deny and PermitOnly aren't yet supported")]
public void Demand ()
{
+ // note: here we're sure it's a CAS demand
if (!SecurityManager.SecurityEnabled)
return;
- // Order is:
- // 1. CheckDemand (current frame)
- // note: for declarative attributes directly calls IsSubsetOf
-
- Assembly a = null;
- StackTrace st = new StackTrace (1); // skip ourself
- StackFrame[] frames = st.GetFrames ();
- foreach (StackFrame sf in frames) {
- MethodBase mb = sf.GetMethod ();
- // however the "final" grant set is resolved by assembly, so
- // there's no need to check it every time (just when we're
- // changing assemblies between frames).
- Assembly af = mb.ReflectedType.Assembly;
- CodeAccessPermission cap = null;
- if (a != af) {
- a = af;
- if (a.GrantedPermissionSet != null)
- cap = (CodeAccessPermission) a.GrantedPermissionSet.GetPermission (this.GetType ());
- else
- cap = null;
-
- // CheckDemand will always return false in case cap is null
- if ((cap == null) || !CheckDemand (cap)) {
- if (a.DeniedPermissionSet != null) {
- cap = (CodeAccessPermission) a.DeniedPermissionSet.GetPermission (this.GetType ());
- }
- else
- cap = null;
-
- // IsSubsetOf "should" always return false if cap is null
- if ((cap != null) && IsSubsetOf (cap)) {
- Type t = this.GetType ();
- // TODO add more details
- throw new SecurityException ("ReqRefuse", t);
- }
- }
- else {
- throw new SecurityException ("Demand failed", a.GetName (),
- a.GrantedPermissionSet, a.DeniedPermissionSet, (MethodInfo) mb,
- SecurityAction.Demand, this, cap, a.Evidence);
- }
- }
- object[] perms = GetFramePermissions ();
- if (perms == null)
- continue;
-
- // 2. CheckPermitOnly
- object o = perms [(int)StackModifier.PermitOnly];
- if (o != null) {
- cap = (o as CodeAccessPermission);
- if (cap != null) {
- if (!CheckPermitOnly (cap))
- throw new SecurityException ("PermitOnly");
- }
- else {
- PermissionSet ps = (o as PermissionSet);
- foreach (IPermission p in ps) {
- if (p is CodeAccessPermission) {
- if (!CheckPermitOnly (p as CodeAccessPermission))
- throw new SecurityException ("PermitOnly");
- }
- }
- }
- }
-
- // 3. CheckDeny
- o = perms [(int)StackModifier.Deny];
- if (o != null) {
- cap = (o as CodeAccessPermission) ;
- if (cap != null) {
- if (!CheckDeny (cap))
- throw new SecurityException ("Deny");
- }
- else {
- PermissionSet ps = (o as PermissionSet);
- foreach (IPermission p in ps) {
- if (p is CodeAccessPermission) {
- if (!CheckPermitOnly (p as CodeAccessPermission))
- throw new SecurityException ("Deny");
- }
- }
- }
- }
-
- // 4. CheckAssert
- o = perms [(int)StackModifier.Assert];
- if (o != null) {
- cap = (o as CodeAccessPermission);
- if (cap != null) {
- if (CheckAssert (cap)) {
- return; // stop the stack walk
- }
- }
- else {
- PermissionSet ps = (o as PermissionSet);
- foreach (IPermission p in ps) {
- if (p is CodeAccessPermission) {
- if (!CheckPermitOnly (p as CodeAccessPermission)) {
- return; // stop the stack walk
- }
- }
- }
- }
- }
- }
+ // skip frames until we get the caller (of our caller)
+ new PermissionSet (this).CasOnlyDemand (3);
}
- // LAMESPEC: Documented as virtual
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public void Deny ()
{
- SetCurrentFrame (StackModifier.Deny, this.Copy ());
+ new PermissionSet (this).Deny ();
}
-#if NET_2_0
- [MonoTODO]
+ [ComVisible (false)]
public override bool Equals (object obj)
{
if (obj == null)
return false;
if (obj.GetType () != this.GetType ())
return false;
- // TODO: compare
- return true;
+ CodeAccessPermission cap = (obj as CodeAccessPermission);
+ return (IsSubsetOf (cap) && cap.IsSubsetOf (this));
}
-#endif
public abstract void FromXml (SecurityElement elem);
-#if NET_2_0
- [MonoTODO]
+ [ComVisible (false)]
public override int GetHashCode ()
{
return base.GetHashCode ();
}
-#endif
public abstract IPermission Intersect (IPermission target);
return null;
}
- // LAMESPEC: Documented as virtual
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public void PermitOnly ()
{
- SetCurrentFrame (StackModifier.PermitOnly, this.Copy ());
+ new PermissionSet (this).PermitOnly ();
}
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public static void RevertAll ()
{
- if (!ClearFramePermissions ()) {
- string msg = Locale.GetText ("No security frame present to be reverted.");
- throw new ExecutionEngineException (msg);
- }
+ if (!SecurityManager.SecurityEnabled)
+ return;
+ throw new NotImplementedException ();
}
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public static void RevertAssert ()
{
- RevertCurrentFrame (StackModifier.Assert);
+ if (!SecurityManager.SecurityEnabled)
+ return;
+ throw new NotImplementedException ();
}
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public static void RevertDeny ()
{
- RevertCurrentFrame (StackModifier.Deny);
+ if (!SecurityManager.SecurityEnabled)
+ return;
+ throw new NotImplementedException ();
}
- [MonoTODO ("unmanaged side is incomplete")]
+ [MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
public static void RevertPermitOnly ()
{
- RevertCurrentFrame (StackModifier.PermitOnly);
- }
-
- // Internal calls
-#if false
- // see mono/mono/metadata/cas.c for implementation
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern bool ClearFramePermissions ();
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern object[] GetFramePermissions ();
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern bool SetFramePermissions (int index, object permissions);
-#else
- // icalls are not yet commited so...
-
- static bool ClearFramePermissions ()
- {
- return true;
- }
-
- static object[] GetFramePermissions ()
- {
- return null;
- }
-
- static bool SetFramePermissions (int index, object permissions)
- {
- return true;
+ if (!SecurityManager.SecurityEnabled)
+ return;
+ throw new NotImplementedException ();
}
-#endif
// Internal helpers methods
case PermissionState.None:
break;
case PermissionState.Unrestricted:
- if (!allowUnrestricted) {
- msg = Locale.GetText ("Unrestricted isn't not allowed for identity permissions.");
- throw new ArgumentException (msg, "state");
- }
+ // unrestricted permissions are possible for identiy permissions
break;
default:
msg = String.Format (Locale.GetText ("Invalid enum {0}"), state);
msg = String.Format (msg, target.GetType (), expected);
throw new ArgumentException (msg, "target");
}
-
- internal static void SetCurrentFrame (StackModifier stackmod, object permissions)
- {
- if (!SetFramePermissions ((int)stackmod, permissions)) {
- string msg = Locale.GetText ("An {0} modifier is already present on the current stack frame.");
- throw new SecurityException (String.Format (msg, stackmod));
- }
- }
-
- internal static void RevertCurrentFrame (StackModifier stackmod)
- {
- if (!SetFramePermissions ((int)stackmod, null)) {
- string msg = Locale.GetText ("No {0} modifier is present on the current stack frame.");
- throw new ExecutionEngineException (String.Format (msg, stackmod));
- }
- }
}
}