Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use default authentication and separate cloaking/impersonation in DCOM call

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
like image 689
ChristianWimmer Avatar asked Jan 03 '10 01:01

ChristianWimmer


1 Answers

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.

like image 110
geekboyUK Avatar answered Sep 22 '22 20:09

geekboyUK