2010-05-27 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.Security.Policy / CodeGroup.cs
blob083af5198961ff30de1459a8860855fb48bc76c6
1 //
2 // System.Security.Policy.CodeGroup
3 //
4 // Authors:
5 // Nick Drochak (ndrochak@gol.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // (C) 2001 Nick Drochak, All rights reserved.
9 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
32 using System.Globalization;
33 using System.Reflection;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
37 namespace System.Security.Policy {
39 [Serializable]
40 [ComVisible (true)]
41 public abstract class CodeGroup {
42 PolicyStatement m_policy;
43 IMembershipCondition m_membershipCondition;
44 string m_description;
45 string m_name;
46 ArrayList m_children = new ArrayList();
47 // PolicyLevel m_level;
49 protected CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
51 if (null == membershipCondition)
52 throw new ArgumentNullException ("membershipCondition");
54 if (policy != null)
55 m_policy = policy.Copy ();
56 m_membershipCondition = membershipCondition.Copy ();
59 // for PolicyLevel (to avoid validation duplication)
60 internal CodeGroup (SecurityElement e, PolicyLevel level)
62 FromXml (e, level);
65 // abstract
67 public abstract CodeGroup Copy ();
69 public abstract string MergeLogic { get; }
71 public abstract PolicyStatement Resolve (Evidence evidence);
73 public abstract CodeGroup ResolveMatchingCodeGroups (Evidence evidence);
75 // properties
77 public PolicyStatement PolicyStatement {
78 get { return m_policy; }
79 set { m_policy = value; }
82 public string Description {
83 get { return m_description; }
84 set { m_description = value; }
87 public IMembershipCondition MembershipCondition {
88 get { return m_membershipCondition; }
89 set {
90 if (null == value)
91 throw new ArgumentException ("value");
92 m_membershipCondition = value;
96 public string Name {
97 get { return m_name; }
98 set { m_name = value; }
101 public IList Children {
102 get { return m_children; }
103 set {
104 if (null == value)
105 throw new ArgumentNullException ("value");
106 m_children = new ArrayList (value);
110 public virtual string AttributeString {
111 get {
112 if (null != m_policy)
113 return m_policy.AttributeString;
114 return null;
118 public virtual string PermissionSetName {
119 get {
120 if (m_policy == null)
121 return null;
122 if (m_policy.PermissionSet is Security.NamedPermissionSet)
123 return ((NamedPermissionSet)(m_policy.PermissionSet)).Name;
124 return null;
128 public void AddChild (CodeGroup group)
130 if (null == group)
131 throw new ArgumentNullException ("group");
133 m_children.Add (group.Copy ());
136 public override bool Equals (object o)
138 CodeGroup cg = (o as CodeGroup);
139 if (cg == null)
140 return false;
142 return Equals (cg, false);
145 public bool Equals (CodeGroup cg, bool compareChildren)
147 if (cg.Name != this.Name)
148 return false;
150 if (cg.Description != this.Description)
151 return false;
153 if (!cg.MembershipCondition.Equals (m_membershipCondition))
154 return false;
156 if (compareChildren) {
157 int childCount = cg.Children.Count;
158 if (this.Children.Count != childCount)
159 return false;
161 for (int index = 0; index < childCount; index++) {
162 // not a deep compare
163 if (!((CodeGroup)(this.Children [index])).Equals ((CodeGroup)(cg.Children [index]), false))
164 return false;
167 return true;
170 public void RemoveChild (CodeGroup group)
172 if (group != null)
173 m_children.Remove (group);
176 public override int GetHashCode ()
178 int hashCode = m_membershipCondition.GetHashCode ();
179 if (m_policy != null)
180 hashCode += m_policy.GetHashCode ();
181 return hashCode;
184 public void FromXml (SecurityElement e)
186 FromXml (e, null);
189 public void FromXml (SecurityElement e, PolicyLevel level)
191 if (null == e)
192 throw new ArgumentNullException("e");
194 PermissionSet ps = null;
195 string psetname = e.Attribute ("PermissionSetName");
196 if ((psetname != null) && (level != null)) {
197 ps = level.GetNamedPermissionSet (psetname);
199 else {
200 SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
201 if (pset != null) {
202 Type classType = Type.GetType (pset.Attribute ("class"));
203 ps = (PermissionSet) Activator.CreateInstance (classType, true);
204 ps.FromXml (pset);
206 else {
207 ps = new PermissionSet (new PermissionSet (PermissionState.None));
210 m_policy = new PolicyStatement (ps);
212 m_children.Clear ();
213 if ((e.Children != null) && (e.Children.Count > 0)) {
214 foreach (SecurityElement se in e.Children) {
215 if (se.Tag == "CodeGroup") {
216 this.AddChild (CodeGroup.CreateFromXml (se, level));
221 m_membershipCondition = null;
222 SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
223 if (mc != null) {
224 string className = mc.Attribute ("class");
225 Type classType = Type.GetType (className);
226 if (classType == null)
227 classType = Type.GetType ("System.Security.Policy." + className);
228 m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType, true);
229 m_membershipCondition.FromXml (mc, level);
232 m_name = e.Attribute("Name");
233 m_description = e.Attribute("Description");
235 // seems like we might need this to Resolve() in subclasses
236 //m_level = level;
238 ParseXml (e, level);
241 protected virtual void ParseXml (SecurityElement e, PolicyLevel level)
245 public SecurityElement ToXml ()
247 return ToXml (null);
250 public SecurityElement ToXml (PolicyLevel level)
252 SecurityElement e = new SecurityElement("CodeGroup");
253 e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
254 e.AddAttribute("version", "1");
256 if (null != Name)
257 e.AddAttribute("Name", Name);
259 if (null != Description)
260 e.AddAttribute("Description", Description);
262 if (null != MembershipCondition)
263 e.AddChild(MembershipCondition.ToXml());
265 if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
266 e.AddChild (PolicyStatement.PermissionSet.ToXml ());
268 foreach (CodeGroup child in Children)
269 e.AddChild(child.ToXml());
271 CreateXml(e, level);
272 return e;
275 protected virtual void CreateXml (SecurityElement element, PolicyLevel level)
279 // internal stuff
281 internal static CodeGroup CreateFromXml (SecurityElement se, PolicyLevel level)
283 string fullClassName = se.Attribute ("class");
284 string className = fullClassName;
285 // many possible formats
286 // a. "FirstMatchCodeGroup"
287 // b. "System.Security.Policy.FirstMatchCodeGroup"
288 // c. "System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\n version=\"1\">\r\n <IMembershipCondition class=\"System.Security.Policy.AllMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
289 int n = className.IndexOf (",");
290 if (n > 0) {
291 className = className.Substring (0, n);
293 n = className.LastIndexOf (".");
294 if (n > 0)
295 className = className.Substring (n + 1);
296 // much faster than calling Activator.CreateInstance
297 switch (className) {
298 case "FileCodeGroup":
299 return new FileCodeGroup (se, level);
300 case "FirstMatchCodeGroup":
301 return new FirstMatchCodeGroup (se, level);
302 case "NetCodeGroup":
303 return new NetCodeGroup (se, level);
304 case "UnionCodeGroup":
305 return new UnionCodeGroup (se, level);
306 default: // unknown
307 Type classType = Type.GetType (fullClassName);
308 CodeGroup cg = (CodeGroup) Activator.CreateInstance (classType, true);
309 cg.FromXml (se, level);
310 return cg;