NameValuePermission.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / Common / NameValuePermission.cs / 1 / NameValuePermission.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
#if ORACLE
namespace System.Data.OracleClient { 
#else
namespace System.Data.Common {
#endif
 
    using System.Collections;
    using System.Data.Common; 
    using System.Diagnostics; 
    using System.Globalization;
    using System.Security; 
    using System.Security.Permissions;
    using System.Text;

    [Serializable] // MDAC 83147 
    sealed internal class NameValuePermission : IComparable {
        // reused as both key and value nodes 
        // key nodes link to value nodes 
        // value nodes link to key nodes
        private string _value; 

        // value node with (null != _restrictions) are allowed to match connection strings
        private DBConnectionString _entry;
 
        private NameValuePermission[] _tree; // with branches
 
        static internal readonly NameValuePermission Default = null;// = new NameValuePermission(String.Empty, new string[] { "File Name" }, KeyRestrictionBehavior.AllowOnly); 

        internal NameValuePermission() { // root node 
        }

        private NameValuePermission(string keyword) {
            _value = keyword; 
       }
 
        private NameValuePermission(string value, DBConnectionString entry) { 
            _value = value;
            _entry = entry; 
        }

        private NameValuePermission(NameValuePermission permit) { // deep-copy
            _value = permit._value; 
            _entry = permit._entry;
            _tree = permit._tree; 
            if (null != _tree) { 
                NameValuePermission[] tree = (_tree.Clone() as NameValuePermission[]);
                for(int i = 0; i < tree.Length; ++i) { 
                    if (null != tree[i]) { // WebData 98488
                        tree[i] = tree[i].CopyNameValue(); // deep copy
                    }
                } 
                _tree = tree;
            } 
        } 

        int IComparable.CompareTo(object a) { 
            return StringComparer.Ordinal.Compare(_value, ((NameValuePermission)a)._value);
        }

        static internal void AddEntry(NameValuePermission kvtree, ArrayList entries, DBConnectionString entry) { 
            Debug.Assert(null != entry, "null DBConnectionString");
 
            if (null != entry.KeyChain) { 
                for(NameValuePair keychain = entry.KeyChain; null != keychain; keychain = keychain.Next) {
                    NameValuePermission kv; 

                    kv = kvtree.CheckKeyForValue(keychain.Name);
                    if (null == kv) {
                        kv = new NameValuePermission(keychain.Name); 
                        kvtree.Add(kv); // add directly into live tree
                    } 
                    kvtree = kv; 

                    kv = kvtree.CheckKeyForValue(keychain.Value); 
                    if (null == kv) {
                        DBConnectionString insertValue = ((null != keychain.Next) ? null : entry);
                        kv = new NameValuePermission(keychain.Value, insertValue);
                        kvtree.Add(kv); // add directly into live tree 
                        if (null != insertValue) {
                            entries.Add(insertValue); 
                        } 
                    }
                    else if (null == keychain.Next) { // shorter chain potential 
                        if (null != kv._entry) {
                            Debug.Assert(entries.Contains(kv._entry), "entries doesn't contain entry");
                            entries.Remove(kv._entry);
                            kv._entry = kv._entry.Intersect(entry); // union new restrictions into existing tree 
                        }
                        else { 
                            kv._entry = entry; 
                        }
                        entries.Add(kv._entry); 
                    }
                    kvtree = kv;
                }
            } 
            else { // global restrictions, MDAC 84443
                DBConnectionString kentry = kvtree._entry; 
                if (null != kentry) { 
                    Debug.Assert(entries.Contains(kentry), "entries doesn't contain entry");
                    entries.Remove(kentry); 
                    kvtree._entry = kentry.Intersect(entry);
                }
                else {
                    kvtree._entry = entry; 
                }
                entries.Add(kvtree._entry); 
            } 
        }
 
        internal void Intersect(ArrayList entries, NameValuePermission target) {
            if (null == target) {
                _tree = null;
                _entry = null; 
            }
            else { 
                if (null != _entry) { 
                    entries.Remove(_entry);
                    _entry = _entry.Intersect(target._entry); 
                    entries.Add(_entry);
                }
                else if (null != target._entry) {
                    _entry = target._entry.Intersect(null); 
                    entries.Add(_entry);
                } 
 
                if (null != _tree) {
                    int count = _tree.Length; 
                    for(int i = 0; i < _tree.Length; ++i) {
                        NameValuePermission kvtree = target.CheckKeyForValue(_tree[i]._value);
                        if (null != kvtree) { // does target tree contain our value
                            _tree[i].Intersect(entries, kvtree); 
                        }
                        else { 
                            _tree[i] = null; 
                            --count;
                        } 
                    }
                    if (0 == count) {
                        _tree = null;
                    } 
                    else if (count < _tree.Length) {
                        NameValuePermission[] kvtree = new NameValuePermission[count]; 
                        for (int i = 0, j = 0; i < _tree.Length; ++i) { 
                            if(null != _tree[i]) {
                                kvtree[j++] = _tree[i]; 
                            }
                        }
                        _tree = kvtree;
                    } 
                }
            } 
        } 

        private void Add(NameValuePermission permit) { 
            NameValuePermission[] tree = _tree;
            int length = ((null != tree) ? tree.Length : 0);
            NameValuePermission[] newtree = new NameValuePermission[1+length];
            for(int i = 0; i < newtree.Length-1; ++i) { 
                newtree[i] = tree[i];
            } 
            newtree[length] = permit; 
            Array.Sort(newtree);
            _tree = newtree; 
        }

#if DATAPERMIT
        internal void DebugDump(string depth) { 
            Debug.WriteLine(depth + "<" + _value + ">");
            if (null != _tree) { 
                for(int i = 0; i < _tree.Length; ++i) { 
                    _tree[i].DebugDump(depth+"-");
                } 
            }
        }
#endif
 
        internal bool CheckValueForKeyPermit(DBConnectionString parsetable) {
            if (null == parsetable) { 
                return false; 
            }
            bool hasMatch = false; 
            NameValuePermission[] keytree = _tree; // _tree won't mutate but Add will replace it
            if (null != keytree) {
                hasMatch = parsetable.IsEmpty; // MDAC 86773
                if (!hasMatch) { 

                    // which key do we follow the key-value chain on 
                    for (int i = 0; i < keytree.Length; ++i) { 
                        NameValuePermission permitKey = keytree[i];
                        if (null != permitKey) { 
                            string keyword = permitKey._value;
#if DATAPERMIT
                            Debug.WriteLine("DBDataPermission try keyword: <" + keyword + ">");
#endif 
#if DEBUG
                            Debug.Assert(null == permitKey._entry, "key member has no restrictions"); 
#endif 
                            if (parsetable.ContainsKey(keyword)) {
                                string valueInQuestion = (string)parsetable[keyword]; 

                                // keyword is restricted to certain values
                                NameValuePermission permitValue = permitKey.CheckKeyForValue(valueInQuestion);
                                if (null != permitValue) { 
                                    //value does match - continue the chain down that branch
                                    if (permitValue.CheckValueForKeyPermit(parsetable)) { 
                                        hasMatch = true; 
                                        // adding a break statement is tempting, but wrong
                                        // user can safetly extend their restrictions for current rule to include missing keyword 
                                        // i.e. Add("provider=sqloledb;integrated security=sspi", "data provider=", KeyRestrictionBehavior.AllowOnly);
                                        // i.e. Add("data provider=msdatashape;provider=sqloledb;integrated security=sspi", "", KeyRestrictionBehavior.AllowOnly);
                                    }
                                    else { // failed branch checking 
#if DATAPERMIT
                                    Debug.WriteLine("DBDataPermission failed branch checking: " + keyword); 
#endif 
                                        return false;
                                    } 
                                }
                                else { // value doesn't match to expected values - fail here

#if DATAPERMIT 
                                Debug.WriteLine("DBDataPermission failed to match expected value " + keyword);
#endif 
                                    return false; 
                                }
                            } 
                        }
                        // else try next keyword
                    }
                } 
                // partial chain match, either leaf-node by shorter chain or fail mid-chain if (null == _restrictions)
            } 
#if DATAPERMIT 
            else {
                Debug.WriteLine("leaf node <" + _entry.UsersConnectionString(true) + ">"); 
            }
#endif
            DBConnectionString entry = _entry;
            if (null != entry) { 
                // also checking !hasMatch is tempting, but wrong
                // user can safetly extend their restrictions for current rule to include missing keyword 
                // i.e. Add("provider=sqloledb;integrated security=sspi", "data provider=", KeyRestrictionBehavior.AllowOnly); 
                // i.e. Add("provider=sqloledb;", "integrated security=;", KeyRestrictionBehavior.AllowOnly);
                hasMatch = entry.IsSupersetOf(parsetable); 
            }
#if DATAPERMIT
            else if (!hasMatch) {
                Debug.WriteLine("DBDataPermission failed on non-terminal node " + _value); 
            }
#endif 
            return hasMatch; // mid-chain failure 
        }
 
        private NameValuePermission CheckKeyForValue(string keyInQuestion) {
            NameValuePermission[] valuetree = _tree; // _tree won't mutate but Add will replace it
            if (null != valuetree) {
                for (int i = 0; i < valuetree.Length; ++i) { 
                    NameValuePermission permitValue = valuetree[i];
#if DATAPERMIT 
                    Debug.WriteLine("DBDataPermission value: <" + permitValue._value  + ">"); 
#endif
                    if (String.Equals(keyInQuestion, permitValue._value, StringComparison.OrdinalIgnoreCase)) { 
                        return permitValue;
                    }
                }
            } 
            return null;
        } 
 
        internal NameValuePermission CopyNameValue() {
            return new NameValuePermission(this); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK