Customizing the Microsoft .NET Framework Common Language Runtime
|
In Chapter 8, I wrote a CLR host called runcocoon.exe that executes applications contained in OLE-structured storage files called cocoons. In this section, I extend runcocoon.exe to use host protection to prevent the assemblies contained in cocoon files from using any of the .NET Framework APIs that are annotated with HostProtectionAttribute. Remember that only partially trusted assemblies are prevented from accessing members blocked by host protection, so the extensions I made to runcocoon.exe in Chapter 10 apply here as well. In that chapter, I used an application domain CAS policy tree to assign a partial level of trust to all assemblies loaded from a cocoon. Because those assemblies are only partially trusted, they're subject to the host protection settings I'll add to runcocoon.exe in this section. I won't list the entire source for the runcocoon.exe host again here. Instead, I'll just provide those portions of the implementation that are specific to host protection. A complete source code listing can be found on this book's companion Web site. Enabling host protection in runcocoon.exe requires two steps:
These two steps are described in more detail in the next sections. Step 1: Obtaining the ICLRHostProtectionManager Interface Pointer
As described in Chapter 2, all of the primary hosting interfaces implemented by the CLR are obtained using the GetCLRManager method on ICLRControl. The following code snippet initializes the CLR with CorBindToRuntimeEx, and then uses ICLRControl::GetCLRManager to get the CLR's implementation of ICLRHostProtectionManager: int wmain(int argc, wchar_t* argv[]) { HRESULT hr = S_OK; // Start the .NET Framework 2.0 version of the CLR ICLRRuntimeHost *pCLR = NULL; hr = CorBindToRuntimeEx( L"v2.0.41013", L"wks", STARTUP_CONCURRENT_GC, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*) &pCLR); assert(SUCCEEDED(hr)); // Get the CLRControl object. ICLRControl *pCLRControl = NULL; hr = pCLR->GetCLRControl(&pCLRControl); assert(SUCCEEDED(hr)); // Ask the CLR for its implementation of ICLRHostProtectionManager. ICLRHostProtectionManager *pCLRHostProtectionManager = NULL; hr = pCLRControl->GetCLRManager(IID_ICLRHostProtectionManager, (void **)&pCLRHostProtectionManager); assert(SUCCEEDED(hr)); // Rest of the host's code omitted... }
Step 2: Specifying Which Host Protection Categories to Block
Now that I have a pointer of type ICLRHostProtectionManager, I simply need to call its SetProtectedCategories method to specify which categories I'd like to block. The following call to SetProtectedCategories blocks the full set of host protection categories: // Block all host protection categories. hr = pCLRHostProtectionManager->SetProtectedCategories ( (EApiCategories)( eSelfAffectingProcessMgmt | eSelfAffectingThreading | eSynchronization | eSharedState | eExternalProcessMgmt | eExternalThreading | eSelfAffectingProcessMgmt | eSelfAffectingThreading | eSecurityInfrastructure | eMayLeakOnAbort | eUI)); assert(SUCCEEDED(hr));
Now that I've enabled host protection, all attempts by cocoon assemblies to access protected APIs will result in an exception of type System.Security.HostProtectionException. The HostProtectionException has fields that describe which categories the host has blocked and which category contains the method that caused the exception to be thrown. For example, the following exception text resulted from a cocoon assembly attempting to call Console.WriteLine, which belongs to the UI host protection category: System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host. The protected resources (only available with full trust) were: All The demanded resources were: UI
Note
|
|