Definir o nível de segurança do processo padrão usando C++

Quando um aplicativo cliente faz logon no WMI (Instrumentação de Gerenciamento do Windows) pela primeira vez, ele deve definir o nível de segurança do processo padrão com uma chamada para CoInitializeSecurity. O COM usa as informações na chamada para determinar quanta segurança o outro processo deve ter para acessar o processo do aplicativo cliente.

As seguintes seções serão abordadas neste tópico:

Para a maioria dos aplicativos cliente, os argumentos mostrados no exemplo a seguir definem a segurança padrão para o WMI.

HRESULT hr = NULL;
hr = CoInitializeSecurity(
        NULL,                       // security descriptor
       -1,                          // use this simple setting
       NULL,                        // use this simple setting
       NULL,                        // reserved
       RPC_C_AUTHN_LEVEL_DEFAULT,   // authentication level  
       RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
       NULL,                        // use this simple setting
       EOAC_NONE,                   // no special capabilities
       NULL);                          // reserved

if (FAILED(hr))
{
  CoUninitialize();
  cout << "Failed to initialize security. Error code = 0x"
       << hex << hr << endl;
  return;
}

O código requer as referências a seguir e as instruções #include para compilar corretamente.

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

Definir o nível de autenticação como RPC_C_AUTHN_LEVEL_DEFAULT permite que o DCOM negocie o nível de autenticação para corresponder às demandas de segurança do computador de destino. Para obter mais informações, consulte Alterar as credenciais de autenticação padrão usando C++ e Alterar as configurações de representação padrão usando C++.

Alterar as credenciais de autenticação padrão usando C++

As credenciais de autenticação padrão funcionam para a maioria das situações, mas talvez seja necessário usar credenciais de autenticação diferentes em situações diferentes. Por exemplo, talvez você queira adicionar criptografia aos procedimentos de autenticação.

A tabela a seguir lista e descreve os diferentes níveis de autenticação.

Nível de autenticação Descrição
RPC_C_AUTHN_LEVEL_DEFAULT Autenticação de segurança padrão.
RPC_C_AUTHN_LEVEL_NONE Sem autenticação.
RPC_C_AUTHN_LEVEL_CONNECT Autenticação somente quando o cliente cria uma relação com o servidor.
RPC_C_AUTHN_LEVEL_CALL Autenticação sempre que o servidor recebe um RPC.
RPC_C_AUTHN_LEVEL_PKT Autenticação sempre que o servidor recebe dados de um cliente.
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY Autenticação de que nenhum dado do pacote foi modificado.
RPC_C_AUTHN_LEVEL_PKT_PRIVACY Inclui todos os níveis de autenticação anteriores e criptografa o valor de cada chamada RPC.

 

Você pode especificar as credenciais de autenticação padrão para vários usuários usando uma estrutura SOLE_AUTHENTICATION_LIST no parâmetro pAuthList de CoInitializeSecurity.

O exemplo de código a seguir mostra como alterar as credenciais de autenticação.

// Auth Identity structure
SEC_WINNT_AUTH_IDENTITY_W        authidentity;
SecureZeroMemory( &authidentity, sizeof(authidentity) );

authidentity.User = L"MyUser";
authidentity.UserLength = wcslen( authidentity.User );
authidentity.Domain = L"MyDomain ";
authidentity.DomainLength = wcslen( authidentity.Domain );
authidentity.Password = L"";
authidentity.PasswordLength = wcslen( authidentity.Password );
authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

SecureZeroMemory( authninfo, sizeof(SOLE_AUTHENTICATION_INFO)*2 );

// NTLM Settings
authninfo[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
authninfo[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[0].pAuthInfo = &authidentity;

// Kerberos Settings
authninfo[1].dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS ;
authninfo[1].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[1].pAuthInfo = &authidentity;

SOLE_AUTHENTICATION_LIST    authentlist;

authentlist.cAuthInfo = 2;
authentlist.aAuthInfo = authninfo;

CoInitializeSecurity( 
  NULL, 
  -1, 
  NULL, 
  NULL, 
  RPC_C_AUTHN_LEVEL_CALL, 
  RPC_C_IMP_LEVEL_IMPERSONATE,
  &authentlist, 
  EOAC_NONE,
  NULL);

Alterar os níveis de representação padrão usando C++

O COM fornece níveis de segurança padrão lidos do registro do sistema. No entanto, a menos que especificamente modificado, as configurações do registro definem um nível muito baixo de representação para que o WMI funcione. Normalmente, o nível de representação padrão é RPC_C_IMP_LEVEL_IDENTIFY, mas o WMI precisa de pelo menos RPC_C_IMP_LEVEL_IMPERSONATE para funcionar com a maioria dos provedores e você pode encontrar uma situação em que você precisa definir um nível mais alto de representação. Para obter mais informações, consulte Conexão ao WMI em um computador remoto. A tabela a seguir lista os diferentes níveis de representação.

Nível Descrição
RPC_C_IMP_LEVEL_DEFAULT O sistema operacional escolhe o nível de representação.
RPC_C_IMP_LEVEL_ANONYMOUS O servidor pode representar o cliente, mas o token de representação não pode ser usado para nada.
RPC_C_IMP_LEVEL_IDENTIFY O servidor pode obter a identidade do cliente e representá-lo para verificação de ACL.
RPC_C_IMP_LEVEL_IMPERSONATE O servidor pode representar o cliente em um limite de computador.
RPC_C_IMP_LEVEL_DELEGATE O servidor pode representar o cliente em vários limites e pode fazer chamadas em nome do cliente.