C++를 사용하여 기본 프로세스 보안 수준 설정

클라이언트 애플리케이션이 WMI(Windows Management Instrumentation)에 처음으로 로그온하는 경우 CoInitializeSecurity를 호출하여 기본 프로세스 보안 수준을 설정해야 합니다. COM은 호출의 정보를 사용하여 다른 프로세스가 클라이언트 애플리케이션 프로세스에 액세스해야 하는 보안을 결정합니다.

이 항목에서 다루는 섹션은 다음과 같습니다.

대부분의 클라이언트 애플리케이션에서 다음 예제에 표시된 인수는 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;
}

코드를 올바르게 컴파일하려면 다음 참조 및 #include 문이 필요합니다.

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

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

인증 수준을 RPC_C_AUTHN_LEVEL_DEFAULT로 설정하면 DCOM이 대상 컴퓨터의 보안 요구 사항에 맞게 인증 수준을 협상할 수 있습니다. 자세한 내용은 C++를 사용하여 기본 인증 자격 증명 변경C++를 사용하여 기본 가장 설정 변경을 참조하세요.

C++를 사용하여 기본 인증 자격 증명 변경

기본 인증 자격 증명은 대부분의 상황에서 작동하지만 다양한 상황에서 다른 인증 자격 증명을 사용해야 할 수 있습니다. 예를 들어 인증 절차에 암호화를 추가할 수 있습니다.

다음 표에서는 다양한 인증 수준을 나열하고 설명합니다.

인증 수준 설명
RPC_C_AUTHN_LEVEL_DEFAULT 기본 보안 인증.
RPC_C_AUTHN_LEVEL_NONE 인증 없음.
RPC_C_AUTHN_LEVEL_CONNECT 클라이언트가 서버와의 관계를 만드는 경우에만 인증합니다.
RPC_C_AUTHN_LEVEL_CALL 서버가 RPC를 받을 때마다 인증합니다.
RPC_C_AUTHN_LEVEL_PKT 서버가 클라이언트에서 데이터를 받을 때마다 인증합니다.
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 패킷의 데이터가 수정되지 않은 인증입니다.
RPC_C_AUTHN_LEVEL_PKT_PRIVACY 이전 모든 인증 수준을 포함하며 각 RPC 호출 값을 암호화합니다.

 

CoInitializeSecuritypAuthList 매개 변수에서 SOLE_AUTHENTICATION_LIST 구조를 사용하여 여러 사용자에 대한 기본 인증 자격 증명을 지정할 수 있습니다.

다음 코드 예제에서는 인증 자격 증명을 변경하는 방법을 보여 줍니다.

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

C++를 사용하여 기본 가장 수준 변경

COM은 시스템 레지스트리에서 읽은 기본 보안 수준을 제공합니다. 그러나 특별히 수정하지 않는 한 레지스트리 설정은 WMI가 작동하기에는 가장 수준을 너무 낮게 설정합니다. 일반적으로 기본 가장 수준은 RPC_C_IMP_LEVEL_IDENTIFY이지만, WMI가 대부분의 공급자에서 작동하려면 최소 RPC_C_IMP_LEVEL_IMPERSONATE가 필요하며 더 높은 수준의 가장을 설정해야 하는 상황이 발생할 수 있습니다. 자세한 내용은 원격 컴퓨터에서 WMI에 연결을 참조하세요. 다음 표에는 다양한 수준의 가장이 나와 있습니다.

Level 설명
RPC_C_IMP_LEVEL_DEFAULT 운영 체제는 가장 수준을 선택합니다.
RPC_C_IMP_LEVEL_ANONYMOUS 서버는 클라이언트를 가장할 수 있지만 가장 토큰은 어떤 용도로도 사용할 수 없습니다.
RPC_C_IMP_LEVEL_IDENTIFY 서버는 클라이언트의 ID를 가져오고 ACL 검사를 위해 클라이언트를 가장할 수 있습니다.
RPC_C_IMP_LEVEL_IMPERSONATE 서버는 한 컴퓨터 경계에서 클라이언트를 가장할 수 있습니다.
RPC_C_IMP_LEVEL_DELEGATE 서버는 여러 경계에서 클라이언트를 가장할 수 있으며 클라이언트를 대신하여 호출할 수 있습니다.