From time to time, it may be necessary to run .NET controls on computer systems that do not allow all operations by all applications using .NET. Systems that limit resource access typically do so through the use of the Microsoft .NET Configuration Tool, mscorcfg.msc, a snap-in application that is installed with the .NET Framework. Note that each version of the Framework installs its own tool. They can be found in:
where xxxx is the build number of the .NET Framework you are using.
The tool can also be run from the Administrative Tools menu in Control Panel. The tool is listed as "Microsoft .NET Framework Configuration" for .NET 2002. Later .NET Frameworks will also be listed if present.
Below is an image of the running snap-in tool (Figure 1).
The Runtime Security Policy node contains subnodes that are used to specify security permissions for Code Groups, including individual assemblies. Permissions can be specified by Enterprise (domain administrators), Machine (individual machine on the network), or User basis.
For this discussion, the focus will be on Machine level permissions. Permissions are specified by defining a code group within the appropriate zone that identifies the code or assemblies involved. For example, in Figure 1, notice the Microsoft_Strong_Name node. This node, part of the default configuration defined by Microsoft, specifies the permission set used for all Microsoft .NET code and assemblies signed with the Microsoft strong name. This includes all of the Microsoft .NET controls that are part of the .NET Framework (for example, DataGrid in System.Windows.Forms.dll).
Actual permissions are specified by the Policy Level assigned to a Code Group by specifying one of the Permissions Sets that appear in the tree node following the Code Groups node. Note that Microsoft has given FullTrust to all of its assemblies by default.
To run other blocks of code and controls on a secure system, it will be necessary to add code groups that identify the code involved. The level of trust necessary to execute each code block depends upon the usage of that code block, and whether the code is part of an assembly that declares the assembly attribute: System.Security.AllowPartiallyTrustedCallers. Assemblies that do not have this attribute always require FullTrust. Assemblies that do have this attribute can execute with less than FullTrust, with the necessary permissions required dependent upon the code of the assembly that is executed by the application.
Note that each assembly may contain code that it does not have permissions to execute, but exceptions will only be thrown if that code is executed. Therefore, only permissions which are necessary for an application must be granted.
Any control that must execute at design time requires FullTrust. This is because the base control, from which all controls derive, must have FullTrust to be handled appropriately by the Microsoft IDE. However, for programs which merely execute on a system, the permissions for the control assemblies may not require FullTrust.
The C1FlexGrid control uses calls to unmanaged Windows APIs such as USER32.DLL, OLE32.DLL, and UXTHEME.DLL. This can be seen in the manifest listed by the Microsoft tool, ILDASM.EXE. Also listed in the manifest is the AllowPartiallyTrustedCallers assembly attribute, so it is possible to execute C1FlexGrid on a secure system, provided all the necessary permissions are granted to the assembly. In this case the permissions must include the ability to call into unmanaged code.
Begin by creating a simple application using C1FlexGrid. Call the application WinApp1, containing just a form with a C1FlexGrid on it. The grid is not bound and has no code filling it, it is just a grid on a form. You should be able to run the application as usual.
Next, adjust the Zone Security settings to simulate deployment to a secure environment. You can do this by selecting the "Runtime Security Policy" node in the snap-in and clicking the "Adjust Zone Security" link:
In the dialog that follows, select "Make Changes to this computer", select the "My Computer" level and move the slider down one notch from Full Trust:
When you are done, try running WinApp1 again. It will throw a security exception immediately, as a result of the C1FlexGrid calls to unmanaged Windows APIs.
To fix the problem, create a new permission set that will be assigned to the C1FlexGrid assembly for use at runtime, that is, for a secure client machine. Because the application doesn't do much, the permissions necessary will be minimal.
Right-click the "Permission Sets" node and select "New" from the context menu. Call the new permission set "C1FlexGrid". In the dialog that follows, double-click "Security" to add specific security permissions to the new permission set. The picture below shows the settings appropriate for minimal C1FlexGrid use:
Notice that the permissions really are minimal, including only those permissions necessary for the code to be executed by C1FlexGrid in the sample application. Note that File IO, File Dialogs, OLEDB, etc., operations that are often associated with C1FlexGrid are not granted, because these operations will not be required by the application. If the grid were bound to a DataSet, or the design dialogs were executed, exceptions would be expected with these permission settings.
Now that the new permission set is ready, the next step is to assign it to the C1FlexGrid and WinApp1 assemblies.
Right-click the "My Computer Zone" node and select "New" from the context menu. Call the new code group "C1FlexGrid", select "Strong Name" as the membership condition, and import the public key from C1.Win.C1FlexGrid.dll.
Note that each of the parent nodes has a set of permissions associated with it. "My_Computer_Zone" is now assigned "LocalIntranet" permissions. As a result, the new C1FlexGrid code group will receive all permissions granted by the "LocalIntranet" permissions, plus those permissions given by the "C1FlexGrid" permission set; that is, the permission sets are additive.
However, a dependent assembly cannot receive more permissions that the calling assembly, so you also need to grant "C1FlexGrid" permissions to WinApp1. To do that, create a new code group called "WinApp1", select "Hash" as the membership condition (WinApp1 doesn't have a strong name), and import the hash code from WinApp1.exe.
The configuration tool should now look like the picture below:
Try running the WinApp1 application again. This time it will execute normally.
If you want, you can simulate other scenarios by adjusting the Zone Security and the C1FlexGrid permission set. Additional permissions may be required depending on the nature of the application and on the security setting of target environment.
When you are satisfied with the new code groups and permission sets, you use the configuration tool to create a deployment package for the new settings. To do that, right-click the "Runtime Security Policy " node and select the "Create Deployment Package" option from the context menu.
When you are done testing, be sure to restore the permissions necessary to do your work. To reset all of the security nodes and permissions to their default values, right click the "Runtime Security Policy" node and select "Reset All" from the context menu.