2008-03-06 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / security-core-clr.c
1 /*
2  * security-core-clr.c: CoreCLR security
3  *
4  * Author:
5  *      Mark Probst <mark.probst@gmail.com>
6  *
7  * (C) 2007 Novell, Inc
8  */
9
10 #include <mono/metadata/class-internals.h>
11 #include <mono/metadata/security-manager.h>
12 #include <mono/metadata/assembly.h>
13
14 #include "security-core-clr.h"
15
16 gboolean mono_security_core_clr_test = FALSE;
17
18 static MonoClass*
19 security_critical_attribute (void)
20 {
21         static MonoClass *class = NULL;
22
23         if (!class) {
24                 class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
25                         "SecurityCriticalAttribute");
26         }
27         g_assert (class);
28         return class;
29 }
30
31 static MonoClass*
32 security_safe_critical_attribute (void)
33 {
34         static MonoClass *class = NULL;
35
36         if (!class) {
37                 class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
38                         "SecuritySafeCriticalAttribute");
39         }
40         g_assert (class);
41         return class;
42 }
43
44 MonoSecurityCoreCLRLevel
45 mono_security_core_clr_level_from_cinfo (MonoCustomAttrInfo *cinfo, MonoImage *image)
46 {
47         int level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
48
49         if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (image))
50                 return level;
51
52         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_safe_critical_attribute ()))
53                 level = MONO_SECURITY_CORE_CLR_SAFE_CRITICAL;
54         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_critical_attribute ()))
55                 level = MONO_SECURITY_CORE_CLR_CRITICAL;
56
57         return level;
58 }
59
60 MonoSecurityCoreCLRLevel
61 mono_security_core_clr_class_level (MonoClass *class)
62 {
63         MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_class (class);
64         MonoSecurityCoreCLRLevel lvl = mono_security_core_clr_level_from_cinfo (cinfo, class->image);
65
66         if (cinfo)
67                 mono_custom_attrs_free (cinfo);
68
69         if (lvl == MONO_SECURITY_CORE_CLR_TRANSPARENT && class->nested_in)
70                 return mono_security_core_clr_class_level (class->nested_in);
71         else
72                 return lvl;
73 }
74
75 MonoSecurityCoreCLRLevel
76 mono_security_core_clr_method_level (MonoMethod *method, gboolean with_class_level)
77 {
78         MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_method (method);
79         MonoSecurityCoreCLRLevel level = mono_security_core_clr_level_from_cinfo (cinfo, method->klass->image);
80
81         if (with_class_level && level == MONO_SECURITY_CORE_CLR_TRANSPARENT)
82                 level = mono_security_core_clr_class_level (method->klass);
83
84         if (cinfo)
85                 mono_custom_attrs_free (cinfo);
86
87         return level;
88 }
89
90 gboolean
91 mono_security_core_clr_is_platform_image (MonoImage *image)
92 {
93         const char *prefix = mono_assembly_getrootdir ();
94         int prefix_len = strlen (prefix);
95         static const char subprefix[] = "/mono/2.1/";
96         int subprefix_len = strlen (subprefix);
97
98         if (!image->name)
99                 return FALSE;
100         if (strncmp (prefix, image->name, prefix_len) != 0)
101                 return FALSE;
102         if (strncmp (subprefix, image->name + prefix_len, subprefix_len) != 0)
103                 return FALSE;
104         if (strchr (image->name + prefix_len + subprefix_len, '/'))
105                 return FALSE;
106         return TRUE;
107 }