The Policy Manager in the CLR performs a number of functions by using the evidence supplied to it. Essentially, the Policy Manager takes this evidence and produces a set of permissions. As shown in Figure 4.3, it includes four policy levels:
Figure 4.3. Role of the Policy Manager under the CLR
Each level normally produces a permission set based on the evidence. These permission sets are then "intersected" to generate the permission set for the entire assembly. As a consequence, all levels must allow a permission before it can enter the assembly's granted permission set. For example, if the Enterprise policy level does not grant a permission, regardless of what the other levels specify, that permission will not be granted. Sometimes, however, a policy may direct the security system to not evaluate lower policy levels. This flexibility provides a means to allow a higher policy level, such as the Enterprise policy level, to effectively override subordinate levels. Each policy level within the security system has a similar architecture. Each level consists of three parts :
Code GroupsA code group consists of a conditional expression and a permission set. If an assembly satisfies the conditional expression, then it is granted the permission set. The set of code groups for each policy level is arranged into a tree structure. Every time a conditional expression evaluates to true, the permission set is granted and the traversal of that branch continues. Whenever a condition evaluates to false, the permission set is not granted and that branch is not examined further. As an example, consider the tree of code groups shown in Figure 4.4. Figure 4.4. A tree of code groups
Assume you have an assembly with the following evidence: It came from www.project42.net and, because it came from the JJJLK product group, it has a strong name of JJJLK. The code group tree traversal may proceed as follows :
Eventually, the conditions satisfied and the granted permission sets would include the following:
Inspection of the policy level code group is fairly simple. It is stored as XML in a well-known location. For example, the Enterprise policy is found at a location such as the following: C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\CONFIG\enter prisesec.config It looks like the following, again edited for brevity: <?xml version="1.0" encoding="utf-8" ?> <configuration> <mscorlib> <security> <policy> <PolicyLevel version="1"> <SecurityClasses> <SecurityClass Name="StrongNameMembershipCondition" Description= "System.Policy.StrongNameMembershipCondition, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> ... </SecurityClasses> <NamedPermissionSets> <PermissionSet class="NamedPermissionSet" version="1" Unrestricted="true" Name="FullTrust" Description="Allows full access to all resources"/> <PermissionSet class="NamedPermissionSet" version="1" Name="LocalIntranet" Description="Default rights...local intranet"> <IPermission class="EnvironmentPermission" version="1" Read="USERNAME"/> <IPermission class="FileDialogPermission" version="1" Unrestricted="true"/> ... <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="All_Code" Description="Code ... of the code group tree."> <IMembershipCondition class="AllMembershipCondition" version="1"/> </CodeGroup> ... <FullTrustAssemblies> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00000000000000000400000000000000" Name="mscorlib.resources" AssemblyVersion="1.0.3300.0"/> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00000000000000000400000000000000" Name="System" AssemblyVersion="1.0.3300.0"/> </FullTrustAssemblies> </PolicyLevel> </policy> </security> </mscorlib> </configuration> Administrators can edit the XML directly to modify the default policy. In addition, a Microsoft Management Console snap-in provides a visual interface for changing these settings. Named Permission SetsA policy level contains a list of named permission sets; the code groups may assign these sets to code that satisfy various code group conditions. Examples of predefined permission sets include the following:
Policy AssembliesDuring security evaluation, other assemblies may need to be loaded for use in the policy evaluation process. Such assemblies may, for example, contain user-defined permission classes. Of course, if these assemblies also need to be evaluated and they refer to other assemblies, a circular dependency could result. To avoid this problem, each assembly contains a list of trusted assemblies that it needs for policy evaluation. This list of required assemblies is naturally referred to as the list of "policy assemblies." Examining Policy Levels and Permission SetsListing 4.6 displays the policy levels and permission set for an application. The application is a C# program run from the local disk, so it receives a fairly powerful permission set. Listing 4.6 Examining the policy levels and permission set for a C# programusing System; using System.Collections; using System.Security; using System.Security.Policy; namespace SecurityResolver { class Sample { static void Main(string[] args) { IEnumerator i = SecurityManager.PolicyHierarchy(); while(i.MoveNext()) { PolicyLevel p = (PolicyLevel) i.Current; Console.WriteLine(p.Label); IEnumerator np = p.NamedPermissionSets.GetEnumerator(); while (np.MoveNext()) { NamedPermissionSet pset = (NamedPermissionSet)np.Current; Console.WriteLine( "\tPSet: \n\t\t Name: {0} \n\t\t Description {1}", pset.Name, pset.Description); } } } } } The output of the program is shown below. It has been edited for brevity. Enterprise PSet: Name: FullTrust Description: Allows full access to all resources ... PSet: Name: LocalIntranet Description: Default rights given to applications on your local intranet ... Machine ... PSet: Name: Nothing Description: Denies all resources, including the right to execute ... User ... Name: SkipVerification Description: Grants right to bypass the verification PSet: Name: Execution Description: Permits execution ... |