// Reinitializes all state in PermissionSet.
        public void Reset()
        {
            if (m_unrestrictedPermSet == null)
            {
                m_unrestrictedPermSet = new TokenBasedSet(12, 4);
            }
            else
            {
                m_unrestrictedPermSet.Reset();
            }

            if (m_normalPermSet == null)
            {
                m_normalPermSet = new TokenBasedSet(6, 4);
            }
            else
            {
                m_normalPermSet.Reset();
            }

            // By default, the PermissionListSet is unrestricted. Why?
            // At the start, having nothing on the stack should indicate success.
            // Once the first non-unrestricted grant is appended to the set,
            // then the PermissionListSet will become non-unrestricted.
            m_unrestricted = true;
            m_state        = PermissionListSetState.None;
        }
        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;
        }
        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());
                }
            }
        }
        public static TokenBasedSet CopyTokenBasedSet(TokenBasedSet set)
        {
            if (set == null || set.GetCount() == 0)
            {
                return(null);
            }

            int maxIndex = set.GetMaxUsedIndex();

            TokenBasedSet copySet = new TokenBasedSet(maxIndex + 1, 4);

            for (int i = 0; i <= maxIndex; ++i)
            {
                Object obj = set.GetItem(i);

                if (obj == null)
                {
                    copySet.SetItem(i, null);
                }
                else if (obj is IPermission)
                {
                    copySet.SetItem(i, ((IPermission)obj).Copy());
                }
                else if (obj is PermissionList)
                {
                    copySet.SetItem(i, ((PermissionList)obj).Copy());
                }
                else
                {
                    BCLDebug.Assert(false, "CopyTokenBasedSet can only be used for IPermission and PermissionList based TokenBasedSets");
                    copySet.SetItem(i, obj);
                }
            }

            return(copySet);
        }
        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"));
                    }
                }
            }
        }
        public bool CheckSetDemandInternal(PermissionSet permSet, bool createException, out Exception exception, bool bNeedAlteredSet, out PermissionSet alteredSet)
        {
            alteredSet = null;

            BCLDebug.Assert(permSet != null, "permSet != null");

            // If the compressed stack is not unrestricted and the demand is
            // then we just throw an exception.
            if (!this.m_unrestricted && permSet.IsUnrestricted())
            {
                if (createException)
                {
                    exception = new SecurityException(Environment.GetResourceString("Security_GenericNoType"));
                }
                else
                {
                    exception = GetStaticException();
                }
                return(false);
            }


            TokenBasedSet normalAlteredSet       = null;
            TokenBasedSet unrestrictedAlteredSet = null;

            // Check the "normal" permissions since we always know we have to check them.

            bool normalContinue = CheckTokenBasedSets(this.m_normalPermSet, permSet.m_normalPermSet, false, PermissionListSetState.None, createException, out exception, bNeedAlteredSet, out normalAlteredSet);

            if (exception != null)
            {
                return(false);
            }

            bool unrestrictedContinue = CheckTokenBasedSets(this.m_unrestrictedPermSet, permSet.m_unrestrictedPermSet, m_unrestricted, m_state, createException, out exception, bNeedAlteredSet, out unrestrictedAlteredSet);

            if (exception != null)
            {
                return(false);
            }

            if ((m_state & PermissionListSetState.UnrestrictedAssert) != 0)
            {
                // If we are unrestricted, we want to terminate the stack walk based
                // on us having an unrestricted assert.

                if (bNeedAlteredSet)
                {
                    unrestrictedAlteredSet = new TokenBasedSet(1, 4);
                }
                unrestrictedContinue = false;
            }

            if (normalContinue || unrestrictedContinue)
            {
                if (!bNeedAlteredSet)
                {
                    return(true);
                }

                // If we need to continue, let's build the altered set.  We only
                // need to do this if 1) our original demand is not unrestricted
                // and 2) if we have altered token based sets.

                if (!permSet.IsUnrestricted())
                {
                    if (normalAlteredSet != null || unrestrictedAlteredSet != null)
                    {
                        alteredSet = new PermissionSet(false);

                        if (normalAlteredSet != null)
                        {
                            alteredSet.m_normalPermSet = normalAlteredSet;
                        }
                        else
                        {
                            alteredSet.m_normalPermSet = CopyTokenBasedSet(permSet.m_normalPermSet);
                        }

                        if (unrestrictedAlteredSet != null)
                        {
                            alteredSet.m_unrestrictedPermSet = unrestrictedAlteredSet;
                        }
                        else
                        {
                            alteredSet.m_unrestrictedPermSet = CopyTokenBasedSet(permSet.m_unrestrictedPermSet);
                        }

                        if (alteredSet.IsEmpty())
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
        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 static void CheckTokenBasedSetHelper(bool ignoreGrants,
                                                     TokenBasedSet grants,
                                                     TokenBasedSet denied,
                                                     TokenBasedSet demands)
        {
            if (demands == null)
            {
                return;
            }

            TokenBasedSetEnumerator enumerator = (TokenBasedSetEnumerator)demands.GetEnum();

            while (enumerator.MoveNext())
            {
                CodeAccessPermission demand = (CodeAccessPermission)enumerator.Current;
                int index = enumerator.GetCurrentIndex();

                if (demand != null)
                {
                    try
                    {
                        // Check to make sure the permission was granted, unless we are supposed
                        // to ignore grants.

                        if (!ignoreGrants)
                        {
                            CodeAccessPermission grant
                                = grants != null ? (CodeAccessPermission)grants.GetItem(index) : null;
                            if (grant != null)
                            {
                                grant.CheckDemand(demand);
                            }
                            else
                            {
                                if (!demand.IsSubsetOf(null))
                                {
                                    throw new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), demand.GetType(), demand.ToXml().ToString());
                                }
                            }
                        }

                        // Check to make sure our permission was not denied.

                        if (denied != null)
                        {
                            CodeAccessPermission deny
                                = (CodeAccessPermission)denied.GetItem(index);
                            if (deny != null && deny.Intersect(demand) != null)
                            {
                                throw new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), demand.GetType(), demand.ToXml().ToString());
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        // Any exception besides a security exception in this code means that
                        // a permission was unable to properly handle what we asked of it.
                        // We will define this to mean that the demand failed.

                        if (e is SecurityException)
                        {
                            throw e;
                        }
                        else
                        {
                            throw new SecurityException(String.Format(Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), demand.GetType(), demand.ToXml().ToString());
                        }
                    }
                }
            }
        }
 public TokenBasedSetEnumerator(TokenBasedSet tb)
 {
     this.Index   = -1;
     this.Current = (object)null;
     this._tb     = tb;
 }