diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 22:44:58 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 22:44:58 +0000 |
commit | 42d7c0218dc58679cebee0a2cd18dcb00a85dfbc (patch) | |
tree | 9aa6253efcbd6cef14c19b4a9aaa22d9de79d4eb /chrome_frame/test | |
parent | 90a7ad5203fea92a68b6ac3b18f09b67a48192d5 (diff) | |
download | chromium_src-42d7c0218dc58679cebee0a2cd18dcb00a85dfbc.zip chromium_src-42d7c0218dc58679cebee0a2cd18dcb00a85dfbc.tar.gz chromium_src-42d7c0218dc58679cebee0a2cd18dcb00a85dfbc.tar.bz2 |
Launch COM server IE as low integrity process on Vista.
Review URL: http://codereview.chromium.org/402089
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32699 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/test')
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 88 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.h | 15 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_unittests.cc | 53 |
3 files changed, 130 insertions, 26 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index cb59615..2cce441 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -7,6 +7,7 @@ #include <atlbase.h> #include <atlwin.h> #include <iepmapi.h> +#include <sddl.h> #include "base/message_loop.h" #include "base/registry.h" // to find IE and firefox @@ -533,4 +534,91 @@ HWND GetChromeRendererWindow() { return chrome_window; } + +LowIntegrityToken::LowIntegrityToken() : impersonated_(false) { +} + +LowIntegrityToken::~LowIntegrityToken() { + RevertToSelf(); +} + +BOOL LowIntegrityToken::RevertToSelf() { + BOOL ok = TRUE; + if (impersonated_) { + DCHECK(IsImpersonated()); + ok = ::RevertToSelf(); + if (ok) + impersonated_ = false; + } + + return ok; +} + +BOOL LowIntegrityToken::Impersonate() { + DCHECK(!impersonated_); + DCHECK(!IsImpersonated()); + HANDLE process_token_handle = NULL; + BOOL ok = ::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, + &process_token_handle); + if (!ok) { + DLOG(ERROR) << "::OpenProcessToken failed: " << GetLastError(); + return ok; + } + + ScopedHandle process_token(process_token_handle); + // Create impersonation low integrity token. + HANDLE impersonation_token_handle = NULL; + ok = ::DuplicateTokenEx(process_token, + TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, NULL, + SecurityImpersonation, TokenImpersonation, &impersonation_token_handle); + if (!ok) { + DLOG(ERROR) << "::DuplicateTokenEx failed: " << GetLastError(); + return ok; + } + + // TODO: sandbox/src/restricted_token_utils.cc has SetTokenIntegrityLevel + // function already. + ScopedHandle impersonation_token(impersonation_token_handle); + PSID integrity_sid = NULL; + TOKEN_MANDATORY_LABEL tml = {0}; + ok = ::ConvertStringSidToSid(SDDL_ML_LOW, &integrity_sid); + if (!ok) { + DLOG(ERROR) << "::ConvertStringSidToSid failed: " << GetLastError(); + return ok; + } + + tml.Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED; + tml.Label.Sid = integrity_sid; + ok = ::SetTokenInformation(impersonation_token, TokenIntegrityLevel, + &tml, sizeof(tml) + ::GetLengthSid(integrity_sid)); + ::LocalFree(integrity_sid); + if (!ok) { + DLOG(ERROR) << "::SetTokenInformation failed: " << GetLastError(); + return ok; + } + + // Switch current thread to low integrity. + ok = ::ImpersonateLoggedOnUser(impersonation_token); + if (ok) { + impersonated_ = true; + } else { + DLOG(ERROR) << "::ImpersonateLoggedOnUser failed: " << GetLastError(); + } + + return ok; +} + +bool LowIntegrityToken::IsImpersonated() { + HANDLE token = NULL; + if (!::OpenThreadToken(::GetCurrentThread(), 0, false, &token) && + ::GetLastError() != ERROR_NO_TOKEN) { + return true; + } + + if (token) + ::CloseHandle(token); + + return false; +} + } // namespace chrome_frame_test diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h index 26da481..2947539 100644 --- a/chrome_frame/test/chrome_frame_test_utils.h +++ b/chrome_frame/test/chrome_frame_test_utils.h @@ -77,6 +77,19 @@ void SendInputToWindow(HWND window, const std::string& input_string); // window. void SetKeyboardFocusToWindow(HWND window, int x, int y); +// Temporarily impersonate the current thread to low integrity for the lifetime +// of the object. Destructor will automatically revert integrity level. +class LowIntegrityToken { + public: + LowIntegrityToken(); + ~LowIntegrityToken(); + BOOL Impersonate(); + BOOL RevertToSelf(); + protected: + static bool IsImpersonated(); + bool impersonated_; +}; + } // namespace chrome_frame_test -#endif // CHROME_FRAME_CHROMETAB_UNITTESTS_CF_TEST_UTILS_H_ +#endif // CHROME_FRAME_TEST_CHROME_FRAME_TEST_UTILS_H_ diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc index 1f2340d..225eda8 100644 --- a/chrome_frame/test/chrome_frame_unittests.cc +++ b/chrome_frame/test/chrome_frame_unittests.cc @@ -15,7 +15,7 @@ #include "base/file_util.h" #include "base/scoped_bstr_win.h" #include "base/scoped_variant_win.h" -#include "base/sys_info.h" +#include "base/win_util.h" #include "gmock/gmock.h" #include "net/url_request/url_request_unittest.h" #include "chrome_frame/test/chrome_frame_unittests.h" @@ -1193,15 +1193,27 @@ HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) { if (!web_browser) return E_INVALIDARG; - ScopedComPtr<IWebBrowser2> web_browser2; - HRESULT hr = CoCreateInstance( - CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, - reinterpret_cast<void**>(web_browser2.Receive())); - - if (SUCCEEDED(hr)) { - *web_browser = web_browser2.Detach(); + HRESULT hr = S_OK; + chrome_frame_test::LowIntegrityToken token; + if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { + // Create medium integrity browser that will launch IE broker. + ScopedComPtr<IWebBrowser2> medium_integrity_browser; + hr = medium_integrity_browser.CreateInstance(CLSID_InternetExplorer, NULL, + CLSCTX_LOCAL_SERVER); + if (FAILED(hr)) + return hr; + medium_integrity_browser->Quit(); + // Broker remains alive. + if (!token.Impersonate()) { + hr = HRESULT_FROM_WIN32(GetLastError()); + return hr; + } } + hr = ::CoCreateInstance(CLSID_InternetExplorer, NULL, + CLSCTX_LOCAL_SERVER | CLSCTX_ENABLE_CLOAKING, IID_IWebBrowser2, + reinterpret_cast<void**>(web_browser)); + // ~LowIntegrityToken() will switch integrity back to medium. return hr; } @@ -1245,24 +1257,15 @@ HRESULT WebBrowserEventSink::OnMessageInternal(const VARIANT* param) { HRESULT WebBrowserEventSink::LaunchIEAndNavigate( const std::wstring& navigate_url) { - int major_version = 0; - int minor_version = 0; - int bugfix_version = 0; - - base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version, - &bugfix_version); - if (major_version > 5) { - DLOG(INFO) << __FUNCTION__ << " Not running test on Windows version: " - << major_version; - return S_FALSE; + HRESULT hr = LaunchIEAsComServer(web_browser2_.Receive()); + EXPECT_EQ(S_OK, hr); + if (hr == S_OK) { + web_browser2_->put_Visible(VARIANT_TRUE); + hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2); + EXPECT_TRUE(hr == S_OK); + hr = Navigate(navigate_url); } - - EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2_.Receive())); - web_browser2_->put_Visible(VARIANT_TRUE); - - HRESULT hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2); - EXPECT_TRUE(hr == S_OK); - return Navigate(navigate_url); + return hr; } HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) { |