diff options
Diffstat (limited to 'src/mscorlib/src/System/Security/Util/XMLUtil.cs')
-rw-r--r-- | src/mscorlib/src/System/Security/Util/XMLUtil.cs | 694 |
1 files changed, 694 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Security/Util/XMLUtil.cs b/src/mscorlib/src/System/Security/Util/XMLUtil.cs new file mode 100644 index 0000000000..0c47f441b4 --- /dev/null +++ b/src/mscorlib/src/System/Security/Util/XMLUtil.cs @@ -0,0 +1,694 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +/*============================================================ +** +** +** PURPOSE: Helpers for XML input & output +** +===========================================================*/ +namespace System.Security.Util { + + using System; + using System.Security; + using System.Security.Permissions; + using System.Security.Policy; + using System.Runtime.InteropServices; + using System.Runtime.Remoting; + using System.IO; + using System.Text; + using System.Runtime.CompilerServices; + using PermissionState = System.Security.Permissions.PermissionState; + using BindingFlags = System.Reflection.BindingFlags; + using Assembly = System.Reflection.Assembly; + using System.Threading; + using System.Globalization; + using System.Reflection; + using System.Diagnostics.Contracts; + + internal static class XMLUtil + { + // + // Warning: Element constructors have side-effects on their + // third argument. + // + + private const String BuiltInPermission = "System.Security.Permissions."; +#if FEATURE_CAS_POLICY + private const String BuiltInMembershipCondition = "System.Security.Policy."; + private const String BuiltInCodeGroup = "System.Security.Policy."; + private const String BuiltInApplicationSecurityManager = "System.Security.Policy."; + private static readonly char[] sepChar = {',', ' '}; +#endif + public static SecurityElement + NewPermissionElement (IPermission ip) + { + return NewPermissionElement (ip.GetType ().FullName) ; + } + + public static SecurityElement + NewPermissionElement (String name) + { + SecurityElement ecr = new SecurityElement( "Permission" ); + ecr.AddAttribute( "class", name ); + return ecr; + } + + public static void + AddClassAttribute( SecurityElement element, Type type, String typename ) + { + // Replace any quotes with apostrophes so that we can include quoted materials + // within classnames. Notably the assembly name member 'loc' uses a quoted string. + + // NOTE: this makes assumptions as to what reflection is expecting for a type string + // it will need to be updated if reflection changes what it wants. + + if ( typename == null ) + typename = type.FullName; + Contract.Assert( type.FullName.Equals( typename ), "Incorrect class name passed! Was : " + typename + " Shoule be: " + type.FullName); + element.AddAttribute( "class", typename + ", " + type.Module.Assembly.FullName.Replace( '\"', '\'' ) ); + } + + internal static bool ParseElementForAssemblyIdentification(SecurityElement el, + out String className, + out String assemblyName, // for example "WindowsBase" + out String assemblyVersion) + { + + className = null; + assemblyName = null; + assemblyVersion = null; + + String fullClassName = el.Attribute( "class" ); + + if (fullClassName == null) + { + return false; + } + if (fullClassName.IndexOf('\'') >= 0) + { + fullClassName = fullClassName.Replace( '\'', '\"' ); + } + + int commaIndex = fullClassName.IndexOf( ',' ); + int namespaceClassNameLength; + + // If the classname is tagged with assembly information, find where + // the assembly information begins. + + if (commaIndex == -1) + { + return false; + } + + namespaceClassNameLength = commaIndex; + className = fullClassName.Substring(0, namespaceClassNameLength); + String assemblyFullName = fullClassName.Substring(commaIndex + 1); + AssemblyName an = new AssemblyName(assemblyFullName); + assemblyName = an.Name; + assemblyVersion = an.Version.ToString(); + return true; + } + [System.Security.SecurityCritical] // auto-generated + private static bool + ParseElementForObjectCreation( SecurityElement el, + String requiredNamespace, + out String className, + out int classNameStart, + out int classNameLength ) + { + className = null; + classNameStart = 0; + classNameLength = 0; + + int requiredNamespaceLength = requiredNamespace.Length; + + String fullClassName = el.Attribute( "class" ); + + if (fullClassName == null) + { + throw new ArgumentException( Environment.GetResourceString( "Argument_NoClass" ) ); + } + + if (fullClassName.IndexOf('\'') >= 0) + { + fullClassName = fullClassName.Replace( '\'', '\"' ); + } + + if (!PermissionToken.IsMscorlibClassName( fullClassName )) + { + return false; + } + + int commaIndex = fullClassName.IndexOf( ',' ); + int namespaceClassNameLength; + + // If the classname is tagged with assembly information, find where + // the assembly information begins. + + if (commaIndex == -1) + { + namespaceClassNameLength = fullClassName.Length; + } + else + { + namespaceClassNameLength = commaIndex; + } + + // Only if the length of the class name is greater than the namespace info + // on our requiredNamespace do we continue + // with our check. + + if (namespaceClassNameLength > requiredNamespaceLength) + { + // Make sure we are in the required namespace. + if (fullClassName.StartsWith(requiredNamespace, StringComparison.Ordinal)) + { + className = fullClassName; + classNameLength = namespaceClassNameLength - requiredNamespaceLength; + classNameStart = requiredNamespaceLength; + return true; + } + } + + return false; + } + +#if FEATURE_CAS_POLICY + public static String SecurityObjectToXmlString(Object ob) + { + if(ob == null) + return ""; + PermissionSet pset = ob as PermissionSet; + if(pset != null) + return pset.ToXml().ToString(); + return ((IPermission)ob).ToXml().ToString(); + } + + [System.Security.SecurityCritical] // auto-generated + public static Object XmlStringToSecurityObject(String s) + { + if(s == null) + return null; + if(s.Length < 1) + return null; + return SecurityElement.FromString(s).ToSecurityObject(); + } +#endif // FEATURE_CAS_POLICY + + [SecuritySafeCritical] + public static IPermission + CreatePermission (SecurityElement el, PermissionState permState, bool ignoreTypeLoadFailures) + { + if (el == null || !(el.Tag.Equals("Permission") || el.Tag.Equals("IPermission")) ) + throw new ArgumentException( String.Format( null, Environment.GetResourceString( "Argument_WrongElementType" ), "<Permission>" ) ) ; + Contract.EndContractBlock(); + + String className; + int classNameLength; + int classNameStart; + + if (!ParseElementForObjectCreation( el, + BuiltInPermission, + out className, + out classNameStart, + out classNameLength )) + { + goto USEREFLECTION; + } + + // We have a built in permission, figure out which it is. + + // UIPermission + // FileIOPermission + // SecurityPermission + // PrincipalPermission + // ReflectionPermission + // FileDialogPermission + // EnvironmentPermission + // GacIdentityPermission + // UrlIdentityPermission + // SiteIdentityPermission + // ZoneIdentityPermission + // KeyContainerPermission + // UnsafeForHostPermission + // HostProtectionPermission + // StrongNameIdentityPermission +#if !FEATURE_CORECLR + // IsolatedStorageFilePermission +#endif + // RegistryPermission + // PublisherIdentityPermission + + switch (classNameLength) + { + case 12: + // UIPermission + if (String.Compare(className, classNameStart, "UIPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new UIPermission( permState ); + else + goto USEREFLECTION; + + case 16: + // FileIOPermission + if (String.Compare(className, classNameStart, "FileIOPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new FileIOPermission( permState ); + else + goto USEREFLECTION; + + case 18: + // RegistryPermission + // SecurityPermission + if (className[classNameStart] == 'R') + { + if (String.Compare(className, classNameStart, "RegistryPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new RegistryPermission( permState ); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "SecurityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new SecurityPermission( permState ); + else + goto USEREFLECTION; + } + +#if !FEATURE_CORECLR + case 19: + // PrincipalPermission + if (String.Compare(className, classNameStart, "PrincipalPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new PrincipalPermission( permState ); + else + goto USEREFLECTION; +#endif // !FEATURE_CORECLR + case 20: + // ReflectionPermission + // FileDialogPermission + if (className[classNameStart] == 'R') + { + if (String.Compare(className, classNameStart, "ReflectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new ReflectionPermission( permState ); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "FileDialogPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new FileDialogPermission( permState ); + else + goto USEREFLECTION; + } + + case 21: + // EnvironmentPermission + // UrlIdentityPermission + // GacIdentityPermission + if (className[classNameStart] == 'E') + { + if (String.Compare(className, classNameStart, "EnvironmentPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new EnvironmentPermission( permState ); + else + goto USEREFLECTION; + } + else if (className[classNameStart] == 'U') + { + if (String.Compare(className, classNameStart, "UrlIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new UrlIdentityPermission( permState ); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "GacIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new GacIdentityPermission( permState ); + else + goto USEREFLECTION; + } + + + case 22: + // SiteIdentityPermission + // ZoneIdentityPermission + // KeyContainerPermission + if (className[classNameStart] == 'S') + { + if (String.Compare(className, classNameStart, "SiteIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new SiteIdentityPermission( permState ); + else + goto USEREFLECTION; + } + else if (className[classNameStart] == 'Z') + { + if (String.Compare(className, classNameStart, "ZoneIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new ZoneIdentityPermission( permState ); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "KeyContainerPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new KeyContainerPermission( permState ); + else + goto USEREFLECTION; + } + + + case 24: + // HostProtectionPermission + if (String.Compare(className, classNameStart, "HostProtectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new HostProtectionPermission( permState ); + else + goto USEREFLECTION; + +#if FEATURE_X509 && FEATURE_CAS_POLICY + case 27: + // PublisherIdentityPermission + if (String.Compare(className, classNameStart, "PublisherIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new PublisherIdentityPermission( permState ); + else + goto USEREFLECTION; +#endif // FEATURE_X509 && FEATURE_CAS_POLICY + + case 28: + // StrongNameIdentityPermission + if (String.Compare(className, classNameStart, "StrongNameIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new StrongNameIdentityPermission( permState ); + else + goto USEREFLECTION; +#if !FEATURE_CORECLR + case 29: + // IsolatedStorageFilePermission + if (String.Compare(className, classNameStart, "IsolatedStorageFilePermission", 0, classNameLength, StringComparison.Ordinal) == 0) + return new IsolatedStorageFilePermission( permState ); + else + goto USEREFLECTION; +#endif + default: + goto USEREFLECTION; + } + +USEREFLECTION: + + Object[] objs = new Object[1]; + objs[0] = permState; + + Type permClass = null; + IPermission perm = null; + + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert(); + permClass = GetClassFromElement(el, ignoreTypeLoadFailures); + if (permClass == null) + return null; + if (!(typeof(IPermission).IsAssignableFrom(permClass))) + throw new ArgumentException( Environment.GetResourceString("Argument_NotAPermissionType") ); + + perm = (IPermission) Activator.CreateInstance(permClass, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null ); + + return perm; + } + +#if FEATURE_CAS_POLICY +#pragma warning disable 618 // CodeGroups are obsolete + [System.Security.SecuritySafeCritical] // auto-generated + public static CodeGroup + CreateCodeGroup (SecurityElement el) + { + if (el == null || !el.Tag.Equals("CodeGroup")) + throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<CodeGroup>" ) ) ; + Contract.EndContractBlock(); + + String className; + int classNameLength; + int classNameStart; + + if (!ParseElementForObjectCreation( el, + BuiltInCodeGroup, + out className, + out classNameStart, + out classNameLength )) + { + goto USEREFLECTION; + } + + switch (classNameLength) + { + case 12: + // NetCodeGroup + if (String.Compare(className, classNameStart, "NetCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0) + return new NetCodeGroup(); + else + goto USEREFLECTION; + + case 13: + // FileCodeGroup + if (String.Compare(className, classNameStart, "FileCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0) + return new FileCodeGroup(); + else + goto USEREFLECTION; + case 14: + // UnionCodeGroup + if (String.Compare(className, classNameStart, "UnionCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0) + return new UnionCodeGroup(); + else + goto USEREFLECTION; + + case 19: + // FirstMatchCodeGroup + if (String.Compare(className, classNameStart, "FirstMatchCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0) + return new FirstMatchCodeGroup(); + else + goto USEREFLECTION; + + default: + goto USEREFLECTION; + } + +USEREFLECTION: + Type groupClass = null; + CodeGroup group = null; + + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert(); + groupClass = GetClassFromElement(el, true); + if (groupClass == null) + return null; + if (!(typeof(CodeGroup).IsAssignableFrom(groupClass))) + throw new ArgumentException( Environment.GetResourceString("Argument_NotACodeGroupType") ); + + group = (CodeGroup) Activator.CreateInstance(groupClass, true); + + Contract.Assert( groupClass.Module.Assembly != Assembly.GetExecutingAssembly(), + "This path should not get called for mscorlib based classes" ); + + return group; + } +#pragma warning restore 618 + + [System.Security.SecurityCritical] // auto-generated + internal static IMembershipCondition + CreateMembershipCondition( SecurityElement el ) + { + if (el == null || !el.Tag.Equals("IMembershipCondition")) + throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<IMembershipCondition>" ) ) ; + Contract.EndContractBlock(); + + String className; + int classNameStart; + int classNameLength; + + if (!ParseElementForObjectCreation( el, + BuiltInMembershipCondition, + out className, + out classNameStart, + out classNameLength )) + { + goto USEREFLECTION; + } + + // We have a built in membership condition, figure out which it is. + + // Here's the list of built in membership conditions as of 9/17/2002 + // System.Security.Policy.AllMembershipCondition + // System.Security.Policy.URLMembershipCondition + // System.Security.Policy.SHA1MembershipCondition + // System.Security.Policy.SiteMembershipCondition + // System.Security.Policy.ZoneMembershipCondition + // System.Security.Policy.PublisherMembershipCondition + // System.Security.Policy.StrongNameMembershipCondition + // System.Security.Policy.ApplicationMembershipCondition + // System.Security.Policy.DomainApplicationMembershipCondition + // System.Security.Policy.ApplicationDirectoryMembershipCondition + + switch (classNameLength) + { + case 22: + // AllMembershipCondition + // URLMembershipCondition + if (className[classNameStart] == 'A') + { + if (String.Compare(className, classNameStart, "AllMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new AllMembershipCondition(); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "UrlMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new UrlMembershipCondition(); + else + goto USEREFLECTION; + } + + case 23: + // HashMembershipCondition + // SiteMembershipCondition + // ZoneMembershipCondition + if (className[classNameStart] == 'H') + { + if (String.Compare(className, classNameStart, "HashMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new HashMembershipCondition(); + else + goto USEREFLECTION; + } + else if (className[classNameStart] == 'S') + { + if (String.Compare(className, classNameStart, "SiteMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new SiteMembershipCondition(); + else + goto USEREFLECTION; + } + else + { + if (String.Compare(className, classNameStart, "ZoneMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new ZoneMembershipCondition(); + else + goto USEREFLECTION; + } + + case 28: + // PublisherMembershipCondition + if (String.Compare(className, classNameStart, "PublisherMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new PublisherMembershipCondition(); + else + goto USEREFLECTION; + + case 29: + // StrongNameMembershipCondition + if (String.Compare(className, classNameStart, "StrongNameMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new StrongNameMembershipCondition(); + else + goto USEREFLECTION; + + case 39: + // ApplicationDirectoryMembershipCondition + if (String.Compare(className, classNameStart, "ApplicationDirectoryMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0) + return new ApplicationDirectoryMembershipCondition(); + else + goto USEREFLECTION; + + default: + goto USEREFLECTION; + } + +USEREFLECTION: + Type condClass = null; + IMembershipCondition cond = null; + + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert(); + condClass = GetClassFromElement(el, true); + if (condClass == null) + return null; + if (!(typeof(IMembershipCondition).IsAssignableFrom(condClass))) + throw new ArgumentException( Environment.GetResourceString("Argument_NotAMembershipCondition") ); + + cond = (IMembershipCondition) Activator.CreateInstance(condClass, true); + + return cond; + } +#endif //#if FEATURE_CAS_POLICY + internal static Type + GetClassFromElement (SecurityElement el, bool ignoreTypeLoadFailures) + { + String className = el.Attribute( "class" ); + + if (className == null) + { + if (ignoreTypeLoadFailures) + return null; + else + throw new ArgumentException( String.Format( null, Environment.GetResourceString("Argument_InvalidXMLMissingAttr"), "class") ); + } + + if (ignoreTypeLoadFailures) + { + try + { + return Type.GetType(className, false, false); + } + catch (SecurityException) + { + return null; + } + } + else + return Type.GetType(className, true, false); + } + + public static bool + IsPermissionElement (IPermission ip, + SecurityElement el) + { + if (!el.Tag.Equals ("Permission") && !el.Tag.Equals ("IPermission")) + return false; + + return true; + } + + public static bool + IsUnrestricted (SecurityElement el) + { + String sUnrestricted = el.Attribute( "Unrestricted" ); + + if (sUnrestricted == null) + return false; + + return sUnrestricted.Equals( "true" ) || sUnrestricted.Equals( "TRUE" ) || sUnrestricted.Equals( "True" ); + } + + + public static String BitFieldEnumToString( Type type, Object value ) + { + int iValue = (int)value; + + if (iValue == 0) + return Enum.GetName( type, 0 ); + + StringBuilder result = StringBuilderCache.Acquire(); + bool first = true; + int flag = 0x1; + + for (int i = 1; i < 32; ++i) + { + if ((flag & iValue) != 0) + { + String sFlag = Enum.GetName( type, flag ); + + if (sFlag == null) + continue; + + if (!first) + { + result.Append( ", " ); + } + + result.Append( sFlag ); + first = false; + } + + flag = flag << 1; + } + + return StringBuilderCache.GetStringAndRelease(result); + } + } +} |