+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.
// 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;
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);
+ }
+ }
}
}
}
#if NET_2_0
+ [MonoTODO]
public override bool Equals (object obj)
{
if (obj == null)
public abstract void FromXml (SecurityElement elem);
#if NET_2_0
+ [MonoTODO]
public override int GetHashCode ()
{
return base.GetHashCode ();
}
public virtual PolicyLevel DomainPolicy {
+ // always return null - may be overriden
get { return null; }
}
}
public virtual PermissionSet RefusedSet {
+ // always return null - may be overriden
get { return null; }
}
public virtual Evidence ProvideAssemblyEvidence (Assembly loadedAssembly, Evidence evidence)
{
+ // no changes - may be overriden
return evidence;
}
}
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))
if (permSet == null)
state = PermissionState.Unrestricted;
else {
+ state = permSet.state;
foreach (IPermission p in permSet.list)
list.Add (p);
}
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);
}
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 ()
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 ()
// - 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)]
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) {
}
#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)
_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;
- }
}
}