From 81079eb221782dbfb16d21453cc0e892f2b1ea3f Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 1 Oct 2009 00:01:17 +0200 Subject: [PATCH] mshtml: Added QueryCustomPolicy implementation. --- dlls/mshtml/secmgr.c | 82 ++++++++++++++++++++++++++++++++- dlls/mshtml/tests/script.c | 93 +++++++++++++++++++++++++++++++++++++- 2 files changed, 171 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/secmgr.c b/dlls/mshtml/secmgr.c index c9b1e4625e3..be56e5dbda9 100644 --- a/dlls/mshtml/secmgr.c +++ b/dlls/mshtml/secmgr.c @@ -27,6 +27,8 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "objsafe.h" +#include "activscp.h" #include "wine/debug.h" @@ -36,6 +38,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; +/* Defined as extern in urlmon.idl, but not exported by uuid.lib */ +const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = + {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; + #define HOSTSECMGR_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IInternetHostSecurityManager, iface) static HRESULT WINAPI InternetHostSecurityManager_QueryInterface(IInternetHostSecurityManager *iface, REFIID riid, void **ppv) @@ -78,12 +84,84 @@ static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHost pContext, cbContext, dwFlags, dwReserved); } +static DWORD confirm_safety(HTMLDocumentNode *This, const WCHAR *url, IUnknown *obj) +{ + DWORD policy, enabled_opts, supported_opts; + IObjectSafety *obj_safety; + HRESULT hres; + + /* FIXME: Check URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY */ + + hres = IInternetSecurityManager_ProcessUrlAction(This->secmgr, url, URLACTION_SCRIPT_SAFE_ACTIVEX, + (BYTE*)&policy, sizeof(policy), NULL, 0, 0, 0); + if(FAILED(hres) || policy != URLPOLICY_ALLOW) + return URLPOLICY_DISALLOW; + + hres = IUnknown_QueryInterface(obj, &IID_IObjectSafety, (void**)&obj_safety); + if(FAILED(hres)) + return URLPOLICY_DISALLOW; + + hres = IObjectSafety_GetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, &supported_opts, &enabled_opts); + if(SUCCEEDED(hres)) { + enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + if(supported_opts & INTERFACE_USES_SECURITY_MANAGER) + enabled_opts |= INTERFACE_USES_SECURITY_MANAGER; + hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts); + } + IObjectSafety_Release(obj_safety); + if(FAILED(hres)) + return URLPOLICY_DISALLOW; + + return URLPOLICY_ALLOW; +} + static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHostSecurityManager *iface, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved) { HTMLDocumentNode *This = HOSTSECMGR_THIS(iface); - FIXME("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); - return E_NOTIMPL; + const WCHAR *url; + HRESULT hres; + + TRACE("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); + + url = This->basedoc.doc_obj->url ? This->basedoc.doc_obj->url : about_blankW; + + hres = IInternetSecurityManager_QueryCustomPolicy(This->secmgr, url, guidKey, ppPolicy, pcbPolicy, + pContext, cbContext, dwReserved); + if(hres != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) + return hres; + + if(IsEqualGUID(&GUID_CUSTOM_CONFIRMOBJECTSAFETY, guidKey)) { + IActiveScript *active_script; + struct CONFIRMSAFETY *cs; + DWORD policy; + + if(cbContext != sizeof(struct CONFIRMSAFETY)) { + FIXME("wrong context size\n"); + return E_FAIL; + } + + cs = (struct CONFIRMSAFETY*)pContext; + hres = IUnknown_QueryInterface(cs->pUnk, &IID_IActiveScript, (void**)&active_script); + if(SUCCEEDED(hres)) { + FIXME("Got IAciveScript iface\n"); + IActiveScript_Release(active_script); + return E_FAIL; + } + + policy = confirm_safety(This, url, cs->pUnk); + + *ppPolicy = CoTaskMemAlloc(sizeof(policy)); + if(!*ppPolicy) + return E_OUTOFMEMORY; + + *(DWORD*)*ppPolicy = policy; + *pcbPolicy = sizeof(policy); + return S_OK; + } + + FIXME("Unknown guidKey %s\n", debugstr_guid(guidKey)); + return hres; } #undef HOSTSECMGR_THIS diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 89b076c727e..5f59ea4e1b6 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -37,6 +37,10 @@ DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +/* Defined as extern in urlmon.idl, but not exported by uuid.lib */ +const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = + {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; + #ifdef _WIN64 #define CTXARG_T DWORDLONG @@ -110,6 +114,10 @@ DEFINE_EXPECT(GetScriptDispatch); DEFINE_EXPECT(funcDisp); DEFINE_EXPECT(script_testprop_d); DEFINE_EXPECT(script_testprop_i); +DEFINE_EXPECT(AXQueryInterface_IActiveScript); +DEFINE_EXPECT(AXQueryInterface_IObjectSafety); +DEFINE_EXPECT(AXGetInterfaceSafetyOptions); +DEFINE_EXPECT(AXSetInterfaceSafetyOptions); #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}" @@ -519,7 +527,7 @@ static SCRIPTSTATE state; static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) { *ppv = NULL; - ok(0, "unexpected call\n"); + ok(0, "unexpected call %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -573,11 +581,72 @@ static const IObjectSafetyVtbl ObjectSafetyVtbl = { static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl }; +static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IActiveScript, riid)) { + CHECK_EXPECT(AXQueryInterface_IActiveScript); + return E_NOINTERFACE; + } + + if(IsEqualGUID(&IID_IObjectSafety, riid)) { + CHECK_EXPECT(AXQueryInterface_IObjectSafety); + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, + DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions) +{ + CHECK_EXPECT(AXGetInterfaceSafetyOptions); + + ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid)); + ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n"); + ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n"); + + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER; + *pdwEnabledOptions = INTERFACE_USES_DISPEX; + + return S_OK; +} + +static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, + DWORD dwOptionSetMask, DWORD dwEnabledOptions) +{ + CHECK_EXPECT(AXSetInterfaceSafetyOptions); + + ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid)); + + ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), + "dwOptionSetMask=%x\n", dwOptionSetMask); + ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), + "dwEnabledOptions=%x\n", dwOptionSetMask); + + return S_OK; +} + +static const IObjectSafetyVtbl AXObjectSafetyVtbl = { + AXObjectSafety_QueryInterface, + ObjectSafety_AddRef, + ObjectSafety_Release, + AXObjectSafety_GetInterfaceSafetyOptions, + AXObjectSafety_SetInterfaceSafetyOptions +}; + +static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl }; + static void test_security(void) { IInternetHostSecurityManager *sec_mgr; IServiceProvider *sp; - DWORD policy; + DWORD policy, policy_size; + struct CONFIRMSAFETY cs; + BYTE *ppolicy; HRESULT hres; hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp); @@ -593,6 +662,26 @@ static void test_security(void) ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres); ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy); + cs.clsid = CLSID_TestActiveX; + cs.pUnk = (IUnknown*)&AXObjectSafety; + cs.dwFlags = 0; + + SET_EXPECT(AXQueryInterface_IActiveScript); + SET_EXPECT(AXQueryInterface_IObjectSafety); + SET_EXPECT(AXGetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions); + hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + CHECK_CALLED(AXQueryInterface_IActiveScript); + CHECK_CALLED(AXQueryInterface_IObjectSafety); + CHECK_CALLED(AXGetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions); + + ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); + ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); + ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy); + CoTaskMemFree(ppolicy); + IInternetHostSecurityManager_Release(sec_mgr); }