File: ping_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (269 lines) | stat: -rw-r--r-- 10,795 bytes parent folder | download | duplicates (6)
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SAFE_BROWSING_CORE_BROWSER_PING_MANAGER_H_
#define COMPONENTS_SAFE_BROWSING_CORE_BROWSER_PING_MANAGER_H_

// A class that reports basic safebrowsing statistics to Google's SafeBrowsing
// servers.
#include <memory>
#include <set>
#include <string>

#include "base/containers/unique_ptr_adapters.h"
#include "base/files/file_util.h"
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/sequence_bound.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/safe_browsing/core/browser/db/hit_report.h"
#include "components/safe_browsing/core/browser/db/util.h"
#include "components/safe_browsing/core/browser/safe_browsing_hats_delegate.h"
#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/gurl.h"

namespace network {
class SimpleURLLoader;
}  // namespace network

namespace safe_browsing {

class PingManager : public KeyedService {
 public:
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class ReportThreatDetailsResult {
    SUCCESS = 0,
    // There was a problem serializing the report to a string.
    SERIALIZATION_ERROR = 1,
    // The report is empty, so it is not sent.
    EMPTY_REPORT = 2,
    kMaxValue = EMPTY_REPORT,
  };

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class PersistThreatDetailsResult {
    // The task to persist the report has posted. The actual file write
    // operation may still fail.
    kPersistTaskPosted = 0,
    // There was a problem serializing the report to a string.
    kSerializationError = 1,
    // The report is empty, so it is not sent.
    kEmptyReport = 2,
    kMaxValue = kEmptyReport,
  };

  // Interface via which a client of this class can surface relevant events in
  // WebUI. All methods must be called on the UI thread.
  class WebUIDelegate {
   public:
    virtual ~WebUIDelegate() = default;

    // Track a client safe browsing report being sent.
    virtual void AddToCSBRRsSent(
        std::unique_ptr<ClientSafeBrowsingReportRequest> csbrr) = 0;

    // Track a hit report being sent.
    virtual void AddToHitReportsSent(std::unique_ptr<HitReport> hit_report) = 0;
  };

  // Helper class to read/write a report on disk.
  class Persister {
   public:
    // These values are persisted to logs. Entries should not be renumbered and
    // numeric values should never be reused.
    enum class WriteResult {
      kSuccess = 0,
      kFailedCreateDirectory = 1,
      kFailedWriteFile = 2,
      kMaxValue = kFailedWriteFile,
    };

    explicit Persister(const base::FilePath& persister_root_path);
    Persister(const Persister&) = delete;
    Persister& operator=(const Persister&) = delete;

    ~Persister() = default;

    // Writes |serialized_report| to a new file in |dir_path_|.
    void WriteReport(const std::string& serialized_report);

    // Reads all persisted reports in |dir_path_|. The reports are deleted
    // regardless of whether the read was successful or not.
    // Returns a list of string representation of the reports.
    std::vector<std::string> ReadAndDeleteReports();

   private:
    // The directory that the files will be written in.
    base::FilePath dir_path_;
  };

  explicit PingManager(
      const V4ProtocolConfig& config,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher,
      base::RepeatingCallback<bool()> get_should_fetch_access_token,
      WebUIDelegate* webui_delegate,
      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
      base::RepeatingCallback<ChromeUserPopulation()>
          get_user_population_callback,
      base::RepeatingCallback<ChromeUserPopulation::PageLoadToken(GURL)>
          get_page_load_token_callback,
      std::unique_ptr<SafeBrowsingHatsDelegate> hats_delegate,
      const base::FilePath& persister_root_path,
      base::RepeatingCallback<bool()> get_should_send_persisted_report);
  PingManager(const PingManager&) = delete;
  PingManager& operator=(const PingManager&) = delete;

  ~PingManager() override;

  // Create an instance of the safe browsing ping manager.
  static std::unique_ptr<PingManager> Create(
      const V4ProtocolConfig& config,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher,
      base::RepeatingCallback<bool()> get_should_fetch_access_token,
      WebUIDelegate* webui_delegate,
      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
      base::RepeatingCallback<ChromeUserPopulation()>
          get_user_population_callback,
      base::RepeatingCallback<ChromeUserPopulation::PageLoadToken(GURL)>
          get_page_load_token_callback,
      std::unique_ptr<SafeBrowsingHatsDelegate> hats_delegate,
      const base::FilePath& persister_root_path,
      base::RepeatingCallback<bool()> get_should_send_persisted_report);

  void OnURLLoaderComplete(network::SimpleURLLoader* source,
                           std::unique_ptr<std::string> response_body);
  void OnSafeBrowsingHitURLLoaderComplete(
      network::SimpleURLLoader* source,
      std::unique_ptr<std::string> response_body);
  void OnThreatDetailsReportURLLoaderComplete(
      network::SimpleURLLoader* source,
      bool has_access_token,
      std::unique_ptr<std::string> response_body);

  // Report to Google when a SafeBrowsing warning is shown to the user.
  // |hit_report.threat_type| should be one of the types known by
  // SafeBrowsingtHitUrl. This method will also sanitize the URLs in the report
  // before sending it.
  void ReportSafeBrowsingHit(
      std::unique_ptr<safe_browsing::HitReport> hit_report);

  // Sends a detailed threat report after performing validation, sanitizing
  // contained URLs, and adding extra details to the report. The returned object
  // provides details on whether the report was successful.
  virtual ReportThreatDetailsResult ReportThreatDetails(
      std::unique_ptr<ClientSafeBrowsingReportRequest> report);

  // Similar to |ReportThreatDetails|, but persists the report on disk and sends
  // it on next startup.
  virtual PersistThreatDetailsResult PersistThreatDetailsAndReportOnNextStartup(
      std::unique_ptr<ClientSafeBrowsingReportRequest> report);

  // Launches a survey and attaches ThreatDetails to the survey response.
  virtual void AttachThreatDetailsAndLaunchSurvey(
      std::unique_ptr<ClientSafeBrowsingReportRequest> report);

  // Only used for tests
  void SetURLLoaderFactoryForTesting(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
  void SetTokenFetcherForTesting(
      std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher);
  void SetHatsDelegateForTesting(
      std::unique_ptr<SafeBrowsingHatsDelegate> hats_delegate);
  void SetOnURLLoaderCompleteCallbackForTesting(
      base::OnceCallback<void()> callback);

 protected:
  friend class PingManagerTest;

 private:
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestSafeBrowsingHitUrl);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestThreatDetailsUrl);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestReportThreatDetails);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestReportSafeBrowsingHit);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestSanitizeHitReport);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, TestSanitizeThreatDetailsReport);

  const V4ProtocolConfig config_;

  using Reports = std::set<std::unique_ptr<network::SimpleURLLoader>,
                           base::UniquePtrComparator>;

  // Generates URL for reporting safe browsing hits.
  GURL SafeBrowsingHitUrl(safe_browsing::HitReport* hit_report) const;

  // Generates URL for reporting threat details for users who opt-in.
  GURL ThreatDetailsUrl() const;

  // Sanitizes the URLs in the client safe browsing report.
  void SanitizeThreatDetailsReport(
      safe_browsing::ClientSafeBrowsingReportRequest* report);

  // Sanitizes the URLs in the hit report.
  void SanitizeHitReport(HitReport* hit_report);

  // Once the user's access_token has been fetched by ReportThreatDetails (or
  // intentionally not fetched), attaches the token and sends the report.
  void ReportThreatDetailsOnGotAccessToken(const std::string& serialized_report,
                                           const std::string& access_token);

  // Reads persisted reports from disk.
  void ReadPersistedReports();

  // Sends `serialized_reports` to Safe Browsing.
  void OnReadPersistedReportsDone(std::vector<std::string> serialized_reports);

  // Track outstanding SafeBrowsing report fetchers for clean up.
  // We add both "hit" and "detail" fetchers in this set.
  Reports safebrowsing_reports_;

  // Used to issue network requests.
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;

  // The token fetcher used for getting access token.
  std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher_;

  // Determines whether it's relevant to fetch the access token for the user
  // based on whether they're a signed-in ESB user.
  base::RepeatingCallback<bool()> get_should_fetch_access_token_;

  // WebUIInfoSingleton extends PingManager::WebUIDelegate to enable the
  // workaround of calling methods in WebUIInfoSingleton without /core having a
  // dependency on /content.
  raw_ptr<WebUIDelegate> webui_delegate_;

  // The task runner for the UI thread.
  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;

  // Pulls the user population.
  base::RepeatingCallback<ChromeUserPopulation()> get_user_population_callback_;

  // Pulls the page load token.
  base::RepeatingCallback<ChromeUserPopulation::PageLoadToken(GURL)>
      get_page_load_token_callback_;

  // Launches HaTS surveys.
  std::unique_ptr<SafeBrowsingHatsDelegate> hats_delegate_;

  base::SequenceBound<Persister> persister_;

  // Determines whether the user has opted in to send persisted reports.
  base::RepeatingCallback<bool()> get_should_send_persisted_report_;

  // If populated, called once the URL loader completes.
  base::OnceCallback<void()> on_url_loader_complete_callback_;

  base::WeakPtrFactory<PingManager> weak_factory_{this};
};

}  // namespace safe_browsing

#endif  // COMPONENTS_SAFE_BROWSING_CORE_BROWSER_PING_MANAGER_H_