File: masked_domain_list_component_installer.cc

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 (188 lines) | stat: -rw-r--r-- 7,508 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
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/component_updater/masked_domain_list_component_installer.h"

#include <cstdint>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/path_service.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/common/chrome_paths.h"
#include "components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h"
#include "components/ip_protection/common/ip_protection_telemetry.h"
#include "components/ip_protection/common/masked_domain_list.h"
#include "components/privacy_sandbox/masked_domain_list/masked_domain_list.pb.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_client.h"
#include "mojo/public/cpp/base/proto_wrapper.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_service.mojom.h"

namespace component_updater {

namespace {

constexpr base::FilePath::CharType kDefaultMdlFileName[] =
    FILE_PATH_LITERAL("Default MDL");

constexpr base::FilePath::CharType kRegularBrowsingMdlFileName[] =
    FILE_PATH_LITERAL("Regular Browsing MDL");

bool UseFlatbuffer() {
  return base::FeatureList::IsEnabled(
      network::features::kMaskedDomainListFlatbufferImpl);
}

struct BuildFlatbufferResult {
  base::File default_mdl_file;
  uint64_t default_mdl_size = 0;
  base::File regular_browsing_mdl_file;
  uint64_t regular_browsing_mdl_size = 0;
};

void BuildFlatbuffer(
    std::optional<mojo_base::ProtoWrapper> masked_domain_list) {
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock()},
      // Build the flatbuffer file in a thread, as it does some CPU-intensive
      // processing and writes to disk, which can block.
      base::BindOnce(
          [](std::optional<mojo_base::ProtoWrapper> masked_domain_list)
              -> std::optional<BuildFlatbufferResult> {
            base::FilePath user_data_path;
            if (!base::PathService::Get(chrome::DIR_USER_DATA,
                                        &user_data_path)) {
              VLOG(1) << "DIR_USER_DATA does not exist";
              return std::nullopt;
            }

            base::FilePath default_mdl_file_path =
                user_data_path.Append(kDefaultMdlFileName);
            base::FilePath regular_browsing_mdl_file_path =
                user_data_path.Append(kRegularBrowsingMdlFileName);

            std::optional<masked_domain_list::MaskedDomainList> mdl =
                masked_domain_list->As<masked_domain_list::MaskedDomainList>();
            if (!mdl.has_value()) {
              VLOG(1) << "Masked Domain List was empty";
              return std::nullopt;
            }
            ip_protection::Telemetry().MdlSize(mdl->ByteSizeLong());
            const base::Time start_time = base::Time::Now();
            if (!ip_protection::MaskedDomainList::BuildFromProto(
                    *mdl, default_mdl_file_path,
                    regular_browsing_mdl_file_path)) {
              VLOG(1) << "Masked Domain List flatbuffer build failed";
              return std::nullopt;
            }
            base::UmaHistogramTimes(
                "NetworkService.IpProtection.ProxyAllowList."
                "FlatbufferBuildTime",
                base::Time::Now() - start_time);

            std::optional<int64_t> default_mdl_size =
                base::GetFileSize(default_mdl_file_path);
            if (!default_mdl_size.has_value()) {
              VLOG(1) << "Could not get size of " << default_mdl_file_path;
              return std::nullopt;
            }
            ip_protection::Telemetry().MdlEstimatedDiskUsage(*default_mdl_size);

            std::optional<int64_t> regular_browsing_mdl_size =
                base::GetFileSize(regular_browsing_mdl_file_path);
            if (!regular_browsing_mdl_size.has_value()) {
              VLOG(1) << "Could not get size of "
                      << regular_browsing_mdl_file_path;
              return std::nullopt;
            }
            ip_protection::Telemetry().MdlEstimatedDiskUsage(
                *regular_browsing_mdl_size);

            // Open the files read-only, and share those file handles to the
            // network service.
            int flags = base::File::AddFlagsForPassingToUntrustedProcess(
                base::File::Flags::FLAG_OPEN | base::File::Flags::FLAG_READ |
                base::File::Flags::FLAG_DELETE_ON_CLOSE);

            base::File default_mdl_file(default_mdl_file_path, flags);
            base::File regular_browsing_mdl_file(regular_browsing_mdl_file_path,
                                                 flags);

            BuildFlatbufferResult result{
                .default_mdl_file = std::move(default_mdl_file),
                .default_mdl_size =
                    base::checked_cast<uint64_t>(*default_mdl_size),
                .regular_browsing_mdl_file =
                    std::move(regular_browsing_mdl_file),
                .regular_browsing_mdl_size =
                    base::checked_cast<uint64_t>(*regular_browsing_mdl_size),
            };
            return result;
          },
          std::move(masked_domain_list)),
      // Call to the network service on the main thread.
      base::BindOnce([](std::optional<BuildFlatbufferResult> result) {
        if (result.has_value()) {
          content::GetNetworkService()->UpdateMaskedDomainListFlatbuffer(
              std::move(result->default_mdl_file), result->default_mdl_size,
              std::move(result->regular_browsing_mdl_file),
              result->regular_browsing_mdl_size);
        }
      }));
}

}  // namespace

void OnMaskedDomainListReady(
    base::Version version,
    std::optional<mojo_base::ProtoWrapper> masked_domain_list) {
  base::UmaHistogramBoolean(
      "NetworkService.IpProtection.ProxyAllowList."
      "UpdateSuccess",
      masked_domain_list.has_value());
  if (masked_domain_list.has_value()) {
    VLOG(1) << "Received Masked Domain List";

    if (UseFlatbuffer()) {
      BuildFlatbuffer(std::move(masked_domain_list));
    } else {
      content::GetNetworkService()->UpdateMaskedDomainList(
          std::move(masked_domain_list).value(),
          /*exclusion_list=*/std::vector<std::string>());
    }
  } else {
    VLOG(1) << "Could not read Masked Domain List file";
  }
}
void RegisterMaskedDomainListComponent(ComponentUpdateService* cus) {
  if (!MaskedDomainListComponentInstallerPolicy::IsEnabled()) {
    return;
  }

  VLOG(1) << "Registering Masked Domain List component.";

  auto policy = std::make_unique<MaskedDomainListComponentInstallerPolicy>(
      base::BindRepeating(OnMaskedDomainListReady));

  base::MakeRefCounted<ComponentInstaller>(std::move(policy),
                                           /*action_handler=*/nullptr,
                                           base::TaskPriority::USER_BLOCKING)
      ->Register(cus, base::OnceClosure());
}
}  // namespace component_updater