2 // System.Security.Policy.CodeGroup
5 // Nick Drochak (ndrochak@gol.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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 {
43 public abstract class CodeGroup {
44 PolicyStatement m_policy;
45 IMembershipCondition m_membershipCondition;
48 ArrayList m_children = new ArrayList();
49 // PolicyLevel m_level;
52 protected CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
54 public CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
57 if (null == membershipCondition)
58 throw new ArgumentNullException ("membershipCondition");
61 m_policy = policy.Copy ();
62 m_membershipCondition = membershipCondition.Copy ();
65 // for PolicyLevel (to avoid validation duplication)
66 internal CodeGroup (SecurityElement e, PolicyLevel level)
73 public abstract CodeGroup Copy ();
75 public abstract string MergeLogic { get; }
77 public abstract PolicyStatement Resolve (Evidence evidence);
79 public abstract CodeGroup ResolveMatchingCodeGroups (Evidence evidence);
83 public PolicyStatement PolicyStatement {
84 get { return m_policy; }
85 set { m_policy = value; }
88 public string Description {
89 get { return m_description; }
90 set { m_description = value; }
93 public IMembershipCondition MembershipCondition {
94 get { return m_membershipCondition; }
97 throw new ArgumentException ("value");
98 m_membershipCondition = value;
103 get { return m_name; }
104 set { m_name = value; }
107 public IList Children {
108 get { return m_children; }
111 throw new ArgumentNullException ("value");
112 m_children = new ArrayList (value);
116 public virtual string AttributeString {
118 if (null != m_policy)
119 return m_policy.AttributeString;
124 public virtual string PermissionSetName {
126 if (m_policy == null)
128 if (m_policy.PermissionSet is Security.NamedPermissionSet)
129 return ((NamedPermissionSet)(m_policy.PermissionSet)).Name;
134 public void AddChild (CodeGroup group)
137 throw new ArgumentNullException ("group");
139 m_children.Add (group.Copy ());
142 public override bool Equals (object o)
144 CodeGroup cg = (o as CodeGroup);
148 return Equals (cg, false);
151 public bool Equals (CodeGroup cg, bool compareChildren)
153 if (cg.Name != this.Name)
156 if (cg.Description != this.Description)
159 if (!cg.MembershipCondition.Equals (m_membershipCondition))
162 if (compareChildren) {
163 int childCount = cg.Children.Count;
164 if (this.Children.Count != childCount)
167 for (int index = 0; index < childCount; index++) {
168 // not a deep compare
169 if (!((CodeGroup)(this.Children [index])).Equals ((CodeGroup)(cg.Children [index]), false))
176 public void RemoveChild (CodeGroup group)
179 m_children.Remove (group);
182 public override int GetHashCode ()
184 int hashCode = m_membershipCondition.GetHashCode ();
185 if (m_policy != null)
186 hashCode += m_policy.GetHashCode ();
190 public void FromXml (SecurityElement e)
195 public void FromXml (SecurityElement e, PolicyLevel level)
198 throw new ArgumentNullException("e");
200 PermissionSet ps = null;
201 string psetname = e.Attribute ("PermissionSetName");
202 if ((psetname != null) && (level != null)) {
203 ps = level.GetNamedPermissionSet (psetname);
206 SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
208 Type classType = Type.GetType (pset.Attribute ("class"));
209 ps = (PermissionSet) Activator.CreateInstance (classType, true);
213 ps = new PermissionSet (new PermissionSet (PermissionState.None));
216 m_policy = new PolicyStatement (ps);
219 if ((e.Children != null) && (e.Children.Count > 0)) {
220 foreach (SecurityElement se in e.Children) {
221 if (se.Tag == "CodeGroup") {
222 this.AddChild (CodeGroup.CreateFromXml (se, level));
227 m_membershipCondition = null;
228 SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
230 string className = mc.Attribute ("class");
231 Type classType = Type.GetType (className);
232 if (classType == null)
233 classType = Type.GetType ("System.Security.Policy." + className);
234 m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType, true);
235 m_membershipCondition.FromXml (mc, level);
238 m_name = e.Attribute("Name");
239 m_description = e.Attribute("Description");
241 // seems like we might need this to Resolve() in subclasses
247 protected virtual void ParseXml (SecurityElement e, PolicyLevel level)
251 public SecurityElement ToXml ()
256 public SecurityElement ToXml (PolicyLevel level)
258 SecurityElement e = new SecurityElement("CodeGroup");
259 e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
260 e.AddAttribute("version", "1");
263 e.AddAttribute("Name", Name);
265 if (null != Description)
266 e.AddAttribute("Description", Description);
268 if (null != MembershipCondition)
269 e.AddChild(MembershipCondition.ToXml());
271 if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
272 e.AddChild (PolicyStatement.PermissionSet.ToXml ());
274 foreach (CodeGroup child in Children)
275 e.AddChild(child.ToXml());
281 protected virtual void CreateXml (SecurityElement element, PolicyLevel level)
287 internal static CodeGroup CreateFromXml (SecurityElement se, PolicyLevel level)
289 string fullClassName = se.Attribute ("class");
290 string className = fullClassName;
291 // many possible formats
292 // a. "FirstMatchCodeGroup"
293 // b. "System.Security.Policy.FirstMatchCodeGroup"
294 // 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"
295 int n = className.IndexOf (",");
297 className = className.Substring (0, n);
299 n = className.LastIndexOf (".");
301 className = className.Substring (n + 1);
302 // much faster than calling Activator.CreateInstance
304 case "FileCodeGroup":
305 return new FileCodeGroup (se, level);
306 case "FirstMatchCodeGroup":
307 return new FirstMatchCodeGroup (se, level);
309 return new NetCodeGroup (se, level);
310 case "UnionCodeGroup":
311 return new UnionCodeGroup (se, level);
313 Type classType = Type.GetType (fullClassName);
314 CodeGroup cg = (CodeGroup) Activator.CreateInstance (classType, true);
315 cg.FromXml (se, level);