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
3 // found in the LICENSE file.
5 // Safe Browsing Database Manager implementation that manages a local
6 // database. This is used by Desktop Chromium.
8 #ifndef CHROME_BROWSER_SAFE_BROWSING_LOCAL_DATABASE_MANAGER_H_
9 #define CHROME_BROWSER_SAFE_BROWSING_LOCAL_DATABASE_MANAGER_H_
17 #include "base/callback.h"
18 #include "base/containers/hash_tables.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/synchronization/lock.h"
23 #include "base/time/time.h"
24 #include "chrome/browser/safe_browsing/database_manager.h"
25 #include "chrome/browser/safe_browsing/protocol_manager.h"
26 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
29 class SafeBrowsingService
;
30 class SafeBrowsingDatabase
;
33 class URLRequestContext
;
34 class URLRequestContextGetter
;
37 namespace safe_browsing
{
38 class ClientSideDetectionService
;
39 class DownloadProtectionService
;
42 // Implemetation that manages a local database on disk.
44 // Construction needs to happen on the main thread.
45 class LocalSafeBrowsingDatabaseManager
46 : public SafeBrowsingDatabaseManager
,
47 public SafeBrowsingProtocolManagerDelegate
{
49 // Bundle of SafeBrowsing state while performing a URL or hash prefix check.
50 struct SafeBrowsingCheck
{
51 // |check_type| should correspond to the type of item that is being
52 // checked, either a URL or a binary hash/URL. We store this for two
53 // purposes: to know which of Client's methods to call when a result is
54 // known, and for logging purposes. It *isn't* used to predict the response
55 // list type, that is information that the server gives us.
56 SafeBrowsingCheck(const std::vector
<GURL
>& urls
,
57 const std::vector
<SBFullHash
>& full_hashes
,
59 safe_browsing_util::ListType check_type
,
60 const std::vector
<SBThreatType
>& expected_threats
);
63 // Either |urls| or |full_hashes| is used to lookup database. |*_results|
64 // are parallel vectors containing the results. They are initialized to
65 // contain SB_THREAT_TYPE_SAFE.
66 std::vector
<GURL
> urls
;
67 std::vector
<SBThreatType
> url_results
;
68 std::vector
<std::string
> url_metadata
;
69 std::vector
<SBFullHash
> full_hashes
;
70 std::vector
<SBThreatType
> full_hash_results
;
72 SafeBrowsingDatabaseManager::Client
* client
;
74 base::TimeTicks start
; // When check was sent to SB service.
75 safe_browsing_util::ListType check_type
; // See comment in constructor.
76 std::vector
<SBThreatType
> expected_threats
;
77 std::vector
<SBPrefix
> prefix_hits
;
78 std::vector
<SBFullHashResult
> cache_hits
;
80 // Invoke one of client's callbacks with these results.
81 void OnSafeBrowsingResult();
83 // Vends weak pointers for async callbacks on the IO thread, such as
84 // timeout checks and replies from checks performed on the SB task runner.
85 // TODO(lzheng): We should consider to use this time out check
86 // for browsing too (instead of implementing in
87 // safe_browsing_resource_handler.cc).
88 scoped_ptr
<base::WeakPtrFactory
<LocalSafeBrowsingDatabaseManager
>>
92 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingCheck
);
95 // Creates the safe browsing service. Need to initialize before using.
96 explicit LocalSafeBrowsingDatabaseManager(
97 const scoped_refptr
<SafeBrowsingService
>& service
);
100 // SafeBrowsingDatabaseManager overrides
103 bool CanCheckUrl(const GURL
& url
) const override
;
105 bool CheckBrowseUrl(const GURL
& url
, Client
* client
) override
;
106 bool CheckDownloadUrl(const std::vector
<GURL
>& url_chain
,
107 Client
* client
) override
;
108 bool CheckExtensionIDs(const std::set
<std::string
>& extension_ids
,
109 Client
* client
) override
;
110 bool MatchCsdWhitelistUrl(const GURL
& url
) override
;
111 bool MatchMalwareIP(const std::string
& ip_address
) override
;
112 bool MatchDownloadWhitelistUrl(const GURL
& url
) override
;
113 bool MatchDownloadWhitelistString(const std::string
& str
) override
;
114 bool MatchInclusionWhitelistUrl(const GURL
& url
) override
;
115 bool IsMalwareKillSwitchOn() override
;
116 bool IsCsdWhitelistKillSwitchOn() override
;
117 void CancelCheck(Client
* client
) override
;
118 void StartOnIOThread() override
;
119 void StopOnIOThread(bool shutdown
) override
;
120 bool download_protection_enabled() const override
;
123 ~LocalSafeBrowsingDatabaseManager() override
;
125 // protected for tests.
126 void NotifyDatabaseUpdateFinished(bool update_succeeded
);
129 // Called on the IO thread when the SafeBrowsingProtocolManager has received
130 // the full hash results for prefix hits detected in the database.
131 void HandleGetHashResults(SafeBrowsingCheck
* check
,
132 const std::vector
<SBFullHashResult
>& full_hashes
,
133 const base::TimeDelta
& cache_lifetime
);
135 friend class base::RefCountedThreadSafe
<LocalSafeBrowsingDatabaseManager
>;
136 friend class SafeBrowsingServerTest
;
137 friend class SafeBrowsingServiceTest
;
138 friend class SafeBrowsingServiceTestHelper
;
139 // TODO(nparker): Rename this test to LocalSafeBrowsingDatabaseManagerTest
140 friend class SafeBrowsingDatabaseManagerTest
;
141 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseManagerTest
,
142 GetUrlSeverestThreatType
);
143 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingDatabaseManagerTest
,
144 ServiceStopWithPendingChecks
);
146 typedef std::set
<SafeBrowsingCheck
*> CurrentChecks
;
147 typedef std::vector
<SafeBrowsingCheck
*> GetHashRequestors
;
148 typedef base::hash_map
<SBPrefix
, GetHashRequestors
> GetHashRequests
;
150 // Clients that we've queued up for checking later once the database is ready.
152 QueuedCheck(const safe_browsing_util::ListType check_type
,
155 const std::vector
<SBThreatType
>& expected_threats
,
156 const base::TimeTicks
& start
);
158 safe_browsing_util::ListType check_type
;
161 std::vector
<SBThreatType
> expected_threats
;
162 base::TimeTicks start
; // When check was queued.
165 // Return the threat type of the severest entry in |full_hashes| which matches
166 // |hash|, or SAFE if none match.
167 static SBThreatType
GetHashSeverestThreatType(
168 const SBFullHash
& hash
,
169 const std::vector
<SBFullHashResult
>& full_hashes
);
171 // Given a URL, compare all the possible host + path full hashes to the set of
172 // provided full hashes. Returns the threat type of the severest matching
173 // result from |full_hashes|, or SAFE if none match.
174 static SBThreatType
GetUrlSeverestThreatType(
176 const std::vector
<SBFullHashResult
>& full_hashes
,
179 // Called to stop operations on the io_thread. This may be called multiple
180 // times during the life of the DatabaseManager. Should be called on IO
182 void DoStopOnIOThread();
184 // Returns whether |database_| exists and is accessible.
185 bool DatabaseAvailable() const;
187 // Called on the IO thread. If the database does not exist, queues up a call
188 // on the db thread to create it. Returns whether the database is available.
190 // Note that this is only needed outside the db thread, since functions on the
191 // db thread can call GetDatabase() directly.
192 bool MakeDatabaseAvailable();
194 // Should only be called on db thread as SafeBrowsingDatabase is not
196 SafeBrowsingDatabase
* GetDatabase();
198 // Called on the IO thread with the check result.
199 void OnCheckDone(SafeBrowsingCheck
* info
);
201 // Called on the database thread to retrieve chunks.
202 void GetAllChunksFromDatabase(GetChunksCallback callback
);
204 // Called on the IO thread with the results of all chunks.
205 void OnGetAllChunksFromDatabase(const std::vector
<SBListChunkRanges
>& lists
,
207 GetChunksCallback callback
);
209 // Called on the IO thread after the database reports that it added a chunk.
210 void OnAddChunksComplete(AddChunksCallback callback
);
212 // Notification that the database is done loading its bloom filter. We may
213 // have had to queue checks until the database is ready, and if so, this
215 void DatabaseLoadComplete();
217 // Called on the database thread to add/remove chunks and host keys.
218 void AddDatabaseChunks(const std::string
& list
,
219 scoped_ptr
<ScopedVector
<SBChunkData
> > chunks
,
220 AddChunksCallback callback
);
222 void DeleteDatabaseChunks(
223 scoped_ptr
<std::vector
<SBChunkDelete
> > chunk_deletes
);
225 void NotifyClientBlockingComplete(Client
* client
, bool proceed
);
227 void DatabaseUpdateFinished(bool update_succeeded
);
229 // Called on the db thread to close the database. See CloseDatabase().
230 void OnCloseDatabase();
232 // Runs on the db thread to reset the database. We assume that resetting the
233 // database is a synchronous operation.
234 void OnResetDatabase();
236 // Internal worker function for processing full hashes.
237 void OnHandleGetHashResults(SafeBrowsingCheck
* check
,
238 const std::vector
<SBFullHashResult
>& full_hashes
);
240 // Run one check against |full_hashes|. Returns |true| if the check
241 // finds a match in |full_hashes|.
242 bool HandleOneCheck(SafeBrowsingCheck
* check
,
243 const std::vector
<SBFullHashResult
>& full_hashes
);
245 // Invoked by CheckDownloadUrl. It checks the download URL on
246 // |safe_browsing_task_runner_|.
247 std::vector
<SBPrefix
> CheckDownloadUrlOnSBThread(
248 const std::vector
<SBPrefix
>& prefixes
);
250 // The callback function when a safebrowsing check is timed out. Client will
251 // be notified that the safebrowsing check is SAFE when this happens.
252 void TimeoutCallback(SafeBrowsingCheck
* check
);
254 // Calls the Client's callback on IO thread after CheckDownloadUrl finishes.
255 void OnAsyncCheckDone(SafeBrowsingCheck
* check
,
256 const std::vector
<SBPrefix
>& prefix_hits
);
258 // Checks all extension ID hashes on |safe_browsing_task_runner_|.
259 std::vector
<SBPrefix
> CheckExtensionIDsOnSBThread(
260 const std::vector
<SBPrefix
>& prefixes
);
262 // Helper function that calls safe browsing client and cleans up |checks_|.
263 void SafeBrowsingCheckDone(SafeBrowsingCheck
* check
);
265 // Helper function to set |check| with default values and start a safe
266 // browsing check with timeout of |timeout|. |task| will be called on
267 // success, otherwise TimeoutCallback will be called.
268 void StartSafeBrowsingCheck(
269 SafeBrowsingCheck
* check
,
270 const base::Callback
<std::vector
<SBPrefix
>(void)>& task
);
272 // SafeBrowsingProtocolManageDelegate override
273 void ResetDatabase() override
;
274 void UpdateStarted() override
;
275 void UpdateFinished(bool success
) override
;
276 void GetChunks(GetChunksCallback callback
) override
;
277 void AddChunks(const std::string
& list
,
278 scoped_ptr
<ScopedVector
<SBChunkData
>> chunks
,
279 AddChunksCallback callback
) override
;
281 scoped_ptr
<std::vector
<SBChunkDelete
>> chunk_deletes
) override
;
283 scoped_refptr
<SafeBrowsingService
> sb_service_
;
285 CurrentChecks checks_
;
287 // Used for issuing only one GetHash request for a given prefix.
288 GetHashRequests gethash_requests_
;
290 // The persistent database. We don't use a scoped_ptr because it
291 // needs to be destroyed on a different thread than this object.
292 SafeBrowsingDatabase
* database_
;
294 // Lock used to prevent possible data races due to compiler optimizations.
295 mutable base::Lock database_lock_
;
297 // Whether the service is running. 'enabled_' is used by the
298 // SafeBrowsingDatabaseManager on the IO thread during normal operations.
301 // Indicate if download_protection is enabled by command switch
302 // so we allow this feature to be exersized.
303 bool enable_download_protection_
;
305 // Indicate if client-side phishing detection whitelist should be enabled
307 bool enable_csd_whitelist_
;
309 // Indicate if the download whitelist should be enabled or not.
310 bool enable_download_whitelist_
;
312 // Indicate if the extension blacklist should be enabled.
313 bool enable_extension_blacklist_
;
315 // Indicate if the csd malware IP blacklist should be enabled.
316 bool enable_ip_blacklist_
;
318 // Indicate if the unwanted software blacklist should be enabled.
319 bool enable_unwanted_software_blacklist_
;
321 // The sequenced task runner for running safe browsing database operations.
322 scoped_refptr
<base::SequencedTaskRunner
> safe_browsing_task_runner_
;
324 // Indicates if we're currently in an update cycle.
325 bool update_in_progress_
;
327 // When true, newly fetched chunks may not in the database yet since the
328 // database is still updating.
329 bool database_update_in_progress_
;
331 // Indicates if we're in the midst of trying to close the database. If this
332 // is true, nothing on the IO thread should access the database.
333 bool closing_database_
;
335 std::deque
<QueuedCheck
> queued_checks_
;
337 // Timeout to use for safe browsing checks.
338 base::TimeDelta check_timeout_
;
340 DISALLOW_COPY_AND_ASSIGN(LocalSafeBrowsingDatabaseManager
);
341 }; // class LocalSafeBrowsingDatabaseManager
343 #endif // CHROME_BROWSER_SAFE_BROWSING_LOCAL_DATABASE_MANAGER_H_