3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
12 // Abstraction for a level of policy (e.g. Enterprise, Machine, User)
15 namespace System.Security.Policy {
16 using Microsoft.Win32;
17 using System.Collections;
18 using System.Globalization;
20 using System.Reflection;
21 using System.Security.Permissions;
22 using System.Security.Util;
23 using System.Runtime.InteropServices;
24 using System.Runtime.Remoting;
25 using System.Runtime.Serialization;
26 using System.Runtime.Versioning;
28 using System.Threading;
29 using System.Diagnostics.Contracts;
31 using System.Runtime.Hosting;
32 using System.Deployment.Internal.Isolation.Manifest;
33 using System.Deployment.Internal.Isolation;
35 // Duplicated in vm\SecurityConfig.h
37 internal enum ConfigId {
39 MachinePolicyLevel = 1,
41 EnterprisePolicyLevel = 3,
45 [System.Runtime.InteropServices.ComVisible(true)]
46 sealed public class PolicyLevel {
47 private ArrayList m_fullTrustAssemblies;
48 private ArrayList m_namedPermissionSets;
49 private CodeGroup m_rootCodeGroup;
50 private string m_label;
51 [OptionalField(VersionAdded = 2)]
52 private PolicyLevelType m_type;
54 // Following fields are present purely for serialization compatability with Everett: not used in Whidbey
55 #pragma warning disable 169
56 private ConfigId m_configId;
57 private bool m_useDefaultCodeGroupsOnReset;
58 private bool m_generateQuickCacheOnLoad;
59 private bool m_caching;
60 private bool m_throwOnLoadError;
61 private Encoding m_encoding;
62 #pragma warning restore 169
64 private bool m_loaded;
65 private SecurityElement m_permSetElement;
66 private string m_path;
72 private static Object s_InternalSyncObject;
73 private static Object InternalSyncObject {
75 if (s_InternalSyncObject == null) {
76 Object o = new Object();
77 Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
79 return s_InternalSyncObject;
83 private static readonly string[] s_reservedNamedPermissionSets = {
94 private void OnDeserialized(StreamingContext ctx) {
95 // If label != null, then we know that we can derive the type from that. In Whidbey, we might be doing unnecessary work here
97 DeriveTypeFromLabel();
100 private void DeriveTypeFromLabel() {
101 if(m_label.Equals(Environment.GetResourceString("Policy_PL_User")))
102 m_type = System.Security.PolicyLevelType.User;
103 else if(m_label.Equals(Environment.GetResourceString("Policy_PL_Machine")))
104 m_type = System.Security.PolicyLevelType.Machine;
105 else if(m_label.Equals(Environment.GetResourceString("Policy_PL_Enterprise")))
106 m_type = System.Security.PolicyLevelType.Enterprise;
107 else if(m_label.Equals(Environment.GetResourceString("Policy_PL_AppDomain")))
108 m_type = System.Security.PolicyLevelType.AppDomain;
110 throw new ArgumentException(Environment.GetResourceString("Policy_Default"));
113 private string DeriveLabelFromType() {
115 case System.Security.PolicyLevelType.User:
116 return Environment.GetResourceString("Policy_PL_User");
117 case System.Security.PolicyLevelType.Machine:
118 return Environment.GetResourceString("Policy_PL_Machine");
119 case System.Security.PolicyLevelType.Enterprise:
120 return Environment.GetResourceString("Policy_PL_Enterprise");
121 case System.Security.PolicyLevelType.AppDomain:
122 return Environment.GetResourceString("Policy_PL_AppDomain");
124 throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)m_type));
130 // No public constructors are exposed. CreateAppDomainLevel is the only public API to create
131 // an AppDomain policy level, and it ensures it is an AppDomain policy level.
134 private PolicyLevel() {}
136 [System.Security.SecurityCritical] // auto-generated
137 [ResourceExposure(ResourceScope.None)]
138 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
139 internal PolicyLevel (PolicyLevelType type) : this (type, GetLocationFromType(type)) {}
140 [ResourceExposure(ResourceScope.Machine)]
141 [ResourceConsumption(ResourceScope.Machine)]
142 internal PolicyLevel (PolicyLevelType type, string path) : this (type, path, ConfigId.None) {}
143 [ResourceExposure(ResourceScope.Machine)]
144 internal PolicyLevel (PolicyLevelType type, string path, ConfigId configId) {
147 m_loaded = (path == null);
148 if (m_path == null) {
149 m_rootCodeGroup = CreateDefaultAllGroup();
150 SetFactoryPermissionSets();
151 SetDefaultFullTrustAssemblies();
153 m_configId = configId;
156 [System.Security.SecurityCritical] // auto-generated
157 [ResourceExposure(ResourceScope.Machine)]
158 [ResourceConsumption(ResourceScope.Machine)]
159 internal static string GetLocationFromType (PolicyLevelType type) {
161 case PolicyLevelType.User:
162 return Config.UserDirectory + "security.config";
163 case PolicyLevelType.Machine:
164 return Config.MachineDirectory + "security.config";
165 case PolicyLevelType.Enterprise:
166 return Config.MachineDirectory + "enterprisesec.config";
172 [System.Security.SecuritySafeCritical] // auto-generated
173 [Obsolete("AppDomain policy levels are obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
174 public static PolicyLevel CreateAppDomainLevel() {
175 return new PolicyLevel(System.Security.PolicyLevelType.AppDomain);
178 public string Label {
181 m_label = DeriveLabelFromType();
187 // Public properties and methods.
191 public PolicyLevelType Type {
197 internal ConfigId ConfigId {
203 internal string Path {
204 [ResourceExposure(ResourceScope.Machine)]
210 public string StoreLocation {
211 [System.Security.SecuritySafeCritical] // auto-generated
212 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy)]
213 [ResourceExposure(ResourceScope.Machine)]
214 [ResourceConsumption(ResourceScope.Machine)]
216 return GetLocationFromType(m_type);
220 public CodeGroup RootCodeGroup {
221 [System.Security.SecuritySafeCritical] // auto-generated
224 return m_rootCodeGroup;
226 [System.Security.SecuritySafeCritical] // auto-generated
229 throw new ArgumentNullException("RootCodeGroup");
230 Contract.EndContractBlock();
233 m_rootCodeGroup = value.Copy();
237 public IList NamedPermissionSets {
238 [System.Security.SecuritySafeCritical] // auto-generated
241 LoadAllPermissionSets();
243 ArrayList newList = new ArrayList(m_namedPermissionSets.Count);
245 IEnumerator enumerator = m_namedPermissionSets.GetEnumerator();
246 while (enumerator.MoveNext()) {
247 newList.Add(((NamedPermissionSet)enumerator.Current).Copy());
254 public CodeGroup ResolveMatchingCodeGroups(Evidence evidence) {
255 if (evidence == null)
256 throw new ArgumentNullException("evidence");
257 Contract.EndContractBlock();
259 return this.RootCodeGroup.ResolveMatchingCodeGroups(evidence);
262 [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")]
263 public void AddFullTrustAssembly(StrongName sn) {
265 throw new ArgumentNullException("sn");
266 Contract.EndContractBlock();
268 AddFullTrustAssembly(new StrongNameMembershipCondition(sn.PublicKey, sn.Name, sn.Version));
271 [System.Security.SecuritySafeCritical] // auto-generated
272 [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")]
273 public void AddFullTrustAssembly(StrongNameMembershipCondition snMC) {
275 throw new ArgumentNullException("snMC");
276 Contract.EndContractBlock();
280 IEnumerator enumerator = m_fullTrustAssemblies.GetEnumerator();
281 while (enumerator.MoveNext()) {
282 if (((StrongNameMembershipCondition)enumerator.Current).Equals(snMC))
283 throw new ArgumentException(Environment.GetResourceString("Argument_AssemblyAlreadyFullTrust"));
286 lock (m_fullTrustAssemblies) {
287 m_fullTrustAssemblies.Add(snMC);
291 [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")]
292 public void RemoveFullTrustAssembly(StrongName sn) {
294 throw new ArgumentNullException("assembly");
295 Contract.EndContractBlock();
297 RemoveFullTrustAssembly(new StrongNameMembershipCondition(sn.PublicKey, sn.Name, sn.Version));
300 [System.Security.SecuritySafeCritical] // auto-generated
301 [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")]
302 public void RemoveFullTrustAssembly(StrongNameMembershipCondition snMC) {
304 throw new ArgumentNullException("snMC");
305 Contract.EndContractBlock();
309 Object toRemove = null;
310 IEnumerator enumerator = m_fullTrustAssemblies.GetEnumerator();
312 while (enumerator.MoveNext()) {
313 if (((StrongNameMembershipCondition)enumerator.Current).Equals(snMC)) {
314 toRemove = enumerator.Current;
319 if (toRemove == null)
320 throw new ArgumentException(Environment.GetResourceString("Argument_AssemblyNotFullTrust"));
322 lock (m_fullTrustAssemblies) {
323 m_fullTrustAssemblies.Remove(toRemove);
327 [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")]
328 public IList FullTrustAssemblies {
329 [System.Security.SecuritySafeCritical] // auto-generated
332 return new ArrayList(m_fullTrustAssemblies);
336 [System.Security.SecuritySafeCritical] // auto-generated
337 public void AddNamedPermissionSet(NamedPermissionSet permSet) {
339 throw new ArgumentNullException("permSet");
340 Contract.EndContractBlock();
343 LoadAllPermissionSets();
346 IEnumerator enumerator = m_namedPermissionSets.GetEnumerator();
347 while (enumerator.MoveNext()) {
348 if (((NamedPermissionSet)enumerator.Current).Name.Equals(permSet.Name))
349 throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateName"));
352 NamedPermissionSet npsCopy = (NamedPermissionSet)permSet.Copy();
353 npsCopy.IgnoreTypeLoadFailures = true;
354 m_namedPermissionSets.Add(npsCopy);
358 public NamedPermissionSet RemoveNamedPermissionSet(NamedPermissionSet permSet) {
360 throw new ArgumentNullException("permSet");
361 Contract.EndContractBlock();
363 return RemoveNamedPermissionSet(permSet.Name);
366 [System.Security.SecuritySafeCritical] // auto-generated
367 public NamedPermissionSet RemoveNamedPermissionSet(string name) {
369 throw new ArgumentNullException("name");
370 Contract.EndContractBlock();
373 LoadAllPermissionSets();
375 int permSetIndex = -1;
377 // First, make sure it's not a reserved permission set.
378 for (int index = 0; index < s_reservedNamedPermissionSets.Length; ++index) {
379 if (s_reservedNamedPermissionSets[index].Equals(name))
380 throw new ArgumentException(Environment.GetResourceString("Argument_ReservedNPMS", name));
383 // Then, find out if a named permission set of that name exists
384 // and remember its index;
386 ArrayList namedPermissionSets = m_namedPermissionSets;
388 for (int index = 0; index < namedPermissionSets.Count; ++index) {
389 if (((NamedPermissionSet)namedPermissionSets[index]).Name.Equals(name)) {
390 permSetIndex = index;
395 if (permSetIndex == -1)
396 throw new ArgumentException(Environment.GetResourceString("Argument_NoNPMS"));
398 // Now, as best as we can in the face of custom CodeGroups figure
399 // out if the permission set is in use. If it is we don't allow
402 ArrayList groups = new ArrayList();
403 groups.Add(this.m_rootCodeGroup);
405 for (int index = 0; index < groups.Count; ++index) {
406 CodeGroup group = (CodeGroup)groups[index];
408 if (group.PermissionSetName != null && group.PermissionSetName.Equals(name)) {
409 throw new ArgumentException(Environment.GetResourceString("Argument_NPMSInUse", name));
412 IEnumerator childEnumerator = group.Children.GetEnumerator();
414 if (childEnumerator != null) {
415 while (childEnumerator.MoveNext()) {
416 groups.Add(childEnumerator.Current);
421 NamedPermissionSet permSet = (NamedPermissionSet)namedPermissionSets[permSetIndex];
422 namedPermissionSets.RemoveAt(permSetIndex);
426 [System.Security.SecuritySafeCritical] // auto-generated
427 public NamedPermissionSet ChangeNamedPermissionSet(string name, PermissionSet pSet) {
429 throw new ArgumentNullException("name");
431 throw new ArgumentNullException("pSet");
432 Contract.EndContractBlock();
434 // First, make sure it's not a reserved permission set.
435 for (int index = 0; index < s_reservedNamedPermissionSets.Length; ++index) {
436 if (s_reservedNamedPermissionSets[index].Equals(name))
437 throw new ArgumentException(Environment.GetResourceString("Argument_ReservedNPMS", name));
440 // Get the current permission set (don't copy it).
441 NamedPermissionSet currentPSet = GetNamedPermissionSetInternal(name);
443 // If the permission set doesn't exist, throw an argument exception
444 if (currentPSet == null)
445 throw new ArgumentException(Environment.GetResourceString("Argument_NoNPMS"));
447 // Copy the current permission set so that we can return it.
448 NamedPermissionSet retval = (NamedPermissionSet)currentPSet.Copy();
450 // Reset the permission set
452 currentPSet.SetUnrestricted(pSet.IsUnrestricted());
454 IEnumerator enumerator = pSet.GetEnumerator();
455 while (enumerator.MoveNext()) {
456 currentPSet.SetPermission(((IPermission)enumerator.Current).Copy());
459 if (pSet is NamedPermissionSet) {
460 currentPSet.Description = ((NamedPermissionSet)pSet).Description;
466 [System.Security.SecuritySafeCritical] // auto-generated
467 public NamedPermissionSet GetNamedPermissionSet(string name) {
469 throw new ArgumentNullException("name");
470 Contract.EndContractBlock();
472 NamedPermissionSet permSet = GetNamedPermissionSetInternal(name);
474 // Copy it so that no corruption can occur.
476 return new NamedPermissionSet(permSet);
481 [System.Security.SecuritySafeCritical] // auto-generated
482 public void Recover() {
483 if (m_configId == ConfigId.None)
484 throw new PolicyException(Environment.GetResourceString("Policy_RecoverNotFileBased"));
487 // This call will safely swap the files.
488 if (!Config.RecoverData(m_configId))
489 throw new PolicyException(Environment.GetResourceString("Policy_RecoverNoConfigFile"));
491 // Now we need to blank out the level
493 m_rootCodeGroup = null;
494 m_namedPermissionSets = null;
495 m_fullTrustAssemblies = new ArrayList();
499 [System.Security.SecuritySafeCritical] // auto-generated
500 public void Reset() {
504 [System.Security.SecuritySafeCritical] // auto-generated
505 public PolicyStatement Resolve(Evidence evidence) {
506 return Resolve(evidence, 0, null);
509 [System.Security.SecuritySafeCritical] // auto-generated
510 public SecurityElement ToXml() {
511 // Make sure we have loaded everything and that all the
512 // permission sets are loaded.
515 LoadAllPermissionSets();
517 IEnumerator enumerator;
518 SecurityElement e = new SecurityElement("PolicyLevel");
519 e.AddAttribute("version", "1");
521 Hashtable classes = new Hashtable();
523 SecurityElement elPermSets = new SecurityElement("NamedPermissionSets");
524 enumerator = m_namedPermissionSets.GetEnumerator();
525 while (enumerator.MoveNext()) {
526 elPermSets.AddChild(NormalizeClassDeep(((NamedPermissionSet)enumerator.Current).ToXml(), classes));
529 SecurityElement elCodeGroup = NormalizeClassDeep(m_rootCodeGroup.ToXml(this), classes);
531 SecurityElement elFullTrust = new SecurityElement("FullTrustAssemblies");
532 enumerator = m_fullTrustAssemblies.GetEnumerator();
533 while (enumerator.MoveNext()) {
534 elFullTrust.AddChild(NormalizeClassDeep(((StrongNameMembershipCondition)enumerator.Current).ToXml(), classes));
537 SecurityElement elClasses = new SecurityElement("SecurityClasses");
538 IDictionaryEnumerator dicEnumerator = classes.GetEnumerator();
539 while (dicEnumerator.MoveNext()) {
540 SecurityElement elClass = new SecurityElement("SecurityClass");
541 elClass.AddAttribute("Name", (string)dicEnumerator.Value);
542 elClass.AddAttribute("Description", (string)dicEnumerator.Key);
543 elClasses.AddChild(elClass);
546 e.AddChild(elClasses);
547 e.AddChild(elPermSets);
548 e.AddChild(elCodeGroup);
549 e.AddChild(elFullTrust);
555 public void FromXml(SecurityElement e) {
557 throw new ArgumentNullException("e");
558 Contract.EndContractBlock();
562 ArrayList fullTrustAssemblies = new ArrayList();
564 SecurityElement eClasses = e.SearchForChildByTag("SecurityClasses");
565 if (eClasses != null) {
566 classes = new Hashtable();
567 IEnumerator enumerator = eClasses.Children.GetEnumerator();
568 while (enumerator.MoveNext()) {
569 SecurityElement current = (SecurityElement)enumerator.Current;
570 if (current.Tag.Equals("SecurityClass")) {
571 string name = current.Attribute("Name");
572 string description = current.Attribute("Description");
574 if (name != null && description != null)
575 classes.Add(name, description);
583 SecurityElement elFullTrust = e.SearchForChildByTag("FullTrustAssemblies");
584 if (elFullTrust != null && elFullTrust.InternalChildren != null) {
585 string className = typeof(System.Security.Policy.StrongNameMembershipCondition).AssemblyQualifiedName;
587 IEnumerator enumerator = elFullTrust.Children.GetEnumerator();
588 while (enumerator.MoveNext()) {
589 StrongNameMembershipCondition sn = new StrongNameMembershipCondition();
590 sn.FromXml((SecurityElement)enumerator.Current);
591 fullTrustAssemblies.Add(sn);
595 m_fullTrustAssemblies = fullTrustAssemblies;
597 ArrayList namedPermissionSets = new ArrayList();
599 SecurityElement elPermSets = e.SearchForChildByTag("NamedPermissionSets");
600 SecurityElement permSetElement = null;
602 // Here we just find the parent element for the named permission sets and
603 // store it so that we can lazily load them later.
605 if (elPermSets != null && elPermSets.InternalChildren != null) {
606 permSetElement = UnnormalizeClassDeep(elPermSets, classes);
608 // Call FindElement for each of the reserved sets (this removes their xml from
610 foreach (string builtInPermissionSet in s_reservedNamedPermissionSets) {
611 FindElement(permSetElement, builtInPermissionSet);
615 if (permSetElement == null)
616 permSetElement = new SecurityElement("NamedPermissionSets");
618 // Then we add in the immutable permission sets (this prevents any alterations
619 // to them in the XML file from impacting the runtime versions).
621 namedPermissionSets.Add(BuiltInPermissionSets.FullTrust);
622 namedPermissionSets.Add(BuiltInPermissionSets.Everything);
623 namedPermissionSets.Add(BuiltInPermissionSets.SkipVerification);
624 namedPermissionSets.Add(BuiltInPermissionSets.Execution);
625 namedPermissionSets.Add(BuiltInPermissionSets.Nothing);
626 namedPermissionSets.Add(BuiltInPermissionSets.Internet);
627 namedPermissionSets.Add(BuiltInPermissionSets.LocalIntranet);
629 foreach(PermissionSet ps in namedPermissionSets)
630 ps.IgnoreTypeLoadFailures = true;
632 m_namedPermissionSets = namedPermissionSets;
633 m_permSetElement = permSetElement;
635 // Parse the root code group.
636 SecurityElement elCodeGroup = e.SearchForChildByTag("CodeGroup");
637 if (elCodeGroup == null)
638 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXMLElement", "CodeGroup", this.GetType().FullName));
640 CodeGroup rootCodeGroup = System.Security.Util.XMLUtil.CreateCodeGroup(UnnormalizeClassDeep(elCodeGroup, classes));
641 if (rootCodeGroup == null)
642 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXMLElement", "CodeGroup", this.GetType().FullName));
644 rootCodeGroup.FromXml(elCodeGroup, this);
645 m_rootCodeGroup = rootCodeGroup;
653 [System.Security.SecurityCritical] // auto-generated
654 internal static PermissionSet GetBuiltInSet(string name) {
655 // Used by PermissionSetAttribute to create one of the built-in,
656 // immutable permission sets.
658 if (String.IsNullOrEmpty(name)) {
661 else if (name.Equals("FullTrust")) {
662 return BuiltInPermissionSets.FullTrust;
664 else if (name.Equals("Nothing")) {
665 return BuiltInPermissionSets.Nothing;
667 else if (name.Equals("Execution")) {
668 return BuiltInPermissionSets.Execution;
670 else if (name.Equals("SkipVerification")) {
671 return BuiltInPermissionSets.SkipVerification;
673 else if (name.Equals("Internet")) {
674 return BuiltInPermissionSets.Internet;
676 else if (name.Equals("LocalIntranet")) {
677 return BuiltInPermissionSets.LocalIntranet;
684 [System.Security.SecurityCritical] // auto-generated
685 internal NamedPermissionSet GetNamedPermissionSetInternal(string name) {
688 lock (InternalSyncObject)
690 // First, try to find it in the list.
691 foreach (NamedPermissionSet permissionSet in m_namedPermissionSets) {
692 if (permissionSet.Name.Equals(name)) {
693 return permissionSet;
698 // We didn't find it in the list, so if we have a stored element
699 // see if it is there.
701 if (m_permSetElement != null)
703 SecurityElement elem = FindElement(m_permSetElement, name);
706 NamedPermissionSet permSet = new NamedPermissionSet();
708 m_namedPermissionSets.Add(permSet);
711 // We play it conservative here and just say that we are loading policy
712 // anytime we have to decode a permission set.
713 permSet.FromXml(elem, false, true);
717 m_namedPermissionSets.Remove(permSet);
721 if (permSet.Name != null)
727 m_namedPermissionSets.Remove(permSet);
736 [System.Security.SecurityCritical] // auto-generated
737 internal PolicyStatement Resolve (Evidence evidence, int count, byte[] serializedEvidence) {
738 if (evidence == null)
739 throw new ArgumentNullException("evidence");
740 Contract.EndContractBlock();
742 PolicyStatement policy = null;
743 if (serializedEvidence != null)
744 policy = CheckCache(count, serializedEvidence);
746 if (policy == null) {
750 bool isFullTrust = m_fullTrustAssemblies != null && IsFullTrustAssembly(m_fullTrustAssemblies, evidence);
752 policy = new PolicyStatement(new PermissionSet(true), PolicyStatementAttribute.Nothing);
756 ArrayList list = GenericResolve(evidence, out allConst);
757 policy = new PolicyStatement();
758 // This will set the permission set to the empty set.
759 policy.PermissionSet = null;
761 IEnumerator enumerator = list.GetEnumerator();
762 while (enumerator.MoveNext()) {
763 PolicyStatement ps = ((CodeGroupStackFrame)enumerator.Current).policy;
765 policy.GetPermissionSetNoCopy().InplaceUnion(ps.GetPermissionSetNoCopy());
766 policy.Attributes |= ps.Attributes;
768 // If we find a policy statement that's dependent upon unverified evidence, we
769 // need to mark that as used so that the VM can potentially force verification on
771 if (ps.HasDependentEvidence) {
772 foreach (IDelayEvaluatedEvidence delayEvidence in ps.DependentEvidence) {
773 delayEvidence.MarkUsed();
780 // We want to store in the cache the evidence that was touched during policy evaluation
781 // rather than the input serialized evidence, since that evidence is optimized for the
782 // standard policy and is not all-inclusive. We need to make sure that any evidence
783 // used to determine the grant set is added to the cache key.
784 Cache(count, evidence.RawSerialize(), policy);
795 [System.Security.SecurityCritical] // auto-generated
796 private void CheckLoaded () {
798 lock (InternalSyncObject) {
805 [ResourceExposure(ResourceScope.Machine)]
806 [ResourceConsumption(ResourceScope.Machine)]
807 private static byte[] ReadFile (string fileName) {
808 using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
809 int size = (int) stream.Length;
810 byte[] data = new byte[size];
811 size = stream.Read(data, 0, size);
817 [System.Security.SecurityCritical] // auto-generated
818 [ResourceExposure(ResourceScope.None)]
819 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
820 private void LoadPolicyLevel () {
821 SecurityElement elRoot;
822 Exception exception = null;
824 CodeAccessPermission.Assert(true);
825 if (!File.InternalExists(m_path))
828 Encoding encoding = Encoding.UTF8;
831 string data = encoding.GetString(ReadFile(m_path));
832 elRoot = SecurityElement.FromString(data);
834 catch (Exception ex) {
836 if (!String.IsNullOrEmpty(ex.Message)) {
837 message = ex.Message;
840 message = ex.GetType().AssemblyQualifiedName;
842 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParseEx", Label, message));
846 if (elRoot == null) {
847 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
851 SecurityElement elMscorlib = elRoot.SearchForChildByTag("mscorlib");
852 if (elMscorlib == null) {
853 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
857 SecurityElement elSecurity = elMscorlib.SearchForChildByTag("security");
858 if (elSecurity == null) {
859 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
863 SecurityElement elPolicy = elSecurity.SearchForChildByTag("policy");
864 if (elPolicy == null) {
865 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
869 SecurityElement elPolicyLevel = elPolicy.SearchForChildByTag("PolicyLevel");
870 if (elPolicyLevel != null) {
872 this.FromXml(elPolicyLevel);
875 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
880 exception = LoadError(Environment.GetResourceString("Error_SecurityPolicyFileParse", Label));
891 if (exception != null)
895 [System.Security.SecurityCritical] // auto-generated
896 private Exception LoadError (string message) {
898 // We ignore TypeLoadExceptions in the case of user, machine
899 // and Enterprise policy levels as some clients depend on that
900 // behavior. We'll throw an exception for any other policy levels.
903 if (m_type != PolicyLevelType.User &&
904 m_type != PolicyLevelType.Machine &&
905 m_type != PolicyLevelType.Enterprise) {
906 return new ArgumentException(message);
909 Config.WriteToEventLog(message);
914 [System.Security.SecurityCritical] // auto-generated
915 private void Cache (int count, byte[] serializedEvidence, PolicyStatement policy) {
916 if (m_configId == ConfigId.None)
918 if (serializedEvidence == null)
921 byte[] policyArray = new SecurityDocument(policy.ToXml(null, true)).m_data;
922 Config.AddCacheEntry(m_configId, count, serializedEvidence, policyArray);
925 [System.Security.SecurityCritical] // auto-generated
926 private PolicyStatement CheckCache (int count, byte[] serializedEvidence) {
927 if (m_configId == ConfigId.None)
929 if (serializedEvidence == null)
933 if (!Config.GetCacheEntry(m_configId, count, serializedEvidence, out cachedValue))
936 PolicyStatement cachedSet = new PolicyStatement();
937 SecurityDocument doc = new SecurityDocument(cachedValue);
938 cachedSet.FromXml(doc, 0, null, true);
942 [System.Security.SecurityCritical] // auto-generated
943 private static bool IsFullTrustAssembly(ArrayList fullTrustAssemblies, Evidence evidence) {
944 if (fullTrustAssemblies.Count == 0)
947 if (evidence != null) {
948 lock (fullTrustAssemblies) {
949 IEnumerator enumerator = fullTrustAssemblies.GetEnumerator();
951 while (enumerator.MoveNext()) {
952 StrongNameMembershipCondition snMC = (StrongNameMembershipCondition) enumerator.Current;
953 if (snMC.Check(evidence)) {
954 if (Environment.GetCompatibilityFlag(CompatibilityFlag.FullTrustListAssembliesInGac)) {
955 if (new ZoneMembershipCondition().Check(evidence))
959 if (new GacMembershipCondition().Check(evidence))
969 #pragma warning disable 618 // Policy is obsolete
970 private CodeGroup CreateDefaultAllGroup() {
971 UnionCodeGroup group = new UnionCodeGroup();
972 group.FromXml(CreateCodeGroupElement("UnionCodeGroup", "FullTrust", new AllMembershipCondition().ToXml()), this);
973 group.Name = Environment.GetResourceString("Policy_AllCode_Name");
974 group.Description = Environment.GetResourceString("Policy_AllCode_DescriptionFullTrust");
978 [System.Security.SecurityCritical] // auto-generated
979 private CodeGroup CreateDefaultMachinePolicy() {
980 UnionCodeGroup root = new UnionCodeGroup();
981 root.FromXml(CreateCodeGroupElement("UnionCodeGroup", "Nothing", new AllMembershipCondition().ToXml()), this);
982 root.Name = Environment.GetResourceString("Policy_AllCode_Name");
983 root.Description = Environment.GetResourceString("Policy_AllCode_DescriptionNothing");
985 UnionCodeGroup myComputerCodeGroup = new UnionCodeGroup();
986 myComputerCodeGroup.FromXml(CreateCodeGroupElement("UnionCodeGroup", "FullTrust", new ZoneMembershipCondition(SecurityZone.MyComputer).ToXml()), this);
987 myComputerCodeGroup.Name = Environment.GetResourceString("Policy_MyComputer_Name");
988 myComputerCodeGroup.Description = Environment.GetResourceString("Policy_MyComputer_Description");
990 // This code give trust to anything StrongName signed by Microsoft.
991 StrongNamePublicKeyBlob blob = new StrongNamePublicKeyBlob(AssemblyRef.MicrosoftPublicKeyFull);
992 UnionCodeGroup microsoft = new UnionCodeGroup();
993 microsoft.FromXml(CreateCodeGroupElement("UnionCodeGroup", "FullTrust", new StrongNameMembershipCondition(blob, null, null).ToXml()), this);
994 microsoft.Name = Environment.GetResourceString("Policy_Microsoft_Name");
995 microsoft.Description = Environment.GetResourceString("Policy_Microsoft_Description");
996 myComputerCodeGroup.AddChildInternal(microsoft);
998 // This code give trust to anything StrongName signed using the ECMA
999 // public key (core system assemblies).
1000 blob = new StrongNamePublicKeyBlob(AssemblyRef.EcmaPublicKeyFull);
1001 UnionCodeGroup ecma = new UnionCodeGroup();
1002 ecma.FromXml(CreateCodeGroupElement("UnionCodeGroup", "FullTrust", new StrongNameMembershipCondition(blob, null, null).ToXml()), this);
1003 ecma.Name = Environment.GetResourceString("Policy_Ecma_Name");
1004 ecma.Description = Environment.GetResourceString("Policy_Ecma_Description");
1005 myComputerCodeGroup.AddChildInternal(ecma);
1007 root.AddChildInternal(myComputerCodeGroup);
1009 // do the rest of the zones
1010 CodeGroup intranet = new UnionCodeGroup();
1011 intranet.FromXml(CreateCodeGroupElement("UnionCodeGroup", "LocalIntranet", new ZoneMembershipCondition(SecurityZone.Intranet).ToXml()), this);
1012 intranet.Name = Environment.GetResourceString("Policy_Intranet_Name");
1013 intranet.Description = Environment.GetResourceString("Policy_Intranet_Description");
1015 CodeGroup intranetNetCode = new NetCodeGroup(new AllMembershipCondition());
1016 intranetNetCode.Name = Environment.GetResourceString("Policy_IntranetNet_Name");
1017 intranetNetCode.Description = Environment.GetResourceString("Policy_IntranetNet_Description");
1018 intranet.AddChildInternal(intranetNetCode);
1020 CodeGroup intranetFileCode = new FileCodeGroup(new AllMembershipCondition(), FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery);
1021 intranetFileCode.Name = Environment.GetResourceString("Policy_IntranetFile_Name");
1022 intranetFileCode.Description = Environment.GetResourceString("Policy_IntranetFile_Description");
1023 intranet.AddChildInternal(intranetFileCode);
1025 root.AddChildInternal(intranet);
1027 CodeGroup internet = new UnionCodeGroup();
1028 internet.FromXml(CreateCodeGroupElement("UnionCodeGroup", "Internet", new ZoneMembershipCondition(SecurityZone.Internet).ToXml()), this);
1029 internet.Name = Environment.GetResourceString("Policy_Internet_Name");
1030 internet.Description = Environment.GetResourceString("Policy_Internet_Description");
1032 CodeGroup internetNet = new NetCodeGroup(new AllMembershipCondition());
1033 internetNet.Name = Environment.GetResourceString("Policy_InternetNet_Name");
1034 internetNet.Description = Environment.GetResourceString("Policy_InternetNet_Description");
1035 internet.AddChildInternal(internetNet);
1037 root.AddChildInternal(internet);
1039 CodeGroup untrusted = new UnionCodeGroup();
1040 untrusted.FromXml(CreateCodeGroupElement("UnionCodeGroup", "Nothing", new ZoneMembershipCondition(SecurityZone.Untrusted).ToXml()), this);
1041 untrusted.Name = Environment.GetResourceString("Policy_Untrusted_Name");
1042 untrusted.Description = Environment.GetResourceString("Policy_Untrusted_Description");
1043 root.AddChildInternal(untrusted);
1045 CodeGroup trusted = new UnionCodeGroup();
1046 trusted.FromXml(CreateCodeGroupElement("UnionCodeGroup", "Internet", new ZoneMembershipCondition(SecurityZone.Trusted).ToXml()), this);
1047 trusted.Name = Environment.GetResourceString("Policy_Trusted_Name");
1048 trusted.Description = Environment.GetResourceString("Policy_Trusted_Description");
1049 CodeGroup trustedNet = new NetCodeGroup(new AllMembershipCondition());
1050 trustedNet.Name = Environment.GetResourceString("Policy_TrustedNet_Name");
1051 trustedNet.Description = Environment.GetResourceString("Policy_TrustedNet_Description");
1052 trusted.AddChildInternal(trustedNet);
1054 root.AddChildInternal(trusted);
1059 private static SecurityElement CreateCodeGroupElement(string codeGroupType, string permissionSetName, SecurityElement mshipElement) {
1060 SecurityElement root = new SecurityElement("CodeGroup");
1061 root.AddAttribute("class", "System.Security." + codeGroupType + ", mscorlib, Version={VERSION}, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken + "");
1062 root.AddAttribute("version", "1");
1063 root.AddAttribute("PermissionSetName", permissionSetName);
1065 root.AddChild(mshipElement);
1069 #pragma warning restore 618
1071 private static string[] EcmaFullTrustAssemblies = new string[] {
1072 "mscorlib.resources",
1076 "System.Xml.resources",
1077 "System.Windows.Forms",
1078 "System.Windows.Forms.resources",
1081 "System.Data.resources",
1082 #endif // !FEATURE_PAL
1084 private static string[] MicrosoftFullTrustAssemblies = new string[] {
1087 "System.Security.resources",
1089 "System.Drawing.resources",
1091 "System.Messaging.resources",
1092 "System.ServiceProcess",
1093 "System.ServiceProcess.resources",
1094 "System.DirectoryServices",
1095 "System.DirectoryServices.resources",
1096 "System.Deployment",
1097 "System.Deployment.resources"
1098 #endif // !FEATURE_PAL
1101 private void SetDefaultFullTrustAssemblies() {
1102 m_fullTrustAssemblies = new ArrayList();
1104 StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob(AssemblyRef.EcmaPublicKeyFull);
1105 for (int index=0; index < EcmaFullTrustAssemblies.Length; index++) {
1106 StrongNameMembershipCondition sn = new StrongNameMembershipCondition(ecmaBlob,
1107 EcmaFullTrustAssemblies[index],
1108 new Version(ThisAssembly.Version));
1109 m_fullTrustAssemblies.Add(sn);
1112 StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob(AssemblyRef.MicrosoftPublicKeyFull);
1113 for (int index=0; index < MicrosoftFullTrustAssemblies.Length; index++) {
1114 StrongNameMembershipCondition sn = new StrongNameMembershipCondition(microsoftBlob,
1115 MicrosoftFullTrustAssemblies[index],
1116 new Version(ThisAssembly.Version));
1117 m_fullTrustAssemblies.Add(sn);
1121 [System.Security.SecurityCritical] // auto-generated
1122 [ResourceExposure(ResourceScope.None)]
1123 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1124 private void SetDefault() {
1126 string path = GetLocationFromType(m_type) + ".default";
1127 if (File.InternalExists(path)) {
1128 PolicyLevel level = new PolicyLevel(m_type, path);
1129 m_rootCodeGroup = level.RootCodeGroup;
1130 m_namedPermissionSets = (ArrayList)level.NamedPermissionSets;
1131 #pragma warning disable 618 // for obsolete FullTrustAssemblies property.
1132 m_fullTrustAssemblies = (ArrayList)level.FullTrustAssemblies;
1133 #pragma warning restore 618
1137 m_namedPermissionSets = null;
1138 m_rootCodeGroup = null;
1139 m_permSetElement = null;
1140 m_rootCodeGroup = (m_type == PolicyLevelType.Machine ? CreateDefaultMachinePolicy() : CreateDefaultAllGroup());
1141 SetFactoryPermissionSets();
1142 SetDefaultFullTrustAssemblies();
1148 private void SetFactoryPermissionSets() {
1149 lock (InternalSyncObject) {
1150 m_namedPermissionSets = new ArrayList();
1151 m_namedPermissionSets.Add(BuiltInPermissionSets.FullTrust);
1152 m_namedPermissionSets.Add(BuiltInPermissionSets.Everything);
1153 m_namedPermissionSets.Add(BuiltInPermissionSets.Nothing);
1154 m_namedPermissionSets.Add(BuiltInPermissionSets.SkipVerification);
1155 m_namedPermissionSets.Add(BuiltInPermissionSets.Execution);
1156 m_namedPermissionSets.Add(BuiltInPermissionSets.Internet);
1157 m_namedPermissionSets.Add(BuiltInPermissionSets.LocalIntranet);
1161 private SecurityElement FindElement(SecurityElement element, string name) {
1162 // This method searches through the children of the saved element
1163 // for a named permission set that matches the input name.
1164 // If it finds a matching set, the appropriate xml element is
1165 // removed from as a child of the parent and then returned.
1167 IEnumerator elemEnumerator = element.Children.GetEnumerator();
1169 while (elemEnumerator.MoveNext()) {
1170 SecurityElement elPermSet = (SecurityElement)elemEnumerator.Current;
1171 if (elPermSet.Tag.Equals("PermissionSet")) {
1172 string elName = elPermSet.Attribute("Name");
1174 if (elName != null && elName.Equals(name)) {
1175 element.InternalChildren.Remove(elPermSet);
1184 [System.Security.SecurityCritical] // auto-generated
1185 private void LoadAllPermissionSets()
1187 // This function loads all the permission sets held in the m_permSetElement member.
1188 // This is useful when you know that an arbitrary permission set loaded from
1189 // the config file could be accessed so you just want to forego the lazy load
1190 // and play it safe.
1192 if (m_permSetElement != null && m_permSetElement.InternalChildren != null) {
1193 lock (InternalSyncObject) {
1194 while (m_permSetElement != null && m_permSetElement.InternalChildren.Count != 0) {
1195 SecurityElement elPermSet = (SecurityElement)m_permSetElement.Children[m_permSetElement.InternalChildren.Count-1];
1196 m_permSetElement.InternalChildren.RemoveAt(m_permSetElement.InternalChildren.Count-1);
1198 if (elPermSet.Tag.Equals("PermissionSet") && elPermSet.Attribute("class").Equals("System.Security.NamedPermissionSet")) {
1199 NamedPermissionSet permSet = new NamedPermissionSet();
1200 permSet.FromXmlNameOnly(elPermSet);
1202 if (permSet.Name != null) {
1203 m_namedPermissionSets.Add(permSet);
1205 permSet.FromXml(elPermSet, false, true);
1208 m_namedPermissionSets.Remove(permSet);
1214 m_permSetElement = null;
1219 #pragma warning disable 618 // Legacy policy is obsolete
1220 [System.Security.SecurityCritical] // auto-generated
1221 private ArrayList GenericResolve(Evidence evidence, out bool allConst) {
1222 CodeGroupStack stack = new CodeGroupStack();
1224 // Note: if m_rootCodeGroup is null it means that we've
1225 // hit a recursive load case and ended up needing to
1226 // do a resolve on an assembly used in policy but is
1227 // not covered by the full trust assemblies list. We'll
1228 // throw a policy exception to cover this case.
1230 CodeGroupStackFrame frame;
1231 CodeGroup rootCodeGroupRef = m_rootCodeGroup;
1233 if (rootCodeGroupRef == null)
1234 throw new PolicyException(Environment.GetResourceString("Policy_NonFullTrustAssembly"));
1236 frame = new CodeGroupStackFrame();
1237 frame.current = rootCodeGroupRef;
1238 frame.parent = null;
1242 ArrayList accumulator = new ArrayList();
1244 bool foundExclusive = false;
1248 Exception storedException = null;
1250 while (!stack.IsEmpty()) {
1251 frame = stack.Pop();
1253 FirstMatchCodeGroup firstMatchGroup = frame.current as FirstMatchCodeGroup;
1254 UnionCodeGroup unionGroup = frame.current as UnionCodeGroup;
1256 if (!(frame.current.MembershipCondition is IConstantMembershipCondition) ||
1257 (unionGroup == null && firstMatchGroup == null)) {
1262 frame.policy = PolicyManager.ResolveCodeGroup(frame.current, evidence);
1264 catch (Exception e) {
1265 // If any exception occurs while attempting a resolve, we catch it here and
1266 // set the equivalent of the resolve not matching to the evidence.
1267 //frame.policy = null;
1269 if (storedException == null)
1270 storedException = e;
1273 if (frame.policy != null) {
1274 if ((frame.policy.Attributes & PolicyStatementAttribute.Exclusive) != 0) {
1276 throw new PolicyException(Environment.GetResourceString("Policy_MultipleExclusive"));
1278 accumulator.RemoveRange(0, accumulator.Count);
1279 accumulator.Add(frame);
1280 foundExclusive = true;
1283 if (!foundExclusive) {
1284 accumulator.Add(frame);
1289 if (storedException != null)
1290 throw storedException;
1294 #pragma warning restore 618
1296 private static string GenerateFriendlyName(string className, Hashtable classes) {
1297 if (classes.ContainsKey(className))
1298 return (string)classes[className];
1300 Type type = System.Type.GetType(className, false, false);
1301 if (type != null && !type.IsVisible)
1307 if (!classes.ContainsValue(type.Name)) {
1308 classes.Add(className, type.Name);
1311 else if (!classes.ContainsValue(type.FullName)) {
1312 classes.Add(className, type.FullName);
1313 return type.FullName;
1316 classes.Add(className, type.AssemblyQualifiedName);
1317 return type.AssemblyQualifiedName;
1321 private SecurityElement NormalizeClassDeep(SecurityElement elem, Hashtable classes) {
1322 NormalizeClass(elem, classes);
1324 if (elem.InternalChildren != null && elem.InternalChildren.Count > 0) {
1325 IEnumerator enumerator = elem.Children.GetEnumerator();
1326 while (enumerator.MoveNext()) {
1327 NormalizeClassDeep((SecurityElement)enumerator.Current, classes);
1334 private SecurityElement NormalizeClass(SecurityElement elem, Hashtable classes) {
1335 if (elem.m_lAttributes == null || elem.m_lAttributes.Count == 0)
1338 int iMax = elem.m_lAttributes.Count;
1339 Contract.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
1341 for (int i = 0; i < iMax; i += 2) {
1342 string strAttrName = (string)elem.m_lAttributes[i];
1344 if (strAttrName.Equals("class")) {
1345 string strAttrValue = (string)elem.m_lAttributes[i+1];
1347 elem.m_lAttributes[i+1] = GenerateFriendlyName(strAttrValue, classes);
1349 // only one class attribute so we can stop once we found it
1357 private SecurityElement UnnormalizeClassDeep(SecurityElement elem, Hashtable classes) {
1358 UnnormalizeClass(elem, classes);
1360 if (elem.InternalChildren != null && elem.InternalChildren.Count > 0) {
1361 IEnumerator enumerator = elem.Children.GetEnumerator();
1363 while (enumerator.MoveNext()) {
1364 UnnormalizeClassDeep((SecurityElement)enumerator.Current, classes);
1371 private SecurityElement UnnormalizeClass(SecurityElement elem, Hashtable classes) {
1372 if (classes == null || elem.m_lAttributes == null || elem.m_lAttributes.Count == 0)
1375 int iMax = elem.m_lAttributes.Count;
1376 Contract.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
1378 for (int i = 0; i < iMax; i += 2) {
1379 string strAttrName = (string)elem.m_lAttributes[i];
1381 if (strAttrName.Equals("class")) {
1382 string strAttrValue = (string)elem.m_lAttributes[i+1];
1383 string className = (string)classes[strAttrValue];
1385 if (className != null)
1386 elem.m_lAttributes[i+1] = className;
1388 // only one class attribute so we can stop after we found it
1389 // no other matches are possible
1398 internal sealed class CodeGroupStackFrame {
1399 internal CodeGroup current;
1400 internal PolicyStatement policy;
1401 internal CodeGroupStackFrame parent;
1404 internal sealed class CodeGroupStack {
1405 private ArrayList m_array;
1407 internal CodeGroupStack() {
1408 m_array = new ArrayList();
1411 internal void Push(CodeGroupStackFrame element) {
1412 m_array.Add(element);
1415 internal CodeGroupStackFrame Pop() {
1417 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyStack"));
1418 Contract.EndContractBlock();
1420 int count = m_array.Count;
1421 CodeGroupStackFrame temp = (CodeGroupStackFrame) m_array[count-1];
1422 m_array.RemoveAt(count-1);
1427 internal bool IsEmpty() {
1428 return m_array.Count == 0;