1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 //
8 
9 namespace System.Security {
10     using System;
11     using System.Threading;
12     using System.Security.Util;
13     using System.Collections;
14     using System.IO;
15     using System.Security.Permissions;
16     using System.Runtime.CompilerServices;
17     using System.Security.Policy;
18 #if FEATURE_SERIALIZATION
19     using System.Runtime.Serialization.Formatters.Binary;
20 #endif // FEATURE_SERIALIZATION
21     using BindingFlags = System.Reflection.BindingFlags;
22     using System.Runtime.Serialization;
23     using System.Text;
24     using System.Globalization;
25     using System.Runtime.Versioning;
26     using System.Diagnostics.Contracts;
27 
28     [Serializable]
29     internal enum SpecialPermissionSetFlag
30     {
31         // These also appear in clr/src/vm/permset.h
32         Regular = 0,
33         NoSet = 1,
34         EmptySet = 2,
35         SkipVerification = 3
36     }
37 
38     [Serializable]
39 #if !FEATURE_CORECLR
40     [StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, Name = "mscorlib", PublicKey = "0x" + AssemblyRef.EcmaPublicKeyFull)]
41 #endif
42     [System.Runtime.InteropServices.ComVisible(true)]
43     public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk, IDeserializationCallback
44     {
45     #if _DEBUG
46         internal static readonly bool debug;
47     #endif
48 
49         [System.Diagnostics.Conditional( "_DEBUG" )]
50         [ResourceExposure(ResourceScope.None)]
51         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
DEBUG_WRITE(String str)52         private static void DEBUG_WRITE(String str) {
53         #if _DEBUG
54             if (debug) Console.WriteLine(str);
55         #endif
56          }
57 
58         [System.Diagnostics.Conditional( "_DEBUG" )]
59         [ResourceExposure(ResourceScope.None)]
60         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
DEBUG_COND_WRITE(bool exp, String str)61         private static void DEBUG_COND_WRITE(bool exp, String str)
62         {
63         #if _DEBUG
64             if (debug && (exp)) Console.WriteLine(str);
65         #endif
66         }
67 
68         [System.Diagnostics.Conditional( "_DEBUG" )]
69         [ResourceExposure(ResourceScope.None)]
70         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
DEBUG_PRINTSTACK(Exception e)71         private static void DEBUG_PRINTSTACK(Exception e)
72         {
73         #if _DEBUG
74             if (debug) Console.Error.WriteLine((e).StackTrace);
75         #endif
76         }
77 
78         // These members are accessed from EE using their hardcoded offset.
79         // Please update the PermissionSetObject in object.h if you make any changes
80         // to the fields here. !dumpobj will show the field layout
81 
82         // First the fields that are serialized x-appdomain (for perf reasons)
83         private bool m_Unrestricted;
84         [OptionalField(VersionAdded = 2)]
85         private bool m_allPermissionsDecoded = false;
86 
87         [OptionalField(VersionAdded = 2)]
88         internal TokenBasedSet m_permSet = null;
89 
90         // This is a hack so that SQL can operate under default policy without actually
91         // granting permissions in assemblies that they disallow.  @
92 
93 
94         [OptionalField(VersionAdded = 2)]
95         private bool m_ignoreTypeLoadFailures = false;
96 
97         // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the PermissionSet
98         [OptionalField(VersionAdded = 2)]
99         private String m_serializedPermissionSet;
100 
101         [NonSerialized] private bool m_CheckedForNonCas;
102         [NonSerialized] private bool m_ContainsCas;
103         [NonSerialized] private bool m_ContainsNonCas;
104 
105         // only used during non X-AD serialization to save the m_permSet value (which we dont want serialized)
106         [NonSerialized] private TokenBasedSet m_permSetSaved;
107 
108         // Following 4 fields are used only for serialization compat purposes: DO NOT USE THESE EVER!
109 #pragma warning disable 169
110         private bool readableonly;
111         private TokenBasedSet m_unrestrictedPermSet;
112         private TokenBasedSet m_normalPermSet;
113 
114         [OptionalField(VersionAdded = 2)]
115         private bool m_canUnrestrictedOverride;
116 #pragma warning restore 169
117         // END: Serialization-only fields
118 
119         internal static readonly PermissionSet s_fullTrust = new PermissionSet( true );
120 
121 #if FEATURE_REMOTING
122         [OnDeserializing]
OnDeserializing(StreamingContext ctx)123         private void OnDeserializing(StreamingContext ctx)
124         {
125             Reset();
126         }
127 
128         [OnDeserialized]
OnDeserialized(StreamingContext ctx)129         private void OnDeserialized(StreamingContext ctx)
130         {
131             if (m_serializedPermissionSet != null)
132             {
133                 // Whidbey non X-AD case
134                 FromXml(SecurityElement.FromString(m_serializedPermissionSet));
135             }
136             else if (m_normalPermSet != null)
137             {
138                 // Everett non X-AD case
139                 m_permSet = m_normalPermSet.SpecialUnion(m_unrestrictedPermSet);
140             }
141             else if (m_unrestrictedPermSet != null)
142             {
143                 // Everett non X-AD case
144                 m_permSet = m_unrestrictedPermSet.SpecialUnion(m_normalPermSet);
145             }
146 
147             m_serializedPermissionSet = null;
148             m_normalPermSet = null;
149             m_unrestrictedPermSet = null;
150 
151         }
152 
153         [OnSerializing]
OnSerializing(StreamingContext ctx)154         private void OnSerializing(StreamingContext ctx)
155         {
156 
157             if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
158             {
159                 m_serializedPermissionSet = ToString(); // For v2.x and beyond
160                 if (m_permSet != null)
161                     m_permSet.SpecialSplit(ref m_unrestrictedPermSet, ref m_normalPermSet, m_ignoreTypeLoadFailures);
162                 m_permSetSaved = m_permSet;
163                 m_permSet = null;
164             }
165         }
166 #endif // !FEATURE_REMOTING
167 
168 #if FEATURE_REMOTING || _DEBUG
169         [OnSerialized]
OnSerialized(StreamingContext context)170         private void OnSerialized(StreamingContext context)
171         {
172 #if FEATURE_REMOTING
173             if ((context.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
174             {
175                 m_serializedPermissionSet = null;
176                 m_permSet = m_permSetSaved;
177                 m_permSetSaved = null;
178                 m_unrestrictedPermSet = null;
179                 m_normalPermSet = null;
180             }
181 #else // !FEATURE_REMOTING
182             Contract.Assert(false, "PermissionSet does not support serialization on CoreCLR");
183 #endif // !FEATURE_REMOTING
184         }
185 #endif // FEATURE_REMOTING || _DEBUG
186 
PermissionSet()187         internal PermissionSet()
188         {
189             Reset();
190             m_Unrestricted = true;
191         }
192 
PermissionSet(bool fUnrestricted)193         internal PermissionSet(bool fUnrestricted)
194             : this()
195         {
196             SetUnrestricted(fUnrestricted);
197         }
198 
PermissionSet(PermissionState state)199         public PermissionSet(PermissionState state)
200             : this()
201         {
202             if (state == PermissionState.Unrestricted)
203             {
204                 SetUnrestricted( true );
205             }
206             else if (state == PermissionState.None)
207             {
208                 SetUnrestricted( false );
209             }
210             else
211             {
212                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
213             }
214         }
215 
PermissionSet(PermissionSet permSet)216         public PermissionSet(PermissionSet permSet)
217             : this()
218         {
219             if (permSet == null)
220             {
221                 Reset();
222                 return;
223             }
224 
225             m_Unrestricted = permSet.m_Unrestricted;
226             m_CheckedForNonCas = permSet.m_CheckedForNonCas;
227             m_ContainsCas = permSet.m_ContainsCas;
228             m_ContainsNonCas = permSet.m_ContainsNonCas;
229             m_ignoreTypeLoadFailures = permSet.m_ignoreTypeLoadFailures;
230 
231             if (permSet.m_permSet != null)
232             {
233                 m_permSet = new TokenBasedSet(permSet.m_permSet);
234 
235                 // now deep copy all permissions in set
236                 for (int i = m_permSet.GetStartingIndex(); i <= m_permSet.GetMaxUsedIndex(); i++)
237                 {
238                     Object obj = m_permSet.GetItem(i);
239                     IPermission perm = obj as IPermission;
240 #if FEATURE_CAS_POLICY
241                     ISecurityElementFactory elem = obj as ISecurityElementFactory;
242 #endif // FEATURE_CAS_POLICY
243                     if (perm != null)
244                     {
245                         m_permSet.SetItem(i, perm.Copy());
246                     }
247 #if FEATURE_CAS_POLICY
248                     else if (elem != null)
249                     {
250                         m_permSet.SetItem(i, elem.Copy());
251                     }
252 #endif // FEATURE_CAS_POLICY
253                 }
254             }
255         }
256 
CopyTo(Array array, int index)257         public virtual void CopyTo(Array array, int index)
258         {
259             if (array == null)
260                 throw new ArgumentNullException( "array" );
261             Contract.EndContractBlock();
262 
263             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
264 
265             while (enumerator.MoveNext())
266             {
267                 array.SetValue(enumerator.Current , index++ );
268             }
269         }
270 
271 
272         // private constructor that doesn't create any token based sets
PermissionSet( Object trash, Object junk )273         private PermissionSet( Object trash, Object junk )
274         {
275             m_Unrestricted = false;
276         }
277 
278 
279         // Returns an object appropriate for synchronizing access to this
280         // Array.
281         public virtual Object SyncRoot
282         {  get { return this; } }
283 
284         // Is this Array synchronized (i.e., thread-safe)?  If you want a synchronized
285         // collection, you can use SyncRoot as an object to synchronize your
286         // collection with.  You could also call GetSynchronized()
287         // to get a synchronized wrapper around the Array.
288         public virtual bool IsSynchronized
289         {  get { return false; } }
290 
291         // Is this Collection ReadOnly?
292         public virtual bool IsReadOnly
293         {  get {return false; } }
294 
295         // Reinitializes all state in PermissionSet - DO NOT null-out m_serializedPermissionSet
Reset()296         internal void Reset()
297         {
298             m_Unrestricted = false;
299             m_allPermissionsDecoded = true;
300             m_permSet = null;
301 
302             m_ignoreTypeLoadFailures = false;
303 
304             m_CheckedForNonCas = false;
305             m_ContainsCas = false;
306             m_ContainsNonCas = false;
307             m_permSetSaved = null;
308 
309 
310         }
311 
CheckSet()312         internal void CheckSet()
313         {
314             if (this.m_permSet == null)
315                 this.m_permSet = new TokenBasedSet();
316         }
317 
IsEmpty()318         public bool IsEmpty()
319         {
320             if (m_Unrestricted)
321                 return false;
322 
323             if (m_permSet == null || m_permSet.FastIsEmpty())
324                 return true;
325 
326             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
327 
328             while (enumerator.MoveNext())
329             {
330                 IPermission perm = (IPermission)enumerator.Current;
331 
332                 if (!perm.IsSubsetOf( null ))
333                 {
334                     return false;
335                 }
336             }
337 
338             return true;
339         }
340 
FastIsEmpty()341         internal bool FastIsEmpty()
342         {
343             if (m_Unrestricted)
344                 return false;
345 
346             if (m_permSet == null || m_permSet.FastIsEmpty())
347                 return true;
348 
349             return false;
350         }
351 
352         public virtual int Count
353         {
354             get
355             {
356                 int count = 0;
357 
358                 if (m_permSet != null)
359                     count += m_permSet.GetCount();
360 
361                 return count;
362             }
363         }
364 
GetPermission(int index)365         internal IPermission GetPermission(int index)
366         {
367             if (m_permSet == null)
368                 return null;
369             Object obj = m_permSet.GetItem( index );
370             if (obj == null)
371                 return null;
372             IPermission perm = obj as IPermission;
373             if (perm != null)
374                 return perm;
375 #if FEATURE_CAS_POLICY
376             perm = CreatePermission(obj, index);
377 #endif // FEATURE_CAS_POLICY
378             if (perm == null)
379                 return null;
380             Contract.Assert( PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ),
381                              "PermissionToken was improperly assigned" );
382             Contract.Assert( PermissionToken.GetToken( perm ).m_index == index,
383                              "Assigning permission to incorrect index in tokenbasedset" );
384             return perm;
385         }
386 
GetPermission(PermissionToken permToken)387         internal IPermission GetPermission(PermissionToken permToken)
388         {
389             if (permToken == null)
390                 return null;
391 
392             return GetPermission( permToken.m_index );
393         }
394 
GetPermission( IPermission perm )395         internal IPermission GetPermission( IPermission perm )
396         {
397             if (perm == null)
398                 return null;
399 
400             return GetPermission(PermissionToken.GetToken( perm ));
401         }
402 
403 #if FEATURE_CAS_POLICY
GetPermission(Type permClass)404         public IPermission GetPermission(Type permClass)
405         {
406             return GetPermissionImpl(permClass);
407         }
408 
GetPermissionImpl(Type permClass)409         protected virtual IPermission GetPermissionImpl(Type permClass)
410         {
411             if (permClass == null)
412                 return null;
413 
414             return GetPermission(PermissionToken.FindToken(permClass));
415         }
416 #endif // FEATURE_CAS_POLICY
417 
SetPermission(IPermission perm)418         public IPermission SetPermission(IPermission perm)
419         {
420             return SetPermissionImpl(perm);
421         }
422 
423         // SetPermission overwrites a permission in a permissionset.
SetPermissionImpl(IPermission perm)424         protected virtual IPermission SetPermissionImpl(IPermission perm)
425         {
426             // can't get token if perm is null
427             if (perm == null)
428                 return null;
429 
430             PermissionToken permToken = PermissionToken.GetToken(perm);
431 
432             if ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0)
433             {
434                 // SetPermission Makes the Permission "Restricted"
435                 m_Unrestricted = false;
436             }
437 
438             CheckSet();
439 
440             IPermission currPerm = GetPermission( permToken.m_index );
441 
442             m_CheckedForNonCas = false;
443 
444             // Should we copy here?
445             m_permSet.SetItem( permToken.m_index, perm );
446             return perm;
447         }
448 
AddPermission(IPermission perm)449         public IPermission AddPermission(IPermission perm)
450         {
451             return AddPermissionImpl(perm);
452         }
453 
AddPermissionImpl(IPermission perm)454         protected virtual IPermission AddPermissionImpl(IPermission perm)
455         {
456             // can't get token if perm is null
457             if (perm == null)
458                 return null;
459 
460             m_CheckedForNonCas = false;
461 
462             // If the permission set is unrestricted, then return an unrestricted instance
463             // of perm.
464 
465             PermissionToken permToken = PermissionToken.GetToken(perm);
466 
467             if (this.IsUnrestricted() && ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0))
468             {
469                 Type perm_type = perm.GetType();
470                 Object[] objs = new Object[1];
471                 objs[0] = PermissionState.Unrestricted;
472                 return (IPermission) Activator.CreateInstance(perm_type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null );
473             }
474 
475             CheckSet();
476             IPermission currPerm = GetPermission(permToken.m_index);
477 
478             // If a Permission exists in this slot, then union it with perm
479             // Otherwise, just add perm.
480 
481             if (currPerm != null) {
482                 IPermission ip_union = currPerm.Union(perm);
483                 m_permSet.SetItem( permToken.m_index, ip_union );
484                 return ip_union;
485             } else {
486                 // Should we copy here?
487                 m_permSet.SetItem( permToken.m_index, perm );
488                 return perm;
489             }
490 
491         }
492 
RemovePermission( int index )493         private IPermission RemovePermission( int index )
494         {
495             IPermission perm = GetPermission(index);
496             if (perm == null)
497                 return null;
498             return (IPermission)m_permSet.RemoveItem( index ); // this cast is safe because the call to GetPermission will guarantee it is an IPermission
499         }
500 
501 #if FEATURE_CAS_POLICY
RemovePermission(Type permClass)502         public IPermission RemovePermission(Type permClass)
503         {
504             return RemovePermissionImpl(permClass);
505         }
506 
RemovePermissionImpl(Type permClass)507         protected virtual IPermission RemovePermissionImpl(Type permClass)
508         {
509             if (permClass == null)
510             {
511                 return null;
512             }
513 
514             PermissionToken permToken = PermissionToken.FindToken(permClass);
515             if (permToken == null)
516             {
517                 return null;
518             }
519 
520             return RemovePermission(permToken.m_index);
521         }
522 #endif // FEATURE_CAS_POLICY
523 
524         // Make this internal soon.
SetUnrestricted(bool unrestricted)525         internal void SetUnrestricted(bool unrestricted)
526         {
527             m_Unrestricted = unrestricted;
528             if (unrestricted)
529             {
530                 // if this is to be an unrestricted permset, null the m_permSet member
531                 m_permSet = null;
532             }
533         }
534 
IsUnrestricted()535         public bool IsUnrestricted()
536         {
537             return m_Unrestricted;
538         }
539 
540         internal enum IsSubsetOfType
541         {
542             Normal,
543             CheckDemand,
544             CheckPermitOnly,
545             CheckAssertion,
546         }
547 
IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas)548         internal bool IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas)
549         {
550     #if _DEBUG
551             if (debug)
552                 DEBUG_WRITE("IsSubsetOf\n" +
553                             "Other:\n" +
554                             (target == null ? "<null>" : target.ToString()) +
555                             "\nMe:\n" +
556                             ToString());
557     #endif
558 
559             firstPermThatFailed = null;
560             if (target == null || target.FastIsEmpty())
561             {
562                 if(this.IsEmpty())
563                     return true;
564                 else
565                 {
566                     firstPermThatFailed = GetFirstPerm();
567                     return false;
568                 }
569             }
570             else if (this.IsUnrestricted() && !target.IsUnrestricted())
571                 return false;
572             else if (this.m_permSet == null)
573                 return true;
574             else
575             {
576                 target.CheckSet();
577 
578                 for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
579                 {
580                     IPermission thisPerm = this.GetPermission(i);
581                     if (thisPerm == null || thisPerm.IsSubsetOf(null))
582                         continue;
583 
584                     IPermission targetPerm = target.GetPermission(i);
585 #if _DEBUG
586                     PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
587                     Contract.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
588 #endif
589 
590                     if (target.m_Unrestricted)
591                         continue;
592 
593                     // targetPerm can be null here, but that is fine since it thisPerm is a subset
594                     // of empty/null then we can continue in the loop.
595                     CodeAccessPermission cap = thisPerm as CodeAccessPermission;
596                     if(cap == null)
597                     {
598                         if (!ignoreNonCas && !thisPerm.IsSubsetOf( targetPerm ))
599                         {
600                             firstPermThatFailed = thisPerm;
601                             return false;
602                         }
603                     }
604                     else
605                     {
606                         firstPermThatFailed = thisPerm;
607                         switch(type)
608                         {
609                         case IsSubsetOfType.Normal:
610                             if (!thisPerm.IsSubsetOf( targetPerm ))
611                                 return false;
612                             break;
613                         case IsSubsetOfType.CheckDemand:
614                             if (!cap.CheckDemand( (CodeAccessPermission)targetPerm ))
615                                 return false;
616                             break;
617                         case IsSubsetOfType.CheckPermitOnly:
618                             if (!cap.CheckPermitOnly( (CodeAccessPermission)targetPerm ))
619                                 return false;
620                             break;
621                         case IsSubsetOfType.CheckAssertion:
622                             if (!cap.CheckAssert( (CodeAccessPermission)targetPerm ))
623                                 return false;
624                             break;
625                         }
626                         firstPermThatFailed = null;
627                     }
628                 }
629             }
630 
631             return true;
632         }
633 
IsSubsetOf(PermissionSet target)634         public bool IsSubsetOf(PermissionSet target)
635         {
636             IPermission perm;
637             return IsSubsetOfHelper(target, IsSubsetOfType.Normal, out perm, false);
638         }
639 
CheckDemand(PermissionSet target, out IPermission firstPermThatFailed)640         internal bool CheckDemand(PermissionSet target, out IPermission firstPermThatFailed)
641         {
642             return IsSubsetOfHelper(target, IsSubsetOfType.CheckDemand, out firstPermThatFailed, true);
643         }
644 
CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed)645         internal bool CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed)
646         {
647             return IsSubsetOfHelper(target, IsSubsetOfType.CheckPermitOnly, out firstPermThatFailed, true);
648         }
649 
CheckAssertion(PermissionSet target)650         internal bool CheckAssertion(PermissionSet target)
651         {
652             IPermission perm;
653             return IsSubsetOfHelper(target, IsSubsetOfType.CheckAssertion, out perm, true);
654         }
655 
CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed)656         internal bool CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed)
657         {
658             firstPermThatFailed = null;
659             if (deniedSet == null || deniedSet.FastIsEmpty() || this.FastIsEmpty())
660                 return true;
661 
662             if(this.m_Unrestricted && deniedSet.m_Unrestricted)
663                 return false;
664 
665             CodeAccessPermission permThis, permThat;
666             PermissionSetEnumeratorInternal enumThis = new PermissionSetEnumeratorInternal(this);
667 
668             while (enumThis.MoveNext())
669             {
670                 permThis = enumThis.Current as CodeAccessPermission;
671                 if(permThis == null || permThis.IsSubsetOf(null))
672                     continue; // ignore non-CAS permissions in the grant set.
673                 if (deniedSet.m_Unrestricted)
674                 {
675                     firstPermThatFailed = permThis;
676                     return false;
677                 }
678                 permThat = (CodeAccessPermission)deniedSet.GetPermission(enumThis.GetCurrentIndex());
679                 if (!permThis.CheckDeny(permThat))
680                 {
681                     firstPermThatFailed = permThis;
682                     return false;
683                 }
684             }
685             if(this.m_Unrestricted)
686             {
687                 PermissionSetEnumeratorInternal enumThat = new PermissionSetEnumeratorInternal(deniedSet);
688                 while (enumThat.MoveNext())
689                 {
690                     if(enumThat.Current is IPermission)
691                         return false;
692                 }
693             }
694             return true;
695         }
696 
CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm )697         internal void CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm )
698         {
699             Contract.Assert( demandedPerm != null, "Expected non-null value" );
700 
701             if (this.m_allPermissionsDecoded || this.m_permSet == null)
702                 return;
703 
704             if (tokenDemandedPerm == null)
705                 tokenDemandedPerm = PermissionToken.GetToken( demandedPerm );
706 
707             Contract.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" );
708 
709             CheckDecoded( tokenDemandedPerm.m_index );
710         }
711 
CheckDecoded( int index )712         internal void CheckDecoded( int index )
713         {
714             if (this.m_allPermissionsDecoded || this.m_permSet == null)
715                 return;
716 
717             GetPermission(index);
718         }
719 
CheckDecoded(PermissionSet demandedSet)720         internal void CheckDecoded(PermissionSet demandedSet)
721         {
722             Contract.Assert(demandedSet != null, "Expected non-null value");
723 
724             if (this.m_allPermissionsDecoded || this.m_permSet == null)
725                 return;
726 
727             PermissionSetEnumeratorInternal enumerator = demandedSet.GetEnumeratorInternal();
728 
729             while (enumerator.MoveNext())
730             {
731                 CheckDecoded(enumerator.GetCurrentIndex());
732             }
733         }
734 
735 #if FEATURE_CAS_POLICY
SafeChildAdd( SecurityElement parent, ISecurityElementFactory child, bool copy )736         static internal void SafeChildAdd( SecurityElement parent, ISecurityElementFactory child, bool copy )
737         {
738             if (child == parent)
739                 return;
740             if (child.GetTag().Equals( "IPermission" ) || child.GetTag().Equals( "Permission" ))
741             {
742                 parent.AddChild( child );
743             }
744             else if (parent.Tag.Equals( child.GetTag() ))
745             {
746                 Contract.Assert( child is SecurityElement, "SecurityElement expected" );
747                 SecurityElement elChild = (SecurityElement)child;
748                 Contract.Assert( elChild.InternalChildren != null,
749                     "Non-permission elements should have children" );
750 
751                 for (int i = 0; i < elChild.InternalChildren.Count; ++i)
752                 {
753                     ISecurityElementFactory current = (ISecurityElementFactory)elChild.InternalChildren[i];
754                     Contract.Assert( !current.GetTag().Equals( parent.Tag ),
755                         "Illegal to insert a like-typed element" );
756                     parent.AddChildNoDuplicates( current );
757                 }
758             }
759             else
760             {
761                 parent.AddChild( (ISecurityElementFactory)(copy ? child.Copy() : child) );
762             }
763         }
764 #endif // FEATURE_CAS_POLICY
765 
InplaceIntersect( PermissionSet other )766         internal void InplaceIntersect( PermissionSet other )
767         {
768             Exception savedException = null;
769 
770             m_CheckedForNonCas = false;
771 
772             if (this == other)
773                 return;
774 
775             if (other == null || other.FastIsEmpty())
776             {
777                 // If the other is empty or null, make this empty.
778                 Reset();
779                 return;
780             }
781 
782             if (this.FastIsEmpty())
783                 return;
784 
785             int maxMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
786             int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex();
787 
788             if (this.IsUnrestricted() && maxMax < otherMax)
789             {
790                 maxMax = otherMax;
791                 this.CheckSet();
792             }
793 
794             if (other.IsUnrestricted())
795             {
796                 other.CheckSet();
797             }
798 
799             for (int i = 0; i <= maxMax; ++i)
800             {
801                 Object thisObj = this.m_permSet.GetItem( i );
802                 IPermission thisPerm = thisObj as IPermission;
803 #if FEATURE_CAS_POLICY
804                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
805 #endif // FEATURE_CAS_POLICY
806 
807                 Object otherObj = other.m_permSet.GetItem( i );
808                 IPermission otherPerm = otherObj as IPermission;
809 #if FEATURE_CAS_POLICY
810                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
811 #endif // FEATURE_CAS_POLICY
812 
813                 if (thisObj == null && otherObj == null)
814                     continue;
815 
816 #if FEATURE_CAS_POLICY
817                 if (thisElem != null && otherElem != null)
818                 {
819                     // If we already have an intersection node, just add another child
820                     if (thisElem.GetTag().Equals( s_str_PermissionIntersection ) ||
821                         thisElem.GetTag().Equals( s_str_PermissionUnrestrictedIntersection ))
822                     {
823                         Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
824                         SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
825                     }
826                     // If either set is unrestricted, intersect the nodes unrestricted
827                     else
828                     {
829                         bool copyOther = true;
830                         if (this.IsUnrestricted())
831                         {
832                             SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
833                             newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
834                             SafeChildAdd( newElemUU, thisElem, false );
835                             thisElem = newElemUU;
836                         }
837                         if (other.IsUnrestricted())
838                         {
839                             SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
840                             newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) );
841                             SafeChildAdd( newElemUU, otherElem, true );
842                             otherElem = newElemUU;
843                             copyOther = false;
844                         }
845 
846                         SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
847                         newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
848 
849                         SafeChildAdd( newElem, thisElem, false );
850                         SafeChildAdd( newElem, otherElem, copyOther );
851                         this.m_permSet.SetItem( i, newElem );
852                     }
853                 }
854                 else
855 #endif // FEATURE_CAS_POLICY
856                 if (thisObj == null)
857                 {
858                     // There is no object in <this>, so intersection is empty except for IUnrestrictedPermissions
859                     if (this.IsUnrestricted())
860                     {
861 #if FEATURE_CAS_POLICY
862                         if (otherElem != null)
863                         {
864                             SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
865                             newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
866                             SafeChildAdd( newElem, otherElem, true );
867                             this.m_permSet.SetItem( i, newElem );
868                             Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
869                         }
870                         else
871 #endif // FEATURE_CAS_POLICY
872                         {
873                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
874                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
875                             {
876                                 this.m_permSet.SetItem( i, otherPerm.Copy() );
877                                 Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
878                             }
879                         }
880                     }
881                 }
882                 else if (otherObj == null)
883                 {
884                     if (other.IsUnrestricted())
885                     {
886 #if FEATURE_CAS_POLICY
887                         if (thisElem != null)
888                         {
889                             SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
890                             newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
891                             SafeChildAdd( newElem, thisElem, false );
892                             this.m_permSet.SetItem( i, newElem );
893                         }
894                         else
895 #endif // FEATURE_CAS_POLICY
896                         {
897                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
898                             if ((token.m_type & PermissionTokenType.IUnrestricted) == 0)
899                                 this.m_permSet.SetItem( i, null );
900                         }
901                     }
902                     else
903                     {
904                         this.m_permSet.SetItem( i, null );
905                     }
906                 }
907                 else
908                 {
909 #if FEATURE_CAS_POLICY
910                     if (thisElem != null)
911                         thisPerm = this.CreatePermission(thisElem, i);
912                     if (otherElem != null)
913                         otherPerm = other.CreatePermission(otherElem, i);
914 #endif // FEATURE_CAS_POLICY
915 
916                     try
917                     {
918                         IPermission intersectPerm;
919                         if (thisPerm == null)
920                             intersectPerm = otherPerm;
921                         else if(otherPerm == null)
922                             intersectPerm = thisPerm;
923                         else
924                             intersectPerm = thisPerm.Intersect( otherPerm );
925                         this.m_permSet.SetItem( i, intersectPerm );
926                     }
927                     catch (Exception e)
928                     {
929                         if (savedException == null)
930                             savedException = e;
931                     }
932                 }
933             }
934 
935             this.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted;
936 
937             if (savedException != null)
938                 throw savedException;
939         }
940 
Intersect(PermissionSet other)941         public PermissionSet Intersect(PermissionSet other)
942         {
943             if (other == null || other.FastIsEmpty() || this.FastIsEmpty())
944             {
945                 return null;
946             }
947 
948             int thisMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
949             int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex();
950             int minMax = thisMax < otherMax ? thisMax : otherMax;
951 
952             if (this.IsUnrestricted() && minMax < otherMax)
953             {
954                 minMax = otherMax;
955                 this.CheckSet();
956             }
957 
958             if (other.IsUnrestricted() && minMax < thisMax)
959             {
960                 minMax = thisMax;
961                 other.CheckSet();
962             }
963 
964             PermissionSet pset = new PermissionSet( false );
965 
966             if (minMax > -1)
967             {
968                 pset.m_permSet = new TokenBasedSet();
969             }
970 
971             for (int i = 0; i <= minMax; ++i)
972             {
973                 Object thisObj = this.m_permSet.GetItem( i );
974                 IPermission thisPerm = thisObj as IPermission;
975 #if FEATURE_CAS_POLICY
976                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
977 #endif // FEATURE_CAS_POLICY
978 
979                 Object otherObj = other.m_permSet.GetItem( i );
980                 IPermission otherPerm = otherObj as IPermission;
981 #if FEATURE_CAS_POLICY
982                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
983 #endif // FEATURE_CAS_POLICY
984 
985                 if (thisObj == null && otherObj == null)
986                     continue;
987 
988 #if FEATURE_CAS_POLICY
989                 if (thisElem != null && otherElem != null)
990                 {
991                     bool copyOther = true;
992                     bool copyThis = true;
993                     SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
994                     newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
995                     if (this.IsUnrestricted())
996                     {
997                         SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
998                         newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
999                         SafeChildAdd( newElemUU, thisElem, true );
1000                         copyThis = false;
1001                         thisElem = newElemUU;
1002                     }
1003                     if (other.IsUnrestricted())
1004                     {
1005                         SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
1006                         newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) );
1007                         SafeChildAdd( newElemUU, otherElem, true );
1008                         copyOther = false;
1009                         otherElem = newElemUU;
1010                     }
1011 
1012                     SafeChildAdd( newElem, otherElem, copyOther );
1013                     SafeChildAdd( newElem, thisElem, copyThis );
1014                     pset.m_permSet.SetItem( i, newElem );
1015                 }
1016                 else
1017 #endif // FEATURE_CAS_POLICY
1018                 if (thisObj == null)
1019                 {
1020                     if (this.m_Unrestricted)
1021                     {
1022 #if FEATURE_CAS_POLICY
1023                         if (otherElem != null)
1024                         {
1025                             SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
1026                             newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
1027                             SafeChildAdd( newElem, otherElem, true );
1028                             pset.m_permSet.SetItem( i, newElem );
1029                             Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1030                         }
1031                         else
1032 #endif // FEATURE_CAS_POLICY
1033                         if (otherPerm != null)
1034                         {
1035                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
1036                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
1037                             {
1038                                 pset.m_permSet.SetItem( i, otherPerm.Copy() );
1039                                 Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1040                             }
1041                         }
1042                     }
1043                 }
1044                 else if (otherObj == null)
1045                 {
1046                     if (other.m_Unrestricted)
1047                     {
1048 #if FEATURE_CAS_POLICY
1049                         if (thisElem != null)
1050                         {
1051                             SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
1052                             newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
1053                             SafeChildAdd( newElem, thisElem, true );
1054                             pset.m_permSet.SetItem( i, newElem );
1055                             Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1056                         }
1057                         else
1058 #endif // FEATURE_CAS_POLICY
1059                         if (thisPerm != null)
1060                         {
1061                             PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
1062                             if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
1063                             {
1064                                 pset.m_permSet.SetItem( i, thisPerm.Copy() );
1065                                 Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1066                             }
1067                         }
1068                     }
1069                 }
1070                 else
1071                 {
1072 #if FEATURE_CAS_POLICY
1073                     if (thisElem != null)
1074                         thisPerm = this.CreatePermission(thisElem, i);
1075                     if (otherElem != null)
1076                         otherPerm = other.CreatePermission(otherElem, i);
1077 #endif // FEATURE_CAS_POLICY
1078 
1079                     IPermission intersectPerm;
1080                     if (thisPerm == null)
1081                         intersectPerm = otherPerm;
1082                     else if(otherPerm == null)
1083                         intersectPerm = thisPerm;
1084                     else
1085                         intersectPerm = thisPerm.Intersect( otherPerm );
1086                     pset.m_permSet.SetItem( i, intersectPerm );
1087                     Contract.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1088                 }
1089             }
1090 
1091             pset.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted;
1092             if (pset.FastIsEmpty())
1093                 return null;
1094             else
1095                 return pset;
1096         }
1097 
InplaceUnion( PermissionSet other )1098         internal void InplaceUnion( PermissionSet other )
1099         {
1100             // Unions the "other" PermissionSet into this one.  It can be optimized to do less copies than
1101             // need be done by the traditional union (and we don't have to create a new PermissionSet).
1102 
1103             if (this == other)
1104                 return;
1105 
1106             // Quick out conditions, union doesn't change this PermissionSet
1107             if (other == null || other.FastIsEmpty())
1108                 return;
1109 
1110 
1111             m_CheckedForNonCas = false;
1112 
1113 
1114 
1115 
1116             this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
1117 
1118             if (this.m_Unrestricted)
1119             {
1120                 // if the result of Union is unrestricted permset, null the m_permSet member
1121                 this.m_permSet = null;
1122                 return;
1123             }
1124 
1125 
1126             // If we reach here, result of Union is not unrestricted
1127             // We have to union "normal" permission no matter what now.
1128             int maxMax = -1;
1129             if (other.m_permSet != null)
1130             {
1131                 maxMax = other.m_permSet.GetMaxUsedIndex();
1132                 this.CheckSet();
1133             }
1134             // Save exceptions until the end
1135             Exception savedException = null;
1136 
1137             for (int i = 0; i <= maxMax; ++i)
1138             {
1139                 Object thisObj = this.m_permSet.GetItem( i );
1140                 IPermission thisPerm = thisObj as IPermission;
1141 #if FEATURE_CAS_POLICY
1142                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
1143 #endif // FEATURE_CAS_POLICY
1144 
1145                 Object otherObj = other.m_permSet.GetItem( i );
1146                 IPermission otherPerm = otherObj as IPermission;
1147 #if FEATURE_CAS_POLICY
1148                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
1149 #endif // FEATURE_CAS_POLICY
1150 
1151                 if (thisObj == null && otherObj == null)
1152                     continue;
1153 
1154 #if FEATURE_CAS_POLICY
1155                 if (thisElem != null && otherElem != null)
1156                 {
1157                     if (thisElem.GetTag().Equals( s_str_PermissionUnion ) ||
1158                         thisElem.GetTag().Equals( s_str_PermissionUnrestrictedUnion ))
1159                     {
1160                         Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
1161                         SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
1162                     }
1163                     else
1164                     {
1165                         SecurityElement newElem;
1166                         if (this.IsUnrestricted() || other.IsUnrestricted())
1167                             newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
1168                         else
1169                             newElem = new SecurityElement( s_str_PermissionUnion );
1170                         newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
1171                         SafeChildAdd( newElem, thisElem, false );
1172                         SafeChildAdd( newElem, otherElem, true );
1173                         this.m_permSet.SetItem( i, newElem );
1174                     }
1175                 }
1176                 else
1177 #endif // FEATURE_CAS_POLICY
1178                 if (thisObj == null)
1179                 {
1180 #if FEATURE_CAS_POLICY
1181                     if (otherElem != null)
1182                     {
1183                         this.m_permSet.SetItem( i, otherElem.Copy() );
1184                     }
1185                     else
1186 #endif // FEATURE_CAS_POLICY
1187                     if (otherPerm != null)
1188                     {
1189                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
1190                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !this.m_Unrestricted)
1191                         {
1192                             this.m_permSet.SetItem( i, otherPerm.Copy() );
1193                         }
1194                     }
1195                 }
1196                 else if (otherObj == null)
1197                 {
1198                     continue;
1199                 }
1200                 else
1201                 {
1202 #if FEATURE_CAS_POLICY
1203                     if (thisElem != null)
1204                         thisPerm = this.CreatePermission(thisElem, i);
1205                     if (otherElem != null)
1206                         otherPerm = other.CreatePermission(otherElem, i);
1207 #endif // FEATURE_CAS_POLICY
1208 
1209                     try
1210                     {
1211                         IPermission unionPerm;
1212                         if(thisPerm == null)
1213                             unionPerm = otherPerm;
1214                         else if(otherPerm == null)
1215                             unionPerm = thisPerm;
1216                         else
1217                             unionPerm = thisPerm.Union( otherPerm );
1218                         this.m_permSet.SetItem( i, unionPerm );
1219                     }
1220                     catch (Exception e)
1221                     {
1222                         if (savedException == null)
1223                             savedException = e;
1224                     }
1225                 }
1226             }
1227 
1228             if (savedException != null)
1229                 throw savedException;
1230         }
1231 
Union(PermissionSet other)1232         public PermissionSet Union(PermissionSet other)
1233         {
1234             // if other is null or empty, return a clone of myself
1235             if (other == null || other.FastIsEmpty())
1236             {
1237                 return this.Copy();
1238             }
1239 
1240             if (this.FastIsEmpty())
1241             {
1242                 return other.Copy();
1243             }
1244 
1245             int maxMax = -1;
1246 
1247             PermissionSet pset = new PermissionSet();
1248             pset.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
1249             if (pset.m_Unrestricted)
1250             {
1251                 // if the result of Union is unrestricted permset, just return
1252                 return pset;
1253             }
1254 
1255             // degenerate case where we look at both this.m_permSet and other.m_permSet
1256             this.CheckSet();
1257             other.CheckSet();
1258             maxMax = this.m_permSet.GetMaxUsedIndex() > other.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : other.m_permSet.GetMaxUsedIndex();
1259             pset.m_permSet = new TokenBasedSet();
1260 
1261 
1262 
1263             for (int i = 0; i <= maxMax; ++i)
1264             {
1265                 Object thisObj = this.m_permSet.GetItem( i );
1266                 IPermission thisPerm = thisObj as IPermission;
1267 #if FEATURE_CAS_POLICY
1268                 ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
1269 #endif // FEATURE_CAS_POLICY
1270 
1271                 Object otherObj = other.m_permSet.GetItem( i );
1272                 IPermission otherPerm = otherObj as IPermission;
1273 #if FEATURE_CAS_POLICY
1274                 ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
1275 #endif // FEATURE_CAS_POLICY
1276 
1277                 if (thisObj == null && otherObj == null)
1278                     continue;
1279 
1280 #if FEATURE_CAS_POLICY
1281                 if (thisElem != null && otherElem != null)
1282                 {
1283                     SecurityElement newElem;
1284                     if (this.IsUnrestricted() || other.IsUnrestricted())
1285                         newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
1286                     else
1287                         newElem = new SecurityElement( s_str_PermissionUnion );
1288                     newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
1289                     SafeChildAdd( newElem, thisElem, true );
1290                     SafeChildAdd( newElem, otherElem, true );
1291                     pset.m_permSet.SetItem( i, newElem );
1292                 }
1293                 else
1294 #endif // FEATURE_CAS_POLICY
1295                 if (thisObj == null)
1296                 {
1297 #if FEATURE_CAS_POLICY
1298                     if (otherElem != null)
1299                     {
1300                         pset.m_permSet.SetItem( i, otherElem.Copy() );
1301                         Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1302                     }
1303                     else
1304 #endif // FEATURE_CAS_POLICY
1305                     if (otherPerm != null)
1306                     {
1307                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
1308                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
1309                         {
1310                             pset.m_permSet.SetItem( i, otherPerm.Copy() );
1311                             Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1312                         }
1313                     }
1314                 }
1315                 else if (otherObj == null)
1316                 {
1317 #if FEATURE_CAS_POLICY
1318                     if (thisElem != null)
1319                     {
1320                         pset.m_permSet.SetItem( i, thisElem.Copy() );
1321                     }
1322                     else
1323 #endif // FEATURE_CAS_POLICY
1324                     if (thisPerm != null)
1325                     {
1326                         PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
1327                         if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
1328                         {
1329                             pset.m_permSet.SetItem( i, thisPerm.Copy() );
1330                             Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1331                         }
1332                     }
1333                 }
1334                 else
1335                 {
1336 #if FEATURE_CAS_POLICY
1337                     if (thisElem != null)
1338                         thisPerm = this.CreatePermission(thisElem, i);
1339                     if (otherElem != null)
1340                         otherPerm = other.CreatePermission(otherElem, i);
1341 #endif // FEATURE_CAS_POLICY
1342 
1343                     IPermission unionPerm;
1344                     if(thisPerm == null)
1345                         unionPerm = otherPerm;
1346                     else if(otherPerm == null)
1347                         unionPerm = thisPerm;
1348                     else
1349                         unionPerm = thisPerm.Union( otherPerm );
1350                     pset.m_permSet.SetItem( i, unionPerm );
1351                     Contract.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
1352                 }
1353             }
1354 
1355             return pset;
1356         }
1357 
1358         // Treating the current permission set as a grant set, and the input set as
1359         // a set of permissions to be denied, try to cancel out as many permissions
1360         // from both sets as possible. For a first cut, any granted permission that
1361         // is a safe subset of the corresponding denied permission can result in
1362         // that permission being removed from both sides.
1363 
MergeDeniedSet(PermissionSet denied)1364         internal void MergeDeniedSet(PermissionSet denied)
1365         {
1366             if (denied == null || denied.FastIsEmpty() || this.FastIsEmpty())
1367                 return;
1368 
1369             m_CheckedForNonCas = false;
1370 
1371             // Check for the unrestricted case: FastIsEmpty() will return false if the PSet is unrestricted, but has no items
1372             if (this.m_permSet == null || denied.m_permSet == null)
1373                 return; //nothing can be removed
1374 
1375             int maxIndex = denied.m_permSet.GetMaxUsedIndex() > this.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : denied.m_permSet.GetMaxUsedIndex();
1376             for (int i = 0; i <= maxIndex; ++i) {
1377                 IPermission deniedPerm = denied.m_permSet.GetItem(i) as IPermission;
1378                 if (deniedPerm == null)
1379                     continue;
1380 
1381                 IPermission thisPerm = this.m_permSet.GetItem(i) as IPermission;
1382 
1383                 if (thisPerm == null && !this.m_Unrestricted) {
1384                     denied.m_permSet.SetItem(i, null);
1385                     continue;
1386                 }
1387 
1388                 if (thisPerm != null && deniedPerm != null) {
1389                     if (thisPerm.IsSubsetOf(deniedPerm)) {
1390                         this.m_permSet.SetItem(i, null);
1391                         denied.m_permSet.SetItem(i, null);
1392                     }
1393                 }
1394             }
1395         }
1396 
1397         // Returns true if perm is contained in this
Contains(IPermission perm)1398         internal bool Contains(IPermission perm)
1399         {
1400             if (perm == null)
1401                 return true;
1402             if (m_Unrestricted)
1403                 return true;
1404             if (FastIsEmpty())
1405                 return false;
1406 
1407             PermissionToken token = PermissionToken.GetToken(perm);
1408             Object thisObj = this.m_permSet.GetItem( token.m_index );
1409             if (thisObj == null)
1410                 return perm.IsSubsetOf( null );
1411 
1412             IPermission thisPerm = GetPermission(token.m_index);
1413             if (thisPerm != null)
1414                 return perm.IsSubsetOf( thisPerm );
1415             else
1416                 return perm.IsSubsetOf( null );
1417         }
1418 
1419         [System.Runtime.InteropServices.ComVisible(false)]
Equals( Object obj )1420         public override bool Equals( Object obj )
1421         {
1422             // Note: this method is designed to accept both PermissionSet and NamedPermissionSets.
1423             // It will compare them based on the values in the base type, thereby ignoring the
1424             // name and description of the named permission set.
1425 
1426             PermissionSet other = obj as PermissionSet;
1427 
1428             if (other == null)
1429                 return false;
1430 
1431             if (this.m_Unrestricted != other.m_Unrestricted)
1432                 return false;
1433 
1434             CheckSet();
1435             other.CheckSet();
1436 
1437             DecodeAllPermissions();
1438             other.DecodeAllPermissions();
1439 
1440             int maxIndex = Math.Max( this.m_permSet.GetMaxUsedIndex(), other.m_permSet.GetMaxUsedIndex() );
1441 
1442             for (int i = 0; i <= maxIndex; ++i)
1443             {
1444                 IPermission thisPerm = (IPermission)this.m_permSet.GetItem( i );
1445                 IPermission otherPerm = (IPermission)other.m_permSet.GetItem( i );
1446 
1447                 if (thisPerm == null && otherPerm == null)
1448                 {
1449                     continue;
1450                 }
1451                 else if (thisPerm == null)
1452                 {
1453                     if (!otherPerm.IsSubsetOf( null ))
1454                         return false;
1455                 }
1456                 else if (otherPerm == null)
1457                 {
1458                     if (!thisPerm.IsSubsetOf( null ))
1459                         return false;
1460                 }
1461                 else
1462                 {
1463                     if (!thisPerm.Equals( otherPerm ))
1464                         return false;
1465                 }
1466             }
1467 
1468             return true;
1469         }
1470 
1471         [System.Runtime.InteropServices.ComVisible(false)]
GetHashCode()1472         public override int GetHashCode()
1473         {
1474             int accumulator;
1475 
1476             accumulator = this.m_Unrestricted ? -1 : 0;
1477 
1478             if (this.m_permSet != null)
1479             {
1480                 DecodeAllPermissions();
1481 
1482                 int maxIndex = this.m_permSet.GetMaxUsedIndex();
1483 
1484                 for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i)
1485                 {
1486                     IPermission perm = (IPermission)this.m_permSet.GetItem( i );
1487                     if (perm != null)
1488                     {
1489                         accumulator = accumulator ^ perm.GetHashCode();
1490                     }
1491                 }
1492             }
1493 
1494             return accumulator;
1495         }
1496 
1497         // Mark this method as requiring a security object on the caller's frame
1498         // so the caller won't be inlined (which would mess up stack crawling).
1499         [System.Security.SecuritySafeCritical]  // auto-generated
1500         [DynamicSecurityMethodAttribute()]
1501         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
Demand()1502         public void Demand()
1503         {
1504             if (this.FastIsEmpty())
1505                 return;  // demanding the empty set always passes.
1506 
1507             ContainsNonCodeAccessPermissions();
1508 
1509             if (m_ContainsCas)
1510             {
1511                 StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
1512                 CodeAccessSecurityEngine.Check(GetCasOnlySet(), ref stackMark);
1513             }
1514             if (m_ContainsNonCas)
1515             {
1516                 DemandNonCAS();
1517             }
1518         }
1519 
1520         [System.Security.SecurityCritical]  // auto-generated
DemandNonCAS()1521         internal void DemandNonCAS()
1522         {
1523             ContainsNonCodeAccessPermissions();
1524 
1525             if (m_ContainsNonCas)
1526             {
1527                 if (this.m_permSet != null)
1528                 {
1529                     CheckSet();
1530                     for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
1531                     {
1532                         IPermission currPerm = GetPermission(i);
1533                         if (currPerm != null && !(currPerm is CodeAccessPermission))
1534                             currPerm.Demand();
1535                     }
1536                 }
1537             }
1538         }
1539 
1540         // Metadata for this method should be flaged with REQ_SQ so that
1541         // EE can allocate space on the stack frame for FrameSecurityDescriptor
1542 
1543         [System.Security.SecuritySafeCritical]  // auto-generated
1544         [DynamicSecurityMethodAttribute()]
1545         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
Assert()1546         public void Assert()
1547         {
1548             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1549             SecurityRuntime.Assert(this, ref stackMark);
1550         }
1551 
1552         // Metadata for this method should be flaged with REQ_SQ so that
1553         // EE can allocate space on the stack frame for FrameSecurityDescriptor
1554 
1555         [System.Security.SecuritySafeCritical]  // auto-generated
1556         [DynamicSecurityMethodAttribute()]
1557         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
1558         [Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
Deny()1559         public void Deny()
1560         {
1561             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1562             SecurityRuntime.Deny(this, ref stackMark);
1563         }
1564 
1565         // Metadata for this method should be flaged with REQ_SQ so that
1566         // EE can allocate space on the stack frame for FrameSecurityDescriptor
1567 
1568         [System.Security.SecuritySafeCritical]  // auto-generated
1569         [DynamicSecurityMethodAttribute()]
1570         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
PermitOnly()1571         public void PermitOnly()
1572         {
1573             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1574             SecurityRuntime.PermitOnly(this, ref stackMark);
1575         }
1576 
GetFirstPerm()1577         internal IPermission GetFirstPerm()
1578         {
1579             IEnumerator enumerator = GetEnumerator();
1580             if(!enumerator.MoveNext())
1581                 return null;
1582             return enumerator.Current as IPermission;
1583         }
1584 
1585         // Returns a deep copy
Copy()1586         public virtual PermissionSet Copy()
1587         {
1588             return new PermissionSet(this);
1589         }
1590 
CopyWithNoIdentityPermissions()1591         internal PermissionSet CopyWithNoIdentityPermissions()
1592         {
1593             // Explicitly make a new PermissionSet, rather than copying, since we may have a
1594             // ReadOnlyPermissionSet which cannot have identity permissions removed from it in a true copy.
1595             PermissionSet copy = new PermissionSet(this);
1596 
1597             // There's no easy way to distinguish an identity permission from any other CodeAccessPermission,
1598             // so remove them directly.
1599 #if FEATURE_CAS_POLICY
1600             copy.RemovePermission(typeof(GacIdentityPermission));
1601 #if FEATURE_X509
1602             copy.RemovePermission(typeof(PublisherIdentityPermission));
1603 #endif
1604             copy.RemovePermission(typeof(StrongNameIdentityPermission));
1605             copy.RemovePermission(typeof(UrlIdentityPermission));
1606             copy.RemovePermission(typeof(ZoneIdentityPermission));
1607 #endif // FEATURE_CAS_POLICY
1608 
1609             return copy;
1610         }
1611 
GetEnumerator()1612         public IEnumerator GetEnumerator()
1613         {
1614             return GetEnumeratorImpl();
1615         }
1616 
GetEnumeratorImpl()1617         protected virtual IEnumerator GetEnumeratorImpl()
1618         {
1619             return new PermissionSetEnumerator(this);
1620         }
1621 
GetEnumeratorInternal()1622         internal PermissionSetEnumeratorInternal GetEnumeratorInternal()
1623         {
1624             return new PermissionSetEnumeratorInternal(this);
1625         }
1626 
1627 #if FEATURE_CAS_POLICY
ToString()1628         public override String ToString()
1629         {
1630             return ToXml().ToString();
1631         }
1632 #endif // FEATURE_CAS_POLICY
1633 
NormalizePermissionSet()1634         private void NormalizePermissionSet()
1635         {
1636             // This function guarantees that all the permissions are placed at
1637             // the proper index within the token based sets.  This becomes necessary
1638             // since these indices are dynamically allocated based on usage order.
1639 
1640             PermissionSet permSetTemp = new PermissionSet(false);
1641 
1642             permSetTemp.m_Unrestricted = this.m_Unrestricted;
1643 
1644             // Move all the normal permissions to the new permission set
1645 
1646             if (this.m_permSet != null)
1647             {
1648                 for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
1649                 {
1650                     Object obj = this.m_permSet.GetItem(i);
1651                     IPermission perm = obj as IPermission;
1652 #if FEATURE_CAS_POLICY
1653                     ISecurityElementFactory elem = obj as ISecurityElementFactory;
1654 
1655                     if (elem != null)
1656                         perm = CreatePerm( elem );
1657 #endif // FEATURE_CAS_POLICY
1658                     if (perm != null)
1659                         permSetTemp.SetPermission( perm );
1660                 }
1661             }
1662 
1663             this.m_permSet = permSetTemp.m_permSet;
1664         }
1665 
1666 #if FEATURE_CAS_POLICY
DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources )1667         private bool DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources )
1668         {
1669             if (data != null && data.Length > 0)
1670             {
1671                 FromXml( new Parser( data, Tokenizer.ByteTokenEncoding.UnicodeTokens ).GetTopElement() );
1672             }
1673 
1674             FilterHostProtectionPermissions(fullTrustOnlyResources, inaccessibleResources);
1675 
1676             // We call this method from unmanaged to code a set we are going to use declaratively.  In
1677             // this case, all the lazy evaluation for partial policy resolution is wasted since we'll
1678             // need to decode all of these shortly to make the demand for whatever.  Therefore, we
1679             // pay that price now so that we can calculate whether all the permissions in the set
1680             // implement the IUnrestrictedPermission interface (the common case) for use in some
1681             // unmanaged optimizations.
1682 
1683             DecodeAllPermissions();
1684 
1685             return true;
1686         }
1687 #endif // FEATURE_CAS_POLICY
1688 
DecodeAllPermissions()1689         private void DecodeAllPermissions()
1690         {
1691             if (m_permSet == null)
1692             {
1693                 m_allPermissionsDecoded = true;
1694                 return;
1695             }
1696 
1697             int maxIndex = m_permSet.GetMaxUsedIndex();
1698             for (int i = 0; i <= maxIndex; ++i)
1699             {
1700                 // GetPermission has the side-effect of decoding the permission in the slot
1701                 GetPermission(i);
1702             }
1703 
1704             m_allPermissionsDecoded = true;
1705         }
1706 
FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible)1707         internal void FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible)
1708         {
1709             HostProtectionPermission.protectedResources = fullTrustOnly;
1710             HostProtectionPermission hpp = (HostProtectionPermission)GetPermission(HostProtectionPermission.GetTokenIndex());
1711             if(hpp == null)
1712                 return;
1713 
1714             HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly));
1715             if (newHpp == null)
1716             {
1717 #if FEATURE_CAS_POLICY
1718                 RemovePermission(typeof(HostProtectionPermission));
1719 #else // !FEATURE_CAS_POLICY
1720                 RemovePermission(HostProtectionPermission.GetTokenIndex());
1721 #endif // FEATURE_CAS_POLICY
1722             }
1723             else if (newHpp.Resources != hpp.Resources)
1724             {
1725                 SetPermission(newHpp);
1726             }
1727         }
1728 
1729 #if FEATURE_CAS_POLICY
FromXml( SecurityElement et )1730         public virtual void FromXml( SecurityElement et )
1731         {
1732             FromXml( et, false, false );
1733         }
1734 
IsPermissionTag( String tag, bool allowInternalOnly )1735         internal static bool IsPermissionTag( String tag, bool allowInternalOnly )
1736         {
1737             if (tag.Equals( s_str_Permission ) ||
1738                 tag.Equals( s_str_IPermission ))
1739             {
1740                 return true;
1741             }
1742 
1743             if (allowInternalOnly &&
1744                 (tag.Equals( s_str_PermissionUnion ) ||
1745                  tag.Equals( s_str_PermissionIntersection ) ||
1746                  tag.Equals( s_str_PermissionUnrestrictedIntersection ) ||
1747                  tag.Equals( s_str_PermissionUnrestrictedUnion)))
1748             {
1749                 return true;
1750             }
1751 
1752             return false;
1753         }
1754 
FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures )1755         internal virtual void FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures )
1756         {
1757             if (et == null)
1758                 throw new ArgumentNullException("et");
1759 
1760             if (!et.Tag.Equals(s_str_PermissionSet))
1761                 throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) );
1762             Contract.EndContractBlock();
1763 
1764             Reset();
1765             m_ignoreTypeLoadFailures = ignoreTypeLoadFailures;
1766             m_allPermissionsDecoded = false;
1767             m_Unrestricted = XMLUtil.IsUnrestricted( et );
1768 
1769             if (et.InternalChildren != null)
1770             {
1771                 int childCount = et.InternalChildren.Count;
1772                 for (int i = 0; i < childCount; ++i)
1773                 {
1774                     SecurityElement elem = (SecurityElement)et.Children[i];
1775 
1776                     if (IsPermissionTag( elem.Tag, allowInternalOnly ))
1777                     {
1778                         String className = elem.Attribute( "class" );
1779 
1780                         PermissionToken token;
1781                         Object objectToInsert;
1782 
1783                         if (className != null)
1784                         {
1785                             token = PermissionToken.GetToken( className );
1786                             if (token == null)
1787                             {
1788                                 objectToInsert = CreatePerm( elem );
1789 #if _DEBUG
1790                                 PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert );
1791                                 Contract.Assert( tokenDebug != null && (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
1792 #endif
1793                                 if (objectToInsert != null)
1794                                 {
1795                                     Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
1796                                         "PermissionToken.GetToken returned null for non-mscorlib permission" );
1797                                     token = PermissionToken.GetToken( (IPermission)objectToInsert );
1798                                     Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
1799                                 }
1800                             }
1801                             else
1802                             {
1803                                 objectToInsert = elem;
1804                             }
1805                         }
1806                         else
1807                         {
1808                             IPermission ip = CreatePerm( elem );
1809                             if (ip == null)
1810                             {
1811                                 token = null;
1812                                 objectToInsert = null;
1813                             }
1814                             else
1815                             {
1816                                 token = PermissionToken.GetToken( ip );
1817                                 Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ),
1818                                                  "PermissionToken was improperly assigned" );
1819                                 objectToInsert = ip;
1820                             }
1821                         }
1822 
1823                         if (token != null && objectToInsert != null)
1824                         {
1825                             if (m_permSet == null)
1826                                 m_permSet = new TokenBasedSet();
1827 
1828                             if (this.m_permSet.GetItem( token.m_index ) != null)
1829                             {
1830                                 // If there is already something in that slot, let's union them
1831                                 // together.
1832 
1833                                 IPermission permInSlot;
1834 
1835                                 if (this.m_permSet.GetItem( token.m_index ) is IPermission)
1836                                     permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index );
1837                                 else
1838                                     permInSlot = CreatePerm( (SecurityElement)this.m_permSet.GetItem( token.m_index ) );
1839 
1840                                 if (objectToInsert is IPermission)
1841                                     objectToInsert = ((IPermission)objectToInsert).Union( permInSlot );
1842                                 else
1843                                     objectToInsert = CreatePerm( (SecurityElement)objectToInsert ).Union( permInSlot );
1844                             }
1845 
1846                             if(m_Unrestricted && objectToInsert is IPermission)
1847                                 objectToInsert = null;
1848 
1849                             this.m_permSet.SetItem( token.m_index, objectToInsert );
1850                         }
1851                     }
1852                 }
1853             }
1854         }
1855 
FromXml( SecurityDocument doc, int position, bool allowInternalOnly )1856         internal virtual void FromXml( SecurityDocument doc, int position, bool allowInternalOnly )
1857         {
1858             if (doc == null)
1859                 throw new ArgumentNullException("doc");
1860             Contract.EndContractBlock();
1861 
1862             if (!doc.GetTagForElement( position ).Equals(s_str_PermissionSet))
1863                 throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) );
1864 
1865             Reset();
1866             m_allPermissionsDecoded = false;
1867             Exception savedException = null;
1868             String strUnrestricted = doc.GetAttributeForElement( position, "Unrestricted" );
1869             if (strUnrestricted != null)
1870                 m_Unrestricted = strUnrestricted.Equals( "True" ) || strUnrestricted.Equals( "true" ) || strUnrestricted.Equals( "TRUE" );
1871             else
1872                 m_Unrestricted = false;
1873 
1874             ArrayList childrenIndices = doc.GetChildrenPositionForElement( position );
1875             int childCount = childrenIndices.Count;
1876             for (int i = 0; i < childCount; ++i)
1877             {
1878                 int childIndex = (int)childrenIndices[i];
1879                 if (IsPermissionTag( doc.GetTagForElement( childIndex ), allowInternalOnly ))
1880                 {
1881                     try
1882                     {
1883                         String className = doc.GetAttributeForElement( childIndex, "class" );
1884 
1885                         PermissionToken token;
1886                         Object objectToInsert;
1887 
1888                         if (className != null)
1889                         {
1890                             token = PermissionToken.GetToken( className );
1891                             if (token == null)
1892                             {
1893                                 objectToInsert = CreatePerm( doc.GetElement( childIndex, true ) );
1894 
1895                                 if (objectToInsert != null)
1896                                 {
1897 #if _DEBUG
1898                                     PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert );
1899                                     Contract.Assert((tokenDebug != null), "PermissionToken.GetToken returned null ");
1900                                     Contract.Assert( (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
1901 #endif
1902                                     Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
1903                                         "PermissionToken.GetToken returned null for non-mscorlib permission" );
1904                                     token = PermissionToken.GetToken( (IPermission)objectToInsert );
1905                                     Contract.Assert((token != null), "PermissionToken.GetToken returned null ");
1906                                     Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
1907                                 }
1908                             }
1909                             else
1910                             {
1911                                 objectToInsert = ((ISecurityElementFactory)new SecurityDocumentElement(doc, childIndex)).CreateSecurityElement();
1912                             }
1913                         }
1914                         else
1915                         {
1916                             IPermission ip = CreatePerm( doc.GetElement( childIndex, true ) );
1917                             if (ip == null)
1918                             {
1919                                 token = null;
1920                                 objectToInsert = null;
1921                             }
1922                             else
1923                             {
1924                                 token = PermissionToken.GetToken( ip );
1925                                 Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ),
1926                                                  "PermissionToken was improperly assigned" );
1927                                 objectToInsert = ip;
1928                             }
1929                         }
1930 
1931                         if (token != null && objectToInsert != null)
1932                         {
1933                             if (m_permSet == null)
1934                                 m_permSet = new TokenBasedSet();
1935 
1936                             IPermission permInSlot = null;
1937                             if (this.m_permSet.GetItem( token.m_index ) != null)
1938                             {
1939                                 // If there is already something in that slot, let's union them
1940                                 // together.
1941 
1942                                 if (this.m_permSet.GetItem( token.m_index ) is IPermission)
1943                                     permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index );
1944                                 else
1945                                     permInSlot = CreatePerm( this.m_permSet.GetItem( token.m_index ) );
1946                             }
1947 
1948                             if (permInSlot != null)
1949                             {
1950                                 if (objectToInsert is IPermission)
1951                                     objectToInsert = permInSlot.Union((IPermission)objectToInsert);
1952                                 else
1953                                     objectToInsert = permInSlot.Union(CreatePerm( objectToInsert ));
1954                             }
1955 
1956                             if(m_Unrestricted && objectToInsert is IPermission)
1957                                 objectToInsert = null;
1958 
1959                             this.m_permSet.SetItem( token.m_index, objectToInsert );
1960                         }
1961                     }
1962                     catch (Exception e)
1963                     {
1964 #if _DEBUG
1965                         if (debug)
1966                             DEBUG_WRITE( "error while decoding permission set =\n" + e.ToString() );
1967 #endif
1968                         if (savedException == null)
1969                             savedException = e;
1970 
1971                     }
1972                 }
1973             }
1974 
1975             if (savedException != null)
1976                 throw savedException;
1977 
1978         }
1979 
CreatePerm(Object obj)1980         private  IPermission CreatePerm(Object obj)
1981         {
1982             return CreatePerm(obj, m_ignoreTypeLoadFailures);
1983         }
1984 
CreatePerm(Object obj, bool ignoreTypeLoadFailures)1985         internal static IPermission CreatePerm(Object obj, bool ignoreTypeLoadFailures)
1986         {
1987             SecurityElement el = obj as SecurityElement;
1988             ISecurityElementFactory isf = obj as ISecurityElementFactory;
1989             if (el == null && isf != null)
1990             {
1991                 el = isf.CreateSecurityElement();
1992             }
1993 
1994             IEnumerator enumerator;
1995             IPermission finalPerm = null;
1996 
1997             switch (el.Tag)
1998             {
1999             case s_str_PermissionUnion:
2000                 enumerator = el.Children.GetEnumerator();
2001                 while (enumerator.MoveNext())
2002                 {
2003                     IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
2004 
2005                     if (finalPerm != null)
2006                         finalPerm = finalPerm.Union( tempPerm );
2007                     else
2008                         finalPerm = tempPerm;
2009                 }
2010                 break;
2011 
2012             case s_str_PermissionIntersection:
2013                 enumerator = el.Children.GetEnumerator();
2014                 while (enumerator.MoveNext())
2015                 {
2016                     IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
2017 
2018                     if (finalPerm != null)
2019                         finalPerm = finalPerm.Intersect( tempPerm );
2020                     else
2021                         finalPerm = tempPerm;
2022 
2023                     if (finalPerm == null)
2024                         return null;
2025                 }
2026                 break;
2027 
2028             case s_str_PermissionUnrestrictedUnion:
2029                 enumerator = el.Children.GetEnumerator();
2030                 bool first = true;
2031                 while (enumerator.MoveNext())
2032                 {
2033                     IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );
2034 
2035                     if (tempPerm == null)
2036                         continue;
2037 
2038                     PermissionToken token = PermissionToken.GetToken( tempPerm );
2039 
2040                     Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
2041 
2042                     if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
2043                     {
2044                         finalPerm = XMLUtil.CreatePermission( GetPermissionElement((SecurityElement)enumerator.Current), PermissionState.Unrestricted, ignoreTypeLoadFailures );
2045                         first = false;
2046                         break;
2047                     }
2048                     else
2049                     {
2050                         Contract.Assert( tempPerm != null, "We should only come here if we have a real permission" );
2051                         if (first)
2052                             finalPerm = tempPerm;
2053                         else
2054                             finalPerm = tempPerm.Union( finalPerm );
2055                         first = false;
2056                     }
2057                 }
2058                 break;
2059 
2060             case s_str_PermissionUnrestrictedIntersection:
2061                 enumerator = el.Children.GetEnumerator();
2062                 while (enumerator.MoveNext())
2063                 {
2064                     IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );
2065 
2066                     if (tempPerm == null)
2067                         return null;
2068 
2069                     PermissionToken token = PermissionToken.GetToken( tempPerm );
2070 
2071                     Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
2072 
2073                     if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
2074                     {
2075                         if (finalPerm != null)
2076                             finalPerm = tempPerm.Intersect( finalPerm );
2077                         else
2078                             finalPerm = tempPerm;
2079                     }
2080                     else
2081                     {
2082                         finalPerm = null;
2083                     }
2084 
2085                     if (finalPerm == null)
2086                         return null;
2087                 }
2088                 break;
2089 
2090             case "IPermission":
2091             case "Permission":
2092                 finalPerm = el.ToPermission(ignoreTypeLoadFailures);
2093                 break;
2094 
2095             default:
2096                 Contract.Assert( false, "Unrecognized case found during permission creation" );
2097                 break;
2098             }
2099 
2100             return finalPerm;
2101         }
2102 
CreatePermission(Object obj, int index)2103         internal IPermission CreatePermission(Object obj, int index)
2104         {
2105             IPermission perm = CreatePerm(obj);
2106             if(perm == null)
2107                 return null;
2108 
2109             // See if the PermissionSet.m_Unrestricted flag covers this permission
2110             if(m_Unrestricted)
2111                 perm = null;
2112 
2113             // Store the decoded result
2114             CheckSet();
2115             m_permSet.SetItem(index, perm);
2116 
2117             // Do some consistency checks
2118             Contract.Assert(perm == null || PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ), "PermissionToken was improperly assigned");
2119             if (perm != null)
2120             {
2121                 PermissionToken permToken = PermissionToken.GetToken(perm);
2122                 if (permToken != null && permToken.m_index != index)
2123                     throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet"));
2124             }
2125 
2126 
2127             return perm;
2128         }
2129 
GetPermissionElement( SecurityElement el )2130         private static SecurityElement GetPermissionElement( SecurityElement el )
2131         {
2132             switch (el.Tag)
2133             {
2134             case "IPermission":
2135             case "Permission":
2136                 return el;
2137             }
2138             IEnumerator enumerator = el.Children.GetEnumerator();
2139             if (enumerator.MoveNext())
2140                 return GetPermissionElement((SecurityElement)enumerator.Current);
2141             Contract.Assert( false, "No Permission or IPermission tag found" );
2142             return null;
2143         }
2144 
CreateEmptyPermissionSetXml()2145         internal static SecurityElement CreateEmptyPermissionSetXml()
2146         {
2147 
2148             SecurityElement elTrunk = new SecurityElement("PermissionSet");
2149             elTrunk.AddAttribute( "class", "System.Security.PermissionSet" );
2150 
2151             elTrunk.AddAttribute( "version", "1" );
2152             return elTrunk;
2153 
2154         }
2155         // internal helper which takes in the hardcoded permission name to avoid lookup at runtime
2156         // can be called from classes that derive from PermissionSet
ToXml(String permName)2157         internal SecurityElement ToXml(String permName)
2158         {
2159             SecurityElement elTrunk = new SecurityElement("PermissionSet");
2160             elTrunk.AddAttribute( "class", permName );
2161 
2162             elTrunk.AddAttribute( "version", "1" );
2163 
2164             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
2165 
2166             if (m_Unrestricted)
2167             {
2168                 elTrunk.AddAttribute(s_str_Unrestricted, "true" );
2169             }
2170 
2171             while (enumerator.MoveNext())
2172             {
2173                 IPermission perm = (IPermission)enumerator.Current;
2174 
2175                 if (!m_Unrestricted)
2176                     elTrunk.AddChild( perm.ToXml() );
2177             }
2178             return elTrunk;
2179         }
2180 
InternalToXml()2181         internal SecurityElement InternalToXml()
2182         {
2183             SecurityElement elTrunk = new SecurityElement("PermissionSet");
2184             elTrunk.AddAttribute( "class", this.GetType().FullName);
2185             elTrunk.AddAttribute( "version", "1" );
2186 
2187             if (m_Unrestricted)
2188             {
2189                 elTrunk.AddAttribute(s_str_Unrestricted, "true" );
2190             }
2191 
2192             if (this.m_permSet != null)
2193             {
2194                 int maxIndex = this.m_permSet.GetMaxUsedIndex();
2195 
2196                 for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i)
2197                 {
2198                     Object obj = this.m_permSet.GetItem( i );
2199                     if (obj != null)
2200                     {
2201                         if (obj is IPermission)
2202                         {
2203                             if (!m_Unrestricted)
2204                                 elTrunk.AddChild( ((IPermission)obj).ToXml() );
2205                         }
2206                         else
2207                         {
2208                             elTrunk.AddChild( (SecurityElement)obj );
2209                         }
2210                     }
2211 
2212                 }
2213             }
2214             return elTrunk ;
2215         }
2216 
ToXml()2217         public virtual SecurityElement ToXml()
2218         {
2219             // If you hit this assert then most likely you are trying to change the name of this class.
2220             // This is ok as long as you change the hard coded string above and change the assert below.
2221             Contract.Assert( this.GetType().FullName.Equals( "System.Security.PermissionSet" ), "Class name changed! Was: System.Security.PermissionSet Should be:" +  this.GetType().FullName);
2222 
2223             return ToXml("System.Security.PermissionSet");
2224         }
2225 #endif // FEATURE_CAS_POLICY
2226 
2227 #if FEATURE_CAS_POLICY && FEATURE_SERIALIZATION
2228         internal
EncodeXml()2229         byte[] EncodeXml()
2230         {
2231             MemoryStream ms = new MemoryStream();
2232             BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode );
2233             writer.Write( this.ToXml().ToString() );
2234             writer.Flush();
2235 
2236             // The BinaryWriter is going to place
2237             // two bytes indicating a Unicode stream.
2238             // We want to chop those off before returning
2239             // the bytes out.
2240 
2241             ms.Position = 2;
2242             int countBytes = (int)ms.Length - 2;
2243             byte[] retval = new byte[countBytes];
2244             ms.Read( retval, 0, retval.Length );
2245             return retval;
2246         }
2247 
2248         /// <internalonly/>
2249         [Obsolete("This method is obsolete and shoud no longer be used.")]
ConvertPermissionSet(String inFormat, byte[] inData, String outFormat)2250         public static byte[] ConvertPermissionSet(String inFormat, byte[] inData, String outFormat)
2251         {
2252             // Since this method has shipped and is public, we cannot remove it without being a breaking change
2253             throw new NotImplementedException();
2254         }
2255 #endif
2256 
2257         // Determines whether the permission set contains any non-code access
2258         // security permissions.
2259         #if FEATURE_CORECLR
2260         [System.Security.SecurityCritical] // auto-generated
2261         #endif
ContainsNonCodeAccessPermissions()2262         public bool ContainsNonCodeAccessPermissions()
2263         {
2264             if (m_CheckedForNonCas)
2265                 return m_ContainsNonCas;
2266 
2267             lock (this)
2268             {
2269                 if (m_CheckedForNonCas)
2270                     return m_ContainsNonCas;
2271 
2272                 m_ContainsCas = false;
2273                 m_ContainsNonCas = false;
2274 
2275                 if (IsUnrestricted())
2276                     m_ContainsCas = true;
2277 
2278                 if (this.m_permSet != null)
2279                 {
2280                     PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
2281 
2282                     while (enumerator.MoveNext() && (!m_ContainsCas || !m_ContainsNonCas))
2283                     {
2284                         IPermission perm = enumerator.Current as IPermission;
2285 
2286                         if (perm != null)
2287                         {
2288                             if (perm is CodeAccessPermission)
2289                                 m_ContainsCas = true;
2290                             else
2291                                 m_ContainsNonCas = true;
2292                         }
2293                     }
2294                 }
2295 
2296                 m_CheckedForNonCas = true;
2297             }
2298 
2299             return m_ContainsNonCas;
2300         }
2301 
2302         // Returns a permission set containing only CAS-permissions. If possible
2303         // this is just the input set, otherwise a new set is allocated.
GetCasOnlySet()2304         private PermissionSet GetCasOnlySet()
2305         {
2306             if (!m_ContainsNonCas)
2307                 return this;
2308 
2309             if (IsUnrestricted())
2310                 return this;
2311 
2312             PermissionSet pset = new PermissionSet(false);
2313 
2314             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
2315 
2316             while (enumerator.MoveNext())
2317             {
2318                 IPermission perm = (IPermission)enumerator.Current;
2319 
2320                 if (perm is CodeAccessPermission)
2321                     pset.AddPermission(perm);
2322             }
2323 
2324             pset.m_CheckedForNonCas = true;
2325             pset.m_ContainsCas = !pset.IsEmpty();
2326             pset.m_ContainsNonCas = false;
2327 
2328             return pset;
2329         }
2330 
2331 #if FEATURE_CAS_POLICY
2332         private const String s_str_PermissionSet = "PermissionSet";
2333         private const String s_str_Permission    = "Permission";
2334         private const String s_str_IPermission    = "IPermission";
2335         private const String s_str_Unrestricted  = "Unrestricted";
2336         private const String s_str_PermissionUnion = "PermissionUnion";
2337         private const String s_str_PermissionIntersection = "PermissionIntersection";
2338         private const String s_str_PermissionUnrestrictedUnion = "PermissionUnrestrictedUnion";
2339         private const String s_str_PermissionUnrestrictedIntersection = "PermissionUnrestrictedIntersection";
2340 
2341         // This method supports v1.x security attrbutes only - we'll require legacy CAS policy mode
2342         // to be enabled for that to work.
2343 #pragma warning disable 618
2344         // Internal routine used to setup a special security context
2345         // for creating and manipulated security custom attributes
2346         // that we use when the Runtime is hosted.
2347         [System.Security.SecurityCritical]  // auto-generated
SetupSecurity()2348         private static void SetupSecurity()
2349         {
2350             PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
2351 
2352             CodeGroup rootGroup = new UnionCodeGroup( new AllMembershipCondition(), level.GetNamedPermissionSet( "Execution" ) );
2353 
2354             StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob( AssemblyRef.MicrosoftPublicKeyFull );
2355             CodeGroup microsoftGroup = new UnionCodeGroup( new StrongNameMembershipCondition( microsoftBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );
2356 
2357             StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob( AssemblyRef.EcmaPublicKeyFull );
2358             CodeGroup ecmaGroup = new UnionCodeGroup( new StrongNameMembershipCondition( ecmaBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );
2359 
2360             CodeGroup gacGroup = new UnionCodeGroup( new GacMembershipCondition(), level.GetNamedPermissionSet( "FullTrust" ) );
2361 
2362             rootGroup.AddChild( microsoftGroup );
2363             rootGroup.AddChild( ecmaGroup );
2364             rootGroup.AddChild( gacGroup );
2365 
2366             level.RootCodeGroup = rootGroup;
2367 
2368             try
2369             {
2370                 AppDomain.CurrentDomain.SetAppDomainPolicy( level );
2371             }
2372             catch (PolicyException)
2373             {
2374             }
2375         }
2376 #endif
2377 #pragma warning restore 618
2378 
2379         // Internal routine used by CreateSerialized to add a permission to the set
MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)2380         private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)
2381         {
2382             Contract.Assert(casPset == null || !casPset.IsReadOnly);
2383             Contract.Assert(nonCasPset == null || !nonCasPset.IsReadOnly);
2384 
2385             if (perm == null)
2386                 return;
2387 
2388             if (!separateCasFromNonCas || perm is CodeAccessPermission)
2389             {
2390                 if(casPset == null)
2391                     casPset = new PermissionSet(false);
2392                 IPermission oldPerm = casPset.GetPermission(perm);
2393                 IPermission unionPerm = casPset.AddPermission(perm);
2394                 if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm ))
2395                     throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
2396             }
2397             else
2398             {
2399                 if(nonCasPset == null)
2400                     nonCasPset = new PermissionSet(false);
2401                 IPermission oldPerm = nonCasPset.GetPermission(perm);
2402                 IPermission unionPerm = nonCasPset.AddPermission( perm );
2403                 if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm ))
2404                     throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
2405             }
2406         }
2407 
2408         // Converts an array of SecurityAttributes to a PermissionSet
2409         #if FEATURE_CORECLR
2410         [System.Security.SecurityCritical] // auto-generated
2411         #endif
2412         [ResourceExposure(ResourceScope.Machine)]  // Reading these attributes can load files.
2413         [ResourceConsumption(ResourceScope.Machine)]
CreateSerialized(Object[] attrs, bool serialize, ref byte[] nonCasBlob, out PermissionSet casPset, HostProtectionResource fullTrustOnlyResources, bool allowEmptyPermissionSets)2414         private static byte[] CreateSerialized(Object[] attrs,
2415                                                bool serialize,
2416                                                ref byte[] nonCasBlob,
2417                                                out PermissionSet casPset,
2418                                                HostProtectionResource fullTrustOnlyResources,
2419                                                bool allowEmptyPermissionSets)
2420         {
2421             // Create two new (empty) sets.
2422             casPset = null;
2423             PermissionSet nonCasPset = null;
2424 
2425             // Most security attributes generate a single permission. The
2426             // PermissionSetAttribute class generates an entire permission set we
2427             // need to merge, however.
2428             for (int i = 0; i < attrs.Length; i++)
2429             {
2430 #pragma warning disable 618
2431                 Contract.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
2432 #pragma warning restore 618
2433                 if (attrs[i] is PermissionSetAttribute)
2434                 {
2435                     PermissionSet pset = ((PermissionSetAttribute)attrs[i]).CreatePermissionSet();
2436                     if (pset == null)
2437                         throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet" ) );
2438 
2439                     PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(pset);
2440 
2441                     while (enumerator.MoveNext())
2442                     {
2443                         IPermission perm = (IPermission)enumerator.Current;
2444                         MergePermission(perm, serialize, ref casPset, ref nonCasPset);
2445                     }
2446 
2447                     if(casPset == null)
2448                         casPset = new PermissionSet(false);
2449                     if (pset.IsUnrestricted())
2450                         casPset.SetUnrestricted(true);
2451                 }
2452                 else
2453                 {
2454 #pragma warning disable 618
2455                     IPermission perm = ((SecurityAttribute)attrs[i]).CreatePermission();
2456 #pragma warning restore 618
2457                     MergePermission(perm, serialize, ref casPset, ref nonCasPset);
2458                 }
2459             }
2460             Contract.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true");
2461 
2462             //
2463             // Filter HostProtection permission.  In the VM, some optimizations are done based upon these
2464             // declarative permission sets being NULL if they do not exist.  When filtering the permission
2465             // set if we end up with an empty set, we can the permission set NULL rather than returning the
2466             // empty set in order to enable those optimizations.
2467             //
2468 
2469             if(casPset != null)
2470             {
2471                 casPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
2472                 casPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
2473                 if (allowEmptyPermissionSets && casPset.IsEmpty())
2474                     casPset = null;
2475             }
2476             if(nonCasPset != null)
2477             {
2478                 nonCasPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
2479                 nonCasPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
2480                 if (allowEmptyPermissionSets && nonCasPset.IsEmpty())
2481                     nonCasPset = null;
2482             }
2483 
2484             // Serialize the set(s).
2485             byte[] casBlob = null;
2486             nonCasBlob = null;
2487 #if FEATURE_CAS_POLICY
2488             if(serialize)
2489             {
2490                 if(casPset != null)
2491                     casBlob = casPset.EncodeXml();
2492                 if(nonCasPset != null)
2493                     nonCasBlob = nonCasPset.EncodeXml();
2494             }
2495 #else // FEATURE_CAS_POLICY
2496             Contract.Assert(!serialize, "Cannot serialize permission sets on CoreCLR");
2497 #endif // FEATURE_CAS_POLICY
2498 
2499             return casBlob;
2500         }
2501 
2502 #if FEATURE_SERIALIZATION
2503         /// <internalonly/>
IDeserializationCallback.OnDeserialization(Object sender)2504         void IDeserializationCallback.OnDeserialization(Object sender)
2505         {
2506             NormalizePermissionSet();
2507             m_CheckedForNonCas = false;
2508         }
2509 #endif
2510 
2511         [System.Security.SecuritySafeCritical]  // auto-generated
2512         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
RevertAssert()2513         public static void RevertAssert()
2514         {
2515             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2516             SecurityRuntime.RevertAssert(ref stackMark);
2517         }
2518 
RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)2519         internal static PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)
2520         {
2521             Contract.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here");
2522             PermissionSet retPs = null;
2523             bFailedToCompress = false;
2524             if (assertSet == null)
2525                 return null;
2526             if (refusedSet != null)
2527             {
2528                 if (refusedSet.IsUnrestricted())
2529                     return null; // we're refusing everything...cannot assert anything now.
2530 
2531                 PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(refusedSet);
2532                 while (enumerator.MoveNext())
2533                 {
2534                     CodeAccessPermission refusedPerm = (CodeAccessPermission)enumerator.Current;
2535                     int i = enumerator.GetCurrentIndex();
2536                     if (refusedPerm != null)
2537                     {
2538                         CodeAccessPermission perm
2539                             = (CodeAccessPermission)assertSet.GetPermission(i);
2540                         try
2541                         {
2542                             if (refusedPerm.Intersect(perm) != null)
2543                             {
2544                                 if (refusedPerm.Equals(perm))
2545                                 {
2546                                     if (retPs == null)
2547                                         retPs = assertSet.Copy();
2548 
2549                                     retPs.RemovePermission(i);
2550                                 }
2551                                 else
2552                                 {
2553                                     // Asserting a permission, part of which is already denied/refused
2554                                     // cannot compress this assert
2555                                     bFailedToCompress = true;
2556                                     return assertSet;
2557                                 }
2558                             }
2559                         }
2560                         catch (ArgumentException)
2561                         {
2562                             // Any exception during removing a refused set from assert set => we play it safe and not assert that perm
2563                             if (retPs == null)
2564                                 retPs = assertSet.Copy();
2565                             retPs.RemovePermission(i);
2566                         }
2567                     }
2568                 }
2569             }
2570             if (retPs != null)
2571                 return retPs;
2572             return assertSet;
2573         }
2574 
RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet)2575         internal static void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet)
2576         {
2577             Contract.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted");
2578             alteredDemandSet = null;
2579 
2580             PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet);
2581             while (enumerator.MoveNext())
2582             {
2583                 CodeAccessPermission demandDerm = (CodeAccessPermission)enumerator.Current;
2584                 int i = enumerator.GetCurrentIndex();
2585                 if (demandDerm != null)
2586                 {
2587                     CodeAccessPermission assertPerm
2588                         = (CodeAccessPermission)assertSet.GetPermission(i);
2589                     try
2590                     {
2591                         if (demandDerm.CheckAssert(assertPerm))
2592                         {
2593                             if (alteredDemandSet == null)
2594                                 alteredDemandSet = demandSet.Copy();
2595 
2596                             alteredDemandSet.RemovePermission(i);
2597                         }
2598                     }
2599                     catch (ArgumentException)
2600                     {
2601                     }
2602                 }
2603             }
2604             return;
2605         }
2606 
IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2)2607         internal static bool IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2)
2608         {
2609             bool isIntersecting = false;
2610             if (assertSet1 != null && assertSet2 != null)
2611             {
2612                 PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(assertSet2);
2613                 while (enumerator.MoveNext())
2614                 {
2615                     CodeAccessPermission perm2 = (CodeAccessPermission)enumerator.Current;
2616                     int i = enumerator.GetCurrentIndex();
2617                     if (perm2 != null)
2618                     {
2619                         CodeAccessPermission perm1
2620                             = (CodeAccessPermission)assertSet1.GetPermission(i);
2621                         try
2622                         {
2623                             if (perm1 != null && !perm1.Equals(perm2))
2624                             {
2625                                 isIntersecting = true; // Same type of permission, but with different flags or something - cannot union them
2626                             }
2627                         }
2628                         catch (ArgumentException)
2629                         {
2630                             isIntersecting = true; //assume worst case
2631                         }
2632                     }
2633                 }
2634             }
2635             return isIntersecting;
2636 
2637         }
2638 
2639         // This is a hack so that SQL can operate under default policy without actually
2640         // granting permissions in assemblies that they disallow.  @
2641 
2642 
2643         internal bool IgnoreTypeLoadFailures
2644         {
2645             set { m_ignoreTypeLoadFailures = value; }
2646         }
2647     }
2648 }
2649