summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 16:04:49 +0000
committerdanno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 16:04:49 +0000
commite541d9fb2e77ff788bf2353331b34ba841b99ff5 (patch)
tree3aeb2e2a599c4a73c9b068c4f98c9258a1a68c5f
parentfacc6ada0300c8e9a67b0cf283257a2c70fa15c2 (diff)
downloadchromium_src-e541d9fb2e77ff788bf2353331b34ba841b99ff5.zip
chromium_src-e541d9fb2e77ff788bf2353331b34ba841b99ff5.tar.gz
chromium_src-e541d9fb2e77ff788bf2353331b34ba841b99ff5.tar.bz2
Implement disabling of plugins through policy
TEST=manual testing of plugins page, ConfigurationPolicyPrefStoreTest* BUG=45856 Review URL: http://codereview.chromium.org/2833034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52487 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/app/policy/mac/app-Manifest.plist18
-rw-r--r--chrome/app/policy/windows/adm/en-US/chrome.adm18
-rw-r--r--chrome/app/policy/windows/admx/chrome.admx17
-rw-r--r--chrome/app/policy/windows/admx/en-US/chrome.adml10
-rw-r--r--chrome/browser/configuration_policy_pref_store.cc41
-rw-r--r--chrome/browser/configuration_policy_pref_store.h5
-rw-r--r--chrome/browser/configuration_policy_pref_store_unittest.cc73
-rw-r--r--chrome/browser/configuration_policy_provider.cc2
-rw-r--r--chrome/browser/configuration_policy_store.h8
-rw-r--r--chrome/browser/dom_ui/plugins_ui.cc16
-rw-r--r--chrome/browser/plugin_updater.cc45
-rw-r--r--chrome/browser/plugin_updater.h1
-rw-r--r--chrome/browser/resources/plugins.html83
-rw-r--r--chrome/common/plugin_group.cc54
-rw-r--r--chrome/common/plugin_group.h14
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
18 files changed, 372 insertions, 43 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 36beb3b..6c423a8 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3680,6 +3680,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_PLUGINS_DISABLED_PLUGIN" desc="Text that signifies that the plug-in is currently disabled.">
(Disabled)
</message>
+ <message name="IDS_PLUGINS_DISABLED_BY_POLICY_PLUGIN" desc="Text that signifies that the plug-in is currently disabled by a policy set by an administrator.">
+ (Disabled by centrally-administered policy)
+ </message>
+ <message name="IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY" desc="Text that indicates a plugin cannot be enabled because it has been disabled by a policy set by an administrator.">
+ Cannot enable plugins that are disabled by policy
+ </message>
<message name="IDS_PLUGINS_DISABLED_RUNNING_PLUGIN" desc="Text that signifies that the plug-in is disabled but still running, and that it will be fully disabled after a browser restart.">
(Still running; will be fully disabled after browser restart)
</message>
diff --git a/chrome/app/policy/mac/app-Manifest.plist b/chrome/app/policy/mac/app-Manifest.plist
index 2e3a1ae..a6bc820 100644
--- a/chrome/app/policy/mac/app-Manifest.plist
+++ b/chrome/app/policy/mac/app-Manifest.plist
@@ -18,9 +18,9 @@
<key>pfm_name</key>
<string>HomepageLocation</string>
<key>pfm_description</key>
- <string>The homepage URL.</string>
- <key>pfm_title</key>
<string>This policy setting specifies the location of the default home page for the user. Specify a URL here, or set to the New Tab Page. If the New Tab Page option is choosen, this will override a URL here.</string>
+ <key>pfm_title</key>
+ <string>The homepage URL.</string>
<key>pfm_targets</key>
<array>
<string>user-managed</string>
@@ -175,6 +175,20 @@
<key>pfm_type</key>
<string>boolean</string>
</dict>
+ <dict>
+ <key>pfm_name</key>
+ <string>DisabledPlugins</string>
+ <key>pfm_description</key>
+ <string>This policy specifies a list of plugins that are disabled. The policy value is a comma-separated list of the names of plugins to be disabled.</string>
+ <key>pfm_title</key>
+ <string>The list of disabled plugins.</string>
+ <key>pfm_targets</key>
+ <array>
+ <string>user-managed</string>
+ </array>
+ <key>pfm_type</key>
+ <string>string</string>
+ </dict>
</array>
</dict>
</plist>
diff --git a/chrome/app/policy/windows/adm/en-US/chrome.adm b/chrome/app/policy/windows/adm/en-US/chrome.adm
index c302a75..f409aeb 100644
--- a/chrome/app/policy/windows/adm/en-US/chrome.adm
+++ b/chrome/app/policy/windows/adm/en-US/chrome.adm
@@ -83,6 +83,20 @@ CLASS MACHINE
VALUEOFF NUMERIC 0
END POLICY
+ POLICY !!DisabledPlugins
+ #if version >= 4
+ SUPPORTED !!SUPPORTED_WINXPSP2
+ #endif
+ EXPLAIN !!DisabledPlugins_Explain
+ VALUENAME "DisabledPlugins"
+ VALUEON NUMERIC 1
+ VALUEOFF NUMERIC 0
+
+ PART !!DisabledPluginsList EDITTEXT
+ VALUENAME "DisabledPluginsList"
+ END PART
+ END POLICY
+
POLICY !!Sync
#if version >= 4
SUPPORTED !!SUPPORTED_WINXPSP2
@@ -178,6 +192,10 @@ and crash-related data to Google and prevents users from changing this setting.\
If you enable this setting, anonymous reporting of usage and crash-related data will be sent to Google.\n\n\
If you disable this setting, anonymous reporting of usage and crash-related data will never be sent to Google.\n\n\
If you enable or disable this setting, users cannot change or override this setting in Google Chrome."
+DisabledPlugins="Specify a list of plugins that are disabled"
+DisabledPlugins_Explain="Specifies a list of plugins that are disabled and prevents users from changing this setting.\n\n\
+value is a comma-separated list of the names of plugins to be disabled."
+DisabledPluginsList="Comma-separated list of disabled plugins:"
Sync="Disallow synchronization of data with Google"
Sync_Explain="Disallows data synchronization using Google-hosted sync services and prevents users from changing this setting.\n\n\
If you enable this setting, users cannot change or override this setting in Google Chrome."
diff --git a/chrome/app/policy/windows/admx/chrome.admx b/chrome/app/policy/windows/admx/chrome.admx
index 1ccf04c..b85b631 100644
--- a/chrome/app/policy/windows/admx/chrome.admx
+++ b/chrome/app/policy/windows/admx/chrome.admx
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitions revision="1.0" schemaVersion="1.0">
<policyNamespaces>
- <target prefix="fullarmor" namespace="FullArmor.4dd057b3-7d4f-4b0e-b832-fd4cd2c92884" />
+ <target prefix="fullarmor" namespace="FullArmor.3cca6b27-3c82-4689-8f0b-4ab08f8341da" />
<using prefix="windows" namespace="Microsoft.Policies.Windows" />
</policyNamespaces>
<supersededAdm fileName="C:\Development\src\chrome\app\policy\windows\adm\en-US\chrome.adm" />
@@ -88,6 +88,19 @@
<decimal value="0" />
</disabledValue>
</policy>
+ <policy name="DisabledPlugins" class="Machine" displayName="$(string.DisabledPlugins)" explainText="$(string.DisabledPlugins_Explain)" presentation="$(presentation.DisabledPlugins)" key="Software\Policies\Google\Chrome" valueName="DisabledPlugins">
+ <parentCategory ref="googlechrome" />
+ <supportedOn ref="SUPPORTED_WINXPSP2" />
+ <enabledValue>
+ <decimal value="1" />
+ </enabledValue>
+ <disabledValue>
+ <decimal value="0" />
+ </disabledValue>
+ <elements>
+ <text id="DisabledPluginsList" valueName="DisabledPluginsList" />
+ </elements>
+ </policy>
<policy name="Sync" class="Machine" displayName="$(string.Sync)" explainText="$(string.Sync_Explain)" presentation="$(presentation.Sync)" key="Software\Policies\Google\Chrome" valueName="SyncDisabled">
<parentCategory ref="googlechrome" />
<supportedOn ref="SUPPORTED_WINXPSP2" />
@@ -124,4 +137,4 @@
</elements>
</policy>
</policies>
-</policyDefinitions>
+</policyDefinitions> \ No newline at end of file
diff --git a/chrome/app/policy/windows/admx/en-US/chrome.adml b/chrome/app/policy/windows/admx/en-US/chrome.adml
index 116715b..28c58f4 100644
--- a/chrome/app/policy/windows/admx/en-US/chrome.adml
+++ b/chrome/app/policy/windows/admx/en-US/chrome.adml
@@ -73,6 +73,11 @@ If you enable this setting, anonymous reporting of usage and crash-related data
If you disable this setting, anonymous reporting of usage and crash-related data will never be sent to Google.
If you enable or disable this setting, users cannot change or override this setting in Google Chrome.</string>
+ <string id="DisabledPlugins">Specify a list of plugins that are disabled</string>
+ <string id="DisabledPlugins_Explain">Specifies a list of plugins that are disabled and prevents users from changing this setting.
+
+value is a comma-separated list of the names of plugins to be disabled.</string>
+ <string id="DisabledPluginsList">Comma-separated list of disabled plugins:</string>
<string id="Sync">Disallow synchronization of data with Google</string>
<string id="Sync_Explain">Disallows data synchronization using Google-hosted sync services and prevents users from changing this setting.
@@ -92,6 +97,11 @@ If you enable this setting, users cannot change or override this setting in Goog
<presentation id="DnsPrefetchingEnabled" />
<presentation id="SafeBrowsingEnabled" />
<presentation id="MetricsReportingEnabled" />
+ <presentation id="DisabledPlugins">
+ <textBox refId="DisabledPluginsList">
+ <label>Comma-separated list of disabled plugins:</label>
+ </textBox>
+ </presentation>
<presentation id="Sync" />
<presentation id="Proxy">
<dropdownList refId="ProxyServerMode">Choose how to specify proxy server settings:</dropdownList>
diff --git a/chrome/browser/configuration_policy_pref_store.cc b/chrome/browser/configuration_policy_pref_store.cc
index 43c9caa..2479a67 100644
--- a/chrome/browser/configuration_policy_pref_store.cc
+++ b/chrome/browser/configuration_policy_pref_store.cc
@@ -6,6 +6,8 @@
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/string16.h"
+#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/configuration_policy_provider.h"
#include "chrome/common/chrome_switches.h"
@@ -224,6 +226,41 @@ bool ConfigurationPolicyPrefStore::ApplyProxyPolicy(PolicyType policy,
return result;
}
+bool ConfigurationPolicyPrefStore::ApplyPluginPolicy(PolicyType policy,
+ Value* value) {
+ if (policy == kPolicyDisabledPlugins) {
+ string16 plugin_list;
+ if (value->GetAsUTF16(&plugin_list)) {
+ std::vector<string16> plugin_names;
+ // Change commas into tabs so that we can change escaped
+ // tabs back into commas, leaving non-escaped commas as tabs
+ // that can be used for splitting the string. Note that plugin
+ // names must not contain backslashes, since a trailing backslash
+ // in a plugin name before a comma would get swallowed during the
+ // splitting.
+ std::replace(plugin_list.begin(), plugin_list.end(), L',', L'\t');
+ ReplaceSubstringsAfterOffset(&plugin_list, 0,
+ ASCIIToUTF16("\\\t"), ASCIIToUTF16(","));
+ SplitString(plugin_list, L'\t', &plugin_names);
+ bool added_plugin = false;
+ scoped_ptr<ListValue> list(new ListValue());
+ for (std::vector<string16>::const_iterator i(plugin_names.begin());
+ i != plugin_names.end(); ++i) {
+ if (!i->empty()) {
+ list->Append(Value::CreateStringValueFromUTF16(*i));
+ added_plugin = true;
+ }
+ }
+ if (added_plugin) {
+ prefs_->Set(prefs::kPluginsPluginsBlacklist, list.release());
+ delete value;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool ConfigurationPolicyPrefStore::ApplySyncPolicy(PolicyType policy,
Value* value) {
if (policy == ConfigurationPolicyStore::kPolicySyncDisabled) {
@@ -255,6 +292,9 @@ void ConfigurationPolicyPrefStore::Apply(PolicyType policy, Value* value) {
if (ApplyProxyPolicy(policy, value))
return;
+ if (ApplyPluginPolicy(policy, value))
+ return;
+
if (ApplySyncPolicy(policy, value))
return;
@@ -264,4 +304,5 @@ void ConfigurationPolicyPrefStore::Apply(PolicyType policy, Value* value) {
// Other policy implementations go here.
NOTIMPLEMENTED();
+ delete value;
}
diff --git a/chrome/browser/configuration_policy_pref_store.h b/chrome/browser/configuration_policy_pref_store.h
index 5035cba..afbb541 100644
--- a/chrome/browser/configuration_policy_pref_store.h
+++ b/chrome/browser/configuration_policy_pref_store.h
@@ -85,6 +85,11 @@ class ConfigurationPolicyPrefStore : public PrefStore,
// of |value| in the case that the policy is proxy-specific.
bool ApplyProxyPolicy(PolicyType policy, Value* value);
+ // Processes plugin policies. Returns true if the specified policy
+ // is a plugin-related policy. ApplyPluginPolicy assumes the ownership
+ // of |value| in the case that the policy is plugin-specific.
+ bool ApplyPluginPolicy(PolicyType policy, Value* value);
+
// Handles sync-related policies. Returns true if the policy was handled.
// Assumes ownership of |value| in that case.
bool ApplySyncPolicy(PolicyType policy, Value* value);
diff --git a/chrome/browser/configuration_policy_pref_store_unittest.cc b/chrome/browser/configuration_policy_pref_store_unittest.cc
index 2311970..56dc576 100644
--- a/chrome/browser/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/configuration_policy_pref_store_unittest.cc
@@ -12,6 +12,12 @@
class ConfigurationPolicyPrefStoreTest : public testing::Test {
public:
+ // Applies a policy that has a string value.
+ void ApplyStringPolicyValue(
+ ConfigurationPolicyPrefStore* store,
+ ConfigurationPolicyStore::PolicyType type,
+ const wchar_t* policy_value);
+
// The following three methods test a policy which controls a string
// preference.
// Checks that by default, it's an empty string.
@@ -46,6 +52,13 @@ class ConfigurationPolicyPrefStoreTest : public testing::Test {
ConfigurationPolicyStore::PolicyType type);
};
+void ConfigurationPolicyPrefStoreTest::ApplyStringPolicyValue(
+ ConfigurationPolicyPrefStore* store,
+ ConfigurationPolicyStore::PolicyType type,
+ const wchar_t* policy_value) {
+ store->Apply(type, Value::CreateStringValue(policy_value));
+}
+
void ConfigurationPolicyPrefStoreTest::TestStringPolicyGetDefault(
const wchar_t* pref_name) {
ConfigurationPolicyPrefStore store(NULL, NULL);
@@ -57,7 +70,7 @@ void ConfigurationPolicyPrefStoreTest::TestStringPolicyGetDefault(
void ConfigurationPolicyPrefStoreTest::TestStringPolicySetValue(
const wchar_t* pref_name, ConfigurationPolicyStore::PolicyType type) {
ConfigurationPolicyPrefStore store(NULL, NULL);
- store.Apply(type, Value::CreateStringValue("http://chromium.org"));
+ ApplyStringPolicyValue(&store, type, L"http://chromium.org");
std::wstring result;
store.prefs()->GetString(pref_name, &result);
EXPECT_EQ(result, L"http://chromium.org");
@@ -391,3 +404,61 @@ TEST_F(ConfigurationPolicyPrefStoreTest,
&bool_result));
}
+TEST_F(ConfigurationPolicyPrefStoreTest,
+ TestPolicyProxyDisabledPlugin) {
+ FilePath unused_path(FILE_PATH_LITERAL("foo.exe"));
+ CommandLine command_line(unused_path);
+ scoped_ptr<MockConfigurationPolicyProvider> provider(
+ new MockConfigurationPolicyProvider());
+
+ ConfigurationPolicyPrefStore store(&command_line, provider.release());
+ ApplyStringPolicyValue(&store,
+ ConfigurationPolicyStore::kPolicyDisabledPlugins,
+ L"plugin1");
+ EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
+
+ ListValue* plugin_blacklist = NULL;
+ EXPECT_TRUE(store.prefs()->GetList(prefs::kPluginsPluginsBlacklist,
+ &plugin_blacklist));
+
+ ListValue::const_iterator current(plugin_blacklist->begin());
+ ListValue::const_iterator end(plugin_blacklist->end());
+
+ ASSERT_TRUE(current != end);
+ std::string plugin_name;
+ (*current)->GetAsString(&plugin_name);
+ EXPECT_EQ("plugin1", plugin_name);
+ ++current;
+ EXPECT_TRUE(current == end);
+}
+
+TEST_F(ConfigurationPolicyPrefStoreTest,
+ TestPolicyProxyDisabledPluginEscapedComma) {
+ FilePath unused_path(FILE_PATH_LITERAL("foo.exe"));
+ CommandLine command_line(unused_path);
+ scoped_ptr<MockConfigurationPolicyProvider> provider(
+ new MockConfigurationPolicyProvider());
+
+ ConfigurationPolicyPrefStore store(&command_line, provider.release());
+ ApplyStringPolicyValue(&store,
+ ConfigurationPolicyStore::kPolicyDisabledPlugins,
+ L"plugin1,plugin2\\,");
+ EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
+
+ ListValue* plugin_blacklist = NULL;
+ EXPECT_TRUE(store.prefs()->GetList(prefs::kPluginsPluginsBlacklist,
+ &plugin_blacklist));
+ ListValue::const_iterator current(plugin_blacklist->begin());
+ ListValue::const_iterator end(plugin_blacklist->end());
+ ASSERT_TRUE(current != end);
+ std::string plugin_name;
+ (*current)->GetAsString(&plugin_name);
+ EXPECT_EQ("plugin1", plugin_name);
+ ++current;
+ ASSERT_TRUE(current != end);
+ (*current)->GetAsString(&plugin_name);
+ EXPECT_EQ("plugin2,", plugin_name);
+ ++current;
+ EXPECT_TRUE(current == end);
+}
+
diff --git a/chrome/browser/configuration_policy_provider.cc b/chrome/browser/configuration_policy_provider.cc
index 3156c59..4cdc433 100644
--- a/chrome/browser/configuration_policy_provider.cc
+++ b/chrome/browser/configuration_policy_provider.cc
@@ -40,6 +40,8 @@ const InternalPolicyValueMapEntry kPolicyValueMap[] = {
Value::TYPE_BOOLEAN, "SafeBrowsingEnabled" },
{ ConfigurationPolicyStore::kPolicyMetricsReportingEnabled,
Value::TYPE_BOOLEAN, "MetricsReportingEnabled" },
+ { ConfigurationPolicyStore::kPolicyDisabledPlugins,
+ Value::TYPE_STRING, "DisabledPluginsList" },
{ ConfigurationPolicyStore::kPolicySyncDisabled,
Value::TYPE_BOOLEAN, "SyncDisabled" }
};
diff --git a/chrome/browser/configuration_policy_store.h b/chrome/browser/configuration_policy_store.h
index 8cdbe77..b12e2a5 100644
--- a/chrome/browser/configuration_policy_store.h
+++ b/chrome/browser/configuration_policy_store.h
@@ -26,7 +26,13 @@ class ConfigurationPolicyStore {
kPolicyDnsPrefetchingEnabled,
kPolicySafeBrowsingEnabled,
kPolicyMetricsReportingEnabled,
- kPolicySyncDisabled
+ kPolicySyncDisabled,
+
+ // A policy for allowing administrators to forcibly disable
+ // specific plugins. This policy is a comma-separated list of
+ // plugin names. Plugin names must not include the backslash
+ // character.
+ kPolicyDisabledPlugins
};
static const int kPolicyNoProxyServerMode = 0;
diff --git a/chrome/browser/dom_ui/plugins_ui.cc b/chrome/browser/dom_ui/plugins_ui.cc
index 25cec21..158f297 100644
--- a/chrome/browser/dom_ui/plugins_ui.cc
+++ b/chrome/browser/dom_ui/plugins_ui.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/dom_ui/plugins_ui.h"
#include <algorithm>
+#include <set>
#include <string>
#include <vector>
@@ -71,6 +72,10 @@ void PluginsUIHTMLSource::StartDataRequest(const std::string& path,
l10n_util::GetString(IDS_PLUGINS_NONE_INSTALLED));
localized_strings.SetString(L"pluginDisabled",
l10n_util::GetString(IDS_PLUGINS_DISABLED_PLUGIN));
+ localized_strings.SetString(L"pluginDisabledByPolicy",
+ l10n_util::GetString(IDS_PLUGINS_DISABLED_BY_POLICY_PLUGIN));
+ localized_strings.SetString(L"pluginCannotBeEnabledDueToPolicy",
+ l10n_util::GetString(IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY));
localized_strings.SetString(L"pluginDownload",
l10n_util::GetString(IDS_PLUGINS_DOWNLOAD));
localized_strings.SetString(L"pluginName",
@@ -143,6 +148,12 @@ class PluginsDOMHandler : public DOMMessageHandler {
void HandleShowTermsOfServiceMessage(const Value* value);
private:
+ // Creates a dictionary containing all the information about the given plugin;
+ // this is put into the list to "return" for the "requestPluginsData" message.
+ DictionaryValue* CreatePluginDetailValue(
+ const WebPluginInfo& plugin,
+ const std::set<string16>& plugin_blacklist_set);
+
// Creates a dictionary containing the important parts of the information
// about the given plugin; this is put into a list and saved in prefs.
DictionaryValue* CreatePluginSummaryValue(const WebPluginInfo& plugin);
@@ -165,8 +176,6 @@ void PluginsDOMHandler::RegisterMessages() {
void PluginsDOMHandler::HandleRequestPluginsData(const Value* value) {
DictionaryValue* results = new DictionaryValue();
-
- // Grouped plugins.
results->Set(L"plugins", plugin_updater::GetPluginGroupsData());
dom_ui_->CallJavascriptFunction(L"returnPluginsData", *results);
@@ -193,7 +202,7 @@ void PluginsDOMHandler::HandleEnablePluginMessage(const Value* value) {
return;
plugin_updater::EnablePluginGroup(enable_str == "true",
- WideToUTF16(group_name));
+ WideToUTF16(group_name));
} else {
FilePath::StringType file_path;
if (!list->GetString(0, &file_path))
@@ -251,6 +260,7 @@ void PluginsUI::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory,
internal_dir);
+ prefs->RegisterListPref(prefs::kPluginsPluginsBlacklist);
prefs->RegisterListPref(prefs::kPluginsPluginsList);
prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF, false);
}
diff --git a/chrome/browser/plugin_updater.cc b/chrome/browser/plugin_updater.cc
index 288de87..4c884d7 100644
--- a/chrome/browser/plugin_updater.cc
+++ b/chrome/browser/plugin_updater.cc
@@ -80,11 +80,12 @@ void EnablePluginGroup(bool enable, const string16& group_name) {
}
}
-void EnablePluginFile(bool enable, const FilePath::StringType& file_path) {
- if (enable)
- NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(file_path));
+void EnablePluginFile(bool enable, const FilePath::StringType& path) {
+ FilePath file_path(path);
+ if (enable && !PluginGroup::IsPluginPathDisabledByPolicy(file_path))
+ NPAPI::PluginList::Singleton()->EnablePlugin(file_path);
else
- NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(file_path));
+ NPAPI::PluginList::Singleton()->DisablePlugin(file_path);
}
#if defined(OS_CHROMEOS)
@@ -166,6 +167,42 @@ void DisablePluginGroupsFromPrefs(Profile* profile) {
}
}
+ // Build the set of policy-disabled plugins once and cache it.
+ // Don't do this in the constructor, there's no profile available there.
+ std::set<string16> policy_disabled_plugins;
+ const ListValue* plugin_blacklist =
+ profile->GetPrefs()->GetList(prefs::kPluginsPluginsBlacklist);
+ if (plugin_blacklist) {
+ ListValue::const_iterator end(plugin_blacklist->end());
+ for (ListValue::const_iterator current(plugin_blacklist->begin());
+ current != end; ++current) {
+ string16 plugin_name;
+ if ((*current)->GetAsUTF16(&plugin_name)) {
+ policy_disabled_plugins.insert(plugin_name);
+ }
+ }
+ }
+ PluginGroup::SetPolicyDisabledPluginSet(policy_disabled_plugins);
+
+ // Disable all of the plugins and plugin groups that are disabled by policy.
+ std::vector<WebPluginInfo> plugins;
+ NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
+ for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
+ it != plugins.end();
+ ++it) {
+ if (PluginGroup::IsPluginNameDisabledByPolicy(it->name))
+ NPAPI::PluginList::Singleton()->DisablePlugin(it->path);
+ }
+
+ std::vector<linked_ptr<PluginGroup> > plugin_groups;
+ GetPluginGroups(&plugin_groups);
+ std::vector<linked_ptr<PluginGroup> >::const_iterator it;
+ for (it = plugin_groups.begin(); it != plugin_groups.end(); ++it) {
+ string16 current_group_name = (*it)->GetGroupName();
+ if (PluginGroup::IsPluginNameDisabledByPolicy(current_group_name))
+ EnablePluginGroup(false, current_group_name);
+ }
+
if (!enable_internal_pdf_ && !found_internal_pdf) {
// The internal PDF plugin is disabled by default, and the user hasn't
// overridden the default.
diff --git a/chrome/browser/plugin_updater.h b/chrome/browser/plugin_updater.h
index ba89b83..fd34b93 100644
--- a/chrome/browser/plugin_updater.h
+++ b/chrome/browser/plugin_updater.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_PLUGIN_UPDATER_H_
#define CHROME_BROWSER_PLUGIN_UPDATER_H_
+#include <set>
#include <vector>
#include "base/basictypes.h"
diff --git a/chrome/browser/resources/plugins.html b/chrome/browser/resources/plugins.html
index e8b14c5..dbaf7555 100644
--- a/chrome/browser/resources/plugins.html
+++ b/chrome/browser/resources/plugins.html
@@ -310,7 +310,7 @@ var pluginDataFormat = {
'fileExtensions': [ 'bar','baz' ],
'mimeType': 'application/my-bar' }
],
- 'enabled': true
+ 'enabledMode': 'enabled'
},
{
'path': '/foobar/baz/YourGreatPlugin.plugin',
@@ -322,7 +322,19 @@ var pluginDataFormat = {
'fileExtensions': [ 'baz' ],
'mimeType': 'application/x-your-baz' }
],
- 'enabled': false
+ 'enabledMode': 'disabledByUser'
+ },
+ {
+ 'path': '/foobiz/bar/HisGreatPlugin.plugin',
+ 'name': 'HisGreatPlugin',
+ 'version': '1.2',
+ 'description': 'His great plugin',
+ 'mimeTypes': [
+ { 'description': 'More baz Stuff',
+ 'fileExtensions': [ 'bor' ],
+ 'mimeType': 'application/x-his-bor' }
+ ],
+ 'enabledMode': 'disabledByPolicy'
}
]
}
@@ -506,7 +518,7 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<div class="plugin" jsselect="plugins">
<table width="100%" cellpadding="2" cellspacing="0">
<tr jsvalues=
- ".className:enabled ? 'plugin-enabled' : 'plugin-disabled'">
+ ".className:enabledMode == 'enabled' ? 'plugin-enabled' : 'plugin-disabled'">
<td valign="top">
<div class="plugin-text">
<div>
@@ -521,8 +533,10 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
</span>
<a jsdisplay="critical" jsvalues=".href:update_url"
i18n-content="pluginDownload">DOWNLOAD UPDATE</a>
- <span jsdisplay="!enabled"
+ <span jsdisplay="enabledMode == 'disabledByUser'"
i18n-content="pluginDisabled">(DISABLED)</span>
+ <span jsdisplay="enabledMode == 'disabledByPolicy'"
+ i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span>
<div jsdisplay="shouldDisplayPluginDescription($this)">
<span dir="ltr" jsvalues=".innerHTML:description">
</div>
@@ -530,17 +544,21 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<div jsselect="plugin_files" class="plugin-details">
<div class="showInTmiMode">
<div jsvalues=
- ".className:enabled ? 'plugin-file-enabled' : 'plugin-file-disabled'">
+ ".className:enabledMode == 'enabled' ? 'plugin-file-enabled' : 'plugin-file-disabled'">
<div><table><tr>
<td class="plugin-details-label"
i18n-content="pluginName">NAME:</td>
<td><span dir="ltr" jscontent="name">NAME</span></td>
</tr></table></div>
- <div><table><tr jsdisplay="shouldDisplayPluginDescription($this)">
- <td class="plugin-details-label"
- i18n-content="pluginDescription">DESCRIPTION:</td>
- <td><span dir="ltr" jsvalues=".innerHTML:description"></td>
- </tr></table></div>
+ <div><table>
+ <tr jsdisplay="shouldDisplayPluginDescription($this)">
+ <td class="plugin-details-label"
+ i18n-content="pluginDescription">DESCRIPTION:</td>
+ <td>
+ <span dir="ltr" jsvalues=".innerHTML:description">
+ </td>
+ </tr>
+ </table></div>
<div><table><tr>
<td class="plugin-details-label"
i18n-content="pluginVersion">VERSION:</td>
@@ -559,23 +577,30 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<div><table><tr>
<td class="plugin-details-label">&nbsp;</td>
<td>
- <span jsdisplay="!enabled"
+ <span jsdisplay="enabledMode == 'disabledByUser'"
i18n-content="pluginDisabled">(DISABLED)</span>
<span>
- <a
- jsvalues=".path:path"
- jsdisplay="enabled"
- onclick="handleEnablePlugin(this, false, false)"
- href="javascript:void(0);"
- i18n-content="disable"
- >DISABLE</a>
- <a
- jsvalues=".path:path"
- jsdisplay="!enabled"
- onclick="handleEnablePlugin(this, true, false)"
- href="javascript:void(0);"
- i18n-content="enable"
- >ENABLE</a>
+ <span jsdisplay="enabledMode == 'disabledByPolicy'"
+ i18n-content="pluginDisabled">(DISABLED_BY_POLICY)</span>
+ <span>
+ <a
+ jsvalues=".path:name"
+ jsdisplay="enabledMode == 'enabled'"
+ onclick="handleEnablePlugin(this, false, false)"
+ href="javascript:void(0);"
+ i18n-content="disable"
+ >DISABLE</a>
+ <a
+ jsvalues=".path:name"
+ jsdisplay="enabledMode == 'disabledByUser'"
+ onclick="handleEnablePlugin(this, true, false)"
+ href="javascript:void(0);"
+ i18n-content="enable"
+ >ENABLE</a>
+ <span
+ jsdisplay="enabledMode == 'disabledByPolicy'"
+ i18n-content="pluginCannotBeEnabledDueToPolicy"
+ >CANNOT_ENABLE</span>
</span>
</td>
</tr></table></div>
@@ -613,18 +638,22 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<span>
<a
jsvalues=".path:name"
- jsdisplay="enabled"
+ jsdisplay="enabledMode == 'enabled'"
onclick="handleEnablePlugin(this, false, true)"
href="javascript:void(0);"
i18n-content="disable"
>DISABLE</a>
<a
jsvalues=".path:name"
- jsdisplay="!enabled"
+ jsdisplay="enabledMode == 'disabledByUser'"
onclick="handleEnablePlugin(this, true, true)"
href="javascript:void(0);"
i18n-content="enable"
>ENABLE</a>
+ <span
+ jsdisplay="enabledMode == 'disabledByPolicy'"
+ i18n-content="pluginCannotBeEnabledDueToPolicy"
+ >CANNOT_ENABLE</span>
</span>
</div>
</td>
diff --git a/chrome/common/plugin_group.cc b/chrome/common/plugin_group.cc
index 984aebc..5df39b3 100644
--- a/chrome/common/plugin_group.cc
+++ b/chrome/common/plugin_group.cc
@@ -68,6 +68,9 @@ static const PluginGroupDefinition kGroupDefinitions[] = {};
#endif
/*static*/
+std::set<string16>* PluginGroup::policy_disabled_puglins_;
+
+/*static*/
const PluginGroupDefinition* PluginGroup::GetPluginGroupDefinitions() {
return kGroupDefinitions;
}
@@ -78,6 +81,36 @@ size_t PluginGroup::GetPluginGroupDefinitionsSize() {
return ARRAYSIZE_UNSAFE(kGroupDefinitions);
}
+/*static*/
+void PluginGroup::SetPolicyDisabledPluginSet(const std::set<string16>& set) {
+ if (!policy_disabled_puglins_) {
+ policy_disabled_puglins_ = new std::set<string16>();
+ *policy_disabled_puglins_ = set;
+ }
+}
+
+/*static*/
+bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
+ return policy_disabled_puglins_ &&
+ policy_disabled_puglins_->find(plugin_name) !=
+ policy_disabled_puglins_->end();
+}
+
+/*static*/
+bool PluginGroup::IsPluginPathDisabledByPolicy(const FilePath& plugin_path) {
+ std::vector<WebPluginInfo> plugins;
+ NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
+ for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
+ it != plugins.end();
+ ++it) {
+ if (FilePath::CompareEqualIgnoreCase(it->path.value(),
+ plugin_path.value()) && IsPluginNameDisabledByPolicy(it->name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
PluginGroup::PluginGroup(const string16& group_name,
const string16& name_matcher,
const std::string& version_range_low,
@@ -231,7 +264,14 @@ DictionaryValue* PluginGroup::GetDataForUI() const {
result->SetString(L"version", max_version_->GetString());
result->SetString(L"update_url", update_url_);
result->SetBoolean(L"critical", IsVulnerable());
- result->SetBoolean(L"enabled", enabled_);
+
+ bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
+ if (group_disabled_by_policy) {
+ result->SetString(L"enabledMode", L"disabledByPolicy");
+ } else {
+ result->SetString(L"enabledMode",
+ enabled_ ? L"enabled" : L"disabledByUser");
+ }
ListValue* plugin_files = new ListValue();
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
@@ -242,7 +282,14 @@ DictionaryValue* PluginGroup::GetDataForUI() const {
plugin_file->SetStringFromUTF16(L"description", web_plugin.desc);
plugin_file->SetString(L"path", web_plugin.path.value());
plugin_file->SetStringFromUTF16(L"version", web_plugin.version);
- plugin_file->SetBoolean(L"enabled", web_plugin.enabled);
+ bool plugin_disabled_by_policy = group_disabled_by_policy ||
+ IsPluginNameDisabledByPolicy(web_plugin.name);
+ if (plugin_disabled_by_policy) {
+ result->SetString(L"enabledMode", L"disabledByPolicy");
+ } else {
+ result->SetString(L"enabledMode",
+ web_plugin.enabled ? L"enabled" : L"disabledByUser");
+ }
plugin_file->SetInteger(L"priority", priority);
ListValue* mime_types = new ListValue();
@@ -286,10 +333,11 @@ void PluginGroup::Enable(bool enable) {
for (std::vector<WebPluginInfo>::const_iterator it =
web_plugin_infos_.begin();
it != web_plugin_infos_.end(); ++it) {
- if (enable) {
+ if (enable && !IsPluginNameDisabledByPolicy(it->name)) {
NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(it->path));
} else {
NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(it->path));
}
}
}
+
diff --git a/chrome/common/plugin_group.h b/chrome/common/plugin_group.h
index dba66ae..f9f6ce3 100644
--- a/chrome/common/plugin_group.h
+++ b/chrome/common/plugin_group.h
@@ -5,6 +5,7 @@
#ifndef CHROME_COMMON_PLUGIN_GROUP_H_
#define CHROME_COMMON_PLUGIN_GROUP_H_
+#include <set>
#include <vector>
#include "base/linked_ptr.h"
@@ -41,6 +42,17 @@ class PluginGroup {
// Find a plugin group matching |info| in the list of hardcoded plugins.
static PluginGroup* FindHardcodedPluginGroup(const WebPluginInfo& info);
+ // Configures the set of plugin names that are disabled by policy.
+ static void SetPolicyDisabledPluginSet(const std::set<string16>& set);
+
+ // Tests to see if a plugin is on the blacklist using its name as
+ // the lookup key.
+ static bool IsPluginNameDisabledByPolicy(const string16& plugin_name);
+
+ // Tests to see if a plugin is on the blacklist using its path as
+ // the lookup key.
+ static bool IsPluginPathDisabledByPolicy(const FilePath& plugin_path);
+
// Find the PluginGroup matching a Plugin in a list of plugin groups. Returns
// NULL if no matching PluginGroup is found.
static PluginGroup* FindGroupMatchingPlugin(
@@ -94,6 +106,8 @@ class PluginGroup {
const std::string& min_version,
const std::string& update_url);
+ static std::set<string16>* policy_disabled_puglins_;
+
string16 group_name_;
string16 name_matcher_;
std::string version_range_low_str_;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 424b011..b65a3da 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -413,6 +413,9 @@ const wchar_t kPluginsLastInternalDirectory[] =
// List pref containing information (dictionaries) on plugins.
const wchar_t kPluginsPluginsList[] = L"plugins.plugins_list";
+// List pref containing names of plugins that are disabled by policy.
+const wchar_t kPluginsPluginsBlacklist[] = L"plugins.plugins_blacklist";
+
// When first shipped, the pdf plugin will be disabled by default. When we
// enable it by default, we'll want to do so only once.
const wchar_t kPluginsEnabledInternalPDF[] = L"plugins.enabled_internal_pdf";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 4a00675..7dfc8ff 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -162,6 +162,7 @@ extern const wchar_t kExtensionsUIDeveloperMode[];
extern const wchar_t kExtensionToolbarSize[];
extern const wchar_t kPluginsLastInternalDirectory[];
extern const wchar_t kPluginsPluginsList[];
+extern const wchar_t kPluginsPluginsBlacklist[];
extern const wchar_t kPluginsEnabledInternalPDF[];
extern const wchar_t kCheckDefaultBrowser[];
#if defined(OS_MACOSX)