The Labs \ Source Viewer \ SSCLI \ System.Security.Util \ XMLUtil

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** CLASS:    XMLUtil
  18. **
  19. ** PURPOSE:  Helpers for XML input & output
  20. **
  21. ===========================================================*/
  22. namespace System.Security.Util
  23. {
  24.    
  25.     using System;
  26.     using System.Security;
  27.     using System.Security.Permissions;
  28.     using System.Security.Policy;
  29.     using System.Runtime.InteropServices;
  30.     using System.Runtime.Remoting;
  31.     using System.Runtime.Remoting.Activation;
  32.     using System.IO;
  33.     using System.Text;
  34.     using System.Runtime.CompilerServices;
  35.     using PermissionState = System.Security.Permissions.PermissionState;
  36.     using BindingFlags = System.Reflection.BindingFlags;
  37.     using Assembly = System.Reflection.Assembly;
  38.     using System.Threading;
  39.     using System.Globalization;
  40.    
  41.     static internal class XMLUtil
  42.     {
  43.         //
  44.         // Warning: Element constructors have side-effects on their
  45.         // third argument.
  46.         //
  47.        
  48.         private const string BuiltInPermission = "System.Security.Permissions.";
  49.         private const string BuiltInMembershipCondition = "System.Security.Policy.";
  50.         private const string BuiltInCodeGroup = "System.Security.Policy.";
  51.         private const string BuiltInApplicationSecurityManager = "System.Security.Policy.";
  52.        
  53.         public static SecurityElement NewPermissionElement(IPermission ip)
  54.         {
  55.             return NewPermissionElement(ip.GetType().FullName);
  56.         }
  57.        
  58.         public static SecurityElement NewPermissionElement(string name)
  59.         {
  60.             SecurityElement ecr = new SecurityElement("Permission");
  61.             ecr.AddAttribute("class", name);
  62.             return ecr;
  63.         }
  64.        
  65.         public static void AddClassAttribute(SecurityElement element, Type type, string typename)
  66.         {
  67.             // Replace any quotes with apostrophes so that we can include quoted materials
  68.             // within classnames. Notably the assembly name member 'loc' uses a quoted string.
  69.            
  70.             // NOTE: this makes assumptions as to what reflection is expecting for a type string
  71.             // it will need to be updated if reflection changes what it wants.
  72.            
  73.             if (typename == null)
  74.                 typename = type.FullName;
  75.             BCLDebug.Assert(type.FullName.Equals(typename), "Incorrect class name passed! Was : " + typename + " Shoule be: " + type.FullName);
  76.             element.AddAttribute("class", typename + ", " + type.Module.Assembly.FullName.Replace('"', '\''));
  77.         }
  78.        
  79.         private static bool ParseElementForObjectCreation(SecurityElement el, string requiredNamespace, out string className, out int classNameStart, out int classNameLength)
  80.         {
  81.             className = null;
  82.             classNameStart = 0;
  83.             classNameLength = 0;
  84.            
  85.             int requiredNamespaceLength = requiredNamespace.Length;
  86.            
  87.             string fullClassName = el.Attribute("class");
  88.            
  89.             if (fullClassName == null) {
  90.                 throw new ArgumentException(Environment.GetResourceString("Argument_NoClass"));
  91.             }
  92.            
  93.             if (fullClassName.IndexOf('\'') >= 0) {
  94.                 fullClassName = fullClassName.Replace('\'', '"');
  95.             }
  96.            
  97.             if (!PermissionToken.IsMscorlibClassName(fullClassName)) {
  98.                 return false;
  99.             }
  100.            
  101.             int commaIndex = fullClassName.IndexOf(',');
  102.             int namespaceClassNameLength;
  103.            
  104.             // If the classname is tagged with assembly information, find where
  105.             // the assembly information begins.
  106.            
  107.             if (commaIndex == -1) {
  108.                 namespaceClassNameLength = fullClassName.Length;
  109.             }
  110.             else {
  111.                 namespaceClassNameLength = commaIndex;
  112.             }
  113.            
  114.             // Only if the length of the class name is greater than the namespace info
  115.             // on our requiredNamespace do we continue
  116.             // with our check.
  117.            
  118.             if (namespaceClassNameLength > requiredNamespaceLength) {
  119.                 // Make sure we are in the required namespace.
  120.                 if (fullClassName.StartsWith(requiredNamespace, StringComparison.Ordinal)) {
  121.                     className = fullClassName;
  122.                     classNameLength = namespaceClassNameLength - requiredNamespaceLength;
  123.                     classNameStart = requiredNamespaceLength;
  124.                     return true;
  125.                 }
  126.             }
  127.            
  128.             return false;
  129.         }
  130.        
  131.         public static string SecurityObjectToXmlString(object ob)
  132.         {
  133.             if (ob == null)
  134.                 return "";
  135.             PermissionSet pset = ob as PermissionSet;
  136.             if (pset != null)
  137.                 return pset.ToXml().ToString();
  138.             return ((IPermission)ob).ToXml().ToString();
  139.         }
  140.        
  141.         public static object XmlStringToSecurityObject(string s)
  142.         {
  143.             if (s == null)
  144.                 return null;
  145.             if (s.Length < 1)
  146.                 return null;
  147.             return SecurityElement.FromString(s).ToSecurityObject();
  148.         }
  149.        
  150.         public static IPermission CreatePermission(SecurityElement el, PermissionState permState, bool ignoreTypeLoadFailures)
  151.         {
  152.             if (el == null || !(el.Tag.Equals("Permission") || el.Tag.Equals("IPermission")))
  153.                 throw new ArgumentException(String.Format(null, Environment.GetResourceString("Argument_WrongElementType"), "<Permission>"));
  154.            
  155.             string className;
  156.             int classNameLength;
  157.             int classNameStart;
  158.            
  159.             if (!ParseElementForObjectCreation(el, BuiltInPermission, out className, out classNameStart, out classNameLength)) {
  160.                 goto USEREFLECTION;
  161.             }
  162.            
  163.             // We have a built in permission, figure out which it is.
  164.            
  165.             // UIPermission
  166.             // FileIOPermission
  167.             // SecurityPermission
  168.             // PrincipalPermission
  169.             // ReflectionPermission
  170.             // FileDialogPermission
  171.             // EnvironmentPermission
  172.             // GacIdentityPermission
  173.             // UrlIdentityPermission
  174.             // SiteIdentityPermission
  175.             // ZoneIdentityPermission
  176.             // KeyContainerPermission
  177.             // UnsafeForHostPermission
  178.             // HostProtectionPermission
  179.             // StrongNameIdentityPermission
  180.             // IsolatedStorageFilePermission
  181.            
  182.             switch (classNameLength) {
  183.                 case 12:
  184.                     // UIPermission
  185.                     if (String.Compare(className, classNameStart, "UIPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  186.                         return new UIPermission(permState);
  187.                     else
  188.                         goto USEREFLECTION;
  189.                     break;
  190.                 case 16:
  191.                    
  192.                     // FileIOPermission
  193.                     if (String.Compare(className, classNameStart, "FileIOPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  194.                         return new FileIOPermission(permState);
  195.                     else
  196.                         goto USEREFLECTION;
  197.                     break;
  198.                 case 18:
  199.                    
  200.                     if (String.Compare(className, classNameStart, "SecurityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  201.                         return new SecurityPermission(permState);
  202.                     else
  203.                         goto USEREFLECTION;
  204.                     break;
  205.                 case 19:
  206.                    
  207.                     // PrincipalPermission
  208.                     if (String.Compare(className, classNameStart, "PrincipalPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  209.                         return new PrincipalPermission(permState);
  210.                     else
  211.                         goto USEREFLECTION;
  212.                     break;
  213.                 case 20:
  214.                    
  215.                     // ReflectionPermission
  216.                     // FileDialogPermission
  217.                     if (className[classNameStart] == 'R') {
  218.                         if (String.Compare(className, classNameStart, "ReflectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  219.                             return new ReflectionPermission(permState);
  220.                         else
  221.                             goto USEREFLECTION;
  222.                     }
  223.                     else {
  224.                         if (String.Compare(className, classNameStart, "FileDialogPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  225.                             return new FileDialogPermission(permState);
  226.                         else
  227.                             goto USEREFLECTION;
  228.                     }
  229.                     break;
  230.                 case 21:
  231.                    
  232.                     // EnvironmentPermission
  233.                     // UrlIdentityPermission
  234.                     // GacIdentityPermission
  235.                     if (className[classNameStart] == 'E') {
  236.                         if (String.Compare(className, classNameStart, "EnvironmentPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  237.                             return new EnvironmentPermission(permState);
  238.                         else
  239.                             goto USEREFLECTION;
  240.                     }
  241.                     else if (className[classNameStart] == 'U') {
  242.                         if (String.Compare(className, classNameStart, "UrlIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  243.                             return new UrlIdentityPermission(permState);
  244.                         else
  245.                             goto USEREFLECTION;
  246.                     }
  247.                     else {
  248.                         if (String.Compare(className, classNameStart, "GacIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  249.                             return new GacIdentityPermission(permState);
  250.                         else
  251.                             goto USEREFLECTION;
  252.                     }
  253.                     break;
  254.                 case 22:
  255.                    
  256.                    
  257.                     // SiteIdentityPermission
  258.                     // ZoneIdentityPermission
  259.                     // KeyContainerPermission
  260.                     if (className[classNameStart] == 'S') {
  261.                         if (String.Compare(className, classNameStart, "SiteIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  262.                             return new SiteIdentityPermission(permState);
  263.                         else
  264.                             goto USEREFLECTION;
  265.                     }
  266.                     else if (className[classNameStart] == 'Z') {
  267.                         if (String.Compare(className, classNameStart, "ZoneIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  268.                             return new ZoneIdentityPermission(permState);
  269.                         else
  270.                             goto USEREFLECTION;
  271.                     }
  272.                     else {
  273.                         goto USEREFLECTION;
  274.                     }
  275.                     break;
  276.                 case 24:
  277.                    
  278.                    
  279.                     // HostProtectionPermission
  280.                     if (String.Compare(className, classNameStart, "HostProtectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  281.                         return new HostProtectionPermission(permState);
  282.                     else
  283.                         goto USEREFLECTION;
  284.                     break;
  285.                 case 28:
  286.                    
  287.                    
  288.                     // StrongNameIdentityPermission
  289.                     if (String.Compare(className, classNameStart, "StrongNameIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  290.                         return new StrongNameIdentityPermission(permState);
  291.                     else
  292.                         goto USEREFLECTION;
  293.                     break;
  294.                 case 29:
  295.                    
  296.                     // IsolatedStorageFilePermission
  297.                     if (String.Compare(className, classNameStart, "IsolatedStorageFilePermission", 0, classNameLength, StringComparison.Ordinal) == 0)
  298.                         return new IsolatedStorageFilePermission(permState);
  299.                     else
  300.                         goto USEREFLECTION;
  301.                     break;
  302.                 default:
  303.                    
  304.                     goto USEREFLECTION;
  305.                     break;
  306.             }
  307.             USEREFLECTION:
  308.            
  309.            
  310.             object[] objs = new object[1];
  311.             objs[0] = permState;
  312.            
  313.             Type permClass = null;
  314.             IPermission perm = null;
  315.            
  316.             new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
  317.             permClass = GetClassFromElement(el, ignoreTypeLoadFailures);
  318.             if (permClass == null)
  319.                 return null;
  320.             if (!(typeof(IPermission).IsAssignableFrom(permClass)))
  321.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotAPermissionType"));
  322.            
  323.             perm = (IPermission)Activator.CreateInstance(permClass, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null);
  324.            
  325.             return perm;
  326.         }
  327.        
  328.         public static CodeGroup CreateCodeGroup(SecurityElement el)
  329.         {
  330.             if (el == null || !el.Tag.Equals("CodeGroup"))
  331.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_WrongElementType"), "<CodeGroup>"));
  332.            
  333.             string className;
  334.             int classNameLength;
  335.             int classNameStart;
  336.            
  337.             if (!ParseElementForObjectCreation(el, BuiltInCodeGroup, out className, out classNameStart, out classNameLength)) {
  338.                 goto USEREFLECTION;
  339.             }
  340.            
  341.             switch (classNameLength) {
  342.                 case 12:
  343.                     // NetCodeGroup
  344.                     if (String.Compare(className, classNameStart, "NetCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
  345.                         return new NetCodeGroup();
  346.                     else
  347.                         goto USEREFLECTION;
  348.                     break;
  349.                 case 13:
  350.                    
  351.                     // FileCodeGroup
  352.                     if (String.Compare(className, classNameStart, "FileCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
  353.                         return new FileCodeGroup();
  354.                     else
  355.                         goto USEREFLECTION;
  356.                     break;
  357.                 case 14:
  358.                     // UnionCodeGroup
  359.                     if (String.Compare(className, classNameStart, "UnionCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
  360.                         return new UnionCodeGroup();
  361.                     else
  362.                         goto USEREFLECTION;
  363.                     break;
  364.                 case 19:
  365.                    
  366.                     // FirstMatchCodeGroup
  367.                     if (String.Compare(className, classNameStart, "FirstMatchCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
  368.                         return new FirstMatchCodeGroup();
  369.                     else
  370.                         goto USEREFLECTION;
  371.                     break;
  372.                 default:
  373.                    
  374.                     goto USEREFLECTION;
  375.                     break;
  376.             }
  377.             USEREFLECTION:
  378.            
  379.             Type groupClass = null;
  380.             CodeGroup group = null;
  381.            
  382.             new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
  383.             groupClass = GetClassFromElement(el, true);
  384.             if (groupClass == null)
  385.                 return null;
  386.             if (!(typeof(CodeGroup).IsAssignableFrom(groupClass)))
  387.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotACodeGroupType"));
  388.            
  389.             group = (CodeGroup)Activator.CreateInstance(groupClass, true);
  390.            
  391.             BCLDebug.Assert(groupClass.Module.Assembly != Assembly.GetExecutingAssembly(), "This path should not get called for mscorlib based classes");
  392.            
  393.             return group;
  394.         }
  395.        
  396.        
  397.         static internal IMembershipCondition CreateMembershipCondition(SecurityElement el)
  398.         {
  399.             if (el == null || !el.Tag.Equals("IMembershipCondition"))
  400.                 throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_WrongElementType"), "<IMembershipCondition>"));
  401.            
  402.             string className;
  403.             int classNameStart;
  404.             int classNameLength;
  405.            
  406.             if (!ParseElementForObjectCreation(el, BuiltInMembershipCondition, out className, out classNameStart, out classNameLength)) {
  407.                 goto USEREFLECTION;
  408.             }
  409.            
  410.             // We have a built in membership condition, figure out which it is.
  411.            
  412.             // Here's the list of built in membership conditions as of 9/17/2002
  413.             // System.Security.Policy.AllMembershipCondition
  414.             // System.Security.Policy.URLMembershipCondition
  415.             // System.Security.Policy.SHA1MembershipCondition
  416.             // System.Security.Policy.SiteMembershipCondition
  417.             // System.Security.Policy.ZoneMembershipCondition
  418.             // System.Security.Policy.PublisherMembershipCondition
  419.             // System.Security.Policy.StrongNameMembershipCondition
  420.             // System.Security.Policy.ApplicationMembershipCondition
  421.             // System.Security.Policy.DomainApplicationMembershipCondition
  422.             // System.Security.Policy.ApplicationDirectoryMembershipCondition
  423.            
  424.             switch (classNameLength) {
  425.                 case 22:
  426.                     // AllMembershipCondition
  427.                     // URLMembershipCondition
  428.                     if (className[classNameStart] == 'A') {
  429.                         if (String.Compare(className, classNameStart, "AllMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  430.                             return new AllMembershipCondition();
  431.                         else
  432.                             goto USEREFLECTION;
  433.                     }
  434.                     else {
  435.                         if (String.Compare(className, classNameStart, "UrlMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  436.                             return new UrlMembershipCondition();
  437.                         else
  438.                             goto USEREFLECTION;
  439.                     }
  440.                     break;
  441.                 case 23:
  442.                    
  443.                     // SiteMembershipCondition
  444.                     // ZoneMembershipCondition
  445.                     if (className[classNameStart] == 'S') {
  446.                         if (String.Compare(className, classNameStart, "SiteMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  447.                             return new SiteMembershipCondition();
  448.                         else
  449.                             goto USEREFLECTION;
  450.                     }
  451.                     else {
  452.                         if (String.Compare(className, classNameStart, "ZoneMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  453.                             return new ZoneMembershipCondition();
  454.                         else
  455.                             goto USEREFLECTION;
  456.                     }
  457.                     break;
  458.                 case 28:
  459.                    
  460.                     goto USEREFLECTION;
  461.                     break;
  462.                 case 29:
  463.                    
  464.                     // StrongNameMembershipCondition
  465.                     if (String.Compare(className, classNameStart, "StrongNameMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  466.                         return new StrongNameMembershipCondition();
  467.                     else
  468.                         goto USEREFLECTION;
  469.                     break;
  470.                 case 39:
  471.                    
  472.                     // ApplicationDirectoryMembershipCondition
  473.                     if (String.Compare(className, classNameStart, "ApplicationDirectoryMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
  474.                         return new ApplicationDirectoryMembershipCondition();
  475.                     else
  476.                         goto USEREFLECTION;
  477.                     break;
  478.                 default:
  479.                    
  480.                     goto USEREFLECTION;
  481.                     break;
  482.             }
  483.             USEREFLECTION:
  484.            
  485.             Type condClass = null;
  486.             IMembershipCondition cond = null;
  487.            
  488.             new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
  489.             condClass = GetClassFromElement(el, true);
  490.             if (condClass == null)
  491.                 return null;
  492.             if (!(typeof(IMembershipCondition).IsAssignableFrom(condClass)))
  493.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotAMembershipCondition"));
  494.            
  495.             cond = (IMembershipCondition)Activator.CreateInstance(condClass, true);
  496.            
  497.             return cond;
  498.         }
  499.        
  500.         static internal Type GetClassFromElement(SecurityElement el, bool ignoreTypeLoadFailures)
  501.         {
  502.             string className = el.Attribute("class");
  503.            
  504.             if (className == null) {
  505.                 if (ignoreTypeLoadFailures)
  506.                     return null;
  507.                 else
  508.                     throw new ArgumentException(String.Format(null, Environment.GetResourceString("Argument_InvalidXMLMissingAttr"), "class"));
  509.             }
  510.            
  511.             if (ignoreTypeLoadFailures) {
  512.                 try {
  513.                     return Type.GetType(className, false, false);
  514.                 }
  515.                 catch (SecurityException) {
  516.                     return null;
  517.                 }
  518.             }
  519.             else
  520.                 return Type.GetType(className, true, false);
  521.         }
  522.        
  523.         public static bool IsPermissionElement(IPermission ip, SecurityElement el)
  524.         {
  525.             if (!el.Tag.Equals("Permission") && !el.Tag.Equals("IPermission"))
  526.                 return false;
  527.            
  528.             return true;
  529.         }
  530.        
  531.         public static bool IsUnrestricted(SecurityElement el)
  532.         {
  533.             string sUnrestricted = el.Attribute("Unrestricted");
  534.            
  535.             if (sUnrestricted == null)
  536.                 return false;
  537.            
  538.             return sUnrestricted.Equals("true") || sUnrestricted.Equals("TRUE") || sUnrestricted.Equals("True");
  539.         }
  540.        
  541.        
  542.         public static string BitFieldEnumToString(Type type, object value)
  543.         {
  544.             int iValue = (int)value;
  545.            
  546.             if (iValue == 0)
  547.                 return Enum.GetName(type, 0);
  548.            
  549.             StringBuilder result = new StringBuilder();
  550.             bool first = true;
  551.             int flag = 1;
  552.            
  553.             for (int i = 1; i < 32; ++i) {
  554.                 if ((flag & iValue) != 0) {
  555.                     string sFlag = Enum.GetName(type, flag);
  556.                    
  557.                     if (sFlag == null)
  558.                         continue;
  559.                    
  560.                     if (!first) {
  561.                         result.Append(", ");
  562.                     }
  563.                    
  564.                     result.Append(sFlag);
  565.                     first = false;
  566.                 }
  567.                
  568.                 flag = flag << 1;
  569.             }
  570.            
  571.             return result.ToString();
  572.         }
  573.     }
  574. }

Developer Fusion