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.

95 lines
2.9 KiB

  1. ///////////////////////////////////////////////////////////
  2. // ObjectWithSiteImplSec.h : Secure implementation of IObjectWithSite
  3. // Copyright (c) Microsoft Corporation 2002.
  4. #pragma once
  5. #ifndef OBJECTWITHSITEIMPLSEC_H
  6. #define OBJECTWITHSITEIMPLSEC_H
  7. #include <guiddef.h>
  8. #include <ocidl.h>
  9. #include <urlmon.h>
  10. #if defined(DEBUG) || defined(W32_OBJECT_STREAMING)
  11. #include <atlconv.h>
  12. #endif
  13. using namespace ::ATL;
  14. #include <strsafe.h>
  15. inline HRESULT IsSafeZone(DWORD dwZone) {
  16. switch (dwZone) {
  17. case URLZONE_LOCAL_MACHINE:
  18. case URLZONE_INTRANET:
  19. case URLZONE_TRUSTED:
  20. // the fixed list of zones we trust
  21. return NOERROR;
  22. default:
  23. // everything else is untrusted
  24. return E_FAIL;
  25. }
  26. }
  27. inline HRESULT IsSafeSite(IUnknown* pSite) {
  28. CComQIPtr<IServiceProvider> psp(pSite);
  29. if (!psp) {
  30. // no service provider interface on the site implies that we're not running in IE
  31. // so by defn running local and trusted thus we return OK
  32. return NOERROR;
  33. }
  34. CComQIPtr<IInternetHostSecurityManager> pManager;
  35. HRESULT hr = psp->QueryService(SID_SInternetHostSecurityManager, IID_IInternetHostSecurityManager, (LPVOID *)&pManager);
  36. if (FAILED(hr)) {
  37. // no security manager interface on the site's service provider implies that we're not
  38. // running in IE, so by defn running local and trusted thus we return OK
  39. return NOERROR;
  40. }
  41. const int MAXZONE = MAX_SIZE_SECURITY_ID+6/*scheme*/+4/*zone(dword)*/+1/*wildcard*/+1/*trailing null*/;
  42. char pbSecurityId[MAXZONE];
  43. DWORD pcbSecurityId = sizeof(pbSecurityId);
  44. ZeroMemory(pbSecurityId, sizeof(pbSecurityId));
  45. hr = pManager->GetSecurityId(reinterpret_cast<BYTE*>(pbSecurityId), &pcbSecurityId, NULL);
  46. if(FAILED(hr)){
  47. // security manager not working(unexpected). but, the site tried to provide one. thus we
  48. // must assume untrusted content and fail
  49. return E_FAIL;
  50. }
  51. char *pbEnd = pbSecurityId + pcbSecurityId - 1;
  52. if (*pbEnd == '*') { //ignore the optional wildcard flag
  53. pbEnd--;
  54. }
  55. pbEnd -= 3; // point to beginning of little endian zone dword
  56. DWORD dwZone = *(reinterpret_cast<long *>(pbEnd));
  57. return IsSafeZone(dwZone);
  58. }
  59. template<class T>
  60. class ATL_NO_VTABLE IObjectWithSiteImplSec : public IObjectWithSite {
  61. public:
  62. CComPtr<IUnknown> m_pSite;
  63. // IObjectWithSite
  64. STDMETHOD(GetSite)(REFIID iid, void** ppvSite) {
  65. if (!ppvSite) {
  66. return E_POINTER;
  67. }
  68. T* pT = static_cast<T*>(this);
  69. if (!pT->m_pSite) {
  70. return E_NOINTERFACE;
  71. }
  72. return pT->m_pSite->QueryInterface(iid, ppvSite);
  73. }
  74. STDMETHOD(SetSite)(IUnknown* pSite) {
  75. HRESULT hr = IsSafeSite(pSite);
  76. if (SUCCEEDED(hr)) {
  77. T* pT = static_cast<T*>(this);
  78. pT->m_pSite = pSite;
  79. }
  80. return hr;
  81. }
  82. };
  83. #endif // OBJECTWITHSITEIMPLSEC_H
  84. // end of file objectwithsiteimplsec.h