Show Changes Show Changes
Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Search

History

10/22/2004 9:30:57 AM
List all versions List all versions
How To Configure Security For ACOM Client
.

It's a pity that I even have to write this item or that it needs to be as complicated as this, but the COM interop team, although content to automate the call to CoInitializeEx for you, apparently doesn't feel the same about helping you with security. In fact, in a simple console or Windows Forms application, for example, nobody in the framework bothers to call CoInitializeSecurity. Didn't anyone on this team read Brown (2000b)? Arrrgh!

Here's the problem. If you're writing a COM client, especially one that communicates with remote COM servers, you need to have some control over your security settings, and if nobody in your process calls CoInitializeSecurity, well, COM does its best to figure out what settings your application needs. And the results are often not pretty. Some settings can be configured via the registry, but not all. And even if you do rely on registry settings and good old DCOMCNFG.EXE (or the MMC snap-in that has now replaced it), the link that ties your registry-based security settings to your application is fragile at best. It's a link in the registry that's based on your EXE name, and it breaks in many cases, such as when the name of the EXE is changed (well, duh!) and it can even break if you use a long file name in some cases. It's designed for legacy applications that didn't know how to call CoInitializeSecurity. You can do better. I've provided some code that makes calling this function pretty easy.

As a COM client, CoInitializeSecurity allows you to control your authentication and impersonation levels, which are really important, as I discussed in WhatIsTheCOMAuthenticationLevel and WhatIsTheCOMImpersonationLevel. Just as important is the ACL that says who is allowed to call into your client process (that's right, if you're a COM client, you very likely act as a COM server in some scenarios — think about callbacks and events). There are also some important security measures that you can control. For example, you can restrict custom marshaling so that an attacker can't load arbitrary DLLs into your process. In short, you really need to call this function if you're writing a base COM client. But there's a catch. Because this function controls process-wide security settings, it can only be called once per process. And if you don't call it before doing something "interesting," like unmarshaling a proxy, COM will take matters into its own hands and effectively call it for you. So you need to call this function early.

Here's the fun part. Normally you should call CoInitializeSecurity when your program first starts up, right after your main thread calls CoInitializeEx. But the .NET Framework takes care of calling CoInitializeEx for you. It does it lazily the first time you make a COM interop call, but by the time you've made that call it's already too late to call CoInitializeSecurity! Bah!

Basically what you have to do is manually call three functions:

But you don't want to call that last function until your application is completely finished using COM. In other words, you want to perform steps 1 and 2 right at the beginning of Main and step 3 right at the end of Main, as shown here.

 static void Main() {
    CoInitializeEx(...);
    CoInitializeSecurity(...);
    RunApplicationUntilItsTimeToQuit();
    CoUninitialize();
 }

I've put together some code in the accompanying library 1 that makes this task pretty easy. This code configures COM for high security by default, ensuring that payloads are integrity protected and encrypted, locking down custom marshaling and blocking anonymous callers using null sessions or guest logons. Here's how to use it from a Windows Forms application.

 using System;
 using KBC.WindowsSecurityUtilities;


 [STAThread]
 static void Main() {
    WindowsSecurityUtilities.Initialize();
    COM.InitializeCOM(false);     // choose STA threading model for a GUI app
    COM.InitializeCOMSecurity();  // use secure defaults
    Application.Run(new MainForm());
    COM.UninitializeCOM();
    WindowsSecurityUtilities.Terminate();
 }

For those who need more control, I’ve provided overloaded versions of InitializeCOMSecurity, but be sure to read WhatIsCoInitializeSecurity so you know what the various settings mean.

1 You can download the library from the book's website.

PortedBy KevinKenny

PluralsightTraining

Keith's first book-in-a-wiki. If you would like to read the book online or order a physical copy to throw at annoying coworkers, surf to the HomePage. Please note that due to overwhelming wikispam, this particular wiki is no longer editable.

About FlexWiki.

Recent Topics