-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ComponentInstaller for Masked Domain List component.
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
Showing
8 changed files
with
415 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
chrome/browser/component_updater/masked_domain_list_component_installer.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
86 changes: 86 additions & 0 deletions
86
chrome/browser/component_updater/masked_domain_list_component_installer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_ |
Oops, something went wrong.