OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The Safe Browsing service is responsible for downloading anti-phishing and | 5 // The Safe Browsing service is responsible for downloading anti-phishing and |
6 // anti-malware tables and checking urls against them. | 6 // anti-malware tables and checking urls against them. |
7 | 7 |
8 #ifndef CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ | 8 #ifndef CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ |
9 #define CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ | 9 #define CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ |
10 | 10 |
11 #include <deque> | 11 #include <deque> |
12 #include <map> | 12 #include <map> |
13 #include <set> | 13 #include <set> |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/callback.h" | |
18 #include "base/containers/hash_tables.h" | |
19 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
20 #include "base/memory/scoped_ptr.h" | |
21 #include "base/synchronization/lock.h" | |
22 #include "base/time/time.h" | |
23 #include "chrome/browser/safe_browsing/protocol_manager.h" | |
24 #include "chrome/browser/safe_browsing/safe_browsing_util.h" | 18 #include "chrome/browser/safe_browsing/safe_browsing_util.h" |
25 #include "url/gurl.h" | 19 #include "url/gurl.h" |
26 | 20 |
27 class SafeBrowsingService; | 21 // Interface to either the locally-managed or a remotely-managed database. |
28 class SafeBrowsingDatabase; | |
29 | |
30 namespace net { | |
31 class URLRequestContext; | |
32 class URLRequestContextGetter; | |
33 } | |
34 | |
35 namespace safe_browsing { | |
36 class ClientSideDetectionService; | |
37 class DownloadProtectionService; | |
38 } | |
39 | |
40 // Construction needs to happen on the main thread. | |
41 class SafeBrowsingDatabaseManager | 22 class SafeBrowsingDatabaseManager |
42 : public base::RefCountedThreadSafe<SafeBrowsingDatabaseManager>, | 23 : public base::RefCountedThreadSafe<SafeBrowsingDatabaseManager> { |
43 public SafeBrowsingProtocolManagerDelegate { | |
44 public: | 24 public: |
45 class Client; | 25 // Callers requesting a result should derive from this class. |
46 | 26 // The destructor should call db_manager->CancelCheck(client) if a |
47 // Bundle of SafeBrowsing state while performing a URL or hash prefix check. | 27 // request is still pending. |
48 struct SafeBrowsingCheck { | |
49 // |check_type| should correspond to the type of item that is being | |
50 // checked, either a URL or a binary hash/URL. We store this for two | |
51 // purposes: to know which of Client's methods to call when a result is | |
52 // known, and for logging purposes. It *isn't* used to predict the response | |
53 // list type, that is information that the server gives us. | |
54 SafeBrowsingCheck(const std::vector<GURL>& urls, | |
55 const std::vector<SBFullHash>& full_hashes, | |
56 Client* client, | |
57 safe_browsing_util::ListType check_type, | |
58 const std::vector<SBThreatType>& expected_threats); | |
59 ~SafeBrowsingCheck(); | |
60 | |
61 // Either |urls| or |full_hashes| is used to lookup database. |*_results| | |
62 // are parallel vectors containing the results. They are initialized to | |
63 // contain SB_THREAT_TYPE_SAFE. | |
64 std::vector<GURL> urls; | |
65 std::vector<SBThreatType> url_results; | |
66 std::vector<std::string> url_metadata; | |
67 std::vector<SBFullHash> full_hashes; | |
68 std::vector<SBThreatType> full_hash_results; | |
69 | |
70 Client* client; | |
71 bool need_get_hash; | |
72 base::TimeTicks start; // When check was sent to SB service. | |
73 safe_browsing_util::ListType check_type; // See comment in constructor. | |
74 std::vector<SBThreatType> expected_threats; | |
75 std::vector<SBPrefix> prefix_hits; | |
76 std::vector<SBFullHashResult> cache_hits; | |
77 | |
78 // Vends weak pointers for async callbacks on the IO thread, such as | |
79 // timeout checks and replies from checks performed on the SB task runner. | |
80 // TODO(lzheng): We should consider to use this time out check | |
81 // for browsing too (instead of implementing in | |
82 // safe_browsing_resource_handler.cc). | |
83 scoped_ptr<base::WeakPtrFactory< | |
84 SafeBrowsingDatabaseManager> > weak_ptr_factory_; | |
85 | |
86 private: | |
87 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingCheck); | |
88 }; | |
89 | |
90 class Client { | 28 class Client { |
91 public: | 29 public: |
92 void OnSafeBrowsingResult(const SafeBrowsingCheck& check); | |
93 | |
94 protected: | |
95 virtual ~Client() {} | 30 virtual ~Client() {} |
96 | 31 |
97 // Called when the result of checking a browse URL is known. | 32 // Called when the result of checking a browse URL is known. |
98 virtual void OnCheckBrowseUrlResult(const GURL& url, | 33 virtual void OnCheckBrowseUrlResult(const GURL& url, |
99 SBThreatType threat_type, | 34 SBThreatType threat_type, |
100 const std::string& metadata) {} | 35 const std::string& metadata) {} |
101 | 36 |
102 // Called when the result of checking a download URL is known. | 37 // Called when the result of checking a download URL is known. |
103 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain, | 38 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain, |
104 SBThreatType threat_type) {} | 39 SBThreatType threat_type) {} |
105 | 40 |
106 // Called when the result of checking a set of extensions is known. | 41 // Called when the result of checking a set of extensions is known. |
107 virtual void OnCheckExtensionsResult( | 42 virtual void OnCheckExtensionsResult( |
108 const std::set<std::string>& threats) {} | 43 const std::set<std::string>& threats) {} |
109 }; | 44 }; |
110 | 45 |
111 // Creates the safe browsing service. Need to initialize before using. | |
112 explicit SafeBrowsingDatabaseManager( | |
113 const scoped_refptr<SafeBrowsingService>& service); | |
114 | |
115 // Returns true if the url's scheme can be checked. | 46 // Returns true if the url's scheme can be checked. |
116 bool CanCheckUrl(const GURL& url) const; | 47 virtual bool CanCheckUrl(const GURL& url) const = 0; |
117 | 48 |
118 // Returns whether download protection is enabled. | 49 // Returns whether download protection is enabled. |
119 bool download_protection_enabled() const { | 50 virtual bool download_protection_enabled() const = 0; |
120 return enable_download_protection_; | |
121 } | |
122 | 51 |
123 // Called on the IO thread to check if the given url is safe or not. If we | 52 // Called on the IO thread to check if the given url is safe or not. If we |
124 // can synchronously determine that the url is safe, CheckUrl returns true. | 53 // can synchronously determine that the url is safe, CheckUrl returns true. |
125 // Otherwise it returns false, and "client" is called asynchronously with the | 54 // Otherwise it returns false, and "client" is called asynchronously with the |
126 // result when it is ready. | 55 // result when it is ready. |
127 virtual bool CheckBrowseUrl(const GURL& url, Client* client); | 56 virtual bool CheckBrowseUrl(const GURL& url, Client* client) = 0; |
128 | 57 |
129 // Check if the prefix for |url| is in safebrowsing download add lists. | 58 // Check if the prefix for |url| is in safebrowsing download add lists. |
130 // Result will be passed to callback in |client|. | 59 // Result will be passed to callback in |client|. |
131 virtual bool CheckDownloadUrl(const std::vector<GURL>& url_chain, | 60 virtual bool CheckDownloadUrl(const std::vector<GURL>& url_chain, |
132 Client* client); | 61 Client* client) = 0; |
133 | 62 |
134 // Check which prefixes in |extension_ids| are in the safebrowsing blacklist. | 63 // Check which prefixes in |extension_ids| are in the safebrowsing blacklist. |
135 // Returns true if not, false if further checks need to be made in which case | 64 // Returns true if not, false if further checks need to be made in which case |
136 // the result will be passed to |client|. | 65 // the result will be passed to |client|. |
137 virtual bool CheckExtensionIDs(const std::set<std::string>& extension_ids, | 66 virtual bool CheckExtensionIDs(const std::set<std::string>& extension_ids, |
138 Client* client); | 67 Client* client) = 0; |
139 | 68 |
140 // Check if the |url| matches any of the full-length hashes from the client- | 69 // Check if the |url| matches any of the full-length hashes from the client- |
141 // side phishing detection whitelist. Returns true if there was a match and | 70 // side phishing detection whitelist. Returns true if there was a match and |
142 // false otherwise. To make sure we are conservative we will return true if | 71 // false otherwise. To make sure we are conservative we will return true if |
143 // an error occurs. This method must be called on the IO thread. | 72 // an error occurs. This method must be called on the IO thread. |
144 virtual bool MatchCsdWhitelistUrl(const GURL& url); | 73 virtual bool MatchCsdWhitelistUrl(const GURL& url) = 0; |
145 | 74 |
146 // Check if the given IP address (either IPv4 or IPv6) matches the malware | 75 // Check if the given IP address (either IPv4 or IPv6) matches the malware |
147 // IP blacklist. | 76 // IP blacklist. |
148 virtual bool MatchMalwareIP(const std::string& ip_address); | 77 virtual bool MatchMalwareIP(const std::string& ip_address) = 0; |
149 | 78 |
150 // Check if the |url| matches any of the full-length hashes from the download | 79 // Check if the |url| matches any of the full-length hashes from the download |
151 // whitelist. Returns true if there was a match and false otherwise. To make | 80 // whitelist. Returns true if there was a match and false otherwise. To make |
152 // sure we are conservative we will return true if an error occurs. This | 81 // sure we are conservative we will return true if an error occurs. This |
153 // method must be called on the IO thread. | 82 // method must be called on the IO thread. |
154 virtual bool MatchDownloadWhitelistUrl(const GURL& url); | 83 virtual bool MatchDownloadWhitelistUrl(const GURL& url) = 0; |
155 | 84 |
156 // Check if |str| matches any of the full-length hashes from the download | 85 // Check if |str| matches any of the full-length hashes from the download |
157 // whitelist. Returns true if there was a match and false otherwise. To make | 86 // whitelist. Returns true if there was a match and false otherwise. To make |
158 // sure we are conservative we will return true if an error occurs. This | 87 // sure we are conservative we will return true if an error occurs. This |
159 // method must be called on the IO thread. | 88 // method must be called on the IO thread. |
160 virtual bool MatchDownloadWhitelistString(const std::string& str); | 89 virtual bool MatchDownloadWhitelistString(const std::string& str) = 0; |
161 | 90 |
162 // Check if the |url| matches any of the full-length hashes from the off- | 91 // Check if the |url| matches any of the full-length hashes from the off- |
163 // domain inclusion whitelist. Returns true if there was a match and false | 92 // domain inclusion whitelist. Returns true if there was a match and false |
164 // otherwise. To make sure we are conservative, we will return true if an | 93 // otherwise. To make sure we are conservative, we will return true if an |
165 // error occurs. This method must be called on the IO thread. | 94 // error occurs. This method must be called on the IO thread. |
166 virtual bool MatchInclusionWhitelistUrl(const GURL& url); | 95 virtual bool MatchInclusionWhitelistUrl(const GURL& url) = 0; |
167 | 96 |
168 // Check if the CSD malware IP matching kill switch is turned on. | 97 // Check if the CSD malware IP matching kill switch is turned on. |
169 virtual bool IsMalwareKillSwitchOn(); | 98 virtual bool IsMalwareKillSwitchOn() = 0; |
170 | 99 |
171 // Check if the CSD whitelist kill switch is turned on. | 100 // Check if the CSD whitelist kill switch is turned on. |
172 virtual bool IsCsdWhitelistKillSwitchOn(); | 101 virtual bool IsCsdWhitelistKillSwitchOn() = 0; |
173 | 102 |
174 // Called on the IO thread to cancel a pending check if the result is no | 103 // Called on the IO thread to cancel a pending check if the result is no |
175 // longer needed. | 104 // longer needed. Also called after the result has been handled. |
176 void CancelCheck(Client* client); | 105 virtual void CancelCheck(Client* client) = 0; |
177 | |
178 // Called on the IO thread when the SafeBrowsingProtocolManager has received | |
179 // the full hash results for prefix hits detected in the database. | |
180 void HandleGetHashResults(SafeBrowsingCheck* check, | |
181 const std::vector<SBFullHashResult>& full_hashes, | |
182 const base::TimeDelta& cache_lifetime); | |
183 | 106 |
184 // Called to initialize objects that are used on the io_thread. This may be | 107 // Called to initialize objects that are used on the io_thread. This may be |
185 // called multiple times during the life of the DatabaseManager. Must be | 108 // called multiple times during the life of the DatabaseManager. Must be |
186 // called on IO thread. | 109 // called on IO thread. |
187 void StartOnIOThread(); | 110 virtual void StartOnIOThread() = 0; |
188 | 111 |
189 // Called to stop or shutdown operations on the io_thread. This may be called | 112 // Called to stop or shutdown operations on the io_thread. This may be called |
190 // multiple times during the life of the DatabaseManager. Must be called | 113 // multiple times during the life of the DatabaseManager. Must be called |
191 // on IO thread. If shutdown is true, the manager is disabled permanently. | 114 // on IO thread. If shutdown is true, the manager is disabled permanently. |
192 void StopOnIOThread(bool shutdown); | 115 virtual void StopOnIOThread(bool shutdown) = 0; |
193 | 116 |
194 protected: | 117 protected: |
195 ~SafeBrowsingDatabaseManager() override; | 118 virtual ~SafeBrowsingDatabaseManager() {} |
196 | 119 |
197 // protected for tests. | |
198 void NotifyDatabaseUpdateFinished(bool update_succeeded); | |
199 | |
200 private: | |
201 friend class base::RefCountedThreadSafe<SafeBrowsingDatabaseManager>; | 120 friend class base::RefCountedThreadSafe<SafeBrowsingDatabaseManager>; |
202 friend class SafeBrowsingServerTest; | 121 }; // class SafeBrowsingDatabaseManager |
203 friend class SafeBrowsingServiceTest; | |
204 friend class SafeBrowsingServiceTestHelper; | |
205 friend class SafeBrowsingDatabaseManagerTest; | |
206 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseManagerTest, | |
207 GetUrlSeverestThreatType); | |
208 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseManagerTest, | |
209 ServiceStopWithPendingChecks); | |
210 | |
211 typedef std::set<SafeBrowsingCheck*> CurrentChecks; | |
212 typedef std::vector<SafeBrowsingCheck*> GetHashRequestors; | |
213 typedef base::hash_map<SBPrefix, GetHashRequestors> GetHashRequests; | |
214 | |
215 // Clients that we've queued up for checking later once the database is ready. | |
216 struct QueuedCheck { | |
217 QueuedCheck(const safe_browsing_util::ListType check_type, | |
218 Client* client, | |
219 const GURL& url, | |
220 const std::vector<SBThreatType>& expected_threats, | |
221 const base::TimeTicks& start); | |
222 ~QueuedCheck(); | |
223 safe_browsing_util::ListType check_type; | |
224 Client* client; | |
225 GURL url; | |
226 std::vector<SBThreatType> expected_threats; | |
227 base::TimeTicks start; // When check was queued. | |
228 }; | |
229 | |
230 // Return the threat type of the severest entry in |full_hashes| which matches | |
231 // |hash|, or SAFE if none match. | |
232 static SBThreatType GetHashSeverestThreatType( | |
233 const SBFullHash& hash, | |
234 const std::vector<SBFullHashResult>& full_hashes); | |
235 | |
236 // Given a URL, compare all the possible host + path full hashes to the set of | |
237 // provided full hashes. Returns the threat type of the severest matching | |
238 // result from |full_hashes|, or SAFE if none match. | |
239 static SBThreatType GetUrlSeverestThreatType( | |
240 const GURL& url, | |
241 const std::vector<SBFullHashResult>& full_hashes, | |
242 size_t* index); | |
243 | |
244 // Called to stop operations on the io_thread. This may be called multiple | |
245 // times during the life of the DatabaseManager. Should be called on IO | |
246 // thread. | |
247 void DoStopOnIOThread(); | |
248 | |
249 // Returns whether |database_| exists and is accessible. | |
250 bool DatabaseAvailable() const; | |
251 | |
252 // Called on the IO thread. If the database does not exist, queues up a call | |
253 // on the db thread to create it. Returns whether the database is available. | |
254 // | |
255 // Note that this is only needed outside the db thread, since functions on the | |
256 // db thread can call GetDatabase() directly. | |
257 bool MakeDatabaseAvailable(); | |
258 | |
259 // Should only be called on db thread as SafeBrowsingDatabase is not | |
260 // threadsafe. | |
261 SafeBrowsingDatabase* GetDatabase(); | |
262 | |
263 // Called on the IO thread with the check result. | |
264 void OnCheckDone(SafeBrowsingCheck* info); | |
265 | |
266 // Called on the database thread to retrieve chunks. | |
267 void GetAllChunksFromDatabase(GetChunksCallback callback); | |
268 | |
269 // Called on the IO thread with the results of all chunks. | |
270 void OnGetAllChunksFromDatabase(const std::vector<SBListChunkRanges>& lists, | |
271 bool database_error, | |
272 GetChunksCallback callback); | |
273 | |
274 // Called on the IO thread after the database reports that it added a chunk. | |
275 void OnAddChunksComplete(AddChunksCallback callback); | |
276 | |
277 // Notification that the database is done loading its bloom filter. We may | |
278 // have had to queue checks until the database is ready, and if so, this | |
279 // checks them. | |
280 void DatabaseLoadComplete(); | |
281 | |
282 // Called on the database thread to add/remove chunks and host keys. | |
283 void AddDatabaseChunks(const std::string& list, | |
284 scoped_ptr<ScopedVector<SBChunkData> > chunks, | |
285 AddChunksCallback callback); | |
286 | |
287 void DeleteDatabaseChunks( | |
288 scoped_ptr<std::vector<SBChunkDelete> > chunk_deletes); | |
289 | |
290 void NotifyClientBlockingComplete(Client* client, bool proceed); | |
291 | |
292 void DatabaseUpdateFinished(bool update_succeeded); | |
293 | |
294 // Called on the db thread to close the database. See CloseDatabase(). | |
295 void OnCloseDatabase(); | |
296 | |
297 // Runs on the db thread to reset the database. We assume that resetting the | |
298 // database is a synchronous operation. | |
299 void OnResetDatabase(); | |
300 | |
301 // Internal worker function for processing full hashes. | |
302 void OnHandleGetHashResults(SafeBrowsingCheck* check, | |
303 const std::vector<SBFullHashResult>& full_hashes); | |
304 | |
305 // Run one check against |full_hashes|. Returns |true| if the check | |
306 // finds a match in |full_hashes|. | |
307 bool HandleOneCheck(SafeBrowsingCheck* check, | |
308 const std::vector<SBFullHashResult>& full_hashes); | |
309 | |
310 // Invoked by CheckDownloadUrl. It checks the download URL on | |
311 // |safe_browsing_task_runner_|. | |
312 std::vector<SBPrefix> CheckDownloadUrlOnSBThread( | |
313 const std::vector<SBPrefix>& prefixes); | |
314 | |
315 // The callback function when a safebrowsing check is timed out. Client will | |
316 // be notified that the safebrowsing check is SAFE when this happens. | |
317 void TimeoutCallback(SafeBrowsingCheck* check); | |
318 | |
319 // Calls the Client's callback on IO thread after CheckDownloadUrl finishes. | |
320 void OnAsyncCheckDone(SafeBrowsingCheck* check, | |
321 const std::vector<SBPrefix>& prefix_hits); | |
322 | |
323 // Checks all extension ID hashes on |safe_browsing_task_runner_|. | |
324 std::vector<SBPrefix> CheckExtensionIDsOnSBThread( | |
325 const std::vector<SBPrefix>& prefixes); | |
326 | |
327 // Helper function that calls safe browsing client and cleans up |checks_|. | |
328 void SafeBrowsingCheckDone(SafeBrowsingCheck* check); | |
329 | |
330 // Helper function to set |check| with default values and start a safe | |
331 // browsing check with timeout of |timeout|. |task| will be called on | |
332 // success, otherwise TimeoutCallback will be called. | |
333 void StartSafeBrowsingCheck( | |
334 SafeBrowsingCheck* check, | |
335 const base::Callback<std::vector<SBPrefix>(void)>& task); | |
336 | |
337 // SafeBrowsingProtocolManageDelegate override | |
338 void ResetDatabase() override; | |
339 void UpdateStarted() override; | |
340 void UpdateFinished(bool success) override; | |
341 void GetChunks(GetChunksCallback callback) override; | |
342 void AddChunks(const std::string& list, | |
343 scoped_ptr<ScopedVector<SBChunkData>> chunks, | |
344 AddChunksCallback callback) override; | |
345 void DeleteChunks( | |
346 scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes) override; | |
347 | |
348 scoped_refptr<SafeBrowsingService> sb_service_; | |
349 | |
350 CurrentChecks checks_; | |
351 | |
352 // Used for issuing only one GetHash request for a given prefix. | |
353 GetHashRequests gethash_requests_; | |
354 | |
355 // The persistent database. We don't use a scoped_ptr because it | |
356 // needs to be destroyed on a different thread than this object. | |
357 SafeBrowsingDatabase* database_; | |
358 | |
359 // Lock used to prevent possible data races due to compiler optimizations. | |
360 mutable base::Lock database_lock_; | |
361 | |
362 // Whether the service is running. 'enabled_' is used by the | |
363 // SafeBrowsingDatabaseManager on the IO thread during normal operations. | |
364 bool enabled_; | |
365 | |
366 // Indicate if download_protection is enabled by command switch | |
367 // so we allow this feature to be exersized. | |
368 bool enable_download_protection_; | |
369 | |
370 // Indicate if client-side phishing detection whitelist should be enabled | |
371 // or not. | |
372 bool enable_csd_whitelist_; | |
373 | |
374 // Indicate if the download whitelist should be enabled or not. | |
375 bool enable_download_whitelist_; | |
376 | |
377 // Indicate if the extension blacklist should be enabled. | |
378 bool enable_extension_blacklist_; | |
379 | |
380 // Indicate if the csd malware IP blacklist should be enabled. | |
381 bool enable_ip_blacklist_; | |
382 | |
383 // Indicate if the unwanted software blacklist should be enabled. | |
384 bool enable_unwanted_software_blacklist_; | |
385 | |
386 // The sequenced task runner for running safe browsing database operations. | |
387 scoped_refptr<base::SequencedTaskRunner> safe_browsing_task_runner_; | |
388 | |
389 // Indicates if we're currently in an update cycle. | |
390 bool update_in_progress_; | |
391 | |
392 // When true, newly fetched chunks may not in the database yet since the | |
393 // database is still updating. | |
394 bool database_update_in_progress_; | |
395 | |
396 // Indicates if we're in the midst of trying to close the database. If this | |
397 // is true, nothing on the IO thread should access the database. | |
398 bool closing_database_; | |
399 | |
400 std::deque<QueuedCheck> queued_checks_; | |
401 | |
402 // Timeout to use for safe browsing checks. | |
403 base::TimeDelta check_timeout_; | |
404 | |
405 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManager); | |
406 }; | |
407 | 122 |
408 #endif // CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ | 123 #endif // CHROME_BROWSER_SAFE_BROWSING_DATABASE_MANAGER_H_ |
OLD | NEW |