(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / System.Security.Policy / PolicyLevel.cs
blob1d6e051b080e8bb824edf775f1a5c6966af36eb4
1 //
2 // System.Security.Policy.PolicyLevel.cs
3 //
4 // Authors:
5 // Nick Drochak (ndrochak@gol.com)
6 // Duncan Mak (duncan@ximian.com)
7 // Sebastien Pouliot <sebastien@ximian.com>
8 //
9 // (C) 2001 Nick Drochak
10 // (C) 2003 Duncan Mak, Ximian Inc.
11 // Portions (C) 2004 Motus Technologies Inc. (http://www.motus.com)
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections; // for IList
35 using System.Globalization;
36 using System.IO;
37 using System.Reflection;
38 using System.Security.Permissions;
40 using Mono.Xml;
42 namespace System.Security.Policy {
44 [Serializable]
45 public sealed class PolicyLevel {
47 string label;
48 CodeGroup root_code_group;
49 private ArrayList full_trust_assemblies;
50 private ArrayList named_permission_sets;
51 private string _location;
52 private PolicyLevelType _type;
53 private Hashtable fullNames;
55 internal PolicyLevel (string label, PolicyLevelType type)
57 this.label = label;
58 _type = type;
59 full_trust_assemblies = new ArrayList ();
60 named_permission_sets = new ArrayList ();
63 internal PolicyLevel (string label, PolicyLevelType type, string filename)
64 : this (label, type)
66 LoadFromFile (filename);
69 internal void LoadFromFile (string filename)
71 bool loaded = false;
72 try {
73 // check for policy file
74 if (!File.Exists (filename)) {
75 // if it doesn't exist use the default configuration (like Fx 2.0)
76 // ref: http://blogs.msdn.com/shawnfa/archive/2004/04/21/117833.aspx
77 string defcfg = filename + ".default";
78 if (File.Exists (defcfg)) {
79 // create policy from default file
80 File.Copy (defcfg, filename);
83 // load security policy configuration
84 if (File.Exists (filename)) {
85 using (StreamReader sr = File.OpenText (filename)) {
86 LoadFromString (sr.ReadToEnd ());
88 loaded = true;
90 else {
91 CreateFromHardcodedDefault (_type);
92 loaded = true;
93 Save ();
96 catch {
97 // this can fail in many ways include
98 // * can't lookup policy (path discovery);
99 // * can't copy default file to policy
100 // * can't read policy file;
101 // * can't save hardcoded policy to filename
102 // * can't decode policy file
103 if (!loaded)
104 CreateFromHardcodedDefault (_type);
106 finally {
107 _location = filename;
111 internal void LoadFromString (string xml)
113 SecurityParser parser = new SecurityParser ();
114 parser.LoadXml (xml);
115 // configuration / mscorlib / security / policy / PolicyLevel
116 SecurityElement configuration = parser.ToXml ();
117 if (configuration.Tag != "configuration")
118 throw new ArgumentException (Locale.GetText ("missing <configuration> root element"));
119 SecurityElement mscorlib = (SecurityElement) configuration.Children [0];
120 if (mscorlib.Tag != "mscorlib")
121 throw new ArgumentException (Locale.GetText ("missing <mscorlib> tag"));
122 SecurityElement security = (SecurityElement) mscorlib.Children [0];
123 if (security.Tag != "security")
124 throw new ArgumentException (Locale.GetText ("missing <security> tag"));
125 SecurityElement policy = (SecurityElement) security.Children [0];
126 if (policy.Tag != "policy")
127 throw new ArgumentException (Locale.GetText ("missing <policy> tag"));
128 SecurityElement policyLevel = (SecurityElement) policy.Children [0];
129 FromXml (policyLevel);
132 // properties
134 public IList FullTrustAssemblies
136 get { return full_trust_assemblies; }
139 public string Label {
140 get { return label; }
143 public IList NamedPermissionSets {
144 get { return named_permission_sets; }
147 public CodeGroup RootCodeGroup {
148 get { return root_code_group; }
149 set {
150 if (value == null)
151 throw new ArgumentNullException ("value");
152 root_code_group = value;
156 public string StoreLocation {
157 get { return _location; }
160 #if NET_2_0
161 public PolicyLevelType Type {
162 get { return _type; }
164 #endif
166 // methods
168 public void AddFullTrustAssembly (StrongName sn)
170 if (sn == null)
171 throw new ArgumentNullException ("sn");
173 StrongNameMembershipCondition snMC = new StrongNameMembershipCondition(
174 sn.PublicKey, sn.Name, sn.Version);
176 AddFullTrustAssembly (snMC);
179 public void AddFullTrustAssembly (StrongNameMembershipCondition snMC)
181 if (snMC == null)
182 throw new ArgumentNullException ("snMC");
184 foreach (StrongNameMembershipCondition sn in full_trust_assemblies) {
185 if (sn.Equals (snMC)) {
186 throw new ArgumentException (Locale.GetText ("sn already has full trust."));
189 full_trust_assemblies.Add (snMC);
192 public void AddNamedPermissionSet (NamedPermissionSet permSet)
194 if (permSet == null)
195 throw new ArgumentNullException ("permSet");
197 foreach (NamedPermissionSet n in named_permission_sets) {
198 if (permSet.Name == n.Name) {
199 throw new ArgumentException (
200 Locale.GetText ("This NamedPermissionSet is the same an existing NamedPermissionSet."));
203 named_permission_sets.Add (permSet.Copy ());
206 public NamedPermissionSet ChangeNamedPermissionSet (string name, PermissionSet pSet)
208 if (name == null)
209 throw new ArgumentNullException ("name");
210 if (pSet == null)
211 throw new ArgumentNullException ("pSet");
212 if (IsReserved (name))
213 throw new ArgumentException (Locale.GetText ("Reserved name"));
215 foreach (NamedPermissionSet n in named_permission_sets) {
216 if (name == n.Name) {
217 named_permission_sets.Remove (n);
218 AddNamedPermissionSet (new NamedPermissionSet (name, pSet));
219 return n;
222 throw new ArgumentException (Locale.GetText ("PermissionSet not found"));
225 public static PolicyLevel CreateAppDomainLevel ()
227 NamedPermissionSet fullTrust = new NamedPermissionSet ("FullTrust", PermissionState.Unrestricted);
228 UnionCodeGroup cg = new UnionCodeGroup (new AllMembershipCondition (), new PolicyStatement (fullTrust));
229 cg.Name = "All_Code";
230 PolicyLevel pl = new PolicyLevel ("AppDomain", PolicyLevelType.AppDomain);
231 pl.RootCodeGroup = cg;
232 pl.Reset ();
233 return pl;
236 public void FromXml (SecurityElement e)
238 if (e == null)
239 throw new ArgumentNullException ("e");
240 // MS doesn't throw an exception for this case
241 // if (e.Tag != "PolicyLevel")
242 // throw new ArgumentException (Locale.GetText ("Invalid XML"));
244 SecurityElement sc = e.SearchForChildByTag ("SecurityClasses");
245 if ((sc != null) && (sc.Children != null) && (sc.Children.Count > 0)) {
246 fullNames = new Hashtable (sc.Children.Count);
247 foreach (SecurityElement se in sc.Children) {
248 fullNames.Add (se.Attributes ["Name"], se.Attributes ["Description"]);
252 SecurityElement nps = e.SearchForChildByTag ("NamedPermissionSets");
253 if ((nps != null) && (nps.Children != null) && (nps.Children.Count > 0)) {
254 named_permission_sets.Clear ();
255 foreach (SecurityElement se in nps.Children) {
256 NamedPermissionSet n = new NamedPermissionSet ();
257 n.Resolver = this;
258 n.FromXml (se);
259 named_permission_sets.Add (n);
263 SecurityElement cg = e.SearchForChildByTag ("CodeGroup");
264 if ((cg != null) && (cg.Children != null) && (cg.Children.Count > 0)) {
265 root_code_group = CodeGroup.CreateFromXml (cg, this);
267 else
268 throw new ArgumentException (Locale.GetText ("Missing Root CodeGroup"));
270 SecurityElement fta = e.SearchForChildByTag ("FullTrustAssemblies");
271 if ((fta != null) && (fta.Children != null) && (fta.Children.Count > 0)) {
272 full_trust_assemblies.Clear ();
273 foreach (SecurityElement se in fta.Children) {
274 if (se.Tag != "IMembershipCondition")
275 throw new ArgumentException (Locale.GetText ("Invalid XML"));
276 string className = se.Attribute ("class");
277 if (className.IndexOf ("StrongNameMembershipCondition") < 0)
278 throw new ArgumentException (Locale.GetText ("Invalid XML - must be StrongNameMembershipCondition"));
279 // we directly use StrongNameMembershipCondition
280 full_trust_assemblies.Add (new StrongNameMembershipCondition (se));
285 public NamedPermissionSet GetNamedPermissionSet (string name)
287 if (name == null)
288 throw new ArgumentNullException ("name");
290 foreach (NamedPermissionSet n in named_permission_sets) {
291 if (n.Name == name)
292 return (NamedPermissionSet) n.Copy ();
294 return null;
297 [MonoTODO]
298 public void Recover ()
300 throw new NotImplementedException ();
303 public void RemoveFullTrustAssembly (StrongName sn)
305 if (sn == null)
306 throw new ArgumentNullException ("sn");
308 StrongNameMembershipCondition s = new StrongNameMembershipCondition (sn.PublicKey, sn.Name, sn.Version);
309 RemoveFullTrustAssembly (s);
312 public void RemoveFullTrustAssembly (StrongNameMembershipCondition snMC)
314 if (snMC == null)
315 throw new ArgumentNullException ("snMC");
317 if (((IList) full_trust_assemblies).Contains (snMC))
318 ((IList) full_trust_assemblies).Remove (snMC);
320 else
321 throw new ArgumentException (
322 Locale.GetText ("sn does not have full trust."));
325 public NamedPermissionSet RemoveNamedPermissionSet (NamedPermissionSet permSet)
327 if (permSet == null)
328 throw new ArgumentNullException ("permSet");
330 if (! ((IList )named_permission_sets).Contains (permSet))
331 throw new ArgumentException (
332 Locale.GetText ("permSet cannot be found."));
334 ((IList) named_permission_sets).Remove (permSet);
336 return permSet;
339 [MonoTODO ("Check for reserved names")]
340 public NamedPermissionSet RemoveNamedPermissionSet (string name)
342 if (name == null)
343 throw new ArgumentNullException ("name");
345 foreach (NamedPermissionSet nps in named_permission_sets) {
346 if (name == nps.Name) {
347 named_permission_sets.Remove (nps);
348 return nps;
351 string msg = String.Format (Locale.GetText ("Name '{0}' cannot be found."), name);
352 throw new ArgumentException (msg, "name");
355 public void Reset ()
357 if (fullNames != null)
358 fullNames.Clear ();
359 full_trust_assemblies.Clear ();
360 named_permission_sets.Clear ();
362 if (_type != PolicyLevelType.AppDomain) {
363 // because the policy doesn't exist LoadFromFile will try to
364 // 1. use the .default file if existing (like Fx 2.0 does); or
365 // 2. use the hard-coded default values
366 // and recreate a policy file
367 if ((_location != null) && (File.Exists (_location))) {
368 try {
369 File.Delete (_location);
371 catch {}
373 LoadFromFile (_location);
375 else {
376 named_permission_sets.Add (new NamedPermissionSet ("LocalIntranet"));
377 named_permission_sets.Add (new NamedPermissionSet ("Internet"));
378 named_permission_sets.Add (new NamedPermissionSet ("SkipVerification"));
379 named_permission_sets.Add (new NamedPermissionSet ("Execution"));
380 named_permission_sets.Add (new NamedPermissionSet ("Nothing"));
381 named_permission_sets.Add (new NamedPermissionSet ("Everything"));
382 named_permission_sets.Add (new NamedPermissionSet ("FullTrust"));
386 public PolicyStatement Resolve (Evidence evidence)
388 if (evidence == null)
389 throw new ArgumentNullException ("evidence");
391 PolicyStatement ps = root_code_group.Resolve (evidence);
392 return ((ps != null) ? ps : PolicyStatement.Empty ());
395 public CodeGroup ResolveMatchingCodeGroups (Evidence evidence)
397 if (evidence == null)
398 throw new ArgumentNullException ("evidence");
400 CodeGroup cg = root_code_group.ResolveMatchingCodeGroups (evidence);
401 // TODO
402 return ((cg != null) ? cg : null);
406 public SecurityElement ToXml ()
408 Hashtable fullNames = new Hashtable ();
409 // only StrongNameMembershipCondition so no need to loop
410 if (full_trust_assemblies.Count > 0) {
411 if (!fullNames.Contains ("StrongNameMembershipCondition")) {
412 fullNames.Add ("StrongNameMembershipCondition", typeof (StrongNameMembershipCondition).FullName);
416 SecurityElement namedPSs = new SecurityElement ("NamedPermissionSets");
417 foreach (NamedPermissionSet nps in named_permission_sets) {
418 SecurityElement se = nps.ToXml ();
419 object objectClass = se.Attributes ["class"];
420 if (!fullNames.Contains (objectClass)) {
421 fullNames.Add (objectClass, nps.GetType ().FullName);
423 namedPSs.AddChild (se);
426 SecurityElement fta = new SecurityElement ("FullTrustAssemblies");
427 foreach (StrongNameMembershipCondition snmc in full_trust_assemblies) {
428 fta.AddChild (snmc.ToXml (this));
431 SecurityElement security_classes = new SecurityElement ("SecurityClasses");
432 if (fullNames.Count > 0) {
433 foreach (DictionaryEntry de in fullNames) {
434 SecurityElement sc = new SecurityElement ("SecurityClass");
435 sc.AddAttribute ("Name", (string)de.Key);
436 sc.AddAttribute ("Description", (string)de.Value);
437 security_classes.AddChild (sc);
441 SecurityElement element = new SecurityElement (typeof (System.Security.Policy.PolicyLevel).Name);
442 element.AddAttribute ("version", "1");
443 element.AddChild (security_classes);
444 element.AddChild (namedPSs);
445 if (root_code_group != null) {
446 element.AddChild (root_code_group.ToXml (this));
448 element.AddChild (fta);
450 return element;
453 // internal stuff
455 internal bool IsReserved (string name)
457 switch (name) {
458 case "FullTrust":
459 case "LocalIntranet":
460 case "Internet":
461 case "SkipVerification":
462 case "Execution":
463 case "Nothing":
464 case "Everything":
465 // FIXME: Are there others ?
466 return true;
467 default:
468 return false;
472 // NOTE: Callers are expected to check for ControlPolicy
473 internal void Save ()
475 if (_type == PolicyLevelType.AppDomain) {
476 throw new PolicyException (Locale.GetText (
477 "Can't save AppDomain PolicyLevel"));
480 if (_location != null) {
481 using (StreamWriter sw = new StreamWriter (_location)) {
482 sw.Write (ToXml ().ToString ());
483 sw.Close ();
488 // TODO : hardcode defaults in case
489 // (a) the specified policy file doesn't exists; and
490 // (b) no corresponding default policy file exists
491 internal void CreateFromHardcodedDefault (PolicyLevelType type)
493 PolicyStatement psu = new PolicyStatement (new PermissionSet (PermissionState.Unrestricted));
495 switch (type) {
496 case PolicyLevelType.Machine:
497 // by default all stuff is in the machine policy...
498 root_code_group = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.MyComputer), psu);
499 root_code_group.Name = "All_Code";
500 break;
501 case PolicyLevelType.User:
502 case PolicyLevelType.Enterprise:
503 case PolicyLevelType.AppDomain:
504 // while the other policies don't restrict anything
505 root_code_group = new UnionCodeGroup (new AllMembershipCondition (), psu);
506 root_code_group.Name = "All_Code";
507 break;
511 internal string ResolveClassName (string className)
513 if (fullNames != null) {
514 object name = fullNames [className];
515 if (name != null)
516 return (string) name;
518 return className;