Définition de la sécurité sur un appel asynchrone

Les appels asynchrones présentent de graves risques de sécurité, car un rappel au récepteur peut ne pas être le résultat de l’appel asynchrone par l’application ou le script d’origine. La sécurité dans les connexions à distance est basée sur le chiffrement de la communication entre le client et le fournisseur sur l’ordinateur distant. En C++, vous pouvez définir le chiffrement via le paramètre de niveau d’authentification dans l’appel à CoInitializeSecurity. Dans le script, définissez authenticationLevel dans la connexion moniker ou sur un objet SWbemSecurity . Pour plus d’informations, consultezDéfinition du niveau de sécurité du processus par défaut à l’aide de VBScript.

Les risques de sécurité pour les appels asynchrones existent, car WMI réduit le niveau d’authentification sur un rappel jusqu’à ce que le rappel réussisse. Lors d’un appel asynchrone sortant, le client peut définir le niveau d’authentification sur la connexion sur WMI. WMI récupère les paramètres de sécurité sur l’appel client et tente de rappeler avec le même niveau d’authentification. Le rappel est toujours lancé au niveau RPC_C_AUTHN_LEVEL_PKT_PRIVACY. Si le rappel échoue, WMI abaisse le niveau d’authentification à un niveau où le rappel peut réussir, si nécessaire, pour RPC_C_AUTHN_LEVEL_NONE. Dans le contexte des appels au sein du système local où le service d’authentification n’est pas Kerberos, le rappel est toujours retourné à RPC_C_AUTHN_LEVEL_NONE.

Le niveau d’authentification minimal est RPC_C_AUTHN_LEVEL_PKT (wbemAuthenticationLevelPktpour les scripts). Toutefois, vous pouvez spécifier un niveau supérieur, tel que RPC_C_AUTHN_LEVEL_PKT_PRIVACY (wbemAuthenticationLevelPktPrivacy). Il est recommandé que les applications clientes ou les scripts définissent le niveau d’authentification sur RPC_C_AUTHN_LEVEL_DEFAULT (wbemAuthenticationLevelDefault), ce qui permet de négocier le niveau d’authentification au niveau spécifié par le serveur.

La valeur de Registre HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault contrôle si WMI recherche un niveau d’authentification acceptable dans les rappels. Il s’agit du seul mécanisme de protection de la sécurité du récepteur pour les appels asynchrones effectués en script ou en Visual Basic. Par défaut, cette clé de Registre est définie sur zéro. Si la clé de Registre est égale à zéro, WMI ne vérifie pas les niveaux d’authentification. Pour sécuriser les appels asynchrones dans le script, définissez la clé de Registre sur 1. Les clients C++ peuvent appeler IWbemUnsecuredApartment::CreateSinkStub pour contrôler l’accès au récepteur. La valeur est créée n’importe où par défaut.

Les rubriques suivantes fournissent des exemples de définition de la sécurité des appels asynchrones :

Définition de la sécurité des appels asynchrones en C++

La méthode IWbemUnsecuredApartment::CreateSinkStub est similaire à la méthode IUnsecuredApartment::CreateObjectStub et crée un récepteur dans un processus distinct, Unsecapp.exe, pour recevoir des rappels. Toutefois, la méthode CreateSinkStub a un paramètre dwFlagqui spécifie comment le processus distinct gère le contrôle d’accès.

Le paramètre dwFlag spécifie l’une des actions suivantes pour Unsecapp.exe :

  • Utilisez le paramètre de clé de Registre pour déterminer s’il faut ou non case activée accès.
  • Ignorez la clé de Registre et case activée toujours l’accès.
  • Ignorez la clé de Registre et n’case activée jamais d’accès.

L’exemple de code de cette rubrique nécessite la compilation correcte de l’instruction #include suivante.

#include <wbemidl.h>

La procédure suivante décrit comment effectuer un appel asynchrone avec IWbemUnsecuredApartment.

Pour effectuer un appel asynchrone avec IWbemUnsecuredApartment

  1. Créez un processus dédié avec un appel à CoCreateInstance.

    L’exemple de code suivant appelle CoCreateInstance pour créer un processus dédié.

    CLSID                    CLSID_WbemUnsecuredApartment;
    IWbemUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_WbemUnsecuredApartment, 
                     NULL, 
                     CLSCTX_LOCAL_SERVER, 
                     IID_IWbemUnsecuredApartment, 
                     (void**)&pUnsecApp);
    
  2. Instanciation de l’objet récepteur.

    L'exemple de code suivant crée un nouvel objet récepteur.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Créez un stub pour le récepteur.

    Un stub est une fonction wrapper produite à partir du récepteur.

    L’exemple de code suivant crée un stub pour le récepteur.

    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. Relâchez le pointeur d’objet récepteur.

    Vous pouvez libérer le pointeur d’objet, car le stub est maintenant propriétaire du pointeur.

    L’exemple de code suivant libère le pointeur d’objet.

    pSink->Release();
    
  5. Utilisez le stub dans tout appel asynchrone.

    Une fois l’appel terminé, relâchez le nombre de références locales.

    L’exemple de code suivant utilise le stub dans un appel asynchrone.

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

    Parfois, vous devrez peut-être annuler un appel asynchrone après avoir passé l’appel. Si vous devez annuler l’appel, annulez l’appel avec le pointeur qui a initialement effectué l’appel.

    L’exemple de code suivant décrit comment annuler un appel asynchrone.

    pServices->CancelAsyncCall(pStubSink);
    
  6. Relâchez le nombre de références locales lorsque vous avez terminé d’utiliser l’appel asynchrone.

    Veillez à libérer le pointeur pStubSink uniquement après avoir confirmé que l’appel asynchrone n’a pas besoin d’être annulé. En outre, ne relâchez pas pStubSink après que WMI a libéré le pointeur du récepteur pSink. La libération de pStubSink après pSink crée un nombre de références circulaire dans lequel le récepteur et le stub restent en mémoire pour toujours. Au lieu de cela, un emplacement possible pour libérer le pointeur se trouve dans l’appel IWbemObjectSink::SetStatus, effectué par WMI pour signaler que l’appel asynchrone d’origine est terminé.

  7. Lorsque vous avez terminé, annulez l’initialisation de COM avec un appel à Release().

    L’exemple de code suivant montre comment appeler Release() sur le pointeur pUnsecApp.

    pUnsecApp->Release();
    

Pour plus d’informations sur la fonction et les paramètres CoInitializeSecurity , consultez la documentation COM.