Enable/disable extensions upon changes in blacklist.
BUG=267514
Review URL: https://codereview.chromium.org/98463005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247263 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 91d83b5..0a999e4 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -565,12 +565,28 @@
}
system_->management_policy()->RegisterProvider(
shared_module_policy_provider_.get());
+
+ LoadGreylistFromPrefs();
}
UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime",
base::Time::Now() - begin_time);
}
+void ExtensionService::LoadGreylistFromPrefs() {
+ scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet();
+
+ for (ExtensionSet::const_iterator it = all_extensions->begin();
+ it != all_extensions->end(); ++it) {
+ extensions::BlacklistState state =
+ extension_prefs_->GetExtensionBlacklistState((*it)->id());
+ if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY ||
+ state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED ||
+ state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION)
+ greylist_.Insert(*it);
+ }
+}
+
void ExtensionService::VerifyAllExtensions() {
ExtensionIdSet to_add;
scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet();
@@ -2723,27 +2739,75 @@
}
void ExtensionService::OnBlacklistUpdated() {
- blacklist_->GetMalwareIDs(
+ blacklist_->GetBlacklistedIDs(
GenerateInstalledExtensionsSet()->GetIDs(),
base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr()));
}
-void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) {
+void ExtensionService::ManageBlacklist(
+ const extensions::Blacklist::BlacklistStateMap& state_map) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::set<std::string> before = registry_->blacklisted_extensions().GetIDs();
- std::set<std::string> no_longer_blacklisted =
- base::STLSetDifference<std::set<std::string> >(before, updated);
- std::set<std::string> not_yet_blacklisted =
- base::STLSetDifference<std::set<std::string> >(updated, before);
+ std::set<std::string> blocked;
+ ExtensionIdSet greylist;
+ ExtensionIdSet unchanged;
+ for (extensions::Blacklist::BlacklistStateMap::const_iterator it =
+ state_map.begin();
+ it != state_map.end();
+ ++it) {
+ switch (it->second) {
+ case extensions::NOT_BLACKLISTED:
+ break;
- for (std::set<std::string>::iterator it = no_longer_blacklisted.begin();
- it != no_longer_blacklisted.end(); ++it) {
+ case extensions::BLACKLISTED_MALWARE:
+ blocked.insert(it->first);
+ break;
+
+ case extensions::BLACKLISTED_SECURITY_VULNERABILITY:
+ case extensions::BLACKLISTED_CWS_POLICY_VIOLATION:
+ case extensions::BLACKLISTED_POTENTIALLY_UNWANTED:
+ greylist.insert(it->first);
+ break;
+
+ case extensions::BLACKLISTED_UNKNOWN:
+ unchanged.insert(it->first);
+ break;
+ }
+ }
+
+ UpdateBlockedExtensions(blocked, unchanged);
+ UpdateGreylistedExtensions(greylist, unchanged, state_map);
+
+ IdentifyAlertableExtensions();
+}
+
+namespace {
+void Partition(const ExtensionIdSet& before,
+ const ExtensionIdSet& after,
+ const ExtensionIdSet& unchanged,
+ ExtensionIdSet* no_longer,
+ ExtensionIdSet* not_yet) {
+ *not_yet = base::STLSetDifference<ExtensionIdSet>(after, before);
+ *no_longer = base::STLSetDifference<ExtensionIdSet>(before, after);
+ *no_longer = base::STLSetDifference<ExtensionIdSet>(*no_longer, unchanged);
+}
+} // namespace
+
+void ExtensionService::UpdateBlockedExtensions(
+ const ExtensionIdSet& blocked,
+ const ExtensionIdSet& unchanged) {
+ ExtensionIdSet not_yet_blocked, no_longer_blocked;
+ Partition(registry_->blacklisted_extensions().GetIDs(),
+ blocked, unchanged,
+ &no_longer_blocked, ¬_yet_blocked);
+
+ for (ExtensionIdSet::iterator it = no_longer_blocked.begin();
+ it != no_longer_blocked.end(); ++it) {
scoped_refptr<const Extension> extension =
registry_->blacklisted_extensions().GetByID(*it);
if (!extension.get()) {
- NOTREACHED() << "Extension " << *it << " no longer blacklisted, "
- << "but it was never blacklisted.";
+ NOTREACHED() << "Extension " << *it << " no longer blocked, "
+ << "but it was never blocked.";
continue;
}
registry_->RemoveBlacklisted(*it);
@@ -2754,8 +2818,8 @@
Manifest::NUM_LOCATIONS);
}
- for (std::set<std::string>::iterator it = not_yet_blacklisted.begin();
- it != not_yet_blacklisted.end(); ++it) {
+ for (ExtensionIdSet::iterator it = not_yet_blocked.begin();
+ it != not_yet_blocked.end(); ++it) {
scoped_refptr<const Extension> extension = GetInstalledExtension(*it);
if (!extension.get()) {
NOTREACHED() << "Extension " << *it << " needs to be "
@@ -2763,13 +2827,55 @@
continue;
}
registry_->AddBlacklisted(extension);
- extension_prefs_->SetExtensionBlacklisted(extension->id(), true);
+ extension_prefs_->SetExtensionBlacklistState(
+ extension->id(), extensions::BLACKLISTED_MALWARE);
UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST);
UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled",
extension->location(), Manifest::NUM_LOCATIONS);
}
+}
- IdentifyAlertableExtensions();
+// TODO(oleg): UMA logging
+void ExtensionService::UpdateGreylistedExtensions(
+ const ExtensionIdSet& greylist,
+ const ExtensionIdSet& unchanged,
+ const extensions::Blacklist::BlacklistStateMap& state_map) {
+ ExtensionIdSet not_yet_greylisted, no_longer_greylisted;
+ Partition(greylist_.GetIDs(),
+ greylist, unchanged,
+ &no_longer_greylisted, ¬_yet_greylisted);
+
+ for (ExtensionIdSet::iterator it = no_longer_greylisted.begin();
+ it != no_longer_greylisted.end(); ++it) {
+ scoped_refptr<const Extension> extension = greylist_.GetByID(*it);
+ if (!extension.get()) {
+ NOTREACHED() << "Extension " << *it << " no longer greylisted, "
+ << "but it was not marked as greylisted.";
+ continue;
+ }
+
+ greylist_.Remove(*it);
+ extension_prefs_->SetExtensionBlacklistState(extension->id(),
+ extensions::NOT_BLACKLISTED);
+ if (extension_prefs_->GetDisableReasons(extension->id()) &
+ extensions::Extension::DISABLE_GREYLIST)
+ EnableExtension(*it);
+ }
+
+ for (ExtensionIdSet::iterator it = not_yet_greylisted.begin();
+ it != not_yet_greylisted.end(); ++it) {
+ scoped_refptr<const Extension> extension = GetInstalledExtension(*it);
+ if (!extension.get()) {
+ NOTREACHED() << "Extension " << *it << " needs to be "
+ << "disabled, but it's not installed.";
+ continue;
+ }
+ greylist_.Insert(extension);
+ extension_prefs_->SetExtensionBlacklistState(extension->id(),
+ state_map.find(*it)->second);
+ if (registry_->enabled_extensions().Contains(extension->id()))
+ DisableExtension(*it, extensions::Extension::DISABLE_GREYLIST);
+ }
}
void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) {