Commit 0026868b authored by Igor's avatar Igor Committed by Chromium LUCI CQ

Policy retrieval for device account in lacros

The policy for device account is passed to Lacros through
LacrosInitParams. The data is used by the new class,
PolicyLoaderLacros. The implementationis based on prototype
from https://chromium-review.googlesource.com/c/chromium/src/+/2353454

Bug: chromium:1114069
Test: Manual testing on the device
Change-Id: Ifbd6c930ae4ce17ab85c808d8d7783e6c6fc7ad7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521121
Commit-Queue: Igor <igorcov@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarRoland Bock <rbock@google.com>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Reviewed-by: default avatarIgor <igorcov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842481}
parent 578cd099
...@@ -505,4 +505,8 @@ void BrowserManager::OnLacrosChromeServiceVersionReady(uint32_t version) { ...@@ -505,4 +505,8 @@ void BrowserManager::OnLacrosChromeServiceVersionReady(uint32_t version) {
lacros_chrome_service_version_ = version; lacros_chrome_service_version_ = version;
} }
void BrowserManager::SetDeviceAccountPolicy(const std::string& policy_blob) {
environment_provider_->SetDeviceAccountPolicy(policy_blob);
}
} // namespace crosapi } // namespace crosapi
...@@ -106,6 +106,11 @@ class BrowserManager : public session_manager::SessionManagerObserver { ...@@ -106,6 +106,11 @@ class BrowserManager : public session_manager::SessionManagerObserver {
lacros_version_ = version; lacros_version_ = version;
} }
// Set the data of device account policy. It is the serialized blob of
// PolicyFetchResponse received from the server, or parsed from the file after
// is was validated by Ash.
void SetDeviceAccountPolicy(const std::string& policy_blob);
protected: protected:
// Notifies Mojo connection to lacros-chrome has been disconnected. // Notifies Mojo connection to lacros-chrome has been disconnected.
void NotifyMojoDisconnected(); void NotifyMojoDisconnected();
......
...@@ -70,6 +70,23 @@ bool IsUserTypeAllowed(const User* user) { ...@@ -70,6 +70,23 @@ bool IsUserTypeAllowed(const User* user) {
} }
} }
// Returns the vector containing policy data of the device account. In case of
// an error, returns nullopt.
base::Optional<std::vector<uint8_t>> GetDeviceAccountPolicy(
EnvironmentProvider* environment_provider) {
if (!user_manager::UserManager::IsInitialized()) {
LOG(ERROR) << "User not initialized.";
return base::nullopt;
}
const auto* primary_user = user_manager::UserManager::Get()->GetPrimaryUser();
if (!primary_user) {
LOG(ERROR) << "No primary user.";
return base::nullopt;
}
std::string policy_data = environment_provider->GetDeviceAccountPolicy();
return std::vector<uint8_t>(policy_data.begin(), policy_data.end());
}
using InterfaceVersions = base::flat_map<base::Token, uint32_t>; using InterfaceVersions = base::flat_map<base::Token, uint32_t>;
template <typename T> template <typename T>
void AddVersion(InterfaceVersions* map) { void AddVersion(InterfaceVersions* map) {
...@@ -102,6 +119,7 @@ mojom::LacrosInitParamsPtr GetLacrosInitParams( ...@@ -102,6 +119,7 @@ mojom::LacrosInitParamsPtr GetLacrosInitParams(
crosapi::mojom::ExoImeSupport::kConsumedByImeWorkaround; crosapi::mojom::ExoImeSupport::kConsumedByImeWorkaround;
params->cros_user_id_hash = chromeos::ProfileHelper::GetUserIdHashFromProfile( params->cros_user_id_hash = chromeos::ProfileHelper::GetUserIdHashFromProfile(
ProfileManager::GetPrimaryUserProfile()); ProfileManager::GetPrimaryUserProfile());
params->device_account_policy = GetDeviceAccountPolicy(environment_provider);
return params; return params;
} }
...@@ -239,8 +257,8 @@ SendMojoInvitationToLacrosChrome( ...@@ -239,8 +257,8 @@ SendMojoInvitationToLacrosChrome(
std::move(mojo_disconnected_callback)); std::move(mojo_disconnected_callback));
// This is for backward compatibility. // This is for backward compatibility.
// TODO(crbug.com/1156033): Remove InitDeperecated() invocation when lacros // TODO(crbug.com/1156033): Remove InitDeprecated() invocation when lacros
// becomes new enough. // becomes mature enough.
lacros_chrome_service->InitDeprecated( lacros_chrome_service->InitDeprecated(
GetLacrosInitParams(environment_provider)); GetLacrosInitParams(environment_provider));
......
...@@ -98,4 +98,13 @@ std::string EnvironmentProvider::GetDeviceAccountGaiaId() { ...@@ -98,4 +98,13 @@ std::string EnvironmentProvider::GetDeviceAccountGaiaId() {
return account_id.GetGaiaId(); return account_id.GetGaiaId();
} }
void EnvironmentProvider::SetDeviceAccountPolicy(
const std::string& policy_blob) {
device_account_policy_blob_ = policy_blob;
}
std::string EnvironmentProvider::GetDeviceAccountPolicy() {
return device_account_policy_blob_;
}
} // namespace crosapi } // namespace crosapi
...@@ -28,6 +28,17 @@ class EnvironmentProvider { ...@@ -28,6 +28,17 @@ class EnvironmentProvider {
// not the Lacros profile. // not the Lacros profile.
virtual crosapi::mojom::DefaultPathsPtr GetDefaultPaths(); virtual crosapi::mojom::DefaultPathsPtr GetDefaultPaths();
virtual std::string GetDeviceAccountGaiaId(); virtual std::string GetDeviceAccountGaiaId();
// Getter and setter for device account policy data. Used to pass data from
// Ash to Lacros. The format is serialized PolicyFetchResponse object. See
// components/policy/proto/device_management_backend.proto for details.
virtual std::string GetDeviceAccountPolicy();
virtual void SetDeviceAccountPolicy(const std::string& policy_blob);
private:
// The serialized PolicyFetchResponse object corresponding to the policy of
// device account. Used to pass the data from Ash to Lacros.
std::string device_account_policy_blob_;
}; };
} // namespace crosapi } // namespace crosapi
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "chrome/browser/chromeos/crosapi/browser_manager.h"
#include "chrome/browser/chromeos/policy/cached_policy_key_loader_chromeos.h" #include "chrome/browser/chromeos/policy/cached_policy_key_loader_chromeos.h"
#include "chrome/browser/chromeos/policy/value_validation/onc_user_policy_value_validator.h" #include "chrome/browser/chromeos/policy/value_validation/onc_user_policy_value_validator.h"
#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/application_lifetime.h"
...@@ -282,6 +283,17 @@ void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated( ...@@ -282,6 +283,17 @@ void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated(
cached_policy_key_loader_->cached_policy_key()); cached_policy_key_loader_->cached_policy_key());
status_ = STATUS_OK; status_ = STATUS_OK;
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (crosapi::BrowserManager::Get()) {
std::string policy_blob;
// Since the policy have passed all the validations, the serialization must
// succeed.
bool success = validator->policy()->SerializeToString(&policy_blob);
DCHECK(success);
crosapi::BrowserManager::Get()->SetDeviceAccountPolicy(policy_blob);
}
#endif
NotifyStoreLoaded(); NotifyStoreLoaded();
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "build/branding_buildflags.h" #include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h" #include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/configuration_policy_handler_list_factory.h" #include "chrome/browser/policy/configuration_policy_handler_list_factory.h"
...@@ -62,6 +63,10 @@ ...@@ -62,6 +63,10 @@
#include "chrome/browser/browser_switcher/browser_switcher_policy_migrator.h" #include "chrome/browser/browser_switcher/browser_switcher_policy_migrator.h"
#endif #endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "components/policy/core/common/policy_loader_lacros.h"
#endif
namespace policy { namespace policy {
namespace { namespace {
bool command_line_enabled_for_testing = false; bool command_line_enabled_for_testing = false;
...@@ -205,6 +210,12 @@ ChromeBrowserPolicyConnector::CreatePlatformProvider() { ...@@ -205,6 +210,12 @@ ChromeBrowserPolicyConnector::CreatePlatformProvider() {
new MacPreferences(), bundle_id); new MacPreferences(), bundle_id);
return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(),
std::move(loader)); std::move(loader));
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
auto loader = std::make_unique<PolicyLoaderLacros>(
base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT}));
return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(),
std::move(loader));
#elif defined(OS_POSIX) && !defined(OS_ANDROID) #elif defined(OS_POSIX) && !defined(OS_ANDROID)
base::FilePath config_dir_path; base::FilePath config_dir_path;
if (base::PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { if (base::PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
......
...@@ -215,7 +215,7 @@ enum ExoImeSupport { ...@@ -215,7 +215,7 @@ enum ExoImeSupport {
// If ash-chrome is newer than lacros-chrome, then some fields may not be // If ash-chrome is newer than lacros-chrome, then some fields may not be
// processed by lacros-chrome. // processed by lacros-chrome.
// //
// Next version: 11 // Next version: 12
[Stable] [Stable]
struct LacrosInitParams { struct LacrosInitParams {
// This is ash-chrome's version of the AshChromeService interface. This is // This is ash-chrome's version of the AshChromeService interface. This is
...@@ -282,6 +282,14 @@ struct LacrosInitParams { ...@@ -282,6 +282,14 @@ struct LacrosInitParams {
// Do not use this to construct paths, use DefaultPaths for that purpose. // Do not use this to construct paths, use DefaultPaths for that purpose.
[MinVersion=10] [MinVersion=10]
string? cros_user_id_hash@10; string? cros_user_id_hash@10;
// Policy blob of the device account. If present, it's a managed account with
// policy data. If empty, it's unmanaged account. If absent, an error occurred
// while loading policy data. The format is serialized PolicyFetchResponse
// object. See components/policy/proto/device_management_backend.proto for
// details.
[MinVersion=11]
array<uint8>? device_account_policy@11;
}; };
// LacrosChromeService defines the APIs that live in lacros-chrome and // LacrosChromeService defines the APIs that live in lacros-chrome and
......
...@@ -189,6 +189,18 @@ source_set("internal") { ...@@ -189,6 +189,18 @@ source_set("internal") {
"//url", "//url",
] ]
if (chromeos_is_browser_only) {
sources += [
"policy_loader_lacros.cc",
"policy_loader_lacros.h",
]
deps += [
"//chromeos/crosapi/mojom",
"//chromeos/lacros",
"//chromeos/startup:startup",
]
}
allow_circular_includes_from = [ allow_circular_includes_from = [
# Generated files use policy_details.h and policy_map.h from this target. # Generated files use policy_details.h and policy_map.h from this target.
# TODO(https://crbug.com/945868) - refactor so we don't have dep cycles. # TODO(https://crbug.com/945868) - refactor so we don't have dep cycles.
......
include_rules = [ include_rules = [
"+chromeos/crosapi",
"+chromeos/lacros",
"+chromeos/startup",
"+chromeos/system", "+chromeos/system",
"+components/account_id", "+components/account_id",
"-components/policy/core/browser", "-components/policy/core/browser",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/core/common/policy_loader_lacros.h"
#include <stddef.h>
#include <algorithm>
#include <set>
#include <string>
#include "base/bind.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
#include "chromeos/startup/startup.h"
#include "components/policy/core/common/cloud/cloud_policy_validator.h"
#include "components/policy/core/common/policy_bundle.h"
#include "components/policy/core/common/policy_proto_decoders.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace policy {
PolicyLoaderLacros::PolicyLoaderLacros(
scoped_refptr<base::SequencedTaskRunner> task_runner)
: AsyncPolicyLoader(task_runner), task_runner_(task_runner) {}
PolicyLoaderLacros::~PolicyLoaderLacros() = default;
void PolicyLoaderLacros::InitOnBackgroundThread() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
}
std::unique_ptr<PolicyBundle> PolicyLoaderLacros::Load() {
std::unique_ptr<PolicyBundle> bundle = std::make_unique<PolicyBundle>();
crosapi::mojom::LacrosInitParamsPtr result;
const crosapi::mojom::LacrosInitParams* init_params;
auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get();
if (lacros_chrome_service) {
init_params = lacros_chrome_service->init_params();
} else {
// On the first start of Lacros browser, the lacros_chrome_service is
// not initialized yet, so take the data directly from the file. This always
// happens on first start after user login, because policy data is loaded
// before the service is initialized. We cannot do other way, since there
// are other dependencies that create a cycle. The in-memory file is used
// to break the cycle. After that, if user reloads the policy the service
// is present.
// TODO(crbug.com/1114069): This code is duplicated in
// LacrosChromeServiceImpl. We could store the data in a static variable
// inside LacrosChromeServiceImpl and make a single static function to call.
base::Optional<std::string> content = chromeos::ReadStartupData();
if (!content) {
LOG(ERROR) << "No content in file for init params";
return bundle;
}
if (!crosapi::mojom::LacrosInitParams::Deserialize(
content->data(), content->size(), &result)) {
LOG(ERROR) << "Failed to parse startup data";
return bundle;
}
init_params = result.get();
}
if (!init_params) {
LOG(ERROR) << "No init params";
return bundle;
}
if (!init_params->device_account_policy) {
LOG(ERROR) << "No policy data";
return bundle;
}
std::vector<uint8_t> data = init_params->device_account_policy.value();
if (data.empty()) {
return bundle;
}
auto policy = std::make_unique<enterprise_management::PolicyFetchResponse>();
if (!policy->ParseFromString(std::string(data.begin(), data.end()))) {
LOG(ERROR) << "Failed to parse policy data";
return bundle;
}
UserCloudPolicyValidator validator(std::move(policy), task_runner_);
validator.ValidatePayload();
validator.RunValidation();
PolicyMap policy_map;
base::WeakPtr<CloudExternalDataManager> external_data_manager;
DecodeProtoFields(*(validator.payload()), external_data_manager,
PolicySource::POLICY_SOURCE_CLOUD,
PolicyScope::POLICY_SCOPE_USER, &policy_map);
bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
.MergeFrom(policy_map);
last_modification_ = base::Time::Now();
return bundle;
}
base::Time PolicyLoaderLacros::LastModificationTime() {
return last_modification_;
}
} // namespace policy
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_
#define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "base/time/time.h"
#include "components/policy/core/common/async_policy_loader.h"
namespace policy {
// A policy loader for Lacros. The data is taken from Ash and the validatity of
// data is trusted, since they have been validated by Ash.
class POLICY_EXPORT PolicyLoaderLacros : public AsyncPolicyLoader {
public:
// Creates the policy loader, saving the task_runner internally. Later
// task_runner is used to have in sequence the process of policy parsing and
// validation.
explicit PolicyLoaderLacros(
scoped_refptr<base::SequencedTaskRunner> task_runner);
// Not copyable or movable
PolicyLoaderLacros(const PolicyLoaderLacros&) = delete;
PolicyLoaderLacros& operator=(const PolicyLoaderLacros&) = delete;
~PolicyLoaderLacros() override;
// AsyncPolicyLoader implementation.
// Verifies that it runs on correct thread.
void InitOnBackgroundThread() override;
// Loads the policy data from LacrosInitParams and populates it in the bundle
// that is returned.
std::unique_ptr<PolicyBundle> Load() override;
// Returns the last time the policy successfully loaded.
base::Time LastModificationTime() override;
private:
// Task runner for running background jobs.
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
// The time of last modification.
base::Time last_modification_;
};
} // namespace policy
#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment