summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-09 06:05:48 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-09 06:05:48 +0000
commitd90398121f891434b26ecd0d886cdb9a1073cf87 (patch)
tree60fe71ad8d62a69840415e165a788d7cfb1087b8 /chrome
parentfc85d0c09ea726d5f4377a92f5f6ad2a904650e4 (diff)
downloadchromium_src-d90398121f891434b26ecd0d886cdb9a1073cf87.zip
chromium_src-d90398121f891434b26ecd0d886cdb9a1073cf87.tar.gz
chromium_src-d90398121f891434b26ecd0d886cdb9a1073cf87.tar.bz2
Add a group policy controlling which sites can install extensions.
BUG=55584 TBR=jhawkins@chromium.org Review URL: https://chromiumcodereview.appspot.com/10542048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141355 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/policy/policy_templates.json19
-rw-r--r--chrome/browser/download/download_crx_util.cc20
-rw-r--r--chrome/browser/extensions/crx_installer.cc7
-rw-r--r--chrome/browser/extensions/crx_installer.h19
-rw-r--r--chrome/browser/extensions/crx_installer_browsertest.cc6
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc5
-rw-r--r--chrome/browser/extensions/extension_prefs.cc23
-rw-r--r--chrome/browser/extensions/extension_prefs.h5
-rw-r--r--chrome/browser/policy/configuration_policy_handler.cc58
-rw-r--r--chrome/browser/policy/configuration_policy_handler.h20
-rw-r--r--chrome/browser/policy/configuration_policy_handler_list.cc4
-rw-r--r--chrome/browser/policy/configuration_policy_handler_unittest.cc59
-rw-r--r--chrome/browser/ui/webui/extensions/install_extension_handler.cc3
-rw-r--r--chrome/common/pref_names.cc13
-rw-r--r--chrome/common/pref_names.h4
-rwxr-xr-xchrome/test/functional/policy_test_cases.py3
16 files changed, 252 insertions, 16 deletions
diff --git a/chrome/app/policy/policy_templates.json b/chrome/app/policy/policy_templates.json
index ad48e2d..3594914 100644
--- a/chrome/app/policy/policy_templates.json
+++ b/chrome/app/policy/policy_templates.json
@@ -112,7 +112,7 @@
# persistent IDs for all fields (but not for groups!) are needed. These are
# specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
# because doing so would break the deployed wire format!
-# For your editing convenience: highest ID currently used: 147
+# For your editing convenience: highest ID currently used: 148
#
# Placeholders:
# The following placeholder strings are automatically substituted:
@@ -1104,6 +1104,23 @@
If this policy is left not set the user can uninstall any extension in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.''',
'label': '''Extension IDs and update URLs to be silently installed''',
},
+ {
+ 'name': 'ExtensionInstallSources',
+ 'type': 'list',
+ 'supported_on': ['chrome.*:21-', 'chrome_os:21-'],
+ 'features': {'dynamic_refresh': True},
+ 'example_value': ['https://corp.mycompany.com/*'],
+ 'id': 148,
+ 'caption': '''Configure extension, app, and user script install sources''',
+ 'desc': '''Allows you to specify which URLs are allowed to install extensions, apps, and themes.
+
+ Starting in Chrome 21, it is more difficult to install extensions, apps, and user scripts from outside the Chrome Web Store. Previously, users could click on a link to a *.crx file, and Chrome would offer to install the file after a few warnings. After Chrome 21, such files must be downloaded an dragged onto the Chrome settings page. This setting allows specific URLs to have the old, easier installation flow.
+
+ Each item in this list is an extension-style match pattern (see http://code.google.com/chrome/extensions/match_patterns.html). Users will be able to easily install items from any URL that matches an item in this list.
+
+ ExtensionInstallBlacklist takes precedence over this policy. That is, an extension on the blacklist won't be installed, even if it happens from a site on this list.''',
+ 'label': '''URL patterns to allow extension, app, and user script installs from''',
+ },
],
},
{
diff --git a/chrome/browser/download/download_crx_util.cc b/chrome/browser/download/download_crx_util.cc
index 08f8d2e..c76dbb3 100644
--- a/chrome/browser/download/download_crx_util.cc
+++ b/chrome/browser/download/download_crx_util.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_notification_types.h"
@@ -43,6 +44,20 @@ ExtensionInstallPrompt* CreateExtensionInstallPrompt(Profile* profile) {
return result;
}
+bool OffStoreInstallAllowedByPrefs(Profile* profile, const DownloadItem& item) {
+ ExtensionPrefs* prefs =
+ ExtensionSystem::Get(profile)->extension_service()->extension_prefs();
+ CHECK(prefs);
+
+ URLPatternSet url_patterns = prefs->GetAllowedInstallSites();
+
+ // TODO(aa): RefererURL is cleared in some cases, for example when going
+ // between secure and non-secure URLs. It would be better if DownloadItem
+ // tracked the initiating page explicitly.
+ return url_patterns.MatchesURL(item.GetURL()) &&
+ url_patterns.MatchesURL(item.GetReferrerUrl());
+}
+
} // namespace
// Tests can call this method to inject a mock ExtensionInstallPrompt
@@ -68,6 +83,11 @@ scoped_refptr<CrxInstaller> OpenChromeExtension(
installer->set_delete_source(true);
installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
+ if (OffStoreInstallAllowedByPrefs(profile, download_item)) {
+ installer->set_off_store_install_allow_reason(
+ CrxInstaller::OffStoreInstallAllowedBecausePref);
+ }
+
if (UserScript::IsURLUserScript(download_item.GetURL(),
download_item.GetMimeType())) {
installer->InstallUserScript(download_item.GetFullPath(),
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index a7137a9..a4a1c13 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -98,7 +98,7 @@ CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> frontend_weak,
allow_silent_install_(false),
install_cause_(extension_misc::INSTALL_CAUSE_UNSET),
creation_flags_(Extension::NO_FLAGS),
- allow_off_store_install_(false) {
+ off_store_install_allow_reason_(OffStoreInstallDisallowed) {
if (!approval)
return;
@@ -260,9 +260,12 @@ bool CrxInstaller::AllowInstall(const Extension* extension,
if (is_gallery_install()) {
UMA_HISTOGRAM_ENUMERATION(kHistogramName, OnStoreInstall,
NumOffStoreInstallDecision);
- } else if (allow_off_store_install_) {
+ } else if (off_store_install_allow_reason_ != OffStoreInstallDisallowed) {
UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallAllowed,
NumOffStoreInstallDecision);
+ UMA_HISTOGRAM_ENUMERATION("Extensions.OffStoreInstallAllowReason",
+ off_store_install_allow_reason_,
+ NumOffStoreInstallAllowReasons);
} else {
UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallDisallowed,
NumOffStoreInstallDecision);
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 9d9ad3b..f90c85f 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -54,6 +54,15 @@ class CrxInstaller
: public SandboxedExtensionUnpackerClient,
public ExtensionInstallPrompt::Delegate {
public:
+ // Used in histograms; do not change order.
+ enum OffStoreInstallAllowReason {
+ OffStoreInstallDisallowed,
+ OffStoreInstallAllowedFromSettingsPage,
+ OffStoreInstallAllowedBecausePref,
+ OffStoreInstallAllowedInTest,
+ NumOffStoreInstallAllowReasons
+ };
+
// Extensions will be installed into frontend->install_directory(),
// then registered with |frontend|. Any install UI will be displayed
// using |client|. Pass NULL for |client| for silent install
@@ -146,8 +155,12 @@ class CrxInstaller
install_cause_ = install_cause;
}
- bool allow_off_store_install() const { return allow_off_store_install_; }
- void set_allow_off_store_install(bool val) { allow_off_store_install_ = val; }
+ OffStoreInstallAllowReason off_store_install_allow_reason() const {
+ return off_store_install_allow_reason_;
+ }
+ void set_off_store_install_allow_reason(OffStoreInstallAllowReason reason) {
+ off_store_install_allow_reason_ = reason;
+ }
void set_page_ordinal(const StringOrdinal& page_ordinal) {
page_ordinal_ = page_ordinal;
@@ -312,7 +325,7 @@ class CrxInstaller
int creation_flags_;
// Whether to allow off store installation.
- bool allow_off_store_install_;
+ OffStoreInstallAllowReason off_store_install_allow_reason_;
DISALLOW_COPY_AND_ASSIGN(CrxInstaller);
};
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index 8e86a1c..c5a0a62 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -199,7 +199,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_AllowOffStore) {
CrxInstaller::Create(service, mock_prompt));
crx_installer->set_install_cause(
extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
- crx_installer->set_allow_off_store_install(kTestData[i]);
+
+ if (kTestData[i]) {
+ crx_installer->set_off_store_install_allow_reason(
+ CrxInstaller::OffStoreInstallAllowedInTest);
+ }
crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
EXPECT_EQ(kTestData[i], WaitForExtensionInstall()) << kTestData[i];
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 385f5b2..6d82f63 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -303,8 +303,11 @@ const Extension* ExtensionBrowserTest::InstallOrUpdateExtension(
scoped_refptr<CrxInstaller> installer(
CrxInstaller::Create(service, install_ui));
installer->set_expected_id(id);
- installer->set_allow_off_store_install(true);
installer->set_is_gallery_install(from_webstore);
+ if (!from_webstore) {
+ installer->set_off_store_install_allow_reason(
+ CrxInstaller::OffStoreInstallAllowedInTest);
+ }
content::NotificationRegistrar registrar;
registrar.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE,
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 41c1017..6f0f3fb 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -1904,6 +1904,27 @@ void ExtensionPrefs::ClearIncognitoSessionOnlyContentSettings() {
}
}
+URLPatternSet ExtensionPrefs::GetAllowedInstallSites() {
+ URLPatternSet result;
+ const ListValue* list = prefs_->GetList(prefs::kExtensionAllowedInstallSites);
+ CHECK(list);
+
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ std::string entry_string;
+ URLPattern entry(URLPattern::SCHEME_ALL);
+ if (!list->GetString(i, &entry_string) ||
+ entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) {
+ LOG(ERROR) << "Invalid value for preference: "
+ << prefs::kExtensionAllowedInstallSites
+ << "." << i;
+ continue;
+ }
+ result.AddPattern(entry);
+ }
+
+ return result;
+}
+
// static
void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(kExtensionsPref, PrefService::UNSYNCABLE_PREF);
@@ -1931,4 +1952,6 @@ void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterInt64Pref(prefs::kNextExtensionsUpdateCheck,
0, // default value
PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterListPref(prefs::kExtensionAllowedInstallSites,
+ PrefService::UNSYNCABLE_PREF);
}
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index 92ca408..37607bf 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -19,6 +19,7 @@
#include "chrome/browser/extensions/extension_scoped_prefs.h"
#include "chrome/browser/extensions/management_policy.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/url_pattern_set.h"
#include "chrome/common/string_ordinal.h"
class ExtensionPrefValueMap;
@@ -432,6 +433,10 @@ class ExtensionPrefs : public extensions::ContentSettingsStore::Observer,
return extension_sorting_.get();
}
+ // Describes the URLs that are able to install extensions. See
+ // prefs::kExtensionAllowedInstallSites for more information.
+ URLPatternSet GetAllowedInstallSites();
+
protected:
// For unit testing. Enables injecting an artificial clock that is used
// to query the current time, when an extension is installed.
diff --git a/chrome/browser/policy/configuration_policy_handler.cc b/chrome/browser/policy/configuration_policy_handler.cc
index 023cb1d..06ab093 100644
--- a/chrome/browser/policy/configuration_policy_handler.cc
+++ b/chrome/browser/policy/configuration_policy_handler.cc
@@ -280,6 +280,64 @@ bool ExtensionListPolicyHandler::CheckAndGetList(
return true;
}
+// ExtensionURLPatternListPolicyHandler implementation -------------------------
+
+ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler(
+ const char* policy_name,
+ const char* pref_path)
+ : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
+ pref_path_(pref_path) {}
+
+ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {}
+
+bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings(
+ const PolicyMap& policies,
+ PolicyErrorMap* errors) {
+ const base::Value* value = NULL;
+ if (!CheckAndGetValue(policies, errors, &value))
+ return false;
+
+ if (!value)
+ return true;
+
+ const base::ListValue* list_value = NULL;
+ if (!value->GetAsList(&list_value)) {
+ NOTREACHED();
+ return false;
+ }
+
+ // Check that the list contains valid URLPattern strings only.
+ for (base::ListValue::const_iterator entry(list_value->begin());
+ entry != list_value->end(); ++entry) {
+ std::string url_pattern_string;
+ if (!(*entry)->GetAsString(&url_pattern_string)) {
+ errors->AddError(policy_name(),
+ entry - list_value->begin(),
+ IDS_POLICY_TYPE_ERROR,
+ ValueTypeToString(base::Value::TYPE_STRING));
+ return false;
+ }
+
+ URLPattern pattern(URLPattern::SCHEME_ALL);
+ if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) {
+ errors->AddError(policy_name(),
+ entry - list_value->begin(),
+ IDS_POLICY_VALUE_FORMAT_ERROR);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings(
+ const PolicyMap& policies,
+ PrefValueMap* prefs) {
+ const Value* value = policies.GetValue(policy_name());
+ if (value)
+ prefs->SetValue(pref_path_, value->DeepCopy());
+}
+
// SimplePolicyHandler implementation ------------------------------------------
SimplePolicyHandler::SimplePolicyHandler(
diff --git a/chrome/browser/policy/configuration_policy_handler.h b/chrome/browser/policy/configuration_policy_handler.h
index 8ddf542..6b75800 100644
--- a/chrome/browser/policy/configuration_policy_handler.h
+++ b/chrome/browser/policy/configuration_policy_handler.h
@@ -128,6 +128,26 @@ class ExtensionListPolicyHandler : public TypeCheckingPolicyHandler {
DISALLOW_COPY_AND_ASSIGN(ExtensionListPolicyHandler);
};
+// Implements additional checks for policies that are lists of extension
+// URLPatterns.
+class ExtensionURLPatternListPolicyHandler : public TypeCheckingPolicyHandler {
+ public:
+ ExtensionURLPatternListPolicyHandler(const char* policy_name,
+ const char* pref_path);
+ virtual ~ExtensionURLPatternListPolicyHandler();
+
+ // ConfigurationPolicyHandler methods:
+ virtual bool CheckPolicySettings(const PolicyMap& policies,
+ PolicyErrorMap* errors) OVERRIDE;
+ virtual void ApplyPolicySettings(const PolicyMap& policies,
+ PrefValueMap* prefs) OVERRIDE;
+
+ private:
+ const char* pref_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionURLPatternListPolicyHandler);
+};
+
// ConfigurationPolicyHandler for the SyncDisabled policy.
class SyncPolicyHandler : public TypeCheckingPolicyHandler {
public:
diff --git a/chrome/browser/policy/configuration_policy_handler_list.cc b/chrome/browser/policy/configuration_policy_handler_list.cc
index b73caf7..23e19cc 100644
--- a/chrome/browser/policy/configuration_policy_handler_list.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list.cc
@@ -336,6 +336,10 @@ ConfigurationPolicyHandlerList::ConfigurationPolicyHandlerList() {
new ExtensionListPolicyHandler(key::kExtensionInstallBlacklist,
prefs::kExtensionInstallDenyList,
true));
+ handlers_.push_back(
+ new ExtensionURLPatternListPolicyHandler(
+ key::kExtensionInstallSources,
+ prefs::kExtensionAllowedInstallSites));
#if !defined(OS_CHROMEOS)
handlers_.push_back(new DownloadDirPolicyHandler());
diff --git a/chrome/browser/policy/configuration_policy_handler_unittest.cc b/chrome/browser/policy/configuration_policy_handler_unittest.cc
index 17bfeaa..baba2ba 100644
--- a/chrome/browser/policy/configuration_policy_handler_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_handler_unittest.cc
@@ -62,4 +62,63 @@ TEST(ExtensionListPolicyHandlerTest, ApplyPolicySettings) {
EXPECT_TRUE(base::Value::Equals(&list, value));
}
+TEST(ExtensionURLPatternListPolicyHandlerTest, CheckPolicySettings) {
+ base::ListValue list;
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+ ExtensionURLPatternListPolicyHandler handler(
+ key::kExtensionInstallSources,
+ prefs::kExtensionAllowedInstallSites);
+
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ list.Append(Value::CreateStringValue("http://*.google.com/*"));
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ list.Append(Value::CreateStringValue("<all_urls>"));
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ list.Append(Value::CreateStringValue("invalid"));
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ EXPECT_FALSE(errors.GetErrors(key::kExtensionInstallSources).empty());
+
+ // URLPattern syntax has a different way to express 'all urls'. Though '*'
+ // would be compatible today, it would be brittle, so we disallow.
+ list.Append(Value::CreateStringValue("*"));
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ EXPECT_FALSE(errors.GetErrors(key::kExtensionInstallSources).empty());
+}
+
+TEST(ExtensionURLPatternListPolicyHandlerTest, ApplyPolicySettings) {
+ base::ListValue list;
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ base::Value* value = NULL;
+ ExtensionURLPatternListPolicyHandler handler(
+ key::kExtensionInstallSources,
+ prefs::kExtensionAllowedInstallSites);
+
+ list.Append(Value::CreateStringValue("https://corp.monkey.net/*"));
+ policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, list.DeepCopy());
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(prefs::kExtensionAllowedInstallSites, &value));
+ EXPECT_TRUE(base::Value::Equals(&list, value));
+}
+
} // namespace policy
diff --git a/chrome/browser/ui/webui/extensions/install_extension_handler.cc b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
index 07c7c0a..3a53ff6 100644
--- a/chrome/browser/ui/webui/extensions/install_extension_handler.cc
+++ b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
@@ -84,7 +84,8 @@ void InstallExtensionHandler::HandleInstallMessage(const ListValue* args) {
CrxInstaller::Create(
ExtensionSystem::Get(profile)->extension_service(),
new ExtensionInstallPrompt(profile)));
- crx_installer->set_allow_off_store_install(true);
+ crx_installer->set_off_store_install_allow_reason(
+ CrxInstaller::OffStoreInstallAllowedFromSettingsPage);
const bool kCaseSensitive = false;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 001489c..f6dd8a8 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1356,13 +1356,18 @@ const char kDisablePluginFinder[] = "plugins.disable_plugin_finder";
const char kBrowserActionContainerWidth[] =
"extensions.browseractions.container.width";
+// The sites that are allowed to install extensions. These sites should be
+// allowed to install extensions without the scary dangerous downloads bar.
+// Also, when off-store-extension installs are disabled, these sites are exempt.
+const char kExtensionAllowedInstallSites[] = "extensions.allowed_install_sites";
+
// A whitelist of extension ids the user can install: exceptions from the
-// following blacklist. This is controlled by the administrator.
+// following blacklist.
const char kExtensionInstallAllowList[] = "extensions.install.allowlist";
+
// A blacklist, containing extensions the user cannot install. This list can
-// conatin "*" meaning all extensions. This is controlled by the administrator.
-// This list should not be confused with the extension blacklist, which is
-// Google controlled.
+// contain "*" meaning all extensions. This list should not be confused with the
+// extension blacklist, which is Google controlled.
const char kExtensionInstallDenyList[] = "extensions.install.denylist";
// Whether we have run the extension-alert system (see ExtensionGlobalError)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index a908784..16343be 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -499,13 +499,11 @@ extern const char kBrowserActionContainerWidth[];
extern const char kLastExtensionsUpdateCheck[];
extern const char kNextExtensionsUpdateCheck[];
+extern const char kExtensionAllowedInstallSites[];
extern const char kExtensionInstallAllowList[];
extern const char kExtensionInstallDenyList[];
-
extern const char kExtensionAlertsInitializedPref[];
-
extern const char kExtensionInstallForceList[];
-
extern const char kExtensionBlacklistUpdateVersion[];
extern const char kNtpTipsResourceServer[];
diff --git a/chrome/test/functional/policy_test_cases.py b/chrome/test/functional/policy_test_cases.py
index 882ba2d..0a16076 100755
--- a/chrome/test/functional/policy_test_cases.py
+++ b/chrome/test/functional/policy_test_cases.py
@@ -137,6 +137,9 @@ class PolicyPrefsTestCases(object):
'ExtensionInstallForcelist':
('kExtensionInstallForceList', ['lcncmkcnkcdbbanbjakcencbaoegdjlp;' +
'https://clients2.google.com/service/update2/crx'], [], OS_ALL),
+ 'ExtensionInstallSources':
+ ('kExtensionInstallSources', ['https://www.corp.monkey.net/*'],
+ [], OS_ALL),
'ShowHomeButton': ('kShowHomeButton', True, [BROWSER], OS_ALL),
'DeveloperToolsDisabled': ('kDevToolsDisabled', True, [], OS_ALL),
'RestoreOnStartup': (None, 5, [BROWSER], OS_ALL),