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
{
41 public abstract class CodeGroup
{
42 PolicyStatement m_policy
;
43 IMembershipCondition m_membershipCondition
;
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");
55 m_policy
= policy
.Copy ();
56 m_membershipCondition
= membershipCondition
.Copy ();
59 // for PolicyLevel (to avoid validation duplication)
60 internal CodeGroup (SecurityElement e
, PolicyLevel level
)
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
);
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; }
91 throw new ArgumentException ("value");
92 m_membershipCondition
= value;
97 get { return m_name; }
98 set { m_name = value; }
101 public IList Children
{
102 get { return m_children; }
105 throw new ArgumentNullException ("value");
106 m_children
= new ArrayList (value);
110 public virtual string AttributeString
{
112 if (null != m_policy
)
113 return m_policy
.AttributeString
;
118 public virtual string PermissionSetName
{
120 if (m_policy
== null)
122 if (m_policy
.PermissionSet
is Security
.NamedPermissionSet
)
123 return ((NamedPermissionSet
)(m_policy
.PermissionSet
)).Name
;
128 public void AddChild (CodeGroup
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
);
142 return Equals (cg
, false);
145 public bool Equals (CodeGroup cg
, bool compareChildren
)
147 if (cg
.Name
!= this.Name
)
150 if (cg
.Description
!= this.Description
)
153 if (!cg
.MembershipCondition
.Equals (m_membershipCondition
))
156 if (compareChildren
) {
157 int childCount
= cg
.Children
.Count
;
158 if (this.Children
.Count
!= childCount
)
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))
170 public void RemoveChild (CodeGroup
group)
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 ();
184 public void FromXml (SecurityElement e
)
189 public void FromXml (SecurityElement e
, PolicyLevel level
)
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
);
200 SecurityElement pset
= e
.SearchForChildByTag ("PermissionSet");
202 Type classType
= Type
.GetType (pset
.Attribute ("class"));
203 ps
= (PermissionSet
) Activator
.CreateInstance (classType
, true);
207 ps
= new PermissionSet (new PermissionSet (PermissionState
.None
));
210 m_policy
= new PolicyStatement (ps
);
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");
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
241 protected virtual void ParseXml (SecurityElement e
, PolicyLevel level
)
245 public SecurityElement
ToXml ()
250 public SecurityElement
ToXml (PolicyLevel level
)
252 SecurityElement e
= new SecurityElement("CodeGroup");
253 e
.AddAttribute("class", this.GetType().AssemblyQualifiedName
);
254 e
.AddAttribute("version", "1");
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());
275 protected virtual void CreateXml (SecurityElement element
, PolicyLevel level
)
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 (",");
291 className
= className
.Substring (0, n
);
293 n
= className
.LastIndexOf (".");
295 className
= className
.Substring (n
+ 1);
296 // much faster than calling Activator.CreateInstance
298 case "FileCodeGroup":
299 return new FileCodeGroup (se
, level
);
300 case "FirstMatchCodeGroup":
301 return new FirstMatchCodeGroup (se
, level
);
303 return new NetCodeGroup (se
, level
);
304 case "UnionCodeGroup":
305 return new UnionCodeGroup (se
, level
);
307 Type classType
= Type
.GetType (fullClassName
);
308 CodeGroup cg
= (CodeGroup
) Activator
.CreateInstance (classType
, true);
309 cg
.FromXml (se
, level
);