2004-08-11 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Wed, 11 Aug 2004 16:54:45 +0000 (16:54 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Wed, 11 Aug 2004 16:54:45 +0000 (16:54 -0000)
* CodeAccessPermission.cs: Basic implementation for Demand (without
full stack trace, i.e. Assert, Deny and PermitOnly aren't considered).
Added TODO to unimplemented NET_2_0 methods.
* HostSecurityManager.cs: Added comments (as it looked not implemented
even to myself).
* PermissionSet.cs: Fixed Unrestricted when copied. Changed exception
ordering in Copy (ArgumentNullException couldn't work). Made IsEmpty
more robust.
* SecurityManager.cs: Implemented IsGranted using Assembly.Demand.
Basic implementation for policy resolution.

svn path=/trunk/mcs/; revision=32223

mcs/class/corlib/System.Security/ChangeLog
mcs/class/corlib/System.Security/CodeAccessPermission.cs
mcs/class/corlib/System.Security/HostSecurityManager.cs
mcs/class/corlib/System.Security/PermissionSet.cs
mcs/class/corlib/System.Security/SecurityManager.cs

index 8c797f50a92142589f8a04220c69e67e45af4f63..ae32b9a4622060adee611fe729aa0f1dc17775cc 100755 (executable)
@@ -1,3 +1,16 @@
+2004-08-11  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * CodeAccessPermission.cs: Basic implementation for Demand (without
+       full stack trace, i.e. Assert, Deny and PermitOnly aren't considered).
+       Added TODO to unimplemented NET_2_0 methods.
+       * HostSecurityManager.cs: Added comments (as it looked not implemented
+       even to myself).
+       * PermissionSet.cs: Fixed Unrestricted when copied. Changed exception
+       ordering in Copy (ArgumentNullException couldn't work). Made IsEmpty
+       more robust.
+       * SecurityManager.cs: Implemented IsGranted using Assembly.Demand. 
+       Basic implementation for policy resolution.
+
 2004-08-03  Sebastien Pouliot  <sebastien@ximian.com>
 
        * PermissionSetCollection.cs: New class in Fx 2.0.
index 273109384503334b2cd47f4144a8ca0417f22284..b71d8e98fce2b1814c1fd0680009bbcf36635800 100755 (executable)
@@ -31,7 +31,9 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Diagnostics;
 using System.Globalization;
+using System.Reflection;
 using System.Security.Permissions;
 using System.Text;
 
@@ -116,69 +118,33 @@ namespace System.Security {
                public abstract IPermission Copy ();
 
                // LAMESPEC: Documented as virtual
-               [MonoTODO ("MS centralize demands for IBuiltInPermission, but I think we should branch back into indivual permission classes.")]
+               [MonoTODO ("Assert, Deny and PermitOnly aren't yet supported")]
                public void Demand ()
                {
-                       IBuiltInPermission perm = (this as IBuiltInPermission);
-                       if (perm == null)
-                               return; // not sure about this :(
-
-                       bool result = false;
-
-                       // TODO : Loop the stack
-                       // TODO : Loop all permission on the current frame
-                       result = CheckDemand (this);
-                       switch (perm.GetTokenIndex ()) {
-                               case 0: // EnvironmentPermission
-                                       // TODO
-                                       break;
-                               case 1: // FileDialogPermission
-                                       // TODO
-                                       break;
-                               case 2: // FileIOPermission
-                                       // TODO
-                                       break;
-                               case 3: // IsolatedStorageFilePermission
-                                       // TODO
-                                       break;
-                               case 4: // ReflectionPermission
-                                       // TODO
-                                       break;
-                               case 5: // RegistryPermission
-                                       // TODO
-                                       break;
-                               case 6: // SecurityPermission
-                                       // TODO
-                                       break;
-                               case 7: // UIPermission
-                                       // TODO
-                                       break;
-                               case 8: // PrincipalPermission
+                       if (!SecurityManager.SecurityEnabled)
+                               return;
+
+                       Assembly a = null;
+                       StackTrace st = new StackTrace (1); // skip ourself
+                       StackFrame[] frames = st.GetFrames ();
+                       foreach (StackFrame sf in frames) {
+                               MethodBase mb = sf.GetMethod ();
+                               // declarative security checks, when present, must be checked
+                               // for each stack frame
+                               if ((MethodAttributes.HasSecurity & mb.Attributes) == MethodAttributes.HasSecurity) {
                                        // TODO
-                                       break;
-                               case 9: // PublisherIdentityPermission
-                                       // TODO
-                                       break;
-                               case 10: // SiteIdentityPermission
-                                       // TODO
-                                       break;
-                               case 11: // StrongNameIdentityPermission
-                                       // TODO
-                                       break;
-                               case 12: // UrlIdentityPermission
-                                       // TODO
-                                       break;
-                               case 13: // ZoneIdentityPermission
-                                       // TODO
-                                       break;
-                               default:
-                                       string message = String.Format (Locale.GetText ("Unknown IBuiltInPermission #{0}"), perm.GetTokenIndex ());
-                                       throw new SecurityException (message);
-                       }
-
-                       if (!result) {
-                               throw new SecurityException (Locale.GetText (
-                                       "Demand failed."));
+                               }
+                               // 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;
+                               if (a != af) {
+                                       a = af;
+                                       if (!a.Demand (this)) {
+                                               Type t = this.GetType ();
+                                               throw new SecurityException ("Demand failed", t);
+                                       }
+                               }
                        }
                }
 
@@ -189,6 +155,7 @@ namespace System.Security {
                }
 
 #if NET_2_0
+               [MonoTODO]
                public override bool Equals (object obj)
                {
                        if (obj == null)
@@ -203,6 +170,7 @@ namespace System.Security {
                public abstract void FromXml (SecurityElement elem);
 
 #if NET_2_0
+               [MonoTODO]
                public override int GetHashCode ()
                {
                        return base.GetHashCode ();
index 8987ccbfa306c1ed383556012b51cce8f052a250..95ba870214ca8d002da587ebe61d354c328008e7 100644 (file)
@@ -42,6 +42,7 @@ namespace System.Security {
                }
 
                public virtual PolicyLevel DomainPolicy {
+                       // always return null - may be overriden
                        get { return null; }
                }
 
@@ -50,6 +51,7 @@ namespace System.Security {
                }
 
                public virtual PermissionSet RefusedSet {
+                       // always return null - may be overriden
                        get { return null; }
                }
 
@@ -62,6 +64,7 @@ namespace System.Security {
 
                public virtual Evidence ProvideAssemblyEvidence (Assembly loadedAssembly, Evidence evidence)
                {
+                       // no changes - may be overriden
                        return evidence;
                }
        }
index 1583d421ec18fe816196854b1733f70f80963fd6..78f506f508d9d08f6a8019b2578f42bb8dfebe7d 100644 (file)
@@ -52,15 +52,14 @@ namespace System.Security {
                        list = new ArrayList ();
                }
 
-               public PermissionSet (PermissionState state)
+               public PermissionSet (PermissionState state) : this ()
                {
-                       if (!Enum.IsDefined(typeof(System.Security.Permissions.PermissionState), state))
-                               throw new System.ArgumentException(); // state is not a valid System.Security.Permissions.PermissionState value.
+                       if (!Enum.IsDefined (typeof (PermissionState), state))
+                               throw new System.ArgumentException ("state");
                        this.state = state;
-                       list = new ArrayList ();
                }
 
-               public PermissionSet (PermissionSet permSet) : this (PermissionState.None)
+               public PermissionSet (PermissionSet permSet) : this ()
                {
                        // LAMESPEC: This would be handled by the compiler.  No way permSet is not a PermissionSet.
                        //if (!(permSet is PermissionSet))
@@ -68,6 +67,7 @@ namespace System.Security {
                        if (permSet == null)
                                state = PermissionState.Unrestricted;
                        else {
+                               state = permSet.state;
                                foreach (IPermission p in permSet.list)
                                        list.Add (p);
                        }
@@ -105,12 +105,12 @@ namespace System.Security {
 
                public virtual void CopyTo (Array array, int index)
                {
+                       if (null == array)
+                               throw new System.ArgumentNullException ("array"); // array is null.
                        if (array.Rank > 1)
                                throw new System.ArgumentException("Array has more than one dimension"); // array has more than one dimension.
                        if (index < 0 || index >= array.Length)
                                throw new System.IndexOutOfRangeException(); // index is outside the range of allowable values for array.
-                       if (null == array)
-                               throw new System.ArgumentNullException(); // array is null.
                        list.CopyTo (array, index);
                }
 
@@ -242,7 +242,9 @@ namespace System.Security {
                public virtual bool IsEmpty () 
                {
                        // note: Unrestricted isn't empty
-                       return ((state == PermissionState.Unrestricted) ? false : (list.Count == 0));
+                       if (state == PermissionState.Unrestricted)
+                               return false;
+                       return ((list == null) || (list.Count == 0));
                }
 
                public virtual bool IsUnrestricted () 
index c7a479f39ddba5ab21c45798bf2bbef989a4cbf4..563adfa7bb8fa889be4f3421e3e50c51981853d6 100644 (file)
@@ -50,16 +50,13 @@ namespace System.Security {
                private static object _lockObject;
                private static ArrayList _hierarchy;
 
-               private static Hashtable _ht;
-
                static SecurityManager () 
                {
                        // lock(this) is bad
                        // http://msdn.microsoft.com/library/en-us/dnaskdr/html/askgui06032003.asp?frame=true
                        _lockObject = new object ();
-
-                       // temporary (to be relocated)
-                       _ht = new Hashtable ();
+                       securityEnabled = true;
+//                     checkExecutionRights = true;
                }
 
                private SecurityManager ()
@@ -110,8 +107,7 @@ namespace System.Security {
                        // - Policy driven
                        // - Only check the caller (no stack walk required)
                        // - Not affected by overrides (like Assert, Deny and PermitOnly)
-                       Assembly a = Assembly.GetCallingAssembly ();
-                       return DemandFromAssembly (perm, a);
+                       return Assembly.GetCallingAssembly ().Demand (perm);
                }
 
                [SecurityPermission (SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPolicy)]
@@ -169,13 +165,15 @@ namespace System.Security {
                        while (ple.MoveNext ()) {
                                PolicyLevel pl = (PolicyLevel) ple.Current;
                                PolicyStatement pst = pl.Resolve (evidence);
-                               if (ps == null)
-                                       ps = pst.PermissionSet;
-                               else
-                                       ps = ps.Intersect (pst.PermissionSet);
-
-                               if ((pst.Attributes & PolicyStatementAttribute.LevelFinal) == PolicyStatementAttribute.LevelFinal)
-                                       break;
+                               if (pst != null) {
+                                       if (ps == null)
+                                               ps = pst.PermissionSet;
+                                       else
+                                               ps = ps.Intersect (pst.PermissionSet);
+       
+                                       if ((pst.Attributes & PolicyStatementAttribute.LevelFinal) == PolicyStatementAttribute.LevelFinal)
+                                               break;
+                               }
                        }
        
                        foreach (object o in evidence) {
@@ -204,11 +202,32 @@ namespace System.Security {
                }
 #endif
 
+               static private SecurityPermission _execution = new SecurityPermission (SecurityPermissionFlag.Execution);
+
                [MonoTODO()]
                public static PermissionSet ResolvePolicy (Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, out PermissionSet denied)
                {
-                       denied = null;
-                       return null;
+                       PermissionSet resolved = ResolvePolicy (evidence);
+                       // do we have the minimal permission requested by the assembly ?
+                       if ((reqdPset != null) && !reqdPset.IsSubsetOf (resolved)) {
+                               throw new PolicyException (Locale.GetText (
+                                       "Policy doesn't grant the minimal permissions required to execute the assembly."));
+                       }
+                       // do we have the right to execute ?
+                       if (checkExecutionRights) {
+                               // unless we have "Full Trust"...
+                               if (!resolved.IsUnrestricted ()) {
+                                       // ... we need to find a SecurityPermission
+                                       IPermission security = resolved.GetPermission (typeof (SecurityPermission));
+                                       if (!_execution.IsSubsetOf (security)) {
+                                               throw new PolicyException (Locale.GetText (
+                                                       "Policy doesn't grant the right to execute to the assembly."));
+                                       }
+                               }
+                       }
+
+                       denied = denyPset;
+                       return resolved;
                }
 
                public static IEnumerator ResolvePolicyGroups (Evidence evidence)
@@ -277,25 +296,5 @@ namespace System.Security {
 
                        _hierarchy = ArrayList.Synchronized (al);
                }
-
-               private static bool DemandFromAssembly (IPermission demanded, Assembly a) 
-               {
-                       PermissionSet granted = (PermissionSet) _ht [a];
-                       if (granted == null) {
-                               Evidence e = a.Evidence;
-                               lock (_lockObject) {
-                                       granted = SecurityManager.ResolvePolicy (e);
-                                       _ht [a] = granted;
-                               }
-                       }
-
-                       Type t = demanded.GetType ();
-                       IPermission p = granted.GetPermission (t);
-                       if (p != null) {
-                               if (!demanded.IsSubsetOf (p))
-                                       return false;
-                       }
-                       return true;
-               }
        }
 }