2004-12-20 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Mon, 20 Dec 2004 15:31:14 +0000 (15:31 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Mon, 20 Dec 2004 15:31:14 +0000 (15:31 -0000)
* appdomain.c: Bump corlib version.
* class-internals.h: Added RuntimeSecurityFrame to mono_defaults.
* domain.c: Add RuntimeSecurityFrame to mono_defaults.
* reflection.c|h: Add functions to get declarative security infos
(blob position and length) for assemblies, classes and methods.

svn path=/trunk/mono/; revision=37978

mono/metadata/ChangeLog
mono/metadata/appdomain.c
mono/metadata/class-internals.h
mono/metadata/domain.c
mono/metadata/reflection.c
mono/metadata/reflection.h

index 91017cae08f420553ebc5b0b2b2edb7e1e16400e..7ff32ce6930d62df3866cb9f5c385bdc5b632dbe 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-20  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * appdomain.c: Bump corlib version.
+       * class-internals.h: Added RuntimeSecurityFrame to mono_defaults.
+       * domain.c: Add RuntimeSecurityFrame to mono_defaults.
+       * reflection.c|h: Add functions to get declarative security infos
+       (blob position and length) for assemblies, classes and methods.
 
 Mon Dec 20 15:28:54 CET 2004 Paolo Molaro <lupus@ximian.com>
 
index 117bd2ffb2d4d991f1d49153cd793063a45718aa..d481e86374e7d3c4ea9e92c5ce626249df28155d 100644 (file)
@@ -28,7 +28,7 @@
 #include <mono/metadata/threadpool.h>
 #include <mono/utils/mono-uri.h>
 
-#define MONO_CORLIB_VERSION 31
+#define MONO_CORLIB_VERSION 32
 
 CRITICAL_SECTION mono_delegate_section;
 
index a83b9100641d6947b66901327147b7b1cc47caf9..d5a4377687d8007b7767d3004f1752e84a82a4dd 100644 (file)
@@ -497,6 +497,7 @@ typedef struct {
        MonoClass *marshalbyrefobject_class;
        MonoClass *monitor_class;
        MonoClass *iremotingtypeinfo_class;
+       MonoClass *runtimesecurityframe_class;
 } MonoDefaults;
 
 extern MonoDefaults mono_defaults;
index bea41e5ac94e84c2ba18e774046ae92fd810ca18..1e1067911836582d9c7a37988c0a106c84cf429b 100644 (file)
@@ -589,6 +589,10 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
                mono_defaults.corlib, "System.Runtime.Remoting", "IRemotingTypeInfo");
        g_assert (mono_defaults.iremotingtypeinfo_class != 0);
 
+       mono_defaults.runtimesecurityframe_class = mono_class_from_name (
+               mono_defaults.corlib, "System.Security", "RuntimeSecurityFrame");
+       g_assert (mono_defaults.runtimesecurityframe_class != 0);
+
        domain->friendly_name = g_path_get_basename (filename);
 
        return domain;
index 3dfa2e23bc6ffee5e50743755a1435c1d8d15077..f478652e82cc69cd0fe186af3325b54be1749d7e 100644 (file)
@@ -8938,3 +8938,165 @@ mono_declsec_flags_from_assembly (MonoAssembly *assembly)
        idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
        return mono_declsec_get_flags (assembly->image, idx);
 }
+
+
+/*
+ * Fill actions for the specific index (which may either be an encoded class token or
+ * an encoded method token) from the metadata image.
+ * Returns TRUE if some actions requiring code generation are present, FALSE otherwise.
+ */
+static MonoBoolean
+fill_actions_from_index (MonoImage *image, guint32 token, MonoDeclSecurityActions* actions)
+{
+       MonoBoolean result = FALSE;
+       MonoTableInfo *t;
+       guint32 cols [MONO_DECL_SECURITY_SIZE];
+       int index = mono_metadata_declsec_from_index (image, token);
+       int i;
+
+       t  = &image->tables [MONO_TABLE_DECLSECURITY];
+       for (i = index; i < t->rows; i++) {
+               mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
+
+               if (cols [MONO_DECL_SECURITY_PARENT] != token)
+                       return result;
+
+               /* if present only replace (class) permissions with method permissions */
+               /* if empty accept either class or method permissions */
+               switch (cols [MONO_DECL_SECURITY_ACTION]) {
+               case SECURITY_ACTION_DEMAND:
+                       if (!actions->demand.blob) {
+                               const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+                               actions->demand.blob = (char*) (blob + 2);
+                               actions->demand.size = mono_metadata_decode_blob_size (blob, &blob);
+                               result = TRUE;
+                       }
+                       break;
+               case SECURITY_ACTION_NONCASDEMAND:
+                       if (!actions->noncasdemand.blob) {
+                               const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+                               actions->noncasdemand.blob = (char*) (blob + 2);
+                               actions->noncasdemand.size = mono_metadata_decode_blob_size (blob, &blob);
+                               result = TRUE;
+                       }
+                       break;
+               case SECURITY_ACTION_DEMANDCHOICE:
+                       if (!actions->demandchoice.blob) {
+                               const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+                               actions->demandchoice.blob = (char*) (blob + 2);
+                               actions->demandchoice.size = mono_metadata_decode_blob_size (blob, &blob);
+                               result = TRUE;
+                       }
+                       break;
+               }
+       }
+
+       return result;
+}
+
+/*
+ * Collect all actions (that requires to generate code in mini) assigned for
+ * the specified method.
+ * Note: Don't use the content of actions if the function return FALSE.
+ */
+MonoBoolean
+mono_declsec_get_demands (MonoMethod *method, MonoDeclSecurityActions* demands)
+{
+       MonoImage *image = method->klass->image;
+       MonoBoolean result = FALSE;
+       guint32 flags;
+
+       /* quick exit if no declarative security is present in the metadata */
+       if (!image->tables [MONO_TABLE_DECLSECURITY].rows)
+               return FALSE;
+
+       memset (demands, 0, sizeof (MonoDeclSecurityActions));
+
+       /* First we look for method-level attributes */
+       if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
+               guint32 idx = find_method_index (method);
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
+               idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+               result = fill_actions_from_index (image, idx, demands);
+       }
+
+       /* Next we fill holes with class-level attributes */
+       /* Here we use (or create) the class declarative cache to look for demands */
+       flags = mono_declsec_flags_from_class (method->klass);
+       if (flags & (MONO_DECLSEC_FLAG_DEMAND | MONO_DECLSEC_FLAG_NONCAS_DEMAND | MONO_DECLSEC_FLAG_DEMAND_CHOICE)) {
+               guint32 idx = mono_metadata_token_index (method->klass->type_token);
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
+               idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+               result |= fill_actions_from_index (image, idx, demands);
+       }
+
+       /* The boolean return value is used as a shortcut in case nothing needs to
+          be generated (e.g. LinkDemand[Choice] and InheritanceDemand[Choice]) */
+       return result;
+}
+
+static MonoBoolean
+get_declsec_action (MonoImage *image, guint32 token, guint32 action, MonoDeclSecurityEntry *entry)
+{
+       guint32 cols [MONO_DECL_SECURITY_SIZE];
+       MonoTableInfo *t;
+       int i;
+
+       int index = mono_metadata_declsec_from_index (image, token);
+       if (index == -1)
+               return FALSE;
+
+       t =  &image->tables [MONO_TABLE_DECLSECURITY];
+       for (i = index; i < t->rows; i++) {
+               mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
+
+               /* shortcut - index are ordered */
+               if (token != cols [MONO_DECL_SECURITY_PARENT])
+                       return FALSE;
+
+               if (cols [MONO_DECL_SECURITY_ACTION] == action) {
+                       const char *metadata = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+                       entry->blob = (char*) (metadata + 2);
+                       entry->size = mono_metadata_decode_blob_size (metadata, &metadata);
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_method_action (MonoMethod *method, guint32 action, MonoDeclSecurityEntry *entry)
+{
+       if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
+               guint32 idx = find_method_index (method);
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
+               idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+               return get_declsec_action (method->klass->image, idx, action, entry);
+       }
+       return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_class_action (MonoClass *klass, guint32 action, MonoDeclSecurityEntry *entry)
+{
+       /* use cache */
+       guint32 flags = mono_declsec_flags_from_class (klass);
+       if (declsec_flags_map [action] & flags) {
+               guint32 idx = mono_metadata_token_index (klass->type_token);
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
+               idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+               return get_declsec_action (klass->image, idx, action, entry);
+       }
+       return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_assembly_action (MonoAssembly *assembly, guint32 action, MonoDeclSecurityEntry *entry)
+{
+       guint32 idx = 1; /* there is only one assembly */
+       idx <<= MONO_HAS_DECL_SECURITY_BITS;
+       idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
+
+       return get_declsec_action (assembly->image, idx, action, entry);
+}
index f3b14d037c3eda397ae1944e2865bb869951dd80..d245be5d3400223a08e4c0fe7a42021201541811 100644 (file)
@@ -105,5 +105,20 @@ guint32 mono_declsec_flags_from_method (MonoMethod *method);
 guint32 mono_declsec_flags_from_class (MonoClass *klass);
 guint32 mono_declsec_flags_from_assembly (MonoAssembly *assembly);
 
-#endif /* __METADATA_REFLECTION_H__ */
+typedef struct {
+       char *blob;                             /* pointer to metadata blob */
+       guint32 size;                           /* size of the metadata blob */
+} MonoDeclSecurityEntry;
+
+typedef struct {
+       MonoDeclSecurityEntry demand;
+       MonoDeclSecurityEntry noncasdemand;
+       MonoDeclSecurityEntry demandchoice;
+} MonoDeclSecurityActions;
+
+MonoBoolean mono_declsec_get_demands (MonoMethod *callee, MonoDeclSecurityActions* demands);
+MonoBoolean mono_declsec_get_method_action (MonoMethod *method, guint32 action, MonoDeclSecurityEntry *entry);
+MonoBoolean mono_declsec_get_class_action (MonoClass *klass, guint32 action, MonoDeclSecurityEntry *entry);
+MonoBoolean mono_declsec_get_assembly_action (MonoAssembly *assembly, guint32 action, MonoDeclSecurityEntry *entry);
 
+#endif /* __METADATA_REFLECTION_H__ */