Microsoft has ramped up the security in their latest operating system – Windows Vista, which means that developers now have to pay more attention to certain security constraints imposed by the operating system when developing applications. Those of you readers who have read my prior posts on User Access Control in Vista (and the further reading article), may be interested in this small software project I put together.
The Problem in a Nutshell
Vista requires that ALL users (even administrators) obtain an elevated security token before being permitted to execute protected API calls or accessing protected system resources (the registry for example). In prior versions of Windows, system administrators were given a privileged security token at login and permitted to perform any task without further confirmation from the interactive user. Windows Vista now allocates a low security token by default to all users and administrators, and an elevated token is only obtained with credentials (users) or confirmation (administrators) when required.
Elevation request is determined by Vista before any process is loaded – so if a particular process is running non-elevated then access to protected resources and APIs within that process is denied. This is an important caveat, as it affects the way in which software developers approach application design.
How does one Elevate their Process?
There are several articles on the Internet about developing elevated processes in Vista, so I’ll not dwell on the steps here (my previous articles cover this subject), but essentially elevation request involves decorating .NET assemblies and WIN32 executables with elevation status in the application manifest file (may be embedded or side-by-side).
The COM Elevation Moniker is another method for obtaining elevation. Using the CEM it is possible to host a COM (Component Object Model) component in elevated state using the dedicated system process – DLLHost.exe. The Windows Vista SDK provides details on adding the necessary code to your project to elevate an out-of-proc component and making it available to your non-elevated application.
So why use the COM Elevation Moniker?
The CEM permits a non-elevated process to execute protected API calls and access protected resources by calling across process boundaries into an elevated process. This is how Vista achieves mid-application elevation – look for the shield symbols in forms and property pages, to get an idea of what I am talking about.
So what’s the big deal?
Development of a CEM component typically involves some work in C++. Development of COM components in VB and .NET is of course possible, but when it comes down to accessing WIN32 calls to perform COM elevation most of the examples are published in C++. Developing a managed CEM is possible but involves some work to get it operating correctly.
What about cross boundary communication? – This is the klutz of the problem with authoring CEM components, how to communicate across process boundaries? COM development answered this problem a long time ago, and the same is true now as it was then – marshalling data and cross process communication is handled by the COM infrastructure. But what about managed code? If you’ve managed to solve the problem of invoking a .NET assembly as a COM CEM component, you still have to communicate over .NET interop, which may not be ideal.
Surely someone must have a way to perform elevation in the managed world?
The .NET Wrapper for COM Elevation
I wanted a way for managed developers to attribute their code classes in such away that embedded methods of these classes would request elevation from the Vista operating system before execution of such methods. So I went about developing a library to encapsulate the complexities of the COM Elevation Moniker. The end result is available to download from here.
After downloading the ZIP files and unpacking it, the library is packaged as an MSI installer file, which must be installed as an administrator to make use of the library functionality. The installer also installs some example code to demonstrate use of the library.
How does the Managed Wrapper Library Work?
Essentially, the wrapper library exists as a managed and non-managed server. The non-managed COM server provides the infrastructure to elevate managed code by hosting it’s own .NET AppDomain. The managed server assembly is loaded into the elevated AppDomain and executes code developed by the end user of my library.
Communication between the hosted managed server and client code is achieved using an IPC (Inter-Process Communication) channel developed against WCF (Windows Communication Foundation). The exact specifics of this set up is beyond the scope of this blog post, but involves the use of CodeDOM (dynamic code generation) to create a dynamic messaging system between elevated code and non-elevated client proxy.
My wrapper library is very much “beta” at present. I’ve published my library in the hope that I can attract a number of developers to use it and let me know their initial thoughts. Documentation is sparse, but I am working on publishing a technical manual. It is important to understand that end-users of my library require no knowledge of WCF development, C++, or COM expertise, which makes my library versatile and easy to use by managed developers of different skill-level.
For now, I’ll end this post with a thank-you – for taking an interest in my project. I look forward to receiving feedback (good and bad), especially any pertaining to security aspects.