summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp3
-rw-r--r--chrome_frame/policy_settings.cc70
-rw-r--r--chrome_frame/policy_settings.h45
-rw-r--r--chrome_frame/test/policy_settings_unittest.cc156
-rw-r--r--chrome_frame/utils.cc28
5 files changed, 296 insertions, 6 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index bdc9c2f..3560f7f 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -139,6 +139,7 @@
'test/exception_barrier_unittest.cc',
'test/html_util_unittests.cc',
'test/http_negotiate_unittest.cc',
+ 'test/policy_settings_unittest.cc',
'test/simulate_input.h',
'test/simulate_input.cc',
'test/urlmon_moniker_tests.h',
@@ -692,6 +693,8 @@
'module_utils.cc',
'module_utils.h',
'ole_document_impl.h',
+ 'policy_settings.cc',
+ 'policy_settings.h',
'protocol_sink_wrap.cc',
'protocol_sink_wrap.h',
'register_bho.rgs',
diff --git a/chrome_frame/policy_settings.cc b/chrome_frame/policy_settings.cc
new file mode 100644
index 0000000..f1c9984
--- /dev/null
+++ b/chrome_frame/policy_settings.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome_frame/policy_settings.h"
+
+#include "base/logging.h"
+#include "base/registry.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/common/policy_constants.h"
+
+PolicySettings::RendererForUrl PolicySettings::GetRendererForUrl(
+ const wchar_t* url) {
+ RendererForUrl renderer = default_renderer_;
+ std::vector<std::wstring>::const_iterator it;
+ for (it = renderer_exclusion_list_.begin();
+ it != renderer_exclusion_list_.end(); ++it) {
+ if (MatchPattern(url, (*it))) {
+ renderer = (renderer == RENDER_IN_HOST) ?
+ RENDER_IN_CHROME_FRAME : RENDER_IN_HOST;
+ break;
+ }
+ }
+ return renderer;
+}
+
+void PolicySettings::RefreshFromRegistry() {
+ default_renderer_ = RENDERER_NOT_SPECIFIED;
+ renderer_exclusion_list_.clear();
+
+ RegKey config_key;
+ DWORD value = RENDERER_NOT_SPECIFIED;
+ HKEY root_key[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER };
+ std::wstring settings_value(
+ ASCIIToWide(policy::key::kChromeFrameRendererSettings));
+ for (int i = 0; i < arraysize(root_key); ++i) {
+ if (config_key.Open(root_key[i], policy::kRegistrySubKey, KEY_READ) &&
+ config_key.ReadValueDW(settings_value.c_str(), &value)) {
+ break;
+ } else {
+ config_key.Close();
+ }
+ }
+
+ DCHECK(value == RENDERER_NOT_SPECIFIED ||
+ value == RENDER_IN_HOST ||
+ value == RENDER_IN_CHROME_FRAME) <<
+ "invalid default renderer setting: " << value;
+
+ if (value != RENDER_IN_HOST && value != RENDER_IN_CHROME_FRAME) {
+ DLOG(INFO) << "default renderer not specified via policy";
+ } else {
+ default_renderer_ = static_cast<RendererForUrl>(value);
+ const char* exclusion_list_name = (default_renderer_ == RENDER_IN_HOST) ?
+ policy::key::kRenderInChromeFrameList :
+ policy::key::kRenderInHostList;
+
+ RegistryValueIterator url_list(config_key.Handle(),
+ ASCIIToWide(exclusion_list_name).c_str());
+ while (url_list.Valid()) {
+ renderer_exclusion_list_.push_back(url_list.Value());
+ ++url_list;
+ }
+ DLOG(INFO) << "Default renderer as specified via policy: " <<
+ default_renderer_ << " exclusion list size: " <<
+ renderer_exclusion_list_.size();
+ }
+}
+
diff --git a/chrome_frame/policy_settings.h b/chrome_frame/policy_settings.h
new file mode 100644
index 0000000..a4c1267
--- /dev/null
+++ b/chrome_frame/policy_settings.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_FRAME_POLICY_SETTINGS_H_
+#define CHROME_FRAME_POLICY_SETTINGS_H_
+
+#include <string>
+#include <vector>
+
+// A simple class that reads and caches policy settings for Chrome Frame.
+// TODO(tommi): Support refreshing when new settings are pushed.
+// TODO(tommi): Use Chrome's classes for this (and the notification service).
+class PolicySettings {
+ public:
+ typedef enum RendererForUrl {
+ RENDERER_NOT_SPECIFIED = -1,
+ RENDER_IN_HOST,
+ RENDER_IN_CHROME_FRAME,
+ };
+
+ PolicySettings() : default_renderer_(RENDERER_NOT_SPECIFIED) {
+ RefreshFromRegistry();
+ }
+
+ ~PolicySettings() {
+ }
+
+ RendererForUrl default_renderer() const {
+ return default_renderer_;
+ }
+
+ RendererForUrl GetRendererForUrl(const wchar_t* url);
+
+ protected:
+ // Protected for now since the class is not thread safe.
+ void RefreshFromRegistry();
+
+ protected:
+ RendererForUrl default_renderer_;
+ std::vector<std::wstring> renderer_exclusion_list_;
+};
+
+
+#endif // CHROME_FRAME_POLICY_SETTINGS_H_
diff --git a/chrome_frame/test/policy_settings_unittest.cc b/chrome_frame/test/policy_settings_unittest.cc
new file mode 100644
index 0000000..9dee3d6
--- /dev/null
+++ b/chrome_frame/test/policy_settings_unittest.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/registry.h"
+#include "base/scoped_ptr.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/common/policy_constants.h"
+#include "chrome_frame/policy_settings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// A best effort way to zap CF policy entries that may be in the registry.
+void DeleteChromeFramePolicyEntries(HKEY root) {
+ RegKey key;
+ if (key.Open(root, policy::kRegistrySubKey, KEY_ALL_ACCESS)) {
+ key.DeleteValue(
+ ASCIIToWide(policy::key::kChromeFrameRendererSettings).c_str());
+ key.DeleteKey(ASCIIToWide(policy::key::kRenderInChromeFrameList).c_str());
+ key.DeleteKey(ASCIIToWide(policy::key::kRenderInHostList).c_str());
+ }
+}
+
+class TempRegKeyOverride {
+ public:
+ static const wchar_t kTempTestKeyPath[];
+
+ TempRegKeyOverride(HKEY override, const wchar_t* temp_name)
+ : override_(override), temp_name_(temp_name) {
+ DCHECK(temp_name && lstrlenW(temp_name));
+ std::wstring key_path(kTempTestKeyPath);
+ key_path += L"\\" + temp_name_;
+ EXPECT_TRUE(temp_key_.Create(HKEY_CURRENT_USER, key_path.c_str(),
+ KEY_ALL_ACCESS));
+ EXPECT_EQ(ERROR_SUCCESS,
+ ::RegOverridePredefKey(override_, temp_key_.Handle()));
+ }
+
+ ~TempRegKeyOverride() {
+ ::RegOverridePredefKey(override_, NULL);
+ // The temp key will be deleted via a call to DeleteAllTempKeys().
+ }
+
+ static void DeleteAllTempKeys() {
+ RegKey key;
+ if (key.Open(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS)) {
+ key.DeleteKey(kTempTestKeyPath);
+ }
+ }
+
+ protected:
+ HKEY override_;
+ RegKey temp_key_;
+ std::wstring temp_name_;
+};
+
+const wchar_t TempRegKeyOverride::kTempTestKeyPath[] =
+ L"Software\\Chromium\\TempTestKeys";
+
+bool SetRendererSettings(HKEY policy_root,
+ PolicySettings::RendererForUrl renderer,
+ const wchar_t* exclusions[],
+ int exclusion_count) {
+ RegKey policy_key;
+ EXPECT_TRUE(policy_key.Create(policy_root, policy::kRegistrySubKey,
+ KEY_ALL_ACCESS));
+ if (!policy_key.Valid())
+ return false;
+
+ policy_key.WriteValue(
+ ASCIIToWide(policy::key::kChromeFrameRendererSettings).c_str(),
+ static_cast<DWORD>(renderer));
+
+ std::wstring in_cf(ASCIIToWide(policy::key::kRenderInChromeFrameList));
+ std::wstring in_host(ASCIIToWide(policy::key::kRenderInHostList));
+ // Remove any previous settings
+ policy_key.DeleteKey(in_cf.c_str());
+ policy_key.DeleteKey(in_host.c_str());
+
+ std::wstring exclusion_list(
+ renderer == PolicySettings::RENDER_IN_CHROME_FRAME ? in_host : in_cf);
+ RegKey exclusion_key;
+ EXPECT_TRUE(exclusion_key.Create(policy_key.Handle(), exclusion_list.c_str(),
+ KEY_ALL_ACCESS));
+ for (int i = 0; i < exclusion_count; ++i) {
+ EXPECT_TRUE(exclusion_key.WriteValue(StringPrintf(L"%i", i).c_str(),
+ exclusions[i]));
+ }
+
+ return true;
+}
+
+} // end namespace
+
+TEST(PolicySettings, RendererForUrl) {
+ TempRegKeyOverride::DeleteAllTempKeys();
+
+ scoped_ptr<TempRegKeyOverride> hklm_pol(
+ new TempRegKeyOverride(HKEY_LOCAL_MACHINE, L"hklm_pol"));
+ scoped_ptr<TempRegKeyOverride> hkcu_pol(
+ new TempRegKeyOverride(HKEY_CURRENT_USER, L"hkcu_pol"));
+
+ const wchar_t* kTestUrls[] = {
+ L"http://www.example.com",
+ L"http://www.pattern.com",
+ L"http://www.test.com"
+ };
+ const wchar_t* kTestFilters[] = {
+ L"*.example.com",
+ L"*.pattern.com",
+ L"*.test.com"
+ };
+ const wchar_t kNoMatchUrl[] = L"http://www.chromium.org";
+
+ scoped_ptr<PolicySettings> settings(new PolicySettings());
+ EXPECT_EQ(settings->default_renderer(),
+ PolicySettings::RENDERER_NOT_SPECIFIED);
+ EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl),
+ PolicySettings::RENDERER_NOT_SPECIFIED);
+
+ HKEY root[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER };
+ for (int i = 0; i < arraysize(root); ++i) {
+ EXPECT_TRUE(SetRendererSettings(root[i],
+ PolicySettings::RENDER_IN_CHROME_FRAME, kTestFilters,
+ arraysize(kTestFilters)));
+
+ settings.reset(new PolicySettings());
+ EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl),
+ PolicySettings::RENDER_IN_CHROME_FRAME);
+ for (int j = 0; j < arraysize(kTestUrls); ++j) {
+ EXPECT_EQ(settings->GetRendererForUrl(kTestUrls[j]),
+ PolicySettings::RENDER_IN_HOST);
+ }
+
+ EXPECT_TRUE(SetRendererSettings(root[i],
+ PolicySettings::RENDER_IN_HOST, NULL, 0));
+
+ settings.reset(new PolicySettings());
+ EXPECT_EQ(settings->GetRendererForUrl(kNoMatchUrl),
+ PolicySettings::RENDER_IN_HOST);
+ for (int j = 0; j < arraysize(kTestUrls); ++j) {
+ EXPECT_EQ(settings->GetRendererForUrl(kTestUrls[j]),
+ PolicySettings::RENDER_IN_HOST);
+ }
+
+ DeleteChromeFramePolicyEntries(root[i]);
+ }
+
+ hkcu_pol.reset(NULL);
+ hklm_pol.reset(NULL);
+ TempRegKeyOverride::DeleteAllTempKeys();
+}
diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc
index 8526b9a..35fbc83 100644
--- a/chrome_frame/utils.cc
+++ b/chrome_frame/utils.cc
@@ -28,6 +28,7 @@
#include "chrome/installer/util/chrome_frame_distribution.h"
#include "chrome_frame/extra_system_apis.h"
#include "chrome_frame/html_utils.h"
+#include "chrome_frame/policy_settings.h"
#include "chrome_frame/simple_resource_loader.h"
#include "chrome_frame/utils.h"
#include "googleurl/src/gurl.h"
@@ -686,19 +687,34 @@ bool DeleteConfigValue(const wchar_t* value_name) {
}
bool IsGcfDefaultRenderer() {
- // TODO(tommi): Implement caching for this config value as it gets
- // checked frequently.
DWORD is_default = 0; // NOLINT
- RegKey config_key;
- if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) {
- config_key.ReadValueDW(kEnableGCFRendererByDefault, &is_default);
+
+ // First check policy settings
+ Singleton<PolicySettings> policy;
+ PolicySettings::RendererForUrl renderer = policy->default_renderer();
+ if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) {
+ is_default = (renderer == PolicySettings::RENDER_IN_CHROME_FRAME);
+ } else {
+ // TODO(tommi): Implement caching for this config value as it gets
+ // checked frequently.
+ RegKey config_key;
+ if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) {
+ config_key.ReadValueDW(kEnableGCFRendererByDefault, &is_default);
+ }
}
return is_default != 0;
}
bool IsOptInUrl(const wchar_t* url) {
- // TODO(tommi): Unit test.
+ // First check if the default renderer settings are specified by policy.
+ // If so, then that overrides the user settings.
+ Singleton<PolicySettings> policy;
+ PolicySettings::RendererForUrl renderer = policy->GetRendererForUrl(url);
+ if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) {
+ return (renderer == PolicySettings::RENDER_IN_CHROME_FRAME);
+ }
+
RegKey config_key;
if (!config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ))
return false;