summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 13:28:58 +0000
committerpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 13:28:58 +0000
commit24ff43d70bfae58e5b7fe4c607fe255ca1c665dd (patch)
treea02df6c3e178747e8b79adceb2a8f3307c7d4155
parent3ce02419d4f7b3cd1fc062f87fb63a78072b5483 (diff)
downloadchromium_src-24ff43d70bfae58e5b7fe4c607fe255ca1c665dd.zip
chromium_src-24ff43d70bfae58e5b7fe4c607fe255ca1c665dd.tar.gz
chromium_src-24ff43d70bfae58e5b7fe4c607fe255ca1c665dd.tar.bz2
Added EnabledPlugins policy.
The EnabledPlugins policy is linked to the plugins.plugins_whitelist preference. Renamed some methods to clarify that policies can both disable and enable plugins. Updated plugins.html (about:plugins) to display policy-enabled plugins. Lots of tweaks in PluginGroup and PluginList (webkit/plugins/npapi) to preserve the user's preference across policy changes. Removing a policy on a plugin restores the state that the user had configured before. TODO: The interaction of "EnabledPlugins" and "DisabledPlugins" when overlapping isn't very well addressed yet. Currently, any plugin matching the "disabled" list will be disabled, regardless of matching or not the "enabled" list. Small fixes: Added missing "noPlugins" string to the jstemplate strings for plugins.html. BUG=55022 TEST=Create a policy enabling a specific plugin and check about:plugins. Also test_shell_test PluginGroupTest.ManagedByPolicy, and unit_tests. Review URL: http://codereview.chromium.org/6469068 Patch from Joao da Silva <joaodasilva@chromium.org>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76373 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd9
-rw-r--r--chrome/app/policy/policy_templates.json38
-rw-r--r--chrome/browser/browser_process_impl.cc12
-rw-r--r--chrome/browser/chromeos/login/login_utils.cc2
-rw-r--r--chrome/browser/plugin_updater.cc89
-rw-r--r--chrome/browser/plugin_updater.h17
-rw-r--r--chrome/browser/policy/config_dir_policy_provider_unittest.cc6
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store.cc9
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store_unittest.cc6
-rw-r--r--chrome/browser/policy/configuration_policy_provider_mac_unittest.cc6
-rw-r--r--chrome/browser/policy/configuration_policy_provider_win_unittest.cc6
-rw-r--r--chrome/browser/resources/plugins.html44
-rw-r--r--chrome/browser/ui/webui/plugins_ui.cc10
-rw-r--r--chrome/common/pref_names.cc9
-rw-r--r--chrome/common/pref_names.h4
-rw-r--r--content/browser/plugin_service.cc5
-rw-r--r--webkit/plugins/npapi/plugin_group.cc201
-rw-r--r--webkit/plugins/npapi/plugin_group.h33
-rw-r--r--webkit/plugins/npapi/plugin_group_unittest.cc109
19 files changed, 487 insertions, 128 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 8e4ada0..568ffb9 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3901,6 +3901,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY" desc="Text that indicates a plug-in cannot be enabled because it has been disabled by enterprise policy.">
Cannot enable plug-ins that are disabled by enterprise policy
</message>
+ <message name="IDS_PLUGINS_ENABLED_BY_POLICY_PLUGIN" desc="Text that signifies that the plug-in is currently enabled by enterprise policy.">
+ (Enabled by enterprise policy)
+ </message>
+ <message name="IDS_PLUGINS_CANNOT_DISABLE_DUE_TO_POLICY" desc="Text that indicates a plug-in cannot be disabled because it has been enabled by enterprise policy.">
+ Cannot disable plug-ins that are enabled by enterprise policy
+ </message>
<message name="IDS_PLUGINS_VERSION" desc="The label in front of a plug-in version number.">
Version:
</message>
@@ -3934,6 +3940,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_PLUGINS_NAME" desc="The label for the name of this plug-in">
Name:
</message>
+ <message name="IDS_PLUGINS_NO_PLUGINS" desc="Text that indicates that no plugins are installed">
+ No plugins are installed
+ </message>
<!-- about:flags -->
<message name="IDS_FLAGS_LONG_TITLE" desc="Long version of the title for the about:flags page.">
diff --git a/chrome/app/policy/policy_templates.json b/chrome/app/policy/policy_templates.json
index dc3dd27..809e2b0 100644
--- a/chrome/app/policy/policy_templates.json
+++ b/chrome/app/policy/policy_templates.json
@@ -91,7 +91,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: 77
+# For your editing convenience: highest ID currently used: 79
#
'policy_definitions': [
{
@@ -390,10 +390,44 @@
The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them.
- If you enable this setting, the specified list of plugins is never used in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. The plugins are marked as disabled in 'about:plugins' and users cannot enable them.''',
+ If you enable this setting, the specified list of plugins is never used in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. The plugins are marked as disabled in 'about:plugins' and users cannot enable them.
+
+ Note that this policy can be overriden by EnabledPlugins and DisabledPluginsExceptions.''',
'label': '''List of disabled plugins''',
},
{
+ 'name': 'EnabledPlugins',
+ 'type': 'list',
+ 'supported_on': ['chrome.*:11-'],
+ 'features': {'dynamic_refresh': 1},
+ 'example_value': ['Java', 'Shockwave Flash', 'Chrome PDF Viewer'],
+ 'id': 78,
+ 'caption': '''Specify a list of enabled plugins''',
+ 'desc': '''Specifies a list of plugins that are enabled in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting.
+
+ The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them.
+
+ The specified list of plugins is always used in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> if they are installed. The plugins are marked as enabled in 'about:plugins' and users cannot disable them.
+
+ Note that this policy overrides both DisabledPlugins and DisabledPluginsExceptions.''',
+ 'label': '''List of enabled plugins''',
+ },
+ {
+ 'name': 'DisabledPluginsExceptions',
+ 'type': 'list',
+ 'supported_on': ['chrome.*:11-'],
+ 'features': {'dynamic_refresh': 1},
+ 'example_value': ['Java', 'Shockwave Flash', 'Chrome PDF Viewer'],
+ 'id': 79,
+ 'caption': '''Specify a list of plugins that the user can enable or disable''',
+ 'desc': '''Specifies a list of plugins that user can enable or disable in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
+
+ The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them.
+
+ If you enable this setting, the specified list of plugins can be used in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. Users can enable or disable them in 'about:plugins', even if the plugin also matches a pattern in DisabledPlugins. Users can also enable and disable plugins that don't match any patterns in DisabledPlugins, DisabledPluginsExceptions and EnabledPlugins.''',
+ 'label': '''List of exceptions to the list of disabled plugins''',
+ },
+ {
'name': 'DisablePluginFinder',
'type': 'main',
'supported_on': ['chrome.*:11-'],
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 7579efc..3a76341 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -753,9 +753,15 @@ void BrowserProcessImpl::CreateLocalState() {
pref_change_registrar_.Init(local_state_.get());
// Make sure the the plugin updater gets notifications of changes
- // in the plugin blacklist.
- local_state_->RegisterListPref(prefs::kPluginsPluginsBlacklist);
- pref_change_registrar_.Add(prefs::kPluginsPluginsBlacklist,
+ // in the plugin policy lists.
+ local_state_->RegisterListPref(prefs::kPluginsDisabledPlugins);
+ pref_change_registrar_.Add(prefs::kPluginsDisabledPlugins,
+ PluginUpdater::GetInstance());
+ local_state_->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions);
+ pref_change_registrar_.Add(prefs::kPluginsDisabledPluginsExceptions,
+ PluginUpdater::GetInstance());
+ local_state_->RegisterListPref(prefs::kPluginsEnabledPlugins);
+ pref_change_registrar_.Add(prefs::kPluginsEnabledPlugins,
PluginUpdater::GetInstance());
// Initialize and set up notifications for the printing enabled
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 342cd5f..18652b7 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -319,7 +319,7 @@ void LoginUtilsImpl::CompleteLogin(
}
// Enable/disable plugins based on user preferences.
- PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile);
+ PluginUpdater::GetInstance()->UpdatePluginGroupsStateFromPrefs(profile);
btl->AddLoginTimeMarker("PluginsStateUpdated", false);
// We suck. This is a hack since we do not have the enterprise feature
diff --git a/chrome/browser/plugin_updater.cc b/chrome/browser/plugin_updater.cc
index 8ba253d..f86637b 100644
--- a/chrome/browser/plugin_updater.cc
+++ b/chrome/browser/plugin_updater.cc
@@ -4,7 +4,6 @@
#include "chrome/browser/plugin_updater.h"
-#include <set>
#include <string>
#include "base/message_loop.h"
@@ -79,35 +78,55 @@ void PluginUpdater::Observe(NotificationType type,
NOTREACHED();
return;
}
- if (*pref_name == prefs::kPluginsPluginsBlacklist) {
+ if (*pref_name == prefs::kPluginsDisabledPlugins ||
+ *pref_name == prefs::kPluginsDisabledPluginsExceptions ||
+ *pref_name == prefs::kPluginsEnabledPlugins) {
PrefService* pref_service = Source<PrefService>(source).ptr();
- const ListValue* list =
- pref_service->GetList(prefs::kPluginsPluginsBlacklist);
- DisablePluginsFromPolicy(list);
+ const ListValue* disabled_list =
+ pref_service->GetList(prefs::kPluginsDisabledPlugins);
+ const ListValue* exceptions_list =
+ pref_service->GetList(prefs::kPluginsDisabledPluginsExceptions);
+ const ListValue* enabled_list =
+ pref_service->GetList(prefs::kPluginsEnabledPlugins);
+ UpdatePluginsStateFromPolicy(disabled_list, exceptions_list, enabled_list);
}
}
-void PluginUpdater::DisablePluginsFromPolicy(const ListValue* plugin_names) {
- // Generate the set of unique disabled plugin patterns from the disabled
- // plugins list.
- std::set<string16> policy_disabled_plugin_patterns;
- if (plugin_names) {
- ListValue::const_iterator end(plugin_names->end());
- for (ListValue::const_iterator current(plugin_names->begin());
- current != end; ++current) {
- string16 plugin_name;
- if ((*current)->GetAsString(&plugin_name)) {
- policy_disabled_plugin_patterns.insert(plugin_name);
- }
- }
- }
- webkit::npapi::PluginGroup::SetPolicyDisabledPluginPatterns(
- policy_disabled_plugin_patterns);
+void PluginUpdater::UpdatePluginsStateFromPolicy(
+ const ListValue* disabled_list,
+ const ListValue* exceptions_list,
+ const ListValue* enabled_list) {
+ std::set<string16> disabled_plugin_patterns;
+ std::set<string16> disabled_plugin_exception_patterns;
+ std::set<string16> enabled_plugin_patterns;
+
+ ListValueToStringSet(disabled_list, &disabled_plugin_patterns);
+ ListValueToStringSet(exceptions_list, &disabled_plugin_exception_patterns);
+ ListValueToStringSet(enabled_list, &enabled_plugin_patterns);
+
+ webkit::npapi::PluginGroup::SetPolicyEnforcedPluginPatterns(
+ disabled_plugin_patterns,
+ disabled_plugin_exception_patterns,
+ enabled_plugin_patterns);
NotifyPluginStatusChanged();
}
-void PluginUpdater::DisablePluginGroupsFromPrefs(Profile* profile) {
+void PluginUpdater::ListValueToStringSet(const ListValue* src,
+ std::set<string16>* dest) {
+ DCHECK(src);
+ DCHECK(dest);
+ ListValue::const_iterator end(src->end());
+ for (ListValue::const_iterator current(src->begin());
+ current != end; ++current) {
+ string16 plugin_name;
+ if ((*current)->GetAsString(&plugin_name)) {
+ dest->insert(plugin_name);
+ }
+ }
+}
+
+void PluginUpdater::UpdatePluginGroupsStateFromPrefs(Profile* profile) {
bool update_internal_dir = false;
FilePath last_internal_dir =
profile->GetPrefs()->GetFilePath(prefs::kPluginsLastInternalDirectory);
@@ -187,11 +206,17 @@ void PluginUpdater::DisablePluginGroupsFromPrefs(Profile* profile) {
}
}
- // Build the set of policy-disabled plugin patterns once and cache it.
+ // Build the set of policy enabled/disabled plugin patterns once and cache it.
// Don't do this in the constructor, there's no profile available there.
- const ListValue* plugin_blacklist =
- profile->GetPrefs()->GetList(prefs::kPluginsPluginsBlacklist);
- DisablePluginsFromPolicy(plugin_blacklist);
+ const ListValue* disabled_plugins =
+ profile->GetPrefs()->GetList(prefs::kPluginsDisabledPlugins);
+ const ListValue* disabled_exception_plugins =
+ profile->GetPrefs()->GetList(prefs::kPluginsDisabledPluginsExceptions);
+ const ListValue* enabled_plugins =
+ profile->GetPrefs()->GetList(prefs::kPluginsEnabledPlugins);
+ UpdatePluginsStateFromPolicy(disabled_plugins,
+ disabled_exception_plugins,
+ enabled_plugins);
if (force_enable_internal_pdf || internal_pdf_enabled) {
// See http://crbug.com/50105 for background.
@@ -246,11 +271,13 @@ void PluginUpdater::OnUpdatePreferences(
// Add the plugin files.
for (size_t i = 0; i < plugins.size(); ++i) {
DictionaryValue* summary = CreatePluginFileSummary(plugins[i]);
- // If the plugin is disabled only by policy don't store this state in the
- // user pref store.
- if (plugins[i].enabled ==
- webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_DISABLED) {
- summary->SetBoolean("enabled", true);
+ // If the plugin is managed by policy, store the user preferred state
+ // instead.
+ if (plugins[i].enabled & webkit::npapi::WebPluginInfo::MANAGED_MASK) {
+ bool user_enabled =
+ (plugins[i].enabled & webkit::npapi::WebPluginInfo::USER_MASK) ==
+ webkit::npapi::WebPluginInfo::USER_ENABLED;
+ summary->SetBoolean("enabled", user_enabled);
}
bool enabled_val;
summary->GetBoolean("enabled", &enabled_val);
diff --git a/chrome/browser/plugin_updater.h b/chrome/browser/plugin_updater.h
index b30418e..c5583fa 100644
--- a/chrome/browser/plugin_updater.h
+++ b/chrome/browser/plugin_updater.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_PLUGIN_UPDATER_H_
#pragma once
+#include <set>
#include <vector>
#include "base/basictypes.h"
@@ -38,8 +39,8 @@ class PluginUpdater : public NotificationObserver {
// Enable or disable a specific plugin file.
void EnablePlugin(bool enable, const FilePath::StringType& file_path);
- // Disable all plugin groups as defined by the user's preference file.
- void DisablePluginGroupsFromPrefs(Profile* profile);
+ // Enable or disable plugin groups as defined by the user's preference file.
+ void UpdatePluginGroupsStateFromPrefs(Profile* profile);
// Write the enable/disable status to the user's preference file.
void UpdatePreferences(Profile* profile, int delay_ms);
@@ -75,9 +76,15 @@ class PluginUpdater : public NotificationObserver {
static DictionaryValue* CreatePluginFileSummary(
const webkit::npapi::WebPluginInfo& plugin);
- // Force plugins to be disabled due to policy. |plugins| contains
- // the list of StringValues of the names of the policy-disabled plugins.
- void DisablePluginsFromPolicy(const ListValue* plugin_names);
+ // Force plugins to be enabled or disabled due to policy.
+ // |disabled_list| contains the list of StringValues of the names of the
+ // policy-disabled plugins, |exceptions_list| the policy-allowed plugins,
+ // and |enabled_list| the policy-enabled plugins.
+ void UpdatePluginsStateFromPolicy(const ListValue* disabled_list,
+ const ListValue* exceptions_list,
+ const ListValue* enabled_list);
+
+ void ListValueToStringSet(const ListValue* src, std::set<string16>* dest);
// Needed to allow singleton instantiation using private constructor.
friend struct DefaultSingletonTraits<PluginUpdater>;
diff --git a/chrome/browser/policy/config_dir_policy_provider_unittest.cc b/chrome/browser/policy/config_dir_policy_provider_unittest.cc
index 9a31e55..7a7fba8 100644
--- a/chrome/browser/policy/config_dir_policy_provider_unittest.cc
+++ b/chrome/browser/policy/config_dir_policy_provider_unittest.cc
@@ -300,6 +300,12 @@ INSTANTIATE_TEST_CASE_P(
ValueTestParams::ForListPolicy(
kPolicyDisabledPlugins,
key::kDisabledPlugins),
+ ValueTestParams::ForListPolicy(
+ kPolicyDisabledPluginsExceptions,
+ key::kDisabledPluginsExceptions),
+ ValueTestParams::ForListPolicy(
+ kPolicyEnabledPlugins,
+ key::kEnabledPlugins),
ValueTestParams::ForBooleanPolicy(
kPolicyAutoFillEnabled,
key::kAutoFillEnabled),
diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc
index 1789bb7..e8b221a 100644
--- a/chrome/browser/policy/configuration_policy_pref_store.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store.cc
@@ -189,7 +189,11 @@ const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
{ Value::TYPE_LIST, kPolicyExtensionInstallForcelist,
prefs::kExtensionInstallForceList},
{ Value::TYPE_LIST, kPolicyDisabledPlugins,
- prefs::kPluginsPluginsBlacklist},
+ prefs::kPluginsDisabledPlugins},
+ { Value::TYPE_LIST, kPolicyDisabledPluginsExceptions,
+ prefs::kPluginsDisabledPluginsExceptions},
+ { Value::TYPE_LIST, kPolicyEnabledPlugins,
+ prefs::kPluginsEnabledPlugins},
{ Value::TYPE_BOOLEAN, kPolicyShowHomeButton,
prefs::kShowHomeButton },
{ Value::TYPE_BOOLEAN, kPolicyJavascriptEnabled,
@@ -887,6 +891,9 @@ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
key::kPasswordManagerAllowShowPasswords },
{ kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
{ kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
+ { kPolicyDisabledPluginsExceptions, Value::TYPE_LIST,
+ key::kDisabledPluginsExceptions },
+ { kPolicyEnabledPlugins, Value::TYPE_LIST, key::kEnabledPlugins },
{ kPolicyApplicationLocaleValue, Value::TYPE_STRING,
key::kApplicationLocaleValue },
{ kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
index a29922d..7495c4f 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
@@ -78,7 +78,11 @@ INSTANTIATE_TEST_CASE_P(
TypeAndName(kPolicyExtensionInstallBlacklist,
prefs::kExtensionInstallDenyList),
TypeAndName(kPolicyDisabledPlugins,
- prefs::kPluginsPluginsBlacklist)));
+ prefs::kPluginsDisabledPlugins),
+ TypeAndName(kPolicyDisabledPluginsExceptions,
+ prefs::kPluginsDisabledPluginsExceptions),
+ TypeAndName(kPolicyEnabledPlugins,
+ prefs::kPluginsEnabledPlugins)));
// Test cases for string-valued policy settings.
class ConfigurationPolicyPrefStoreStringTest
diff --git a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
index fae2597..fc15aa7 100644
--- a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
@@ -274,6 +274,12 @@ INSTANTIATE_TEST_CASE_P(
PolicyTestParams::ForListPolicy(
kPolicyDisabledPlugins,
key::kDisabledPlugins),
+ PolicyTestParams::ForListPolicy(
+ kPolicyDisabledPluginsExceptions,
+ key::kDisabledPluginsExceptions),
+ PolicyTestParams::ForListPolicy(
+ kPolicyEnabledPlugins,
+ key::kEnabledPlugins),
PolicyTestParams::ForBooleanPolicy(
kPolicyAutoFillEnabled,
key::kAutoFillEnabled),
diff --git a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
index b929e4a..9a30165 100644
--- a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
@@ -429,6 +429,12 @@ INSTANTIATE_TEST_CASE_P(
PolicyTestParams::ForListPolicy(
kPolicyDisabledPlugins,
key::kDisabledPlugins),
+ PolicyTestParams::ForListPolicy(
+ kPolicyDisabledPluginsExceptions,
+ key::kDisabledPluginsExceptions),
+ PolicyTestParams::ForListPolicy(
+ kPolicyEnabledPlugins,
+ key::kEnabledPlugins),
PolicyTestParams::ForBooleanPolicy(
kPolicyAutoFillEnabled,
key::kAutoFillEnabled),
diff --git a/chrome/browser/resources/plugins.html b/chrome/browser/resources/plugins.html
index 7434968..07d61f7 100644
--- a/chrome/browser/resources/plugins.html
+++ b/chrome/browser/resources/plugins.html
@@ -273,7 +273,19 @@ var pluginDataFormat = {
'fileExtensions': [ 'bar','baz' ],
'mimeType': 'application/my-bar' }
],
- 'enabledMode': 'enabled'
+ 'enabledMode': 'enabledByUser'
+ },
+ {
+ 'path': '/tmp/MyFirst.plugin',
+ 'name': 'MyFirstPlugin',
+ 'version': '3.14r15926',
+ 'description': 'My first plugin',
+ 'mimeTypes': [
+ { 'description': 'New Guy Media',
+ 'fileExtensions': [ 'mfp' ],
+ 'mimeType': 'application/x-my-first' }
+ ],
+ 'enabledMode': 'enabledByPolicy'
},
{
'path': '/foobar/baz/YourGreatPlugin.plugin',
@@ -438,6 +450,14 @@ function shouldDisplayPluginDescription(plugin) {
plugin.description != plugin.name + ' ' + plugin.version;
}
+/**
+ * Determines whether a plugin is enabled or not.
+ */
+function isPluginEnabled(plugin) {
+ return plugin.enabledMode == 'enabledByUser' ||
+ plugin.enabledMode == 'enabledByPolicy';
+}
+
// Unfortunately, we don't have notifications for plugin (list) status changes
// (yet), so in the meanwhile just update regularly.
setInterval(requestPluginsData, 30000);
@@ -494,7 +514,7 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<div class="plugin" jsselect="plugins">
<table width="100%" cellpadding="2" cellspacing="0">
<tr jsvalues=
- ".className:enabledMode == 'enabled' ? 'plugin-enabled' : 'plugin-disabled'">
+ ".className:isPluginEnabled($this) ? 'plugin-enabled' : 'plugin-disabled'">
<td valign="top">
<div class="plugin-text">
<div>
@@ -513,6 +533,8 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
i18n-content="pluginDisabled">(DISABLED)</span>
<span jsdisplay="enabledMode == 'disabledByPolicy'"
i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span>
+ <span jsdisplay="enabledMode == 'enabledByPolicy'"
+ i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span>
<div jsdisplay="shouldDisplayPluginDescription($this)">
<span dir="ltr" jsvalues=".innerHTML:description">
</div>
@@ -520,7 +542,7 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<div jsselect="plugin_files" class="plugin-details">
<div class="showInTmiMode">
<div jsvalues=
- ".className:enabledMode == 'enabled' ? 'plugin-file-enabled' : 'plugin-file-disabled'">
+ ".className:isPluginEnabled($this) ? 'plugin-file-enabled' : 'plugin-file-disabled'">
<div><table><tr>
<td class="plugin-details-label"
i18n-content="pluginName">NAME:</td>
@@ -551,11 +573,13 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<span jsdisplay="enabledMode == 'disabledByUser'"
i18n-content="pluginDisabled">(DISABLED)</span>
<span jsdisplay="enabledMode == 'disabledByPolicy'"
- i18n-content="pluginDisabled">(DISABLED_BY_POLICY)</span>
+ i18n-content="pluginDisabledByPolicy">(DISABLED_BY_POLICY)</span>
+ <span jsdisplay="enabledMode == 'enabledByPolicy'"
+ i18n-content="pluginEnabledByPolicy">(ENABLED_BY_POLICY)</span>
<span>
<a
jsvalues=".path:path"
- jsdisplay="enabledMode == 'enabled'"
+ jsdisplay="enabledMode == 'enabledByUser'"
onclick="handleEnablePlugin(this, false, false)"
href="javascript:void(0);"
i18n-content="disable"
@@ -568,6 +592,10 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
i18n-content="enable"
>ENABLE</a>
<span
+ jsdisplay="enabledMode == 'enabledByPolicy'"
+ i18n-content="pluginCannotBeDisabledDueToPolicy"
+ >CANNOT_DISABLE</span>
+ <span
jsdisplay="enabledMode == 'disabledByPolicy'"
i18n-content="pluginCannotBeEnabledDueToPolicy"
>CANNOT_ENABLE</span>
@@ -608,7 +636,7 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
<span>
<a
jsvalues=".path:name"
- jsdisplay="enabledMode == 'enabled'"
+ jsdisplay="enabledMode == 'enabledByUser'"
onclick="handleEnablePlugin(this, false, true)"
href="javascript:void(0);"
i18n-content="disable"
@@ -621,6 +649,10 @@ document.addEventListener('DOMContentLoaded', requestPluginsData);
i18n-content="enable"
>ENABLE</a>
<span
+ jsdisplay="enabledMode == 'enabledByPolicy'"
+ i18n-content="pluginCannotBeDisabledDueToPolicy"
+ >CANNOT_DISABLE</span>
+ <span
jsdisplay="enabledMode == 'disabledByPolicy'"
i18n-content="pluginCannotBeEnabledDueToPolicy"
>CANNOT_ENABLE</span>
diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc
index 76346e4..f5ed6b7 100644
--- a/chrome/browser/ui/webui/plugins_ui.cc
+++ b/chrome/browser/ui/webui/plugins_ui.cc
@@ -80,6 +80,10 @@ void PluginsUIHTMLSource::StartDataRequest(const std::string& path,
l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_BY_POLICY_PLUGIN));
localized_strings.SetString("pluginCannotBeEnabledDueToPolicy",
l10n_util::GetStringUTF16(IDS_PLUGINS_CANNOT_ENABLE_DUE_TO_POLICY));
+ localized_strings.SetString("pluginEnabledByPolicy",
+ l10n_util::GetStringUTF16(IDS_PLUGINS_ENABLED_BY_POLICY_PLUGIN));
+ localized_strings.SetString("pluginCannotBeDisabledDueToPolicy",
+ l10n_util::GetStringUTF16(IDS_PLUGINS_CANNOT_DISABLE_DUE_TO_POLICY));
localized_strings.SetString("pluginDownload",
l10n_util::GetStringUTF16(IDS_PLUGINS_DOWNLOAD));
localized_strings.SetString("pluginName",
@@ -102,6 +106,8 @@ void PluginsUIHTMLSource::StartDataRequest(const std::string& path,
l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLE));
localized_strings.SetString("enable",
l10n_util::GetStringUTF16(IDS_PLUGINS_ENABLE));
+ localized_strings.SetString("noPlugins",
+ l10n_util::GetStringUTF16(IDS_PLUGINS_NO_PLUGINS));
ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
@@ -366,7 +372,9 @@ void PluginsUI::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory,
internal_dir);
- prefs->RegisterListPref(prefs::kPluginsPluginsBlacklist);
+ prefs->RegisterListPref(prefs::kPluginsDisabledPlugins);
+ prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions);
+ prefs->RegisterListPref(prefs::kPluginsEnabledPlugins);
prefs->RegisterListPref(prefs::kPluginsPluginsList);
prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF, false);
prefs->RegisterBooleanPref(prefs::kPluginsShowDetails, false);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 23b035f..21c61b2 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -562,7 +562,14 @@ const char kPluginsLastInternalDirectory[] = "plugins.last_internal_directory";
const char kPluginsPluginsList[] = "plugins.plugins_list";
// List pref containing names of plugins that are disabled by policy.
-const char kPluginsPluginsBlacklist[] = "plugins.plugins_blacklist";
+const char kPluginsDisabledPlugins[] = "plugins.plugins_disabled";
+
+// List pref containing exceptions to the list of plugins disabled by policy.
+const char kPluginsDisabledPluginsExceptions[] =
+ "plugins.plugins_disabled_exceptions";
+
+// List pref containing names of plugins that are enabled by policy.
+const char kPluginsEnabledPlugins[] = "plugins.plugins_enabled";
// 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.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 9372456..6f7f2d6 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -204,7 +204,9 @@ extern const char kExtensionsUIDeveloperMode[];
extern const char kExtensionToolbarSize[];
extern const char kPluginsLastInternalDirectory[];
extern const char kPluginsPluginsList[];
-extern const char kPluginsPluginsBlacklist[];
+extern const char kPluginsDisabledPlugins[];
+extern const char kPluginsDisabledPluginsExceptions[];
+extern const char kPluginsEnabledPlugins[];
extern const char kPluginsEnabledInternalPDF[];
extern const char kPluginsShowSetReaderDefaultInfobar[];
extern const char kPluginsShowDetails[];
diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
index f7ca16e..76a2b1c 100644
--- a/content/browser/plugin_service.cc
+++ b/content/browser/plugin_service.cc
@@ -84,8 +84,9 @@ bool PluginService::enable_chrome_plugins_ = true;
void PluginService::InitGlobalInstance(Profile* profile) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // We first group the plugins and then figure out which groups to disable.
- PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile);
+ // We first group the plugins and then figure out which groups to
+ // enable or disable.
+ PluginUpdater::GetInstance()->UpdatePluginGroupsStateFromPrefs(profile);
// Have Chrome plugins write their data to the profile directory.
GetInstance()->SetChromePluginDataDir(profile->GetPath());
diff --git a/webkit/plugins/npapi/plugin_group.cc b/webkit/plugins/npapi/plugin_group.cc
index fc5a4c1..4b61baa 100644
--- a/webkit/plugins/npapi/plugin_group.cc
+++ b/webkit/plugins/npapi/plugin_group.cc
@@ -26,25 +26,42 @@ const char* PluginGroup::kShockwaveGroupName = "Shockwave";
/*static*/
std::set<string16>* PluginGroup::policy_disabled_plugin_patterns_;
+/*static*/
+std::set<string16>* PluginGroup::policy_disabled_plugin_exception_patterns_;
+/*static*/
+std::set<string16>* PluginGroup::policy_enabled_plugin_patterns_;
/*static*/
-void PluginGroup::SetPolicyDisabledPluginPatterns(
- const std::set<string16>& set) {
+void PluginGroup::SetPolicyEnforcedPluginPatterns(
+ const std::set<string16>& plugins_disabled,
+ const std::set<string16>& plugins_disabled_exceptions,
+ const std::set<string16>& plugins_enabled) {
if (!policy_disabled_plugin_patterns_)
- policy_disabled_plugin_patterns_ = new std::set<string16>(set);
+ policy_disabled_plugin_patterns_ = new std::set<string16>(plugins_disabled);
+ else
+ *policy_disabled_plugin_patterns_ = plugins_disabled;
+
+ if (!policy_disabled_plugin_exception_patterns_)
+ policy_disabled_plugin_exception_patterns_ =
+ new std::set<string16>(plugins_disabled_exceptions);
+ else
+ *policy_disabled_plugin_exception_patterns_ = plugins_disabled_exceptions;
+
+ if (!policy_enabled_plugin_patterns_)
+ policy_enabled_plugin_patterns_ = new std::set<string16>(plugins_enabled);
else
- *policy_disabled_plugin_patterns_ = set;
+ *policy_enabled_plugin_patterns_ = plugins_enabled;
}
/*static*/
-bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
- if (!policy_disabled_plugin_patterns_)
+bool PluginGroup::IsStringMatchedInSet(const string16& name,
+ const std::set<string16>* pattern_set) {
+ if (!pattern_set)
return false;
- std::set<string16>::const_iterator pattern(
- policy_disabled_plugin_patterns_->begin());
- while (pattern != policy_disabled_plugin_patterns_->end()) {
- if (MatchPattern(plugin_name, *pattern))
+ std::set<string16>::const_iterator pattern(pattern_set->begin());
+ while (pattern != pattern_set->end()) {
+ if (MatchPattern(name, *pattern))
return true;
++pattern;
}
@@ -52,6 +69,38 @@ bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
return false;
}
+/*static*/
+bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
+ // A plugin that matches some "disabled" pattern but also matches an "enabled"
+ // pattern will be enabled. Example: disable "*", enable "Flash, Java".
+ // Same for matching an "exception" pattern.
+ return IsStringMatchedInSet(plugin_name, policy_disabled_plugin_patterns_) &&
+ !IsStringMatchedInSet(plugin_name, policy_enabled_plugin_patterns_) &&
+ !IsStringMatchedInSet(plugin_name,
+ policy_disabled_plugin_exception_patterns_);
+}
+
+/*static*/
+bool PluginGroup::IsPluginFileNameDisabledByPolicy(const string16& plugin_name,
+ const string16& group_name) {
+ // This handles a specific plugin within a group that is allowed,
+ // but whose name matches a disabled pattern.
+ // Example: disable "*", exception "Java".
+ bool group_has_exception = IsStringMatchedInSet(
+ group_name,
+ policy_disabled_plugin_exception_patterns_);
+
+ return !IsPluginNameEnabledByPolicy(plugin_name) &&
+ !group_has_exception &&
+ IsPluginNameDisabledByPolicy(plugin_name);
+}
+
+/*static*/
+bool PluginGroup::IsPluginNameEnabledByPolicy(const string16& plugin_name) {
+ // There are no exceptions to enabled plugins.
+ return IsStringMatchedInSet(plugin_name, policy_enabled_plugin_patterns_);
+}
+
VersionRange::VersionRange(VersionRangeDefinition definition)
: low_str(definition.version_matcher_low),
high_str(definition.version_matcher_high),
@@ -262,8 +311,13 @@ bool PluginGroup::EnablePlugin(const FilePath& filename) {
bool did_enable = false;
ResetGroupState();
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
- if (web_plugin_infos_[i].path == filename)
- did_enable = Enable(&web_plugin_infos_[i], WebPluginInfo::USER_ENABLED);
+ if (web_plugin_infos_[i].path == filename) {
+ did_enable = Enable(
+ &web_plugin_infos_[i],
+ IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name) ?
+ WebPluginInfo::USER_ENABLED_POLICY_ENABLED :
+ WebPluginInfo::USER_ENABLED);
+ }
UpdateActivePlugin(web_plugin_infos_[i]);
}
return did_enable;
@@ -326,23 +380,35 @@ DictionaryValue* PluginGroup::GetDataForUI() const {
result->SetBoolean("critical", IsVulnerable());
bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(name);
+ bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(name);
ListValue* plugin_files = new ListValue();
bool all_plugins_disabled_by_policy = true;
+ bool all_plugins_enabled_by_policy = true;
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
DictionaryValue* plugin_file = new DictionaryValue();
plugin_file->SetString("name", web_plugin_infos_[i].name);
plugin_file->SetString("description", web_plugin_infos_[i].desc);
plugin_file->SetString("path", web_plugin_infos_[i].path.value());
plugin_file->SetString("version", web_plugin_infos_[i].version);
+
bool plugin_disabled_by_policy = group_disabled_by_policy ||
((web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_DISABLED) != 0);
+ bool plugin_enabled_by_policy = group_enabled_by_policy ||
+ ((web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_ENABLED) != 0);
+
+ if (!plugin_disabled_by_policy)
+ all_plugins_disabled_by_policy = false;
+ if (!plugin_enabled_by_policy)
+ all_plugins_enabled_by_policy = false;
+
if (plugin_disabled_by_policy) {
plugin_file->SetString("enabledMode", "disabledByPolicy");
+ } else if (plugin_enabled_by_policy) {
+ plugin_file->SetString("enabledMode", "enabledByPolicy");
} else {
- all_plugins_disabled_by_policy = false;
plugin_file->SetString(
"enabledMode", IsPluginEnabled(web_plugin_infos_[i]) ?
- "enabled" : "disabledByUser");
+ "enabledByUser" : "disabledByUser");
}
ListValue* mime_types = new ListValue();
@@ -369,8 +435,12 @@ DictionaryValue* PluginGroup::GetDataForUI() const {
if (group_disabled_by_policy || all_plugins_disabled_by_policy) {
result->SetString("enabledMode", "disabledByPolicy");
+ } else if (group_enabled_by_policy || all_plugins_enabled_by_policy) {
+ result->SetString("enabledMode", "enabledByPolicy");
} else {
- result->SetString("enabledMode", enabled_ ? "enabled" : "disabledByUser");
+ result->SetString("enabledMode", enabled_ ?
+ "enabledByUser" :
+ "disabledByUser");
}
result->Set("plugin_files", plugin_files);
@@ -440,21 +510,28 @@ void PluginGroup::DisableOutdatedPlugins() {
bool PluginGroup::EnableGroup(bool enable) {
bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
- // We can't enable groups disabled by policy
- if (group_disabled_by_policy && enable)
+ bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(group_name_);
+
+ // We can't enable nor disable groups controlled by policy.
+ if ((group_disabled_by_policy && enable) ||
+ (group_enabled_by_policy && !enable))
return false;
ResetGroupState();
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ bool policy_enabled =
+ IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name);
bool policy_disabled =
- IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name);
- if (enable && !policy_disabled) {
+ IsPluginFileNameDisabledByPolicy(web_plugin_infos_[i].name,
+ group_name_);
+ if (policy_disabled) {
+ Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_DISABLED);
+ } else if (policy_enabled) {
+ Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_ENABLED);
+ } else if (enable) {
Enable(&web_plugin_infos_[i], WebPluginInfo::USER_ENABLED);
} else {
- Disable(&web_plugin_infos_[i],
- policy_disabled || group_disabled_by_policy ?
- WebPluginInfo::POLICY_DISABLED :
- WebPluginInfo::USER_DISABLED);
+ Disable(&web_plugin_infos_[i], WebPluginInfo::USER_DISABLED);
}
UpdateActivePlugin(web_plugin_infos_[i]);
}
@@ -463,19 +540,30 @@ bool PluginGroup::EnableGroup(bool enable) {
void PluginGroup::EnforceGroupPolicy() {
bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
+ bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(group_name_);
ResetGroupState();
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ bool policy_enabled =
+ group_enabled_by_policy ||
+ IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name);
bool policy_disabled =
- IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name) |
- group_disabled_by_policy;
-
- // TODO(pastarmovj): Add the code for enforcing enabled by policy...
+ !policy_enabled &&
+ (group_disabled_by_policy ||
+ IsPluginFileNameDisabledByPolicy(web_plugin_infos_[i].name,
+ group_name_));
if (policy_disabled) {
Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_DISABLED);
- // ...here would a else if (policy_enabled) { ... } be then.
+ } else if (policy_enabled) {
+ Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_ENABLED);
} else {
- Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED);
+ // If not managed, use the user's preference.
+ if ((web_plugin_infos_[i].enabled & WebPluginInfo::USER_MASK) ==
+ WebPluginInfo::USER_ENABLED) {
+ Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED);
+ } else {
+ Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED);
+ }
}
UpdateActivePlugin(web_plugin_infos_[i]);
}
@@ -487,45 +575,46 @@ void PluginGroup::ResetGroupState() {
version_.reset(Version::GetVersionFromString("0"));
}
-bool PluginGroup::Enable(WebPluginInfo* plugin,
- int new_reason) {
- DCHECK(new_reason == WebPluginInfo::USER_ENABLED ||
- new_reason == WebPluginInfo::POLICY_UNMANAGED ||
- new_reason == WebPluginInfo::POLICY_ENABLED);
+/*static*/
+bool PluginGroup::SetPluginState(WebPluginInfo* plugin,
+ int new_reason,
+ bool state_changes) {
// If we are only stripping the policy then mask the policy bits.
if (new_reason == WebPluginInfo::POLICY_UNMANAGED) {
plugin->enabled &= WebPluginInfo::USER_MASK;
return true;
}
- // If already enabled just upgrade the reason.
- if (IsPluginEnabled(*plugin)) {
- plugin->enabled |= new_reason;
- return true;
+ if (new_reason & WebPluginInfo::MANAGED_MASK) {
+ // Policy-enforced change: preserve the user's preference, and override
+ // a possible previous policy flag.
+ plugin->enabled = (plugin->enabled & WebPluginInfo::USER_MASK) | new_reason;
+ } else if (state_changes && (plugin->enabled & WebPluginInfo::MANAGED_MASK)) {
+ // Refuse change when managed.
+ return false;
} else {
- // Only changeable if not managed.
- if (plugin->enabled & WebPluginInfo::MANAGED_MASK)
- return false;
- plugin->enabled = new_reason;
+ // Accept the user update, but keep the policy flag if present.
+ plugin->enabled = (plugin->enabled & WebPluginInfo::MANAGED_MASK) |
+ new_reason;
}
return true;
}
-bool PluginGroup::Disable(WebPluginInfo* plugin,
- int new_reason) {
+/*static*/
+bool PluginGroup::Enable(WebPluginInfo* plugin, int new_reason) {
+ DCHECK(new_reason == WebPluginInfo::USER_ENABLED ||
+ new_reason == WebPluginInfo::POLICY_ENABLED ||
+ new_reason == WebPluginInfo::USER_ENABLED_POLICY_ENABLED ||
+ new_reason == WebPluginInfo::POLICY_UNMANAGED);
+ return SetPluginState(plugin, new_reason, !IsPluginEnabled(*plugin));
+}
+
+/*static*/
+bool PluginGroup::Disable(WebPluginInfo* plugin, int new_reason) {
DCHECK(new_reason == WebPluginInfo::USER_DISABLED ||
new_reason == WebPluginInfo::POLICY_DISABLED ||
- new_reason == WebPluginInfo::USER_DISABLED_POLICY_DISABLED);
- // If already disabled just upgrade the reason.
- if (!IsPluginEnabled(*plugin)) {
- plugin->enabled |= new_reason;
- return true;
- } else {
- // Only changeable if not managed.
- if (plugin->enabled & WebPluginInfo::MANAGED_MASK)
- return false;
- plugin->enabled = new_reason;
- }
- return true;
+ new_reason == WebPluginInfo::USER_DISABLED_POLICY_DISABLED ||
+ new_reason == WebPluginInfo::POLICY_UNMANAGED);
+ return SetPluginState(plugin, new_reason, IsPluginEnabled(*plugin));
}
} // namespace npapi
diff --git a/webkit/plugins/npapi/plugin_group.h b/webkit/plugins/npapi/plugin_group.h
index 9e0250c..39d9cd1 100644
--- a/webkit/plugins/npapi/plugin_group.h
+++ b/webkit/plugins/npapi/plugin_group.h
@@ -94,14 +94,24 @@ class PluginGroup {
PluginGroup& operator=(const PluginGroup& other);
- // Configures the set of plugin name patterns for disabling plugins via
- // enterprise configuration management.
- static void SetPolicyDisabledPluginPatterns(const std::set<string16>& set);
-
- // Tests to see if a plugin is on the blacklist using its name as
- // the lookup key.
+ // Configures the set of plugin name patterns for enabling and disabling
+ // plugins via enterprise configuration management.
+ static void SetPolicyEnforcedPluginPatterns(
+ const std::set<string16>& plugins_disabled,
+ const std::set<string16>& plugins_disabled_exceptions,
+ const std::set<string16>& plugins_enabled);
+
+ // Tests whether |plugin_name| is disabled by policy.
static bool IsPluginNameDisabledByPolicy(const string16& plugin_name);
+ // Tests whether |plugin_name| within the plugin group |group_name| is
+ // disabled by policy.
+ static bool IsPluginFileNameDisabledByPolicy(const string16& plugin_name,
+ const string16& group_name);
+
+ // Tests whether |plugin_name| is enabled by policy.
+ static bool IsPluginNameEnabledByPolicy(const string16& plugin_name);
+
// Returns true if the given plugin matches this group.
bool Match(const WebPluginInfo& plugin) const;
@@ -245,13 +255,24 @@ class PluginGroup {
// Returns true on success. Does not update the group state.
static bool Disable(WebPluginInfo* plugin, int reason);
+ // Helper function to implement the functions above.
+ static bool SetPluginState(WebPluginInfo* plugin,
+ int new_reason,
+ bool state_changes);
+
// Returns a non-const vector of all plugins in the group. This is only used
// by PluginList.
std::vector<WebPluginInfo>& GetPluginsContainer() {
return web_plugin_infos_;
}
+ // Checks if |name| matches any of the patterns in |pattern_set|.
+ static bool IsStringMatchedInSet(const string16& name,
+ const std::set<string16>* pattern_set);
+
static std::set<string16>* policy_disabled_plugin_patterns_;
+ static std::set<string16>* policy_disabled_plugin_exception_patterns_;
+ static std::set<string16>* policy_enabled_plugin_patterns_;
std::string identifier_;
string16 group_name_;
diff --git a/webkit/plugins/npapi/plugin_group_unittest.cc b/webkit/plugins/npapi/plugin_group_unittest.cc
index 476655f..960d470 100644
--- a/webkit/plugins/npapi/plugin_group_unittest.cc
+++ b/webkit/plugins/npapi/plugin_group_unittest.cc
@@ -89,11 +89,13 @@ class PluginGroupTest : public testing::Test {
}
protected:
virtual void TearDown() {
- PluginGroup::SetPolicyDisabledPluginPatterns(std::set<string16>());
+ PluginGroup::SetPolicyEnforcedPluginPatterns(std::set<string16>(),
+ std::set<string16>(),
+ std::set<string16>());
}
};
-TEST(PluginGroupTest, PluginGroupMatch) {
+TEST_F(PluginGroupTest, PluginGroupMatch) {
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
kPluginDef3));
EXPECT_TRUE(group->Match(kPlugin3045));
@@ -106,7 +108,7 @@ TEST(PluginGroupTest, PluginGroupMatch) {
EXPECT_FALSE(group->Match(kPluginNoVersion));
}
-TEST(PluginGroupTest, PluginGroupMatchCorrectVersion) {
+TEST_F(PluginGroupTest, PluginGroupMatchCorrectVersion) {
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
kPluginDef3));
EXPECT_TRUE(group->Match(kPlugin2043));
@@ -124,7 +126,7 @@ TEST(PluginGroupTest, PluginGroupMatchCorrectVersion) {
EXPECT_TRUE(group->Match(kPlugin4043));
}
-TEST(PluginGroupTest, PluginGroupDescription) {
+TEST_F(PluginGroupTest, PluginGroupDescription) {
string16 desc3043(ASCIIToUTF16("MyPlugin version 3.0.43"));
string16 desc3045(ASCIIToUTF16("MyPlugin version 3.0.45"));
@@ -163,7 +165,7 @@ TEST(PluginGroupTest, PluginGroupDescription) {
}
}
-TEST(PluginGroupTest, PluginGroupDefinition) {
+TEST_F(PluginGroupTest, PluginGroupDefinition) {
for (size_t i = 0; i < arraysize(kPluginDefinitions); ++i) {
scoped_ptr<PluginGroup> def_group(
PluginGroupTest::CreatePluginGroup(kPluginDefinitions[i]));
@@ -171,7 +173,7 @@ TEST(PluginGroupTest, PluginGroupDefinition) {
}
}
-TEST(PluginGroupTest, DisableOutdated) {
+TEST_F(PluginGroupTest, DisableOutdated) {
PluginGroupDefinition plugindefs[] = { kPluginDef3, kPluginDef34 };
for (size_t i = 0; i < 2; ++i) {
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
@@ -188,7 +190,7 @@ TEST(PluginGroupTest, DisableOutdated) {
}
}
-TEST(PluginGroupTest, VersionExtraction) {
+TEST_F(PluginGroupTest, VersionExtraction) {
// Some real-world plugin versions (spaces, commata, parentheses, 'r', oh my)
const char* versions[][2] = {
{ "7.6.6 (1671)", "7.6.6.1671" }, // Quicktime
@@ -216,11 +218,13 @@ TEST(PluginGroupTest, VersionExtraction) {
}
}
-TEST(PluginGroupTest, DisabledByPolicy) {
+TEST_F(PluginGroupTest, DisabledByPolicy) {
std::set<string16> disabled_plugins;
disabled_plugins.insert(ASCIIToUTF16("Disable this!"));
disabled_plugins.insert(ASCIIToUTF16("*Google*"));
- PluginGroup::SetPolicyDisabledPluginPatterns(disabled_plugins);
+ PluginGroup::SetPolicyEnforcedPluginPatterns(disabled_plugins,
+ std::set<string16>(),
+ std::set<string16>());
EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(ASCIIToUTF16("42")));
EXPECT_TRUE(PluginGroup::IsPluginNameDisabledByPolicy(
@@ -229,7 +233,90 @@ TEST(PluginGroupTest, DisabledByPolicy) {
ASCIIToUTF16("Google Earth")));
}
-TEST(PluginGroupTest, IsVulnerable) {
+TEST_F(PluginGroupTest, EnabledByPolicy) {
+ std::set<string16> enabled_plugins;
+ enabled_plugins.insert(ASCIIToUTF16("Enable that!"));
+ enabled_plugins.insert(ASCIIToUTF16("PDF*"));
+ PluginGroup::SetPolicyEnforcedPluginPatterns(std::set<string16>(),
+ std::set<string16>(),
+ enabled_plugins);
+
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(ASCIIToUTF16("42")));
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(
+ ASCIIToUTF16("Enable that!")));
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(
+ ASCIIToUTF16("PDF Reader")));
+}
+
+TEST_F(PluginGroupTest, EnabledAndDisabledByPolicy) {
+ const string16 k42(ASCIIToUTF16("42"));
+ const string16 kEnabled(ASCIIToUTF16("Enabled"));
+ const string16 kEnabled2(ASCIIToUTF16("Enabled 2"));
+ const string16 kEnabled3(ASCIIToUTF16("Enabled 3"));
+ const string16 kException(ASCIIToUTF16("Exception"));
+ const string16 kException2(ASCIIToUTF16("Exception 2"));
+ const string16 kGoogleMars(ASCIIToUTF16("Google Mars"));
+ const string16 kGoogleEarth(ASCIIToUTF16("Google Earth"));
+
+ std::set<string16> disabled_plugins;
+ std::set<string16> disabled_plugins_exceptions;
+ std::set<string16> enabled_plugins;
+
+ disabled_plugins.insert(kEnabled);
+ disabled_plugins_exceptions.insert(kEnabled);
+ enabled_plugins.insert(kEnabled);
+
+ disabled_plugins_exceptions.insert(kException);
+
+ disabled_plugins.insert(kEnabled2);
+ enabled_plugins.insert(kEnabled2);
+
+ disabled_plugins.insert(kException2);
+ disabled_plugins_exceptions.insert(kException2);
+
+ disabled_plugins_exceptions.insert(kEnabled3);
+ enabled_plugins.insert(kEnabled3);
+
+ PluginGroup::SetPolicyEnforcedPluginPatterns(disabled_plugins,
+ disabled_plugins_exceptions,
+ enabled_plugins);
+
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(k42));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(k42));
+
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(kEnabled));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kEnabled));
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(kEnabled2));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kEnabled2));
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(kEnabled3));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kEnabled3));
+
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(kException));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kException));
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(kException2));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kException2));
+
+ disabled_plugins.clear();
+ disabled_plugins_exceptions.clear();
+ enabled_plugins.clear();
+
+ disabled_plugins.insert(ASCIIToUTF16("*"));
+ disabled_plugins_exceptions.insert(ASCIIToUTF16("*Google*"));
+ enabled_plugins.insert(kGoogleEarth);
+
+ PluginGroup::SetPolicyEnforcedPluginPatterns(disabled_plugins,
+ disabled_plugins_exceptions,
+ enabled_plugins);
+
+ EXPECT_TRUE(PluginGroup::IsPluginNameEnabledByPolicy(kGoogleEarth));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kGoogleEarth));
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(kGoogleMars));
+ EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(kGoogleMars));
+ EXPECT_FALSE(PluginGroup::IsPluginNameEnabledByPolicy(k42));
+ EXPECT_TRUE(PluginGroup::IsPluginNameDisabledByPolicy(k42));
+}
+
+TEST_F(PluginGroupTest, IsVulnerable) {
// Adobe Reader 10
VersionRangeDefinition adobe_reader_version_range[] = {
{ "10", "11", "", false },
@@ -270,7 +357,7 @@ TEST(PluginGroupTest, IsVulnerable) {
EXPECT_TRUE(PluginGroup(*group).RequiresAuthorization());
}
-TEST(PluginGroupTest, MultipleVersions) {
+TEST_F(PluginGroupTest, MultipleVersions) {
scoped_ptr<PluginGroup> group(
PluginGroupTest::CreatePluginGroup(kPluginDef3));
group->AddPlugin(kPlugin3044);