diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc index 300a5748dc81..8973ba736146 100644 --- a/chrome/updater/configurator.cc +++ b/chrome/updater/configurator.cc @@ -62,7 +62,9 @@ Configurator::Configurator(network::NetworkModule* network_module) unzip_factory_(base::MakeRefCounted()), network_fetcher_factory_( base::MakeRefCounted(network_module)), - patch_factory_(base::MakeRefCounted()) { + patch_factory_(base::MakeRefCounted()), + 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()) { @@ -109,6 +111,11 @@ int Configurator::UpdateDelay() const { } std::vector Configurator::UpdateUrl() const { +#if !defined(COBALT_BUILD_TYPE_GOLD) + if (allow_self_signed_packages_ && !update_server_url_.empty()) { + return std::vector{GURL(update_server_url_)}; + } +#endif // !defined(COBALT_BUILD_TYPE_GOLD) if (base::CommandLine::ForCurrentProcess()->HasSwitch( browser::switches::kUseQAUpdateServer)) { return std::vector{GURL(kUpdaterJSONDefaultUrlQA)}; @@ -344,5 +351,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(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 diff --git a/chrome/updater/configurator.h b/chrome/updater/configurator.h index 9478dc709ec5..9ac265528e70 100644 --- a/chrome/updater/configurator.h +++ b/chrome/updater/configurator.h @@ -95,6 +95,15 @@ class Configurator : public update_client::Configurator { static std::string GetAppGuidHelper(const std::string& updater_channel, const std::string& 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() override; @@ -115,6 +124,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); }; diff --git a/chrome/updater/updater_module.cc b/chrome/updater/updater_module.cc index dbe58fed6b00..25a4038d46bf 100644 --- a/chrome/updater/updater_module.cc +++ b/chrome/updater/updater_module.cc @@ -266,10 +266,20 @@ void UpdaterModule::Update() { return; } +#if defined(COBALT_BUILD_TYPE_GOLD) + bool skip_verify_public_key_hash = false; + bool require_network_encryption = true; +#else // defined(COBALT_BUILD_TYPE_GOLD) + bool skip_verify_public_key_hash = GetAllowSelfSignedPackages(); + bool require_network_encryption = GetRequireNetworkEncryption(); +#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& ids) -> std::vector> { update_client::CrxComponent component; @@ -279,10 +289,16 @@ void UpdaterModule::Update() { component.pk_hash.assign(std::begin(kCobaltPublicKeyHash), std::end(kCobaltPublicKeyHash)); component.requires_network_encryption = true; +#if !defined(COBALT_BUILD_TYPE_GOLD) + if (skip_verify_public_key_hash) { + component.pk_hash.clear(); + } + component.requires_network_encryption = require_network_encryption; +#endif // !defined(COBALT_BUILD_TYPE_GOLD) 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) { @@ -432,6 +448,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 diff --git a/chrome/updater/updater_module.h b/chrome/updater/updater_module.h index d01953902cbd..db901342718a 100644 --- a/chrome/updater/updater_module.h +++ b/chrome/updater/updater_module.h @@ -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: diff --git a/cobalt/h5vcc/h5vcc_updater.cc b/cobalt/h5vcc/h5vcc_updater.cc index a5f0ed701716..e80975504e25 100644 --- a/cobalt/h5vcc/h5vcc_updater.cc +++ b/cobalt/h5vcc/h5vcc_updater.cc @@ -91,6 +91,54 @@ 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) { +#if !defined(COBALT_BUILD_TYPE_GOLD) + if (updater_module_) { + updater_module_->SetAllowSelfSignedPackages(allow_self_signed_packages); + } +#endif // !defined(COBALT_BUILD_TYPE_GOLD) +} + +std::string H5vccUpdater::GetUpdateServerUrl() const { + if (updater_module_) { + return updater_module_->GetUpdateServerUrl(); + } + + return ""; +} + +void H5vccUpdater::SetUpdateServerUrl(const std::string& update_server_url) { +#if !defined(COBALT_BUILD_TYPE_GOLD) + if (updater_module_) { + updater_module_->SetUpdateServerUrl(update_server_url); + } +#endif // !defined(COBALT_BUILD_TYPE_GOLD) +} + +bool H5vccUpdater::GetRequireNetworkEncryption() const { + if (updater_module_) { + return updater_module_->GetRequireNetworkEncryption(); + } + + return false; +} + +void H5vccUpdater::SetRequireNetworkEncryption( + bool require_network_encryption) { +#if !defined(COBALT_BUILD_TYPE_GOLD) + if (updater_module_) { + updater_module_->SetRequireNetworkEncryption(require_network_encryption); + } +#endif // !defined(COBALT_BUILD_TYPE_GOLD) +} #endif // SB_IS(EVERGREEN) } // namespace h5vcc } // namespace cobalt diff --git a/cobalt/h5vcc/h5vcc_updater.h b/cobalt/h5vcc/h5vcc_updater.h index c028f950aeaf..22aa845fc4ec 100644 --- a/cobalt/h5vcc/h5vcc_updater.h +++ b/cobalt/h5vcc/h5vcc_updater.h @@ -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 diff --git a/cobalt/h5vcc/h5vcc_updater.idl b/cobalt/h5vcc/h5vcc_updater.idl index ada4538bde0c..ac24b46c7bf7 100644 --- a/cobalt/h5vcc/h5vcc_updater.idl +++ b/cobalt/h5vcc/h5vcc_updater.idl @@ -35,4 +35,18 @@ interface H5vccUpdater { // used for testing. void setUseCompressedUpdates(boolean use_compressed_updates); + // Toggles the ability to load self-signed builds 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); }; diff --git a/components/update_client/configurator.h b/components/update_client/configurator.h index 3932b8d1b260..df96c4bce7c0 100644 --- a/components/update_client/configurator.h +++ b/components/update_client/configurator.h @@ -185,6 +185,15 @@ class Configurator : public base::RefCountedThreadSafe { 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: diff --git a/components/update_client/test_configurator.h b/components/update_client/test_configurator.h index a25f2d1e205e..6fe5cbe6445c 100644 --- a/components/update_client/test_configurator.h +++ b/components/update_client/test_configurator.h @@ -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_; diff --git a/tools/stub_omaha_server.py b/tools/stub_omaha_server.py new file mode 100644 index 000000000000..9391d54377a1 --- /dev/null +++ b/tools/stub_omaha_server.py @@ -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//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)