1 //
2 // Author:
3 //   Jb Evain (jbevain@gmail.com)
4 //
5 // Copyright (c) 2008 - 2015 Jb Evain
6 // Copyright (c) 2008 - 2011 Novell, Inc.
7 //
8 // Licensed under the MIT/X11 license.
9 //
10 
11 #if !NET_CORE
12 
13 using System;
14 using System.Security;
15 using SSP = System.Security.Permissions;
16 
17 namespace Mono.Cecil.Rocks {
18 
19 #if INSIDE_ROCKS
20 	public
21 #endif
22 	static class SecurityDeclarationRocks {
23 
ToPermissionSet(this SecurityDeclaration self)24 		public static PermissionSet ToPermissionSet (this SecurityDeclaration self)
25 		{
26 			if (self == null)
27 				throw new ArgumentNullException ("self");
28 
29 			PermissionSet set;
30 			if (TryProcessPermissionSetAttribute (self, out set))
31 				return set;
32 
33 			return CreatePermissionSet (self);
34 		}
35 
TryProcessPermissionSetAttribute(SecurityDeclaration declaration, out PermissionSet set)36 		static bool TryProcessPermissionSetAttribute (SecurityDeclaration declaration, out PermissionSet set)
37 		{
38 			set = null;
39 
40 			if (!declaration.HasSecurityAttributes && declaration.SecurityAttributes.Count != 1)
41 				return false;
42 
43 			var security_attribute = declaration.SecurityAttributes [0];
44 			if (!security_attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute"))
45 				return false;
46 
47 			var attribute = new SSP.PermissionSetAttribute ((SSP.SecurityAction) declaration.Action);
48 
49 			var named_argument = security_attribute.Properties [0];
50 			string value = (string) named_argument.Argument.Value;
51 			switch (named_argument.Name) {
52 			case "XML":
53 				attribute.XML = value;
54 				break;
55 			case "Name":
56 				attribute.Name = value;
57 				break;
58 			default:
59 				throw new NotImplementedException (named_argument.Name);
60 			}
61 
62 			set = attribute.CreatePermissionSet ();
63 			return true;
64 		}
65 
CreatePermissionSet(SecurityDeclaration declaration)66 		static PermissionSet CreatePermissionSet (SecurityDeclaration declaration)
67 		{
68 			var set = new PermissionSet (SSP.PermissionState.None);
69 
70 			foreach (var attribute in declaration.SecurityAttributes) {
71 				var permission = CreatePermission (declaration, attribute);
72 				set.AddPermission (permission);
73 			}
74 
75 			return set;
76 		}
77 
CreatePermission(SecurityDeclaration declaration, SecurityAttribute attribute)78 		static IPermission CreatePermission (SecurityDeclaration declaration, SecurityAttribute attribute)
79 		{
80 			var attribute_type = Type.GetType (attribute.AttributeType.FullName);
81 			if (attribute_type == null)
82 				throw new ArgumentException ("attribute");
83 
84 			var security_attribute = CreateSecurityAttribute (attribute_type, declaration);
85 			if (security_attribute == null)
86 				throw new InvalidOperationException ();
87 
88 			CompleteSecurityAttribute (security_attribute, attribute);
89 
90 			return security_attribute.CreatePermission ();
91 		}
92 
CompleteSecurityAttribute(SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)93 		static void CompleteSecurityAttribute (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
94 		{
95 			if (attribute.HasFields)
96 				CompleteSecurityAttributeFields (security_attribute, attribute);
97 
98 			if (attribute.HasProperties)
99 				CompleteSecurityAttributeProperties (security_attribute, attribute);
100 		}
101 
CompleteSecurityAttributeFields(SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)102 		static void CompleteSecurityAttributeFields (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
103 		{
104 			var type = security_attribute.GetType ();
105 
106 			foreach (var named_argument in attribute.Fields)
107 				type.GetField (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value);
108 		}
109 
CompleteSecurityAttributeProperties(SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)110 		static void CompleteSecurityAttributeProperties (SSP.SecurityAttribute security_attribute, SecurityAttribute attribute)
111 		{
112 			var type = security_attribute.GetType ();
113 
114 			foreach (var named_argument in attribute.Properties)
115 				type.GetProperty (named_argument.Name).SetValue (security_attribute, named_argument.Argument.Value, null);
116 		}
117 
CreateSecurityAttribute(Type attribute_type, SecurityDeclaration declaration)118 		static SSP.SecurityAttribute CreateSecurityAttribute (Type attribute_type, SecurityDeclaration declaration)
119 		{
120 			SSP.SecurityAttribute security_attribute;
121 			try {
122 				security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (
123 					attribute_type, new object [] { (SSP.SecurityAction) declaration.Action });
124 			} catch (MissingMethodException) {
125 				security_attribute = (SSP.SecurityAttribute) Activator.CreateInstance (attribute_type, new object [0]);
126 			}
127 
128 			return security_attribute;
129 		}
130 
ToSecurityDeclaration(this PermissionSet self, SecurityAction action, ModuleDefinition module)131 		public static SecurityDeclaration ToSecurityDeclaration (this PermissionSet self, SecurityAction action, ModuleDefinition module)
132 		{
133 			if (self == null)
134 				throw new ArgumentNullException ("self");
135 			if (module == null)
136 				throw new ArgumentNullException ("module");
137 
138 			var declaration = new SecurityDeclaration (action);
139 
140 			var attribute = new SecurityAttribute (
141 				module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute"));
142 
143 			attribute.Properties.Add (
144 				new CustomAttributeNamedArgument (
145 					"XML",
146 					new CustomAttributeArgument (
147 						module.TypeSystem.String, self.ToXml ().ToString ())));
148 
149 			declaration.SecurityAttributes.Add (attribute);
150 
151 			return declaration;
152 		}
153 	}
154 }
155 
156 #endif
157