diff options
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); |