Skip to content

Commit

Permalink
[EG] Update the EG updater to allow sideloading (#4428)
Browse files Browse the repository at this point in the history
Add h5vcc API options to skip checking if package signature matches our
key and to set a custom URL to check for package updates.

Implement the above features into the updater for non-gold builds only.

Add a stub server for serving packages.

b/325626249

Original change was reviewed here:
#3938
  • Loading branch information
TyHolc authored Dec 3, 2024
1 parent ae3ff88 commit 361ea7c
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 2 deletions.
36 changes: 35 additions & 1 deletion chrome/updater/configurator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ Configurator::Configurator(network::NetworkModule* network_module)
unzip_factory_(base::MakeRefCounted<UnzipperFactory>()),
network_fetcher_factory_(
base::MakeRefCounted<NetworkFetcherFactoryCobalt>(network_module)),
patch_factory_(base::MakeRefCounted<PatcherFactory>()) {
patch_factory_(base::MakeRefCounted<PatcherFactory>()),
allow_self_signed_packages_(false),
require_network_encryption_(true) {
LOG(INFO) << "Configurator::Configurator";
const std::string persisted_channel = persisted_data_->GetLatestChannel();
if (persisted_channel.empty()) {
Expand Down Expand Up @@ -107,6 +109,12 @@ int Configurator::UpdateDelay() const {
}

std::vector<GURL> Configurator::UpdateUrl() const {
// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (allow_self_signed_packages_ && !update_server_url_.empty()) {
return std::vector<GURL>{GURL(update_server_url_)};
}
#endif // !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
browser::switches::kUseQAUpdateServer)) {
return std::vector<GURL>{GURL(kUpdaterJSONDefaultUrlQA)};
Expand Down Expand Up @@ -369,5 +377,31 @@ void Configurator::SetUseCompressedUpdates(bool use_compressed_updates) {
use_compressed_updates_.store(use_compressed_updates);
}

bool Configurator::GetAllowSelfSignedPackages() const {
return allow_self_signed_packages_.load();
}

void Configurator::SetAllowSelfSignedPackages(bool allow_self_signed_packages) {
allow_self_signed_packages_.store(allow_self_signed_packages);
}

std::string Configurator::GetUpdateServerUrl() const {
base::AutoLock auto_lock(const_cast<base::Lock&>(update_server_url_lock_));
return update_server_url_;
}

void Configurator::SetUpdateServerUrl(const std::string& update_server_url) {
LOG(INFO) << "Configurator::SetUpdateServerUrl update_server_url=" << update_server_url;
base::AutoLock auto_lock(update_server_url_lock_);
update_server_url_ = update_server_url;
}

bool Configurator::GetRequireNetworkEncryption() const {
return require_network_encryption_.load();
}
void Configurator::SetRequireNetworkEncryption(bool require_network_encryption) {
require_network_encryption_.store(require_network_encryption);
}

} // namespace updater
} // namespace cobalt
13 changes: 13 additions & 0 deletions chrome/updater/configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ class Configurator : public update_client::Configurator {
const std::string& version,
const int sb_version);

bool GetAllowSelfSignedPackages() const override;
void SetAllowSelfSignedPackages(bool allow_self_signed_packages) override;

std::string GetUpdateServerUrl() const override;
void SetUpdateServerUrl(const std::string& update_server_url) override;

bool GetRequireNetworkEncryption() const override;
void SetRequireNetworkEncryption(bool require_network_encryption) override;

private:
friend class base::RefCountedThreadSafe<Configurator>;
~Configurator() override;
Expand All @@ -117,6 +126,10 @@ class Configurator : public update_client::Configurator {
uint64_t min_free_space_bytes_ = 48 * 1024 * 1024;
base::Lock min_free_space_bytes_lock_;
std::atomic_bool use_compressed_updates_;
std::atomic_bool allow_self_signed_packages_;
std::string update_server_url_;
base::Lock update_server_url_lock_;
std::atomic_bool require_network_encryption_;

DISALLOW_COPY_AND_ASSIGN(Configurator);
};
Expand Down
96 changes: 95 additions & 1 deletion chrome/updater/updater_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,22 @@ void UpdaterModule::Update() {
return;
}

// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're
// fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
bool skip_verify_public_key_hash = GetAllowSelfSignedPackages();
bool require_network_encryption = GetRequireNetworkEncryption();
#else
bool skip_verify_public_key_hash = false;
bool require_network_encryption = true;
#endif // defined(COBALT_BUILD_TYPE_GOLD)

update_client_->Update(
app_ids,
base::BindOnce(
[](base::Version manifest_version,
bool skip_verify_public_key_hash,
bool require_network_encryption,
const std::vector<std::string>& ids)
-> std::vector<base::Optional<update_client::CrxComponent>> {
update_client::CrxComponent component;
Expand All @@ -279,10 +291,18 @@ void UpdaterModule::Update() {
component.pk_hash.assign(std::begin(kCobaltPublicKeyHash),
std::end(kCobaltPublicKeyHash));
component.requires_network_encryption = true;
// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check
// once we're fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (skip_verify_public_key_hash) {
component.pk_hash.clear();
}
component.requires_network_encryption = require_network_encryption;
#endif // !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
component.crx_format_requirement = crx_file::VerifierFormat::CRX3;
return {component};
},
manifest_version),
manifest_version, skip_verify_public_key_hash, require_network_encryption),
false,
base::BindOnce(
[](base::OnceClosure closure, update_client::Error error) {
Expand Down Expand Up @@ -432,6 +452,80 @@ void UpdaterModule::SetUseCompressedUpdates(bool use_compressed_updates) {
config->SetUseCompressedUpdates(use_compressed_updates);
}

bool UpdaterModule::GetAllowSelfSignedPackages() const {
LOG(INFO) << "UpdaterModule::GetAllowSelfSignedPackages";
auto config = updater_configurator_;
if (!config) {
LOG(ERROR) << "UpdaterModule::GetAllowSelfSignedPackages: missing configurator";
return false;
}

bool allow_self_signed_builds = config->GetAllowSelfSignedPackages();
LOG(INFO) << "UpdaterModule::GetAllowSelfSignedPackages allow_self_signed_builds="
<< allow_self_signed_builds;
return allow_self_signed_builds;
}

void UpdaterModule::SetAllowSelfSignedPackages(bool allow_self_signed_builds) {
LOG(INFO) << "UpdaterModule::SetAllowSelfSignedPackages";
auto config = updater_configurator_;
if (!config) {
LOG(ERROR) << "UpdaterModule::SetAllowSelfSignedPackages: missing configurator";
return;
}

config->SetAllowSelfSignedPackages(allow_self_signed_builds);
}

std::string UpdaterModule::GetUpdateServerUrl() const {
LOG(INFO) << "UpdaterModule::GetUpdateServerUrl";
auto config = updater_configurator_;
if (!config) {
LOG(ERROR) << "UpdaterModule::GetUpdateServerUrl: missing configurator";
return "";
}

std::string update_server_url = config->GetUpdateServerUrl();
LOG(INFO) << "UpdaterModule::GetUpdateServerUrl update_server_url="
<< update_server_url;
return update_server_url;
}

void UpdaterModule::SetUpdateServerUrl(const std::string& update_server_url) {
LOG(INFO) << "UpdaterModule::SetUpdateServerUrl";
auto config = updater_configurator_;
if(!config) {
LOG(ERROR) << "UpdaterModule::SetUpdateServerUrl: missing configurator";
return;
}

config->SetUpdateServerUrl(update_server_url);
}

bool UpdaterModule::GetRequireNetworkEncryption() const {
LOG(INFO) << "UpdaterModule::GetRequireNetworkEncryption";
auto config = updater_configurator_;
if (!config) {
LOG(ERROR) << "UpdaterModule::GetRequireNetworkEncryption: missing configurator";
return true;
}

bool require_network_encryption = config->GetRequireNetworkEncryption();
LOG(INFO) << "UpdaterModule::GetRequireNetworkEncryption require_network_encryption="
<< require_network_encryption;
return require_network_encryption;
}

void UpdaterModule::SetRequireNetworkEncryption(bool require_network_encryption) {
LOG(INFO) << "UpdaterModule::SetRequireNetworkEncryption";
auto config = updater_configurator_;
if (!config) {
LOG(ERROR) << "UpdaterModule::SetRequireNetworkEncryption: missing configurator";
return;
}

config->SetRequireNetworkEncryption(require_network_encryption);
}

} // namespace updater
} // namespace cobalt
9 changes: 9 additions & 0 deletions chrome/updater/updater_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ class UpdaterModule {
bool GetUseCompressedUpdates() const;
void SetUseCompressedUpdates(bool use_compressed_updates);

bool GetAllowSelfSignedPackages() const;
void SetAllowSelfSignedPackages(bool allow_self_signed_packages);

std::string GetUpdateServerUrl() const;
void SetUpdateServerUrl(const std::string& update_server_url);

bool GetRequireNetworkEncryption() const;
void SetRequireNetworkEncryption(bool require_network_encryption);

void MarkSuccessful();

private:
Expand Down
54 changes: 54 additions & 0 deletions cobalt/h5vcc/h5vcc_updater.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,60 @@ void H5vccUpdater::SetUseCompressedUpdates(bool use_compressed_updates) {
return updater_module_->SetUseCompressedUpdates(use_compressed_updates);
}

bool H5vccUpdater::GetAllowSelfSignedPackages() {
if (updater_module_) {
return updater_module_->GetAllowSelfSignedPackages();
}

return false;
}

void H5vccUpdater::SetAllowSelfSignedPackages(bool allow_self_signed_packages) {
// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're
// fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (updater_module_) {
updater_module_->SetAllowSelfSignedPackages(allow_self_signed_packages);
}
#endif // !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
}

std::string H5vccUpdater::GetUpdateServerUrl() const {
if (updater_module_) {
return updater_module_->GetUpdateServerUrl();
}

return "";
}

void H5vccUpdater::SetUpdateServerUrl(const std::string& update_server_url) {
// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're
// fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (updater_module_) {
updater_module_->SetUpdateServerUrl(update_server_url);
}
#endif // !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
}

bool H5vccUpdater::GetRequireNetworkEncryption() const {
if (updater_module_) {
return updater_module_->GetRequireNetworkEncryption();
}

return false;
}

void H5vccUpdater::SetRequireNetworkEncryption(
bool require_network_encryption) {
// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're
// fully launched.
#if !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
if (updater_module_) {
updater_module_->SetRequireNetworkEncryption(require_network_encryption);
}
#endif // !defined(COBALT_BUILD_TYPE_GOLD) && ALLOW_EVERGREEN_SIDELOADING
}
#endif // SB_IS(EVERGREEN)
} // namespace h5vcc
} // namespace cobalt
9 changes: 9 additions & 0 deletions cobalt/h5vcc/h5vcc_updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ class H5vccUpdater : public script::Wrappable {
bool GetUseCompressedUpdates() const;
void SetUseCompressedUpdates(bool use_compressed_updates);

bool GetAllowSelfSignedPackages();
void SetAllowSelfSignedPackages(bool allow_self_signed_packages);

std::string GetUpdateServerUrl() const;
void SetUpdateServerUrl(const std::string& update_server_url);

bool GetRequireNetworkEncryption() const;
void SetRequireNetworkEncryption(bool require_network_encryption);

#else
H5vccUpdater() {}
#endif
Expand Down
14 changes: 14 additions & 0 deletions cobalt/h5vcc/h5vcc_updater.idl
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ interface H5vccUpdater {
// used for testing.
void setUseCompressedUpdates(boolean use_compressed_updates);

// Toggles the ability to load self-signed packages in the updater. This
// should only be used for testing and should not be available in production.
boolean getAllowSelfSignedPackages();
void setAllowSelfSignedPackages(boolean allow_self_signed_packages);

// Sets the URL the updater will use for updates. This should only be used for
// testing and should not be available in production.
DOMString getUpdateServerUrl();
void setUpdateServerUrl(DOMString update_server_url);

// Sets if network encryption is required for the update server. This should
// only be used for testing and should not be available in production.
boolean getRequireNetworkEncryption();
void setRequireNetworkEncryption(boolean require_network_encryption);
};
9 changes: 9 additions & 0 deletions components/update_client/configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,15 @@ class Configurator : public base::RefCountedThreadSafe<Configurator> {

virtual bool GetUseCompressedUpdates() const = 0;
virtual void SetUseCompressedUpdates(bool use_compressed_updates) = 0;

virtual bool GetAllowSelfSignedPackages() const = 0;
virtual void SetAllowSelfSignedPackages(bool allow_self_signed_packages) = 0;

virtual std::string GetUpdateServerUrl() const = 0;
virtual void SetUpdateServerUrl(const std::string& update_server_url) = 0;

virtual bool GetRequireNetworkEncryption() const = 0;
virtual void SetRequireNetworkEncryption(bool require_network_encryption) = 0;
#endif

protected:
Expand Down
9 changes: 9 additions & 0 deletions components/update_client/test_configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ class TestConfigurator : public Configurator {

bool GetUseCompressedUpdates() const override { return false; }
void SetUseCompressedUpdates(bool use_compressed_updates) override {}

bool GetAllowSelfSignedPackages() const override { return false; }
void SetAllowSelfSignedPackages(bool allow_self_signed_packages) override {}

std::string GetUpdateServerUrl() const override { return ""; }
void SetUpdateServerUrl(const std::string& update_server_url) override {}

bool GetRequireNetworkEncryption() const override { return true; }
void SetRequireNetworkEncryption(bool require_network_encryption) override {}
#else
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
Expand Down
4 changes: 4 additions & 0 deletions starboard/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,8 @@ struct CompileAssert {};
// longer rely on them, and operate with the assumption that their values are
// always 1.

// TODO(b/325626249): Remove the ALLOW_EVERGREEN_SIDELOADING check once we're
// fully launched.
#define ALLOW_EVERGREEN_SIDELOADING 0

#endif // STARBOARD_CONFIGURATION_H_
38 changes: 38 additions & 0 deletions tools/stub_omaha_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# server.py

from flask import Flask, jsonify, send_file
from hashlib import file_digest
from os import path

app = Flask(__name__)
file_location = '/usr/local/google/home/<path_to_crx>/cobalt.crx'
self_endpoint = 'http://127.0.0.1:5000'

@app.route('/omaha/stub/health', methods=['GET'])
def get_health():
return jsonify({'status': 'healthy'})

@app.route('/omaha/stub/update', methods=['POST'])
def post_updates():
# Get SHA256 hash of the file being served.
with open(file_location, 'rb') as f:
digest = file_digest(f, 'sha256').hexdigest()
filename = path.basename(f.name)

# Populate the JSON response with required fields.
update = {'response':{'protocol':'3.1','app':[{'appid':'{A9557415-DDCD-4948-8113-C643EFCF710C}','updatecheck':{'status':'ok','urls':{'url':[{'codebase': self_endpoint + '/omaha/stub/file/'}]},'manifest':{'version':'99.99.1030','packages':{'package':[{'hash_sha256':digest,'name':filename}]}}}}]}}

# Add a prefix to the response data.
response = jsonify(update)
data = response.get_data(as_text=True)
data = ")]}'" + data
response.set_data(data)

return response

@app.route('/omaha/stub/file/cobalt.crx', methods=['GET'])
def get_file():
return send_file(file_location)

if __name__ == '__main__':
app.run(debug=True)

0 comments on commit 361ea7c

Please sign in to comment.