2009-03-20 Sebastien Pouliot <sebastien@ximian.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  * Copyright 2007-2009 Novell, Inc (http://www.novell.com)
8  */
9
10 #include <mono/metadata/class-internals.h>
11 #include <mono/metadata/security-manager.h>
12 #include <mono/metadata/assembly.h>
13 #include <mono/metadata/appdomain.h>
14 #include <mono/metadata/verify-internals.h>
15
16 #include "security-core-clr.h"
17
18 gboolean mono_security_core_clr_test = FALSE;
19
20 static MonoClass*
21 security_critical_attribute (void)
22 {
23         static MonoClass *class = NULL;
24
25         if (!class) {
26                 class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
27                         "SecurityCriticalAttribute");
28         }
29         g_assert (class);
30         return class;
31 }
32
33 static MonoClass*
34 security_safe_critical_attribute (void)
35 {
36         static MonoClass *class = NULL;
37
38         if (!class) {
39                 class = mono_class_from_name (mono_defaults.corlib, "System.Security", 
40                         "SecuritySafeCriticalAttribute");
41         }
42         g_assert (class);
43         return class;
44 }
45
46 static MonoSecurityCoreCLRLevel
47 mono_security_core_clr_level_from_cinfo (MonoCustomAttrInfo *cinfo, MonoImage *image)
48 {
49         int level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
50
51         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_safe_critical_attribute ()))
52                 level = MONO_SECURITY_CORE_CLR_SAFE_CRITICAL;
53         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_critical_attribute ()))
54                 level = MONO_SECURITY_CORE_CLR_CRITICAL;
55
56         return level;
57 }
58
59 MonoSecurityCoreCLRLevel
60 mono_security_core_clr_class_level (MonoClass *class)
61 {
62         MonoCustomAttrInfo *cinfo;
63         MonoSecurityCoreCLRLevel level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
64
65         /* non-platform code is always Transparent - whatever the attributes says */
66         if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (class->image))
67                 return level;
68
69         cinfo = mono_custom_attrs_from_class (class);
70         if (cinfo) {
71                 level = mono_security_core_clr_level_from_cinfo (cinfo, class->image);
72                 mono_custom_attrs_free (cinfo);
73         }
74
75         if (level == MONO_SECURITY_CORE_CLR_TRANSPARENT && class->nested_in)
76                 level = mono_security_core_clr_class_level (class->nested_in);
77
78         return level;
79 }
80
81 MonoSecurityCoreCLRLevel
82 mono_security_core_clr_method_level (MonoMethod *method, gboolean with_class_level)
83 {
84         MonoCustomAttrInfo *cinfo;
85         MonoSecurityCoreCLRLevel level = MONO_SECURITY_CORE_CLR_TRANSPARENT;
86
87         /* non-platform code is always Transparent - whatever the attributes says */
88         if (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (method->klass->image))
89                 return level;
90
91         cinfo = mono_custom_attrs_from_method (method);
92         if (cinfo) {
93                 level = mono_security_core_clr_level_from_cinfo (cinfo, method->klass->image);
94                 mono_custom_attrs_free (cinfo);
95         }
96
97         if (with_class_level && level == MONO_SECURITY_CORE_CLR_TRANSPARENT)
98                 level = mono_security_core_clr_class_level (method->klass);
99
100         return level;
101 }
102
103 gboolean
104 mono_security_core_clr_is_platform_image (MonoImage *image)
105 {
106         const char *prefix = mono_assembly_getrootdir ();
107         int prefix_len = strlen (prefix);
108         static const char subprefix[] = "/mono/2.1/";
109         int subprefix_len = strlen (subprefix);
110
111         if (!image->name)
112                 return FALSE;
113         if (strncmp (prefix, image->name, prefix_len) != 0)
114                 return FALSE;
115         if (strncmp (subprefix, image->name + prefix_len, subprefix_len) != 0)
116                 return FALSE;
117         if (strchr (image->name + prefix_len + subprefix_len, '/'))
118                 return FALSE;
119         return TRUE;
120 }
121
122 void
123 mono_security_enable_core_clr ()
124 {
125         mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
126         mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
127 }