Skip to content

Commit

Permalink
Add ComponentInstaller for Masked Domain List component.
Browse files Browse the repository at this point in the history
This component will receive a file (format TBD) that contains the
configuration for the privacy proxy that is part of IP Protection
proposal (https://developer.chrome.com/docs/privacy-sandbox/ip-protection).

This change only includes the client-side boilerplate needed to register
the component and further CLs will pipe the file's contents over to the
Network Service and make use of it. Registration is gated behind a flag
to prevent unnecessary requests for component updates at this early
stage of development.

Bug: 1415482
Change-Id: I6a25682546a424d8ccdb654b1350a0a4d72e2154
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250361
Reviewed-by: Joshua Pawlicki <waffles@chromium.org>
Commit-Queue: Alex Kallam <aakallam@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1118135}
  • Loading branch information
aakallam authored and Chromium LUCI CQ committed Mar 16, 2023
1 parent ace6e91 commit 9d51baa
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 0 deletions.
2 changes: 2 additions & 0 deletions chrome/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ static_library("browser") {
"component_updater/desktop_sharing_hub_component_remover.h",
"component_updater/first_party_sets_component_installer.cc",
"component_updater/first_party_sets_component_installer.h",
"component_updater/masked_domain_list_component_installer.cc",
"component_updater/masked_domain_list_component_installer.h",
"component_updater/mei_preload_component_installer.cc",
"component_updater/mei_preload_component_installer.h",
"component_updater/pki_metadata_component_installer.cc",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// 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 <utility>

#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/task/thread_pool.h"
#include "base/version.h"
#include "chrome/common/chrome_features.h"
#include "components/component_updater/component_installer.h"
#include "components/update_client/update_client.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using component_updater::ComponentUpdateService;

namespace {

using ListReadyRepeatingCallback = component_updater::
MaskedDomainListComponentInstallerPolicy::ListReadyRepeatingCallback;

constexpr base::FilePath::CharType kMaskedDomainListFileName[] =
FILE_PATH_LITERAL("list.json");

// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: cffplpkejcbdpfnfabnjikeicbedmifn
constexpr uint8_t kMaskedDomainListPublicKeySHA256[32] = {
0x25, 0x5f, 0xbf, 0xa4, 0x92, 0x13, 0xf5, 0xd5, 0x01, 0xd9, 0x8a,
0x48, 0x21, 0x43, 0xc8, 0x5d, 0x5c, 0x49, 0x4f, 0xdc, 0xa9, 0x31,
0xba, 0x61, 0x1d, 0x2e, 0xe0, 0x0e, 0x26, 0x76, 0x03, 0xf9};

constexpr char kMaskedDomainListManifestName[] = "Masked Domain List";

constexpr base::FilePath::CharType kMaskedDomainListRelativeInstallDir[] =
FILE_PATH_LITERAL("MaskedDomainListPreloaded");

base::File OpenFile(const base::FilePath& pb_path) {
return base::File(pb_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
}

bool IsMaskedDomainListEnabled() {
// TODO(aakallam): move this to a more accessible location.
return base::FeatureList::IsEnabled(features::kMaskedDomainList);
}

base::TaskPriority GetTaskPriority() {
return IsMaskedDomainListEnabled() ? base::TaskPriority::USER_BLOCKING
: base::TaskPriority::BEST_EFFORT;
}

} // namespace

namespace component_updater {

MaskedDomainListComponentInstallerPolicy::
MaskedDomainListComponentInstallerPolicy(
ListReadyRepeatingCallback on_list_ready)
: on_list_ready_(on_list_ready) {
CHECK(on_list_ready);
}

MaskedDomainListComponentInstallerPolicy::
~MaskedDomainListComponentInstallerPolicy() = default;

bool MaskedDomainListComponentInstallerPolicy::
SupportsGroupPolicyEnabledComponentUpdates() const {
return true;
}

bool MaskedDomainListComponentInstallerPolicy::RequiresNetworkEncryption()
const {
// Update checks and pings associated with this component do not require
// confidentiality, since the component is identical for all users.
return false;
}

update_client::CrxInstaller::Result
MaskedDomainListComponentInstallerPolicy::OnCustomInstall(
const base::Value::Dict& manifest,
const base::FilePath& install_dir) {
return update_client::CrxInstaller::Result(0); // Nothing custom here.
}

void MaskedDomainListComponentInstallerPolicy::OnCustomUninstall() {}

base::FilePath MaskedDomainListComponentInstallerPolicy::GetInstalledPath(
const base::FilePath& base) {
return base.Append(kMaskedDomainListFileName);
}

void MaskedDomainListComponentInstallerPolicy::ComponentReady(
const base::Version& version,
const base::FilePath& install_dir,
base::Value::Dict manifest) {
if (install_dir.empty() || !IsMaskedDomainListEnabled()) {
return;
}

VLOG(1) << "Masked Domain List Component ready, version "
<< version.GetString() << " in " << install_dir.value();

base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), GetTaskPriority()},
base::BindOnce(&OpenFile, GetInstalledPath(install_dir)),
base::BindOnce(on_list_ready_, version));
}

// Called during startup and installation before ComponentReady().
bool MaskedDomainListComponentInstallerPolicy::VerifyInstallation(
const base::Value::Dict& manifest,
const base::FilePath& install_dir) const {
// Actual validation will be done in the Network Service.
return base::PathExists(GetInstalledPath(install_dir));
}

base::FilePath MaskedDomainListComponentInstallerPolicy::GetRelativeInstallDir()
const {
return base::FilePath(kMaskedDomainListRelativeInstallDir);
}

void MaskedDomainListComponentInstallerPolicy::GetHash(
std::vector<uint8_t>* hash) const {
hash->assign(kMaskedDomainListPublicKeySHA256,
kMaskedDomainListPublicKeySHA256 +
std::size(kMaskedDomainListPublicKeySHA256));
}

std::string MaskedDomainListComponentInstallerPolicy::GetName() const {
return kMaskedDomainListManifestName;
}

update_client::InstallerAttributes
MaskedDomainListComponentInstallerPolicy::GetInstallerAttributes() const {
return update_client::InstallerAttributes();
}

void RegisterMaskedDomainListComponent(ComponentUpdateService* cus) {
if (!IsMaskedDomainListEnabled()) {
return;
}

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

auto policy = std::make_unique<MaskedDomainListComponentInstallerPolicy>(
/*on_list_ready=*/base::BindRepeating(
[](base::Version version, base::File list_file) {
VLOG(1) << "Received Masked Domain List";
// TODO(aakallam): do something with the file
}));

base::MakeRefCounted<ComponentInstaller>(std::move(policy))
->Register(cus, base::OnceClosure(), GetTaskPriority());
}

} // namespace component_updater
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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.

#ifndef CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_

#include <stdint.h>

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

#include "base/files/file.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "base/version.h"
#include "components/component_updater/component_installer.h"

namespace base {
class FilePath;
} // namespace base

namespace component_updater {

class ComponentUpdateService;

class MaskedDomainListComponentInstallerPolicy
: public ComponentInstallerPolicy {
public:
using ListReadyRepeatingCallback =
base::RepeatingCallback<void(base::Version, base::File)>;

// |on_list_ready| will be called on the UI thread when the list is ready. It
// is exposed here for testing.
explicit MaskedDomainListComponentInstallerPolicy(
ListReadyRepeatingCallback on_list_ready);
~MaskedDomainListComponentInstallerPolicy() override;

MaskedDomainListComponentInstallerPolicy(
const MaskedDomainListComponentInstallerPolicy&) = delete;
MaskedDomainListComponentInstallerPolicy operator=(
const MaskedDomainListComponentInstallerPolicy&) = delete;

private:
FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest,
NonexistentFile);
FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest,
NonexistentFile_OnComponentReady);
FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest,
LoadsFile_OnComponentReady);
FRIEND_TEST_ALL_PREFIXES(MaskedDomainListComponentInstallerTest,
LoadsNewListWhenUpdated);

// The following methods override ComponentInstallerPolicy.
bool SupportsGroupPolicyEnabledComponentUpdates() const override;
bool RequiresNetworkEncryption() const override;
update_client::CrxInstaller::Result OnCustomInstall(
const base::Value::Dict& manifest,
const base::FilePath& install_dir) override;
void OnCustomUninstall() override;
bool VerifyInstallation(const base::Value::Dict& manifest,
const base::FilePath& install_dir) const override;
void ComponentReady(const base::Version& version,
const base::FilePath& install_dir,
base::Value::Dict manifest) override;
base::FilePath GetRelativeInstallDir() const override;
void GetHash(std::vector<uint8_t>* hash) const override;
std::string GetName() const override;
update_client::InstallerAttributes GetInstallerAttributes() const override;

static base::FilePath GetInstalledPath(const base::FilePath& base);

ListReadyRepeatingCallback on_list_ready_;
};

// Call once during startup to make the component update service aware of
// the Masked Domain List component.
void RegisterMaskedDomainListComponent(ComponentUpdateService* cus);

} // namespace component_updater

#endif // CHROME_BROWSER_COMPONENT_UPDATER_MASKED_DOMAIN_LIST_COMPONENT_INSTALLER_H_

0 comments on commit 9d51baa

Please sign in to comment.