[ Team LiB ] |
6.2 Programming EvidenceIn the normal course of application development, you have little need to work directly with evidence; the default evidence supplied by the runtime is sufficient to correctly drive the policy resolution process. If you do need to base runtime decisions on the evidence of an assembly, you'll most likely do so using identity permissions. In the following sections, we show you how to use the advanced .NET support for directly manipulating evidence, which you will need when performing any of the following tasks:
6.2.1 Introduction to Evidence ProgrammingThe runtime establishes the identity and grant set of an assembly when the assembly is loaded. You cannot alter the identity of an already loaded assembly to change the permissions granted to it. Therefore, you must provide all evidence at the time you load the assembly. Note that the runtime loads each assembly only once into a given application domain. Subsequent load requests result in the runtime using the already loaded assembly. If you try to reload an already loaded assembly but alter its identity by specifying additional items of evidence, the runtime will throw a System.IO.FileLoadException.
If you do not have the ControlEvidence permission, the runtime will throw a System.Security.SecurityException when you try to load the assembly. You can use permission requests to ensure that the runtime will not attempt to execute your code unless it has the ControlEvidence permission, or you can simply attempt to load your assembly and be prepared to handle the SecurityException that will occur if you do not have it. In order to provide your evidence, you must create the set of evidence objects and add them to a System.Security.Policy.Evidence collection. You then pass the Evidence collection as an argument to the method that loads the assembly. Your evidence takes precedence over the default evidence provided by the assembly loader. When specifying the evidence, you can provide both host and assembly evidence. However, given the limitations of assembly evidence outlined earlier in Section 6.1.1, there is little value in providing anything but host evidence, and so that is where we will focus our discussions. You can add as many evidence types as you want to the Evidence collection, but only the last one of each type affects the policy resolution process. If we add two pieces of Url evidence to an Evidence collection, the first being http://www.oreilly.com and the second being http://www.somecompany.com, then the permissions for the assembly will be based on the http://www.somecompany.com evidence. 6.2.2 Using the Evidence ClassThe System.Security.Policy.Evidence class is a specialized collection that contains two sets of evidence objects: a collection of host evidence and a collection of assembly evidence. The Evidence class has three constructors, as shown in the following declarations: # C# public Evidence( ); public Evidence(Evidence evidence); public Evidence( object[] hostEvidence, object[] assemblyEvidence ); # Visual Basic .NET Public Sub New( ) Public Sub New(ByVal evidence As Evidence) Public Sub New( ByVal hostEvidence( ) As Object, _ ByVal assemblyEvidence( ) As Object _ ) The first constructor creates an empty Evidence object. The second constructor takes an existing Evidence object and makes a copy of it. Note that this is a shallow copy, meaning that the new Evidence collection references the same evidence objects contained in the source Evidence collection; no new evidence objects are created. This is not an issue when using the standard evidence types because they are immutable. The third constructor takes two Object arrays: the hostEvidence argument contains the evidence objects for the host evidence collection and the assemblyEvidence argument contains the evidence objects for the assembly evidence collection. The Evidence class implements the System.Collections.ICollection collection to facilitate the manipulation of the evidence objects it contains. In addition, Evidence implements members that support direct manipulation of the host and assembly evidence subcollections. Figure 6-2 illustrates the structure of the Evidence class and shows the key methods you use to work with contained evidence elements. Figure 6-2. Structure of the Evidence classTable 6-2 summarizes the members of the Evidence class; the members that require your code to have the ControlEvidence permission are indicated in the far right column titled "C".
6.2.3 Using the Standard Evidence ClassesThe evidence objects you will most commonly use to define the identity of your assemblies are the seven standard evidence classes from the System.Security.Policy namespace:
Each of these classes is relatively simple and independent; they do not extend a common base class (other than System.Object), nor do they implement a common interface. However, their designs all follow a similar pattern, resulting in the following commonalities:
The following sections discuss each of the evidence classes in detail and demonstrate how to use them. 6.2.3.1 The ApplicationDirectory classThe System.Security.Policy.ApplicationDirectory class contains a URL that represents the root installation directory of an application. ApplicationDirectory evidence is unique amongst the standard evidence classes in that the runtime does not evaluate it in isolation. If an assembly has ApplicationDirectory evidence, the runtime also looks for Url evidence to determine if the Url evidence represents a child location specified in the ApplicationDirectory evidence. This will become clearer when we discuss membership conditions and policy resolution in Chapter 8. The ApplicationDirectory class constructor shown takes a System.String argument specifying the URL of the application root: # C# public ApplicationDirectory(String name); # Visual Basic .NET Public Sub New(ByVal name As String) The read-only Directory property returns the URL string used in construction. 6.2.3.2 The Hash classThe System.Security.Policy.Hash class provides evidence based on a hash value of an assembly. A hash is a numeric value calculated using cryptographic algorithms that take the bytes contained in the assembly file as input. The nature of hashing algorithms means that it is very unlikely for the contents of two assemblies to result in the same hash value; even changing a single bit will result in a very different hash value. This means that a hash value provides a unique identity for an assembly (similar to a fingerprint). You can use a hash value to distinguish between two different assemblies, but by itself, a hash does not guarantee the source or integrity of an assembly; this is the purpose of strong names and publisher certificates (see Chapter 2). We provide a detailed discussion of hashing in Chapter 13. The Hash class is different from other evidence classes in that it provides multiple evidence values (hash values) from a single set of source data. The Hash class constructor takes a System.Reflection.Assembly object that identifies the assembly from which to generate hash values: # C# public Hash(Assembly assembly); # Visual Basic .NET Public Sub New(ByVal assembly as Assembly) By default, the Hash class supports two hashing algorithms: MD5 and SHA1. The read-only MD5 property returns an MD5 hash value based on the assembly content, and the read-only SHA1 property does the same but using the SHA1 algorithm. In addition, the GenerateHash method allows you to compute an assembly's hash using other hashing algorithms. The GenerateHash method takes a System.Security.Cryptography.HashAlgorithm argument containing an object that implements the required hashing algorithm. There are a number of hashing-algorithm implementations provided in the .NET class library (see Chapter 13). The following code demonstrates the use of Hash to calculate the MD5, SHA1, and SHA512 hash values for an assembly. We use the System.Security.Cryptography.SHA512Managed class to provide the SHA512 hashing implementation: # C# using System.Reflection; using System.Security.Policy; using System.Security.Cryptography; public class HashEvidenceDemo { public static void Main( ) { // Create a new Hash object for the currently executing // assembly. Hash hashEvidence = new Hash(Assembly.GetExecutingAssembly( )); // Use the Hash class to generate hash values for // the current assembly byte[] md5 = hashEvidence.MD5; byte[] sha1 = hashEvidence.SHA1; byte[] sha512 = hashEvidence.GenerateHash(new SHA512Managed( )); } } # Visual Basic .NET Imports System.Security.Policy Imports System.Security.Cryptography Public Class HashEvidenceDemo Public Shared Sub Main( ) ' Create a new Hash object for the currently executing ' assembly. Use fully qualifed name of Assembly class ' to avoid conflict with Visual Basic .NET keyword. Dim hashEvidence As Hash = _ New Hash(System.Reflection.Assembly.GetExecutingAssembly( )) ' Use the Hash class to generate hash values for ' the current assembly Dim md5( ) As Byte = hashEvidence.MD5 Dim sha1( ) As Byte = hashEvidence.SHA1 Dim sha512( ) As Byte = _ hashEvidence.GenerateHash(New SHA512Managed( )) End Sub End Class
6.2.3.3 The Publisher classThe System.Security.Policy.Publisher class provides evidence based on the Authenticode X.509 v3 digital certificate used to sign an assembly. The publisher (producer, author, or creator) of an assembly signs it to prove to consumers that they created the assembly. We discuss signing assemblies in Chapter 2.
The Publisher class constructor shown here takes a System.Security.Cryptography.X509Certificates.X509Certificate object that contains the publisher's code-signing certificate. There are many simple ways to create an X509Certificate object, including loading it from a certificate file or extracting it from an existing signed file; refer to the .NET Framework SDK documentation for details: # C# public Publisher (X509Certificate cert); # Visual Basic .NET Public Sub New(ByVal cert As X509Certificate) The read-only Certificate property returns the X509Certificate object provided during creation. The following code demonstrates the creation of Publisher evidence using an X509 certificate contained in a certificate file named C:\MyCert.cer and displays the certificate principal using the GetName( ) method of the X509Certificate object retrieved via the Certificate property: # C# using System; using System.Security.Policy; using System.Security.Cryptography.X509Certificates; public class PublisherEvidenceDemo { public static void Main( ) { // Create a new X509Certificate object from the // test certificate file C:\MyCert.cer. X509Certificate cert = X509Certificate.CreateFromCertFile(@"C:\MyCert.cer"); // Create a new Publisher evidence object from the // loaded X509Certificate object Publisher publisherEvidence = new Publisher(cert); // Use the Certificate property to get the publisher // certificate and display the principal name. Console.WriteLine(publisherEvidence.Certificate.GetName( )); } } # Visual Basic .NET Imports System Imports System.Security.Policy Imports System.Security.Cryptography.X509Certificates Public Class PublisherEvidenceDemo Public Shared Sub Main( ) ' Create a new X509Certificate object from the ' test certificate file C:\MyCert.cer. Dim cert As X509Certificate = _ X509Certificate.CreateFromCertFile("C:\MyCert.cer") ' Create a new Publisher evidence object from the ' loaded X509Certificate object Dim publisherEvidence As Publisher = New Publisher(cert) ' Use the Certificate property to get the publisher ' certificate and display the principal name. Console.WriteLine(publisherEvidence.Certificate.GetName( )) End Sub End Class 6.2.3.4 The Site classThe System.Security.Policy.Site class provides evidence based on the fully qualified host name portion of the URL from where the assembly was loaded (for example, the site from the URL https://www.somecompany.com:8080/dev/HelloWorld.exe is www.somecompany.com).
The Site class constructor shown takes a System.String argument containing the name of the site to use as evidence. After construction, the site name is available through the read-only Name property: # C# public Publisher (string name); # Visual Basic .NET Public Sub New(ByVal name As String) The Site class also provides the static CreateFromUrl factory method to simplify the creation of Site objects from URL strings. The value of siteEvidence.Name in the following example is www.somecompany.com: # C# String url = "https://www.somecompany.com:8080/dev/HelloWorld.exe"; Site siteEvidence = Site.CreateFromUrl(url); # Visual Basic.NET Dim url As String = "https://www.somecompany.com:8080/dev/HelloWorld.exe" Dim siteEvidence As Site = Site.CreateFromUrl(url) The runtime does not provide Site evidence for assemblies loaded from file protocol URLs such as file://C:\Dev\HelloWorld.exe. CreateFromUrl will actually throw a System.ArgumentException if you pass it such a URL. 6.2.3.5 The StrongName classThe System.Security.Policy.StrongName class provides evidence based on the strong name of an assembly. A strong name provides the assembly with a unique versioned identity and is a guarantee of the integrity of an assembly. However, a strong name does not guarantee the integrity of the source of an assembly, which is the purpose of publisher certificates. We discuss assembly strong names and publisher certificates in Chapter 2.
The StrongName class constructor takes three arguments:
Each of the arguments provided during construction is available through the read-only Name, PublicKey, and Version properties of the StrongName class. To obtain the strong-name information required to create a StrongName object you can use the Secutil tool (Secutil.exe) to extract the public key, name, and version from a strong-named assembly. There is no simple way to extract this information using the .NET class library. The following command will extract the strong-name information from the assembly HelloWorld.exe and write it to the strongname.txt file in a format that you can easily incorporate into your program: secutil -array -cmode -strongname HelloWorld.exe > strongname.txt The contents of strongname.txt will look something like this: Microsoft (R) .NET Framework SecUtil 1.0.3705.0 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Public Key = { 0, 36, 0, 0, 4, 128, 0, 0, 148, 0, 0, 0, 6, 2, 0, 0, 0, 36, 0, 0, 82, 83, 65, 49, 0, 4, 0, 0, 1, 0, 1, 0, 169, 206, 164, 8, 66, 197, 231, 138, 148, 74, 99, 125, 171, 203, 120, 143, 240, 155, 104, 138, 4, 123, 15, 55, 85, 255, 183, 20, 111, 10, 217, 58, 127, 15, 236, 86, 16, 121, 222, 35, 161, 14, 122, 246, 85, 226, 162, 221, 46, 215, 161, 151, 183, 38, 31, 150, 198, 119, 109, 94, 11, 65, 208, 33, 122, 172, 106, 62, 192, 4, 35, 255, 220, 10, 43, 90, 92, 183, 29, 136, 57, 235, 30, 5, 127, 72, 210, 108, 215, 226, 65, 197, 184, 28, 129, 184, 191, 211, 159, 69, 8, 84, 116, 65, 186, 179, 35, 116, 174, 223, 167, 217, 116, 8, 178, 232, 213, 155, 172, 87, 181, 187, 61, 43, 133, 105, 10, 187 } Name = HelloWorld Version = 1.1578.0.0 Success With the strong-name information extracted by Secutil, it is a simple matter to create StrongName evidence, as shown below: # C# using System; using System.Security.Policy; using System.Security.Permissions; public class StrongNameEvidenceDemo { // Create a byte array containing the strong name public key // data. static byte[] publickey = { 0, 36, 0, 0, 4, 128, 0, 0, 148, 0, 0, 0, 6, 2, 0, 0, 0, 36, 0, 0, 82, 83, 65, 49, 0, 4, 0, 0, 1, 0, 1, 0, 169, 206, 164, 8, 66, 197, 231, 138, 148, 74, 99, 125, 171, 203, 120, 143, 240, 155, 104, 138, 4, 123, 15, 55, 85, 255, 183, 20, 111, 10, 217, 58, 127, 15, 236, 86, 16, 121, 222, 35, 161, 14, 122, 246, 85, 226, 162, 221, 46, 215, 161, 151, 183, 38, 31, 150, 198, 119, 109, 94, 11, 65, 208, 33, 122, 172, 106, 62, 192, 4, 35, 255, 220, 10, 43, 90, 92, 183, 29, 136, 57, 235, 30, 5, 127, 72, 210, 108, 215, 226, 65, 197, 184, 28, 129, 184, 191, 211, 159, 69, 8, 84, 116, 65, 186, 179, 35, 116, 174, 223, 167, 217, 116, 8, 178, 232, 213, 155, 172, 87, 181, 187, 61, 43, 133, 105, 10, 187 }; public static void Main( ) { // Create a StrongNamePublicKeyBlob object from the // publickey byte array. StrongNamePublicKeyBlob blob = new StrongNamePublicKeyBlob(publickey); // Create a Version object based on the assembly version // number Version version = new Version("1.1578.0.0"); // Create the new StrongName evidence object StrongName sn = new StrongName(blob, "HelloWorld", version); } } # Visual Basic .NET Imports System Imports System.Security.Policy Imports System.Security.Permissions Public Class StrongNameEvidenceDemo ' Create a byte array containing the strong name public key ' data. Shared publickey( ) As Byte = { 0, 36, 0, 0, 4, 128, 0, 0, 148, _ 0, 0, 0, 6, 2, 0, 0, 0, 36, 0, 0, 82, 83, 65, 49, 0, 4, 0, _ 0, 1, 0, 1, 0, 169, 206, 164, 8, 66, 197, 231, 138, 148, 74, _ 99, 125, 171, 203, 120, 143, 240, 155, 104, 138, 4, 123, 15, _ 55, 85, 255, 183, 20, 111, 10, 217, 58, 127, 15, 236, 86, 16, _ 121, 222, 35, 161, 14, 122, 246, 85, 226, 162, 221, 46, 215, _ 161, 151, 183, 38, 31, 150, 198, 119, 109, 94, 11, 65, 208, _ 33, 122, 172, 106, 62, 192, 4, 35, 255, 220, 10, 43, 90, 92, _ 183, 29, 136, 57, 235, 30, 5, 127, 72, 210, 108, 215, 226, 65, _ 197, 184, 28, 129, 184, 191, 211, 159, 69, 8, 84, 116, 65, 186, _ 179, 35, 116, 174, 223, 167, 217, 116, 8, 178, 232, 213, 155, _ 172, 87, 181, 187, 61, 43, 133, 105, 10, 187} Public Shared Sub Main( ) ' Create a StrongNamePublicKeyBlob object from the ' publickey byte array. Dim blob As StrongNamePublicKeyBlob = _ New StrongNamePublicKeyBlob(publickey) ' Create a Version object based on the assembly version ' number Dim version As Version = New Version("1.1578.0.0") ' Create the new StrongName evidence object Dim sn As StrongName = New StrongName(blob,"HelloWorld",version) End Sub End Class 6.2.3.6 The Url classThe System.Security.Policy.Url class provides evidence based on the URL from where an assembly was loaded. If the assembly is loaded using a file path on the local machine, the Url evidence contains a file:// protocol URL; other possibilities are http:// and https:// if the assembly was loaded from a web site.
The Url class constructor shown takes a System.String argument specifying the URL from where the assembly was loaded: # C# public Url(String name); # Visual Basic .NET Public Sub New(ByVal name As String) The Url constructor performs some validation on the URL string to ensure that file://-based URLs are correctly formatted but does not limit the scope of the protocol you can use. The read-only Value property returns the URL string used in construction. 6.2.3.7 The Zone classThe System.Security.Policy.Zone class provides evidence based on the Internet Explorer security zone from where an assembly was loaded. The runtime maps the URL of an assembly against the Internet Explorer zone configuration to determine the type of Zone evidence to create.
The Zone class constructor shown below takes as an argument a member of the System.Security.SecurityZone enumeration which specifies the type of Zone evidence to create; we list the possible values in Table 6-3. The read-only SecurityZone property returns the SecurityZone member specified during construction: # C# public Zone (SecurityZone zone); # Visual Basic .NET Public Sub New(ByVal zone As SecurityZone)
The Zone class also provides the static CreateFromUrl factory method to simplify the creation of Zone objects from URL strings. When you call CreateFromUrl the runtime maps the specified URL against the Internet Explorer zone configuration and returns the appropriate Zone object. The following code demonstrates how to create Zone evidence representing the Trusted zone, as well as how to create a zone from the URL https://www.somecompany.com:8080/dev/HelloWorld.exe: # C# String url = "https://www.somecompany.com:8080/dev/HelloWorld.exe"; Zone z1 = Zone.CreateFromUrl(url); Zone z2 = new Zone(SecurityZone.Trusted); # Visual Basic.NET Dim url As String = "https://www.somecompany.com:8080/dev/HelloWorld.exe" Dim z1 As Zone = Zone.CreateFromUrl(url) Dim z2 As Zone = New Zone(SecurityZone.Trusted) 6.2.4 Viewing EvidenceThe ability to view an assembly's evidence is extremely useful when debugging CAS-related programming issues and will help you to understand the concepts discussed previously. The System.Reflection.Assembly and System.AppDomain classes have read-only Evidence properties that contain the evidence CAS used during policy resolution to determine the assembly's or application domain's permissions. The Evidence property is read-only because, as we described earlier, you can only assign evidence when you load an assembly or create an application domain.
It is unlikely that you will need to use an evidence in order to make security decisions at runtime. Most of the standard evidence classes result in the inclusion of an appropriate identity permission in the grant set of the assembly. Identity permissions, which we discuss in Chapter 7, are tightly integrated with the CAS framework and allow you to base security decisions on the identity of an assembly. Example 6-1 shows how to display an assembly's evidence, using a class named LoadAndList, which you should build into an executable named LoadAndList.exe. The LoadAndList class takes the name of an assembly as a command-line argument, loads the specified assembly, and lists the assembly's host and assembly evidence to the console. The LoadAndList class uses the Assembly.Evidence property to get the assembly's evidence and uses two loops to enumerate first the host and then the assembly evidence: Example 6-1. Displaying an assembly's evidence# C# using System; using System.Reflection; using System.Collections; using System.Security.Policy; public class LoadAndList { public static void Main(string[] args) { // Load the specified assembly Assembly a = Assembly.LoadFrom(args[0]); // Get the Evidence collection from the // loaded assembly Evidence e = a.Evidence; // Display the Host Evidence IEnumerator x = e.GetHostEnumerator( ); Console.WriteLine("HOST EVIDENCE:"); while(x.MoveNext( )) { Console.WriteLine(x.Current.ToString( )); } // Display the Assembly Evidence x = e.GetAssemblyEnumerator( ); Console.WriteLine("ASSEMBLY EVIDENCE:"); while(x.MoveNext( )) { Console.WriteLine(x.Current.ToString( )); } } } # Visual Basic .NET Imports System Imports System.Collections Imports System.Security.Policy Public Class LoadAndList Public Shared Sub Main(ByVal args( ) As String) ' Load the specified assembly Dim a As System.Reflection.Assembly = _ System.Reflection.Assembly.LoadFrom(args(0)) ' Get the Evidence collection from the ' loaded assembly Dim e As Evidence = a.Evidence ' Display the Host Evidence Dim x As IEnumerator = e.GetHostEnumerator( ) Console.WriteLine("HOST EVIDENCE:") While x.MoveNext( ) Console.WriteLine(x.Current.ToString( )) End While ' Display the Assembly Evidence x = e.GetAssemblyEnumerator( ) Console.WriteLine("ASSEMBLY EVIDENCE:") While x.MoveNext( ) Console.WriteLine(x.Current.ToString( )) End While End Sub End Class The LoadAndList utility provides you with the opportunity to demonstrate an important point we made earlier in this chapter: the identity of an assembly can vary greatly based on the location from which it is loaded, resulting in the assembly being granted a different set of permissions. Instead of the path of an assembly file, pass LoadAndList the URL of an assembly to load. If you place an assembly in the root directory of a Microsoft Internet Information Services (IIS) server running on your local machine, the evidence assigned to the assembly will be very different if you access it using an HTTP URL as opposed to the a file path. For example, if you take any assembly (use one named HelloWorld.exe) and place it in the root directory of the IIS server running on our Windows 2000 machine, executing the command LoadAndList C:\Inetpub\wwwroot\HelloWorld.exe results in the following display of host evidence (the Hash evidence is abbreviated): HOST EVIDENCE: <System.Security.Policy.Zone version="1"> <Zone>MyComputer</Zone> </System.Security.Policy.Zone> <System.Security.Policy.Url version="1"> <Url>file://C:/Inetpub/wwwroot/HelloWorld.exe</Url> </System.Security.Policy.Url> <System.Security.Policy.Hash version="1"> <RawData>4D5A90000300000004000000FFFF000</RawData> </System.Security.Policy.Hash> Alternatively, executing the command LoadAndList http://localhost/HelloWorld.exe results in a very different set of host evidence despite the fact that you are looking at the same assembly. Notice the changes (highlighted below) to the value of the Zone and Url evidence, and the addition of the new Site evidence. The Hash evidence (based on the content of the assembly) remains unchanged, as would StrongName and Publisher evidence if it were present. Notice that in both cases, the assembly evidence collection is empty: HOST EVIDENCE: <System.Security.Policy.Zone version="1"> <Zone>Intranet</Zone> </System.Security.Policy.Zone> <System.Security.Policy.Url version="1"> <Url>http://localhost/HelloWorld.exe</Url> </System.Security.Policy.Url> <System.Security.Policy.Site version="1"> <Name>localhost</Name> </System.Security.Policy.Site> <System.Security.Policy.Hash version="1"> <RawData>4D5A90000300000004000000FFFF000</RawData> </System.Security.Policy.Hash> 6.2.5 Assigning Evidence to AssembliesTable 6-4 lists the most commonly used methods of the AppDomain and Assembly classes that directly or indirectly result in the runtime loading an assembly. Each of these methods has one or more overloads that allow you to provide an Evidence collection for the loaded assembly.
Although the purpose and signatures of the methods listed in Table 6-4 vary, the steps necessary to supply evidence to a new assembly are the same:
Example 6-2 shows how to assign evidence to an assembly, using a modified version of the LoadAndList class (from Example 6-1) named LoadAndAssign. The LoadAndAssign class loads a named assembly, and assigns it new Site, Url, and Zone host evidence. Because we do not discuss the use of permission requests until Chapter 7, we catch all exceptions and display a message to the user. If you execute LoadAndAssign from your local machine, there should be no problem with permissions as long as you have not modified the default security policy. However, you should always handle any security exceptions that you know might be thrown. Example 6-2. Assigning evidence to an assembly# C# using System; using System.Reflection; using System.Collections; using System.Security; using System.Security.Policy; public class LoadAndAssign { public static void Main(string[] args) { // Create a new Evidence collection Evidence e = new Evidence( ); // Add host evidence to the Evidence collection e.AddHost(new Site("www.oreilly.com")); e.AddHost(new Url(@"file://C:/Dev/Test.exe")); e.AddHost(new Zone(SecurityZone.Trusted)); // Create a new Assembly reference Assembly a = null; try { // Load the specified assembly and provide the Evidence // collection a = Assembly.LoadFrom(args[0], e); } catch (Exception ex) { Console.WriteLine("Could not load assembly - {0}.", args[0]); Console.WriteLine(ex); return; } // Display the Host Evidence of the assembly IEnumerator x = a.Evidence.GetHostEnumerator( ); Console.WriteLine("HOST EVIDENCE:"); while(x.MoveNext( )) { Console.WriteLine(x.Current.ToString( )); } // Display the Assembly Evidence of the assembly x = a.Evidence.GetAssemblyEnumerator( ); Console.WriteLine("ASSEMBLY EVIDENCE:"); while(x.MoveNext( )) { Console.WriteLine(x.Current.ToString( )); } } } # Visual Basic .NET Imports System Imports System.Collections Imports System.Security Imports System.Security.Policy Public Class LoadAndAssign Public Shared Sub Main(ByVal args( ) As String) ' Create a new Evidence collection Dim e As Evidence = new Evidence( ) ' Add host evidence to the Evidence collection e.AddHost(new Site("www.oreilly.com")) e.AddHost(new Url("file://C:/Dev/Test.exe")) e.AddHost(new Zone(SecurityZone.Trusted)) ' Create a new Assembly reference Dim a As System.Reflection.Assembly = Nothing Try ' Load the specified assembly and provide the Evidence ' collection a = System.Reflection.Assembly.LoadFrom(args(0), e) Catch ex As SecurityException Console.WriteLine("Could not load assembly - {0}.", args(0)) Console.WriteLine(ex) Return End Try ' Display the Host Evidence of the assembly Dim x As IEnumerator = a.Evidence.GetHostEnumerator( ) Console.WriteLine("HOST EVIDENCE:") While x.MoveNext( ) Console.WriteLine(x.Current.ToString( )) End While ' Display the Assembly Evidence of the assembly x = a.Evidence.GetAssemblyEnumerator( ) Console.WriteLine("ASSEMBLY EVIDENCE:") While x.MoveNext( ) Console.WriteLine(x.Current.ToString( )) End While End Sub End Class From the command line, entering the command LoadAndAssign C:\Inetpub\wwwroot\HelloWorld.exe to load the HelloWorld.exe assembly you used in Example 6-1 results in the display of host evidence similar to that listed below. The Url and Zone evidence you specified has replaced the default evidence. There is also Site evidence, which was previously present only when you used an HTTP URL to specify the location of the assembly: HOST EVIDENCE: <System.Security.Policy.Hash version="1"> <RawData>4D5A90000300000004000000FFFF000</RawData> </System.Security.Policy.Hash> <System.Security.Policy.Site version="1"> <Name>www.oreilly.com</Name> </System.Security.Policy.Site> <System.Security.Policy.Url version="1"> <Url>file://C:/Dev/Test.exe</Url> </System.Security.Policy.Url> <System.Security.Policy.Zone version="1"> <Zone>Trusted</Zone> </System.Security.Policy.Zone> 6.2.6 Assigning Evidence to Application DomainsMany of the standard evidence types are more applicable to assemblies than to application domains, but there is nothing to stop you assigning any of the evidence types of application domains. For example, although it is impossible to sign an application domain with a publisher certificate, you could still assign Publisher evidence to an application domain manually. This may be appropriate on a server that runs code on behalf of many different companies. You may decide to run all code from a single company in its own application domain. Assigning the application domain Publisher evidence ensures that any code running within the application domain is limited to the permissions you assign to that particular company. The benefits of application domain evidence will become clearer when we discuss security demands and stack walks in Chapter 7. When you create an application domain using the static AppDomain.CreateDomain method, two of the method overloads give you the option of providing an Evidence collection for the new application domain: # C# public static AppDomain CreateDomain( string friendlyName, Evidence securityInfo, AppDomainSetup info ); public static AppDomain CreateDomain( string friendlyName, Evidence securityInfo, string appBasePath, string appRelativeSearchPath, bool shadowCopyFiles ); # Visual Basic .NET Overloads Public Shared Function CreateDomain( _ ByVal friendlyName As String, _ ByVal securityInfo As Evidence, _ ByVal info As AppDomainSetup _ ) As AppDomain Overloads Public Shared Function CreateDomain( _ ByVal friendlyName As String, _ ByVal securityInfo As Evidence, _ ByVal appBasePath As String, _ ByVal appRelativeSearchPath As String, _ ByVal shadowCopyFiles As Boolean _ ) As AppDomain The process of specifying evidence for an application domain is the same as for assemblies except that you pass the Evidence collection populated with evidence objects to the CreateDomain method: # C# // Create an empty Evidence collection Evidence e = New Evidence( ); // Add Host and Assembly Evidence e.AddHost(new Site("www.oreilly.com")); e.AddHost(new Zone(SecurityZone.Trusted)); // Create a new application domain reference. AppDomain d = null; try { // Create the new application domain d = AppDomain.CreateDomain("New Domain", e, null); } catch (Exception ex) { Console.WriteLine("Could not create application domain"); Console.WriteLine(ex); } # Visual Basic .NET ' Create an empty Evidence collection Dim e As Evidence = New Evidence( ) ' Add Host and Assembly Evidence e.AddHost(New Site("www.oreilly.com")) e.AddHost(New Zone(SecurityZone.Trusted)) ' Create a new application domain reference. Dim d As AppDomain = Nothing Try ' Create the new application domain d = AppDomain.CreateDomain("New Domain",e,Nothing) Catch ex As Exception Console.WriteLine("Could not create application domain") Console.WriteLine(ex) End Try Be aware of the following behavior:
|
[ Team LiB ] |