42

I'm trying achieve two things with DCOM (Out of process)

  1. Set the process wide authentication using CoInitializeSecurity and its parameter pAuthList.
  2. Using cloaking to change the caller's identity in special situations (COM calls)

My thoughts:

  1. AFAIK the auth info structure contains the default authentication information (like username and password for RPC_C_AUTHN_WINNT) for all new COM calls. So instead of the process token the information in the auth structure should be used by COM. However, all COM calls/connections are always using the process' identity instead of the applied default one.

  2. Usually, one can use CoSetProxyBlanket to change the auth info for a proxy. This works for me. My question here is whether it must or must not work if I impersonate the token myself and call the COM function. I've read in various MSDN articles that applying EOAC_DYNAMIC_CLOAKING to CoInitializeSecurity should make it working. However, my manually "impersonated COM calls always shows the process identity on the server side.

The client looks like this (Delphi)

var
authList : SOLE_AUTHENTICATION_LIST;
authidentity : SEC_WINNT_AUTH_IDENTITY_W;
authInfo : array[0..1] of SOLE_AUTHENTICATION_INFO;

pcAuthSvc : DWORD;
asAuthSvc : array[0..0] of SOLE_AUTHENTICATION_SERVICE;
Token : TJwSecurityToken;

begin
ZeroMemory( @authidentity, sizeof(authidentity) );

authidentity.User := 'Testbenutzer';
authidentity.UserLength := Length('Testbenutzer');
authidentity.Domain := '';
authidentity.DomainLength := 0;
authidentity.Password := 'test';
authidentity.PasswordLength := 4;
authidentity.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE;


ZeroMemory( @authInfo, sizeof( authInfo ) );

// NTLM Settings
authInfo[0].dwAuthnSvc := RPC_C_AUTHN_WINNT;
authInfo[0].dwAuthzSvc := RPC_C_AUTHZ_NONE;
authInfo[0].pAuthInfo := @authidentity;



authList.cAuthInfo := 1;
authList.aAuthInfo := @authInfo;

OleCheck(CoInitializeSecurity(
  NULL,                            // Security descriptor
  -1,                              // Count of entries in asAuthSvc
  NULL,                            // asAuthSvc array
  NULL,                            // Reserved for future use
  RPC_C_AUTHN_LEVEL_CONNECT,       // Authentication level
  RPC_C_IMP_LEVEL_IMPERSONATE,     // Impersonation level
  @authList,                       // Authentication Information
  DWORd(EOAC_DYNAMIC_CLOAKING),                       // Additional capabilities
  NULL                             // Reserved
  ));
//create COM object
int := CoSecurityTestObj.Create;
int.TestCall;

The server also has set the flag EOAC_DYNAMIC_CLOAKING. It uses CoImpersonateClient to get the thread token and the username. It also uses CoQueryClientBlanket to get the authInfo (as SEC_WINNT_AUTH_IDENTITY_W structure). However both calls always return the process identity of the client.

Also impersonating manually doesn't work (2.):

Token := TJwSecurityToken.CreateLogonUser(authidentity.User, '', authidentity.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT);
 Token.ImpersonateLoggedOnUser;
 int := CoSecurityTestObj.Create;
 int.TestCall;

Questions again:

  1. Am I wrong or why is the default auth info structure (WinNT with username and password) not used as default authentication in each COM connection/call ?

  2. Am I wrong or why doesn't manual impersonation work? Be aware that I tested number 2. separately so number 1. cannot interfere.

This is basic work for the JEDI Windows Security Code Library which I extend to support COM security. So your help will go GPL/MPL.

References:

Cloaking:

  1. http://msdn.microsoft.com/en-us/library/ms683778%28VS.85%29.aspx
  2. http://msdn.microsoft.com/en-us/library/cc246058%28PROT.10%29.aspx
  3. http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsCoInitializeSecurity.html

CoInitializeSecurity and pAuthInfo

  1. http://www.codeguru.cn/vc&mfc/apracticalguideusingvisualcandatl/93.htm

Getting security blanket (server side)

  1. http://www.codeguru.cn/vc&mfc/apracticalguideusingvisualcandatl/92.htm
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
ChristianWimmer
  • 1,039
  • 8
  • 16
  • 2
    Solved number #2. The constant EOAC_DYNAMIC_CLOAKING was defined wrong. *stupidme* – ChristianWimmer Jan 03 '10 at 02:18
  • In case 1. it should use the current identity but only if it is able to delegate it, which is only in a Kerberos i.e. domain environment. Also the process identity must be "trusted for delegation". If there is a remote client and you are trying to call on to another server (2 hops) legacy NTLM authentication will not allow that. – Ben Feb 02 '12 at 16:37
  • Did you ever get to solve the CoInitializeSecurity to have effect process wide for client? – misterti Feb 04 '19 at 10:21

1 Answers1

1

Have you tried calling CoInitializeSecurity() with RPC_C_AUTHN_LEVEL_CALL instead of RPC_C_AUTHN_LEVEL_CONNECT?

Usually when I create DCOM clients I create COSERVERINFO and pass to CoCreateInstanceEx() with security credentials, remembering to call CoSetProxyBlanket() on all interfaces.

geekboyUK
  • 498
  • 4
  • 14