2005-01-25 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mono / mini / declsec.c
1 /*
2  * declsec.c:  Declarative Security support
3  *
4  * Author:
5  *      Sebastien Pouliot  <sebastien@ximian.com>
6  *
7  * Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
8  */
9
10 #include "declsec.h"
11
12 /*
13  * Does the methods (or it's class) as any declarative security attribute ?
14  * Is so are they applicable ? (e.g. static class constructor)
15  */
16 MonoBoolean
17 mono_method_has_declsec (MonoMethod *method)
18 {
19         if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
20                 method = mono_marshal_method_from_wrapper (method);
21                 if (!method)
22                         return FALSE;
23         } else if (method->wrapper_type != MONO_WRAPPER_NONE)
24                 return FALSE;
25
26         if ((method->klass->flags & TYPE_ATTRIBUTE_HAS_SECURITY) || (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
27                 /* ignore static constructors */
28                 if (strcmp (method->name, ".cctor"))
29                         return TRUE;
30         }
31         return FALSE;
32 }
33
34
35 /*
36  * Fill actions for the specific index (which may either be an encoded class token or
37  * an encoded method token) from the metadata image.
38  * Returns TRUE if some actions requiring code generation are present, FALSE otherwise.
39  */
40 void
41 mono_declsec_cache_stack_modifiers (MonoJitInfo *jinfo)
42 {
43         /* first find the stack modifiers applied to the method */
44         guint32 flags = mono_declsec_flags_from_method (jinfo->method);
45         jinfo->cas_method_assert = (flags & MONO_DECLSEC_FLAG_ASSERT) != 0;
46         jinfo->cas_method_deny = (flags & MONO_DECLSEC_FLAG_DENY) != 0;
47         jinfo->cas_method_permitonly = (flags & MONO_DECLSEC_FLAG_PERMITONLY) != 0;
48
49         /* then find the stack modifiers applied to the class */
50         flags = mono_declsec_flags_from_class (jinfo->method->klass);
51         jinfo->cas_class_assert = (flags & MONO_DECLSEC_FLAG_ASSERT) != 0;
52         jinfo->cas_class_deny = (flags & MONO_DECLSEC_FLAG_DENY) != 0;
53         jinfo->cas_class_permitonly = (flags & MONO_DECLSEC_FLAG_PERMITONLY) != 0;
54 }
55
56
57 MonoSecurityFrame*
58 mono_declsec_create_frame (MonoDomain *domain, MonoJitInfo *jinfo)
59 {
60         MonoSecurityFrame *frame = (MonoSecurityFrame*) mono_object_new (domain, mono_defaults.runtimesecurityframe_class);
61
62         if (!jinfo->cas_inited) {
63                 if (mono_method_has_declsec (jinfo->method)) {
64                         /* Cache the stack modifiers into the MonoJitInfo structure to speed up future stack walks */
65                         mono_declsec_cache_stack_modifiers (jinfo);
66                 }
67                 jinfo->cas_inited = TRUE;
68         }
69
70         frame->method = mono_method_get_object (domain, jinfo->method, NULL);
71
72         /* stack modifiers on methods have priority on (i.e. replaces) modifiers on class */
73
74         if (jinfo->cas_method_assert) {
75                 mono_declsec_get_method_action (jinfo->method, SECURITY_ACTION_ASSERT, &frame->assert);
76         } else if (jinfo->cas_class_assert) {
77                 mono_declsec_get_class_action (jinfo->method->klass, SECURITY_ACTION_ASSERT, &frame->assert);
78         }
79
80         if (jinfo->cas_method_deny) {
81                 mono_declsec_get_method_action (jinfo->method, SECURITY_ACTION_DENY, &frame->deny);
82         } else if (jinfo->cas_class_deny) {
83                 mono_declsec_get_class_action (jinfo->method->klass, SECURITY_ACTION_DENY, &frame->deny);
84         }
85
86         if (jinfo->cas_method_permitonly) {
87                 mono_declsec_get_method_action (jinfo->method, SECURITY_ACTION_PERMITONLY, &frame->permitonly);
88         } else if (jinfo->cas_class_permitonly) {
89                 mono_declsec_get_class_action (jinfo->method->klass, SECURITY_ACTION_PERMITONLY, &frame->permitonly);
90         }
91
92         /* g_warning ("FRAME %s A(%p,%d) D(%p,%d) PO(%p,%d)", 
93         jinfo->method->name, frame->assert.blob, frame->assert.size, frame->deny.blob, frame->deny.size, frame->permitonly.blob,frame->permitonly.size); */
94
95         return frame;
96 }