summaryrefslogtreecommitdiffstats
path: root/chrome_frame/test
diff options
context:
space:
mode:
authorstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-20 22:44:58 +0000
committerstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-20 22:44:58 +0000
commit42d7c0218dc58679cebee0a2cd18dcb00a85dfbc (patch)
tree9aa6253efcbd6cef14c19b4a9aaa22d9de79d4eb /chrome_frame/test
parent90a7ad5203fea92a68b6ac3b18f09b67a48192d5 (diff)
downloadchromium_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.cc88
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.h15
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc53
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) {