Securing WMI Connections

At the beginning of this chapter, I mentioned that in order to establish the proper security settings for a WMI session, the client process should call several security API functions such as CoInitializeSecurity and CoSetProxyBlanket. Fortunately, it is not something that a developer of the management applications has to do manually. Here again, the initialization logic of the ManagementScope type kindly takes care of setting the appropriate authentication and impersonation levels for the process. A developer however, is afforded the luxury of controlling both the authentication and the impersonation settings through the instance of the ConnectionOptions type, associated with the ManagementScope object. This type, briefly mentioned above, has the following properties:

• Authentication: Gets or sets the COM authentication level to be used for the WMI connection

• Impersonation: Gets or sets the COM impersonation level to be used for the WMI connection

• Authority: Gets or sets the authority value to be used for the WMI connection

• Locale: Gets or sets the locale value to be used for the WMI connection

• Username: Gets or sets the name of the security principal to be used for theWMI connection

• Password: Gets or sets the password to be used for the WMI connection

• EnablePrivileges: Gets or sets a Boolean flag that indicates whether the privileges are to be enabled for the WMI connection

As you can see, all of these properties, with the exception of the EnablePrivileges, which is discussed later in this chapter, map directly to the parameters of the IWbemLocator::ConnectServer method. However, these properties are also used by the private Secure method of the ManagementScope type, which, during the initialization phase, sets the appropriate authentication and impersonation levels for the process and "blesses" the retrieved IWbemServices interface pointer.

The Username, Password, Locale, and Authority properties of the ConnectionOptions type are governed by the same rules as the respective parameters of the IWbemLocator::ConnectServer method. The Impersonation and Authentication properties, however, are of enumeration types ImpersonationLevel and AuthenticationLevel respectively, which means that you must use a member of the appropriate enumeration when initializing these properties. It should come as no surprise that the members of these enumeration types map one-to-one to the respective COM authentication and impersonation level constants.


Members of AuthenticationLevel Enumeration
MEMBER : Default
COM CONSTANT : RPC_C_AUTH_LEVEL_DEFAULT
DESCRIPTION : Under Windows NT 4.0, this value defaults to RPC_C_AUTH_LEVEL_CONNECT. Under Windows 2000 and later, this value instructs COM to select an appropriate authentication level using its normal security blanket negotiation algorithm.

None
RPC_C_AUTH_LEVEL_NONE
Instructs COM not to perform any authentication.

Connect
RPC_C_AUTH_LEVEL_CONNECT
Causes COM to authenticate the credentials of the client only when the client establishes a session with the server.

Call
RPC_C_AUTH_LEVEL_CALL
Instructs COM to authenticate the client at the beginning of each RPC when the server receives the request.

Packet
RPC_C_AUTH_LEVEL_PKT
Instructs COM to ensure that the data is received from the authenticated client.

PacketIntegrity
RPC_C_AUTH_LEVEL_PKT_INTEGRITY
Causes COM to ensure the integrity of the data received from the client.

PacketPrivacy
RPC_C_AUTH_LEVEL_PKT_PRIVACY
Instructs COM to perform all types of authentication referred to in this table and encrypt all RPC arguments.

Unchanged
The authentication level remains unchanged.




Members of ImpersonationLevel Enumeration
MEMBER : Default
COM CONSTANT : RPC_C_IMP_LEVEL_DEFAULT
DESCRIPTION : This value can be used with Windows 2000 and later. It instructs COM to select an appropriate impersonation level using its normal security blanket negotiation algorithm.

Anonymous
RPC_C_IMT_LEVEL_ANONYMOUS
The client remains anonymous to the server. The impersonation is possible, but since the server's impersonation token will not contain any client security information, the server will not be able to perform any tasks under the security context of the client.

Identity
RPC_C_IMP_LEVEL_IDENTITY
The server's impersonation token will include the client's identity, which implies that the server will be able to impersonate the client for ACL checking. However, the server will not be able to access the system objects on behalf of the client.

Impersonate
RPC_C_IMP_LEVEL_IMPERSONATE
The server may impersonate the client's security context, but only while it is accessing the resources on the local machine on behalf of the client. In other words, the impersonation token cannot be used across the machines' boundaries.

Delegate
RPC_C_IMP_LEVEL_DELEGATE
The server may impersonate the client's security context while accessing the resources on local or remote machines on behalf of the client. The impersonation token can be passed across the machines' boundaries. This impersonation level is available under Windows 2000 and later.

By constructing an instance of the ConnectionOptions type and associating it with the management scope, you may effectively control the security settings for a WMI client process:

ConnectionOptions co = new ConnectionOptions();
co.Username = "Administrator";
co.Password = "password";
co.Authentication = AuthenticationLevel.PacketPrivacy;
co.Impersonation = ImpersonationLevel.Impersonate;
ManagementScope ms = new ManagementScope(@"\\BCK_OFFICE\root\CIMV2", co);
ManagementObject mo = new ManagementObject(@" Win32_Process=100");
mo.Scope = ms;
Console.WriteLine(mo["__CLASS"]);

Unless the ConnectionOptions object is explicitly associated with an instance of the ManagementScope, the latter constructs a default ConnectionOptions instance during its initialization. Therefore, you can use the default object to control the security settings of the process:

ManagementScope ms = new ManagementScope();
ms.Path = new ManagementPath(@"\\BCK_OFFICE\root\CIMV2");
ms.Options.Username = "Administrator";
ms.Options.Password = "password";
ms.Options.Authentication = AuthenticationLevel.PacketPrivacy;
ms.Options.Impersonation = ImpersonationLevel.Impersonate;
ManagementObject mo = new ManagementObject(@" Win32_Process=100");
mo.Scope = ms;
Console.WriteLine(mo["__CLASS"]);

Finally, the ConnectionOptions type is equipped with a convenient constructor method that allows you to set all of the object properties at once. This constructor has the following signature:

public ConnectionOptions (
string locale,
string username,
string password,
string authority,
ImpersonationLevel impersonation,
AuthenticationLevel authentication,
bool enablePrivileges,
ManagementNamedValueCollection context,
TimeSpan timeout
);

where
• locale: A string that specifies the locale (i.e., MS_xxx) to be used for the WMI connection

• username: A string that specifies the name of the user to be used for the WMI connection

• password: A string that specifies the password to be used for the WMI connection

• authority: A string that specifies the authority to be used for the WMI connection

• impersonation: A member of the ImpersonationLevel enumeration that indicates the impersonation level to be used for the WMI connection.

• authentication: A member of the AuthenticationLevel enumeration that indicates the authentication level to be used for the WMI connection

• enablePrivileges: A Boolean flag that indicates whether the privileges are to be enabled for the WMI connection

• context: A ManagementNamedValueCollection that contains providerspecific context values

• timeout: A TimeSpan object that sets the timeout value for the connection operation


Using this constructor, the earlier code may be changed as follows:

ConnectionOptions co = new ConnectionOptions(
null, "Administrator", "password", null, ImpersonationLevel.Impersonate,
AuthenticationLevel.PacketPrivacy, false, null, new TimeSpan());
ManagementScope ms = new ManagementScope(@"\\BCK_OFFICE\root\CIMV2", co);
ManagementObject mo = new ManagementObject(@" Win32_Process=100");
mo.Scope = ms;
Console.WriteLine(mo["__CLASS"]);

Although using this constructor may save you a bit of typing, it certainly does not promote code readability and lacks in clarity when compared to setting the properties of the ConnectionOptions object explicitly.

Source of Information : Dot NET System Management Services - Apress

0 comments


Subscribe to Developer Techno ?
Enter your email address:

Delivered by FeedBurner