2009-02-10 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  * 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 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 (!mono_security_core_clr_test && !mono_security_core_clr_is_platform_image (image))
52                 return level;
53
54         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_safe_critical_attribute ()))
55                 level = MONO_SECURITY_CORE_CLR_SAFE_CRITICAL;
56         if (cinfo && mono_custom_attrs_has_attr (cinfo, security_critical_attribute ()))
57                 level = MONO_SECURITY_CORE_CLR_CRITICAL;
58
59         return level;
60 }
61
62 MonoSecurityCoreCLRLevel
63 mono_security_core_clr_class_level (MonoClass *class)
64 {
65         MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_class (class);
66         MonoSecurityCoreCLRLevel lvl = mono_security_core_clr_level_from_cinfo (cinfo, class->image);
67
68         if (cinfo)
69                 mono_custom_attrs_free (cinfo);
70
71         if (lvl == MONO_SECURITY_CORE_CLR_TRANSPARENT && class->nested_in)
72                 return mono_security_core_clr_class_level (class->nested_in);
73         else
74                 return lvl;
75 }
76
77 MonoSecurityCoreCLRLevel
78 mono_security_core_clr_method_level (MonoMethod *method, gboolean with_class_level)
79 {
80         MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_method (method);
81         MonoSecurityCoreCLRLevel level = mono_security_core_clr_level_from_cinfo (cinfo, method->klass->image);
82
83         if (with_class_level && level == MONO_SECURITY_CORE_CLR_TRANSPARENT)
84                 level = mono_security_core_clr_class_level (method->klass);
85
86         if (cinfo)
87                 mono_custom_attrs_free (cinfo);
88
89         return level;
90 }
91
92 gboolean
93 mono_security_core_clr_is_platform_image (MonoImage *image)
94 {
95         const char *prefix = mono_assembly_getrootdir ();
96         int prefix_len = strlen (prefix);
97         static const char subprefix[] = "/mono/2.1/";
98         int subprefix_len = strlen (subprefix);
99
100         if (!image->name)
101                 return FALSE;
102         if (strncmp (prefix, image->name, prefix_len) != 0)
103                 return FALSE;
104         if (strncmp (subprefix, image->name + prefix_len, subprefix_len) != 0)
105                 return FALSE;
106         if (strchr (image->name + prefix_len + subprefix_len, '/'))
107                 return FALSE;
108         return TRUE;
109 }
110
111 void
112 mono_security_enable_core_clr ()
113 {
114         mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
115         mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
116 }