|
|
/*****************************************************************************\
FILE: autosecurity.cpp
DESCRIPTION: Helpers functions to check if an Automation interface or ActiveX Control is hosted or used by a safe caller.
BryanSt 8/20/1999 Copyright (C) Microsoft Corp 1999-1999. All rights reserved. \*****************************************************************************/
#include "stock.h"
#pragma hdrstop
#include <autosecurity.h> // CAutomationSecurity
#include <ieguidp.h> // IID_IBrowserService
#include "ccstock.h" // LocalZoneCheck
/***************************************************************\
DESCRIPTION: Some hosts are always safe. Visual Basic is one example.
PARAMETERS: RETURN: This function will return TRUE if the host is always safe. HRESULT: This is a more descriptive error so the caller can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc. \***************************************************************/ BOOL CAutomationSecurity::IsSafeHost(OUT OPTIONAL HRESULT * phr) { BOOL fAlwaysSafe;
// _dwSafetyOptions being zero means we are in a mode
// that needs to assume the caller or data is from
// an untrusted source.
if (0 == _dwSafetyOptions) { fAlwaysSafe = TRUE; if (phr) *phr = S_OK; } else { fAlwaysSafe = FALSE; if (phr) *phr = E_ACCESSDENIED; }
return fAlwaysSafe; }
/***************************************************************\
DESCRIPTION: The class that implements this can check if the host is from the Local zone. This way, we can prevent a host that would try to call unsafe automation methods or misrepresent the consequence of the ActiveX Control's UI.
PARAMETERS: RETURN: TRUE if the security check passed. FALSE means the host isn't trusted so don't care out unsafe operations. dwFlags: What behaviors does the caller want? Currently: CAS_REG_VALIDATION: This means the caller needs the host's HTML to be registered and the checksum to be valid. HRESULT: This is a more descriptive error so the caller can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc. \***************************************************************/ BOOL CAutomationSecurity::IsHostLocalZone(IN DWORD dwFlags, OUT OPTIONAL HRESULT * phr) { HRESULT hr;
// See if the host is always safe.
if (!IsSafeHost(&hr)) { // It isn't, so let's see if this content is safe.
// (Normally the immediate HTML FRAME)
// Is it from the local zone?
hr = LocalZoneCheck(_punkSite);
// Does the caller also want to verify it's checksum?
if ((S_OK == hr) && (CAS_REG_VALIDATION & dwFlags)) { IBrowserService* pbs; WCHAR wszPath[MAX_PATH];
wszPath[0] = 0; hr = E_ACCESSDENIED;
// ask the browser, for example we are in a .HTM doc
if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs)))) { LPITEMIDLIST pidl;
if (SUCCEEDED(pbs->GetPidl(&pidl))) { DWORD dwAttribs = SFGAO_FOLDER;
if (SUCCEEDED(SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszPath, ARRAYSIZE(wszPath), &dwAttribs)) && (dwAttribs & SFGAO_FOLDER)) // This is a folder. So, wszPath should be the path for it's webview template
{ IOleCommandTarget *pct;
// find the template path from webview, for example a .HTT file
if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_DefView, IID_PPV_ARG(IOleCommandTarget, &pct)))) { VARIANT vPath;
vPath.vt = VT_EMPTY; if (pct->Exec(&CGID_DefView, DVCMDID_GETTEMPLATEDIRNAME, 0, NULL, &vPath) == S_OK) { if (vPath.vt == VT_BSTR && vPath.bstrVal) { DWORD cchPath = ARRAYSIZE(wszPath);
if (S_OK != PathCreateFromUrlW(vPath.bstrVal, wszPath, &cchPath, 0)) { // it might not be an URL, in this case it is a file path
StrCpyNW(wszPath, vPath.bstrVal, ARRAYSIZE(wszPath)); } } VariantClear(&vPath); } pct->Release(); } } ILFree(pidl); }
pbs->Release(); } else { ASSERT(0); // no browser, where are we?
}
if (wszPath[0]) { DWORD dwRVTFlags = (SHRVT_VALIDATE | SHRVT_REGISTERIFPROMPTOK);
if (CAS_PROMPT_USER & dwFlags) dwRVTFlags |= SHRVT_PROMPTUSER; hr = SHRegisterValidateTemplate(wszPath, dwRVTFlags); } } } if (S_FALSE == hr) hr = E_ACCESSDENIED; // The caller needs to soften the hr to S_OK if it's concerned for script.
if (phr) *phr = hr;
return ((S_OK == hr) ? TRUE : FALSE); }
/***************************************************************\
DESCRIPTION: The class that implements this can check if the host is from the Local zone. This way, we can prevent a host that would try to call unsafe automation methods or misrepresent the consequence of the ActiveX Control's UI.
PARAMETERS: RETURN: TRUE if the security check passed. FALSE means the host isn't trusted so don't care out unsafe operations. dwFlags: What behaviors does the caller want? Currently: CAS_REG_VALIDATION: This means the caller needs the host's HTML to be registered and the checksum to be valid. HRESULT: This is a more descriptive error so the caller can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc. \***************************************************************/ BOOL CAutomationSecurity::IsUrlActionAllowed(IN IInternetHostSecurityManager * pihsm, IN DWORD dwUrlAction, IN DWORD dwFlags, OUT OPTIONAL HRESULT * phr) { HRESULT hr; IInternetHostSecurityManager * pihsmTemp = NULL;
if (!pihsm) { hr = IUnknown_QueryService(_punkSite, IID_IInternetHostSecurityManager, IID_PPV_ARG(IInternetHostSecurityManager, &pihsmTemp)); pihsm= pihsmTemp; }
hr = ZoneCheckHost(pihsm, dwUrlAction, dwFlags);
if (S_FALSE == hr) hr = E_ACCESSDENIED; // The caller needs to soften the hr to S_OK if it's concerned for script.
if (phr) *phr = hr;
ATOMICRELEASE(pihsmTemp); return ((S_OK == hr) ? TRUE : FALSE); }
HRESULT CAutomationSecurity::MakeObjectSafe(IN IUnknown ** ppunk) { HRESULT hr;
// See if the host is always safe.
if (!IsSafeHost(&hr)) { // It isn't, so let's ask the control if it's
// going to be safe.
hr = MakeSafeForScripting(ppunk); } return hr; }
|