Declarative security defines application security requirements as part of the declaration of main application elements such as a namespace, class, or method. It relies on attributes defined as part of an application element declaration, such as a method. The compiler normally processes these attributes during compile time, which means the declaration appears as part of the application manifest.
You’ve already seen several examples of declarative security throughout the book (and will see several more before the completion of the book). For example, the “Using the Permission View Tool” section of the chapter relies on declarative security. This example points out one of the reasons you should use declarative security in some cases. Declarative security creates entries in the assembly metadata that are easy to retrieve and use as a basis for setting assembly security. Someone who
Declarative security is also good from a documentation standpoint. All of the security requirements for a particular element appear as part of the declaration. You don’t have to wade through the code to find the security statement that could cause coding problems down the road.
You can use declarative and imperative security interchangeably for many needs, but declarative security is more effective in some situations. Whenever you need to consider the documentation aspects of an application as a higher priority than ease of use or dynamic data manipulation, declarative security is the tool of choice.
Imperative security appears as statements within the application code. You define a security object, and then use
Declarative security is important because it provides so many good features, such as instant documentation and good metadata access. In fact, declarative security may provide so many good features that you might be tempted to use it exclusively. However, you do need to use imperative security in some situations.
Whenever a security need requires a dynamic data
Many developers also find that imperative security is
The registry is the central storage area for all kinds of information for the local machine, the
The
RegistryPermission
class provides code access security for the registry as long as you implement it correctly. The
Listing 4.5 Implementing Code Access Security for the Registry
|
|
class AccessReg { // Some global
variables
used to make registry access easier. private RegistryKey HKey; // HKEY_CURRENT_USER reference. private RegistryKey CKey; // Company key reference. private RegistryKey AppKey; // Application key reference. private RegistryPermission RegPerm; // Registry permission object. private Boolean RegStat; // Registry lock status. public AccessReg() { // Permission for the company registry setting. RegPerm = new RegistryPermission(RegistryPermissionAccess.AllAccess, @"HKEY_CURRENT_USER\Software\" + Application.CompanyName); // Permission for the application registry setting. RegPerm.AddPathList(RegistryPermissionAccess.AllAccess, @"HKEY_CURRENT_USER\Software\" + Application.CompanyName + @"\" + Application.ProductName + @"\0"); // Ensure access initially. RegPerm.Demand(); // Get the HKEY_CURRENT_USER key. HKey = Registry.CurrentUser.OpenSubKey("Software", true); // Verify the company key exists. CKey = HKey.OpenSubKey(Application.CompanyName, true); if (CKey == null) CKey = HKey.CreateSubKey(Application.CompanyName); // Verify the application key exists. AppKey = CKey.OpenSubKey(Application.ProductName, true); if (AppKey == null) AppKey = CKey.CreateSubKey(Application.ProductName); } public void Finalize() { // Close the keys. AppKey.Close(); CKey.Close(); HKey.Close(); // Clear the references. AppKey = null; CKey = null; HKey = null; } public void WriteData(String Value, String Data) { // Check the registry lock status. if (RegStat) RegPerm.Deny(); else RegPerm.Assert(); try { // Write data to the registry. AppKey.SetValue(Value, Data); } catch (SecurityException SE) { // Display an error message. MessageBox.Show("Write Access Denied", "Security Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } public String ReadData(String Value) { // Check the registry lock status. if (RegStat) RegPerm.Deny(); else RegPerm.Assert(); try { // Read data from the registry. return (String)AppKey.GetValue(Value); } catch (SecurityException SE) { // Display an error message. MessageBox.Show("Read Access Denied", "Security Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // Return an error string. return "Key Access Error!"; } } public void LockRegKey() { // Lock the registry key. RegStat = true; } public void UnlockRegKey() { // Release any registry key lock. RegStat = false; } }
|
|
The
AccessReg
class shows a number of
The code begins by creating
RegPerm
, the registry permission for the key used to store registry data for this program. The
RegistryPermission
constructor call creates a
This portion of the code ends by opening three registry keys using the
OpenSubKey()
method. The first key
The code includes a
Finalize()
method. All that this method does is ensure that the registry keys are closed and the global variables cleared. Otherwise,
The
WriteData()
and
ReadData()
Securing the registry is important because it contains entries crucial to your machine’s functionality. Registry security in the Win32 API world depends on the RegSetKeySecurity() and RegGetKeySecurity() functions. The Win32 API also requires use of functions such as RegOpenKeyEx() and RegSetValueEx() to interact with the registry. You can find a list of these functions at http://msdn.microsoft.com/library/en-us/sysinfo/base/registry_functions.asp .
The
Microsoft.Win32.RegistryKey
class provides access to the registry without relying on Win32 API or Platform Invoke (PInvoke) calls. You can learn more about this class at
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfMicrosoftWin32RegistryKeyMembersTopic.asp
. The
System.Security.Permissions.RegistryPermission
class provides code access security for your .NET application. However, the security measures leave the registry wide
To actually lock a registry key from
The massive holes in registry security aren’t limited to problems with physical locking and code access only security. If you don’t lock every path for a particular registry entry, it’s possible to use the
RegistryKey
class to access the value even though your code supposedly locked it. Read the “Canonicalization Problems Using Deny”