Beveiliging instellen voor een asynchrone aanroep
Asynchrone aanroepen vormen ernstige beveiligingsrisico's omdat een callback naar de sink mogelijk niet het gevolg is van de asynchrone aanroep door de oorspronkelijke toepassing of het oorspronkelijke script. Beveiliging in externe verbindingen is gebaseerd op versleuteling van de communicatie tussen de client en de provider op de externe computer. In C++ kunt u versleuteling instellen via de parameter op verificatieniveau in de aanroep naar CoInitializeSecurity. Stel bij het uitvoeren van scripts de AuthenticationLevel- in de moniker-verbinding of op een SWbemSecurity--object in. Zie Het standaardbeveiligingsniveau voor procesbeveiliging instellen met behulp van VBScript-voor meer informatie.
De beveiligingsrisico's voor asynchrone aanroepen bestaan omdat WMI het verificatieniveau voor een callback verlaagt totdat de callback slaagt. Bij een uitgaande asynchrone aanroep kan de client het verificatieniveau voor de verbinding met WMI instellen. WMI haalt de beveiligingsinstellingen voor de clientoproep op en probeert terug te bellen met hetzelfde verificatieniveau. De callback wordt altijd geïnitieerd op het RPC_C_AUTHN_LEVEL_PKT_PRIVACY niveau. Als de callback mislukt, verlaagt WMI het verificatieniveau tot een niveau waarop de callback, indien nodig, kan slagen op RPC_C_AUTHN_LEVEL_NONE. In de context van aanroepen binnen het lokale systeem waar de verificatieservice niet Kerberos is, wordt de callback altijd geretourneerd op RPC_C_AUTHN_LEVEL_NONE.
Het minimale verificatieniveau is RPC_C_AUTHN_LEVEL_PKT (wbemAuthenticationLevelPkt-voor scripting). U kunt echter een hoger niveau opgeven, zoals RPC_C_AUTHN_LEVEL_PKT_PRIVACY (wbemAuthenticationLevelPktPrivacy). Het wordt aanbevolen dat clienttoepassingen of scripts het verificatieniveau instellen op RPC_C_AUTHN_LEVEL_DEFAULT (wbemAuthenticationLevelDefault) waarmee het verificatieniveau kan worden onderhandeld naar het niveau dat door de server is opgegeven.
De HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault registerwaarde bepaalt of WMI controleert op een acceptabel verificatieniveau in callbacks. Dit is het enige mechanisme om de beveiliging van sinks te beschermen voor asynchrone aanroepen in scripts of Visual Basic. Deze registersleutel is standaard ingesteld op nul. Als de registersleutel nul is, controleert WMI geen verificatieniveaus. Als u asynchrone aanroepen in scripts wilt beveiligen, stelt u de registersleutel in op 1. C++-clients kunnen IWbemUnsecuredApartment aanroepen::CreateSinkStub om de toegang tot de sink te beheren. De waarde wordt standaard overal gecreëerd.
De volgende onderwerpen bevatten voorbeelden van het instellen van asynchrone aanroepbeveiliging:
- beveiliging instellen voor een asynchrone aanroep in VBScript-
- Asynchrone oproepbeveiliging instellen in C++
Asynchrone oproepbeveiliging instellen in C++
De methode IWbemUnsecuredApartment::CreateSinkStub is vergelijkbaar met de methode IUnsecuredApartment::CreateObjectStub en maakt een "sink" in een afzonderlijk proces Unsecapp.exeaan om callbacks te ontvangen. De methode CreateSinkStub heeft echter een dwFlag-parameterdie aangeeft hoe het afzonderlijke proces toegangsbeheer verwerkt.
De parameter dwFlag geeft een van de volgende acties op voor Unsecapp.exe:
- Gebruik de registersleutelinstelling om te bepalen of de toegang al dan niet moet worden gecontroleerd.
- Negeer de registersleutel en controleer altijd de toegang.
- Negeer de registersleutel en controleer nooit de toegang.
Voor het codevoorbeeld in dit onderwerp is de volgende #include instructie vereist om correct te compileren.
#include <wbemidl.h>
In de volgende procedure wordt beschreven hoe u een asynchrone aanroep uitvoert met IWbemUnsecuredApartment.
Een asynchrone aanroep uitvoeren met IWbemUnsecuredApartment
Maak een speciaal proces met een aanroep naar CoCreateInstance.
In het volgende codevoorbeeld wordt CoCreateInstance- aanroepen om een speciaal proces te maken.
CLSID CLSID_WbemUnsecuredApartment; IWbemUnsecuredApartment* pUnsecApp = NULL; CoCreateInstance(CLSID_WbemUnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IWbemUnsecuredApartment, (void**)&pUnsecApp);
Instantieer het uitvoerobject.
In het volgende codevoorbeeld wordt een nieuw sink-object gemaakt.
CMySink* pSink = new CMySink; pSink->AddRef();
Maak een stub voor de sink.
Een stub is een wrapperfunctie die afkomstig is van de sink.
In het volgende codevoorbeeld wordt een stub voor de sink gemaakt.
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);
Laat de sinkobjectpointer los.
U kunt de objectpointer vrijgeven omdat de stub nu eigenaar is van de aanwijzer.
In het volgende codevoorbeeld wordt de objectpointer vrijgegeven.
pSink->Release();
Gebruik de stub in een asynchrone aanroep.
Wanneer u klaar bent met de aanroep, laat u het lokale referentieaantal los.
In het volgende codevoorbeeld wordt de stub gebruikt in een asynchrone aanroep.
// pServices is an IWbemServices* object pServices->CreateInstanceEnumAsync(strClassName, 0, NULL, pStubSink);
Soms moet u mogelijk een asynchrone oproep annuleren nadat u de oproep hebt uitgevoerd. Als u het gesprek wilt annuleren, annuleert u de oproep met dezelfde aanwijzer die oorspronkelijk de oproep heeft gemaakt.
In het volgende codevoorbeeld wordt beschreven hoe u een asynchrone aanroep annuleert.
pServices->CancelAsyncCall(pStubSink);
Laat het lokale referentieaantal los wanneer u klaar bent met de asynchrone aanroep.
Zorg ervoor dat u de pStubSink aanwijzer pas loslaat nadat u hebt bevestigd dat er geen noodzaak is om de asynchrone aanroep te annuleren. Laat pStubSink verder niet los nadat WMI de pSink sinkaanwijzer vrijgeeft. Het vrijgeven van pStubSink na pSink creëert een circulaire referentie waardoor zowel de sink als de stub permanent in het geheugen blijven. In plaats daarvan bevindt zich een mogelijke locatie voor het vrijgeven van de aanwijzer in de IWbemObjectSink::SetStatus aanroep, gemaakt door WMI om te melden dat de oorspronkelijke asynchrone aanroep is voltooid.
Wanneer u klaar bent, de-initialiseer COM met een aanroep naar Release().
In het volgende codevoorbeeld ziet u hoe u Release() aanroept op de pUnsecApp aanwijzer.
pUnsecApp->Release();
Zie voor meer informatie over de functie CoInitializeSecurity en parameters de COM-documentatie.