3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>Microsoft</OWNER>
12 ** PURPOSE: Helpers for XML input & output
14 ===========================================================*/
15 namespace System.Security.Util {
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Security.Policy;
21 using System.Runtime.InteropServices;
22 using System.Runtime.Remoting;
25 using System.Runtime.CompilerServices;
26 using PermissionState = System.Security.Permissions.PermissionState;
27 using BindingFlags = System.Reflection.BindingFlags;
28 using Assembly = System.Reflection.Assembly;
29 using System.Threading;
30 using System.Globalization;
31 using System.Reflection;
32 using System.Diagnostics.Contracts;
34 internal static class XMLUtil
37 // Warning: Element constructors have side-effects on their
41 private const String BuiltInPermission = "System.Security.Permissions.";
42 #if FEATURE_CAS_POLICY
43 private const String BuiltInMembershipCondition = "System.Security.Policy.";
44 private const String BuiltInCodeGroup = "System.Security.Policy.";
45 private const String BuiltInApplicationSecurityManager = "System.Security.Policy.";
46 private static readonly char[] sepChar = {',', ' '};
48 public static SecurityElement
49 NewPermissionElement (IPermission ip)
51 return NewPermissionElement (ip.GetType ().FullName) ;
54 public static SecurityElement
55 NewPermissionElement (String name)
57 SecurityElement ecr = new SecurityElement( "Permission" );
58 ecr.AddAttribute( "class", name );
63 AddClassAttribute( SecurityElement element, Type type, String typename )
65 // Replace any quotes with apostrophes so that we can include quoted materials
66 // within classnames. Notably the assembly name member 'loc' uses a quoted string.
68 // NOTE: this makes assumptions as to what reflection is expecting for a type string
69 // it will need to be updated if reflection changes what it wants.
71 if ( typename == null )
72 typename = type.FullName;
73 Contract.Assert( type.FullName.Equals( typename ), "Incorrect class name passed! Was : " + typename + " Shoule be: " + type.FullName);
74 element.AddAttribute( "class", typename + ", " + type.Module.Assembly.FullName.Replace( '\"', '\'' ) );
77 internal static bool ParseElementForAssemblyIdentification(SecurityElement el,
79 out String assemblyName, // for example "WindowsBase"
80 out String assemblyVersion)
85 assemblyVersion = null;
87 String fullClassName = el.Attribute( "class" );
89 if (fullClassName == null)
93 if (fullClassName.IndexOf('\'') >= 0)
95 fullClassName = fullClassName.Replace( '\'', '\"' );
98 int commaIndex = fullClassName.IndexOf( ',' );
99 int namespaceClassNameLength;
101 // If the classname is tagged with assembly information, find where
102 // the assembly information begins.
104 if (commaIndex == -1)
109 namespaceClassNameLength = commaIndex;
110 className = fullClassName.Substring(0, namespaceClassNameLength);
111 String assemblyFullName = fullClassName.Substring(commaIndex + 1);
112 AssemblyName an = new AssemblyName(assemblyFullName);
113 assemblyName = an.Name;
114 assemblyVersion = an.Version.ToString();
117 [System.Security.SecurityCritical] // auto-generated
119 ParseElementForObjectCreation( SecurityElement el,
120 String requiredNamespace,
121 out String className,
122 out int classNameStart,
123 out int classNameLength )
129 int requiredNamespaceLength = requiredNamespace.Length;
131 String fullClassName = el.Attribute( "class" );
133 if (fullClassName == null)
135 throw new ArgumentException( Environment.GetResourceString( "Argument_NoClass" ) );
138 if (fullClassName.IndexOf('\'') >= 0)
140 fullClassName = fullClassName.Replace( '\'', '\"' );
143 if (!PermissionToken.IsMscorlibClassName( fullClassName ))
148 int commaIndex = fullClassName.IndexOf( ',' );
149 int namespaceClassNameLength;
151 // If the classname is tagged with assembly information, find where
152 // the assembly information begins.
154 if (commaIndex == -1)
156 namespaceClassNameLength = fullClassName.Length;
160 namespaceClassNameLength = commaIndex;
163 // Only if the length of the class name is greater than the namespace info
164 // on our requiredNamespace do we continue
167 if (namespaceClassNameLength > requiredNamespaceLength)
169 // Make sure we are in the required namespace.
170 if (fullClassName.StartsWith(requiredNamespace, StringComparison.Ordinal))
172 className = fullClassName;
173 classNameLength = namespaceClassNameLength - requiredNamespaceLength;
174 classNameStart = requiredNamespaceLength;
182 #if FEATURE_CAS_POLICY
183 public static String SecurityObjectToXmlString(Object ob)
187 PermissionSet pset = ob as PermissionSet;
189 return pset.ToXml().ToString();
190 return ((IPermission)ob).ToXml().ToString();
193 [System.Security.SecurityCritical] // auto-generated
194 public static Object XmlStringToSecurityObject(String s)
200 return SecurityElement.FromString(s).ToSecurityObject();
202 #endif // FEATURE_CAS_POLICY
204 [SecuritySafeCritical]
205 public static IPermission
206 CreatePermission (SecurityElement el, PermissionState permState, bool ignoreTypeLoadFailures)
208 if (el == null || !(el.Tag.Equals("Permission") || el.Tag.Equals("IPermission")) )
209 throw new ArgumentException( String.Format( null, Environment.GetResourceString( "Argument_WrongElementType" ), "<Permission>" ) ) ;
210 Contract.EndContractBlock();
216 if (!ParseElementForObjectCreation( el,
220 out classNameLength ))
225 // We have a built in permission, figure out which it is.
229 // SecurityPermission
230 // PrincipalPermission
231 // ReflectionPermission
232 // FileDialogPermission
233 // EnvironmentPermission
234 // GacIdentityPermission
235 // UrlIdentityPermission
236 // SiteIdentityPermission
237 // ZoneIdentityPermission
238 // KeyContainerPermission
239 // UnsafeForHostPermission
240 // HostProtectionPermission
241 // StrongNameIdentityPermission
243 // IsolatedStorageFilePermission
246 // RegistryPermission
247 // PublisherIdentityPermission
248 #endif // !FEATURE_PAL
250 switch (classNameLength)
254 if (String.Compare(className, classNameStart, "UIPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
255 return new UIPermission( permState );
261 if (String.Compare(className, classNameStart, "FileIOPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
262 return new FileIOPermission( permState );
268 // RegistryPermission
269 // SecurityPermission
270 if (className[classNameStart] == 'R')
272 if (String.Compare(className, classNameStart, "RegistryPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
273 return new RegistryPermission( permState );
279 if (String.Compare(className, classNameStart, "SecurityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
280 return new SecurityPermission( permState );
284 #else // !FEATURE_PAL
285 if (String.Compare(className, classNameStart, "SecurityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
286 return new SecurityPermission( permState );
289 #endif // !FEATURE_PAL
293 // PrincipalPermission
294 if (String.Compare(className, classNameStart, "PrincipalPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
295 return new PrincipalPermission( permState );
298 #endif // !FEATURE_CORECLR
300 // ReflectionPermission
301 // FileDialogPermission
302 if (className[classNameStart] == 'R')
304 if (String.Compare(className, classNameStart, "ReflectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
305 return new ReflectionPermission( permState );
311 if (String.Compare(className, classNameStart, "FileDialogPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
312 return new FileDialogPermission( permState );
318 // EnvironmentPermission
319 // UrlIdentityPermission
320 // GacIdentityPermission
321 if (className[classNameStart] == 'E')
323 if (String.Compare(className, classNameStart, "EnvironmentPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
324 return new EnvironmentPermission( permState );
328 else if (className[classNameStart] == 'U')
330 if (String.Compare(className, classNameStart, "UrlIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
331 return new UrlIdentityPermission( permState );
337 if (String.Compare(className, classNameStart, "GacIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
338 return new GacIdentityPermission( permState );
345 // SiteIdentityPermission
346 // ZoneIdentityPermission
347 // KeyContainerPermission
348 if (className[classNameStart] == 'S')
350 if (String.Compare(className, classNameStart, "SiteIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
351 return new SiteIdentityPermission( permState );
355 else if (className[classNameStart] == 'Z')
357 if (String.Compare(className, classNameStart, "ZoneIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
358 return new ZoneIdentityPermission( permState );
365 if (String.Compare(className, classNameStart, "KeyContainerPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
366 return new KeyContainerPermission( permState );
368 #endif // !FEATURE_PAL
374 // HostProtectionPermission
375 if (String.Compare(className, classNameStart, "HostProtectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
376 return new HostProtectionPermission( permState );
380 #if FEATURE_X509 && FEATURE_CAS_POLICY
382 // PublisherIdentityPermission
383 if (String.Compare(className, classNameStart, "PublisherIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
384 return new PublisherIdentityPermission( permState );
387 #endif // FEATURE_X509 && FEATURE_CAS_POLICY
390 // StrongNameIdentityPermission
391 if (String.Compare(className, classNameStart, "StrongNameIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
392 return new StrongNameIdentityPermission( permState );
397 // IsolatedStorageFilePermission
398 if (String.Compare(className, classNameStart, "IsolatedStorageFilePermission", 0, classNameLength, StringComparison.Ordinal) == 0)
399 return new IsolatedStorageFilePermission( permState );
409 Object[] objs = new Object[1];
412 Type permClass = null;
413 IPermission perm = null;
415 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
416 permClass = GetClassFromElement(el, ignoreTypeLoadFailures);
417 if (permClass == null)
419 if (!(typeof(IPermission).IsAssignableFrom(permClass)))
420 throw new ArgumentException( Environment.GetResourceString("Argument_NotAPermissionType") );
422 perm = (IPermission) Activator.CreateInstance(permClass, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null );
427 #if FEATURE_CAS_POLICY
428 #pragma warning disable 618 // CodeGroups are obsolete
429 [System.Security.SecuritySafeCritical] // auto-generated
430 public static CodeGroup
431 CreateCodeGroup (SecurityElement el)
433 if (el == null || !el.Tag.Equals("CodeGroup"))
434 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<CodeGroup>" ) ) ;
435 Contract.EndContractBlock();
441 if (!ParseElementForObjectCreation( el,
445 out classNameLength ))
450 switch (classNameLength)
454 if (String.Compare(className, classNameStart, "NetCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
455 return new NetCodeGroup();
461 if (String.Compare(className, classNameStart, "FileCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
462 return new FileCodeGroup();
467 if (String.Compare(className, classNameStart, "UnionCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
468 return new UnionCodeGroup();
473 // FirstMatchCodeGroup
474 if (String.Compare(className, classNameStart, "FirstMatchCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
475 return new FirstMatchCodeGroup();
484 Type groupClass = null;
485 CodeGroup group = null;
487 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
488 groupClass = GetClassFromElement(el, true);
489 if (groupClass == null)
491 if (!(typeof(CodeGroup).IsAssignableFrom(groupClass)))
492 throw new ArgumentException( Environment.GetResourceString("Argument_NotACodeGroupType") );
494 group = (CodeGroup) Activator.CreateInstance(groupClass, true);
496 Contract.Assert( groupClass.Module.Assembly != Assembly.GetExecutingAssembly(),
497 "This path should not get called for mscorlib based classes" );
501 #pragma warning restore 618
503 [System.Security.SecurityCritical] // auto-generated
504 internal static IMembershipCondition
505 CreateMembershipCondition( SecurityElement el )
507 if (el == null || !el.Tag.Equals("IMembershipCondition"))
508 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<IMembershipCondition>" ) ) ;
509 Contract.EndContractBlock();
515 if (!ParseElementForObjectCreation( el,
516 BuiltInMembershipCondition,
519 out classNameLength ))
524 // We have a built in membership condition, figure out which it is.
526 // Here's the list of built in membership conditions as of 9/17/2002
527 // System.Security.Policy.AllMembershipCondition
528 // System.Security.Policy.URLMembershipCondition
529 // System.Security.Policy.SHA1MembershipCondition
530 // System.Security.Policy.SiteMembershipCondition
531 // System.Security.Policy.ZoneMembershipCondition
532 // System.Security.Policy.PublisherMembershipCondition
533 // System.Security.Policy.StrongNameMembershipCondition
534 // System.Security.Policy.ApplicationMembershipCondition
535 // System.Security.Policy.DomainApplicationMembershipCondition
536 // System.Security.Policy.ApplicationDirectoryMembershipCondition
538 switch (classNameLength)
541 // AllMembershipCondition
542 // URLMembershipCondition
543 if (className[classNameStart] == 'A')
545 if (String.Compare(className, classNameStart, "AllMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
546 return new AllMembershipCondition();
552 if (String.Compare(className, classNameStart, "UrlMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
553 return new UrlMembershipCondition();
560 // HashMembershipCondition
561 // SiteMembershipCondition
562 // ZoneMembershipCondition
563 if (className[classNameStart] == 'H')
565 if (String.Compare(className, classNameStart, "HashMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
566 return new HashMembershipCondition();
570 else if (className[classNameStart] == 'S')
572 // SiteMembershipCondition
573 // ZoneMembershipCondition
574 if (className[classNameStart] == 'S')
575 #endif // !FEATURE_PAL
577 if (String.Compare(className, classNameStart, "SiteMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
578 return new SiteMembershipCondition();
584 if (String.Compare(className, classNameStart, "ZoneMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
585 return new ZoneMembershipCondition();
592 // PublisherMembershipCondition
593 if (String.Compare(className, classNameStart, "PublisherMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
594 return new PublisherMembershipCondition();
596 #endif // !FEATURE_PAL
600 // StrongNameMembershipCondition
601 if (String.Compare(className, classNameStart, "StrongNameMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
602 return new StrongNameMembershipCondition();
607 // ApplicationDirectoryMembershipCondition
608 if (String.Compare(className, classNameStart, "ApplicationDirectoryMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
609 return new ApplicationDirectoryMembershipCondition();
618 Type condClass = null;
619 IMembershipCondition cond = null;
621 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
622 condClass = GetClassFromElement(el, true);
623 if (condClass == null)
625 if (!(typeof(IMembershipCondition).IsAssignableFrom(condClass)))
626 throw new ArgumentException( Environment.GetResourceString("Argument_NotAMembershipCondition") );
628 cond = (IMembershipCondition) Activator.CreateInstance(condClass, true);
632 #endif //#if FEATURE_CAS_POLICY
634 GetClassFromElement (SecurityElement el, bool ignoreTypeLoadFailures)
636 String className = el.Attribute( "class" );
638 if (className == null)
640 if (ignoreTypeLoadFailures)
643 throw new ArgumentException( String.Format( null, Environment.GetResourceString("Argument_InvalidXMLMissingAttr"), "class") );
646 if (ignoreTypeLoadFailures)
650 return Type.GetType(className, false, false);
652 catch (SecurityException)
658 return Type.GetType(className, true, false);
662 IsPermissionElement (IPermission ip,
665 if (!el.Tag.Equals ("Permission") && !el.Tag.Equals ("IPermission"))
672 IsUnrestricted (SecurityElement el)
674 String sUnrestricted = el.Attribute( "Unrestricted" );
676 if (sUnrestricted == null)
679 return sUnrestricted.Equals( "true" ) || sUnrestricted.Equals( "TRUE" ) || sUnrestricted.Equals( "True" );
683 public static String BitFieldEnumToString( Type type, Object value )
685 int iValue = (int)value;
688 return Enum.GetName( type, 0 );
690 StringBuilder result = StringBuilderCache.Acquire();
694 for (int i = 1; i < 32; ++i)
696 if ((flag & iValue) != 0)
698 String sFlag = Enum.GetName( type, flag );
705 result.Append( ", " );
708 result.Append( sFlag );
715 return StringBuilderCache.GetStringAndRelease(result);