As you have already seen, the glue that connects code groups, permissions, and permission sets consists of three levels of security policy (enterprise, machine, and user). Security configuration information in .NET is stored in XML configuration files that are protected by Wmdows security. For example, the machine-level security policy is writable only by users in the Administrators and SYSTEM ;, Wmdows groups.
The files that store the security policy are located in the following paths:
¤ Enterprise policy configuration – <windows> \Microsoft. NET\Frarnework\<version> \ Config\enterprise.config
¤ Machine policy configuration – <windows>\Microsoft .NET\Frarnework\<version>\ ~onfig\security.config
¤ User policy configuration – %USERPROFILE%\appl ica t i on da ta \Microsof t \ CLR security Config\ version>\security.config
The subdirectory <version> varies, depending on the version of the CLR you have on your machine. Because .NET 2.0, 3.0, and .NET 3.5 are based on the same version of the runtime, you find just one configuration for all these Framework versions. If necessary, it’s possible to edit these configuration files manually, for example, if an administrator needs to configure policy for a user without logging in to his account. However, in general it’s recommended to use caspol . exe or other administrator tools.
Given everything you have read so far, you are ready for a simple application that accesses the local drive – the kind of behavior you are likely to want to manage carefuJly. The application is a C# Windows Forms application with a list box and a button (see Figure 20-9). When you click the button, the list box is populated from a file called animals. txt from your local user folder. Before starting the application, you need to copy the file to this folder. In Windows Vista, the file is c: \ user s \ . <usernarne>\Documents\animals.txt .
The application was created by using Visual Studio, and the only changes were to add the list box and Load Data button to the form and to add an event to the button that looks like this:
It opens a simple text file animals. txt from the user folder, which contains a list of animals on separate lines, and loads each line into a string, which it then uses to create each item in the list box. If you run the application from your local machine and click the button, you will see the data loaded and displayed in the list box (see Figure 20-10). Behind the scenes the runtime has granted the assembly the permission it needs to execute, access the user interface, and read data from the local disk.
As mentioned earlier, the permissions on the Intranet zone code group are more restrictive than on the local machine; in particular, they do not allow access to the local disk. If you run the application again, but this time from a network share, it will run just as before because it is granted the permissions to execute and access the user interface; however, if you now click the Load Data button on the form, a security exception is thrown (see Figure 20-11).You’ll see in the exception message text that it mentions the System.Security. Permissions. FileIOPermission object; this is the permission that the application was net granted and that was demanded by the class in the Framework that was used to load the data from the file on the local disk.
By default, the Intranet code group is granted the LocalIntranet permission set; change the permission set to FullTrust so that any code from the Intranet zone can run completely unrestricted.
First, you need to get the numeric label of the LocalIntranet code group. You can do this with the following command:
This will output something like this:
Notice that the LocalIntranet group islistedas 1.2.You can use the following command to apply fulltrust:
caspol.exe -chggrou~ 1.2 FullTrust
Ifyou run the application from the network share again and clickthe button, you will see that the list box ispopulated with the content of the filein the root of the C :, drive and no exception occurs.
In scenariosjike these, in which you are making use of resources governed by permissions, itis advisable to extend the code so that security exceptions are caught and the application can degrade gracefully.For example, in the sample application, you can add a try /ca tch block around the fileaccess code, and ifa Securi tyException isthrown, you can display a line in the listbox saying “Permission denied accessing file”
membership conditions can be used to tightly control the requirements of the application – perhaps using its location on the intranet, a strong name, or a certificate proving the identity of the publisher
Managing Code Groups and Permissions
In managing security on .NET,if you find that an assembly is failing with a security exception, you usually have three choices: .
¤ Ease the policy permissions – You can change the permissions for the Machine policy to allow more permissions for specific code groups. However, it is not a good practice to give more permissions to the assemblies from an intranet or the Internet, because this can lead to Trojan horses gaining access to your system. Instead, you can add new code groups that have specific permissions as required.
¤ Move the assembly – Assemblies from a network share are not trusted as much as assemblies installed on the local system. Instead of creating a new code group, you can move the assembly to the local system so that it gets more permissions
¤ Apply a strong name to the assembly – A good practice is to apply a strong name to the
assembly and create a code group that trusts the strong name.
To make these kinds of decisions, you must take into account your level of trust of the assembly
Turning Security On and Off
By default, .NETsecurity is enabled. If, for any reason, you need to turn it off, you can do so like this:
caspol.exe -security off
As a new ~curity feature, running this command from the command prompt turns security off only temporarily. As soon as you press the Enter key, security is turned on again. You can keep this command prompt open as long as required and continue working with another command prompt. When you are finished doing the security related tasks, press the Enter key and security is turned on again. Youcan also explicitly turn it on again:
caspol.exe -security on
To return the security configuration to its original state, you can type this command:
This command resets the security policy to the installation’s default.
Creating a Code Group
You can create your own code groups and then apply specific permissions to them. For example, you could specify that you want to trust all code from the Web site www.wrox. comand-to give it full access to the system (without trusting code from any other Web site). Earlier, theJf(>olcaspol was used to display a list with the available group and number assignments. The zone Inte~t is labeled 1.3,so now type this command:
car,lol.exe -addgroup 1.3 -site www.wrox.comFullTrust
Note ~t this command will ask for confirmation because this is an attempt to alter the security policy on ~t1i.1machine.lfthe command caspol. exe -listgroups is now run again, you will see that the new 0<J,igrouPhas been added and assigned FullTrust:
Here’s another example. Say that you want to create a code group under the Intranet code group (1.2) that grants FullTrust to allapplications running from a specificnetwork share. To do so, you run the following command:
=aspol.exe -addgroup 1.2 -url file:\\intranetserver/sharename/* ~ullTru
Deleting a Code Group
To remove a code group that has been created, you can type a command likethis: >caspol.exe -remgroup 1.3.2
Itwill ask for confirmation that you want to alterthe security policy,and ifyou give itpositive confirmation, itwill tatethat the group has been removed.
Changing a Code Group’s Permissions
Changing a Code Group’s Permissions To ease or restrictthe permissions assigned to a code group, you use caspo l .exe again. Suppose that you want to apply FullTrust to the Intranet zone; first,you need to get the label that represents the Intranet code group
The output shows the I.ptranetcode group:
Once you have the Intranetcode group’s label.1.2.you can enter a second command to alterthe code group’s rmissions:
caspol.exe -chggroup 1.2 FullTrust
The command asks you to confirm the change to the securitypolicy.and ifyou run the caspol. exe – listgroups command again. you can see that the permission on the end of the Intranet linehas changed to FullTrust
Creating and Applying Permissions Set
You can create new permission setsusing a command likethis
caspol.exe -addpset MyCustomPermissionSet permissionset.xml
This command specifies that you are creating a new permission set called My Custom Permission Set. which is configured with the contents of the specified XML file.The XML file must contain a standard format that specifies a Permission Set. For reference.here is the permission set file for the Everything permission set.which you can trim down to the permission set you want to create
To view all permission sets in XML format, you can use this command:
To give a new definition to an existing permission set by applying an XML PermissionSet configuration file, you can use this command:.
caspol.exe -chgpset permissionset.xml MyCustomPermissionSet
Distributing Code Using a Strong. Name
NET provides the ability to match an assembly to a code group when the assembly’s identity and integrity have been confirmed using a strong name. This scenario is very common when assemblies are being deployed across networks (for example, when distributing software over the Internet).
If you are a software company and you want to provide code to your customers via the Internet, you build an assembly and give it a strong name. The strong name ensures that the assembly can be uniquely identified, and also provides protection against tampering. Your customers can incorporate this strong name into their code access security policy; an assembly that matches this unique strong name can then be assigned permissions explicitly. As discussed in Chapter 17, “Assemblies,” the strong name includes checksums for hashes of all the files within an assembly, so you have strong evidence that the assembly has not been altered since the publisher created the strong name.
Note that if your application uses an installer, the installer will install assemblies that have already been given a strong name. The strong name is generated once for each distribution before being sent to customers; the installer does not run these commands. The reason for this is that the strong name provides an assurance that the assembly has not been modified since it left your company. A common way to achieve this is to give your customer not only the application code but also, separately, a copy of
the strong name for the assembly. You might find it beneficial to pass the strong name to your customer using a secure form (perhaps a fax or an encrypted email) to guard against the assembly being tampered with in the process.
Consider an example in which an assembly with a strong name is created to distribute it in such a way that the recipient of the assembly can use the strong name to grant the Full Trust permission to the assemb~.
First, a key pair is needed. Creating strong names has already been discussed in Chapter 17, so there is no need to repeat it here. Rebuilding the assembly with the key ensures that the hash is recalculated and the assembly is protected against malicious modifications. Also, the assembly can be uniquely identified with the strong name. This identification can be used with membership conditions of code groups. A membership condition can be “based on the requirement to match a specific strong name.
The following command states that a new code group is created using the strong name from the specified assembly manifest file, that the code group is independent of the version number of the assembly, and that the code group has granted the FullTrust permissions:
caspol.exe -addgroup 1 -strong -file SimpleExample.exe -noname -noversionFullTrust
In this example, the application will now run from any zone, even the Internet zone, because the strong name provides powerful evidence that the assembly can be trusted. Look at your code groups using caspo l . exe -listgroups, and you will see the new code group (1.6 and its associated public key in hexadecimal):
To accessthe strongname inan assembly, you can use the secutil. exe toolagainstthe assembly manifest file.Using the -hex option,the public key isshown inhexadecimal (likecaspol. exe);the argument -strongname specifiesthatthe strong name should be shown. Type thiscommand, and you willsee a listingcontainingthe strong name public key,the assembly name, and the assembly version:
secutil.exe -hex -strongname SimpleExample.exe
Microsoft (R) .NET Framework SecUtil 3.5.21004.1
Copyright (c) Microsoft Corporation. All rights reserved
You may be surprisedabout the two strong name code groups thatare installedby defaultand what they referto.One isa strong name key forMicrosoft code; the other strong name key isforthe partsof .NET thathave been submitted to the EeMA forstandardization,which willgive Microsoftmuch lesscontrol
DIstrIbutIng Code UsIng CertIfIcates
The preceding sectiondiscussed how a strong name can be applied to an assembly so thatsystem administratorscan explicitlygrant permissions toassemblies thatmatch thatstrong name, using a code access group. Although thismethod fsecuritypolicymanagement can be very effective,itissometimes necessary towork ata higher level,where the administratorof the securitypolicygrants permissions on the basisof thepublisherofthe software,ratherthan toeach individualsoftware component. You
probably have seen a similarmethod used before when you have downloaded executablesfrom the Internetthathave been Authenticode signed
To provide information about the software publisher, you can make use’of digital certificates and sign assemblies so that consumers of the software can verify the identity of the software publisher. In a commercial environment, you would obtain a certificate from a company such as Verisign or Thawte. The advantage of buying a certificate from a supplier instead of creating your own is that it provides a high level of trust in its authenticity;
the supplier acts as a trusted third party. For test purposes, however, .NET includes a command-line utility you can use to create a test certificate. The process of creating certificates and using them for publishing software is complex, but we walk through a simple example in this section.
The example code will be made for the fictitious company called ABCCorporation. In this company, the software product ABCSuite should be trusted. First, create a test certificate by typing the following command:
>rnakecert -sv abckey.pvk -r -n “CN=ABCCorporation” abccorptest.cer The command creates a test certificate under the name ABCCorporation and saves it to a file called abccorptest. cer. The -sv abckey. pvk argument creates a key file to store the private key. Whe:t creating the key file, you are asked for a password that you should remember. After creating the certificate, you can create a software publisher test certificate with the Software Publisher Certificate Test tool (Cert2spc. exe):
cert2spc abccorptest.cer abccorptest.spc
To sign the assembly with the certificate, use the signcode. exe utility on the assembly file containing the assembly manifest. Often, the easiest way to sign an assembly is to use the sign tool. exe in its wizard mode; to start the wizard, just type signtool. exe with the parameter signwizard.
When you click Next, the program asks you to specify where the file is that should be signed. For an assembly, select the file containing the manifest, for example SirnpleExample. exe, and click the Next button. On the Signing Options page, you must select the Custom option to define the previously created cer!ificate file.
In the next dialog box, you are asked to specify the certificate that should be used to sign the assembly. Click Select from File and browse to the file abccorptest. spc. You will now see the screen
The next screen that appears asks for your private key. The key file abckey. pvk was created by the rnakecert utility, so you can select the options as shown in Figure 20-13. The cryptographic service provider is an application that implements the cryptographic standards. Next you are asked a series of questions about the encryption algorithm that should be used for signing
the assembly (rndSor shal) and the name and URLof the application, and you are shown a final confirmation dialog.
Because the executable is now signed with the certificate, a recipient of the assembly has access to strong evidence ‘as to who published the software. The runtime can examine the certificate and match the publisher of the assembly to a code group with high levels of confidence about the identity of the code because the trusted third-party certifies the publisher’s identity
The test certificate must now be installed with the trusted certificates. Start the Certificate Manager certmgr:
Select the Trusted Root Certification Authorities tab and Certificates below in the tree. Select Action ~ All Task ~ Import … to import the certificate file. With the Certificate Import, select the certificate File abccorptest. cer. After clicking the Next button, verify that the certificate store listed is Trusted Root Certification Authorities, which is the case when you have chosen this selection in the tree
Before the import is completed, you will get a warning dialog, as shown in Figure 20-15,because the test certificate cannot be validated. Click Yesto install the certificate .
After the cerlificateisinstalledas a trusted root authority,you can see itin the certificateslist,as shown in Figure 20-16.
Now turn your attentionto a machine that you want to configure to trustsoftware from the ABC Corporation. You ean createa new code access group that matches thissoftware from ABC Corporation. You justhave to grab a hexadecimal representation of the certificatefrom the assembly using the secutil. exe tool:
Now createthe new code group and apply the FullTrustpermission to assemblies published by the ABC Corporation using this(ratherlong) command:
The parameters specifythat the code group should be added at the top level(1)and that the code group membership condition isof the type P>.lblisher;the lastparameter specifiesthe permission set to grant (FullTrust).The command willask for confirmation
The operation you are performing will alter security policy. Are you sure you want to perform this operation? (yes/no)
y . Added union code group with ‘-pub” membership condition to the Machine level. Success
The machine isnow configured to fullytrustallassemblies thathave been signed with the certificate from ABC Corporation. To confirm that,you can nul a caspol. exe -lg command, which liststhe new code access group.
As another check, askcaspo l .exe to tellyou what code groups your assembly matches:
caspol.exe -resolvegroup SimpleExample.exe
Level = Enterprlse