[netcore] Remove local copy of static alc resolve methods
[mono-project.git] / mcs / class / corlib / System.Security.Policy / PolicyLevel.cs
blob4e1427fe1be2a49be2faae58fd83ec535b308ca3
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-2005 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.Runtime.InteropServices;
39 using System.Security.Permissions;
41 using Mono.Xml;
43 namespace System.Security.Policy {
45 [Serializable]
46 [ComVisible (true)]
47 public sealed class PolicyLevel {
49 string label;
50 CodeGroup root_code_group;
51 private ArrayList full_trust_assemblies;
52 private ArrayList named_permission_sets;
53 private string _location;
54 private PolicyLevelType _type;
55 private Hashtable fullNames;
56 private SecurityElement xml;
58 internal PolicyLevel (string label, PolicyLevelType type)
60 this.label = label;
61 _type = type;
62 full_trust_assemblies = new ArrayList ();
63 named_permission_sets = new ArrayList ();
66 internal void LoadFromFile (string filename)
68 try {
69 // check for policy file
70 if (!File.Exists (filename)) {
71 // if it doesn't exist use the default configuration (like Fx 2.0)
72 // ref: http://blogs.msdn.com/shawnfa/archive/2004/04/21/117833.aspx
73 string defcfg = filename + ".default";
74 if (File.Exists (defcfg)) {
75 // create policy from default file
76 File.Copy (defcfg, filename);
79 // load security policy configuration
80 if (File.Exists (filename)) {
81 using (StreamReader sr = File.OpenText (filename)) {
82 xml = FromString (sr.ReadToEnd ());
84 try {
85 SecurityManager.ResolvingPolicyLevel = this;
86 FromXml (xml);
88 finally {
89 SecurityManager.ResolvingPolicyLevel = this;
91 } else {
92 CreateDefaultFullTrustAssemblies ();
93 CreateDefaultNamedPermissionSets ();
94 CreateDefaultLevel (_type);
95 Save ();
98 catch {
99 // this can fail in many ways including...
100 // * can't lookup policy (path discovery);
101 // * can't copy default file to policy
102 // * can't read policy file;
103 // * can't decode policy file
104 // * can't save hardcoded policy to filename
106 finally {
107 _location = filename;
111 internal void LoadFromString (string xml)
113 FromXml (FromString (xml));
116 private SecurityElement FromString (string xml)
118 SecurityParser parser = new SecurityParser ();
119 parser.LoadXml (xml);
120 // configuration / mscorlib / security / policy / PolicyLevel
121 SecurityElement configuration = parser.ToXml ();
122 if (configuration.Tag != "configuration")
123 throw new ArgumentException (Locale.GetText ("missing <configuration> root element"));
124 SecurityElement mscorlib = (SecurityElement) configuration.Children [0];
125 if (mscorlib.Tag != "mscorlib")
126 throw new ArgumentException (Locale.GetText ("missing <mscorlib> tag"));
127 SecurityElement security = (SecurityElement) mscorlib.Children [0];
128 if (security.Tag != "security")
129 throw new ArgumentException (Locale.GetText ("missing <security> tag"));
130 SecurityElement policy = (SecurityElement) security.Children [0];
131 if (policy.Tag != "policy")
132 throw new ArgumentException (Locale.GetText ("missing <policy> tag"));
133 SecurityElement policyLevel = (SecurityElement) policy.Children [0];
134 return policyLevel;
137 // properties
139 [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
140 public IList FullTrustAssemblies {
141 get { return full_trust_assemblies; }
144 public string Label {
145 get { return label; }
148 public IList NamedPermissionSets {
149 get { return named_permission_sets; }
152 public CodeGroup RootCodeGroup {
153 get { return root_code_group; }
154 set {
155 if (value == null)
156 throw new ArgumentNullException ("value");
157 root_code_group = value;
161 public string StoreLocation {
162 get { return _location; }
165 [ComVisible (false)]
166 public PolicyLevelType Type {
167 get { return _type; }
170 // methods
172 [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
173 public void AddFullTrustAssembly (StrongName sn)
175 if (sn == null)
176 throw new ArgumentNullException ("sn");
178 StrongNameMembershipCondition snMC = new StrongNameMembershipCondition(
179 sn.PublicKey, sn.Name, sn.Version);
181 AddFullTrustAssembly (snMC);
184 [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
185 public void AddFullTrustAssembly (StrongNameMembershipCondition snMC)
187 if (snMC == null)
188 throw new ArgumentNullException ("snMC");
190 foreach (StrongNameMembershipCondition sn in full_trust_assemblies) {
191 if (sn.Equals (snMC)) {
192 throw new ArgumentException (Locale.GetText ("sn already has full trust."));
195 full_trust_assemblies.Add (snMC);
198 public void AddNamedPermissionSet (NamedPermissionSet permSet)
200 if (permSet == null)
201 throw new ArgumentNullException ("permSet");
203 foreach (NamedPermissionSet n in named_permission_sets) {
204 if (permSet.Name == n.Name) {
205 throw new ArgumentException (
206 Locale.GetText ("This NamedPermissionSet is the same an existing NamedPermissionSet."));
209 named_permission_sets.Add (permSet.Copy ());
212 public NamedPermissionSet ChangeNamedPermissionSet (string name, PermissionSet pSet)
214 if (name == null)
215 throw new ArgumentNullException ("name");
216 if (pSet == null)
217 throw new ArgumentNullException ("pSet");
218 if (DefaultPolicies.ReservedNames.IsReserved (name))
219 throw new ArgumentException (Locale.GetText ("Reserved name"));
221 foreach (NamedPermissionSet n in named_permission_sets) {
222 if (name == n.Name) {
223 named_permission_sets.Remove (n);
224 AddNamedPermissionSet (new NamedPermissionSet (name, pSet));
225 return n;
228 throw new ArgumentException (Locale.GetText ("PermissionSet not found"));
231 public static PolicyLevel CreateAppDomainLevel ()
233 UnionCodeGroup cg = new UnionCodeGroup (new AllMembershipCondition (), new PolicyStatement (DefaultPolicies.FullTrust));
234 cg.Name = "All_Code";
235 PolicyLevel pl = new PolicyLevel ("AppDomain", PolicyLevelType.AppDomain);
236 pl.RootCodeGroup = cg;
237 pl.Reset ();
238 return pl;
242 public void FromXml (SecurityElement e)
244 if (e == null)
245 throw new ArgumentNullException ("e");
246 // MS doesn't throw an exception for this case
247 // if (e.Tag != "PolicyLevel")
248 // throw new ArgumentException (Locale.GetText ("Invalid XML"));
250 SecurityElement sc = e.SearchForChildByTag ("SecurityClasses");
251 if ((sc != null) && (sc.Children != null) && (sc.Children.Count > 0)) {
252 fullNames = new Hashtable (sc.Children.Count);
253 foreach (SecurityElement se in sc.Children) {
254 fullNames.Add (se.Attributes ["Name"], se.Attributes ["Description"]);
258 SecurityElement fta = e.SearchForChildByTag ("FullTrustAssemblies");
259 if ((fta != null) && (fta.Children != null) && (fta.Children.Count > 0)) {
260 full_trust_assemblies.Clear ();
261 foreach (SecurityElement se in fta.Children) {
262 if (se.Tag != "IMembershipCondition")
263 throw new ArgumentException (Locale.GetText ("Invalid XML"));
264 string className = se.Attribute ("class");
265 if (className.IndexOf ("StrongNameMembershipCondition") < 0)
266 throw new ArgumentException (Locale.GetText ("Invalid XML - must be StrongNameMembershipCondition"));
267 // we directly use StrongNameMembershipCondition
268 full_trust_assemblies.Add (new StrongNameMembershipCondition (se));
272 SecurityElement cg = e.SearchForChildByTag ("CodeGroup");
273 if ((cg != null) && (cg.Children != null) && (cg.Children.Count > 0)) {
274 root_code_group = CodeGroup.CreateFromXml (cg, this);
275 } else {
276 throw new ArgumentException (Locale.GetText ("Missing Root CodeGroup"));
279 SecurityElement nps = e.SearchForChildByTag ("NamedPermissionSets");
280 if ((nps != null) && (nps.Children != null) && (nps.Children.Count > 0)) {
281 named_permission_sets.Clear ();
282 foreach (SecurityElement se in nps.Children) {
283 NamedPermissionSet n = new NamedPermissionSet ();
284 n.Resolver = this;
285 n.FromXml (se);
286 named_permission_sets.Add (n);
291 public NamedPermissionSet GetNamedPermissionSet (string name)
293 if (name == null)
294 throw new ArgumentNullException ("name");
296 foreach (NamedPermissionSet n in named_permission_sets) {
297 if (n.Name == name)
298 return (NamedPermissionSet) n.Copy ();
300 return null;
303 public void Recover ()
305 if (_location == null) {
306 string msg = Locale.GetText ("Only file based policies may be recovered.");
307 throw new PolicyException (msg);
310 string backup = _location + ".backup";
311 if (!File.Exists (backup)) {
312 string msg = Locale.GetText ("No policy backup exists.");
313 throw new PolicyException (msg);
316 try {
317 File.Copy (backup, _location, true);
319 catch (Exception e) {
320 string msg = Locale.GetText ("Couldn't replace the policy file with it's backup.");
321 throw new PolicyException (msg, e);
325 [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
326 public void RemoveFullTrustAssembly (StrongName sn)
328 if (sn == null)
329 throw new ArgumentNullException ("sn");
331 StrongNameMembershipCondition s = new StrongNameMembershipCondition (sn.PublicKey, sn.Name, sn.Version);
332 RemoveFullTrustAssembly (s);
335 [Obsolete ("All GACed assemblies are now fully trusted and all permissions now succeed on fully trusted code.")]
336 public void RemoveFullTrustAssembly (StrongNameMembershipCondition snMC)
338 if (snMC == null)
339 throw new ArgumentNullException ("snMC");
341 if (((IList) full_trust_assemblies).Contains (snMC))
342 ((IList) full_trust_assemblies).Remove (snMC);
344 else
345 throw new ArgumentException (
346 Locale.GetText ("sn does not have full trust."));
349 public NamedPermissionSet RemoveNamedPermissionSet (NamedPermissionSet permSet)
351 if (permSet == null)
352 throw new ArgumentNullException ("permSet");
354 return RemoveNamedPermissionSet (permSet.Name);
357 public NamedPermissionSet RemoveNamedPermissionSet (string name)
359 if (name == null)
360 throw new ArgumentNullException ("name");
361 if (DefaultPolicies.ReservedNames.IsReserved (name))
362 throw new ArgumentException (Locale.GetText ("Reserved name"));
364 foreach (NamedPermissionSet nps in named_permission_sets) {
365 if (name == nps.Name) {
366 named_permission_sets.Remove (nps);
367 return nps;
370 string msg = String.Format (Locale.GetText ("Name '{0}' cannot be found."), name);
371 throw new ArgumentException (msg, "name");
374 public void Reset ()
376 if (fullNames != null)
377 fullNames.Clear ();
379 if (_type != PolicyLevelType.AppDomain) {
380 full_trust_assemblies.Clear ();
381 named_permission_sets.Clear ();
383 // because the policy doesn't exist LoadFromFile will try to
384 // 1. use the .default file if existing (like Fx 2.0 does); or
385 // 2. use the hard-coded default values
386 // and recreate a policy file
387 if ((_location != null) && (File.Exists (_location))) {
388 try {
389 File.Delete (_location);
391 catch {}
393 LoadFromFile (_location);
394 } else {
395 CreateDefaultFullTrustAssemblies ();
396 CreateDefaultNamedPermissionSets ();
400 public PolicyStatement Resolve (Evidence evidence)
402 if (evidence == null)
403 throw new ArgumentNullException ("evidence");
405 PolicyStatement ps = root_code_group.Resolve (evidence);
406 return ((ps != null) ? ps : PolicyStatement.Empty ());
409 public CodeGroup ResolveMatchingCodeGroups (Evidence evidence)
411 if (evidence == null)
412 throw new ArgumentNullException ("evidence");
414 CodeGroup cg = root_code_group.ResolveMatchingCodeGroups (evidence);
415 return ((cg != null) ? cg : null);
418 public SecurityElement ToXml ()
420 Hashtable fullNames = new Hashtable ();
421 // only StrongNameMembershipCondition so no need to loop
422 if (full_trust_assemblies.Count > 0) {
423 if (!fullNames.Contains ("StrongNameMembershipCondition")) {
424 fullNames.Add ("StrongNameMembershipCondition", typeof (StrongNameMembershipCondition).FullName);
428 SecurityElement namedPSs = new SecurityElement ("NamedPermissionSets");
429 foreach (NamedPermissionSet nps in named_permission_sets) {
430 SecurityElement se = nps.ToXml ();
431 object objectClass = se.Attributes ["class"];
432 if (!fullNames.Contains (objectClass)) {
433 fullNames.Add (objectClass, nps.GetType ().FullName);
435 namedPSs.AddChild (se);
438 SecurityElement fta = new SecurityElement ("FullTrustAssemblies");
439 foreach (StrongNameMembershipCondition snmc in full_trust_assemblies) {
440 fta.AddChild (snmc.ToXml (this));
443 SecurityElement security_classes = new SecurityElement ("SecurityClasses");
444 if (fullNames.Count > 0) {
445 foreach (DictionaryEntry de in fullNames) {
446 SecurityElement sc = new SecurityElement ("SecurityClass");
447 sc.AddAttribute ("Name", (string)de.Key);
448 sc.AddAttribute ("Description", (string)de.Value);
449 security_classes.AddChild (sc);
453 SecurityElement element = new SecurityElement (typeof (System.Security.Policy.PolicyLevel).Name);
454 element.AddAttribute ("version", "1");
455 element.AddChild (security_classes);
456 element.AddChild (namedPSs);
457 if (root_code_group != null) {
458 element.AddChild (root_code_group.ToXml (this));
460 element.AddChild (fta);
462 return element;
465 // internal stuff
467 // NOTE: Callers are expected to check for ControlPolicy
468 internal void Save ()
470 if (_type == PolicyLevelType.AppDomain) {
471 throw new PolicyException (Locale.GetText (
472 "Can't save AppDomain PolicyLevel"));
475 if (_location != null) {
476 try {
477 if (File.Exists (_location)) {
478 File.Copy (_location, _location + ".backup", true);
481 catch (Exception) {
483 finally {
484 using (StreamWriter sw = new StreamWriter (_location)) {
485 sw.Write (ToXml ().ToString ());
486 sw.Close ();
492 // Hardcode defaults in case
493 // (a) the specified policy file doesn't exists; and
494 // (b) no corresponding default policy file exists
495 internal void CreateDefaultLevel (PolicyLevelType type)
497 PolicyStatement psu = new PolicyStatement (DefaultPolicies.FullTrust);
499 switch (type) {
500 case PolicyLevelType.Machine:
501 // by default all stuff is in the machine policy...
502 PolicyStatement psn = new PolicyStatement (DefaultPolicies.Nothing);
503 root_code_group = new UnionCodeGroup (new AllMembershipCondition (), psn);
504 root_code_group.Name = "All_Code";
506 UnionCodeGroup myComputerZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.MyComputer), psu);
507 myComputerZone.Name = "My_Computer_Zone";
508 // TODO: strongname code group for ECMA and MS keys
509 root_code_group.AddChild (myComputerZone);
511 UnionCodeGroup localIntranetZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Intranet),
512 new PolicyStatement (DefaultPolicies.LocalIntranet));
513 localIntranetZone.Name = "LocalIntranet_Zone";
514 // TODO: same site / same directory
515 root_code_group.AddChild (localIntranetZone);
517 PolicyStatement psi = new PolicyStatement (DefaultPolicies.Internet);
518 UnionCodeGroup internetZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Internet), psi);
519 internetZone.Name = "Internet_Zone";
520 // TODO: same site
521 root_code_group.AddChild (internetZone);
523 UnionCodeGroup restrictedZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Untrusted), psn);
524 restrictedZone.Name = "Restricted_Zone";
525 root_code_group.AddChild (restrictedZone);
527 UnionCodeGroup trustedZone = new UnionCodeGroup (new ZoneMembershipCondition (SecurityZone.Trusted), psi);
528 trustedZone.Name = "Trusted_Zone";
529 // TODO: same site
530 root_code_group.AddChild (trustedZone);
531 break;
532 case PolicyLevelType.User:
533 case PolicyLevelType.Enterprise:
534 case PolicyLevelType.AppDomain:
535 // while the other policies don't restrict anything
536 root_code_group = new UnionCodeGroup (new AllMembershipCondition (), psu);
537 root_code_group.Name = "All_Code";
538 break;
542 internal void CreateDefaultFullTrustAssemblies ()
544 // (default) assemblies that are fully trusted during policy resolution
545 full_trust_assemblies.Clear ();
546 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("mscorlib", DefaultPolicies.Key.Ecma));
547 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System", DefaultPolicies.Key.Ecma));
548 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Data", DefaultPolicies.Key.Ecma));
549 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.DirectoryServices", DefaultPolicies.Key.MsFinal));
550 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Drawing", DefaultPolicies.Key.MsFinal));
551 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.Messaging", DefaultPolicies.Key.MsFinal));
552 full_trust_assemblies.Add (DefaultPolicies.FullTrustMembership ("System.ServiceProcess", DefaultPolicies.Key.MsFinal));
555 internal void CreateDefaultNamedPermissionSets ()
557 named_permission_sets.Clear ();
558 try {
559 SecurityManager.ResolvingPolicyLevel = this;
560 named_permission_sets.Add (DefaultPolicies.LocalIntranet);
561 named_permission_sets.Add (DefaultPolicies.Internet);
562 named_permission_sets.Add (DefaultPolicies.SkipVerification);
563 named_permission_sets.Add (DefaultPolicies.Execution);
564 named_permission_sets.Add (DefaultPolicies.Nothing);
565 named_permission_sets.Add (DefaultPolicies.Everything);
566 named_permission_sets.Add (DefaultPolicies.FullTrust);
568 finally {
569 SecurityManager.ResolvingPolicyLevel = null;
573 internal string ResolveClassName (string className)
575 if (fullNames != null) {
576 object name = fullNames [className];
577 if (name != null)
578 return (string) name;
580 return className;
583 internal bool IsFullTrustAssembly (Assembly a)
585 AssemblyName an = a.GetName ();
586 StrongNamePublicKeyBlob snpkb = new StrongNamePublicKeyBlob (an.GetPublicKey ());
587 StrongNameMembershipCondition snMC = new StrongNameMembershipCondition (snpkb, an.Name, an.Version);
588 foreach (StrongNameMembershipCondition sn in full_trust_assemblies) {
589 if (sn.Equals (snMC)) {
590 return true;
593 return false;