Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2005-02-25 18:03:53 +0300
committerSebastien Pouliot <sebastien@ximian.com>2005-02-25 18:03:53 +0300
commit4e207b1532f8ed8be08bb16253ea32cf5f4bd2cd (patch)
treec53b9d198137faea595f70a3126d62558011f05a /mcs/class/corlib/System.Security/SecurityManager.cs
parent9376859ca14bb481b6f3b3f528e2bb17255ca049 (diff)
2005-02-25 Sebastien Pouliot <sebastien@ximian.com>
* CodeAccessPermission.cs: Implement Equals for NET_2_0 profile. * PermissionSet.cs: Added code to decode the metadata format used for declarative security in 2.0 (except enums and arrays now). * PermissionSetCollection.cs: Added code to decode from the new metadata format used for declarative security in 2.0. * SecurityManager.cs: Added support for LinkDemandChoice, Inheritance DemandChoice and DemandChoice (2.0). Added support for reflected LinkDemand (promotes the demand to a full Demand). svn path=/trunk/mcs/; revision=41204
Diffstat (limited to 'mcs/class/corlib/System.Security/SecurityManager.cs')
-rw-r--r--mcs/class/corlib/System.Security/SecurityManager.cs157
1 files changed, 127 insertions, 30 deletions
diff --git a/mcs/class/corlib/System.Security/SecurityManager.cs b/mcs/class/corlib/System.Security/SecurityManager.cs
index fe58517dd27..8ac8d68b102 100644
--- a/mcs/class/corlib/System.Security/SecurityManager.cs
+++ b/mcs/class/corlib/System.Security/SecurityManager.cs
@@ -432,42 +432,100 @@ namespace System.Security {
string xml = Encoding.Unicode.GetString (encodedPermissions);
return new PermissionSet (xml);
case 0x2E:
- // TODO: Fx 2.0
- throw new SecurityException ("Unsupported 2.0 metadata format.");
+ // Fx 2.0 are encoded "somewhat, but not enough, like" custom attributes
+ // note: we still support the older format!
+ return PermissionSet.CreateFromBinaryFormat (encodedPermissions);
default:
- throw new SecurityException ("Unknown metadata format.");
+ throw new SecurityException (Locale.GetText ("Unknown metadata format."));
}
}
-
- private static PermissionSet Union (byte[] classPermissions, byte[] methodPermissions)
+#if NET_2_0
+ internal static PermissionSetCollection DecodeCollection (IntPtr permissions, int length)
{
- if (classPermissions != null) {
- PermissionSet ps = Decode (classPermissions);
- if (methodPermissions != null) {
- ps = ps.Union (Decode (methodPermissions));
+ // Permission sets from the runtime (declarative security) can be cached
+ // for performance as they can never change (i.e. they are read-only).
+
+ if (_declsecCache == null) {
+ lock (_lockObject) {
+ if (_declsecCache == null) {
+ _declsecCache = new Hashtable ();
+ }
}
- return ps;
}
- return Decode (methodPermissions);
+ PermissionSetCollection psc = null;
+ lock (_lockObject) {
+ object key = (object) (int) permissions;
+ psc = (PermissionSetCollection) _declsecCache [key];
+ if (psc == null) {
+ // create permissionset and add it to the cache
+ byte[] data = new byte [length];
+ Marshal.Copy (permissions, data, 0, length);
+ psc = DecodeCollection (data);
+ _declsecCache.Add (key, psc);
+ }
+ }
+ return psc;
+ }
+
+ internal static PermissionSetCollection DecodeCollection (byte[] encodedPermissions)
+ {
+ if ((encodedPermissions == null) || (encodedPermissions.Length < 1))
+ throw new SecurityException ("Invalid metadata format.");
+
+ switch (encodedPermissions [0]) {
+ case 60:
+ // Fx 1.0/1.1 declarative security permissions metadata is in Unicode-encoded XML
+ throw new SecurityException (Locale.GetText ("1.0 metadata format doesn't support collections."));
+ case 0x2E:
+ // Fx 2.0 are encoded "somewhat, but not enough, like" custom attributes
+ // note: we still support the older format!
+ return PermissionSetCollection.CreateFromBinaryFormat (encodedPermissions);
+ default:
+ throw new SecurityException (Locale.GetText ("Unknown metadata format."));
+ }
}
+#endif
// security check when using reflection
- internal static void ReflectedLinkDemand ()
+ // When using reflection LinkDemand are promoted to full Demand (i.e. stack walk)
+ private unsafe static void ReflectedLinkDemand (RuntimeDeclSecurityActions *klass, RuntimeDeclSecurityActions *method)
{
- // TODO - get the declarative LinkDemand permission set
PermissionSet ps = null;
- Assembly corlib = typeof (int).Assembly;
- // find the real caller of the icall
- foreach (SecurityFrame f in SecurityFrame.GetStack (0)) {
- // ignore System.Reflection class in corlib
- if ((f.Assembly != corlib) || !f.Method.Name.StartsWith ("System.Reflection")) {
- if (!SecurityManager.IsGranted (f.Assembly, ps, false))
- LinkDemandSecurityException (1, f.Assembly, f.Method);
- }
+ if (klass->cas.size > 0) {
+ ps = Decode (klass->cas.blob, klass->cas.size);
+ }
+ if (klass->noncas.size > 0) {
+ PermissionSet p = Decode (klass->noncas.blob, klass->noncas.size);
+ ps = (ps == null) ? p : ps.Union (p);
+ }
+
+ if (method->cas.size > 0) {
+ PermissionSet p = Decode (method->cas.blob, method->cas.size);
+ ps = (ps == null) ? p : ps.Union (p);
}
+ if (method->noncas.size > 0) {
+ PermissionSet p = Decode (method->noncas.blob, method->noncas.size);
+ ps = (ps == null) ? p : ps.Union (p);
+ }
+
+ // in this case we union-ed the permission sets because we want to do
+ // a single stack walk (not up to 4).
+ if (ps != null)
+ ps.Demand ();
+#if NET_2_0
+ // Process LinkDemandChoice (2.0)
+ if (klass->choice.size > 0) {
+ PermissionSetCollection psc = DecodeCollection (klass->choice.blob, klass->choice.size);
+ psc.DemandChoice ();
+ }
+ if (method->choice.size > 0) {
+ PermissionSetCollection psc = DecodeCollection (method->choice.blob, method->choice.size);
+ psc.DemandChoice ();
+ }
+#endif
}
// internal - get called at JIT time
@@ -481,21 +539,46 @@ namespace System.Security {
ps = Decode (klass->cas.blob, klass->cas.size);
result = SecurityManager.IsGranted (a, ps, false);
}
- if (klass->noncas.size > 0) {
+ if (result && (klass->noncas.size > 0)) {
ps = Decode (klass->noncas.blob, klass->noncas.size);
result = SecurityManager.IsGranted (a, ps, true);
}
- if (method->cas.size > 0) {
+ if (result && (method->cas.size > 0)) {
ps = Decode (method->cas.blob, method->cas.size);
result = SecurityManager.IsGranted (a, ps, false);
}
- if (method->noncas.size > 0) {
+ if (result && (method->noncas.size > 0)) {
ps = Decode (method->noncas.blob, method->noncas.size);
result = SecurityManager.IsGranted (a, ps, true);
}
-
- // TODO LinkDemandChoice (2.0)
+#if NET_2_0
+ // success if one of the permission is granted
+ if (result && (klass->choice.size > 0)) {
+ PermissionSetCollection psc = DecodeCollection (klass->choice.blob, klass->choice.size);
+ if (psc.Count > 0) {
+ result = false;
+ foreach (PermissionSet pset in psc) {
+ if (SecurityManager.IsGranted (a, pset, false)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ if (result && (method->choice.size > 0)) {
+ PermissionSetCollection psc = DecodeCollection (method->choice.blob, method->choice.size);
+ if (psc.Count > 0) {
+ result = false;
+ foreach (PermissionSet pset in psc) {
+ if (SecurityManager.IsGranted (a, pset, false)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+#endif
return result;
}
catch (SecurityException) {
@@ -620,8 +703,21 @@ namespace System.Security {
ps = Decode (actions->noncas.blob, actions->noncas.size);
result = SecurityManager.IsGranted (a, ps, true);
}
-
- // TODO InheritanceDemandChoice (2.0)
+#if NET_2_0
+ // success if one of the permission is granted
+ if (result && (actions->choice.size > 0)) {
+ PermissionSetCollection psc = DecodeCollection (actions->choice.blob, actions->choice.size);
+ if (psc.Count > 0) {
+ result = false;
+ foreach (PermissionSet pset in psc) {
+ if (SecurityManager.IsGranted (a, pset, false)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+#endif
return result;
}
catch (SecurityException) {
@@ -629,6 +725,7 @@ namespace System.Security {
}
}
+
// internal - get called by JIT generated code
private static void InternalDemand (IntPtr permissions, int length)
@@ -640,8 +737,8 @@ namespace System.Security {
private static void InternalDemandChoice (IntPtr permissions, int length)
{
#if NET_2_0
- PermissionSet ps = Decode (permissions, length);
- // TODO
+ PermissionSetCollection psc = DecodeCollection (permissions, length);
+ psc.DemandChoice ();
#else
throw new SecurityException ("SecurityAction.DemandChoice is only possible in 2.0");
#endif