Commit d761a60e authored by Omar Morsi's avatar Omar Morsi Committed by Commit Bot

KeyPermissions: Add ARC key permissions manager delegate

This CL introduces ARC key permissions manager delegate which observes
changes that affect ARC usage allowance of corporate keys residing on a
specific token. If an ArcKpmDelegate observes a change in the state of
ARC usage allowance, it notifies all observers. ArcKpmDelegates are
utilized by key permissions managers to keep key permissions updated in
chaps.

Bug: 1113115, 1127284
Change-Id: Ib7636c83f313904c7d5a23f91baca6bf43907344
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2479706
Commit-Queue: Omar Morsi <omorsi@google.com>
Reviewed-by: default avatarLong Cheng <lgcheng@google.com>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823681}
parent 21511ffc
......@@ -2024,6 +2024,8 @@ source_set("chromeos") {
"platform_keys/extension_platform_keys_service.h",
"platform_keys/extension_platform_keys_service_factory.cc",
"platform_keys/extension_platform_keys_service_factory.h",
"platform_keys/key_permissions/arc_key_permissions_manager_delegate.cc",
"platform_keys/key_permissions/arc_key_permissions_manager_delegate.h",
"platform_keys/key_permissions/extension_key_permissions_service.cc",
"platform_keys/key_permissions/extension_key_permissions_service.h",
"platform_keys/key_permissions/extension_key_permissions_service_factory.cc",
......@@ -3574,6 +3576,7 @@ source_set("unit_tests") {
"ownership/owner_settings_service_chromeos_unittest.cc",
"phonehub/browser_tabs_metadata_fetcher_impl_unittest.cc",
"phonehub/browser_tabs_model_provider_impl_unittest.cc",
"platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc",
"platform_keys/key_permissions/key_permissions_service_impl_unittest.cc",
"plugin_vm/mock_plugin_vm_manager.cc",
"plugin_vm/mock_plugin_vm_manager.h",
......
// 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 "chrome/browser/chromeos/platform_keys/key_permissions/arc_key_permissions_manager_delegate.h"
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/observer_list_types.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/extension_key_permissions_service.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_service.h"
#include "components/policy/policy_constants.h"
namespace {
// Owned by ChromeBrowserMainPartsChromeos.
chromeos::platform_keys::SystemTokenArcKpmDelegate*
g_system_token_arc_usage_manager_delegate = nullptr;
} // namespace
namespace chromeos {
namespace platform_keys {
ArcKpmDelegate::Observer::Observer() = default;
ArcKpmDelegate::Observer::~Observer() = default;
ArcKpmDelegate::ArcKpmDelegate() = default;
ArcKpmDelegate::~ArcKpmDelegate() = default;
void ArcKpmDelegate::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void ArcKpmDelegate::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
void ArcKpmDelegate::NotifyArcUsageAllowanceForCorporateKeysChanged(
bool allowed) {
for (auto& observer : observer_list_) {
observer.OnArcUsageAllowanceForCorporateKeysChanged(allowed);
}
}
UserPrivateTokenArcKpmDelegate::UserPrivateTokenArcKpmDelegate(Profile* profile)
: profile_(profile),
is_primary_profile_(ProfileHelper::IsPrimaryProfile(profile)),
policy_service_(profile->GetProfilePolicyConnector()->policy_service()),
arc_app_list_prefs_(ArcAppListPrefs::Get(profile)) {
if (is_primary_profile_) {
SystemTokenArcKpmDelegate::Get()->SetPrimaryUserArcKpmDelegate(this);
}
policy_change_registrar_ = std::make_unique<policy::PolicyChangeRegistrar>(
policy_service_, policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
/*component_id=*/std::string()));
policy_change_registrar_->Observe(
policy::key::kKeyPermissions,
base::BindRepeating(
&UserPrivateTokenArcKpmDelegate::OnKeyPermissionsPolicyChanged,
base::Unretained(this)));
if (arc_app_list_prefs_) {
arc_app_list_prefs_->AddObserver(this);
}
auto* arc_session_manager = arc::ArcSessionManager::Get();
if (arc_session_manager) {
arc_session_manager->AddObserver(this);
}
CheckArcKeyAvailibility();
}
UserPrivateTokenArcKpmDelegate::~UserPrivateTokenArcKpmDelegate() {
auto* arc_session_manager = arc::ArcSessionManager::Get();
if (arc_session_manager) {
arc_session_manager->RemoveObserver(this);
}
if (arc_app_list_prefs_) {
arc_app_list_prefs_->RemoveObserver(this);
}
policy_change_registrar_.reset();
if (is_primary_profile_) {
SetArcUsageAllowance(false);
SystemTokenArcKpmDelegate::Get()->SetPrimaryUserArcKpmDelegate(nullptr);
}
}
bool UserPrivateTokenArcKpmDelegate::AreCorporateKeysAllowedForArcUsage()
const {
return corporate_keys_allowed_for_arc_usage_;
}
void UserPrivateTokenArcKpmDelegate::CheckArcKeyAvailibility() {
if (!arc::IsArcAllowedForProfile(profile_)) {
SetArcUsageAllowance(false);
return;
}
std::vector<std::string> corporate_key_usage_allowed_app_ids =
ExtensionKeyPermissionsService::GetCorporateKeyUsageAllowedAppIds(
policy_service_);
for (const auto& package_name : corporate_key_usage_allowed_app_ids) {
DCHECK(arc_app_list_prefs_);
if (arc_app_list_prefs_->ArcAppListPrefs::IsPackageInstalled(
package_name)) {
SetArcUsageAllowance(true);
return;
}
}
SetArcUsageAllowance(false);
}
void UserPrivateTokenArcKpmDelegate::SetArcUsageAllowance(bool allowed) {
if (corporate_keys_allowed_for_arc_usage_ != allowed) {
corporate_keys_allowed_for_arc_usage_ = allowed;
NotifyArcUsageAllowanceForCorporateKeysChanged(allowed);
}
}
void UserPrivateTokenArcKpmDelegate::OnArcPlayStoreEnabledChanged(
bool enabled) {
CheckArcKeyAvailibility();
}
void UserPrivateTokenArcKpmDelegate::OnKeyPermissionsPolicyChanged(
const base::Value* old_value,
const base::Value* new_value) {
CheckArcKeyAvailibility();
}
void UserPrivateTokenArcKpmDelegate::OnPackageInstalled(
const arc::mojom::ArcPackageInfo& package_info) {
CheckArcKeyAvailibility();
}
void UserPrivateTokenArcKpmDelegate::OnPackageRemoved(
const std::string& package_name,
bool uninstalled) {
CheckArcKeyAvailibility();
}
// static
SystemTokenArcKpmDelegate* SystemTokenArcKpmDelegate::Get() {
return g_system_token_arc_usage_manager_delegate;
}
// static
void SystemTokenArcKpmDelegate::SetSystemTokenArcKpmDelegateForTesting(
SystemTokenArcKpmDelegate* system_token_arc_kpm_delegate) {
g_system_token_arc_usage_manager_delegate = system_token_arc_kpm_delegate;
}
SystemTokenArcKpmDelegate::SystemTokenArcKpmDelegate() {
DCHECK(!g_system_token_arc_usage_manager_delegate);
g_system_token_arc_usage_manager_delegate = this;
DCHECK(!primary_user_arc_usage_manager_);
// Notification for the initial state of the usage allowance. The state may
// change after SetPrimaryUserArcKpmDelegate is called.
NotifyArcUsageAllowanceForCorporateKeysChanged(false);
}
SystemTokenArcKpmDelegate::~SystemTokenArcKpmDelegate() {
DCHECK(g_system_token_arc_usage_manager_delegate);
g_system_token_arc_usage_manager_delegate = nullptr;
ClearPrimaryUserArcKpmDelegate();
}
bool SystemTokenArcKpmDelegate::AreCorporateKeysAllowedForArcUsage() const {
if (!primary_user_arc_usage_manager_) {
return false;
}
return primary_user_arc_usage_manager_->AreCorporateKeysAllowedForArcUsage();
}
// TODO(crbug.com/1144820): Make setting the primary user's ARC KPM delegate in
// SystemTokenArcKpmDelegate more robust.
void SystemTokenArcKpmDelegate::SetPrimaryUserArcKpmDelegate(
UserPrivateTokenArcKpmDelegate* primary_user_arc_usage_manager) {
ClearPrimaryUserArcKpmDelegate();
if (primary_user_arc_usage_manager == nullptr) {
return;
}
primary_user_arc_usage_manager_ = primary_user_arc_usage_manager;
primary_user_arc_usage_manager_delegate_observer_.Add(
primary_user_arc_usage_manager_);
OnArcUsageAllowanceForCorporateKeysChanged(
primary_user_arc_usage_manager_->AreCorporateKeysAllowedForArcUsage());
}
void SystemTokenArcKpmDelegate::ClearPrimaryUserArcKpmDelegate() {
if (!primary_user_arc_usage_manager_) {
return;
}
primary_user_arc_usage_manager_delegate_observer_.Remove(
primary_user_arc_usage_manager_);
primary_user_arc_usage_manager_ = nullptr;
OnArcUsageAllowanceForCorporateKeysChanged(false);
}
void SystemTokenArcKpmDelegate::OnArcUsageAllowanceForCorporateKeysChanged(
bool allowed) {
if (corporate_keys_allowed_for_arc_usage_ == allowed) {
return;
}
corporate_keys_allowed_for_arc_usage_ = allowed;
NotifyArcUsageAllowanceForCorporateKeysChanged(allowed);
}
} // namespace platform_keys
} // namespace chromeos
// 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 CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_ARC_KEY_PERMISSIONS_MANAGER_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_ARC_KEY_PERMISSIONS_MANAGER_DELEGATE_H_
#include <memory>
#include <string>
#include "base/observer_list_types.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
class Profile;
namespace base {
class Value;
}
namespace policy {
class PolicyChangeRegistrar;
class PolicyService;
} // namespace policy
namespace chromeos {
namespace platform_keys {
// ARC key permissions manager delegate (ArcKpmDelegate) instances observes
// changes that affect ARC usage allowance of corporate keys residing on a
// specific token. If an ArcKpmDelegate observes a change in the state of ARC
// usage allowance, it notifies all observers by calling
// OnArcUsageAllowanceForCorporateKeysChanged. ArcKpmDelegates are used by KPMs
// to keep key permissions updated in chaps.
class ArcKpmDelegate {
public:
class Observer : public base::CheckedObserver {
public:
Observer();
explicit Observer(const ArcKpmDelegate&) = delete;
Observer& operator=(const ArcKpmDelegate&) = delete;
~Observer() override;
virtual void OnArcUsageAllowanceForCorporateKeysChanged(bool allowed) = 0;
};
ArcKpmDelegate();
ArcKpmDelegate(const ArcKpmDelegate&) = delete;
ArcKpmDelegate& operator=(const ArcKpmDelegate&) = delete;
virtual ~ArcKpmDelegate();
// Returns true if corporate keys are allowed for ARC usage for the token in
// question.
virtual bool AreCorporateKeysAllowedForArcUsage() const = 0;
virtual void AddObserver(Observer* observer);
virtual void RemoveObserver(Observer* observer);
protected:
virtual void NotifyArcUsageAllowanceForCorporateKeysChanged(bool allowed);
bool corporate_keys_allowed_for_arc_usage_ = false;
base::ObserverList<Observer> observer_list_;
};
// A UserPrivateTokenArcKpmDelegate instance observes changes that affect
// ARC usage allowance of corporate keys residing on a specific user token.
// Corporate keys are allowed for ARC usage on a user token if:
// 1- ARC is enabled for this user and
// 2- there exists an ARC app A installed for the user session and
// 3- app A is mentioned in KeyPermissions user policy.
class UserPrivateTokenArcKpmDelegate : public ArcKpmDelegate,
public arc::ArcSessionManagerObserver,
public ArcAppListPrefs::Observer,
public base::CheckedObserver {
public:
explicit UserPrivateTokenArcKpmDelegate(Profile* profile);
UserPrivateTokenArcKpmDelegate(const UserPrivateTokenArcKpmDelegate&) =
delete;
UserPrivateTokenArcKpmDelegate& operator=(
const UserPrivateTokenArcKpmDelegate&) = delete;
~UserPrivateTokenArcKpmDelegate() override;
// ArcKpmDelegate
bool AreCorporateKeysAllowedForArcUsage() const override;
private:
void CheckArcKeyAvailibility();
void SetArcUsageAllowance(bool allowed);
void OnKeyPermissionsPolicyChanged(const base::Value* old_value,
const base::Value* new_value);
// arc::ArcSessionManager
void OnArcPlayStoreEnabledChanged(bool enabled) override;
// ArcAppListPrefs::Observer
void OnPackageInstalled(
const arc::mojom::ArcPackageInfo& package_info) override;
void OnPackageRemoved(const std::string& package_name,
bool uninstalled) override;
Profile* const profile_;
const bool is_primary_profile_;
policy::PolicyService* const policy_service_;
std::unique_ptr<policy::PolicyChangeRegistrar> policy_change_registrar_;
// This is non-null pointer only for the primary user.
ArcAppListPrefs* const arc_app_list_prefs_;
};
// SystemTokenArcKpmDelegate observes changes that affect ARC usage allowance of
// corporate keys residing on the system token.
// ARC usage is allowed for corporate keys residing on the system token if it is
// allowed for corporate keys residing on the primary user's token.
//
// ** ArcKpmDelegate Chaining **
// As mentioned above, SystemTokenArcKpmDelegate depends on the state reported
// by the UserPrivateTokenArcKpmDelegate instance for the primary user. So
// SystemTokenArcKpmDelegate will forward system token KPM queries about ARC
// usage allowance to the primary user UserPrivateTokenArcKpmDelegate instance
// if exists. It will also notify the system token KPM about ARC usage changes
// whenever the primary user UserPrivateTokenArcKpmDelegate instance observes
// changes.
class SystemTokenArcKpmDelegate : public ArcKpmDelegate,
public ArcKpmDelegate::Observer {
public:
// Returns a global instance. May return null if not initialized.
static SystemTokenArcKpmDelegate* Get();
static void SetSystemTokenArcKpmDelegateForTesting(
SystemTokenArcKpmDelegate* system_token_arc_kpm_delegate);
SystemTokenArcKpmDelegate();
SystemTokenArcKpmDelegate(const SystemTokenArcKpmDelegate&) = delete;
SystemTokenArcKpmDelegate& operator=(const SystemTokenArcKpmDelegate&) =
delete;
~SystemTokenArcKpmDelegate() override;
// ArcKpmDelegate
bool AreCorporateKeysAllowedForArcUsage() const override;
// Sets the primary user private token delegate to which the system token
// delegate is chained (Check ArcKpmDelegate Chaining documentation above).
// Note: This should be called with nullptr before the primary user delegate
// is destroyed.
void SetPrimaryUserArcKpmDelegate(
UserPrivateTokenArcKpmDelegate* primary_user_arc_usage_manager);
void ClearPrimaryUserArcKpmDelegate();
private:
// ArcKpmDelegate::Observer
void OnArcUsageAllowanceForCorporateKeysChanged(bool allowed) override;
UserPrivateTokenArcKpmDelegate* primary_user_arc_usage_manager_ = nullptr;
ScopedObserver<ArcKpmDelegate, ArcKpmDelegate::Observer>
primary_user_arc_usage_manager_delegate_observer_{this};
};
} // namespace platform_keys
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_ARC_KEY_PERMISSIONS_MANAGER_DELEGATE_H_
......@@ -79,6 +79,11 @@ class KeyPermissionsManager {
virtual void IsKeyAllowedForUsage(IsKeyAllowedForUsageCallback callback,
KeyUsage key_usage,
const std::string& public_key_spki_der) = 0;
// Returns true if corporate keys are allowed for ARC usages. Currently,
// either all corporate keys on a token are allowed for ARC usage or none of
// them.
virtual bool AreCorporateKeysAllowedForArcUsage() const = 0;
};
} // namespace platform_keys
......
......@@ -58,10 +58,11 @@ enum class MigrationStatus {
kMaxValue = kFailed,
};
chaps::KeyPermissions CreateKeyPermissions(bool corporate_usage_allowed) {
chaps::KeyPermissions CreateKeyPermissions(bool corporate_usage_allowed,
bool arc_usage_allowed) {
chaps::KeyPermissions key_permissions;
key_permissions.mutable_key_usages()->set_corporate(corporate_usage_allowed);
key_permissions.mutable_key_usages()->set_arc(false);
key_permissions.mutable_key_usages()->set_arc(arc_usage_allowed);
return key_permissions;
}
......@@ -133,6 +134,15 @@ void KeyPermissionsManagerImpl::KeyPermissionsInChapsUpdater::
/*corporate_usage_retrieval_status=*/Status::kSuccess);
break;
}
case Mode::kUpdateArcUsageFlag: {
key_permissions_manager_->IsKeyAllowedForUsage(
base::BindOnce(&KeyPermissionsInChapsUpdater::
UpdatePermissionsForKeyWithCorporateFlag,
weak_ptr_factory_.GetWeakPtr(), public_key_spki_der),
KeyUsage::kCorporate, public_key_spki_der);
break;
}
}
}
......@@ -149,8 +159,12 @@ void KeyPermissionsManagerImpl::KeyPermissionsInChapsUpdater::
DCHECK(corporate_usage_allowed.has_value());
bool arc_usage_allowed =
corporate_usage_allowed.value() &&
key_permissions_manager_->AreCorporateKeysAllowedForArcUsage();
chaps::KeyPermissions key_permissions =
CreateKeyPermissions(corporate_usage_allowed.value());
CreateKeyPermissions(corporate_usage_allowed.value(), arc_usage_allowed);
key_permissions_manager_->platform_keys_service_->SetAttributeForKey(
key_permissions_manager_->token_id_, public_key_spki_der,
......@@ -202,7 +216,7 @@ KeyPermissionsManagerImpl::CreateSystemTokenKeyPermissionsManager() {
auto system_token_key_permissions_manager =
std::make_unique<KeyPermissionsManagerImpl>(
TokenId::kSystem,
TokenId::kSystem, std::make_unique<SystemTokenArcKpmDelegate>(),
PlatformKeysServiceFactory::GetInstance()->GetDeviceWideService(),
g_browser_process->local_state());
g_system_token_key_permissions_manager =
......@@ -225,14 +239,19 @@ void KeyPermissionsManagerImpl::SetOneTimeMigrationEnabledForTesting(
KeyPermissionsManagerImpl::KeyPermissionsManagerImpl(
TokenId token_id,
std::unique_ptr<ArcKpmDelegate> arc_usage_manager_delegate,
PlatformKeysService* platform_keys_service,
PrefService* pref_service)
: token_id_(token_id),
arc_usage_manager_delegate_(std::move(arc_usage_manager_delegate)),
platform_keys_service_(platform_keys_service),
pref_service_(pref_service) {
DCHECK(arc_usage_manager_delegate_);
DCHECK(platform_keys_service_);
DCHECK(pref_service_);
arc_usage_manager_delegate_observer_.Add(arc_usage_manager_delegate_.get());
// This waits until the token this KPM is responsible for is available.
platform_keys_service_->GetTokens(base::BindOnce(
&KeyPermissionsManagerImpl::OnGotTokens, weak_ptr_factory_.GetWeakPtr()));
......@@ -260,6 +279,10 @@ void KeyPermissionsManagerImpl::OnGotTokens(
StartOneTimeMigration();
} else {
OnReadyForQueries();
// On initialization, ARC usage allowance for corporate keys may be
// different than after the one-time migration ends, so we trigger an update
// in chaps.
UpdateKeyPermissionsInChaps();
}
}
......@@ -277,8 +300,8 @@ void KeyPermissionsManagerImpl::AllowKeyForUsage(
switch (usage) {
case KeyUsage::kArc:
LOG(ERROR)
<< "ARC key usage is managed internally by key permissions manager.";
LOG(ERROR) << "ARC usage of corporate keys is managed internally by "
"ArcKpmDelegate.";
std::move(callback).Run(Status::kErrorInternal);
break;
case KeyUsage::kCorporate: {
......@@ -311,7 +334,7 @@ void KeyPermissionsManagerImpl::AllowKeyForCorporateUsage(
AllowKeyForUsageCallback callback,
const std::string& public_key_spki_der) {
chaps::KeyPermissions key_permissions = CreateKeyPermissions(
/*corporate_usage_allowed=*/true);
/*corporate_usage_allowed=*/true, AreCorporateKeysAllowedForArcUsage());
platform_keys_service_->SetAttributeForKey(
token_id_, public_key_spki_der, KeyAttributeType::kKeyPermissions,
......@@ -354,6 +377,33 @@ void KeyPermissionsManagerImpl::IsKeyAllowedForUsageWithPermissions(
std::move(callback).Run(allowed, Status::kSuccess);
}
bool KeyPermissionsManagerImpl::AreCorporateKeysAllowedForArcUsage() const {
return arc_usage_manager_delegate_->AreCorporateKeysAllowedForArcUsage();
}
void KeyPermissionsManagerImpl::UpdateKeyPermissionsInChaps() {
if (!IsOneTimeMigrationDone()) {
// This function will always be called after the one-time migration is done.
return;
}
key_permissions_in_chaps_updater_ =
std::make_unique<KeyPermissionsInChapsUpdater>(
KeyPermissionsInChapsUpdater::Mode::kUpdateArcUsageFlag, this);
key_permissions_in_chaps_updater_->Update(
base::BindOnce(&KeyPermissionsManagerImpl::OnKeyPermissionsInChapsUpdated,
weak_ptr_factory_.GetWeakPtr()));
}
void KeyPermissionsManagerImpl::OnKeyPermissionsInChapsUpdated(
Status update_status) {
if (update_status != Status::kSuccess) {
// TODO(crbug.com/1140105): Record the number of times
// KeyPermissionsInChapsUpdater fails in UMA.
LOG(ERROR) << "Updating key permissions in chaps failed.";
}
}
void KeyPermissionsManagerImpl::StartOneTimeMigration() {
DCHECK(!IsOneTimeMigrationDone());
......@@ -394,12 +444,34 @@ void KeyPermissionsManagerImpl::OnOneTimeMigrationDone(
pref_service_->SetBoolean(prefs::kKeyPermissionsOneTimeMigrationDone, true);
OnReadyForQueries();
// Double-check keys permissions after the migration is done just in case any
// ARC updates happened during the migration.
UpdateKeyPermissionsInChaps();
}
bool KeyPermissionsManagerImpl::IsOneTimeMigrationDone() const {
return pref_service_->GetBoolean(prefs::kKeyPermissionsOneTimeMigrationDone);
}
void KeyPermissionsManagerImpl::OnArcUsageAllowanceForCorporateKeysChanged(
bool allowed) {
if (allowed == arc_usage_allowed_for_corporate_keys_) {
return;
}
if (allowed) {
VLOG(0) << "ARC usage is allowed for corporate keys on token: "
<< static_cast<int>(token_id_) << ".";
} else {
VLOG(0) << "ARC usage is not allowed for corporate keys on token: "
<< static_cast<int>(token_id_) << ".";
}
arc_usage_allowed_for_corporate_keys_ = allowed;
UpdateKeyPermissionsInChaps();
}
void KeyPermissionsManagerImpl::OnReadyForQueries() {
ready_for_queries_ = true;
for (auto& callback : queries_waiting_list_) {
......
......@@ -15,6 +15,7 @@
#include "base/observer_list_types.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/arc_key_permissions_manager_delegate.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_manager.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
......@@ -27,10 +28,11 @@ namespace platform_keys {
class PlatformKeysService;
class KeyPermissionsManagerImpl : public KeyPermissionsManager {
class KeyPermissionsManagerImpl : public KeyPermissionsManager,
public ArcKpmDelegate::Observer {
public:
// Updates chaps with the current "corporate" flag for keys on a certain
// token.
// Updates chaps with the current "arc" and "corporate" flags for keys on a
// certain token.
class KeyPermissionsInChapsUpdater {
public:
// The updater possible modes.
......@@ -38,7 +40,11 @@ class KeyPermissionsManagerImpl : public KeyPermissionsManager {
// Used for the one-time key permissions migration step. For more
// information regarding the one-time migration step, please refer to
// KeyPermissionsManager documentation.
kMigratePermissionsFromPrefs
kMigratePermissionsFromPrefs,
// Used for updating ARC usage flag in chaps after the one-time key
// permissions migration step is done and when ARC usage allowance
// changes for keys on a token.
kUpdateArcUsageFlag
};
// |key_permissions_manager| must not be null and must outlive the updater
......@@ -112,9 +118,11 @@ class KeyPermissionsManagerImpl : public KeyPermissionsManager {
// Don't use this constructor directly. Use
// GetSystemTokenKeyPermissionsManager or
// GetUserPrivateTokenKeyPermissionsManager instead.
KeyPermissionsManagerImpl(TokenId token_id,
PlatformKeysService* platform_keys_service,
PrefService* pref_service);
KeyPermissionsManagerImpl(
TokenId token_id,
std::unique_ptr<ArcKpmDelegate> arc_usage_manager_delegate,
PlatformKeysService* platform_keys_service,
PrefService* pref_service);
KeyPermissionsManagerImpl(const KeyPermissionsManagerImpl&) = delete;
KeyPermissionsManagerImpl& operator=(const KeyPermissionsManagerImpl&) =
delete;
......@@ -126,11 +134,21 @@ class KeyPermissionsManagerImpl : public KeyPermissionsManager {
void IsKeyAllowedForUsage(IsKeyAllowedForUsageCallback callback,
KeyUsage usage,
const std::string& public_key_spki_der) override;
bool AreCorporateKeysAllowedForArcUsage() const override;
private:
// ArcKpmDelegate::Observer
void OnArcUsageAllowanceForCorporateKeysChanged(bool allowed) override;
void OnGotTokens(std::unique_ptr<std::vector<TokenId>> token_ids,
Status status);
// Updates the permissions of the keys residing on |token_id| in chaps. If
// this method is called while an update is already running, it will cancel
// the running update and start a new one.
void UpdateKeyPermissionsInChaps();
void OnKeyPermissionsInChapsUpdated(Status update_status);
void StartOneTimeMigration();
void OnOneTimeMigrationDone(Status migration_status);
......@@ -162,6 +180,9 @@ class KeyPermissionsManagerImpl : public KeyPermissionsManager {
// The token for which the key permissions manager instance is responsible.
const TokenId token_id_;
// True if ARC usage is allowed for corporate keys according to
// |arc_usage_manager_delegate_|.
bool arc_usage_allowed_for_corporate_keys_ = false;
// True if the token is ready and the one-time migration is done.
// List of queries waiting for the token to be ready and the one-time
// migration to be done.
......@@ -172,8 +193,12 @@ class KeyPermissionsManagerImpl : public KeyPermissionsManager {
// If not nullptr, then this is the only updater running.
std::unique_ptr<KeyPermissionsInChapsUpdater>
key_permissions_in_chaps_updater_;
// The ARC usage manager delegate for |token_id_|.
std::unique_ptr<ArcKpmDelegate> arc_usage_manager_delegate_;
PlatformKeysService* const platform_keys_service_ = nullptr;
PrefService* const pref_service_ = nullptr;
ScopedObserver<ArcKpmDelegate, ArcKpmDelegate::Observer>
arc_usage_manager_delegate_observer_{this};
base::WeakPtrFactory<KeyPermissionsManagerImpl> weak_ptr_factory_{this};
};
......
......@@ -35,6 +35,8 @@ class MockKeyPermissionsManager : public KeyPermissionsManager {
KeyUsage key_usage,
const std::string& public_key_spki_der),
(override));
MOCK_METHOD(bool, AreCorporateKeysAllowedForArcUsage, (), (const, override));
};
} // namespace platform_keys
......
......@@ -22,8 +22,11 @@ UserPrivateTokenKeyPermissionsManagerService::
UserPrivateTokenKeyPermissionsManagerService(Profile* profile) {
DCHECK(profile);
auto arc_usage_manager_delegate =
std::make_unique<UserPrivateTokenArcKpmDelegate>(profile);
key_permissions_manager_ = std::make_unique<KeyPermissionsManagerImpl>(
TokenId::kUser,
TokenId::kUser, std::move(arc_usage_manager_delegate),
PlatformKeysServiceFactory::GetInstance()->GetForBrowserContext(profile),
profile->GetPrefs());
}
......
......@@ -696,6 +696,11 @@ std::unique_ptr<ArcAppListPrefs::PackageInfo> ArcAppListPrefs::GetPackage(
std::move(permissions));
}
bool ArcAppListPrefs::IsPackageInstalled(
const std::string& package_name) const {
return GetPackage(package_name) != nullptr;
}
std::vector<std::string> ArcAppListPrefs::GetAppIds() const {
if (arc::ShouldArcAlwaysStart())
return GetAppIdsNoArcEnabledCheck();
......
......@@ -268,6 +268,9 @@ class ArcAppListPrefs : public KeyedService,
std::unique_ptr<PackageInfo> GetPackage(
const std::string& package_name) const;
// Returns true if a package with |package_name| is installed.
bool IsPackageInstalled(const std::string& package_name) const;
// Constructs path to app local data.
base::FilePath GetAppPath(const std::string& app_id) const;
......
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