windows-nt/Source/XPSP1/NT/multimedia/dshow/mfvideo/mswebdvd/objectwithsiteimplsec.h
2020-09-26 16:20:57 +08:00

96 lines
2.9 KiB
C++

///////////////////////////////////////////////////////////
// ObjectWithSiteImplSec.h : Secure implementation of IObjectWithSite
// Copyright (c) Microsoft Corporation 2002.
#pragma once
#ifndef OBJECTWITHSITEIMPLSEC_H
#define OBJECTWITHSITEIMPLSEC_H
#include <guiddef.h>
#include <ocidl.h>
#include <urlmon.h>
#if defined(DEBUG) || defined(W32_OBJECT_STREAMING)
#include <atlconv.h>
#endif
using namespace ::ATL;
#include <strsafe.h>
inline HRESULT IsSafeZone(DWORD dwZone) {
switch (dwZone) {
case URLZONE_LOCAL_MACHINE:
case URLZONE_INTRANET:
case URLZONE_TRUSTED:
// the fixed list of zones we trust
return NOERROR;
default:
// everything else is untrusted
return E_FAIL;
}
}
inline HRESULT IsSafeSite(IUnknown* pSite) {
CComQIPtr<IServiceProvider> psp(pSite);
if (!psp) {
// no service provider interface on the site implies that we're not running in IE
// so by defn running local and trusted thus we return OK
return NOERROR;
}
CComQIPtr<IInternetHostSecurityManager> pManager;
HRESULT hr = psp->QueryService(SID_SInternetHostSecurityManager, IID_IInternetHostSecurityManager, (LPVOID *)&pManager);
if (FAILED(hr)) {
// no security manager interface on the site's service provider implies that we're not
// running in IE, so by defn running local and trusted thus we return OK
return NOERROR;
}
const int MAXZONE = MAX_SIZE_SECURITY_ID+6/*scheme*/+4/*zone(dword)*/+1/*wildcard*/+1/*trailing null*/;
char pbSecurityId[MAXZONE];
DWORD pcbSecurityId = sizeof(pbSecurityId);
ZeroMemory(pbSecurityId, sizeof(pbSecurityId));
hr = pManager->GetSecurityId(reinterpret_cast<BYTE*>(pbSecurityId), &pcbSecurityId, NULL);
if(FAILED(hr)){
// security manager not working(unexpected). but, the site tried to provide one. thus we
// must assume untrusted content and fail
return E_FAIL;
}
char *pbEnd = pbSecurityId + pcbSecurityId - 1;
if (*pbEnd == '*') { //ignore the optional wildcard flag
pbEnd--;
}
pbEnd -= 3; // point to beginning of little endian zone dword
DWORD dwZone = *(reinterpret_cast<long *>(pbEnd));
return IsSafeZone(dwZone);
}
template<class T>
class ATL_NO_VTABLE IObjectWithSiteImplSec : public IObjectWithSite {
public:
CComPtr<IUnknown> m_pSite;
// IObjectWithSite
STDMETHOD(GetSite)(REFIID iid, void** ppvSite) {
if (!ppvSite) {
return E_POINTER;
}
T* pT = static_cast<T*>(this);
if (!pT->m_pSite) {
return E_NOINTERFACE;
}
return pT->m_pSite->QueryInterface(iid, ppvSite);
}
STDMETHOD(SetSite)(IUnknown* pSite) {
HRESULT hr = IsSafeSite(pSite);
if (SUCCEEDED(hr)) {
T* pT = static_cast<T*>(this);
pT->m_pSite = pSite;
}
return hr;
}
};
#endif // OBJECTWITHSITEIMPLSEC_H
// end of file objectwithsiteimplsec.h