I am trying to achieve two things with DCOM (out of process)
- Establish process authentication using CoInitializeSecurity and its pAuthList parameter.
- Using cloaking to change the caller ID in special situations (COM calls)
My thoughts:
AFAIK in the auth information structure contains default authentication information (for example, username and password for RPC_C_AUTHN_WINNT) for all new COM calls. Therefore, instead of the process token, the information in the auth structure should be used by COM. However, all COM calls / connections always use the process identifier instead of the default one.
You can usually use CoSetProxyBlanket to change the auth information for a proxy. This works for me. My question here is whether it should work or not work if I issue a token myself and call the COM function. I read in various MSDN articles that applying EOAC_DYNAMIC_CLOAKING to CoInitializeSecurity should make it work. However, my manual "impersonated COM calls" always show the server-side process identifier.
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 set the EOAC_DYNAMIC_CLOAKING flag. It uses CoImpersonateClient to get the stream token and username. It also uses CoQueryClientBlanket to get authInfo (as a SEC_WINNT_AUTH_IDENTITY_W structure). However, both calls always return the client process ID.
Also, handing yourself out manually does not work (2.):
Token := TJwSecurityToken.CreateLogonUser(authidentity.User, '', authidentity.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT); Token.ImpersonateLoggedOnUser; int := CoSecurityTestObj.Create; int.TestCall;
Questions again:
Am I mistaken, or why is the default authentication data structure (WinNT with username and password) not used as the default authentication in every COM connection / call?
Am I mistaken or why manual impersonation does not work? Keep in mind that I tested number 2. separately, so number 1. cannot interfere.
This is the main job for the Windows JEDI Security Code Library, which I am distributing to support COM security. Therefore your help will go GPL / MPL.
Literature:
Cloaking:
CoInitializeSecurity and pAuthInfo
Obtaining protective coverage (server side)
security delphi com
ChristianWimmer Jan 03 '09 at 1:55
source share