Сущность технологии СОМ. Библиотека программиста

ОглавлениеДобавить в закладки К обложке

void TurnOffAllSecurity(IApe *pApe) {

IUnknown *pUnkProxyManager = 0;

// get a pointer to the proxy manager

// получаем указатель на администратор заместителей

HRESULT hr = pApe->QueryInterface(IID_IUnknown, (void**)&pUnkProxyManager);

assert(SUCCEEDED(hr));

// set blanket for proxy manager

// устанавливаем защиту для администратора заместителей

hr = CoSetProxyBlanket(pUnkProxyManager, RPC_C_AUTHN_NONE, RPC_C_AUTHZ_NONE, О, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_ANONYMOUS, 0, EOAC_NONE);

assert(SUCCEEDED(hr));

// set blanket for interface proxy

// устанавливаем защиту для интерфейсного заместителя

hr = CoSetProxyBlanket(pApe, RPC_C_AUTHN_NONE, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_ANONYMOUS, 0, EOAC_NONE);

assert(SUCCEEDED(hr));

// release temporary pointer to proxy manager

// освобождаем временный указатель на администратор заместителей

pUnkProxyManager->Release();

}

Хотя представляется возможным установить и запросить защиту для администратора заместителей, невозможно скопировать администратор заместителей с помощью IClientSecurity::CopyProxy, так как это нарушило бы правила идентификации COM.

Когда ORPC-запрос направляется интерфейсной заглушке, COM создает объект контекста вызова (call context object), представляющий различные аспекты вызова, в том числе установки защиты того интерфейсного заместителя, который отправил этот запрос. COM связывает этот контекстный объект с потоком, который будет выполнять вызов метода. Библиотека COM выставляет API-функцию CoGetCallContext, позволяющую реализациям метода получить контекст для текущего вызова метода:

HRESULT CoGetCallContext ([in] REFIID riid, [out, iid_is(riid)] void **ppv);

В Windows NT 4.0 единственным интерфейсом, доступным для контекстного объекта вызова, является интерфейс IServerSecurity:

[local, object, uuid(0000013E-0000-0000-C000-000000000046)]

interface IServerSecurity : IUnknown {

// get caller's security settings

// получаем установки защиты вызывающей программы

HRESULT QueryBlanket( [out] DWORD *pAuthnSvc,

// authentication pkg

// модуль аутентификации

[out] DWORD *pAuthzSvc,

// authorization pkg

// модуль авторизации

[out] OLECHAR **pServerName,

// server principal

// серверный принципал

[out] DWORD *pAuthnLevel,

// authentication level

// уровень аутентификации

[out] DWORD *pImpLevel,

// impersonation level

// уровень заимствования прав

[out] void *pPrivs,

// client principal

// клиентский принципал

[out] DWORD *pCaps

// EOAC flags

// флаги EOAC

);

// start running with credentials of caller

// начинаем выполнение с полномочиями вызывающей программы

HRESULT ImpersonateClent(void);

// stop running with credentials of caller

// заканчиваем выполнение с полномочиями вызывающей программы

HRESULT RevertToSelf(void);

// test for Impersonation

// тест для заимствования прав BOOL

IsImpersonating(void);

}

IServerSecurity::QueryBlanket возвращает установки полной защиты, фактически использованные для текущего ORPC-вызова (которые могут несколько отличаться от клиентских установок благодаря специфическому для SSP повышению уровней). Как было в случае с IClientSecurity::QueryBlanket, функции IServerSecurity::QueryBlanket также разрешается передавать нуль вместо неиспользуемых параметров. Ниже приведен пример реализации метода, которая гарантирует, что вызывающая программа обеспечила возможность шифрования перед обработкой вызова:

STDMETHODIMP Gorilla::SwingFromTree(/*(in]*/ long nTreeID) {

// get current call context

// получаем контекст текущего вызова IServerSecurity *pss = 0;

HRESULT hr = CoGetCallContext(IID_IServerSecurity, (void**)&pss);

DWORD dwAuthnLevel;

if (SUCCEEDED(hr)) {

// get authentication level of current call

// получаем уровень аутентификации текущего вызова

hr = pss->QueryBlanket(0, 0, 0, &dwAuthnLevel, 0, 0, 0);

pss->Release(); }

// verify proper authentication level


Логин
Пароль
Запомнить меня