1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_BLOCKLIST_H_ 6 #define CHROME_BROWSER_EXTENSIONS_BLOCKLIST_H_ 7 8 #include <list> 9 #include <map> 10 #include <memory> 11 #include <set> 12 #include <string> 13 #include <vector> 14 15 #include "base/callback.h" 16 #include "base/callback_list.h" 17 #include "base/macros.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/observer_list.h" 20 #include "components/keyed_service/core/keyed_service.h" 21 #include "components/safe_browsing/core/db/database_manager.h" 22 #include "extensions/browser/blocklist_state.h" 23 24 namespace content { 25 class BrowserContext; 26 } 27 28 namespace extensions { 29 30 class BlocklistStateFetcher; 31 class ExtensionPrefs; 32 33 // The blocklist of extensions backed by safe browsing. 34 class Blocklist : public KeyedService, public base::SupportsWeakPtr<Blocklist> { 35 public: 36 class Observer { 37 public: 38 // Observes |blocklist| on construction and unobserves on destruction. 39 explicit Observer(Blocklist* blocklist); 40 41 virtual void OnBlocklistUpdated() = 0; 42 43 protected: 44 virtual ~Observer(); 45 46 private: 47 Blocklist* blocklist_; 48 }; 49 50 class ScopedDatabaseManagerForTest { 51 public: 52 explicit ScopedDatabaseManagerForTest( 53 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> 54 database_manager); 55 56 ~ScopedDatabaseManagerForTest(); 57 58 private: 59 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> original_; 60 61 DISALLOW_COPY_AND_ASSIGN(ScopedDatabaseManagerForTest); 62 }; 63 64 using BlocklistStateMap = std::map<std::string, BlocklistState>; 65 66 using GetBlocklistedIDsCallback = 67 base::OnceCallback<void(const BlocklistStateMap&)>; 68 69 using GetMalwareIDsCallback = 70 base::OnceCallback<void(const std::set<std::string>&)>; 71 72 using IsBlocklistedCallback = base::OnceCallback<void(BlocklistState)>; 73 74 explicit Blocklist(ExtensionPrefs* prefs); 75 76 ~Blocklist() override; 77 78 static Blocklist* Get(content::BrowserContext* context); 79 80 // From the set of extension IDs passed in via |ids|, asynchronously checks 81 // which are blocklisted and includes them in the resulting map passed 82 // via |callback|, which will be sent on the caller's message loop. The values 83 // of the map are the blocklist state for each extension. Extensions with 84 // a BlocklistState of NOT_BLOCKLISTED are not included in the result. 85 // 86 // For a synchronous version which ONLY CHECKS CURRENTLY INSTALLED EXTENSIONS 87 // see ExtensionPrefs::IsExtensionBlocklisted. 88 void GetBlocklistedIDs(const std::set<std::string>& ids, 89 GetBlocklistedIDsCallback callback); 90 91 // From the subset of extension IDs passed in via |ids|, select the ones 92 // marked in the blocklist as BLOCKLISTED_MALWARE and asynchronously pass 93 // to |callback|. Basically, will call GetBlocklistedIDs and filter its 94 // results. 95 void GetMalwareIDs(const std::set<std::string>& ids, 96 GetMalwareIDsCallback callback); 97 98 // More convenient form of GetBlocklistedIDs for checking a single extension. 99 void IsBlocklisted(const std::string& extension_id, 100 IsBlocklistedCallback callback); 101 102 // Used to mock BlocklistStateFetcher in unit tests. Blocklist owns the 103 // |fetcher|. 104 void SetBlocklistStateFetcherForTest(BlocklistStateFetcher* fetcher); 105 106 // Reset the owned BlocklistStateFetcher to null and return the current 107 // BlocklistStateFetcher. 108 BlocklistStateFetcher* ResetBlocklistStateFetcherForTest(); 109 110 // Reset the listening for an updated database. 111 void ResetDatabaseUpdatedListenerForTest(); 112 113 // Adds/removes an observer to the blocklist. 114 void AddObserver(Observer* observer); 115 void RemoveObserver(Observer* observer); 116 117 private: 118 // Use via ScopedDatabaseManagerForTest. 119 static void SetDatabaseManager( 120 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> 121 database_manager); 122 static scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> 123 GetDatabaseManager(); 124 125 void ObserveNewDatabase(); 126 127 void NotifyObservers(); 128 129 void GetBlocklistStateForIDs(GetBlocklistedIDsCallback callback, 130 const std::set<std::string>& blocklisted_ids); 131 132 void RequestExtensionsBlocklistState(const std::set<std::string>& ids, 133 base::OnceClosure callback); 134 135 void OnBlocklistStateReceived(const std::string& id, BlocklistState state); 136 137 void ReturnBlocklistStateMap(GetBlocklistedIDsCallback callback, 138 const std::set<std::string>& blocklisted_ids); 139 140 base::ObserverList<Observer>::Unchecked observers_; 141 142 std::unique_ptr<base::RepeatingClosureList::Subscription> 143 database_updated_subscription_; 144 std::unique_ptr<base::RepeatingClosureList::Subscription> 145 database_changed_subscription_; 146 147 // The cached BlocklistState's, received from BlocklistStateFetcher. 148 BlocklistStateMap blocklist_state_cache_; 149 150 std::unique_ptr<BlocklistStateFetcher> state_fetcher_; 151 152 // The list of ongoing requests for blocklist states that couldn't be 153 // served directly from the cache. A new request is created in 154 // GetBlocklistedIDs and deleted when the callback is called from 155 // OnBlocklistStateReceived. 156 // 157 // This is a list of requests. Each item in the list is a request. A request 158 // is a pair of [vector of string ids to check, response closure]. 159 std::list<std::pair<std::vector<std::string>, base::OnceClosure>> 160 state_requests_; 161 162 DISALLOW_COPY_AND_ASSIGN(Blocklist); 163 }; 164 165 } // namespace extensions 166 167 #endif // CHROME_BROWSER_EXTENSIONS_BLOCKLIST_H_ 168