safe_browsing_service.h revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1// Copyright (c) 2010 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// The Safe Browsing service is responsible for downloading anti-phishing and
6// anti-malware tables and checking urls against them.
7
8#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_
9#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_
10#pragma once
11
12#include <deque>
13#include <set>
14#include <string>
15#include <vector>
16
17#include "base/hash_tables.h"
18#include "base/lock.h"
19#include "base/ref_counted.h"
20#include "base/scoped_ptr.h"
21#include "base/time.h"
22#include "chrome/browser/safe_browsing/safe_browsing_util.h"
23#include "googleurl/src/gurl.h"
24#include "webkit/glue/resource_type.h"
25
26class MalwareDetails;
27class PrefService;
28class SafeBrowsingDatabase;
29class SafeBrowsingProtocolManager;
30class SafeBrowsingServiceFactory;
31class URLRequestContextGetter;
32
33namespace base {
34class Thread;
35}
36
37// Construction needs to happen on the main thread.
38class SafeBrowsingService
39    : public base::RefCountedThreadSafe<SafeBrowsingService> {
40 public:
41  // Users of this service implement this interface to be notified
42  // asynchronously of the result.
43  enum UrlCheckResult {
44    URL_SAFE,
45    URL_PHISHING,
46    URL_MALWARE,
47    BINARY_MALWARE,  // This binary is a malware.
48  };
49
50  class Client {
51   public:
52    virtual ~Client() {}
53
54    void OnSafeBrowsingResult(const GURL& url, UrlCheckResult result) {
55      OnBrowseUrlCheckResult(url, result);
56      OnDownloadUrlCheckResult(url, result);
57      // TODO(lzheng): This is not implemented yet.
58      // OnDownloadHashCheckResult(url, result);
59    }
60
61    // Called when the user has made a decision about how to handle the
62    // SafeBrowsing interstitial page.
63    virtual void OnBlockingPageComplete(bool proceed) {}
64
65   protected:
66    // Called when the result of checking a browse URL is known.
67    virtual void OnBrowseUrlCheckResult(const GURL& url,
68                                        UrlCheckResult result) {}
69
70    // Called when the result of checking a download URL is known.
71    virtual void OnDownloadUrlCheckResult(const GURL& url,
72                                          UrlCheckResult result) {}
73
74    // Called when the result of checking a download binary hash is known.
75    virtual void OnDownloadHashCheckResult(const GURL& url,
76                                           UrlCheckResult result) {}
77  };
78
79  // Structure used to pass parameters between the IO and UI thread when
80  // interacting with the blocking page.
81  struct UnsafeResource {
82    UnsafeResource();
83    ~UnsafeResource();
84
85    GURL url;
86    GURL original_url;
87    ResourceType::Type resource_type;
88    UrlCheckResult threat_type;
89    Client* client;
90    int render_process_host_id;
91    int render_view_id;
92  };
93
94  // Bundle of SafeBrowsing state for one URL check.
95  struct SafeBrowsingCheck {
96    SafeBrowsingCheck();
97    ~SafeBrowsingCheck();
98
99    GURL url;
100    Client* client;
101    bool need_get_hash;
102    base::Time start;  // Time that check was sent to SB service.
103    UrlCheckResult result;
104    std::vector<SBPrefix> prefix_hits;
105    std::vector<SBFullHashResult> full_hits;
106
107   private:
108    DISALLOW_COPY_AND_ASSIGN(SafeBrowsingCheck);
109  };
110
111  // Makes the passed |factory| the factory used to instanciate
112  // a SafeBrowsingService. Useful for tests.
113  static void RegisterFactory(SafeBrowsingServiceFactory* factory) {
114    factory_ = factory;
115  }
116
117  // Create an instance of the safe browsing service.
118  static SafeBrowsingService* CreateSafeBrowsingService();
119
120  // Called on the UI thread to initialize the service.
121  void Initialize();
122
123  // Called on the main thread to let us know that the io_thread is going away.
124  void ShutDown();
125
126  // Returns true if the url's scheme can be checked.
127  bool CanCheckUrl(const GURL& url) const;
128
129  // Called on the IO thread to check if the given url is safe or not.  If we
130  // can synchronously determine that the url is safe, CheckUrl returns true.
131  // Otherwise it returns false, and "client" is called asynchronously with the
132  // result when it is ready.
133  virtual bool CheckBrowseUrl(const GURL& url, Client* client);
134
135  // Check if the prefix for |url| is in safebrowsing download add lists.
136  // Result will be passed to callback in |client|.
137  bool CheckDownloadUrl(const GURL& url, Client* client);
138
139  // Called on the IO thread to cancel a pending check if the result is no
140  // longer needed.
141  void CancelCheck(Client* client);
142
143  // Called on the IO thread to display an interstitial page.
144  // |url| is the url of the resource that matches a safe browsing list.
145  // If the request contained a chain of redirects, |url| is the last url
146  // in the chain, and |original_url| is the first one (the root of the
147  // chain). Otherwise, |original_url| = |url|.
148  void DisplayBlockingPage(const GURL& url,
149                           const GURL& original_url,
150                           ResourceType::Type resource_type,
151                           UrlCheckResult result,
152                           Client* client,
153                           int render_process_host_id,
154                           int render_view_id);
155
156  // Called on the IO thread when the SafeBrowsingProtocolManager has received
157  // the full hash results for prefix hits detected in the database.
158  void HandleGetHashResults(
159      SafeBrowsingCheck* check,
160      const std::vector<SBFullHashResult>& full_hashes,
161      bool can_cache);
162
163  // Called on the IO thread.
164  void HandleChunk(const std::string& list, SBChunkList* chunks);
165  void HandleChunkDelete(std::vector<SBChunkDelete>* chunk_deletes);
166
167  // Update management.  Called on the IO thread.
168  void UpdateStarted();
169  void UpdateFinished(bool update_succeeded);
170  // Whether there is an update in progress. Called on the IO thread.
171  bool IsUpdateInProgress() const;
172
173  // The blocking page on the UI thread has completed.
174  void OnBlockingPageDone(const std::vector<UnsafeResource>& resources,
175                          bool proceed);
176
177  // Called on the UI thread when the SafeBrowsingProtocolManager has received
178  // updated MAC keys.
179  void OnNewMacKeys(const std::string& client_key,
180                    const std::string& wrapped_key);
181
182  // Notification on the UI thread from the advanced options UI.
183  void OnEnable(bool enabled);
184
185  bool enabled() const { return enabled_; }
186
187  // Preference handling.
188  static void RegisterPrefs(PrefService* prefs);
189
190  // Called on the IO thread to try to close the database, freeing the memory
191  // associated with it.  The database will be automatically reopened as needed.
192  //
193  // NOTE: Actual database closure is asynchronous, and until it happens, the IO
194  // thread is not allowed to access it; may not actually trigger a close if one
195  // is already pending or doing so would cause problems.
196  void CloseDatabase();
197
198  // Called on the IO thread to reset the database.
199  void ResetDatabase();
200
201  // Log the user perceived delay caused by SafeBrowsing. This delay is the time
202  // delta starting from when we would have started reading data from the
203  // network, and ending when the SafeBrowsing check completes indicating that
204  // the current page is 'safe'.
205  void LogPauseDelay(base::TimeDelta time);
206
207  // When a safebrowsing blocking page goes away, it calls this method
208  // so the service can serialize and send MalwareDetails.
209  virtual void ReportMalwareDetails(scoped_refptr<MalwareDetails> details);
210
211 protected:
212  // Creates the safe browsing service.  Need to initialize before using.
213  SafeBrowsingService();
214
215  virtual ~SafeBrowsingService();
216
217 private:
218  friend class SafeBrowsingServiceFactoryImpl;
219
220  typedef std::set<SafeBrowsingCheck*> CurrentChecks;
221  typedef std::vector<SafeBrowsingCheck*> GetHashRequestors;
222  typedef base::hash_map<SBPrefix, GetHashRequestors> GetHashRequests;
223
224  // Used for whitelisting a render view when the user ignores our warning.
225  struct WhiteListedEntry;
226
227  // Clients that we've queued up for checking later once the database is ready.
228  struct QueuedCheck {
229    Client* client;
230    GURL url;
231    base::Time start;
232  };
233
234  friend class base::RefCountedThreadSafe<SafeBrowsingService>;
235  friend class SafeBrowsingServiceTest;
236
237  // Called to initialize objects that are used on the io_thread.
238  void OnIOInitialize(const std::string& client_key,
239                      const std::string& wrapped_key,
240                      URLRequestContextGetter* request_context_getter);
241
242  // Called to shutdown operations on the io_thread.
243  void OnIOShutdown();
244
245  // Returns whether |database_| exists and is accessible.
246  bool DatabaseAvailable() const;
247
248  // Called on the IO thread.  If the database does not exist, queues up a call
249  // on the db thread to create it.  Returns whether the database is available.
250  //
251  // Note that this is only needed outside the db thread, since functions on the
252  // db thread can call GetDatabase() directly.
253  bool MakeDatabaseAvailable();
254
255  // Should only be called on db thread as SafeBrowsingDatabase is not
256  // threadsafe.
257  SafeBrowsingDatabase* GetDatabase();
258
259  // Called on the IO thread with the check result.
260  void OnCheckDone(SafeBrowsingCheck* info);
261
262  // Called on the database thread to retrieve chunks.
263  void GetAllChunksFromDatabase();
264
265  // Called on the IO thread with the results of all chunks.
266  void OnGetAllChunksFromDatabase(const std::vector<SBListChunkRanges>& lists,
267                                  bool database_error);
268
269  // Called on the IO thread after the database reports that it added a chunk.
270  void OnChunkInserted();
271
272  // Notification that the database is done loading its bloom filter.  We may
273  // have had to queue checks until the database is ready, and if so, this
274  // checks them.
275  void DatabaseLoadComplete();
276
277  // Called on the database thread to add/remove chunks and host keys.
278  // Callee will free the data when it's done.
279  void HandleChunkForDatabase(const std::string& list,
280                              SBChunkList* chunks);
281
282  void DeleteChunks(std::vector<SBChunkDelete>* chunk_deletes);
283
284  static UrlCheckResult GetResultFromListname(const std::string& list_name);
285
286  void NotifyClientBlockingComplete(Client* client, bool proceed);
287
288  void DatabaseUpdateFinished(bool update_succeeded);
289
290  // Start up SafeBrowsing objects. This can be called at browser start, or when
291  // the user checks the "Enable SafeBrowsing" option in the Advanced options
292  // UI.
293  void Start();
294
295  // Called on the db thread to close the database.  See CloseDatabase().
296  void OnCloseDatabase();
297
298  // Runs on the db thread to reset the database. We assume that resetting the
299  // database is a synchronous operation.
300  void OnResetDatabase();
301
302  // Store in-memory the GetHash response. Runs on the database thread.
303  void CacheHashResults(const std::vector<SBPrefix>& prefixes,
304                        const std::vector<SBFullHashResult>& full_hashes);
305
306  // Internal worker function for processing full hashes.
307  void OnHandleGetHashResults(SafeBrowsingCheck* check,
308                              const std::vector<SBFullHashResult>& full_hashes);
309
310  // Run one check against |full_hashes|.  Returns |true| if the check
311  // finds a match in |full_hashes|.
312  bool HandleOneCheck(SafeBrowsingCheck* check,
313                      const std::vector<SBFullHashResult>& full_hashes);
314
315  // Invoked on the UI thread to show the blocking page.
316  void DoDisplayBlockingPage(const UnsafeResource& resource);
317
318  // As soon as we create a blocking page, we schedule this method to
319  // report hits to the malware or phishing list to the server.
320  void ReportSafeBrowsingHit(const GURL& malicious_url,
321                             const GURL& page_url,
322                             const GURL& referrer_url,
323                             bool is_subresource,
324                             UrlCheckResult threat_type);
325
326  // Invoked by CheckDownloadUrl. It checks the download URL on
327  // safe_browsing_thread_.
328  void CheckDownloadUrlOnSBThread(SafeBrowsingCheck* check);
329
330  // Call the Client's callback in IO thread after CheckDownloadUrl finishes.
331  void CheckDownloadUrlDone(SafeBrowsingCheck* check, UrlCheckResult result);
332
333  // The factory used to instanciate a SafeBrowsingService object.
334  // Useful for tests, so they can provide their own implementation of
335  // SafeBrowsingService.
336  static SafeBrowsingServiceFactory* factory_;
337
338  CurrentChecks checks_;
339
340  // Used for issuing only one GetHash request for a given prefix.
341  GetHashRequests gethash_requests_;
342
343  // The sqlite database.  We don't use a scoped_ptr because it needs to be
344  // destructed on a different thread than this object.
345  SafeBrowsingDatabase* database_;
346
347  // Lock used to prevent possible data races due to compiler optimizations.
348  mutable Lock database_lock_;
349
350  // Handles interaction with SafeBrowsing servers.
351  SafeBrowsingProtocolManager* protocol_manager_;
352
353  std::vector<WhiteListedEntry> white_listed_entries_;
354
355  // Whether the service is running. 'enabled_' is used by SafeBrowsingService
356  // on the IO thread during normal operations.
357  bool enabled_;
358
359  // Indicate if download_protection is enabled by command switch
360  // so we allow this feature to be exersized.
361  bool enable_download_protection_;
362
363  // The SafeBrowsing thread that runs database operations.
364  //
365  // Note: Functions that run on this thread should run synchronously and return
366  // to the IO thread, not post additional tasks back to this thread, lest we
367  // cause a race condition at shutdown time that leads to a database leak.
368  scoped_ptr<base::Thread> safe_browsing_thread_;
369
370  // Indicates if we're currently in an update cycle.
371  bool update_in_progress_;
372
373  // When true, newly fetched chunks may not in the database yet since the
374  // database is still updating.
375  bool database_update_in_progress_;
376
377  // Indicates if we're in the midst of trying to close the database.  If this
378  // is true, nothing on the IO thread should access the database.
379  bool closing_database_;
380
381  std::deque<QueuedCheck> queued_checks_;
382
383  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService);
384};
385
386// Factory for creating SafeBrowsingService.  Useful for tests.
387class SafeBrowsingServiceFactory {
388 public:
389  SafeBrowsingServiceFactory() { }
390  virtual ~SafeBrowsingServiceFactory() { }
391  virtual SafeBrowsingService* CreateSafeBrowsingService() = 0;
392 private:
393  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactory);
394};
395
396#endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_
397