// Copy the nodes of the first list. Note that the // list gets new nodes, but the Permissions aren't deep // copied. As long as we never directly expose a list, // and if the Permissions are treated as read only, // then this is OK. public PermissionList(PermissionList permList) : this() { if (permList == null || permList.m_head == null) { return; } // Assign head to a copy of the first node m_head = new PListNode(permList.m_head); // Use m_last to traverse list starting from head m_last = m_head; // While m_last isn't really the last, continue to // make copies of the original nodes that m_last.next points to.\ // When we're done, m_last points to last of the copies. while (m_last.next != null) { m_last.next = new PListNode(m_last.next); m_last = m_last.next; } // Copy how many elements there are. m_cElt = permList.m_cElt; }
private PermissionList GetListForToken(PermissionToken permToken, bool create) { TokenBasedSet permSet; BCLDebug.Assert(permToken != null, "permToken != null"); if (permToken.m_isUnrestricted) { permSet = m_unrestrictedPermSet; } else { permSet = m_normalPermSet; } PermissionList plist = (PermissionList)permSet.GetItem(permToken.m_index); if (plist == null && create) { plist = new PermissionList(); permSet.SetItem(permToken.m_index, plist); } return(plist); }
// Appends a PermissionList to the current list. // NOTE: Since AppendList does not make a copy of the parameter before // appending it, operations on the newly formed list also side-effect // the parameter. If this is not desired, make a copy of the parameter // before calling AppendList. public virtual void AppendList(PermissionList permList) { // Check for null if (permList == null) { return; } // If current list is empty, then DO NOT // append list, possibly adding Permissions! if (m_head == null) { return; } // Append list only if the last element of the current list does // not guarantee a failed check, thus stopping a walk. else if (!(m_last.type == MatchChecked && m_last.perm == null)) { // Make sure there is something in the target // list to append. if (permList.m_head != null) { // Stick the head of the target list to the end of // the current list... m_last.next = permList.m_head; // The new last is the last of the target list... m_last = permList.m_last; // Add up the elements. m_cElt += permList.m_cElt; } } }
// Makes a copy of the list and a deep copy of all the permissions. public virtual PermissionList DeepPermissionCopy() { PermissionList nlist = new PermissionList(); if (m_head == null) { return(nlist); } nlist.m_head = new PListNode(m_head.perm == null ? null : (CodeAccessPermission)m_head.perm.Copy(), m_head.type, m_head.next, m_head.prev); nlist.m_last = nlist.m_head; while (nlist.m_last.next != null) { nlist.m_last.next = new PListNode(nlist.m_last.next.perm == null ? null : (CodeAccessPermission)nlist.m_last.next.perm.Copy(), nlist.m_last.next.type, nlist.m_last.next.next, nlist.m_last); nlist.m_last = nlist.m_last.next; } nlist.m_cElt = m_cElt; return(nlist); }
internal void GetZoneAndOrigin(ArrayList zoneList, ArrayList originList) { PermissionList zone = this.FindPermissionList(typeof(ZoneIdentityPermission)); PermissionList url = this.FindPermissionList(typeof(UrlIdentityPermission)); IEnumerator enumerator; enumerator = new PermissionListEnumerator(zone); while (enumerator.MoveNext()) { PListNode node = (PListNode)enumerator.Current; if (node.type == PermissionList.MatchChecked && node.perm != null) { zoneList.Add(((ZoneIdentityPermission)node.perm).SecurityZone); } } enumerator = new PermissionListEnumerator(url); while (enumerator.MoveNext()) { PListNode node = (PListNode)enumerator.Current; if (node.type == PermissionList.MatchChecked && node.perm != null) { originList.Add(((UrlIdentityPermission)node.perm).Url); } } }
/* * Helpers designed for stack compression */ private void NullTerminateRest(int startIndex, int action) { for (int i = startIndex; i <= m_unrestrictedPermSet.GetMaxUsedIndex(); i++) { PermissionList plist = (PermissionList)m_unrestrictedPermSet.GetItem(i); if (plist != null) { plist.AppendPermissionAndCompress(null, action); } } }
public void AddPermission(CodeAccessPermission perm, int type) { //BCLDebug.Assert(type == MatchAssert || type == MatchDeny, "type == MatchAssert || type == MatchDeny"); // can't get token if perm is null if (perm == null) { return; } PermissionToken permToken = PermissionToken.GetToken(perm); PermissionList plist = GetListForToken(permToken, true); plist.AppendPermission(perm, type); }
public PermissionListSet(PermissionListSet permListSet) { if (permListSet == null) { Reset(); return; } m_unrestrictedPermSet = new TokenBasedSet(permListSet.m_unrestrictedPermSet); // Now deep copy all permission lists in set. // Note that this DOES deep copy permissions in the list. for (int i = 0; i <= m_unrestrictedPermSet.GetMaxUsedIndex(); i++) { PermissionList plist = (PermissionList)m_unrestrictedPermSet.GetItem(i); if (plist != null) { m_unrestrictedPermSet.SetItem(i, plist.Copy()); } } m_normalPermSet = new TokenBasedSet(permListSet.m_normalPermSet); // Now deep copy all permission lists in set. // Note that this DOES deep copy permissions in the list. for (int i = 0; i <= m_normalPermSet.GetMaxUsedIndex(); i++) { PermissionList plist = (PermissionList)m_normalPermSet.GetItem(i); if (plist != null) { m_normalPermSet.SetItem(i, plist.Copy()); } } m_unrestricted = permListSet.m_unrestricted; m_state = permListSet.m_state; }
// Copy the nodes of the first list. Note that the // list gets new nodes, but the Permissions aren't deep // copied. As long as we never directly expose a list, // and if the Permissions are treated as read only, // then this is OK. public PermissionList(PermissionList permList) : this() { if (permList == null || permList.m_head == null) return; // Assign head to a copy of the first node m_head = new PListNode(permList.m_head); // Use m_last to traverse list starting from head m_last = m_head; // While m_last isn't really the last, continue to // make copies of the original nodes that m_last.next points to.\ // When we're done, m_last points to last of the copies. while (m_last.next != null) { m_last.next = new PListNode(m_last.next); m_last = m_last.next; } // Copy how many elements there are. m_cElt = permList.m_cElt; }
private void AppendStackHelper(TokenBasedSet thisSet, TokenBasedSet permSet, bool unrestrictedThisSet, bool unrestrictedPermSet, bool unrestricted) { int maxThis = thisSet.GetMaxUsedIndex(); int maxPerm = permSet.GetMaxUsedIndex(); int maxIndex = maxThis > maxPerm ? maxThis : maxPerm; for (int i = 0; i <= maxIndex; i++) { PermissionList plist = (PermissionList)thisSet.GetItem(i); PermissionList appendList = (PermissionList)permSet.GetItem(i); if (plist != null) { if (appendList != null) { // This call will not add the permission if the list is // empty, or if the last element is a normal check with // a null Permission. Let the method take care of it... plist.AppendStack(appendList.Copy()); } else { // Nothing on the compressed stack for this index, // so terminate current list. if (!unrestrictedPermSet) { plist.AppendPermissionAndCompress(null, PermissionList.MatchChecked); } } } else if (unrestrictedThisSet && appendList != null) { thisSet.SetItem(i, appendList.Copy()); } } }
// Makes a copy of the list and a deep copy of all the permissions. public virtual PermissionList DeepPermissionCopy() { PermissionList nlist = new PermissionList(); if (m_head == null) return nlist; nlist.m_head = new PListNode(m_head.perm == null ? null : (CodeAccessPermission)m_head.perm.Copy(), m_head.type, m_head.next); nlist.m_last = nlist.m_head; while (nlist.m_last.next != null) { nlist.m_last.next = new PListNode(nlist.m_last.next.perm == null ? null : (CodeAccessPermission)nlist.m_last.next.perm.Copy(), nlist.m_last.next.type, nlist.m_last.next.next); nlist.m_last = nlist.m_last.next; } nlist.m_cElt = m_cElt; return nlist; }
public virtual void AppendStack(PermissionList permList) { // Check for null if (permList == null) { return; } // If current list is empty, then DO NOT // append list, possibly adding Permissions! if (m_head == null) { return; } else { // Make sure there is something in the target // list to append. if (permList.m_head != null) { // If the last element of the current list and the first element of the // appended list are both of type MatchChecked, then we can merge the // entries together using intersect to conserve the number of entries // in the final list. if (m_last.type == MatchChecked && permList.m_head.type == MatchChecked) { // If the entries are non-null, then call Intersect. if (m_last.perm != null && permList.m_head.perm != null) { m_last.perm = (CodeAccessPermission)m_last.perm.Intersect(permList.m_head.perm); } else { m_last.perm = null; } // If the last element is now null, then don't bother appending // anything more. Also, // if the combined element was the only element in the appended list, // then there is nothing further to append. So, only do work to append // if the m_head.next is non-null. if (m_last.perm != null && permList.m_head.next != null) { // Stick the element after the head of the target list // to the end of the current list... m_last.next = permList.m_head.next; // The new last is the last element of the target list... m_last = permList.m_last; // The new count is is the sum minus 1 to account for the // merge performed above. m_cElt += (permList.m_cElt - 1); } } // Otherwise, append the list only if the last element is not a // guaranteed failure during a stack walk: the type is Normal and // it is null. else if (!(m_last.type == MatchChecked && m_last.perm == null)) { // Stick the head of the target list to the end of // the current list... m_last.next = permList.m_head; // The new last is the last of the target list... m_last = permList.m_last; // Add up the elements. m_cElt += permList.m_cElt; } } } }
internal PermissionListEnumerator(PermissionList list) { m_list = list; Reset(); }
public virtual void AppendStack(PermissionList permList) { // Check for null if (permList == null) return; // If current list is empty, then DO NOT // append list, possibly adding Permissions! if (m_head == null) { return; } else { // Make sure there is something in the target // list to append. if (permList.m_head != null) { // If the last element of the current list and the first element of the // appended list are both of type MatchChecked, then we can merge the // entries together using intersect to conserve the number of entries // in the final list. if (m_last.type == MatchChecked && permList.m_head.type == MatchChecked) { // If the entries are non-null, then call Intersect. if (m_last.perm != null && permList.m_head.perm != null) { m_last.perm = (CodeAccessPermission) m_last.perm.Intersect(permList.m_head.perm); } else { m_last.perm = null; } // If the last element is now null, then don't bother appending // anything more. Also, // if the combined element was the only element in the appended list, // then there is nothing further to append. So, only do work to append // if the m_head.next is non-null. if (m_last.perm != null && permList.m_head.next != null) { // Stick the element after the head of the target list // to the end of the current list... m_last.next = permList.m_head.next; // The new last is the last element of the target list... m_last = permList.m_last; // The new count is is the sum minus 1 to account for the // merge performed above. m_cElt += (permList.m_cElt - 1); } } // Otherwise, append the list only if the last element is not a // guaranteed failure during a stack walk: the type is Normal and // it is null. else if (! (m_last.type == MatchChecked && m_last.perm == null)) { // Stick the head of the target list to the end of // the current list... m_last.next = permList.m_head; // The new last is the last of the target list... m_last = permList.m_last; // Add up the elements. m_cElt += permList.m_cElt; } } } }
internal bool CheckDemandInternal(CodeAccessPermission demand, PermissionToken permToken, bool createException, out Exception exception) { BCLDebug.Assert(demand != null, "demand != null"); BCLDebug.Assert(permToken != null, "permToken != null"); // First, find if there is a permission list of this type. PermissionList permList = FindPermissionList(permToken); if (permList != null) { // If so, check against it to determine our action. bool cont = permList.CheckDemandInternal(demand, createException, out exception); // We don't record modifiers for the unrestricted permission set in the // individual lists. Therefore, permList.CheckDemandInternal may say // that we have to continue the stackwalk, but we know better. if (cont && permToken.m_isUnrestricted) { if ((m_state & PermissionListSetState.UnrestrictedDeny) != 0) { if (createException) { exception = new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName)); } else { exception = GetStaticException(); } return(false); } else { cont = cont && ((m_state & PermissionListSetState.UnrestrictedAssert) == 0); } } return(cont); } #if _DEBUG // Let's check to make sure we always pass demands for empty permissions. else if (demand.IsSubsetOf(null)) { BCLDebug.Assert(false, "We should pick of empty demands before this point"); exception = null; return(true); } #endif // If the permission is not unrestricted, the lack of a permission list // denotes that no frame on the stack granted this permission, and therefore // we pass back the failure condition. else if (!permToken.m_isUnrestricted) { if (createException) { exception = new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName)); } else { exception = GetStaticException(); } return(false); } // If this permission list set is not unrestricted and there is no unrestricted assert // then the lack of a permission list denotes that no frame on the stack granted // this permission, and therefore we pass back the failure condition. If there is // an unrestricted assert, then we pass back success and terminate the stack walk. else if (!this.IsUnrestricted()) { if (createException) { exception = new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName)); } else { exception = GetStaticException(); } return(false); } // If we made it all the way through, that means that we are in the unrestricted // state and that this permission is encompassed in that. If we have an unrestricted // assert, we are done with the state walk (return false), otherwise keep going. exception = null; return((m_state & PermissionListSetState.UnrestrictedAssert) == 0); }
private PermissionList GetListForToken(PermissionToken permToken, bool create) { TokenBasedSet permSet; BCLDebug.Assert(permToken != null, "permToken != null"); if (permToken.m_isUnrestricted) permSet = m_unrestrictedPermSet; else permSet = m_normalPermSet; PermissionList plist = (PermissionList)permSet.GetItem(permToken.m_index); if (plist == null && create) { plist = new PermissionList(); permSet.SetItem(permToken.m_index, plist); } return plist; }
private void AppendTokenBasedSets(TokenBasedSet thisSet, TokenBasedSet permSet, int type, bool unrestricted) { int thisMaxIndex = thisSet.GetMaxUsedIndex(); int permMaxIndex = permSet == null ? 0 : permSet.GetMaxUsedIndex(); int maxIndex = thisMaxIndex > permMaxIndex ? thisMaxIndex : permMaxIndex; // Loop over the relevant indexes... for (int i = 0; i <= maxIndex; i++) { PermissionList plist = (PermissionList)thisSet.GetItem(i); CodeAccessPermission cap = permSet == null ? null : (CodeAccessPermission)permSet.GetItem(i); if (plist == null) { if (this.m_unrestricted) { switch (type) { case PermissionList.MatchChecked: case PermissionList.MatchPermitOnly: plist = new PermissionList(); plist.AppendPermission(cap, type); thisSet.SetItem(i, plist); break; case PermissionList.MatchDeny: case PermissionList.MatchAssert: if (cap != null) { plist = new PermissionList(); plist.AppendPermission(cap, type); thisSet.SetItem(i, plist); } break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionListType")); } } } else { // A list already exists. All lists should have at least // one element in them. // Normally, only append if the permission is not null. // However, if the type is Checked, then make sure the // list is terminated with a permission, null or not. switch (type) { case PermissionList.MatchChecked: case PermissionList.MatchPermitOnly: plist.AppendPermissionAndCompress(cap, type); break; case PermissionList.MatchDeny: case PermissionList.MatchAssert: if (cap != null) { plist.AppendPermissionAndCompress(cap, type); } break; default: throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionListType")); } } } }
private static bool CheckTokenBasedSets(TokenBasedSet thisSet, TokenBasedSet permSet, bool unrestricted, PermissionListSetState state, bool createException, out Exception exception, bool bNeedAlteredSet, out TokenBasedSet alteredSet) { alteredSet = null; // If the set is empty, there is no reason to walk the // stack. if (permSet == null || permSet.FastIsEmpty()) { if (bNeedAlteredSet) { alteredSet = new TokenBasedSet(1, 4); } exception = null; return(false); } int permMaxIndex = permSet.GetMaxUsedIndex(); // Make a quick check to see if permSet definitely contains permissions that this set doesn't if (permMaxIndex > thisSet.GetMaxUsedIndex()) { // The only way we don't want to throw an exception is // if we are unrestricted. Then, if we don't want to throw // an exception we may want to terminate the stack walk // based on an unrestricted assert. if (unrestricted) { if (((state & PermissionListSetState.UnrestrictedAssert) != 0)) { if (bNeedAlteredSet) { alteredSet = new TokenBasedSet(1, 4); } exception = null; return(false); } else { exception = null; return(true); } } else { if (createException) { exception = new SecurityException(Environment.GetResourceString("Security_GenericNoType")); } else { exception = GetStaticException(); } return(false); } } bool continueStackWalk = false; // We know that checking to <permMaxIndex> is sufficient because of above check for (int i = 0; i <= permMaxIndex; i++) { Object obj = permSet.GetItem(i); if (obj != null) { CodeAccessPermission cap = (CodeAccessPermission)obj; PermissionList permList = (PermissionList)thisSet.GetItem(i); if (permList != null) { bool tempContinue = permList.CheckDemandInternal(cap, createException, out exception); if (exception != null) { return(false); } if (tempContinue) { // If we are supposed to continue the stack walk but there is an unrestricted // deny, then we should fail. if (((state & PermissionListSetState.UnrestrictedDeny) != 0) && (cap is IUnrestrictedPermission)) { if (createException) { exception = new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), cap.GetType().AssemblyQualifiedName)); } else { exception = GetStaticException(); } return(false); } continueStackWalk = true; } else if (((state & PermissionListSetState.UnrestrictedAssert) == 0) && (cap is IUnrestrictedPermission)) { // We only want to build the altered set if we don't have an // unrestricted assert because we know if we have an unrestricted // assert and we don't throw an exception that the stackwalk should // include no unrestricted permissions. if (bNeedAlteredSet) { if (alteredSet == null) { alteredSet = CopyTokenBasedSet(permSet); } alteredSet.SetItem(i, null); } } } else { if (!unrestricted) { if (createException) { exception = new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), cap.GetType().AssemblyQualifiedName)); } else { exception = GetStaticException(); } return(false); } } } } exception = null; return(continueStackWalk); }
private void AppendTokenBasedSets( TokenBasedSet thisSet, TokenBasedSet permSet, int type, bool unrestricted ) { int thisMaxIndex = thisSet.GetMaxUsedIndex(); int permMaxIndex = permSet == null ? 0 : permSet.GetMaxUsedIndex(); int maxIndex = thisMaxIndex > permMaxIndex ? thisMaxIndex : permMaxIndex; // Loop over the relevant indexes... for (int i = 0; i <= maxIndex; i++) { PermissionList plist = (PermissionList)thisSet.GetItem(i); CodeAccessPermission cap = permSet == null ? null : (CodeAccessPermission)permSet.GetItem(i); if (plist == null) { if (this.m_unrestricted) { switch (type) { case PermissionList.MatchChecked: case PermissionList.MatchPermitOnly: plist = new PermissionList(); plist.AppendPermission(cap, type); thisSet.SetItem( i, plist ); break; case PermissionList.MatchDeny: case PermissionList.MatchAssert: if (cap != null) { plist = new PermissionList(); plist.AppendPermission(cap, type); thisSet.SetItem( i, plist ); } break; default: throw new ArgumentException(Environment.GetResourceString( "Argument_InvalidPermissionListType" )); } } } else { // A list already exists. All lists should have at least // one element in them. // Normally, only append if the permission is not null. // However, if the type is Checked, then make sure the // list is terminated with a permission, null or not. switch (type) { case PermissionList.MatchChecked: case PermissionList.MatchPermitOnly: plist.AppendPermissionAndCompress(cap, type); break; case PermissionList.MatchDeny: case PermissionList.MatchAssert: if (cap != null) plist.AppendPermissionAndCompress(cap, type); break; default: throw new ArgumentException(Environment.GetResourceString( "Argument_InvalidPermissionListType" )); } } } }
// Appends a PermissionList to the current list. // NOTE: Since AppendList does not make a copy of the parameter before // appending it, operations on the newly formed list also side-effect // the parameter. If this is not desired, make a copy of the parameter // before calling AppendList. public virtual void AppendList(PermissionList permList) { // Check for null if (permList == null) return; // If current list is empty, then DO NOT // append list, possibly adding Permissions! if (m_head == null) { return; } // Append list only if the last element of the current list does // not guarantee a failed check, thus stopping a walk. else if (! (m_last.type == MatchChecked && m_last.perm == null)) { // Make sure there is something in the target // list to append. if (permList.m_head != null) { // Stick the head of the target list to the end of // the current list... m_last.next = permList.m_head; // The new last is the last of the target list... m_last = permList.m_last; // Add up the elements. m_cElt += permList.m_cElt; } } }