SECURITY

Programming Security Policy (part 1) - Programming Code Groups

6/12/2012 4:43:53 PM
The .NET security administration tools are sufficient for most users and security administrators to configure their security policy, but to have complete control over all security policy features, you must do so programmatically. As with evidence and permissions, .NET represents each of the security policy elements with classes, meaning that you can manipulate them in your own code very easily.

In the following sections, we provide explanations of how to program the key components of security policy, starting with code groups and membership conditions, then moving on to policy levels, and finally the security manager. We conclude with an example that brings together all elements of security policy programming; we demonstrate how to manipulate the policy of an application domain to control the policy resolution process applied to the assemblies loaded into it.

8.2.1. Programming Code Groups

The abstract System.Security.Policy.CodeGroup class provides the base representation of a code group and defines the functionality that lies at the heart of the policy resolution process. Four noninheritable subclasses extend CodeGroup to provide concrete implementations that you can use in security policy programming; these are shown in Figure 1.

Figure 1. Concrete subclasses of CodeGroup


Membership condition

An object that implements the System.Security.Policy.IMembershipCondition interface provides the functionality to determine whether an assembly or application domain qualifies for membership to the code group. You must specify the membership condition at CodeGroup instantiation but can change it later using the MembershipCondition property.


Policy statement

The policy statement contains values that specify the effect the CodeGroup has on assemblies and application domains that are members of the group. The System.Security.Policy.PolicyStatement class represents a code group's policy statement. It contains a value from the System.Security.Policy.PolicyStatementAttribute enumeration to represent the code group's attributes, and a System.Security.PermissionSet that specifies the set of permissions granted by the code group to its members.


Children

Each CodeGroup contains an ordered list of child CodeGroup objects. In turn, each child CodeGroup can have its own children, creating a tree structure. The Children property gets or sets the code group's children using a System.Collections.IList containing the set of child CodeGroup objects.

Figure 2. Structure of the CodeGroup class

The most important method of the CodeGroup class is Resolve, which takes an Evidence collection as an argument. Policy resolution of an assembly (or application domain) consists of the runtime calling the Resolve method on the root CodeGroup in each policy level and passing it the assembly's Evidence collection. In the Resolve method, the CodeGroup is responsible for determining if the assembly's evidence qualifies it for membership, how to apply any attributes, and how or if the CodeGroup should use its children to continue the policy resolution process. Resolve returns a PolicyStatement that represents the net effect of all code groups in the tree to which the assembly qualified for membership. The key difference between each of the CodeGroup subclasses is how they process the Resolve method:


UnionCodeGroup

This is the most commonly used code group type, which implements policy resolution. Members are tested against all child code groups for membership. The resulting PolicyStatement contains the union of the code group's permission set and the permission sets of each child of which the assembly is also a member. If a code group has the Exclusive attribute, the PolicyStatement will include only those permissions granted by that group.


FileCodeGroup

This operates the same as UnionCodeGroup with respect to matching members against its children and how the resulting PolicyStatement is calculated. However, FileCodeGroup does not support attributes and does not contain a statically defined permission set. With each call to Resolve, if the evidence of the assembly contains "file://"-based Url evidence, the FileCodeGroup dynamically generates a permission set that contains a System.Security.Permissions.FileIOPermission granting access to the directory specified in the Url evidence.


NetCodeGroup

This operates the same as FileCodeGroup, but with each call to Resolve, if the evidence of the assembly contains "http://" or "https://" Url (or Site) evidence, the NetCodeGroup dynamically generates a permission set that contains a System.Security.Permissions.WebPermission granting connect access to the specified web site. 


FirstMatchCodeGroup

This operates the same UnionCodeGroup but evaluates members against its children only until it finds the first matching child group. The resulting PolicyStatement contains the permission granted by the FirstMatchCodeGroup and at most one of its child groups; this makes the order of the child elements important.

As important as Resolve is to the runtime, both Resolve and the similar ResolveMatchingCodeGroups method provide minimal value when used directly. You cannot use them to drive the policy resolution process manually, and therefore they are useful only for testing and debugging. Table 1 summarizes the properties and methods of CodeGroup and highlights any special behavior implemented by the subclasses. No specific code-access permissions are required to use the members of the code group classes.

Table 1. Members of the code group classes
Member Description
Properties  
AttributeString Returns a String representing the code group's attributes. FileCodeGroup and NetCodeGroup do not use attributes and always return null (C#) or Nothing (Visual Basic .NET).
Children Gets or sets the code group's child code groups. The child CodeGroup elements are contained in an IList. For FirstMatchCodeGroup groups, the order of the children in the IList is important.
Description Gets or sets the description of the code group as a String.
MembershipCondition Gets or sets the membership condition for the code group using a System.Security.Policy.IMembershipCondition instance.
MergeLogic Returns a String that describes the logic used to merge the permissions of the code group and its children; returns "First Match" for FirstMatchCodeGroup and "Union" for the other three types of code groups.
Name Gets or sets the name of the code group using a String.
PermissionSetName Gets a String containing the name of the code group's permission set. This is null (C#) or Nothing (Visual Basic .NET) if the permission set does not have a name. The NetCodeGroup class always returns the name "Same site Web" and the FileCodeGroup always returns the name "Same directory FileIO-" appended with the type of file access granted.
PolicyStatement Gets or sets the PolicyStatement of the code group.
Methods  
AddChild Creates a copy of the specified CodeGroup and adds it to the end of the current list of children.
Copy Creates a deep copy of the CodeGroup, including all child code groups.
Equals Basic equality is determined by comparing the Name, Description, and MembershipCndition of two CodeGroup objects. It is also possible to force a comparison that includes all child code groups.
FromXml Reconstructs a CodeGroup from XML previously generated using the ToXml method.
RemoveChild Removes the specified CodeGroup from the list of immediate children.
Resolve Returns a PolicyStatement containing the permissions granted by the CodeGroup based on a specified Evidence collection. As discussed earlier, the type of code group determines how the permissions of child code groups affect the final PolicyStatement.
ResolveMatchingCodeGroups Returns a CodeGroup tree containing all of the child code groups to which a specified Evidence collection qualifies for membership. The type of code group determines the set of child code groups contained in the final collection.
ToXml Returns a SecurityElement containing the XML object model for the CodeGroup. ToXml is useful for writing the contents of a code group to an XML file so that you can import it when using the administrative tools.

Before demonstrating the creation and manipulation of code groups, we provide details of membership conditions and policy statements.

1.1. Programming membership conditions

Membership conditions are classes that implement the IMembershipCondition interface. All four types of code group contain a single IMembershipCondition instance that you must specify as an argument to the code group's constructor; you can get and set the IMembershipCondition through the CodeGroup.MembershipCondition property after construction.

The IMembershipCondition interface defines a method named Check, which takes an Evidence collection argument and returns a Boolean value indicating whether the values of the contained evidence objects satisfy a configurable condition:

# C#

bool Check(Evidence evidence);

# Visual Basic .NET

Function Check(ByVal evidence As Evidence) As Boolean

A CodeGroup calls the Check method of its IMembershipCondtion during policy resolution to evaluate whether an assembly or application domain qualifies for membership to the code group.

The .NET Framework includes the eight standard membership condition classes listed in Table 2; all are members of the System.Security.Policy namespace. Seven of these classes contain the logic necessary to test the values of standard evidence classes. One additional membership condition class, named AllMembershipCondition always returns true when Check is called, regardless of the evidence provided. This means a code group using AllMembershipCondition as its membership condition will contain all assemblies and application domains tested against it.

Table 2. Standard membership condition classes
Membership class Membership condition
AllMembershipCondition All code irrespective of evidence.
ApplicationDirectoryMembershipCondition Evidence collection contains both ApplicationDirectory and Url evidence. The Url evidence represents a location that is a child of that represented by the ApplicationDirectory evidence.
HashMembershipCondition Evidence collection contains a Hash class with the specified hash value.
PublisherMembershipCondition Evidence collection contains a Publisher class with the specified publisher certificate.
SiteMembershipCondition Evidence collection contains a Site class with the specified site name.
StrongNameMembershipCondition Evidence collection contains a StrongName class with the specified hash value.
UrlMembershipCondition Evidence collection contains a Url class with the specified URL location.
ZoneMembershipCondition Evidence collection contains a Zone class with the specified security zone.

The constructors for each type of membership condition vary depending on the evidence types they evaluate, but all of them are relatively straightforward to use if you understand the standard evidence types. You should consult the .NET Framework SDK documentation for complete details, but here are some examples of how to create membership conditions:

# C#

// Create a membership condition to match all code.
IMembershipCondition m1 = new AllMembershipCondition(  );

// Create a membership condition to match all code with
// Internet Zone evidence.
IMembershipCondition m2 = 
    new ZoneMembershipCondition(SecurityZone.Internet);

// Create a membership condition to match all code from
// all "oreilly.com" Sites.
IMembershipCondition m3 = 
    new SiteMembershipCondition("*.oreilly.com");

// Create a membership condition to match all code with
// the same Publisher certificate as was used to sign
// the SomeFile.exe assembly.
IMembershipCondition m4 = 
    new PublisherMembershipCondition(
        X509Certificate.CreateFromSignedFile("SomeFile.exe")
    );

# Visual Basic .NET

' Create a membership condition to match all code.
Dim m1 As IMembershipCondition =  New AllMembershipCondition(  ) 
 
' Create a membership condition to match all code with
' Internet Zone evidence.
Dim m2 As IMembershipCondition =  _
New ZoneMembershipCondition(SecurityZone.Internet) 
 
' Create a membership condition to match all code from
' all "oreilly.com" Sites.
Dim m3 As IMembershipCondition = _
New SiteMembershipCondition("*.oreilly.com")

' Create a membership condition to match all code with
' the same Publisher certificate as was used to sign
' the SomeFile.exe assembly.
Dim m4 As IMembershipCondition =  _
New PublisherMembershipCondition( _
X509Certificate.CreateFromSignedFile("SomeFile.exe"))

					  

1.2. Programming policy statements

For the UnionCodeGroup and FirstMatchCodeGroup classes, a PolicyStatement class represents the effect the code group has on its members, including the code group's attributes and its permission set. The FileCodeGroup and NetCodeGroup classes do not require you to set a policy statement, because they generate their permission sets dynamically and do not support attributes.

Provide a PolicyStatement as an argument to the UnionCodeGroup and FirstMatchCodeGroup constructors, and you can get and set the PolicyStatement after construction through the CodeGroup.PolicyStatement property.

The PolicyStatement class provides two constructors. The first takes a System.Security.PermissionSet argument specifying the permissions a code group grants to its members. The second constructor takes both a PermissionSet and a member of the System.Security.Policy.PolicyStatementAttribute enumeration, representing the code group's set of attributes. We list the possible values of PolicyStatementAttribute in Table 3.

Table 3. Members of the PolicyStatementAttribute enumeration
Member Description
All The code group has both the Exclusive and LevelFinal attributes
Exclusive The code group has only the Exclusive attribute. See "Code Group Attributes" for details
LevelFinal The code group has only the LevelFinal attribute. See "Code Group Attributes" for details
Nothing The code group has no attributes

The properties listed in Table 4 provide access to the content of the PolicyStatement after instantiation.

Table 4. Properties of PolicyStatement
Property Description
Attributes Gets or sets the attributes contained in the policy statement as a member of the PolicyStatementAttribute enumeration.
AttributeString Gets a human-readable String representing the attributes contained in the PolicyStatement.
PermissionSet Gets or sets the permission contained in the PolicyStatement as a PermissionSet.

The following examples demonstrate how to create PolicyStatement objects. 

# C#

// Create a PolicyStatement that grants Unrestricted access 
// to everything
PolicyStatement p1 = new PolicyStatement(
    new PermissionSet(PermissionState.Unrestricted)
);

// Create a PolicyStatement that grants read access to the 
// file "C:\File.txt" and specifies the LevelFinal attribute.
PermissionSet pset = new PermissionSet(
    new FileIOPermission(FileIOPermissionAccess.Read,@"C:\File.txt"));
PolicyStatement p2 = new PolicyStatement(
    pset, PolicyStatementAttribute.LevelFinal);
        
# Visual Basic .NET

' Create a PolicyStatement that grants Unrestricted access 
' to everything
Dim p1 As PolicyStatement =  New PolicyStatement( _
New PermissionSet(PermissionState.Unrestricted)) 
 
' Create a PolicyStatement that grants read access to the 
' file "C:\File.txt" and specifies the LevelFinal attribute.
Dim pset As PermissionSet = New PermissionSet( _
New FileIOPermission(FileIOPermissionAccess.Read,"C:\File.txt"))  

Dim p2 As PolicyStatement = New PolicyStatement _
(pset,PolicyStatementAttribute.LevelFinal)

					  

1.3. Creating code groups

With the knowledge of how to create policy statements and membership conditions, creating code groups is straightforward. You create UnionCodeGroup and FirstMatchCodeGroup objects by providing an IMembershipCondition and a PolicyStatement as constructor arguments. The following example creates a UnionCodeGroup with the Exclusive attribute that matches all code downloaded from any web site in the oreilly.com domain and grants it unrestricted access to the filesystem:

# C# 

// Create the permission set and add unrestricted file access.
PermissionSet pset = new PermissionSet(PermissionState.None);
pset.AddPermission(new FileIOPermission(PermissionState.Unrestricted));

// Create the policy statement and set the Exclusive attribute.
PolicyStatement pstate = 
    new PolicyStatement(pset, PolicyStatementAttribute.Exclusive);

// Create the membership condition to match all "*.oreilly.com" sites.
IMembershipCondition mcon = 
    new SiteMembershipCondition("*.oreilly.com");

// Create the UnionCodeGroup
UnionCodeGroup cg = new UnionCodeGroup(mcon, pstate);

# Visual Basic .NET

' Create the permission set and add unrestricted file access.
Dim pset As PermissionSet = New PermissionSet(PermissionState.None) 
pset.AddPermission(New FileIOPermission(PermissionState.Unrestricted))
 
' Create the policy statement and set the Exclusive attribute.
Dim pstate As PolicyStatement = _
New PolicyStatement(pset, PolicyStatementAttribute.Exclusive) 
 
' Create the membership condition to match all "*.oreilly.com" sites.
Dim mcon As IMembershipCondition = _
New SiteMembershipCondition("*.oreilly.com") 
 
' Create the UnionCodeGroup
Dim cg As UnionCodeGroup = New UnionCodeGroup(mcon,pstate)

					  

The NetCodeGroup class constructor takes only an IMembershipCondition, because it calculates dynamically its permission set and does not support attributes; therefore, there is no need for a PolicyStatement. The following example creates a NetCodeGroup that allows all code signed with the publisher certificate contained in the Publisher.cer file to connect back to the web site from where it is loaded.

# C# 

NetCodeGroup cg = new NetCodeGroup(
    new PublisherMembershipCondition(
        X509Certificate.CreateFromCerFile("Publisher.cer")
    ));

# Visual Basic .NET

Dim cg As NetCodeGroup = New NetCodeGroup( _
New PublisherMembershipCondition( _
X509Certificate.CreateFromCerFile("Publisher.cer")))

The FileCodeGroup constructor takes an IMembershipCondition and a System.Security.Permissions.FileIOPermissionAccess argument. The FileIOPermissionAccess specifies the type of file access permission the FileCodeGroup should include in its dynamically generated permission set; see Table 5 for possible values. 

Table 5. Members of the FileIOPermissionAccess enumeration
Property Description
AllAccess All access
Append Access to append content to an existing file or directory
NoAccess No access
PathDiscovery Access to the information contained in the path of a directory or file
Read Access to read from a file or directory
Write Access to write to a file or directory, including overwriting and deleting existing files and directories

The following code creates a FileCodeGroup that allows all code signed with the publisher certificate contained in the Publisher.cer file to write to the directory from which it was loaded:

# C# 

FileCodeGroup cg = new FileCodeGroup(
    new PublisherMembershipCondition(
        X509Certificate.CreateFromCertFile("Publisher.cer")),
    FileIOPermissionAccess.Write
);

# Visual Basic .NET

Dim cg As FileCodeGroup = New FileCodeGroup( _
New PublisherMembershipCondition( _
X509Certificate.CreateFromCertFile("Publisher.cer")),
FileIOPermissionAccess.Write)
Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8