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