Dela via


Ställa in säkerhet för ett asynkront anrop

Asynkrona anrop medför allvarliga säkerhetsrisker eftersom ett återanrop till mottagare kanske inte är ett resultat av det asynkrona anropet från det ursprungliga programmet eller skriptet. Säkerheten i fjärranslutningar baseras på kryptering av kommunikationen mellan klienten och providern på fjärrdatorn. I C++ kan du ange kryptering via parametern för autentiseringsnivå i anropet till CoInitializeSecurity. I skript anger du AuthenticationLevel- i moniker-anslutningen eller på ett SWbemSecurity-objekt. Mer information finns i Ange standardprocesssäkerhetsnivå med VBScript-.

Säkerhetsriskerna för asynkrona anrop finns eftersom WMI sänker autentiseringsnivån vid ett återanrop tills återanropet lyckas. Vid ett utgående asynkront anrop kan klienten ange autentiseringsnivån på anslutningen till WMI. WMI hämtar säkerhetsinställningarna för klientanropet och försöker anropa tillbaka med samma autentiseringsnivå. Återanropet initieras alltid på RPC_C_AUTHN_LEVEL_PKT_PRIVACY-nivå. Om återuppringningen misslyckas, sänker WMI autentiseringsnivån till en nivå där återuppringningen kan lyckas, om det behövs, till RPC_C_AUTHN_LEVEL_NONE. I samband med anrop i det lokala systemet där autentiseringstjänsten inte är Kerberos returneras återanropet alltid på RPC_C_AUTHN_LEVEL_NONE.

Den minsta autentiseringsnivån är RPC_C_AUTHN_LEVEL_PKT (wbemAuthenticationLevelPktför skript). Du kan dock ange en högre nivå, till exempel RPC_C_AUTHN_LEVEL_PKT_PRIVACY (wbemAuthenticationLevelPktPrivacy). Vi rekommenderar att klientprogram eller skript anger autentiseringsnivån till RPC_C_AUTHN_LEVEL_DEFAULT (wbemAuthenticationLevelDefault) som gör att autentiseringsnivån kan förhandlas fram till den nivå som anges av servern.

HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault registervärde styr om WMI söker efter en acceptabel autentiseringsnivå i motringningar. Det här är den enda mekanismen för att skydda mottagarsäkerhet för asynkrona anrop som görs i skript eller Visual Basic. Som standard är registernyckeln inställd på noll. Om registernyckeln är noll verifierar inte WMI autentiseringsnivåer. Om du vill skydda asynkrona anrop i skript anger du registernyckeln till 1. C++-klienter kan anropa IWbemUnsecuredApartment::CreateSinkStub för att styra åtkomsten till "sink". Värdet skapas var som helst per automatik.

Följande avsnitt innehåller exempel på hur du ställer in asynkron samtalssäkerhet:

Ställa in asynkron samtalssäkerhet i C++

Metoden IWbemUnsecuredApartment::CreateSinkStub liknar IUnsecuredApartment::CreateObjectStub och skapar en mottagare i en separat process, Unsecapp.exe, för att ta emot återanmälningar. Metoden CreateSinkStub har dock en dwFlag-parameter som anger hur den separata processen hanterar åtkomstkontroll.

Parametern dwFlag anger någon av följande åtgärder för Unsecapp.exe:

  • Använd registernyckelinställningen för att avgöra om åtkomsten ska kontrolleras eller inte.
  • Ignorera registernyckeln och kontrollera alltid åtkomsten.
  • Ignorera registernyckeln och kontrollera aldrig åtkomsten.

Kodexemplet i det här avsnittet kräver följande #include-instruktion för att kompilera korrekt.

#include <wbemidl.h>

Följande procedur beskriver hur du utför ett asynkront anrop med IWbemUnsecuredApartment.

Utför ett asynkront anrop med IWbemUnsecuredApartment

  1. Skapa en dedikerad process med ett anrop till CoCreateInstance.

    I följande kodexempel anropas CoCreateInstance för att skapa en dedikerad process.

    CLSID                    CLSID_WbemUnsecuredApartment;
    IWbemUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_WbemUnsecuredApartment, 
                     NULL, 
                     CLSCTX_LOCAL_SERVER, 
                     IID_IWbemUnsecuredApartment, 
                     (void**)&pUnsecApp);
    
  2. Instansiera sink-objektet.

    I följande kodexempel skapas ett nytt mottagarobjekt.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Skapa en stub för diskbänken.

    En stub är en omslutningsfunktion som härstammar från sinken.

    I följande kodexempel skapas en stub för en datasänka.

    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. Släpp pekaren för sinkobjektet.

    Du kan släppa objektpekaren eftersom stub-filen nu äger pekaren.

    I följande kodexempel frigörs objektpekaren.

    pSink->Release();
    
  5. Använd stub i alla asynkrona anrop.

    När du är klar med anropet släpper du det lokala referensantalet.

    I följande kodexempel används stub i ett asynkront anrop.

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

    Ibland kan du behöva avbryta ett asynkront anrop när du har ringt samtalet. Om du behöver avbryta samtalet avbryter du samtalet med samma pekare som ursprungligen gjorde samtalet.

    I följande kodexempel beskrivs hur du avbryter ett asynkront anrop.

    pServices->CancelAsyncCall(pStubSink);
    
  6. Frigör det lokala referensantalet när du är klar med det asynkrona anropet.

    Se till att släppa pStubSink pekaren först när du har bekräftat att det asynkrona anropet inte behöver avbrytas. Släpp inte pStubSink efter att WMI har släppt pSink mottagarpekare. Genom att släppa pStubSink efter pSink skapas en cirkulär referensräkning där både mottagaren och stuben förblir i minnet för alltid. En möjlig plats att släppa pekaren på istället är i anropet IWbemObjectSink::SetStatus, vilket görs av WMI för att rapportera att det ursprungliga asynkrona anropet är klart.

  7. När du är klar kan du uninitialisera COM med ett anrop till Release().

    Följande kodexempel visar hur du anropar Release() på pekaren pUnsecApp.

    pUnsecApp->Release();
    

Mer information om funktionen och parametrarna CoInitializeSecurity finns i dokumentationen COM.