Udostępnij za pośrednictwem


Ustawianie domyślnego poziomu zabezpieczeń procesu przy użyciu języka C++

Gdy aplikacja kliencka loguje się do instrumentacji zarządzania Windows (WMI) po raz pierwszy, musi ustawić domyślny poziom zabezpieczeń procesu z wywołaniem CoInitializeSecurity. COM używa informacji w wywołaniu, aby określić, jaki poziom zabezpieczeń musi mieć inny proces, aby uzyskać dostęp do procesu aplikacji klienckiej.

W tym temacie omówiono następujące sekcje:

W przypadku większości aplikacji klienckich argumenty pokazane w poniższym przykładzie ustawiają domyślne zabezpieczenia dla usługi 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;
}

Kod wymaga następujących odwołań i instrukcji #include w celu poprawnego skompilowania.

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

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

Ustawienie poziomu uwierzytelniania na RPC_C_AUTHN_LEVEL_DEFAULT umożliwia dcOM negocjowanie poziomu uwierzytelniania w celu dopasowania do wymagań dotyczących zabezpieczeń komputera docelowego. Aby uzyskać więcej informacji, zobacz Zmienianie domyślnych poświadczeń uwierzytelniania przy użyciu języka C++ i Zmienianie domyślnych ustawień personifikacji przy użyciujęzyka C++.

Zmienianie domyślnych poświadczeń uwierzytelniania przy użyciu języka C++

Domyślne poświadczenia uwierzytelniania działają w większości sytuacji, ale może być konieczne użycie różnych poświadczeń uwierzytelniania w różnych sytuacjach. Na przykład możesz dodać szyfrowanie do procedur uwierzytelniania.

W poniższej tabeli wymieniono i opisano różne poziomy uwierzytelniania.

Poziom uwierzytelniania Opis
RPC_C_AUTHN_LEVEL_DEFAULT (domyślny poziom uwierzytelniania) Domyślne uwierzytelnianie zabezpieczeń.
RPC_C_AUTHN_LEVEL_NONE Brak uwierzytelniania.
RPC_C_AUTHN_LEVEL_CONNECT Uwierzytelnianie tylko wtedy, gdy klient tworzy relację z serwerem.
RPC_C_AUTHN_LEVEL_CALL Uwierzytelnianie za każdym razem, gdy serwer otrzymuje RPC.
RPC_C_AUTHN_LEVEL_PKT Uwierzytelnianie za każdym razem, gdy serwer odbiera dane od klienta.
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY Uwierzytelnianie, że żadne dane z pakietu nie zostały zmodyfikowane.
RPC_C_AUTHN_LEVEL_PKT_PRIVACY Obejmuje wszystkie poprzednie poziomy uwierzytelniania i szyfruje wartość każdego wywołania RPC.

 

Domyślne poświadczenia uwierzytelniania dla wielu użytkowników można określić przy użyciu struktury SOLE_AUTHENTICATION_LIST w parametrze pAuthList CoInitializeSecurity.

Poniższy przykład kodu pokazuje, jak zmienić poświadczenia uwierzytelniania.

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

Zmienianie domyślnych poziomów personifikacji przy użyciu języka C++

Model COM zapewnia domyślne poziomy zabezpieczeń odczytane z rejestru systemowego. Jednak jeśli nie zostaną specjalnie zmodyfikowane, ustawienia rejestru ustawiają zbyt niski poziom personifikacji, aby usługa WMI działała. Zazwyczaj domyślny poziom podszywania się to RPC_C_IMP_LEVEL_IDENTIFY, ale usługa WMI wymaga co najmniej RPC_C_IMP_LEVEL_IMPERSONATE do działania z większością dostawców. Może zaistnieć konieczność ustawienia wyższego poziomu podszywania się. Aby uzyskać więcej informacji, zobacz Nawiązywanie połączenia z usługą WMI na komputerze zdalnym. W poniższej tabeli wymieniono różne poziomy personifikacji.

Poziom Opis
RPC_C_IMP_LEVEL_DEFAULT System operacyjny wybiera poziom personifikacji.
RPC_C_IMP_LEVEL_ANONYMOUS Serwer może personifikować klienta, ale token personifikacji nie może być używany dla niczego.
RPC_C_IMP_LEVEL_IDENTIFY Serwer może uzyskać tożsamość klienta i podszyć się pod klienta na potrzeby kontroli ACL.
RPC_C_IMP_LEVEL_IMPERSONATE Serwer może podszywać się pod klienta w obrębie jednej granicy sieciowej.
RPC_C_IMP_LEVEL_DELEGATE Serwer może udawać klienta, przekraczać wiele granic i dokonywać wywołań w imieniu klienta.