| OLD | NEW | 
|    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |    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 |    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 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ |    5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ | 
|    6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ |    6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ | 
|    7  |    7  | 
|    8 #include <map> |    8 #include <map> | 
|    9 #include <set> |    9 #include <set> | 
|   10 #include <string> |   10 #include <string> | 
|   11 #include <vector> |   11 #include <vector> | 
|   12  |   12  | 
|   13 #include "base/containers/hash_tables.h" |   13 #include "base/containers/hash_tables.h" | 
|   14 #include "base/files/file_path.h" |   14 #include "base/files/file_path.h" | 
|   15 #include "base/gtest_prod_util.h" |   15 #include "base/gtest_prod_util.h" | 
|   16 #include "base/memory/scoped_ptr.h" |   16 #include "base/memory/scoped_ptr.h" | 
|   17 #include "base/memory/weak_ptr.h" |   17 #include "base/memory/weak_ptr.h" | 
 |   18 #include "base/sequenced_task_runner.h" | 
|   18 #include "base/synchronization/lock.h" |   19 #include "base/synchronization/lock.h" | 
|   19 #include "base/threading/thread_checker.h" |  | 
|   20 #include "base/time/time.h" |   20 #include "base/time/time.h" | 
|   21 #include "chrome/browser/safe_browsing/safe_browsing_store.h" |   21 #include "chrome/browser/safe_browsing/safe_browsing_store.h" | 
|   22  |   22  | 
|   23 namespace safe_browsing { |   23 namespace safe_browsing { | 
|   24 class PrefixSet; |   24 class PrefixSet; | 
|   25 } |   25 } | 
|   26  |   26  | 
|   27 class GURL; |   27 class GURL; | 
|   28 class SafeBrowsingDatabase; |   28 class SafeBrowsingDatabase; | 
|   29  |   29  | 
|   30 // Factory for creating SafeBrowsingDatabase. Tests implement this factory |   30 // Factory for creating SafeBrowsingDatabase. Tests implement this factory | 
|   31 // to create fake Databases for testing. |   31 // to create fake Databases for testing. | 
|   32 class SafeBrowsingDatabaseFactory { |   32 class SafeBrowsingDatabaseFactory { | 
|   33  public: |   33  public: | 
|   34   SafeBrowsingDatabaseFactory() { } |   34   SafeBrowsingDatabaseFactory() { } | 
|   35   virtual ~SafeBrowsingDatabaseFactory() { } |   35   virtual ~SafeBrowsingDatabaseFactory() { } | 
|   36   virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( |   36   virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( | 
 |   37       scoped_refptr<base::SequencedTaskRunner> db_task_runner, | 
|   37       bool enable_download_protection, |   38       bool enable_download_protection, | 
|   38       bool enable_client_side_whitelist, |   39       bool enable_client_side_whitelist, | 
|   39       bool enable_download_whitelist, |   40       bool enable_download_whitelist, | 
|   40       bool enable_extension_blacklist, |   41       bool enable_extension_blacklist, | 
|   41       bool enable_side_effect_free_whitelist, |   42       bool enable_side_effect_free_whitelist, | 
|   42       bool enable_ip_blacklist, |   43       bool enable_ip_blacklist, | 
|   43       bool enable_unwanted_software_list) = 0; |   44       bool enable_unwanted_software_list) = 0; | 
|   44  |   45  | 
|   45  private: |   46  private: | 
|   46   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactory); |   47   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactory); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   57 // as phishing by the client-side phishing detection. These on-disk databases |   58 // as phishing by the client-side phishing detection. These on-disk databases | 
|   58 // are shared among all profiles, as it doesn't contain user-specific data. This |   59 // are shared among all profiles, as it doesn't contain user-specific data. This | 
|   59 // object is not thread-safe, i.e. all its methods should be used on the same |   60 // object is not thread-safe, i.e. all its methods should be used on the same | 
|   60 // thread that it was created on, unless specified otherwise. |   61 // thread that it was created on, unless specified otherwise. | 
|   61 class SafeBrowsingDatabase { |   62 class SafeBrowsingDatabase { | 
|   62  public: |   63  public: | 
|   63   // Factory method for obtaining a SafeBrowsingDatabase implementation. |   64   // Factory method for obtaining a SafeBrowsingDatabase implementation. | 
|   64   // It is not thread safe. |   65   // It is not thread safe. | 
|   65   // The browse list and off-domain inclusion whitelist are always on; |   66   // The browse list and off-domain inclusion whitelist are always on; | 
|   66   // availability of other lists is controlled by the flags on this method. |   67   // availability of other lists is controlled by the flags on this method. | 
|   67   static SafeBrowsingDatabase* Create(bool enable_download_protection, |   68   static SafeBrowsingDatabase* Create( | 
|   68                                       bool enable_client_side_whitelist, |   69       scoped_refptr<base::SequencedTaskRunner> db_task_runner, | 
|   69                                       bool enable_download_whitelist, |   70       bool enable_download_protection, | 
|   70                                       bool enable_extension_blacklist, |   71       bool enable_client_side_whitelist, | 
|   71                                       bool side_effect_free_whitelist, |   72       bool enable_download_whitelist, | 
|   72                                       bool enable_ip_blacklist, |   73       bool enable_extension_blacklist, | 
|   73                                       bool enable_unwanted_software_list); |   74       bool side_effect_free_whitelist, | 
 |   75       bool enable_ip_blacklist, | 
 |   76       bool enable_unwanted_software_list); | 
|   74  |   77  | 
|   75   // Makes the passed |factory| the factory used to instantiate |   78   // Makes the passed |factory| the factory used to instantiate | 
|   76   // a SafeBrowsingDatabase. This is used for tests. |   79   // a SafeBrowsingDatabase. This is used for tests. | 
|   77   static void RegisterFactory(SafeBrowsingDatabaseFactory* factory) { |   80   static void RegisterFactory(SafeBrowsingDatabaseFactory* factory) { | 
|   78     factory_ = factory; |   81     factory_ = factory; | 
|   79   } |   82   } | 
|   80  |   83  | 
|   81   virtual ~SafeBrowsingDatabase(); |   84   virtual ~SafeBrowsingDatabase(); | 
|   82  |   85  | 
|   83   // Initializes the database with the given filename. |   86   // Initializes the database with the given filename. | 
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  288   // Useful for tests, so they can provide their own implementation of |  291   // Useful for tests, so they can provide their own implementation of | 
|  289   // SafeBrowsingDatabase. |  292   // SafeBrowsingDatabase. | 
|  290   static SafeBrowsingDatabaseFactory* factory_; |  293   static SafeBrowsingDatabaseFactory* factory_; | 
|  291 }; |  294 }; | 
|  292  |  295  | 
|  293 class SafeBrowsingDatabaseNew : public SafeBrowsingDatabase { |  296 class SafeBrowsingDatabaseNew : public SafeBrowsingDatabase { | 
|  294  public: |  297  public: | 
|  295   // Create a database with the stores below. Takes ownership of all store |  298   // Create a database with the stores below. Takes ownership of all store | 
|  296   // objects handed to this constructor. Ignores all future operations on lists |  299   // objects handed to this constructor. Ignores all future operations on lists | 
|  297   // for which the store is initialized to NULL. |  300   // for which the store is initialized to NULL. | 
|  298   SafeBrowsingDatabaseNew(SafeBrowsingStore* browse_store, |  301   SafeBrowsingDatabaseNew( | 
|  299                           SafeBrowsingStore* download_store, |  302       scoped_refptr<base::SequencedTaskRunner> db_task_runner, | 
|  300                           SafeBrowsingStore* csd_whitelist_store, |  303       SafeBrowsingStore* browse_store, | 
|  301                           SafeBrowsingStore* download_whitelist_store, |  304       SafeBrowsingStore* download_store, | 
|  302                           SafeBrowsingStore* inclusion_whitelist_store, |  305       SafeBrowsingStore* csd_whitelist_store, | 
|  303                           SafeBrowsingStore* extension_blacklist_store, |  306       SafeBrowsingStore* download_whitelist_store, | 
|  304                           SafeBrowsingStore* side_effect_free_whitelist_store, |  307       SafeBrowsingStore* inclusion_whitelist_store, | 
|  305                           SafeBrowsingStore* ip_blacklist_store, |  308       SafeBrowsingStore* extension_blacklist_store, | 
|  306                           SafeBrowsingStore* unwanted_software_store); |  309       SafeBrowsingStore* side_effect_free_whitelist_store, | 
|  307  |  310       SafeBrowsingStore* ip_blacklist_store, | 
|  308   // Create a database with a browse store. This is a legacy interface that |  311       SafeBrowsingStore* unwanted_software_store); | 
|  309   // useds Sqlite. |  | 
|  310   SafeBrowsingDatabaseNew(); |  | 
|  311  |  312  | 
|  312   ~SafeBrowsingDatabaseNew() override; |  313   ~SafeBrowsingDatabaseNew() override; | 
|  313  |  314  | 
|  314   // Implement SafeBrowsingDatabase interface. |  315   // Implement SafeBrowsingDatabase interface. | 
|  315   void Init(const base::FilePath& filename) override; |  316   void Init(const base::FilePath& filename) override; | 
|  316   bool ResetDatabase() override; |  317   bool ResetDatabase() override; | 
|  317   bool ContainsBrowseUrl(const GURL& url, |  318   bool ContainsBrowseUrl(const GURL& url, | 
|  318                          std::vector<SBPrefix>* prefix_hits, |  319                          std::vector<SBPrefix>* prefix_hits, | 
|  319                          std::vector<SBFullHashResult>* cache_hits) override; |  320                          std::vector<SBFullHashResult>* cache_hits) override; | 
|  320   bool ContainsUnwantedSoftwareUrl( |  321   bool ContainsUnwantedSoftwareUrl( | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  400     // shortest amount of time possible (e.g., release it before computing final |  401     // shortest amount of time possible (e.g., release it before computing final | 
|  401     // results if possible). |  402     // results if possible). | 
|  402     class ReadTransaction; |  403     class ReadTransaction; | 
|  403  |  404  | 
|  404     // Obtained through BeginWriteTransaction(): a WriteTransaction allows |  405     // Obtained through BeginWriteTransaction(): a WriteTransaction allows | 
|  405     // modification of the ThreadSafeStateManager's state. It should be used for |  406     // modification of the ThreadSafeStateManager's state. It should be used for | 
|  406     // the shortest amount of time possible (e.g., pre-compute the new state |  407     // the shortest amount of time possible (e.g., pre-compute the new state | 
|  407     // before grabbing a WriteTransaction to swap it in atomically). |  408     // before grabbing a WriteTransaction to swap it in atomically). | 
|  408     class WriteTransaction; |  409     class WriteTransaction; | 
|  409  |  410  | 
|  410     explicit ThreadSafeStateManager(const base::ThreadChecker& thread_checker); |  411     explicit ThreadSafeStateManager( | 
 |  412         scoped_refptr<base::SequencedTaskRunner> db_task_runner); | 
|  411     ~ThreadSafeStateManager(); |  413     ~ThreadSafeStateManager(); | 
|  412  |  414  | 
|  413     scoped_ptr<ReadTransaction> BeginReadTransaction(); |  415     scoped_ptr<ReadTransaction> BeginReadTransaction(); | 
|  414     scoped_ptr<ReadTransaction> BeginReadTransactionNoLockOnMainThread(); |  416     scoped_ptr<ReadTransaction> BeginReadTransactionNoLockOnMainThread(); | 
|  415     scoped_ptr<WriteTransaction> BeginWriteTransaction(); |  417     scoped_ptr<WriteTransaction> BeginWriteTransaction(); | 
|  416  |  418  | 
|  417    private: |  419    private: | 
|  418     // The SafeBrowsingDatabase's ThreadChecker, used to verify that writes are |  420     // The sequenced task runner for this object, used to verify that its state | 
|  419     // only made on its main thread. This is important as it allows reading from |  421     // is only ever accessed in sequence via the runner. | 
|  420     // the main thread without holding the lock. |  422     scoped_refptr<base::SequencedTaskRunner> db_task_runner_; | 
|  421     const base::ThreadChecker& thread_checker_; |  | 
|  422  |  423  | 
|  423     // Lock for protecting access to this class' state. |  424     // Lock for protecting access to this class' state. | 
|  424     mutable base::Lock lock_; |  425     mutable base::Lock lock_; | 
|  425  |  426  | 
|  426     SBWhitelist csd_whitelist_; |  427     SBWhitelist csd_whitelist_; | 
|  427     SBWhitelist download_whitelist_; |  428     SBWhitelist download_whitelist_; | 
|  428     SBWhitelist inclusion_whitelist_; |  429     SBWhitelist inclusion_whitelist_; | 
|  429  |  430  | 
|  430     // The IP blacklist should be small.  At most a couple hundred IPs. |  431     // The IP blacklist should be small.  At most a couple hundred IPs. | 
|  431     IPBlacklist ip_blacklist_; |  432     IPBlacklist ip_blacklist_; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  452   // impl. |  453   // impl. | 
|  453   using SBWhitelistId = ThreadSafeStateManager::SBWhitelistId; |  454   using SBWhitelistId = ThreadSafeStateManager::SBWhitelistId; | 
|  454   using PrefixSetId = ThreadSafeStateManager::PrefixSetId; |  455   using PrefixSetId = ThreadSafeStateManager::PrefixSetId; | 
|  455   using ReadTransaction = ThreadSafeStateManager::ReadTransaction; |  456   using ReadTransaction = ThreadSafeStateManager::ReadTransaction; | 
|  456   using WriteTransaction = ThreadSafeStateManager::WriteTransaction; |  457   using WriteTransaction = ThreadSafeStateManager::WriteTransaction; | 
|  457  |  458  | 
|  458   // Manages the non-thread safe (i.e. only to be accessed to the database's |  459   // Manages the non-thread safe (i.e. only to be accessed to the database's | 
|  459   // main thread) state of this class. |  460   // main thread) state of this class. | 
|  460   class DatabaseStateManager { |  461   class DatabaseStateManager { | 
|  461    public: |  462    public: | 
|  462     explicit DatabaseStateManager(const base::ThreadChecker& thread_checker) |  463     explicit DatabaseStateManager( | 
|  463         : thread_checker_(thread_checker), |  464         scoped_refptr<base::SequencedTaskRunner> db_task_runner); | 
|  464           corruption_detected_(false), |  465     ~DatabaseStateManager(); | 
|  465           change_detected_(false) {} |  | 
|  466  |  466  | 
|  467     void init_filename_base(const base::FilePath& filename_base) { |  467     void init_filename_base(const base::FilePath& filename_base) { | 
|  468       DCHECK(thread_checker_.CalledOnValidThread()); |  468       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  469       DCHECK(filename_base_.empty()) << "filename already initialized"; |  469       DCHECK(filename_base_.empty()) << "filename already initialized"; | 
|  470       filename_base_ = filename_base; |  470       filename_base_ = filename_base; | 
|  471     } |  471     } | 
|  472  |  472  | 
|  473     const base::FilePath& filename_base() { |  473     const base::FilePath& filename_base() { | 
|  474       DCHECK(thread_checker_.CalledOnValidThread()); |  474       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  475       return filename_base_; |  475       return filename_base_; | 
|  476     } |  476     } | 
|  477  |  477  | 
|  478     void set_corruption_detected() { |  478     void set_corruption_detected() { | 
|  479       DCHECK(thread_checker_.CalledOnValidThread()); |  479       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  480       corruption_detected_ = true; |  480       corruption_detected_ = true; | 
|  481     } |  481     } | 
|  482  |  482  | 
|  483     void reset_corruption_detected() { |  483     void reset_corruption_detected() { | 
|  484       DCHECK(thread_checker_.CalledOnValidThread()); |  484       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  485       corruption_detected_ = false; |  485       corruption_detected_ = false; | 
|  486     } |  486     } | 
|  487  |  487  | 
|  488     bool corruption_detected() { |  488     bool corruption_detected() { | 
|  489       DCHECK(thread_checker_.CalledOnValidThread()); |  489       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  490       return corruption_detected_; |  490       return corruption_detected_; | 
|  491     } |  491     } | 
|  492  |  492  | 
|  493     void set_change_detected() { |  493     void set_change_detected() { | 
|  494       DCHECK(thread_checker_.CalledOnValidThread()); |  494       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  495       change_detected_ = true; |  495       change_detected_ = true; | 
|  496     } |  496     } | 
|  497  |  497  | 
|  498     void reset_change_detected() { |  498     void reset_change_detected() { | 
|  499       DCHECK(thread_checker_.CalledOnValidThread()); |  499       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  500       change_detected_ = false; |  500       change_detected_ = false; | 
|  501     } |  501     } | 
|  502  |  502  | 
|  503     bool change_detected() { |  503     bool change_detected() { | 
|  504       DCHECK(thread_checker_.CalledOnValidThread()); |  504       DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); | 
|  505       return change_detected_; |  505       return change_detected_; | 
|  506     } |  506     } | 
|  507  |  507  | 
|  508    private: |  508    private: | 
|  509     // The SafeBrowsingDatabase's ThreadChecker, used to verify that this class' |  509     // The sequenced task runner for this object, used to verify that its state | 
|  510     // state is only ever accessed from the database's main thread. |  510     // is only ever accessed in sequence via the runner. | 
|  511     const base::ThreadChecker& thread_checker_; |  511     scoped_refptr<base::SequencedTaskRunner> db_task_runner_; | 
|  512  |  512  | 
|  513     // The base filename passed to Init(), used to generate the store and prefix |  513     // The base filename passed to Init(), used to generate the store and prefix | 
|  514     // set filenames used to store data on disk. |  514     // set filenames used to store data on disk. | 
|  515     base::FilePath filename_base_; |  515     base::FilePath filename_base_; | 
|  516  |  516  | 
|  517     // Set if corruption is detected during the course of an update. |  517     // Set if corruption is detected during the course of an update. | 
|  518     // Causes the update functions to fail with no side effects, until |  518     // Causes the update functions to fail with no side effects, until | 
|  519     // the next call to |UpdateStarted()|. |  519     // the next call to |UpdateStarted()|. | 
|  520     bool corruption_detected_; |  520     bool corruption_detected_; | 
|  521  |  521  | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  628  |  628  | 
|  629   // Returns a raw pointer to ThreadSafeStateManager's PrefixGetHashCache for |  629   // Returns a raw pointer to ThreadSafeStateManager's PrefixGetHashCache for | 
|  630   // testing. This should only be used in unit tests (where multi-threading and |  630   // testing. This should only be used in unit tests (where multi-threading and | 
|  631   // synchronization are not problematic). |  631   // synchronization are not problematic). | 
|  632   PrefixGetHashCache* GetUnsynchronizedPrefixGetHashCacheForTesting(); |  632   PrefixGetHashCache* GetUnsynchronizedPrefixGetHashCacheForTesting(); | 
|  633  |  633  | 
|  634   // Records a file size histogram for the database or PrefixSet backed by |  634   // Records a file size histogram for the database or PrefixSet backed by | 
|  635   // |filename|. |  635   // |filename|. | 
|  636   void RecordFileSizeHistogram(const base::FilePath& file_path); |  636   void RecordFileSizeHistogram(const base::FilePath& file_path); | 
|  637  |  637  | 
|  638   base::ThreadChecker thread_checker_; |  638   // The sequenced task runner for this object, used to verify that its state | 
 |  639   // is only ever accessed in sequence via the runner. | 
 |  640   scoped_refptr<base::SequencedTaskRunner> db_task_runner_; | 
|  639  |  641  | 
|  640   ThreadSafeStateManager state_manager_; |  642   ThreadSafeStateManager state_manager_; | 
|  641  |  643  | 
|  642   DatabaseStateManager db_state_manager_; |  644   DatabaseStateManager db_state_manager_; | 
|  643  |  645  | 
|  644   // Underlying persistent stores for chunk data: |  646   // Underlying persistent stores for chunk data: | 
|  645   //   - |browse_store_|: For browsing related (phishing and malware URLs) |  647   //   - |browse_store_|: For browsing related (phishing and malware URLs) | 
|  646   //     chunks and prefixes. |  648   //     chunks and prefixes. | 
|  647   //   - |download_store_|: For download related (download URL and binary hash) |  649   //   - |download_store_|: For download related (download URL and binary hash) | 
|  648   //     chunks and prefixes. |  650   //     chunks and prefixes. | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  674   const scoped_ptr<SafeBrowsingStore> ip_blacklist_store_; |  676   const scoped_ptr<SafeBrowsingStore> ip_blacklist_store_; | 
|  675   const scoped_ptr<SafeBrowsingStore> unwanted_software_store_; |  677   const scoped_ptr<SafeBrowsingStore> unwanted_software_store_; | 
|  676  |  678  | 
|  677   // Used to schedule resetting the database because of corruption. This factory |  679   // Used to schedule resetting the database because of corruption. This factory | 
|  678   // and the WeakPtrs it issues should only be used on the database's main |  680   // and the WeakPtrs it issues should only be used on the database's main | 
|  679   // thread. |  681   // thread. | 
|  680   base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_; |  682   base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_; | 
|  681 }; |  683 }; | 
|  682  |  684  | 
|  683 #endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ |  685 #endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ | 
| OLD | NEW |