File: files_request_handler.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (196 lines) | stat: -rw-r--r-- 7,590 bytes parent folder | download | duplicates (5)
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
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FILES_REQUEST_HANDLER_H_
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FILES_REQUEST_HANDLER_H_

#include <memory>

#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/enterprise/connectors/analysis/request_handler_base.h"
#include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h"
#include "chrome/browser/safe_browsing/cloud_content_scanning/file_opening_job.h"
#include "components/enterprise/common/proto/connectors.pb.h"
#include "components/file_access/scoped_file_access.h"

namespace safe_browsing {

class FileAnalysisRequest;
class FileOpeningJob;

}  // namespace safe_browsing

namespace enterprise_connectors {

// Handles deep scanning requests for multiple files which are specified by
// `paths_`. Files are scanned in parallel and piped to the BinaryUploadService
// `upload_service_`. On completion of the scan, `callback_` is called with the
// scanning results. After the scanning is complete, ReportWarningBypass can be
// called to report a warning bypass of all warned files.
class FilesRequestHandler : public RequestHandlerBase {
 public:
  // File information used as an input to event report functions.
  struct FileInfo {
    FileInfo();
    FileInfo(FileInfo&& other);
    ~FileInfo();

    // Hex-encoded SHA256 hash for the given file.
    std::string sha256;

    // File size in bytes. -1 represents an unknown size.
    uint64_t size = 0;

    // File mime type.
    std::string mime_type;
  };

  // Callback that informs caller of scanning verdicts for each file.
  using CompletionCallback =
      base::OnceCallback<void(std::vector<RequestHandlerResult>)>;

  // A factory function used in tests to create fake FilesRequestHandler
  // instances.
  using Factory = base::RepeatingCallback<std::unique_ptr<FilesRequestHandler>(
      ContentAnalysisInfo* content_analysis_info,
      safe_browsing::BinaryUploadService* upload_service,
      Profile* profile,
      GURL url,
      const std::string& source,
      const std::string& destination,
      const std::string& content_transfer_method,
      safe_browsing::DeepScanAccessPoint access_point,
      const std::vector<base::FilePath>& paths,
      CompletionCallback callback)>;

  // Create an instance of FilesRequestHandler. If a factory is set, it will be
  // used instead.
  // Note that `analysis_settings` is saved as const reference and not copied.
  // The calling side is responsible that `analysis_settings` is not destroyed
  // before scanning is completed.
  static std::unique_ptr<FilesRequestHandler> Create(
      ContentAnalysisInfo* content_analysis_info,
      safe_browsing::BinaryUploadService* upload_service,
      Profile* profile,
      GURL url,
      const std::string& source,
      const std::string& destination,
      const std::string& content_transfer_method,
      safe_browsing::DeepScanAccessPoint access_point,
      const std::vector<base::FilePath>& paths,
      CompletionCallback callback);

  // In tests, sets a factory function for creating fake FilesRequestHandlers.
  static void SetFactoryForTesting(Factory factory);
  static void ResetFactoryForTesting();

  ~FilesRequestHandler() override;

  void ReportWarningBypass(
      std::optional<std::u16string> user_justification) override;

 protected:
  FilesRequestHandler(ContentAnalysisInfo* content_analysis_info,
                      safe_browsing::BinaryUploadService* upload_service,
                      Profile* profile,
                      GURL url,
                      const std::string& source,
                      const std::string& destination,
                      const std::string& content_transfer_method,
                      safe_browsing::DeepScanAccessPoint access_point,
                      const std::vector<base::FilePath>& paths,
                      CompletionCallback callback);

  bool UploadDataImpl() override;

  void FileRequestCallbackForTesting(
      base::FilePath path,
      safe_browsing::BinaryUploadService::Result result,
      enterprise_connectors::ContentAnalysisResponse response);

 private:
  // Prepares an upload request for the file at `path`.  If the file
  // cannot be uploaded it will have a failure verdict added to `result_`.
  safe_browsing::FileAnalysisRequest* PrepareFileRequest(size_t index);

  // Called when the file info for `path` has been fetched. Also begins the
  // upload process.
  void OnGotFileInfo(
      std::unique_ptr<safe_browsing::BinaryUploadService::Request> request,
      size_t index,
      safe_browsing::BinaryUploadService::Result result,
      safe_browsing::BinaryUploadService::Request::Data data);

  // Called when a request is finished early without uploading it.
  // This is, e.g., called for encrypted files and responsible for posting the
  // required data to safe-browsing ui.
  void FinishRequestEarly(
      std::unique_ptr<safe_browsing::BinaryUploadService::Request> request,
      safe_browsing::BinaryUploadService::Result result);

  // Upload the request for deep scanning using the binary upload service.
  // These methods exist so they can be overridden in tests as needed.
  // The `result` argument exists as an optimization to finish the request early
  // when the result is known in advance to avoid using the upload service.
  virtual void UploadFileForDeepScanning(
      safe_browsing::BinaryUploadService::Result result,
      const base::FilePath& path,
      std::unique_ptr<safe_browsing::BinaryUploadService::Request> request);

  void FileRequestCallback(
      size_t index,
      safe_browsing::BinaryUploadService::Result result,
      enterprise_connectors::ContentAnalysisResponse response);

  void FileRequestStartCallback(
      size_t index,
      const safe_browsing::BinaryUploadService::Request& request);

  void MaybeCompleteScanRequest();

  void CreateFileOpeningJob(
      std::vector<safe_browsing::FileOpeningJob::FileOpeningTask> tasks,
      file_access::ScopedFileAccess file_access);

  // Owner of the FileOpeningJob responsible for opening files on parallel
  // threads. Always nullptr for non-file content scanning.
  std::unique_ptr<safe_browsing::FileOpeningJob> file_opening_job_;

  std::vector<base::FilePath> paths_;
  std::vector<FileInfo> file_info_;

  // The number of file scans that have completed. If more than one file is
  // requested for scanning in `data_`, each is scanned in parallel with
  // separate requests.
  size_t file_result_count_ = 0;

  std::vector<RequestHandlerResult> results_;

  // Scanning responses of files that got DLP warning verdicts.
  std::map<size_t, enterprise_connectors::ContentAnalysisResponse>
      file_warnings_;

  // This is set to true as soon as a TOO_MANY_REQUESTS response is obtained. No
  // more data should be upload for `this` at that point.
  bool throttled_ = false;

  std::string source_;
  std::string destination_;
  std::string content_transfer_method_;

  CompletionCallback callback_;

  std::vector<base::TimeTicks> start_times_;

  std::unique_ptr<file_access::ScopedFileAccess> scoped_file_access_;

  base::WeakPtrFactory<FilesRequestHandler> weak_ptr_factory_{this};
};

}  // namespace enterprise_connectors

#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FILES_REQUEST_HANDLER_H_