1 //
2 // SecurityDeclaration.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // Copyright (c) 2008 - 2011 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 using System;
30 
31 using Mono.Collections.Generic;
32 
33 namespace Mono.Cecil {
34 
35 	public enum SecurityAction : ushort {
36 		Request = 1,
37 		Demand = 2,
38 		Assert = 3,
39 		Deny = 4,
40 		PermitOnly = 5,
41 		LinkDemand = 6,
42 		InheritDemand = 7,
43 		RequestMinimum = 8,
44 		RequestOptional = 9,
45 		RequestRefuse = 10,
46 		PreJitGrant = 11,
47 		PreJitDeny = 12,
48 		NonCasDemand = 13,
49 		NonCasLinkDemand = 14,
50 		NonCasInheritance = 15
51 	}
52 
53 	public interface ISecurityDeclarationProvider : IMetadataTokenProvider {
54 
55 		bool HasSecurityDeclarations { get; }
56 		Collection<SecurityDeclaration> SecurityDeclarations { get; }
57 	}
58 
59 	public sealed class SecurityAttribute : ICustomAttribute {
60 
61 		TypeReference attribute_type;
62 
63 		internal Collection<CustomAttributeNamedArgument> fields;
64 		internal Collection<CustomAttributeNamedArgument> properties;
65 
66 		public TypeReference AttributeType {
67 			get { return attribute_type; }
68 			set { attribute_type = value; }
69 		}
70 
71 		public bool HasFields {
72 			get { return !fields.IsNullOrEmpty (); }
73 		}
74 
75 		public Collection<CustomAttributeNamedArgument> Fields {
76 			get { return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ()); }
77 		}
78 
79 		public bool HasProperties {
80 			get { return !properties.IsNullOrEmpty (); }
81 		}
82 
83 		public Collection<CustomAttributeNamedArgument> Properties {
84 			get { return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ()); }
85 		}
86 
SecurityAttribute(TypeReference attributeType)87 		public SecurityAttribute (TypeReference attributeType)
88 		{
89 			this.attribute_type = attributeType;
90 		}
91 	}
92 
93 	public sealed class SecurityDeclaration {
94 
95 		readonly internal uint signature;
96 		byte [] blob;
97 		readonly ModuleDefinition module;
98 
99 		internal bool resolved;
100 		SecurityAction action;
101 		internal Collection<SecurityAttribute> security_attributes;
102 
103 		public SecurityAction Action {
104 			get { return action; }
105 			set { action = value; }
106 		}
107 
108 		public bool HasSecurityAttributes {
109 			get {
110 				Resolve ();
111 
112 				return !security_attributes.IsNullOrEmpty ();
113 			}
114 		}
115 
116 		public Collection<SecurityAttribute> SecurityAttributes {
117 			get {
118 				Resolve ();
119 
120 				return security_attributes ?? (security_attributes = new Collection<SecurityAttribute> ());
121 			}
122 		}
123 
124 		internal bool HasImage {
125 			get { return module != null && module.HasImage; }
126 		}
127 
SecurityDeclaration(SecurityAction action, uint signature, ModuleDefinition module)128 		internal SecurityDeclaration (SecurityAction action, uint signature, ModuleDefinition module)
129 		{
130 			this.action = action;
131 			this.signature = signature;
132 			this.module = module;
133 		}
134 
SecurityDeclaration(SecurityAction action)135 		public SecurityDeclaration (SecurityAction action)
136 		{
137 			this.action = action;
138 			this.resolved = true;
139 		}
140 
SecurityDeclaration(SecurityAction action, byte [] blob)141 		public SecurityDeclaration (SecurityAction action, byte [] blob)
142 		{
143 			this.action = action;
144 			this.resolved = false;
145 			this.blob = blob;
146 		}
147 
GetBlob()148 		public byte [] GetBlob ()
149 		{
150 			if (blob != null)
151 				return blob;
152 
153 			if (!HasImage || signature == 0)
154 				throw new NotSupportedException ();
155 
156 			return blob = module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature));
157 		}
158 
Resolve()159 		void Resolve ()
160 		{
161 			if (resolved || !HasImage)
162 				return;
163 
164 			module.Read (this, (declaration, reader) => {
165 				reader.ReadSecurityDeclarationSignature (declaration);
166 				return this;
167 			});
168 
169 			resolved = true;
170 		}
171 	}
172 
173 	static partial class Mixin {
174 
GetHasSecurityDeclarations( this ISecurityDeclarationProvider self, ModuleDefinition module)175 		public static bool GetHasSecurityDeclarations (
176 			this ISecurityDeclarationProvider self,
177 			ModuleDefinition module)
178 		{
179 			return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider));
180 		}
181 
GetSecurityDeclarations( this ISecurityDeclarationProvider self, ModuleDefinition module)182 		public static Collection<SecurityDeclaration> GetSecurityDeclarations (
183 			this ISecurityDeclarationProvider self,
184 			ModuleDefinition module)
185 		{
186 			return module.HasImage ()
187 				? module.Read (self, (provider, reader) => reader.ReadSecurityDeclarations (provider))
188 				: new Collection<SecurityDeclaration> ();
189 		}
190 	}
191 }
192