Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
9.0 KiB

  1. /*****************************************************************************\
  2. FILE: security.cpp
  3. DESCRIPTION:
  4. Helpers functions to check if an Automation interface or ActiveX Control
  5. is hosted or used by a safe caller.
  6. BryanSt 8/25/1999
  7. Copyright (C) Microsoft Corp 1999-1999. All rights reserved.
  8. \*****************************************************************************/
  9. #include "stock.h"
  10. #pragma hdrstop
  11. #include <mshtml.h>
  12. /***************************************************************\
  13. DESCRIPTION:
  14. We are given a site via IObjectWithSite. Obtain the hosting
  15. IHTMLDocument from there. This is typically used to get a URL from
  16. in order to check zones or ProcessUrlAction() attributes, or if there are
  17. two URLs you can compare their zones from cross-zone restrictions.
  18. \***************************************************************/
  19. STDAPI GetHTMLDoc2(IUnknown *punk, IHTMLDocument2 **ppHtmlDoc)
  20. {
  21. *ppHtmlDoc = NULL;
  22. if (!punk)
  23. return E_FAIL;
  24. *ppHtmlDoc = NULL;
  25. // The window.external, jscript "new ActiveXObject" and the <OBJECT> tag
  26. // don't take us down the same road.
  27. IOleClientSite *pClientSite;
  28. HRESULT hr = punk->QueryInterface(IID_PPV_ARG(IOleClientSite, &pClientSite));
  29. if (SUCCEEDED(hr))
  30. {
  31. // <OBJECT> tag path
  32. IOleContainer *pContainer;
  33. // This will return the interface for the current FRAME containing the
  34. // OBJECT tag. We will only check that frames security because we
  35. // rely on MSHTML to block cross frame scripting when it isn't safe.
  36. hr = pClientSite->GetContainer(&pContainer);
  37. if (SUCCEEDED(hr))
  38. {
  39. hr = pContainer->QueryInterface(IID_PPV_ARG(IHTMLDocument2, ppHtmlDoc));
  40. pContainer->Release();
  41. }
  42. if (FAILED(hr))
  43. {
  44. // window.external path
  45. IWebBrowser2 *pWebBrowser2;
  46. hr = IUnknown_QueryService(pClientSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &pWebBrowser2));
  47. if (SUCCEEDED(hr))
  48. {
  49. IDispatch *pDispatch;
  50. hr = pWebBrowser2->get_Document(&pDispatch);
  51. if (SUCCEEDED(hr))
  52. {
  53. hr = pDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument2, ppHtmlDoc));
  54. pDispatch->Release();
  55. }
  56. pWebBrowser2->Release();
  57. }
  58. }
  59. pClientSite->Release();
  60. }
  61. else
  62. {
  63. // jscript path
  64. hr = IUnknown_QueryService(punk, SID_SContainerDispatch, IID_PPV_ARG(IHTMLDocument2, ppHtmlDoc));
  65. }
  66. ASSERT(FAILED(hr) || (*ppHtmlDoc));
  67. return hr;
  68. }
  69. /***************************************************************\
  70. DESCRIPTION:
  71. This function is supposed to find out the zone from the
  72. specified URL or Path.
  73. \***************************************************************/
  74. STDAPI LocalZoneCheckPath(LPCWSTR pszUrl, IUnknown * punkSite)
  75. {
  76. DWORD dwZoneID = URLZONE_UNTRUSTED;
  77. HRESULT hr = GetZoneFromUrl(pszUrl, punkSite, &dwZoneID);
  78. if (SUCCEEDED(hr))
  79. {
  80. if (dwZoneID == URLZONE_LOCAL_MACHINE)
  81. hr = S_OK;
  82. else
  83. hr = E_ACCESSDENIED;
  84. }
  85. return hr;
  86. }
  87. /***************************************************************\
  88. DESCRIPTION:
  89. Get the zone from the specified URL or Path.
  90. \***************************************************************/
  91. STDAPI GetZoneFromUrl(LPCWSTR pszUrl, IUnknown * punkSite, DWORD * pdwZoneID)
  92. {
  93. HRESULT hr = E_FAIL;
  94. if (pszUrl && pdwZoneID)
  95. {
  96. IInternetSecurityManager * pSecMgr = NULL;
  97. // WARNING: IInternetSecurityManager is the guy who translates
  98. // from URL->Zone. If we CoCreate this object, it will do the
  99. // default mapping. Some hosts, like Outlook Express, want to
  100. // over ride the default mapping in order to sandbox some content.
  101. // I beleive this could be used to force HTML in an email
  102. // message (C:\mailmessage.eml) to act like it's from a more
  103. // untrusted zone. We use QueryService to get this interface
  104. // from our host. This info is from SanjayS. (BryanSt 8/21/1999)
  105. hr = IUnknown_QueryService(punkSite, SID_SInternetSecurityManager, IID_PPV_ARG(IInternetSecurityManager, &pSecMgr));
  106. if (FAILED(hr))
  107. {
  108. hr = CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IInternetSecurityManager, &pSecMgr));
  109. }
  110. if (SUCCEEDED(hr))
  111. {
  112. hr = pSecMgr->MapUrlToZone(pszUrl, pdwZoneID, 0);
  113. ATOMICRELEASE(pSecMgr);
  114. }
  115. }
  116. else
  117. {
  118. hr = E_INVALIDARG;
  119. }
  120. return hr;
  121. }
  122. /***************************************************************\
  123. DESCRIPTION:
  124. We are given a site via IObjectWithSite. See if that host
  125. maps to the Local Zone.
  126. \***************************************************************/
  127. STDAPI LocalZoneCheck(IUnknown *punkSite)
  128. {
  129. DWORD dwZoneID = URLZONE_UNTRUSTED;
  130. HRESULT hr = GetZoneFromSite(punkSite, &dwZoneID);
  131. if (SUCCEEDED(hr))
  132. {
  133. if (dwZoneID == URLZONE_LOCAL_MACHINE)
  134. hr = S_OK;
  135. else
  136. hr = E_ACCESSDENIED;
  137. }
  138. return hr;
  139. }
  140. STDAPI GetZoneFromSite(IUnknown *punkSite, DWORD *pdwZoneID)
  141. {
  142. // Return S_FALSE if we don't have a host site since we have no way of doing a
  143. // security check. This is as far as VB 5.0 apps get.
  144. if (!punkSite)
  145. {
  146. *pdwZoneID = URLZONE_UNTRUSTED;
  147. return S_FALSE;
  148. }
  149. HRESULT hr = E_ACCESSDENIED;
  150. BOOL fTriedBrowser = FALSE;
  151. // Try to find the original template path for zone checking
  152. IOleCommandTarget * pct;
  153. if (SUCCEEDED(IUnknown_QueryService(punkSite, SID_DefView, IID_PPV_ARG(IOleCommandTarget, &pct))))
  154. {
  155. VARIANT vTemplatePath;
  156. vTemplatePath.vt = VT_EMPTY;
  157. if (pct->Exec(&CGID_DefView, DVCMDID_GETTEMPLATEDIRNAME, 0, NULL, &vTemplatePath) == S_OK)
  158. {
  159. fTriedBrowser = TRUE;
  160. if (vTemplatePath.vt == VT_BSTR)
  161. {
  162. hr = GetZoneFromUrl(vTemplatePath.bstrVal, punkSite, pdwZoneID);
  163. }
  164. // We were able to talk to the browser, so don't fall back on Trident because they may be
  165. // less secure.
  166. fTriedBrowser = TRUE;
  167. VariantClear(&vTemplatePath);
  168. }
  169. pct->Release();
  170. }
  171. // If this is one of those cases where the browser doesn't exist (AOL, VB, ...) then
  172. // we will check the scripts security. If we did ask the browser, don't ask trident
  173. // because the browser is often more restrictive in some cases.
  174. if (!fTriedBrowser && (hr != S_OK))
  175. {
  176. // Try to use the URL from the document to zone check
  177. IHTMLDocument2 *pHtmlDoc;
  178. /***************************************************************\
  179. NOTE:
  180. 1. If punkSite points into an <IFRAME APPLICATION="yes"> in a
  181. HTA file, then the URL GetHTMLDoc2() returns
  182. is for the IFRAME SRC..
  183. 2. If this isn't an HTML container, then we can't calculate a zone, so it's E_ACCESSDENIED.
  184. \***************************************************************/
  185. if (SUCCEEDED(GetHTMLDoc2(punkSite, &pHtmlDoc)))
  186. {
  187. BSTR bstrURL;
  188. /***************************************************************\
  189. QUESTION:
  190. 1. If this HTML container isn't safe but it's URL maps to the
  191. Local Zone, then we have a problem. This may happen with
  192. email messages, especially if they are saved to a file.
  193. If the user reopens a saved .eml file, it will be hosted in
  194. it's mail container that may support the IInternet interface
  195. to indicate that it's in an untrusted zone. Will we get
  196. a Local Zone URL in that case?
  197. ANSWER:
  198. 1. The container can override zone mappings by supporting
  199. IInternetSecurityManager.
  200. QUESTION:
  201. 2. What if there are multiple frames in different zones.
  202. Will trident block cross frame scripting?
  203. ANSWER:
  204. 2. Yes.
  205. \***************************************************************/
  206. if (SUCCEEDED(pHtmlDoc->get_URL(&bstrURL)))
  207. {
  208. // NOTE: the above URL is improperly escaped, this is
  209. // due to app compat. if you depend on this URL being valid
  210. // use another means to get this
  211. hr = GetZoneFromUrl(bstrURL, punkSite, pdwZoneID);
  212. SysFreeString(bstrURL);
  213. }
  214. pHtmlDoc->Release();
  215. }
  216. }
  217. return hr;
  218. }