File: v4_update_protocol_manager.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (215 lines) | stat: -rw-r--r-- 8,478 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_
#define COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_

// A class that implements Chrome's interface with the SafeBrowsing V4 update
// protocol.
//
// The V4UpdateProtocolManager handles formatting and making requests of, and
// handling responses from, Google's SafeBrowsing servers. The purpose of this
// class is to get hash prefixes from the SB server for the given set of lists.

#include <memory>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/safe_browsing_db/safe_browsing_prefs.h"
#include "components/safe_browsing_db/safebrowsing.pb.h"
#include "components/safe_browsing_db/util.h"
#include "components/safe_browsing_db/v4_protocol_manager_util.h"
#include "net/url_request/url_fetcher_delegate.h"

class GURL;

namespace net {
class URLFetcher;
class URLRequestContextGetter;
}  // namespace net

namespace safe_browsing {

class V4UpdateProtocolManagerFactory;

// V4UpdateCallback is invoked when a scheduled update completes.
// Parameters:
//   - The vector of update response protobufs received from the server for
//     each list type.
typedef base::Callback<void(std::unique_ptr<ParsedServerResponse>)>
    V4UpdateCallback;

typedef base::Callback<ExtendedReportingLevel()> ExtendedReportingLevelCallback;

class V4UpdateProtocolManager : public net::URLFetcherDelegate,
                                public base::NonThreadSafe {
 public:
  ~V4UpdateProtocolManager() override;

  // Makes the passed |factory| the factory used to instantiate
  // a V4UpdateProtocolManager. Useful for tests.
  static void RegisterFactory(V4UpdateProtocolManagerFactory* factory) {
    factory_ = factory;
  }

  // Create an instance of the safe browsing v4 protocol manager.
  static std::unique_ptr<V4UpdateProtocolManager> Create(
      net::URLRequestContextGetter* request_context_getter,
      const V4ProtocolConfig& config,
      V4UpdateCallback update_callback,
      ExtendedReportingLevelCallback extended_reporting_level_callback);

  // net::URLFetcherDelegate interface.
  void OnURLFetchComplete(const net::URLFetcher* source) override;

  // Schedule the next update without backoff.
  void ScheduleNextUpdate(std::unique_ptr<StoreStateMap> store_state_map);

 protected:
  // Constructs a V4UpdateProtocolManager that issues network requests using
  // |request_context_getter|. It schedules updates to get the hash prefixes for
  // SafeBrowsing lists, and invoke |callback| when the results are retrieved.
  // The callback may be invoked synchronously.
  V4UpdateProtocolManager(
      net::URLRequestContextGetter* request_context_getter,
      const V4ProtocolConfig& config,
      V4UpdateCallback update_callback,
      ExtendedReportingLevelCallback extended_reporting_level_callback);

 private:
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestGetUpdatesErrorHandlingNetwork);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestGetUpdatesErrorHandlingResponseCode);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, TestGetUpdatesNoError);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestGetUpdatesWithOneBackoff);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestBase64EncodingUsesUrlEncoding);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, TestDisableAutoUpdates);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestGetUpdatesHasTimeout);
  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                           TestExtendedReportingLevelIncluded);
  friend class V4UpdateProtocolManagerFactoryImpl;

  // Fills a FetchThreatListUpdatesRequest protocol buffer for a request.
  // Returns the serialized and base64 URL encoded request as a string.
  std::string GetBase64SerializedUpdateRequestProto();

  // The method to populate |gurl| with the URL to be sent to the server.
  // |request_base64| is the base64 encoded form of an instance of the protobuf
  // FetchThreatListUpdatesRequest. Also sets the appropriate header values for
  // sending PVer4 requests in |headers|.
  void GetUpdateUrlAndHeaders(const std::string& request_base64,
                              GURL* gurl,
                              net::HttpRequestHeaders* headers) const;

  // Parses the base64 encoded response received from the server as a
  // FetchThreatListUpdatesResponse protobuf and returns each of the
  // ListUpdateResponse protobufs contained in it as a vector.
  // Returns true if parsing is successful, false otherwise.
  bool ParseUpdateResponse(const std::string& data_base64,
                           ParsedServerResponse* parsed_server_response);

  // Resets the update error counter and multiplier.
  void ResetUpdateErrors();

  // Called when update request times out. Cancels the existing request and
  // re-sends the update request.
  void HandleTimeout();

  // Updates internal update and backoff state for each update response error,
  // assuming that the current time is |now|.
  void HandleUpdateError(const base::Time& now);

  // Generates the URL for the update request and issues the request for the
  // lists passed to the constructor.
  void IssueUpdateRequest();

  // Returns whether another update is currently scheduled.
  bool IsUpdateScheduled() const;

  // Schedule the next update with backoff specified.
  void ScheduleNextUpdateWithBackoff(bool back_off);

  // Schedule the next update, after the given interval.
  void ScheduleNextUpdateAfterInterval(base::TimeDelta interval);

  // Get the next update interval, considering whether we are in backoff.
  base::TimeDelta GetNextUpdateInterval(bool back_off);

  // The factory that controls the creation of V4UpdateProtocolManager.
  // This is used by tests.
  static V4UpdateProtocolManagerFactory* factory_;

  // The last known state of the lists.
  // Updated after every successful update of the database.
  std::unique_ptr<StoreStateMap> store_state_map_;

  // The number of HTTP response errors since the the last successful HTTP
  // response, used for request backoff timing.
  size_t update_error_count_;

  // Multiplier for the backoff error after the second.
  size_t update_back_off_mult_;

  // The time delta after which the next update request may be sent.
  // It is set to a random interval between 60 and 300 seconds at start.
  // The server can set it by setting the minimum_wait_duration.
  base::TimeDelta next_update_interval_;

  // The config of the client making Pver4 requests.
  const V4ProtocolConfig config_;

  // The context we use to issue network requests.
  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;

  // ID for URLFetchers for testing.
  int url_fetcher_id_;

  // The callback that's called when GetUpdates completes.
  V4UpdateCallback update_callback_;

  // The pending update request. The request must be canceled when the object is
  // destroyed.
  std::unique_ptr<net::URLFetcher> request_;

  // Timer to setup the next update request.
  base::OneShotTimer update_timer_;

  base::Time last_response_time_;

  // Used to interrupt and re-schedule update requests that take too long to
  // complete.
  base::OneShotTimer timeout_timer_;

  ExtendedReportingLevelCallback extended_reporting_level_callback_;

  DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManager);
};

// Interface of a factory to create V4UpdateProtocolManager.  Useful for tests.
class V4UpdateProtocolManagerFactory {
 public:
  V4UpdateProtocolManagerFactory() {}
  virtual ~V4UpdateProtocolManagerFactory() {}
  virtual std::unique_ptr<V4UpdateProtocolManager> CreateProtocolManager(
      net::URLRequestContextGetter* request_context_getter,
      const V4ProtocolConfig& config,
      V4UpdateCallback update_callback,
      ExtendedReportingLevelCallback extended_reporting_level_callback) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManagerFactory);
};

}  // namespace safe_browsing

#endif  // COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_