summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-15 14:41:48 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-15 14:41:48 +0000
commit55604d73d488ecdbfaca303d9e4ee1ec01391301 (patch)
tree5c3ac04d1ebb4bbf8f120d30569df7a1c5ff521b /chrome_frame
parentdb9afc2141180923600d998c46ae2afc32453495 (diff)
downloadchromium_src-55604d73d488ecdbfaca303d9e4ee1ec01391301.zip
chromium_src-55604d73d488ecdbfaca303d9e4ee1ec01391301.tar.gz
chromium_src-55604d73d488ecdbfaca303d9e4ee1ec01391301.tar.bz2
Basic policy implementation for Chrome Frame. We read the policy settings on first request and cache them.
In order to refresh the policy settings the browser has to be restarted. Future implementations may support pushing out policy changes without requiring the user to restart the browser. TEST=Use the policy templates to change the default renderer ("Configure the default renderer for Chrome Frame") and relevant exclusion lists. BUG=29349 Review URL: http://codereview.chromium.org/3435004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59496 0039d316-1c4b-4281-b951-d872f2087c98
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;