Impostazione del livello di sicurezza del processo predefinito con C++

Quando un'applicazione client accede a Strumentazione gestione Windows (WMI) per la prima volta, deve impostare il livello di sicurezza del processo predefinito con una chiamata a CoInitializeSecurity. COM usa le informazioni nella chiamata per determinare la quantità di sicurezza che un altro processo deve avere per accedere al processo dell'applicazione client.

In questo argomento vengono illustrate le sezioni seguenti:

Per la maggior parte delle applicazioni client, gli argomenti illustrati nell'esempio seguente impostano la sicurezza predefinita per 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;
}

Il codice richiede che i riferimenti e le istruzioni #include seguenti vengano compilati correttamente.

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

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

L'impostazione del livello di autenticazione su RPC_C_AUTHN_LEVEL_DEFAULT consente a DCOM di negoziare il livello di autenticazione in modo che corrisponda alle richieste di sicurezza del computer di destinazione. Per altre informazioni, vedere Modifica delle credenziali di autenticazione predefinite con C++ e Modifica delle impostazioni di rappresentazione predefinite con C++.

Modifica delle credenziali di autenticazione predefinite con C++

Le credenziali di autenticazione predefinite funzionano per la maggior parte delle situazioni, ma potrebbe essere necessario usare credenziali di autenticazione diverse in situazioni diverse. Ad esempio, è possibile aggiungere la crittografia alle procedure di autenticazione.

La tabella seguente elenca e descrive i diversi livelli di autenticazione.

Livello di autenticazione Descrizione
RPC_C_AUTHN_LEVEL_DEFAULT Autenticazione di sicurezza predefinita.
RPC_C_AUTHN_LEVEL_NONE Nessuna autenticazione.
RPC_C_AUTHN_LEVEL_CONNECT Autenticazione solo quando il client crea una relazione con il server.
RPC_C_AUTHN_LEVEL_CALL Autenticazione ogni volta che il server riceve un RPC.
RPC_C_AUTHN_LEVEL_PKT Autenticazione ogni volta che il server riceve i dati da un client.
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY Autenticazione che non ha modificato dati dal pacchetto.
RPC_C_AUTHN_LEVEL_PKT_PRIVACY Include tutti i livelli di autenticazione precedenti e crittografa il valore di ogni chiamata RPC.

 

È possibile specificare le credenziali di autenticazione predefinite per più utenti usando una struttura SOLE_AUTHENTICATION_LIST nel parametro pAuthList di CoInitializeSecurity.

Nell'esempio di codice seguente viene illustrato come modificare le credenziali di autenticazione.

// 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);

Modifica dei livelli di rappresentazione predefiniti con C++

COM fornisce i livelli di sicurezza predefiniti letti dal Registro di sistema. Tuttavia, a meno che non venga modificata in modo specifico, le impostazioni del Registro di sistema impostano il livello di rappresentazione troppo basso per il funzionamento di WMI. In genere, il livello di rappresentazione predefinito è RPC_C_IMP_LEVEL_IDENTIFY, ma WMI richiede almeno RPC_C_IMP_LEVEL_IMPERSONATE per funzionare con la maggior parte dei provider e si potrebbe riscontrare una situazione in cui è necessario impostare un livello di rappresentazione superiore. Per altre informazioni, vedere Connessione a WMI in un computer remoto. Nella tabella seguente sono elencati i diversi livelli di rappresentazione.

Level Descrizione
RPC_C_IMP_LEVEL_DEFAULT Il sistema operativo sceglie il livello di rappresentazione.
RPC_C_IMP_LEVEL_ANONYMOUS Il server può rappresentare il client, ma non è possibile usare il token di rappresentazione per qualsiasi elemento.
RPC_C_IMP_LEVEL_IDENTIFY Il server può ottenere l'identità del client e rappresentare il client per il controllo ACL.
RPC_C_IMP_LEVEL_IMPERSONATE Il server può rappresentare il client attraverso un limite del computer.
RPC_C_IMP_LEVEL_DELEGATE Il server può rappresentare il client attraverso più limiti e può effettuare chiamate per conto del client.