Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mcs / class / corlib / System.Security / CodeAccessPermission.cs
old mode 100755 (executable)
new mode 100644 (file)
index 447191f..15fbb4a
@@ -9,7 +9,7 @@
 // (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
@@ -35,238 +35,65 @@ using System.Diagnostics;
 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);
 
@@ -287,70 +114,43 @@ namespace System.Security {
                        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
 
@@ -371,10 +171,7 @@ namespace System.Security {
                        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);
@@ -436,21 +233,5 @@ namespace System.Security {
                        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));
-                       }
-               }
        }
 }