Sdílet prostřednictvím


Nastavení zabezpečení asynchronního volání

Asynchronní volání představují závažná bezpečnostní rizika, protože zpětné volání do jímky nemusí být výsledkem asynchronního volání původní aplikace nebo skriptu. Zabezpečení vzdálených připojení je založeno na šifrování komunikace mezi klientem a poskytovatelem na vzdáleném počítači. V jazyce C++ můžete nastavit šifrování prostřednictvím parametru úrovně ověřování ve volání CoInitializeSecurity. Ve skriptování nastavte AuthenticationLevel v připojení moniker nebo v objektu SWbem Security. Další informace naleznete v tématu Nastavení výchozí úrovně zabezpečení procesu pomocí jazyka VBScript.

Existují bezpečnostní rizika pro asynchronní volání, protože rozhraní WMI snižuje úroveň ověřování u zpětného volání, dokud zpětné volání nebude úspěšné. Při odchozím asynchronním volání může klient nastavit úroveň ověřování u připojení k rozhraní WMI. Rozhraní WMI načte nastavení zabezpečení pro volání klienta a pokusí se volat zpět se stejnou úrovní ověřování. Zpětné volání je vždy zahájeno na úrovni RPC_C_AUTHN_LEVEL_PKT_PRIVACY. Pokud zpětné volání selže, WMI sníží úroveň ověřování na takovou úroveň, kde může zpětné volání uspět, v případě potřeby na RPC_C_AUTHN_LEVEL_NONE. V kontextu volání v rámci místního systému, kde není ověřovací služba Kerberos, je vždy vráceno zpětné volání na RPC_C_AUTHN_LEVEL_NONE.

Minimální úroveň ověřování je RPC_C_AUTHN_LEVEL_PKT (wbemAuthenticationLevelPktpro skriptování). Můžete však zadat vyšší úroveň, například RPC_C_AUTHN_LEVEL_PKT_PRIVACY (wbemAuthenticationLevelPktPrivacy). Doporučuje se, aby klientské aplikace nebo skripty nastavily úroveň ověřování na RPC_C_AUTHN_LEVEL_DEFAULT (wbemAuthenticationLevelDefault), která umožňuje vyjednat úroveň ověřování na úroveň určenou serverem.

HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault hodnota registru určuje, jestli služba WMI kontroluje přijatelnou úroveň ověřování ve zpětných voláních. Toto je jediný mechanismus pro ochranu zabezpečení jímky pro asynchronní volání provedená ve skriptování nebo v jazyce Visual Basic. Ve výchozím nastavení je tento klíč registru nastaven na nulu. Pokud je klíč registru nulový, služba WMI neověří úrovně ověřování. Pokud chcete zabezpečit asynchronní volání ve skriptování, nastavte klíč registru na hodnotu 1. Klienti C++ mohou volat IWbemUnsecuredApartment::CreateSinkStub k řízení přístupu k sinku. Hodnota se ve výchozím nastavení vytvoří kdekoli.

Následující témata obsahují příklady nastavení zabezpečení asynchronních volání:

Nastavení zabezpečení asynchronního volání v jazyce C++

Metoda IWbemUnsecuredApartment::CreateSinkStub se podobá metodě IUnsecuredApartment::CreateObjectStub a vytvoří sink v samostatném procesu, Unsecapp.exe, pro přijímání zpětných volání. Metoda CreateSinkStub má však parametr dwFlag, který určuje, jak samostatný proces zpracovává řízení přístupu.

Parametr dwFlag určuje jednu z následujících akcí pro Unsecapp.exe:

  • Pomocí nastavení klíče registru určete, jestli chcete zkontrolovat přístup nebo ne.
  • Ignorujte klíč registru a vždy zkontrolujte přístup.
  • Ignorujte klíč registru a nikdy nekontrolujte přístup.

Příklad kódu v tomto tématu vyžaduje, aby se správně zkompiloval následující příkaz #include.

#include <wbemidl.h>

Následující postup popisuje, jak provést asynchronní volání s IWbemUnsecuredApartment.

Chcete-li provést asynchronní volání pomocí IWbemUnsecuredApartment

  1. Vytvořte vyhrazený proces voláním CoCreateInstance .

    Následující příklad kódu volá CoCreateInstance k vytvoření vyhrazeného procesu.

    CLSID                    CLSID_WbemUnsecuredApartment;
    IWbemUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_WbemUnsecuredApartment, 
                     NULL, 
                     CLSCTX_LOCAL_SERVER, 
                     IID_IWbemUnsecuredApartment, 
                     (void**)&pUnsecApp);
    
  2. Vytvořte instanci objektu jímky.

    Následující příklad kódu vytvoří nový objekt jímky.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Vytvořte zástupnou funkci pro sink.

    Zástupný procedura je obalová funkce vytvořená z jímky.

    Následující příklad kódu vytvoří zástupný kód pro jímku.

    LPCWSTR          wszReserved = NULL;           
    IWbemObjectSink* pStubSink   = NULL;
    IUnknown*        pStubUnk    = NULL; 
    
    pUnsecApp->CreateSinkStub(pSink,
                              WBEM_FLAG_UNSECAPP_CHECK_ACCESS,  //Authenticate callbacks regardless of registry key
                              wszReserved,
                              &pStubSink);
    
  4. Uvolněte ukazatel objektu jímky.

    Ukazatel objektu můžete uvolnit, protože zástupný objekt teď vlastní ukazatel.

    Následující příklad kódu uvolní ukazatel objektu.

    pSink->Release();
    
  5. Zástupný kód použijte v libovolném asynchronním volání.

    Po dokončení volání uvolněte místní referenční počet.

    Následující příklad kódu používá zástupný kód v asynchronním volání.

    // pServices is an IWbemServices* object
    pServices->CreateInstanceEnumAsync(strClassName, 0, NULL, pStubSink);
    

    Někdy možná budete muset zrušit asynchronní volání po jeho uskutečnění. Pokud potřebujete hovor zrušit, zrušte hovor stejným ukazatelem, který původně hovor provedl.

    Následující příklad kódu popisuje, jak zrušit asynchronní volání.

    pServices->CancelAsyncCall(pStubSink);
    
  6. Po dokončení asynchronního volání uvolněte místní referenční počet.

    Nezapomeňte uvolnit ukazatel pStubSink až poté, co potvrdíte, že asynchronní volání nesmí být zrušeno. Dále neuvolňujte pStubSink poté, co WMI uvolní ukazatel pSink sink. Uvolnění pStubSink po pSink vytvoří cyklickou referenci, ve které sink i stub zůstávají v paměti navždy. Místo pro uvolnění ukazatele je možné najít ve volání IWbemObjectSink::SetStatus, vytvořeném rozhraním WMI, aby ohlásilo, že původní asynchronní volání bylo dokončeno.

  7. Po dokončení ukončete inicializaci COM voláním Release().

    Následující příklad kódu ukazuje, jak zavolat Release() na ukazateli pUnsecApp.

    pUnsecApp->Release();
    

Další informace o funkci a jejích parametrech CoInitializeSecurity naleznete v dokumentaci COM .