OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 FROM_HERE, | 550 FROM_HERE, |
551 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), | 551 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), |
552 base::TimeDelta::FromSeconds(kGarbageCollectStartupDelay)); | 552 base::TimeDelta::FromSeconds(kGarbageCollectStartupDelay)); |
553 | 553 |
554 if (extension_prefs_->NeedsStorageGarbageCollection()) { | 554 if (extension_prefs_->NeedsStorageGarbageCollection()) { |
555 GarbageCollectIsolatedStorage(); | 555 GarbageCollectIsolatedStorage(); |
556 extension_prefs_->SetNeedsStorageGarbageCollection(false); | 556 extension_prefs_->SetNeedsStorageGarbageCollection(false); |
557 } | 557 } |
558 system_->management_policy()->RegisterProvider( | 558 system_->management_policy()->RegisterProvider( |
559 shared_module_policy_provider_.get()); | 559 shared_module_policy_provider_.get()); |
| 560 |
| 561 LoadGreylistFromPrefs(); |
560 } | 562 } |
561 | 563 |
562 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", | 564 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", |
563 base::Time::Now() - begin_time); | 565 base::Time::Now() - begin_time); |
564 } | 566 } |
565 | 567 |
| 568 void ExtensionService::LoadGreylistFromPrefs() { |
| 569 scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet(); |
| 570 |
| 571 for (ExtensionSet::const_iterator it = all_extensions->begin(); |
| 572 it != all_extensions->end(); ++it) { |
| 573 extensions::BlacklistState state = |
| 574 extension_prefs_->GetExtensionBlacklistState((*it)->id()); |
| 575 if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || |
| 576 state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || |
| 577 state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) |
| 578 greylist_.Insert(*it); |
| 579 } |
| 580 } |
| 581 |
566 void ExtensionService::VerifyAllExtensions() { | 582 void ExtensionService::VerifyAllExtensions() { |
567 ExtensionIdSet to_add; | 583 ExtensionIdSet to_add; |
568 scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet(); | 584 scoped_ptr<ExtensionSet> all_extensions = GenerateInstalledExtensionsSet(); |
569 | 585 |
570 for (ExtensionSet::const_iterator i = all_extensions->begin(); | 586 for (ExtensionSet::const_iterator i = all_extensions->begin(); |
571 i != all_extensions->end(); ++i) { | 587 i != all_extensions->end(); ++i) { |
572 const Extension& extension = **i; | 588 const Extension& extension = **i; |
573 | 589 |
574 if (InstallVerifier::NeedsVerification(extension)) | 590 if (InstallVerifier::NeedsVerification(extension)) |
575 to_add.insert(extension.id()); | 591 to_add.insert(extension.id()); |
(...skipping 2131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2707 to_be_installed.push_back((*it)->id()); | 2723 to_be_installed.push_back((*it)->id()); |
2708 } | 2724 } |
2709 for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); | 2725 for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); |
2710 it != to_be_installed.end(); | 2726 it != to_be_installed.end(); |
2711 ++it) { | 2727 ++it) { |
2712 MaybeFinishDelayedInstallation(*it); | 2728 MaybeFinishDelayedInstallation(*it); |
2713 } | 2729 } |
2714 } | 2730 } |
2715 | 2731 |
2716 void ExtensionService::OnBlacklistUpdated() { | 2732 void ExtensionService::OnBlacklistUpdated() { |
2717 blacklist_->GetMalwareIDs( | 2733 blacklist_->GetBlacklistedIDs( |
2718 GenerateInstalledExtensionsSet()->GetIDs(), | 2734 GenerateInstalledExtensionsSet()->GetIDs(), |
2719 base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); | 2735 base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); |
2720 } | 2736 } |
2721 | 2737 |
2722 void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) { | 2738 void ExtensionService::ManageBlacklist( |
| 2739 const extensions::Blacklist::BlacklistStateMap& state_map) { |
2723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2724 | 2741 |
2725 std::set<std::string> before = registry_->blacklisted_extensions().GetIDs(); | 2742 std::set<std::string> blocked; |
2726 std::set<std::string> no_longer_blacklisted = | 2743 ExtensionIdSet greylist; |
2727 base::STLSetDifference<std::set<std::string> >(before, updated); | 2744 ExtensionIdSet unchanged; |
2728 std::set<std::string> not_yet_blacklisted = | 2745 for (extensions::Blacklist::BlacklistStateMap::const_iterator it = |
2729 base::STLSetDifference<std::set<std::string> >(updated, before); | 2746 state_map.begin(); |
| 2747 it != state_map.end(); |
| 2748 ++it) { |
| 2749 switch (it->second) { |
| 2750 case extensions::NOT_BLACKLISTED: |
| 2751 break; |
2730 | 2752 |
2731 for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); | 2753 case extensions::BLACKLISTED_MALWARE: |
2732 it != no_longer_blacklisted.end(); ++it) { | 2754 blocked.insert(it->first); |
| 2755 break; |
| 2756 |
| 2757 case extensions::BLACKLISTED_SECURITY_VULNERABILITY: |
| 2758 case extensions::BLACKLISTED_CWS_POLICY_VIOLATION: |
| 2759 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: |
| 2760 greylist.insert(it->first); |
| 2761 break; |
| 2762 |
| 2763 case extensions::BLACKLISTED_UNKNOWN: |
| 2764 unchanged.insert(it->first); |
| 2765 break; |
| 2766 } |
| 2767 } |
| 2768 |
| 2769 UpdateBlockedExtensions(blocked, unchanged); |
| 2770 UpdateGreylistedExtensions(greylist, unchanged, state_map); |
| 2771 |
| 2772 IdentifyAlertableExtensions(); |
| 2773 } |
| 2774 |
| 2775 namespace { |
| 2776 void Partition(const ExtensionIdSet& before, |
| 2777 const ExtensionIdSet& after, |
| 2778 const ExtensionIdSet& unchanged, |
| 2779 ExtensionIdSet* no_longer, |
| 2780 ExtensionIdSet* not_yet) { |
| 2781 *not_yet = base::STLSetDifference<ExtensionIdSet>(after, before); |
| 2782 *no_longer = base::STLSetDifference<ExtensionIdSet>(before, after); |
| 2783 *no_longer = base::STLSetDifference<ExtensionIdSet>(*no_longer, unchanged); |
| 2784 } |
| 2785 } // namespace |
| 2786 |
| 2787 void ExtensionService::UpdateBlockedExtensions( |
| 2788 const ExtensionIdSet& blocked, |
| 2789 const ExtensionIdSet& unchanged) { |
| 2790 ExtensionIdSet not_yet_blocked, no_longer_blocked; |
| 2791 Partition(registry_->blacklisted_extensions().GetIDs(), |
| 2792 blocked, unchanged, |
| 2793 &no_longer_blocked, ¬_yet_blocked); |
| 2794 |
| 2795 for (ExtensionIdSet::iterator it = no_longer_blocked.begin(); |
| 2796 it != no_longer_blocked.end(); ++it) { |
2733 scoped_refptr<const Extension> extension = | 2797 scoped_refptr<const Extension> extension = |
2734 registry_->blacklisted_extensions().GetByID(*it); | 2798 registry_->blacklisted_extensions().GetByID(*it); |
2735 if (!extension.get()) { | 2799 if (!extension.get()) { |
2736 NOTREACHED() << "Extension " << *it << " no longer blacklisted, " | 2800 NOTREACHED() << "Extension " << *it << " no longer blocked, " |
2737 << "but it was never blacklisted."; | 2801 << "but it was never blocked."; |
2738 continue; | 2802 continue; |
2739 } | 2803 } |
2740 registry_->RemoveBlacklisted(*it); | 2804 registry_->RemoveBlacklisted(*it); |
2741 extension_prefs_->SetExtensionBlacklisted(extension->id(), false); | 2805 extension_prefs_->SetExtensionBlacklisted(extension->id(), false); |
2742 AddExtension(extension.get()); | 2806 AddExtension(extension.get()); |
2743 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", | 2807 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", |
2744 extension->location(), | 2808 extension->location(), |
2745 Manifest::NUM_LOCATIONS); | 2809 Manifest::NUM_LOCATIONS); |
2746 } | 2810 } |
2747 | 2811 |
2748 for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); | 2812 for (ExtensionIdSet::iterator it = not_yet_blocked.begin(); |
2749 it != not_yet_blacklisted.end(); ++it) { | 2813 it != not_yet_blocked.end(); ++it) { |
2750 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); | 2814 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
2751 if (!extension.get()) { | 2815 if (!extension.get()) { |
2752 NOTREACHED() << "Extension " << *it << " needs to be " | 2816 NOTREACHED() << "Extension " << *it << " needs to be " |
2753 << "blacklisted, but it's not installed."; | 2817 << "blacklisted, but it's not installed."; |
2754 continue; | 2818 continue; |
2755 } | 2819 } |
2756 registry_->AddBlacklisted(extension); | 2820 registry_->AddBlacklisted(extension); |
2757 extension_prefs_->SetExtensionBlacklisted(extension->id(), true); | 2821 extension_prefs_->SetExtensionBlacklistState( |
| 2822 extension->id(), extensions::BLACKLISTED_MALWARE); |
2758 UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST); | 2823 UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST); |
2759 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", | 2824 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", |
2760 extension->location(), Manifest::NUM_LOCATIONS); | 2825 extension->location(), Manifest::NUM_LOCATIONS); |
2761 } | 2826 } |
| 2827 } |
2762 | 2828 |
2763 IdentifyAlertableExtensions(); | 2829 // TODO(oleg): UMA logging |
| 2830 void ExtensionService::UpdateGreylistedExtensions( |
| 2831 const ExtensionIdSet& greylist, |
| 2832 const ExtensionIdSet& unchanged, |
| 2833 const extensions::Blacklist::BlacklistStateMap& state_map) { |
| 2834 ExtensionIdSet not_yet_greylisted, no_longer_greylisted; |
| 2835 Partition(greylist_.GetIDs(), |
| 2836 greylist, unchanged, |
| 2837 &no_longer_greylisted, ¬_yet_greylisted); |
| 2838 |
| 2839 for (ExtensionIdSet::iterator it = no_longer_greylisted.begin(); |
| 2840 it != no_longer_greylisted.end(); ++it) { |
| 2841 scoped_refptr<const Extension> extension = greylist_.GetByID(*it); |
| 2842 if (!extension.get()) { |
| 2843 NOTREACHED() << "Extension " << *it << " no longer greylisted, " |
| 2844 << "but it was not marked as greylisted."; |
| 2845 continue; |
| 2846 } |
| 2847 |
| 2848 greylist_.Remove(*it); |
| 2849 extension_prefs_->SetExtensionBlacklistState(extension->id(), |
| 2850 extensions::NOT_BLACKLISTED); |
| 2851 if (extension_prefs_->GetDisableReasons(extension->id()) & |
| 2852 extensions::Extension::DISABLE_GREYLIST) |
| 2853 EnableExtension(*it); |
| 2854 } |
| 2855 |
| 2856 for (ExtensionIdSet::iterator it = not_yet_greylisted.begin(); |
| 2857 it != not_yet_greylisted.end(); ++it) { |
| 2858 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| 2859 if (!extension.get()) { |
| 2860 NOTREACHED() << "Extension " << *it << " needs to be " |
| 2861 << "disabled, but it's not installed."; |
| 2862 continue; |
| 2863 } |
| 2864 greylist_.Insert(extension); |
| 2865 extension_prefs_->SetExtensionBlacklistState(extension->id(), |
| 2866 state_map.find(*it)->second); |
| 2867 if (registry_->enabled_extensions().Contains(extension->id())) |
| 2868 DisableExtension(*it, extensions::Extension::DISABLE_GREYLIST); |
| 2869 } |
2764 } | 2870 } |
2765 | 2871 |
2766 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { | 2872 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { |
2767 update_observers_.AddObserver(observer); | 2873 update_observers_.AddObserver(observer); |
2768 } | 2874 } |
2769 | 2875 |
2770 void ExtensionService::RemoveUpdateObserver( | 2876 void ExtensionService::RemoveUpdateObserver( |
2771 extensions::UpdateObserver* observer) { | 2877 extensions::UpdateObserver* observer) { |
2772 update_observers_.RemoveObserver(observer); | 2878 update_observers_.RemoveObserver(observer); |
2773 } | 2879 } |
2774 | 2880 |
2775 // Used only by test code. | 2881 // Used only by test code. |
2776 void ExtensionService::UnloadAllExtensionsInternal() { | 2882 void ExtensionService::UnloadAllExtensionsInternal() { |
2777 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); | 2883 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); |
2778 | 2884 |
2779 registry_->ClearAll(); | 2885 registry_->ClearAll(); |
2780 system_->runtime_data()->ClearAll(); | 2886 system_->runtime_data()->ClearAll(); |
2781 | 2887 |
2782 // TODO(erikkay) should there be a notification for this? We can't use | 2888 // TODO(erikkay) should there be a notification for this? We can't use |
2783 // EXTENSION_UNLOADED since that implies that the extension has been disabled | 2889 // EXTENSION_UNLOADED since that implies that the extension has been disabled |
2784 // or uninstalled. | 2890 // or uninstalled. |
2785 } | 2891 } |
OLD | NEW |