1 // Copyright (c) 2011 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.
5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
13 #include "base/containers/hash_tables.h"
14 #include "base/files/file_path.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/synchronization/lock.h"
20 #include "base/time/time.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_store.h"
23 namespace safe_browsing
{
28 class SafeBrowsingDatabase
;
30 // Factory for creating SafeBrowsingDatabase. Tests implement this factory
31 // to create fake Databases for testing.
32 class SafeBrowsingDatabaseFactory
{
34 SafeBrowsingDatabaseFactory() { }
35 virtual ~SafeBrowsingDatabaseFactory() { }
36 virtual SafeBrowsingDatabase
* CreateSafeBrowsingDatabase(
37 const scoped_refptr
<base::SequencedTaskRunner
>& db_task_runner
,
38 bool enable_download_protection
,
39 bool enable_client_side_whitelist
,
40 bool enable_download_whitelist
,
41 bool enable_extension_blacklist
,
42 bool enable_side_effect_free_whitelist
,
43 bool enable_ip_blacklist
,
44 bool enable_unwanted_software_list
) = 0;
47 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactory
);
50 // Encapsulates on-disk databases that for safebrowsing. There are
51 // four databases: browse, download, download whitelist and
52 // client-side detection (csd) whitelist databases. The browse database contains
53 // information about phishing and malware urls. The download database contains
54 // URLs for bad binaries (e.g: those containing virus) and hash of
55 // these downloaded contents. The download whitelist contains whitelisted
56 // download hosting sites as well as whitelisted binary signing certificates
57 // etc. The csd whitelist database contains URLs that will never be considered
58 // as phishing by the client-side phishing detection. These on-disk databases
59 // are shared among all profiles, as it doesn't contain user-specific data. This
60 // object is not thread-safe, i.e. all its methods should be used on the same
61 // thread that it was created on, unless specified otherwise.
62 class SafeBrowsingDatabase
{
64 // Factory method for obtaining a SafeBrowsingDatabase implementation.
65 // It is not thread safe.
66 // The browse list and off-domain inclusion whitelist are always on;
67 // availability of other lists is controlled by the flags on this method.
68 static SafeBrowsingDatabase
* Create(
69 const scoped_refptr
<base::SequencedTaskRunner
>& db_task_runner
,
70 bool enable_download_protection
,
71 bool enable_client_side_whitelist
,
72 bool enable_download_whitelist
,
73 bool enable_extension_blacklist
,
74 bool side_effect_free_whitelist
,
75 bool enable_ip_blacklist
,
76 bool enable_unwanted_software_list
);
78 // Makes the passed |factory| the factory used to instantiate
79 // a SafeBrowsingDatabase. This is used for tests.
80 static void RegisterFactory(SafeBrowsingDatabaseFactory
* factory
) {
84 virtual ~SafeBrowsingDatabase();
86 // Initializes the database with the given filename.
87 virtual void Init(const base::FilePath
& filename
) = 0;
89 // Deletes the current database and creates a new one.
90 virtual bool ResetDatabase() = 0;
92 // Returns false if |url| is not in the browse database or already was cached
93 // as a miss. If it returns true, |prefix_hits| contains sorted unique
94 // matching hash prefixes which had no cached results and |cache_hits|
95 // contains any matching cached gethash results. This function is safe to
96 // call from any thread.
97 virtual bool ContainsBrowseUrl(
99 std::vector
<SBPrefix
>* prefix_hits
,
100 std::vector
<SBFullHashResult
>* cache_hits
) = 0;
102 // Returns true iff the given url is on the unwanted software blacklist.
103 // Returns false if |url| is not in the browse database or already was cached
104 // as a miss. If it returns true, |prefix_hits| contains sorted unique
105 // matching hash prefixes which had no cached results and |cache_hits|
106 // contains any matching cached gethash results. This function is safe to
107 // call from any thread.
108 virtual bool ContainsUnwantedSoftwareUrl(
110 std::vector
<SBPrefix
>* prefix_hits
,
111 std::vector
<SBFullHashResult
>* cache_hits
) = 0;
113 // Returns false if none of |prefixes| are in Download database. If it returns
114 // true, |prefix_hits| should contain the prefixes for the URLs that were in
115 // the database. This function can ONLY be accessed from creation thread.
116 virtual bool ContainsDownloadUrlPrefixes(
117 const std::vector
<SBPrefix
>& prefixes
,
118 std::vector
<SBPrefix
>* prefix_hits
) = 0;
120 // Returns false if |url| is not on the client-side phishing detection
121 // whitelist. Otherwise, this function returns true. Note: the whitelist
122 // only contains full-length hashes so we don't return any prefix hit. This
123 // function is safe to call from any thread.
124 virtual bool ContainsCsdWhitelistedUrl(const GURL
& url
) = 0;
126 // The download whitelist is used for two purposes: a white-domain list of
127 // sites that are considered to host only harmless binaries as well as a
128 // whitelist of arbitrary strings such as hashed certificate authorities that
129 // are considered to be trusted. The two methods below let you lookup the
130 // whitelist either for a URL or an arbitrary string. These methods will
131 // return false if no match is found and true otherwise. This function is safe
132 // to call from any thread.
133 virtual bool ContainsDownloadWhitelistedUrl(const GURL
& url
) = 0;
134 virtual bool ContainsDownloadWhitelistedString(const std::string
& str
) = 0;
136 // Returns true if |url| is on the off-domain inclusion whitelist.
137 virtual bool ContainsInclusionWhitelistedUrl(const GURL
& url
) = 0;
139 // Populates |prefix_hits| with any prefixes in |prefixes| that have matches
140 // in the database, returning true if there were any matches.
142 // This function can ONLY be accessed from the creation thread.
143 virtual bool ContainsExtensionPrefixes(
144 const std::vector
<SBPrefix
>& prefixes
,
145 std::vector
<SBPrefix
>* prefix_hits
) = 0;
147 // Returns false unless the hash of |url| is on the side-effect free
148 // whitelist. This function is safe to call from any thread.
149 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL
& url
) = 0;
151 // Returns true iff the given IP is currently on the csd malware IP blacklist.
152 // This function is safe to call from any thread.
153 virtual bool ContainsMalwareIP(const std::string
& ip_address
) = 0;
155 // A database transaction should look like:
157 // std::vector<SBListChunkRanges> lists;
158 // if (db.UpdateStarted(&lists)) {
159 // // Do something with |lists|.
161 // // Process add/sub commands.
162 // db.InsertChunks(list_name, chunks);
164 // // Process adddel/subdel commands.
165 // db.DeleteChunks(chunks_deletes);
167 // // If passed true, processes the collected chunk info and
168 // // rebuilds the filter. If passed false, rolls everything
170 // db.UpdateFinished(success);
173 // If UpdateStarted() returns true, the caller MUST eventually call
174 // UpdateFinished(). If it returns false, the caller MUST NOT call
175 // the other functions.
176 virtual bool UpdateStarted(std::vector
<SBListChunkRanges
>* lists
) = 0;
177 virtual void InsertChunks(const std::string
& list_name
,
178 const std::vector
<SBChunkData
*>& chunks
) = 0;
179 virtual void DeleteChunks(
180 const std::vector
<SBChunkDelete
>& chunk_deletes
) = 0;
181 virtual void UpdateFinished(bool update_succeeded
) = 0;
183 // Store the results of a GetHash response. In the case of empty results, we
184 // cache the prefixes until the next update so that we don't have to issue
185 // further GetHash requests we know will be empty. This function is safe to
186 // call from any thread.
187 virtual void CacheHashResults(
188 const std::vector
<SBPrefix
>& prefixes
,
189 const std::vector
<SBFullHashResult
>& full_hits
,
190 const base::TimeDelta
& cache_lifetime
) = 0;
192 // Returns true if the malware IP blacklisting killswitch URL is present
193 // in the csd whitelist. This function is safe to call from any thread.
194 virtual bool IsMalwareIPMatchKillSwitchOn() = 0;
196 // Returns true if the whitelist killswitch URL is present in the csd
197 // whitelist. This function is safe to call from any thread.
198 virtual bool IsCsdWhitelistKillSwitchOn() = 0;
200 // The name of the bloom-filter file for the given database file.
201 // NOTE(shess): OBSOLETE. Present for deleting stale files.
202 static base::FilePath
BloomFilterForFilename(
203 const base::FilePath
& db_filename
);
205 // The name of the prefix set file for the given database file.
206 static base::FilePath
PrefixSetForFilename(const base::FilePath
& db_filename
);
208 // Filename for malware and phishing URL database.
209 static base::FilePath
BrowseDBFilename(
210 const base::FilePath
& db_base_filename
);
212 // Filename for download URL and download binary hash database.
213 static base::FilePath
DownloadDBFilename(
214 const base::FilePath
& db_base_filename
);
216 // Filename for client-side phishing detection whitelist databsae.
217 static base::FilePath
CsdWhitelistDBFilename(
218 const base::FilePath
& csd_whitelist_base_filename
);
220 // Filename for download whitelist databsae.
221 static base::FilePath
DownloadWhitelistDBFilename(
222 const base::FilePath
& download_whitelist_base_filename
);
224 // Filename for the off-domain inclusion whitelist databsae.
225 static base::FilePath
InclusionWhitelistDBFilename(
226 const base::FilePath
& inclusion_whitelist_base_filename
);
228 // Filename for extension blacklist database.
229 static base::FilePath
ExtensionBlacklistDBFilename(
230 const base::FilePath
& extension_blacklist_base_filename
);
232 // Filename for side-effect free whitelist database.
233 static base::FilePath
SideEffectFreeWhitelistDBFilename(
234 const base::FilePath
& side_effect_free_whitelist_base_filename
);
236 // Filename for the csd malware IP blacklist database.
237 static base::FilePath
IpBlacklistDBFilename(
238 const base::FilePath
& ip_blacklist_base_filename
);
240 // Filename for the unwanted software blacklist database.
241 static base::FilePath
UnwantedSoftwareDBFilename(
242 const base::FilePath
& db_filename
);
244 // Get the prefixes matching the download |urls|.
245 static void GetDownloadUrlPrefixes(const std::vector
<GURL
>& urls
,
246 std::vector
<SBPrefix
>* prefixes
);
248 // SafeBrowsing Database failure types for histogramming purposes. Explicitly
249 // label new values and do not re-use old values. Also make sure to reflect
250 // modifications made below in the SB2DatabaseFailure histogram enum.
252 FAILURE_DATABASE_CORRUPT
= 0,
253 FAILURE_DATABASE_CORRUPT_HANDLER
= 1,
254 FAILURE_BROWSE_DATABASE_UPDATE_BEGIN
= 2,
255 FAILURE_BROWSE_DATABASE_UPDATE_FINISH
= 3,
256 FAILURE_DATABASE_FILTER_MISSING_OBSOLETE
= 4,
257 FAILURE_DATABASE_FILTER_READ_OBSOLETE
= 5,
258 FAILURE_DATABASE_FILTER_WRITE_OBSOLETE
= 6,
259 FAILURE_DATABASE_FILTER_DELETE
= 7,
260 FAILURE_DATABASE_STORE_MISSING
= 8,
261 FAILURE_DATABASE_STORE_DELETE
= 9,
262 FAILURE_DOWNLOAD_DATABASE_UPDATE_BEGIN
= 10,
263 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH
= 11,
264 FAILURE_WHITELIST_DATABASE_UPDATE_BEGIN
= 12,
265 FAILURE_WHITELIST_DATABASE_UPDATE_FINISH
= 13,
266 FAILURE_BROWSE_PREFIX_SET_READ
= 14,
267 FAILURE_BROWSE_PREFIX_SET_WRITE
= 15,
268 FAILURE_BROWSE_PREFIX_SET_DELETE
= 16,
269 FAILURE_EXTENSION_BLACKLIST_UPDATE_BEGIN
= 17,
270 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH
= 18,
271 FAILURE_EXTENSION_BLACKLIST_DELETE
= 19,
272 FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_BEGIN
= 20,
273 FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH
= 21,
274 FAILURE_SIDE_EFFECT_FREE_WHITELIST_DELETE
= 22,
275 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ
= 23,
276 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE
= 24,
277 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_DELETE
= 25,
278 FAILURE_IP_BLACKLIST_UPDATE_BEGIN
= 26,
279 FAILURE_IP_BLACKLIST_UPDATE_FINISH
= 27,
280 FAILURE_IP_BLACKLIST_UPDATE_INVALID
= 28,
281 FAILURE_IP_BLACKLIST_DELETE
= 29,
282 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_BEGIN
= 30,
283 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH
= 31,
284 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_READ
= 32,
285 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE
= 33,
286 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE
= 34,
288 // Memory space for histograms is determined by the max. ALWAYS
289 // ADD NEW VALUES BEFORE THIS ONE.
293 static void RecordFailure(FailureType failure_type
);
296 // The factory used to instantiate a SafeBrowsingDatabase object.
297 // Useful for tests, so they can provide their own implementation of
298 // SafeBrowsingDatabase.
299 static SafeBrowsingDatabaseFactory
* factory_
;
302 class SafeBrowsingDatabaseNew
: public SafeBrowsingDatabase
{
304 // Create a database with the stores below. Takes ownership of all store
305 // objects handed to this constructor. Ignores all future operations on lists
306 // for which the store is initialized to NULL.
307 SafeBrowsingDatabaseNew(
308 const scoped_refptr
<base::SequencedTaskRunner
>& db_task_runner
,
309 SafeBrowsingStore
* browse_store
,
310 SafeBrowsingStore
* download_store
,
311 SafeBrowsingStore
* csd_whitelist_store
,
312 SafeBrowsingStore
* download_whitelist_store
,
313 SafeBrowsingStore
* inclusion_whitelist_store
,
314 SafeBrowsingStore
* extension_blacklist_store
,
315 SafeBrowsingStore
* side_effect_free_whitelist_store
,
316 SafeBrowsingStore
* ip_blacklist_store
,
317 SafeBrowsingStore
* unwanted_software_store
);
319 ~SafeBrowsingDatabaseNew() override
;
321 // Implement SafeBrowsingDatabase interface.
322 void Init(const base::FilePath
& filename
) override
;
323 bool ResetDatabase() override
;
324 bool ContainsBrowseUrl(const GURL
& url
,
325 std::vector
<SBPrefix
>* prefix_hits
,
326 std::vector
<SBFullHashResult
>* cache_hits
) override
;
327 bool ContainsUnwantedSoftwareUrl(
329 std::vector
<SBPrefix
>* prefix_hits
,
330 std::vector
<SBFullHashResult
>* cache_hits
) override
;
331 bool ContainsDownloadUrlPrefixes(const std::vector
<SBPrefix
>& prefixes
,
332 std::vector
<SBPrefix
>* prefix_hits
) override
;
333 bool ContainsCsdWhitelistedUrl(const GURL
& url
) override
;
334 bool ContainsDownloadWhitelistedUrl(const GURL
& url
) override
;
335 bool ContainsDownloadWhitelistedString(const std::string
& str
) override
;
336 bool ContainsInclusionWhitelistedUrl(const GURL
& url
) override
;
337 bool ContainsExtensionPrefixes(const std::vector
<SBPrefix
>& prefixes
,
338 std::vector
<SBPrefix
>* prefix_hits
) override
;
339 bool ContainsSideEffectFreeWhitelistUrl(const GURL
& url
) override
;
340 bool ContainsMalwareIP(const std::string
& ip_address
) override
;
341 bool UpdateStarted(std::vector
<SBListChunkRanges
>* lists
) override
;
342 void InsertChunks(const std::string
& list_name
,
343 const std::vector
<SBChunkData
*>& chunks
) override
;
344 void DeleteChunks(const std::vector
<SBChunkDelete
>& chunk_deletes
) override
;
345 void UpdateFinished(bool update_succeeded
) override
;
346 void CacheHashResults(const std::vector
<SBPrefix
>& prefixes
,
347 const std::vector
<SBFullHashResult
>& full_hits
,
348 const base::TimeDelta
& cache_lifetime
) override
;
350 // Returns the value of malware_kill_switch_;
351 bool IsMalwareIPMatchKillSwitchOn() override
;
353 // Returns true if the CSD whitelist has everything whitelisted.
354 bool IsCsdWhitelistKillSwitchOn() override
;
357 friend class SafeBrowsingDatabaseTest
;
358 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseTest
, HashCaching
);
359 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseTest
, CachedFullMiss
);
360 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseTest
, CachedPrefixHitFullMiss
);
361 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseTest
, BrowseFullHashMatching
);
362 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseTest
,
363 BrowseFullHashAndPrefixMatching
);
365 // A SafeBrowsing whitelist contains a list of whitelisted full-hashes (stored
366 // in a sorted vector) as well as a boolean flag indicating whether all
367 // lookups in the whitelist should be considered matches for safety.
368 typedef std::pair
<std::vector
<SBFullHash
>, bool> SBWhitelist
;
370 // This map holds a csd malware IP blacklist which maps a prefix mask
371 // to a set of hashed blacklisted IP prefixes. Each IP prefix is a hashed
372 // IPv6 IP prefix using SHA-1.
373 typedef std::map
<std::string
, base::hash_set
<std::string
> > IPBlacklist
;
375 typedef std::map
<SBPrefix
, SBCachedFullHashResult
> PrefixGetHashCache
;
377 // The ThreadSafeStateManager holds the SafeBrowsingDatabase's state which
378 // must be accessed in a thread-safe fashion. It must be constructed on the
379 // SafeBrowsingDatabaseManager's main thread. The main thread will then be the
380 // only thread on which this state can be modified; allowing for unlocked
381 // reads on the main thread and thus avoiding contention while performing
382 // intensive operations such as writing that state to disk. The state can only
383 // be accessed via (Read|Write)Transactions obtained through this class which
384 // will automatically handle thread-safety.
385 class ThreadSafeStateManager
{
387 // Identifiers for stores held by the ThreadSafeStateManager. Allows helper
388 // methods to start a transaction themselves and keep it as short as
389 // possible rather than force callers to start the transaction early to pass
390 // a store pointer to the said helper methods.
391 enum class SBWhitelistId
{
396 enum class PrefixSetId
{
398 SIDE_EFFECT_FREE_WHITELIST
,
402 // Obtained through BeginReadTransaction(NoLockOnMainTaskRunner)?(): a
403 // ReadTransaction allows read-only observations of the
404 // ThreadSafeStateManager's state. The |prefix_gethash_cache_| has a special
405 // allowance to be writable from a ReadTransaction but can't benefit from
406 // unlocked ReadTransactions. ReadTransaction should be held for the
407 // shortest amount of time possible (e.g., release it before computing final
408 // results if possible).
409 class ReadTransaction
;
411 // Obtained through BeginWriteTransaction(): a WriteTransaction allows
412 // modification of the ThreadSafeStateManager's state. It should be used for
413 // the shortest amount of time possible (e.g., pre-compute the new state
414 // before grabbing a WriteTransaction to swap it in atomically).
415 class WriteTransaction
;
417 explicit ThreadSafeStateManager(
418 const scoped_refptr
<const base::SequencedTaskRunner
>& db_task_runner
);
419 ~ThreadSafeStateManager();
421 scoped_ptr
<ReadTransaction
> BeginReadTransaction();
422 scoped_ptr
<ReadTransaction
> BeginReadTransactionNoLockOnMainTaskRunner();
423 scoped_ptr
<WriteTransaction
> BeginWriteTransaction();
426 // The sequenced task runner for this object, used to verify that its state
427 // is only ever accessed from the runner.
428 scoped_refptr
<const base::SequencedTaskRunner
> db_task_runner_
;
430 // Lock for protecting access to this class' state.
431 mutable base::Lock lock_
;
433 SBWhitelist csd_whitelist_
;
434 SBWhitelist download_whitelist_
;
435 SBWhitelist inclusion_whitelist_
;
437 // The IP blacklist should be small. At most a couple hundred IPs.
438 IPBlacklist ip_blacklist_
;
440 // PrefixSets to speed up lookups for particularly large lists. The
441 // PrefixSet themselves are never modified, instead a new one is swapped in
443 scoped_ptr
<const safe_browsing::PrefixSet
> browse_prefix_set_
;
444 scoped_ptr
<const safe_browsing::PrefixSet
>
445 side_effect_free_whitelist_prefix_set_
;
446 scoped_ptr
<const safe_browsing::PrefixSet
> unwanted_software_prefix_set_
;
448 // Cache of gethash results for prefix stores. Entries should not be used if
449 // they are older than their expire_after field. Cached misses will have
450 // empty full_hashes field. Cleared on each update. The cache is "mutable"
451 // as it can be written to from any transaction holding the lock, including
453 mutable PrefixGetHashCache prefix_gethash_cache_
;
455 DISALLOW_COPY_AND_ASSIGN(ThreadSafeStateManager
);
458 // Forward the above inner-definitions to alleviate some verbosity in the
460 using SBWhitelistId
= ThreadSafeStateManager::SBWhitelistId
;
461 using PrefixSetId
= ThreadSafeStateManager::PrefixSetId
;
462 using ReadTransaction
= ThreadSafeStateManager::ReadTransaction
;
463 using WriteTransaction
= ThreadSafeStateManager::WriteTransaction
;
465 // Manages the non-thread safe (i.e. only to be accessed to the database's
466 // main thread) state of this class.
467 class DatabaseStateManager
{
469 explicit DatabaseStateManager(
470 const scoped_refptr
<const base::SequencedTaskRunner
>& db_task_runner
);
471 ~DatabaseStateManager();
473 void init_filename_base(const base::FilePath
& filename_base
) {
474 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
475 DCHECK(filename_base_
.empty()) << "filename already initialized";
476 filename_base_
= filename_base
;
479 const base::FilePath
& filename_base() {
480 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
481 return filename_base_
;
484 void set_corruption_detected() {
485 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
486 corruption_detected_
= true;
489 void reset_corruption_detected() {
490 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
491 corruption_detected_
= false;
494 bool corruption_detected() {
495 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
496 return corruption_detected_
;
499 void set_change_detected() {
500 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
501 change_detected_
= true;
504 void reset_change_detected() {
505 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
506 change_detected_
= false;
509 bool change_detected() {
510 DCHECK(db_task_runner_
->RunsTasksOnCurrentThread());
511 return change_detected_
;
515 // The sequenced task runner for this object, used to verify that its state
516 // is only ever accessed from the runner.
517 scoped_refptr
<const base::SequencedTaskRunner
> db_task_runner_
;
519 // The base filename passed to Init(), used to generate the store and prefix
520 // set filenames used to store data on disk.
521 base::FilePath filename_base_
;
523 // Set if corruption is detected during the course of an update.
524 // Causes the update functions to fail with no side effects, until
525 // the next call to |UpdateStarted()|.
526 bool corruption_detected_
;
528 // Set to true if any chunks are added or deleted during an update.
529 // Used to optimize away database update.
530 bool change_detected_
;
532 DISALLOW_COPY_AND_ASSIGN(DatabaseStateManager
);
535 bool PrefixSetContainsUrl(const GURL
& url
,
536 PrefixSetId prefix_set_id
,
537 std::vector
<SBPrefix
>* prefix_hits
,
538 std::vector
<SBFullHashResult
>* cache_hits
);
540 // Exposed for testing of PrefixSetContainsUrlHashes() on the
541 // PrefixSet backing kMalwareList.
542 bool ContainsBrowseUrlHashesForTesting(
543 const std::vector
<SBFullHash
>& full_hashes
,
544 std::vector
<SBPrefix
>* prefix_hits
,
545 std::vector
<SBFullHashResult
>* cache_hits
);
547 bool PrefixSetContainsUrlHashes(const std::vector
<SBFullHash
>& full_hashes
,
548 PrefixSetId prefix_set_id
,
549 std::vector
<SBPrefix
>* prefix_hits
,
550 std::vector
<SBFullHashResult
>* cache_hits
);
552 // Returns true if the whitelist is disabled or if any of the given hashes
553 // matches the whitelist.
554 bool ContainsWhitelistedHashes(SBWhitelistId whitelist_id
,
555 const std::vector
<SBFullHash
>& hashes
);
557 // Return the store matching |list_id|.
558 SafeBrowsingStore
* GetStore(int list_id
);
560 // Deletes the files on disk.
563 // Load the prefix set in "|db_filename| Prefix Set" off disk, if available,
564 // and stores it in the PrefixSet identified by |prefix_set_id|.
565 // |read_failure_type| provides a caller-specific error code to be used on
566 // failure. This method should only ever be called during initialization as
567 // it performs some disk IO while holding a transaction (for the sake of
568 // avoiding uncessary back-and-forth interactions with the lock during
570 void LoadPrefixSet(const base::FilePath
& db_filename
,
571 ThreadSafeStateManager::WriteTransaction
* txn
,
572 PrefixSetId prefix_set_id
,
573 FailureType read_failure_type
);
575 // Writes the current prefix set "|db_filename| Prefix Set" on disk.
576 // |write_failure_type| provides a caller-specific error code to be used on
578 void WritePrefixSet(const base::FilePath
& db_filename
,
579 PrefixSetId prefix_set_id
,
580 FailureType write_failure_type
);
582 // Loads the given full-length hashes to the given whitelist. If the number
583 // of hashes is too large or if the kill switch URL is on the whitelist
584 // we will whitelist everything.
585 void LoadWhitelist(const std::vector
<SBAddFullHash
>& full_hashes
,
586 SBWhitelistId whitelist_id
);
588 // Parses the IP blacklist from the given full-length hashes.
589 void LoadIpBlacklist(const std::vector
<SBAddFullHash
>& full_hashes
);
591 // Helpers for handling database corruption.
592 // |OnHandleCorruptDatabase()| runs |ResetDatabase()| and sets
593 // |corruption_detected_|, |HandleCorruptDatabase()| posts
594 // |OnHandleCorruptDatabase()| to the current thread, to be run
595 // after the current task completes.
596 // TODO(shess): Wire things up to entirely abort the update
597 // transaction when this happens.
598 void HandleCorruptDatabase();
599 void OnHandleCorruptDatabase();
601 // Helpers for InsertChunks().
602 void InsertAddChunk(SafeBrowsingStore
* store
,
603 safe_browsing_util::ListType list_id
,
604 const SBChunkData
& chunk
);
605 void InsertSubChunk(SafeBrowsingStore
* store
,
606 safe_browsing_util::ListType list_id
,
607 const SBChunkData
& chunk
);
609 // Updates the |store| and stores the result on disk under |store_filename|.
610 void UpdateHashPrefixStore(const base::FilePath
& store_filename
,
611 SafeBrowsingStore
* store
,
612 FailureType failure_type
);
614 // Updates a PrefixStore store for URLs (|url_store|) which is backed on disk
615 // by a "|db_filename| Prefix Set" file. Specific failure types are provided
616 // to highlight the specific store who made the initial request on failure.
617 // |store_full_hashes_in_prefix_set| dictates whether full_hashes from the
618 // |url_store| should be cached in the |prefix_set| as well.
619 void UpdatePrefixSetUrlStore(const base::FilePath
& db_filename
,
620 SafeBrowsingStore
* url_store
,
621 PrefixSetId prefix_set_id
,
622 FailureType finish_failure_type
,
623 FailureType write_failure_type
,
624 bool store_full_hashes_in_prefix_set
);
626 void UpdateUrlStore(SafeBrowsingStore
* url_store
,
627 PrefixSetId prefix_set_id
,
628 FailureType failure_type
);
630 void UpdateWhitelistStore(const base::FilePath
& store_filename
,
631 SafeBrowsingStore
* store
,
632 SBWhitelistId whitelist_id
);
633 void UpdateIpBlacklistStore();
635 // Returns a raw pointer to ThreadSafeStateManager's PrefixGetHashCache for
636 // testing. This should only be used in unit tests (where multi-threading and
637 // synchronization are not problematic).
638 PrefixGetHashCache
* GetUnsynchronizedPrefixGetHashCacheForTesting();
640 // Records a file size histogram for the database or PrefixSet backed by
642 void RecordFileSizeHistogram(const base::FilePath
& file_path
);
644 // The sequenced task runner for this object, used to verify that its state
645 // is only ever accessed from the runner and post some tasks to it.
646 scoped_refptr
<base::SequencedTaskRunner
> db_task_runner_
;
648 ThreadSafeStateManager state_manager_
;
650 DatabaseStateManager db_state_manager_
;
652 // Underlying persistent stores for chunk data:
653 // - |browse_store_|: For browsing related (phishing and malware URLs)
654 // chunks and prefixes.
655 // - |download_store_|: For download related (download URL and binary hash)
656 // chunks and prefixes.
657 // - |csd_whitelist_store_|: For the client-side phishing detection
658 // whitelist chunks and full-length hashes. This list only contains 256
660 // - |download_whitelist_store_|: For the download whitelist chunks and
661 // full-length hashes. This list only contains 256 bit hashes.
662 // - |inclusion_whitelist_store_|: For the inclusion whitelist. Same format
663 // as |download_whitelist_store_|.
664 // - |extension_blacklist_store_|: For extension IDs.
665 // - |side_effect_free_whitelist_store_|: For side-effect free whitelist.
666 // - |ip_blacklist_store_|: For IP blacklist.
667 // - |unwanted_software_store_|: For unwanted software list (format
668 // identical to browsing lists).
670 // The stores themselves will be modified throughout the existence of this
671 // database, but shouldn't ever be swapped out (hence the const scoped_ptr --
672 // which could be swapped for C++11's std::optional when that's available).
673 // They are NonThreadSafe and should thus only be accessed on the database's
674 // main thread as enforced by SafeBrowsingStoreFile's implementation.
675 const scoped_ptr
<SafeBrowsingStore
> browse_store_
;
676 const scoped_ptr
<SafeBrowsingStore
> download_store_
;
677 const scoped_ptr
<SafeBrowsingStore
> csd_whitelist_store_
;
678 const scoped_ptr
<SafeBrowsingStore
> download_whitelist_store_
;
679 const scoped_ptr
<SafeBrowsingStore
> inclusion_whitelist_store_
;
680 const scoped_ptr
<SafeBrowsingStore
> extension_blacklist_store_
;
681 const scoped_ptr
<SafeBrowsingStore
> side_effect_free_whitelist_store_
;
682 const scoped_ptr
<SafeBrowsingStore
> ip_blacklist_store_
;
683 const scoped_ptr
<SafeBrowsingStore
> unwanted_software_store_
;
685 // Used to schedule resetting the database because of corruption. This factory
686 // and the WeakPtrs it issues should only be used on the database's main
688 base::WeakPtrFactory
<SafeBrowsingDatabaseNew
> reset_factory_
;
691 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_