13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_MANAGER_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_MANAGER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A class that implements Chrome's interface with the SafeBrowsing protocol.
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The SafeBrowsingProtocolManager handles formatting and making requests of,
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and handling responses from, Google's SafeBrowsing servers. This class uses
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The SafeBrowsingProtocolParser class to do the actual parsing.
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <deque>
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/gtest_prod_util.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/hash_tables.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/safe_browsing/chunk_range.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/safe_browsing/protocol_parser.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/safe_browsing/safe_browsing_service.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/safe_browsing/safe_browsing_util.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace net {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass URLRequestStatus;
323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}  // namespace net
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(COMPILER_GCC)
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Allows us to use URLFetchers in a hash_map with gcc (MSVC is okay without
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// specifying this).
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace __gnu_cxx {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<>
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct hash<const URLFetcher*> {
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t operator()(const URLFetcher* fetcher) const {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reinterpret_cast<size_t>(fetcher);
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass SafeBrowsingProtocolManager;
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Interface of a factory to create ProtocolManager.  Useful for tests.
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass SBProtocolManagerFactory {
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SBProtocolManagerFactory() {}
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual ~SBProtocolManagerFactory() {}
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual SafeBrowsingProtocolManager* CreateProtocolManager(
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SafeBrowsingService* sb_service,
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& client_name,
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& client_key,
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& wrapped_key,
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::URLRequestContextGetter* request_context_getter,
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& info_url_prefix,
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& mackey_url_prefix,
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      bool disable_auto_update) = 0;
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DISALLOW_COPY_AND_ASSIGN(SBProtocolManagerFactory);
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SafeBrowsingProtocolManager : public URLFetcher::Delegate {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestBackOffTimes);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestChunkStrings);
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestGetHashUrl);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           TestGetHashBackOffTimes);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestMacKeyUrl);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest,
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           TestSafeBrowsingHitUrl);
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest,
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           TestMalwareDetailsUrl);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestNextChunkUrl);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestUpdateUrl);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class SafeBrowsingServiceTest;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~SafeBrowsingProtocolManager();
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Makes the passed |factory| the factory used to instantiate
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // a SafeBrowsingService. Useful for tests.
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static void RegisterFactory(SBProtocolManagerFactory* factory) {
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    factory_ = factory;
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Create an instance of the safe browsing service.
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static SafeBrowsingProtocolManager* Create(
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SafeBrowsingService* sb_service,
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& client_name,
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& client_key,
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& wrapped_key,
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::URLRequestContextGetter* request_context_getter,
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& info_url_prefix,
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const std::string& mackey_url_prefix,
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      bool disable_auto_update);
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets up the update schedule and internal state for making periodic requests
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of the SafeBrowsing service.
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void Initialize();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // URLFetcher::Delegate interface.
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnURLFetchComplete(const URLFetcher* source,
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const GURL& url,
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                  const net::URLRequestStatus& status,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  int response_code,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const ResponseCookies& cookies,
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const std::string& data);
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // API used by the SafeBrowsingService for issuing queries. When the results
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are available, SafeBrowsingService::HandleGetHashResults is called.
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void GetFullHash(SafeBrowsingService::SafeBrowsingCheck* check,
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           const std::vector<SBPrefix>& prefixes);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Forces the start of next update after |next_update_msec| in msec.
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ForceScheduleNextUpdate(int next_update_msec);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Scheduled update callback.
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void GetNextUpdate();
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called by the SafeBrowsingService when our request for a list of all chunks
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for each list is done.  If database_error is true, that means the protocol
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // manager shouldn't fetch updates since they can't be written to disk.  It
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should try again later to open the database.
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnGetChunksComplete(const std::vector<SBListChunkRanges>& list,
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           bool database_error);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called after the chunks that were parsed were inserted in the database.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnChunkInserted();
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // For UMA users we report to Google when a SafeBrowsing interstitial is shown
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // to the user.  |threat_type| should be one of the types known by
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // SafeBrowsingHitUrl.
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void ReportSafeBrowsingHit(const GURL& malicious_url,
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             const GURL& page_url,
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             const GURL& referrer_url,
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             bool is_subresource,
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             SafeBrowsingService::UrlCheckResult threat_type,
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             const std::string& post_data);
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Users can opt-in on the SafeBrowsing interstitial to send detailed
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // malware reports. |report| is the serialized report.
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void ReportMalwareDetails(const std::string& report);
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool is_initial_request() const { return initial_request_; }
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // The last time we received an update.
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::Time last_update() const { return last_update_; }
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Setter for additional_query_. To make sure the additional_query_ won't
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be changed in the middle of an update, caller (e.g.: SafeBrowsingService)
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should call this after callbacks triggered in UpdateFinished() or before
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IssueUpdateRequest().
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_additional_query(const std::string& query) {
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    additional_query_ = query;
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string& additional_query() const {
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return additional_query_;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Enumerate failures for histogramming purposes.  DO NOT CHANGE THE
1653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // ORDERING OF THESE VALUES.
1663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  enum ResultType {
1673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // 200 response code means that the server recognized the hash
1683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // prefix, while 204 is an empty response indicating that the
1693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // server did not recognize it.
1703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_STATUS_200,
1713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_STATUS_204,
1723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Subset of successful responses which returned no full hashes.
1743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // This includes the 204 case, and also 200 responses for stale
1753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // prefixes (deleted at the server but yet deleted on the client).
1763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_FULL_HASH_EMPTY,
1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Subset of successful responses for which one or more of the
1793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // full hashes matched (should lead to an interstitial).
1803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_FULL_HASH_HIT,
1813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Subset of successful responses which weren't empty and have no
1833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // matches.  It means that there was a prefix collision which was
1843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // cleared up by the full hashes.
1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_FULL_HASH_MISS,
1863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Memory space for histograms is determined by the max.  ALWAYS
1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // ADD NEW VALUES BEFORE THIS ONE.
1893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    GET_HASH_RESULT_MAX
1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  };
1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Record a GetHash result. |is_download| indicates if the get
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // hash is triggered by download related lookup.
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static void RecordGetHashResult(bool is_download,
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                  ResultType result_type);
1963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen protected:
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Constructs a SafeBrowsingProtocolManager for |sb_service| that issues
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // network requests using |request_context_getter|. When |disable_auto_update|
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // is true, protocol manager won't schedule next update until
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // ForceScheduleNextUpdate is called.
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SafeBrowsingProtocolManager(
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SafeBrowsingService* sb_service,
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& client_name,
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& client_key,
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& wrapped_key,
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::URLRequestContextGetter* request_context_getter,
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& http_url_prefix,
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& https_url_prefix,
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bool disable_auto_update);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  friend class SBProtocolManagerFactoryImpl;
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Internal API for fetching information from the SafeBrowsing servers. The
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GetHash requests are higher priority since they can block user requests
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so are handled separately.
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum SafeBrowsingRequestType {
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NO_REQUEST = 0,     // No requests in progress
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    UPDATE_REQUEST,     // Request for redirect URLs
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CHUNK_REQUEST,      // Request for a specific chunk
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GETKEY_REQUEST      // Update the client's MAC key
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Composes a URL using |prefix|, |method| (e.g.: gethash, download,
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // newkey, report), |client_name| and |version|. When not empty,
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |additional_query| is appended to the URL with an additional "&"
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // in the front.
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static std::string ComposeUrl(const std::string& prefix,
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const std::string& method,
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const std::string& client_name,
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const std::string& version,
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const std::string& additional_query);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Generates Update URL for querying about the latest set of chunk updates.
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Append "wrkey=xxx" to the URL when |use_mac| is true.
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL UpdateUrl(bool use_mac) const;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Generates GetHash request URL for retrieving full hashes.
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Append "wrkey=xxx" to the URL when |use_mac| is true.
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL GetHashUrl(bool use_mac) const;
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Generates new MAC client key request URL.
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL MacKeyUrl() const;
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Generates URL for reporting safe browsing hits for UMA users.
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  GURL SafeBrowsingHitUrl(
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const GURL& malicious_url, const GURL& page_url, const GURL& referrer_url,
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      bool is_subresource,
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      SafeBrowsingService::UrlCheckResult threat_type) const;
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Generates URL for reporting malware details for users who opt-in.
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  GURL MalwareDetailsUrl() const;
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Composes a ChunkUrl based on input string.
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL NextChunkUrl(const std::string& input) const;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the time (in milliseconds) for the next update request. If
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 'back_off' is true, the time returned will increment an error count and
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // return the appriate next time (see ScheduleNextUpdate below).
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetNextUpdateTime(bool back_off);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Worker function for calculating GetHash and Update backoff times (in
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // seconds). 'Multiplier' is doubled for each consecutive error between the
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 2nd and 5th, and 'error_count' is incremented with each call.
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetNextBackOffTime(int* error_count, int* multiplier);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Manages our update with the next allowable update time. If 'back_off_' is
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // true, we must decrease the frequency of requests of the SafeBrowsing
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // service according to section 5 of the protocol specification.
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When disable_auto_update_ is set, ScheduleNextUpdate will do nothing.
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ForceScheduleNextUpdate has to be called to trigger the update.
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ScheduleNextUpdate(bool back_off);
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sends a request for a list of chunks we should download to the SafeBrowsing
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // servers. In order to format this request, we need to send all the chunk
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // numbers for each list that we have to the server. Getting the chunk numbers
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // requires a database query (run on the database thread), and the request
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is sent upon completion of that query in OnGetChunksComplete.
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void IssueUpdateRequest();
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sends a request for a chunk to the SafeBrowsing servers.
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void IssueChunkRequest();
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gets a key from the SafeBrowsing servers for use with MAC. This should only
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be called once per client unless the server directly tells us to update.
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void IssueKeyRequest();
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Formats a string returned from the database into:
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   "list_name;a:<add_chunk_ranges>:s:<sub_chunk_ranges>:mac\n"
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static std::string FormatList(const SBListChunkRanges& list, bool use_mac);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Runs the protocol parser on received data and update the
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SafeBrowsingService with the new content. Returns 'true' on successful
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // parse, 'false' on error.
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HandleServiceResponse(const GURL& url, const char* data, int length);
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the SafeBrowsing service wants us to re-key, we clear our key state and
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // issue the request.
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void HandleReKey();
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Updates internal state for each GetHash response error, assuming that the
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // current time is |now|.
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void HandleGetHashError(const base::Time& now);
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper function for update completion.
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateFinished(bool success);
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A callback that runs if we timeout waiting for a response to an update
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // request. We use this to properly set our update state.
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateResponseTimeout();
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // The factory that controls the creation of SafeBrowsingProtocolManager.
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // This is used by tests.
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static SBProtocolManagerFactory* factory_;
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Main SafeBrowsing interface object.
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SafeBrowsingService* sb_service_;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Current active request (in case we need to cancel) for updates or chunks
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // from the SafeBrowsing service. We can only have one of these outstanding
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // at any given time unlike GetHash requests, which are tracked separately.
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<URLFetcher> request_;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The kind of request that is currently in progress.
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SafeBrowsingRequestType request_type_;
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The number of HTTP response errors, used for request backoff timing.
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int update_error_count_;
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int gethash_error_count_;
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Multipliers which double (max == 8) for each error after the second.
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int update_back_off_mult_;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int gethash_back_off_mult_;
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Multiplier between 0 and 1 to spread clients over an interval.
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  float back_off_fuzz_;
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The list for which we are make a request.
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string list_name_;
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For managing the next earliest time to query the SafeBrowsing servers for
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // updates.
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int next_update_sec_;
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::OneShotTimer<SafeBrowsingProtocolManager> update_timer_;
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All chunk requests that need to be made, along with their MAC.
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::deque<ChunkUrl> chunk_request_urls_;
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Map of GetHash requests.
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::hash_map<const URLFetcher*,
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         SafeBrowsingService::SafeBrowsingCheck*> HashRequests;
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HashRequests hash_requests_;
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The next scheduled update has special behavior for the first 2 requests.
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum UpdateRequestState {
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FIRST_REQUEST = 0,
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SECOND_REQUEST,
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NORMAL_REQUEST
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateRequestState update_state_;
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We'll attempt to get keys once per browser session if we don't already have
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // them. They are not essential to operation, but provide a layer of
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // verification.
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool initial_request_;
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // True if the service has been given an add/sub chunk but it hasn't been
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // added to the database yet.
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool chunk_pending_to_write_;
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The keys used for MAC. Empty keys mean we aren't using MAC.
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string client_key_;
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string wrapped_key_;
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The last time we successfully received an update.
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Time last_update_;
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // While in GetHash backoff, we can't make another GetHash until this time.
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Time next_gethash_time_;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Current product version sent in each request.
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string version_;
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used for measuring chunk request latency.
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Time chunk_request_start_;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tracks the size of each update (in bytes).
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int update_size_;
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Track outstanding SafeBrowsing report fetchers for clean up.
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // We add both "hit" and "detail" fetchers in this set.
389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::set<const URLFetcher*> safebrowsing_reports_;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The safe browsing client name sent in each request.
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string client_name_;
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A string that is appended to the end of URLs for download, gethash,
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // newkey, safebrowsing hits and chunk update requests.
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string additional_query_;
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The context we use to issue network requests.
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // URL prefix where browser fetches safebrowsing chunk updates, hashes, and
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // reports hits to the safebrowsing list for UMA users.
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  std::string http_url_prefix_;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // URL prefix where browser fetches MAC client key, and reports detailed
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // malware reports for users who opt-in.
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  std::string https_url_prefix_;
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When true, protocol manager will not start an update unless
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ForceScheduleNextUpdate() is called. This is set for testing purpose.
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool disable_auto_update_;
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingProtocolManager);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_MANAGER_H_
417