Source code of Windows XP (NT5)
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.

218 lines
7.5 KiB

  1. /*****************************************************************************\
  2. FILE: autosecurity.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/20/1999
  7. Copyright (C) Microsoft Corp 1999-1999. All rights reserved.
  8. \*****************************************************************************/
  9. #include "stock.h"
  10. #pragma hdrstop
  11. #include <autosecurity.h> // CAutomationSecurity
  12. #include <ieguidp.h> // IID_IBrowserService
  13. #include "ccstock.h" // LocalZoneCheck
  14. /***************************************************************\
  15. DESCRIPTION:
  16. Some hosts are always safe. Visual Basic is one example.
  17. PARAMETERS:
  18. RETURN: This function will return TRUE if the host is
  19. always safe.
  20. HRESULT: This is a more descriptive error so the caller
  21. can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc.
  22. \***************************************************************/
  23. BOOL CAutomationSecurity::IsSafeHost(OUT OPTIONAL HRESULT * phr)
  24. {
  25. BOOL fAlwaysSafe;
  26. // _dwSafetyOptions being zero means we are in a mode
  27. // that needs to assume the caller or data is from
  28. // an untrusted source.
  29. if (0 == _dwSafetyOptions)
  30. {
  31. fAlwaysSafe = TRUE;
  32. if (phr)
  33. *phr = S_OK;
  34. }
  35. else
  36. {
  37. fAlwaysSafe = FALSE;
  38. if (phr)
  39. *phr = E_ACCESSDENIED;
  40. }
  41. return fAlwaysSafe;
  42. }
  43. /***************************************************************\
  44. DESCRIPTION:
  45. The class that implements this can check if the host is
  46. from the Local zone. This way, we can prevent a host that
  47. would try to call unsafe automation methods or misrepresent
  48. the consequence of the ActiveX Control's UI.
  49. PARAMETERS:
  50. RETURN: TRUE if the security check passed. FALSE means
  51. the host isn't trusted so don't care out unsafe
  52. operations.
  53. dwFlags: What behaviors does the caller want? Currently:
  54. CAS_REG_VALIDATION: This means the caller needs the
  55. host's HTML to be registered and the checksum to
  56. be valid.
  57. HRESULT: This is a more descriptive error so the caller
  58. can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc.
  59. \***************************************************************/
  60. BOOL CAutomationSecurity::IsHostLocalZone(IN DWORD dwFlags, OUT OPTIONAL HRESULT * phr)
  61. {
  62. HRESULT hr;
  63. // See if the host is always safe.
  64. if (!IsSafeHost(&hr))
  65. {
  66. // It isn't, so let's see if this content is safe.
  67. // (Normally the immediate HTML FRAME)
  68. // Is it from the local zone?
  69. hr = LocalZoneCheck(_punkSite);
  70. // Does the caller also want to verify it's checksum?
  71. if ((S_OK == hr) && (CAS_REG_VALIDATION & dwFlags))
  72. {
  73. IBrowserService* pbs;
  74. WCHAR wszPath[MAX_PATH];
  75. wszPath[0] = 0;
  76. hr = E_ACCESSDENIED;
  77. // ask the browser, for example we are in a .HTM doc
  78. if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs))))
  79. {
  80. LPITEMIDLIST pidl;
  81. if (SUCCEEDED(pbs->GetPidl(&pidl)))
  82. {
  83. DWORD dwAttribs = SFGAO_FOLDER;
  84. if (SUCCEEDED(SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszPath, ARRAYSIZE(wszPath), &dwAttribs))
  85. && (dwAttribs & SFGAO_FOLDER)) // This is a folder. So, wszPath should be the path for it's webview template
  86. {
  87. IOleCommandTarget *pct;
  88. // find the template path from webview, for example a .HTT file
  89. if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_DefView, IID_PPV_ARG(IOleCommandTarget, &pct))))
  90. {
  91. VARIANT vPath;
  92. vPath.vt = VT_EMPTY;
  93. if (pct->Exec(&CGID_DefView, DVCMDID_GETTEMPLATEDIRNAME, 0, NULL, &vPath) == S_OK)
  94. {
  95. if (vPath.vt == VT_BSTR && vPath.bstrVal)
  96. {
  97. DWORD cchPath = ARRAYSIZE(wszPath);
  98. if (S_OK != PathCreateFromUrlW(vPath.bstrVal, wszPath, &cchPath, 0))
  99. {
  100. // it might not be an URL, in this case it is a file path
  101. StrCpyNW(wszPath, vPath.bstrVal, ARRAYSIZE(wszPath));
  102. }
  103. }
  104. VariantClear(&vPath);
  105. }
  106. pct->Release();
  107. }
  108. }
  109. ILFree(pidl);
  110. }
  111. pbs->Release();
  112. }
  113. else
  114. {
  115. ASSERT(0); // no browser, where are we?
  116. }
  117. if (wszPath[0])
  118. {
  119. DWORD dwRVTFlags = (SHRVT_VALIDATE | SHRVT_REGISTERIFPROMPTOK);
  120. if (CAS_PROMPT_USER & dwFlags)
  121. dwRVTFlags |= SHRVT_PROMPTUSER;
  122. hr = SHRegisterValidateTemplate(wszPath, dwRVTFlags);
  123. }
  124. }
  125. }
  126. if (S_FALSE == hr)
  127. hr = E_ACCESSDENIED; // The caller needs to soften the hr to S_OK if it's concerned for script.
  128. if (phr)
  129. *phr = hr;
  130. return ((S_OK == hr) ? TRUE : FALSE);
  131. }
  132. /***************************************************************\
  133. DESCRIPTION:
  134. The class that implements this can check if the host is
  135. from the Local zone. This way, we can prevent a host that
  136. would try to call unsafe automation methods or misrepresent
  137. the consequence of the ActiveX Control's UI.
  138. PARAMETERS:
  139. RETURN: TRUE if the security check passed. FALSE means
  140. the host isn't trusted so don't care out unsafe
  141. operations.
  142. dwFlags: What behaviors does the caller want? Currently:
  143. CAS_REG_VALIDATION: This means the caller needs the
  144. host's HTML to be registered and the checksum to
  145. be valid.
  146. HRESULT: This is a more descriptive error so the caller
  147. can differenciate E_OUTOFMEMORY from E_INVALIDARG, etc.
  148. \***************************************************************/
  149. BOOL CAutomationSecurity::IsUrlActionAllowed(IN IInternetHostSecurityManager * pihsm, IN DWORD dwUrlAction, IN DWORD dwFlags, OUT OPTIONAL HRESULT * phr)
  150. {
  151. HRESULT hr;
  152. IInternetHostSecurityManager * pihsmTemp = NULL;
  153. if (!pihsm)
  154. {
  155. hr = IUnknown_QueryService(_punkSite, IID_IInternetHostSecurityManager, IID_PPV_ARG(IInternetHostSecurityManager, &pihsmTemp));
  156. pihsm= pihsmTemp;
  157. }
  158. hr = ZoneCheckHost(pihsm, dwUrlAction, dwFlags);
  159. if (S_FALSE == hr)
  160. hr = E_ACCESSDENIED; // The caller needs to soften the hr to S_OK if it's concerned for script.
  161. if (phr)
  162. *phr = hr;
  163. ATOMICRELEASE(pihsmTemp);
  164. return ((S_OK == hr) ? TRUE : FALSE);
  165. }
  166. HRESULT CAutomationSecurity::MakeObjectSafe(IN IUnknown ** ppunk)
  167. {
  168. HRESULT hr;
  169. // See if the host is always safe.
  170. if (!IsSafeHost(&hr))
  171. {
  172. // It isn't, so let's ask the control if it's
  173. // going to be safe.
  174. hr = MakeSafeForScripting(ppunk);
  175. }
  176. return hr;
  177. }