Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
As chamadas assíncronas apresentam sérios riscos de segurança porque uma chamada de retorno para o coletor de pode não ser resultado da chamada assíncrona por parte do aplicativo ou script original. A segurança em conexões remotas é baseada na criptografia da comunicação entre o cliente e o provedor no computador remoto. Em C++, você pode definir a criptografia por meio do parâmetro de nível de autenticação na chamada para CoInitializeSecurity. Em scripts, defina o AuthenticationLevel na conexão de moniker ou em um objeto SWbemSecurity. Para obter mais informações, consulte Definindo o nível de segurança padrão do processo usando o VBScript.
Os riscos de segurança para chamadas assíncronas existem porque o WMI reduz o nível de autenticação num retorno de chamada até que o retorno de chamada seja bem-sucedido. Em uma chamada assíncrona de saída, o cliente pode definir o nível de autenticação na conexão com WMI. O WMI recupera as configurações de segurança na chamada do cliente e tenta ligar de volta com o mesmo nível de autenticação. A chamada de retorno é sempre iniciada no nível RPC_C_AUTHN_LEVEL_PKT_PRIVACY. Se o retorno de chamada falhar, o WMI reduzirá o nível de autenticação para um nível em que o retorno de chamada possa ser bem-sucedido, se necessário, para RPC_C_AUTHN_LEVEL_NONE. No contexto de chamadas dentro do sistema local onde o serviço de autenticação não é Kerberos, o retorno de chamada ocorre sempre em RPC_C_AUTHN_LEVEL_NONE.
O nível mínimo de autenticação é RPC_C_AUTHN_LEVEL_PKT (wbemAuthenticationLevelPktpara scripting). No entanto, você pode especificar um nível superior, como RPC_C_AUTHN_LEVEL_PKT_PRIVACY (wbemAuthenticationLevelPktPrivacy). É recomendável que os aplicativos cliente ou scripts definam o nível de autenticação como RPC_C_AUTHN_LEVEL_DEFAULT (wbemAuthenticationLevelDefault), o que permite que o nível de autenticação seja negociado para o nível especificado pelo servidor.
O HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault controla se o WMI verifica a existência de um nível de autenticação aceitável em chamadas de retorno. Este é o único mecanismo para proteger a segurança do coletor para chamadas assíncronas feitas em scripts ou Visual Basic. Por padrão, essa chave do Registro é definida como zero. Se a chave do Registro for zero, o WMI não verificará os níveis de autenticação. Para proteger chamadas assíncronas em scripts, defina a chave do Registro como 1. Os clientes C++ podem chamar IWbemUnsecuredApartment::CreateSinkStub para controlar o acesso ao coletor. O valor é criado em qualquer lugar por padrão.
Os tópicos a seguir fornecem exemplos de configuração de segurança de chamada assíncrona:
- Definindo a segurança em uma chamada assíncrona no VBScript
- Definindo a segurança de chamada assíncrona em C++
Definindo a segurança de chamada assíncrona em C++
O método IWbemUnsecuredApartment::CreateSinkStub é semelhante ao método IUnsecuredApartment::CreateObjectStub e cria um coletor em um processo separado, Unsecapp.exe, para receber retornos de chamada. No entanto, o método CreateSinkStub tem um parâmetro dwFlagque especifica como o processo separado manipula o controle de acesso.
O parâmetro dwFlag especifica uma das seguintes ações para Unsecapp.exe:
- Use a configuração da chave do Registro para determinar se o acesso deve ou não ser verificado.
- Ignore a chave do Registro e sempre verifique o acesso.
- Ignore a chave do Registro e nunca verifique o acesso.
O exemplo de código neste tópico requer a seguinte instrução #include para compilar corretamente.
#include <wbemidl.h>
O procedimento a seguir descreve como executar uma chamada assíncrona com IWbemUnsecuredApartment.
Para executar uma chamada assíncrona com IWbemUnsecuredApartment
Crie um processo dedicado com uma chamada para CoCreateInstance.
O exemplo de código a seguir chama CoCreateInstance para criar um processo dedicado.
CLSID CLSID_WbemUnsecuredApartment; IWbemUnsecuredApartment* pUnsecApp = NULL; CoCreateInstance(CLSID_WbemUnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IWbemUnsecuredApartment, (void**)&pUnsecApp);Instanciar o objeto do sumidouro.
O exemplo de código a seguir cria um novo objeto coletor.
CMySink* pSink = new CMySink; pSink->AddRef();Crie um esboço para a pia.
Um esboço é uma função de encapsulamento produzida a partir do sink.
O exemplo de código a seguir cria um stub para o coletor.
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);Liberte o ponteiro do objeto sumidouro.
Você pode liberar o ponteiro de objeto porque o stub agora possui o ponteiro.
O exemplo de código abaixo libera o ponteiro do objeto.
pSink->Release();Use o stub em qualquer chamada assíncrona.
Quando terminar a chamada, liberte a contagem de referência local.
O exemplo de código a seguir usa o stub em uma chamada assíncrona.
// pServices is an IWbemServices* object pServices->CreateInstanceEnumAsync(strClassName, 0, NULL, pStubSink);Às vezes, você pode ter que cancelar uma chamada assíncrona depois de fazer a chamada. Se precisares cancelar a chamada, cancela a chamada com o mesmo ponteiro que fez a chamada originalmente.
O exemplo de código a seguir descreve como cancelar uma chamada assíncrona.
pServices->CancelAsyncCall(pStubSink);Liberte a contagem de referência local quando terminar do uso da chamada assíncrona.
Certifique-se de liberar o ponteiro pStubSink somente depois de confirmar que a chamada assíncrona não deve ser cancelada. Além disso, não solte pStubSink depois que o WMI liberar o ponteiro de sink pSink. Liberar pStubSink após pSink cria uma contagem de referência circular na qual tanto o recetor quanto o stub permanecem na memória para sempre. Em vez disso, um possível local para liberar o ponteiro está na chamada IWbemObjectSink::SetStatus, feita pelo WMI para informar que a chamada assíncrona original foi concluída.
Quando terminar, desinicialize o COM com uma chamada para Release().
O exemplo de código a seguir mostra como chamar Release() no ponteiro pUnsecApp.
pUnsecApp->Release();
Para obter mais informações sobre a função CoInitializeSecurity e parâmetros, consulte a documentação do COM.