diff options
24 files changed, 532 insertions, 464 deletions
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index 83e653b..2dc5d05 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc @@ -22,7 +22,7 @@ #include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" #include "chrome/browser/chromeos/app_mode/kiosk_external_updater.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -59,7 +59,7 @@ void OnRemoveAppCryptohomeComplete(const std::string& app, // Check for presence of machine owner public key file. void CheckOwnerFilePresence(bool *present) { scoped_refptr<ownership::OwnerKeyUtil> util = - OwnerSettingsServiceFactory::GetInstance()->GetOwnerKeyUtil(); + OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(); *present = util.get() && util->IsPublicKeyPresent(); } diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index a0222b5..659e00d 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -55,7 +55,7 @@ #include "chrome/browser/chromeos/memory/oom_priority_manager.h" #include "chrome/browser/chromeos/net/network_portal_detector_impl.h" #include "chrome/browser/chromeos/options/cert_library.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/power/idle_action_warning_observer.h" @@ -187,7 +187,7 @@ class DBusServices { DeviceSettingsService::Initialize(); DeviceSettingsService::Get()->SetSessionManager( DBusThreadManager::Get()->GetSessionManagerClient(), - OwnerSettingsServiceFactory::GetInstance()->GetOwnerKeyUtil()); + OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil()); } ~DBusServices() { diff --git a/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc b/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc index 804a32e..97b24d2 100644 --- a/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc +++ b/chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc @@ -5,10 +5,11 @@ #include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" #include "base/thread_task_runner_handle.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/login/login_state.h" +#include "components/ownership/owner_key_util.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" @@ -44,9 +45,9 @@ void ChromeCryptohomeAuthenticator::CheckSafeModeOwnership( LoginState::LOGGED_IN_USER_NONE); } - OwnerSettingsService::IsOwnerForSafeModeAsync( + OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync( context.GetUserIDHash(), - OwnerSettingsServiceFactory::GetInstance()->GetOwnerKeyUtil(), + OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(), callback); } diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc index 7fd127e..67019a8 100644 --- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc +++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc @@ -18,8 +18,8 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" @@ -136,8 +136,8 @@ class CryptohomeAuthenticatorTest : public testing::Test { mock_caller_(NULL), mock_homedir_methods_(NULL), owner_key_util_(new ownership::MockOwnerKeyUtil()) { - OwnerSettingsServiceFactory::GetInstance()->SetOwnerKeyUtilForTesting( - owner_key_util_); + OwnerSettingsServiceChromeOSFactory::GetInstance() + ->SetOwnerKeyUtilForTesting(owner_key_util_); user_context_.SetKey(Key("fakepass")); user_context_.SetUserIDHash("me_nowhere_com_hash"); const user_manager::User* user = diff --git a/chrome/browser/chromeos/ownership/owner_settings_service.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc index d9afe65..6f04ebb 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include <string> #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback.h" #include "base/command_line.h" #include "base/prefs/pref_service.h" +#include "base/threading/thread_checker.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -17,6 +19,7 @@ #include "chrome/browser/profiles/profile.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/tpm_token_loader.h" +#include "components/ownership/owner_key_util.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_details.h" @@ -54,70 +57,12 @@ bool IsOwnerInTests(const std::string& user_id) { return static_cast<const base::StringValue*>(value)->GetString() == user_id; } -// Assembles PolicyData based on |settings|, |policy_data| and -// |user_id|. -scoped_ptr<em::PolicyData> AssemblePolicy( - const std::string& user_id, - const em::PolicyData* policy_data, - const em::ChromeDeviceSettingsProto* settings) { - scoped_ptr<em::PolicyData> policy(new em::PolicyData()); - if (policy_data) { - // Preserve management settings. - if (policy_data->has_management_mode()) - policy->set_management_mode(policy_data->management_mode()); - if (policy_data->has_request_token()) - policy->set_request_token(policy_data->request_token()); - if (policy_data->has_device_id()) - policy->set_device_id(policy_data->device_id()); - } else { - // If there's no previous policy data, this is the first time the device - // setting is set. We set the management mode to NOT_MANAGED initially. - policy->set_management_mode(em::PolicyData::NOT_MANAGED); - } - policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); - policy->set_timestamp( - (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); - policy->set_username(user_id); - if (!settings->SerializeToString(policy->mutable_policy_value())) - return scoped_ptr<em::PolicyData>(); - - return policy.Pass(); -} - -std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy, - crypto::RSAPrivateKey* private_key) { - // Assemble the policy. - em::PolicyFetchResponse policy_response; - if (!policy->SerializeToString(policy_response.mutable_policy_data())) { - LOG(ERROR) << "Failed to encode policy payload."; - return std::string(); - } - - // Generate the signature. - scoped_ptr<crypto::SignatureCreator> signature_creator( - crypto::SignatureCreator::Create(private_key)); - signature_creator->Update( - reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()), - policy_response.policy_data().size()); - std::vector<uint8> signature_bytes; - std::string policy_blob; - if (!signature_creator->Final(&signature_bytes)) { - LOG(ERROR) << "Failed to create policy signature."; - return std::string(); - } - - policy_response.mutable_policy_data_signature()->assign( - reinterpret_cast<const char*>(vector_as_array(&signature_bytes)), - signature_bytes.size()); - return policy_response.SerializeAsString(); -} - void LoadPrivateKeyByPublicKey( const scoped_refptr<OwnerKeyUtil>& owner_key_util, scoped_refptr<PublicKey> public_key, const std::string& username_hash, - const base::Callback<void(scoped_refptr<PublicKey> public_key, - scoped_refptr<PrivateKey> private_key)>& + const base::Callback<void(const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key)>& callback) { crypto::EnsureNSSInit(); crypto::ScopedPK11Slot slot = @@ -129,11 +74,12 @@ void LoadPrivateKeyByPublicKey( base::Bind(callback, public_key, private_key)); } -void LoadPrivateKey(const scoped_refptr<OwnerKeyUtil>& owner_key_util, - const std::string username_hash, - const base::Callback<void( - scoped_refptr<PublicKey> public_key, - scoped_refptr<PrivateKey> private_key)>& callback) { +void LoadPrivateKey( + const scoped_refptr<OwnerKeyUtil>& owner_key_util, + const std::string username_hash, + const base::Callback<void(const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key)>& + callback) { std::vector<uint8> public_key_data; scoped_refptr<PublicKey> public_key; if (!owner_key_util->ImportPublicKey(&public_key_data)) { @@ -175,15 +121,14 @@ bool DoesPrivateKeyExistAsyncHelper( // not. Responds via |callback|. void DoesPrivateKeyExistAsync( const scoped_refptr<OwnerKeyUtil>& owner_key_util, - const OwnerSettingsService::IsOwnerCallback& callback) { + const OwnerSettingsServiceChromeOS::IsOwnerCallback& callback) { if (!owner_key_util) { callback.Run(false); return; } scoped_refptr<base::TaskRunner> task_runner = - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); + BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); base::PostTaskAndReplyWithResult( task_runner.get(), FROM_HERE, @@ -191,60 +136,28 @@ void DoesPrivateKeyExistAsync( callback); } -// Returns the current management mode. -em::PolicyData::ManagementMode GetManagementMode( - DeviceSettingsService* service) { - if (!service) { - LOG(ERROR) << "DeviceSettingsService is not initialized"; - return em::PolicyData::NOT_MANAGED; - } - - const em::PolicyData* policy_data = service->policy_data(); - if (policy_data && policy_data->has_management_mode()) - return policy_data->management_mode(); - return em::PolicyData::NOT_MANAGED; -} - -// Returns true if it is okay to transfer from the current mode to the new -// mode. This function should be called in SetManagementMode(). -bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, - em::PolicyData::ManagementMode new_mode) { - // Mode is not changed. - if (current_mode == new_mode) - return true; - - switch (current_mode) { - case em::PolicyData::NOT_MANAGED: - // For consumer management enrollment. - return new_mode == em::PolicyData::CONSUMER_MANAGED; - - case em::PolicyData::ENTERPRISE_MANAGED: - // Management mode cannot be set when it is currently ENTERPRISE_MANAGED. - return false; - - case em::PolicyData::CONSUMER_MANAGED: - // For consumer management unenrollment. - return new_mode == em::PolicyData::NOT_MANAGED; - } - - NOTREACHED(); - return false; +DeviceSettingsService* GetDeviceSettingsService() { + if (g_device_settings_service_for_testing) + return g_device_settings_service_for_testing; + return DeviceSettingsService::IsInitialized() ? DeviceSettingsService::Get() + : NULL; } } // namespace -OwnerSettingsService::OwnerSettingsService( +OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS( Profile* profile, const scoped_refptr<OwnerKeyUtil>& owner_key_util) - : profile_(profile), - owner_key_util_(owner_key_util), + : ownership::OwnerSettingsService(owner_key_util), + profile_(profile), waiting_for_profile_creation_(true), waiting_for_tpm_token_(true), weak_factory_(this) { if (TPMTokenLoader::IsInitialized()) { TPMTokenLoader::TPMTokenStatus tpm_token_status = TPMTokenLoader::Get()->IsTPMTokenEnabled( - base::Bind(&OwnerSettingsService::OnTPMTokenReady, as_weak_ptr())); + base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady, + weak_factory_.GetWeakPtr())); waiting_for_tpm_token_ = tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED; } @@ -259,7 +172,7 @@ OwnerSettingsService::OwnerSettingsService( content::Source<Profile>(profile_)); } -OwnerSettingsService::~OwnerSettingsService() { +OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() { DCHECK(thread_checker_.CalledOnValidThread()); if (DBusThreadManager::IsInitialized() && DBusThreadManager::Get()->GetSessionManagerClient()) { @@ -267,80 +180,32 @@ OwnerSettingsService::~OwnerSettingsService() { } } -bool OwnerSettingsService::IsOwner() { +void OwnerSettingsServiceChromeOS::OnTPMTokenReady( + bool /* tpm_token_enabled */) { DCHECK(thread_checker_.CalledOnValidThread()); - return private_key_ && private_key_->key(); -} + waiting_for_tpm_token_ = false; -void OwnerSettingsService::IsOwnerAsync(const IsOwnerCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (private_key_) { - base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(callback, IsOwner())); - } else { - pending_is_owner_callbacks_.push_back(callback); - } + // TPMTokenLoader initializes the TPM and NSS database which is necessary to + // determine ownership. Force a reload once we know these are initialized. + ReloadKeypair(); } -bool OwnerSettingsService::AssembleAndSignPolicyAsync( +void OwnerSettingsServiceChromeOS::SignAndStorePolicyAsync( scoped_ptr<em::PolicyData> policy, - const AssembleAndSignPolicyCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!IsOwner()) - return false; - base::PostTaskAndReplyWithResult( - BrowserThread::GetBlockingPool(), - FROM_HERE, - base::Bind( - &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()), - callback); - return true; -} - -void OwnerSettingsService::SignAndStoreAsync( - scoped_ptr<em::ChromeDeviceSettingsProto> settings, const base::Closure& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - scoped_ptr<em::PolicyData> policy = AssemblePolicy( - user_id_, GetDeviceSettingsService()->policy_data(), settings.get()); - if (!policy) { - HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); - return; - } - - EnqueueSignAndStore(policy.Pass(), callback); -} - -void OwnerSettingsService::SetManagementSettingsAsync( - em::PolicyData::ManagementMode management_mode, - const std::string& request_token, - const std::string& device_id, - const base::Closure& callback) { - em::PolicyData::ManagementMode current_mode = - GetManagementMode(GetDeviceSettingsService()); - if (!CheckManagementModeTransition(current_mode, management_mode)) { - LOG(ERROR) << "Invalid management mode transition: current mode = " - << current_mode << ", new mode = " << management_mode; - HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); - return; - } - - DeviceSettingsService* service = GetDeviceSettingsService(); - scoped_ptr<em::PolicyData> policy = AssemblePolicy( - user_id_, service->policy_data(), service->device_settings()); - if (!policy) { - HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); - return; - } - - policy->set_management_mode(management_mode); - policy->set_request_token(request_token); - policy->set_device_id(device_id); - - EnqueueSignAndStore(policy.Pass(), callback); + SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation( + base::Bind(&OwnerSettingsServiceChromeOS::HandleCompletedOperation, + weak_factory_.GetWeakPtr(), + callback), + policy.Pass()); + operation->set_owner_settings_service(weak_factory_.GetWeakPtr()); + pending_operations_.push_back(operation); + if (pending_operations_.front() == operation) + StartNextOperation(); } -void OwnerSettingsService::Observe( +void OwnerSettingsServiceChromeOS::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { @@ -357,26 +222,17 @@ void OwnerSettingsService::Observe( } waiting_for_profile_creation_ = false; - ReloadPrivateKey(); + ReloadKeypair(); } -void OwnerSettingsService::OnTPMTokenReady(bool /* unused token_enabled */) { - DCHECK(thread_checker_.CalledOnValidThread()); - waiting_for_tpm_token_ = false; - - // TPMTokenLoader initializes the TPM and NSS database which is necessary to - // determine ownership. Force a reload once we know these are initialized. - ReloadPrivateKey(); -} - -void OwnerSettingsService::OwnerKeySet(bool success) { +void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) { DCHECK(thread_checker_.CalledOnValidThread()); if (success) - ReloadPrivateKey(); + ReloadKeypair(); } // static -void OwnerSettingsService::IsOwnerForSafeModeAsync( +void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync( const std::string& user_hash, const scoped_refptr<OwnerKeyUtil>& owner_key_util, const IsOwnerCallback& callback) { @@ -394,74 +250,49 @@ void OwnerSettingsService::IsOwnerForSafeModeAsync( } // static -void OwnerSettingsService::SetDeviceSettingsServiceForTesting( +void OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting( DeviceSettingsService* device_settings_service) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); g_device_settings_service_for_testing = device_settings_service; } -void OwnerSettingsService::ReloadPrivateKey() { - DCHECK(thread_checker_.CalledOnValidThread()); - if (waiting_for_profile_creation_ || waiting_for_tpm_token_) - return; - scoped_refptr<base::TaskRunner> task_runner = - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); - task_runner->PostTask( - FROM_HERE, - base::Bind(&LoadPrivateKey, - GetOwnerKeyUtil(), - ProfileHelper::GetUserIdHashFromProfile(profile_), - base::Bind(&OwnerSettingsService::OnPrivateKeyLoaded, - weak_factory_.GetWeakPtr()))); -} - -void OwnerSettingsService::OnPrivateKeyLoaded( - scoped_refptr<PublicKey> public_key, - scoped_refptr<PrivateKey> private_key) { +void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() { DCHECK(thread_checker_.CalledOnValidThread()); - public_key_ = public_key; - private_key_ = private_key; user_id_ = profile_->GetProfileName(); const bool is_owner = IsOwner() || IsOwnerInTests(user_id_); if (is_owner && GetDeviceSettingsService()) GetDeviceSettingsService()->InitOwner(user_id_, weak_factory_.GetWeakPtr()); - - std::vector<IsOwnerCallback> is_owner_callbacks; - is_owner_callbacks.swap(pending_is_owner_callbacks_); - for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin()); - it != is_owner_callbacks.end(); - ++it) { - it->Run(is_owner); - } } -void OwnerSettingsService::EnqueueSignAndStore( - scoped_ptr<em::PolicyData> policy, - const base::Closure& callback) { - SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation( - base::Bind(&OwnerSettingsService::HandleCompletedOperation, - weak_factory_.GetWeakPtr(), - callback), - policy.Pass()); - operation->set_delegate(weak_factory_.GetWeakPtr()); - pending_operations_.push_back(operation); - if (pending_operations_.front() == operation) - StartNextOperation(); +void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback< + void(const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key)>& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + if (waiting_for_profile_creation_ || waiting_for_tpm_token_) + return; + scoped_refptr<base::TaskRunner> task_runner = + BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); + task_runner->PostTask( + FROM_HERE, + base::Bind(&LoadPrivateKey, + owner_key_util_, + ProfileHelper::GetUserIdHashFromProfile(profile_), + callback)); } -void OwnerSettingsService::StartNextOperation() { +void OwnerSettingsServiceChromeOS::StartNextOperation() { DeviceSettingsService* service = GetDeviceSettingsService(); if (!pending_operations_.empty() && service && service->session_manager_client()) { pending_operations_.front()->Start( - service->session_manager_client(), GetOwnerKeyUtil(), public_key_); + service->session_manager_client(), owner_key_util_, public_key_); } } -void OwnerSettingsService::HandleCompletedOperation( +void OwnerSettingsServiceChromeOS::HandleCompletedOperation( const base::Closure& callback, SessionManagerOperation* operation, DeviceSettingsService::Status status) { @@ -477,10 +308,10 @@ void OwnerSettingsService::HandleCompletedOperation( (operation->public_key() && public_key_ && operation->public_key()->data() != public_key_->data())) { // Public part changed so we need to reload private part too. - ReloadPrivateKey(); + ReloadKeypair(); content::NotificationService::current()->Notify( chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, - content::Source<OwnerSettingsService>(this), + content::Source<OwnerSettingsServiceChromeOS>(this), content::NotificationService::NoDetails()); } service->OnSignAndStoreOperationCompleted(status); @@ -492,26 +323,4 @@ void OwnerSettingsService::HandleCompletedOperation( StartNextOperation(); } -void OwnerSettingsService::HandleError(DeviceSettingsService::Status status, - const base::Closure& callback) { - LOG(ERROR) << "Session manager operation failed: " << status; - GetDeviceSettingsService()->OnSignAndStoreOperationCompleted(status); - if (!callback.is_null()) - callback.Run(); -} - -scoped_refptr<OwnerKeyUtil> OwnerSettingsService::GetOwnerKeyUtil() { - DCHECK(thread_checker_.CalledOnValidThread()); - return owner_key_util_; -} - -DeviceSettingsService* OwnerSettingsService::GetDeviceSettingsService() { - DCHECK(thread_checker_.CalledOnValidThread()); - if (g_device_settings_service_for_testing) - return g_device_settings_service_for_testing; - if (DeviceSettingsService::IsInitialized()) - return DeviceSettingsService::Get(); - return NULL; -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/ownership/owner_settings_service.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h index 37bbabb..3ef3d7e 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service.h +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h @@ -2,60 +2,51 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ +#ifndef CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_H_ +#define CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_H_ #include <deque> #include <vector> -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chromeos/dbus/session_manager_client.h" #include "components/keyed_service/core/keyed_service.h" #include "components/ownership/owner_key_util.h" +#include "components/ownership/owner_settings_service.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" class Profile; +namespace ownership { +class OwnerKeyUtil; +} + namespace chromeos { class SessionManagerOperation; -// This class reloads owner key from profile NSS slots. +// The class is a profile-keyed service which holds public/private +// keypair corresponds to a profile. The keypair is reloaded automatically when +// profile is created and TPM token is ready. Note that the private part of a +// key can be loaded only for the owner. // // TODO (ygorshenin@): move write path for device settings here // (crbug.com/230018). -class OwnerSettingsService : public DeviceSettingsService::PrivateKeyDelegate, - public KeyedService, - public content::NotificationObserver, - public SessionManagerClient::Observer { +class OwnerSettingsServiceChromeOS : public ownership::OwnerSettingsService, + public content::NotificationObserver, + public SessionManagerClient::Observer { public: - virtual ~OwnerSettingsService(); - - base::WeakPtr<OwnerSettingsService> as_weak_ptr() { - return weak_factory_.GetWeakPtr(); - } + virtual ~OwnerSettingsServiceChromeOS(); void OnTPMTokenReady(bool tpm_token_enabled); - // DeviceSettingsService::PrivateKeyDelegate implementation: - virtual bool IsOwner() OVERRIDE; - virtual void IsOwnerAsync(const IsOwnerCallback& callback) OVERRIDE; - virtual bool AssembleAndSignPolicyAsync( + // ownership::OwnerSettingsService implementation: + virtual void SignAndStorePolicyAsync( scoped_ptr<enterprise_management::PolicyData> policy, - const AssembleAndSignPolicyCallback& callback) OVERRIDE; - virtual void SignAndStoreAsync( - scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> settings, - const base::Closure& callback) OVERRIDE; - virtual void SetManagementSettingsAsync( - enterprise_management::PolicyData::ManagementMode management_mode, - const std::string& request_token, - const std::string& device_id, const base::Closure& callback) OVERRIDE; // NotificationObserver implementation: @@ -77,23 +68,22 @@ class OwnerSettingsService : public DeviceSettingsService::PrivateKeyDelegate, DeviceSettingsService* device_settings_service); private: - friend class OwnerSettingsServiceFactory; + friend class OwnerSettingsServiceChromeOSFactory; - OwnerSettingsService( + OwnerSettingsServiceChromeOS( Profile* profile, const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util); - // Reloads private key from profile's NSS slots. Responds via call - // to OnPrivateKeyLoaded(). - void ReloadPrivateKey(); + // OwnerSettingsService protected interface overrides: - // Called when ReloadPrivateKey() completes it's work. - void OnPrivateKeyLoaded(scoped_refptr<ownership::PublicKey> public_key, - scoped_refptr<ownership::PrivateKey> private_key); + // Reloads private key from profile's NSS slots, responds via |callback|. + virtual void ReloadKeypairImpl(const base::Callback< + void(const scoped_refptr<ownership::PublicKey>& public_key, + const scoped_refptr<ownership::PrivateKey>& private_key)>& callback) + OVERRIDE; - // Puts request to perform sign-and-store operation in the queue. - void EnqueueSignAndStore(scoped_ptr<enterprise_management::PolicyData> policy, - const base::Closure& callback); + // Possibly notifies DeviceSettingsService that owner's keypair is loaded. + virtual void OnPostKeypairLoadedActions() OVERRIDE; // Performs next operation in the queue. void StartNextOperation(); @@ -103,33 +93,12 @@ class OwnerSettingsService : public DeviceSettingsService::PrivateKeyDelegate, SessionManagerOperation* operation, DeviceSettingsService::Status status); - // Called when it's not possible to store settings. - void HandleError(DeviceSettingsService::Status status, - const base::Closure& callback); - - // Returns testing instance of OwnerKeyUtil when it's set, otherwise - // returns |owner_key_util_|. - scoped_refptr<ownership::OwnerKeyUtil> GetOwnerKeyUtil(); - - // Returns testing instance of DeviceSettingsService when it's set, - // otherwise returns pointer to a singleton instance, when it's - // initialized. - DeviceSettingsService* GetDeviceSettingsService(); - // Profile this service instance belongs to. Profile* profile_; // User ID this service instance belongs to. std::string user_id_; - scoped_refptr<ownership::PublicKey> public_key_; - - scoped_refptr<ownership::PrivateKey> private_key_; - - scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_; - - std::vector<IsOwnerCallback> pending_is_owner_callbacks_; - // Whether profile still needs to be initialized. bool waiting_for_profile_creation_; @@ -142,13 +111,11 @@ class OwnerSettingsService : public DeviceSettingsService::PrivateKeyDelegate, content::NotificationRegistrar registrar_; - base::ThreadChecker thread_checker_; - - base::WeakPtrFactory<OwnerSettingsService> weak_factory_; + base::WeakPtrFactory<OwnerSettingsServiceChromeOS> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(OwnerSettingsService); + DISALLOW_COPY_AND_ASSIGN(OwnerSettingsServiceChromeOS); }; } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ +#endif // CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_factory.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc index 4f2e79d..b971f34 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_factory.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "base/path_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chromeos/chromeos_paths.h" @@ -15,29 +15,30 @@ namespace chromeos { -OwnerSettingsServiceFactory::OwnerSettingsServiceFactory() +OwnerSettingsServiceChromeOSFactory::OwnerSettingsServiceChromeOSFactory() : BrowserContextKeyedServiceFactory( "OwnerSettingsService", BrowserContextDependencyManager::GetInstance()) { } -OwnerSettingsServiceFactory::~OwnerSettingsServiceFactory() { +OwnerSettingsServiceChromeOSFactory::~OwnerSettingsServiceChromeOSFactory() { } // static -OwnerSettingsService* OwnerSettingsServiceFactory::GetForProfile( - Profile* profile) { - return static_cast<OwnerSettingsService*>( +OwnerSettingsServiceChromeOS* +OwnerSettingsServiceChromeOSFactory::GetForProfile(Profile* profile) { + return static_cast<OwnerSettingsServiceChromeOS*>( GetInstance()->GetServiceForBrowserContext(profile, true)); } // static -OwnerSettingsServiceFactory* OwnerSettingsServiceFactory::GetInstance() { - return Singleton<OwnerSettingsServiceFactory>::get(); +OwnerSettingsServiceChromeOSFactory* +OwnerSettingsServiceChromeOSFactory::GetInstance() { + return Singleton<OwnerSettingsServiceChromeOSFactory>::get(); } scoped_refptr<ownership::OwnerKeyUtil> -OwnerSettingsServiceFactory::GetOwnerKeyUtil() { +OwnerSettingsServiceChromeOSFactory::GetOwnerKeyUtil() { if (owner_key_util_.get()) return owner_key_util_; base::FilePath public_key_path; @@ -47,25 +48,27 @@ OwnerSettingsServiceFactory::GetOwnerKeyUtil() { return owner_key_util_; } -void OwnerSettingsServiceFactory::SetOwnerKeyUtilForTesting( +void OwnerSettingsServiceChromeOSFactory::SetOwnerKeyUtilForTesting( const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util) { owner_key_util_ = owner_key_util; } // static -KeyedService* OwnerSettingsServiceFactory::BuildInstanceFor( +KeyedService* OwnerSettingsServiceChromeOSFactory::BuildInstanceFor( content::BrowserContext* browser_context) { Profile* profile = static_cast<Profile*>(browser_context); if (profile->IsGuestSession() || ProfileHelper::IsSigninProfile(profile)) return NULL; - return new OwnerSettingsService(profile, GetInstance()->GetOwnerKeyUtil()); + return new OwnerSettingsServiceChromeOS(profile, + GetInstance()->GetOwnerKeyUtil()); } -bool OwnerSettingsServiceFactory::ServiceIsCreatedWithBrowserContext() const { +bool OwnerSettingsServiceChromeOSFactory::ServiceIsCreatedWithBrowserContext() + const { return true; } -KeyedService* OwnerSettingsServiceFactory::BuildServiceInstanceFor( +KeyedService* OwnerSettingsServiceChromeOSFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { return BuildInstanceFor(context); } diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_factory.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h index 597656b..3409456 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_factory.h +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h @@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_FACTORY_H_ - -#include <string> +#ifndef CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_FACTORY_H_ #include "base/compiler_specific.h" #include "base/macros.h" @@ -22,13 +20,14 @@ class OwnerKeyUtil; namespace chromeos { -class OwnerSettingsService; +class OwnerSettingsServiceChromeOS; -class OwnerSettingsServiceFactory : public BrowserContextKeyedServiceFactory { +class OwnerSettingsServiceChromeOSFactory + : public BrowserContextKeyedServiceFactory { public: - static OwnerSettingsService* GetForProfile(Profile* profile); + static OwnerSettingsServiceChromeOS* GetForProfile(Profile* profile); - static OwnerSettingsServiceFactory* GetInstance(); + static OwnerSettingsServiceChromeOSFactory* GetInstance(); scoped_refptr<ownership::OwnerKeyUtil> GetOwnerKeyUtil(); @@ -36,10 +35,10 @@ class OwnerSettingsServiceFactory : public BrowserContextKeyedServiceFactory { const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util); private: - friend struct DefaultSingletonTraits<OwnerSettingsServiceFactory>; + friend struct DefaultSingletonTraits<OwnerSettingsServiceChromeOSFactory>; - OwnerSettingsServiceFactory(); - virtual ~OwnerSettingsServiceFactory(); + OwnerSettingsServiceChromeOSFactory(); + virtual ~OwnerSettingsServiceChromeOSFactory(); static KeyedService* BuildInstanceFor(content::BrowserContext* context); @@ -52,9 +51,9 @@ class OwnerSettingsServiceFactory : public BrowserContextKeyedServiceFactory { scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_; - DISALLOW_COPY_AND_ASSIGN(OwnerSettingsServiceFactory); + DISALLOW_COPY_AND_ASSIGN(OwnerSettingsServiceChromeOSFactory); }; } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_FACTORY_H_ +#endif // CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_FACTORY_H_ diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc index 79d79b9..6f61750 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc @@ -13,8 +13,6 @@ #include "base/test/scoped_path_override.h" #include "base/values.h" #include "chrome/browser/chromeos/login/users/fake_user_manager.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" diff --git a/chrome/browser/chromeos/settings/device_settings_service.cc b/chrome/browser/chromeos/settings/device_settings_service.cc index 9ba9324..36de11d 100644 --- a/chrome/browser/chromeos/settings/device_settings_service.cc +++ b/chrome/browser/chromeos/settings/device_settings_service.cc @@ -35,6 +35,62 @@ int kLoadRetryDelayMs = 1000 * 5; // of retry time. int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; +// Assembles PolicyData based on |settings|, |policy_data| and +// |user_id|. +scoped_ptr<em::PolicyData> AssemblePolicy( + const std::string& user_id, + const em::PolicyData* policy_data, + const em::ChromeDeviceSettingsProto* settings) { + scoped_ptr<em::PolicyData> policy(new em::PolicyData()); + if (policy_data) { + // Preserve management settings. + if (policy_data->has_management_mode()) + policy->set_management_mode(policy_data->management_mode()); + if (policy_data->has_request_token()) + policy->set_request_token(policy_data->request_token()); + if (policy_data->has_device_id()) + policy->set_device_id(policy_data->device_id()); + } else { + // If there's no previous policy data, this is the first time the device + // setting is set. We set the management mode to NOT_MANAGED initially. + policy->set_management_mode(em::PolicyData::NOT_MANAGED); + } + policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); + policy->set_timestamp( + (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); + policy->set_username(user_id); + if (!settings->SerializeToString(policy->mutable_policy_value())) + return scoped_ptr<em::PolicyData>(); + + return policy.Pass(); +} + +// Returns true if it is okay to transfer from the current mode to the new +// mode. This function should be called in SetManagementMode(). +bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, + em::PolicyData::ManagementMode new_mode) { + // Mode is not changed. + if (current_mode == new_mode) + return true; + + switch (current_mode) { + case em::PolicyData::NOT_MANAGED: + // For consumer management enrollment. + return new_mode == em::PolicyData::CONSUMER_MANAGED; + + case em::PolicyData::ENTERPRISE_MANAGED: + // Management mode cannot be set when it is currently ENTERPRISE_MANAGED. + return false; + + case em::PolicyData::CONSUMER_MANAGED: + // For consumer management unenrollment. + return new_mode == em::PolicyData::NOT_MANAGED; + } + + NOTREACHED(); + return false; +} + } // namespace namespace chromeos { @@ -116,10 +172,18 @@ void DeviceSettingsService::Load() { void DeviceSettingsService::SignAndStore( scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, const base::Closure& callback) { - if (!delegate_) + if (!owner_settings_service_) { HandleError(STORE_KEY_UNAVAILABLE, callback); - else - delegate_->SignAndStoreAsync(new_settings.Pass(), callback); + return; + } + scoped_ptr<em::PolicyData> policy = + AssemblePolicy(GetUsername(), policy_data(), new_settings.get()); + if (!policy) { + HandleError(STORE_POLICY_ERROR, callback); + return; + } + + owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); } void DeviceSettingsService::SetManagementSettings( @@ -127,12 +191,34 @@ void DeviceSettingsService::SetManagementSettings( const std::string& request_token, const std::string& device_id, const base::Closure& callback) { - if (!delegate_) { + if (!owner_settings_service_) { HandleError(STORE_KEY_UNAVAILABLE, callback); - } else { - delegate_->SetManagementSettingsAsync( - management_mode, request_token, device_id, callback); + return; + } + + em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; + if (policy_data() && policy_data()->has_management_mode()) + current_mode = policy_data()->management_mode(); + + if (!CheckManagementModeTransition(current_mode, management_mode)) { + LOG(ERROR) << "Invalid management mode transition: current mode = " + << current_mode << ", new mode = " << management_mode; + HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); + return; + } + + scoped_ptr<em::PolicyData> policy = + AssemblePolicy(GetUsername(), policy_data(), device_settings()); + if (!policy) { + HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); + return; } + + policy->set_management_mode(management_mode); + policy->set_request_token(request_token); + policy->set_device_id(device_id); + + owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); } void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, @@ -169,18 +255,19 @@ void DeviceSettingsService::GetOwnershipStatusAsync( } bool DeviceSettingsService::HasPrivateOwnerKey() { - return delegate_ && delegate_->IsOwner(); + return owner_settings_service_ && owner_settings_service_->IsOwner(); } void DeviceSettingsService::InitOwner( const std::string& username, - const base::WeakPtr<PrivateKeyDelegate>& delegate) { + const base::WeakPtr<ownership::OwnerSettingsService>& + owner_settings_service) { // When InitOwner() is called twice with the same |username| it's // worth to reload settings since owner key may become available. if (!username_.empty() && username_ != username) return; username_ = username; - delegate_ = delegate; + owner_settings_service_ = owner_settings_service; EnsureReload(true); } @@ -230,14 +317,15 @@ void DeviceSettingsService::EnqueueLoad(bool force_key_load) { base::Closure())); operation->set_force_key_load(force_key_load); operation->set_username(username_); - operation->set_delegate(delegate_); + operation->set_owner_settings_service(owner_settings_service_); Enqueue(operation); } void DeviceSettingsService::EnsureReload(bool force_key_load) { if (!pending_operations_.empty()) { pending_operations_.front()->set_username(username_); - pending_operations_.front()->set_delegate(delegate_); + pending_operations_.front()->set_owner_settings_service( + owner_settings_service_); pending_operations_.front()->RestartLoad(force_key_load); } else { EnqueueLoad(force_key_load); diff --git a/chrome/browser/chromeos/settings/device_settings_service.h b/chrome/browser/chromeos/settings/device_settings_service.h index b514037..d29e689 100644 --- a/chrome/browser/chromeos/settings/device_settings_service.h +++ b/chrome/browser/chromeos/settings/device_settings_service.h @@ -17,6 +17,7 @@ #include "base/observer_list.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chromeos/dbus/session_manager_client.h" +#include "components/ownership/owner_settings_service.h" #include "components/policy/core/common/cloud/cloud_policy_validator.h" #include "crypto/scoped_nss_types.h" #include "policy/proto/device_management_backend.pb.h" @@ -82,48 +83,6 @@ class DeviceSettingsService : public SessionManagerClient::Observer { virtual void DeviceSettingsUpdated() = 0; }; - class PrivateKeyDelegate { - public: - typedef base::Callback<void(bool is_owner)> IsOwnerCallback; - typedef base::Callback<void(std::string policy_blob)> - AssembleAndSignPolicyCallback; - - virtual ~PrivateKeyDelegate() {} - - // Returns whether current user is owner or not. When this method - // is called too early, incorrect result can be returned because - // private key loading may be in progress. - virtual bool IsOwner() = 0; - - // Determines whether current user is owner or not, responds via - // |callback|. - virtual void IsOwnerAsync(const IsOwnerCallback& callback) = 0; - - // Assembles and signs |policy|, responds via |callback|. - virtual bool AssembleAndSignPolicyAsync( - scoped_ptr<enterprise_management::PolicyData> policy, - const AssembleAndSignPolicyCallback& callback) = 0; - - // Signs |settings| with the private half of the owner key and sends - // the resulting policy blob to session manager for storage. The - // result of the operation is reported through |callback|. If - // successful, the updated device settings are present in - // policy_data() and device_settings() when the callback runs. - virtual void SignAndStoreAsync( - scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> settings, - const base::Closure& callback) = 0; - - // Sets the management related settings in PolicyData. Note that if - // |management_mode| is NOT_MANAGED, |request_token| and |device_id| - // should be empty strings. The result of the operation is reported - // through |callback|. - virtual void SetManagementSettingsAsync( - enterprise_management::PolicyData::ManagementMode management_mode, - const std::string& request_token, - const std::string& device_id, - const base::Closure& callback) = 0; - }; - // Manage singleton instance. static void Initialize(); static bool IsInitialized(); @@ -205,7 +164,9 @@ class DeviceSettingsService : public SessionManagerClient::Observer { // Sets the identity of the user that's interacting with the service. This is // relevant only for writing settings through SignAndStore(). void InitOwner(const std::string& username, - const base::WeakPtr<PrivateKeyDelegate>& delegate); + const base::WeakPtr<ownership::OwnerSettingsService>& + owner_settings_service); + const std::string& GetUsername() const; // Adds an observer. @@ -218,7 +179,7 @@ class DeviceSettingsService : public SessionManagerClient::Observer { virtual void PropertyChangeComplete(bool success) OVERRIDE; private: - friend class OwnerSettingsService; + friend class OwnerSettingsServiceChromeOS; // Enqueues a new operation. Takes ownership of |operation| and starts it // right away if there is no active operation currently. @@ -265,7 +226,7 @@ class DeviceSettingsService : public SessionManagerClient::Observer { std::string username_; scoped_refptr<ownership::PublicKey> public_key_; - base::WeakPtr<PrivateKeyDelegate> delegate_; + base::WeakPtr<ownership::OwnerSettingsService> owner_settings_service_; scoped_ptr<enterprise_management::PolicyData> policy_data_; scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> device_settings_; diff --git a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc index 4c293a5..3515a67 100644 --- a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc +++ b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc @@ -9,8 +9,8 @@ #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" #include "chrome/test/base/testing_profile.h" @@ -497,8 +497,8 @@ TEST_F(DeviceSettingsServiceTest, OnTPMTokenReadyForNonOwner) { const std::string& user_id = device_policy_.policy_data().username(); InitOwner(user_id, false); - OwnerSettingsService* service = - OwnerSettingsServiceFactory::GetForProfile(profile_.get()); + OwnerSettingsServiceChromeOS* service = + OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get()); ASSERT_TRUE(service); service->IsOwnerAsync(base::Bind(&DeviceSettingsServiceTest::OnIsOwner, base::Unretained(this))); @@ -542,8 +542,8 @@ TEST_F(DeviceSettingsServiceTest, OnTPMTokenReadyForOwner) { const std::string& user_id = device_policy_.policy_data().username(); owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey()); InitOwner(user_id, false); - OwnerSettingsService* service = - OwnerSettingsServiceFactory::GetForProfile(profile_.get()); + OwnerSettingsServiceChromeOS* service = + OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get()); ASSERT_TRUE(service); service->IsOwnerAsync(base::Bind(&DeviceSettingsServiceTest::OnIsOwner, base::Unretained(this))); @@ -599,8 +599,8 @@ TEST_F(DeviceSettingsServiceTest, IsCurrentUserOwnerAsyncWithLoadedCerts) { device_settings_service_.GetOwnershipStatus()); EXPECT_FALSE(is_owner_set_); - OwnerSettingsService* service = - OwnerSettingsServiceFactory::GetForProfile(profile_.get()); + OwnerSettingsServiceChromeOS* service = + OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get()); ASSERT_TRUE(service); service->IsOwnerAsync(base::Bind(&DeviceSettingsServiceTest::OnIsOwner, base::Unretained(this))); diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc index 518e8246..9225906 100644 --- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc +++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc @@ -7,8 +7,8 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/threading/sequenced_worker_pool.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -207,7 +207,7 @@ DeviceSettingsTestBase::DeviceSettingsTestBase() : user_manager_(new FakeUserManager()), user_manager_enabler_(user_manager_), owner_key_util_(new ownership::MockOwnerKeyUtil()) { - OwnerSettingsServiceFactory::GetInstance()->SetOwnerKeyUtilForTesting( + OwnerSettingsServiceChromeOSFactory::GetInstance()->SetOwnerKeyUtilForTesting( owner_key_util_); } @@ -228,13 +228,13 @@ void DeviceSettingsTestBase::SetUp() { device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); device_settings_service_.SetSessionManager(&device_settings_test_helper_, owner_key_util_); - OwnerSettingsService::SetDeviceSettingsServiceForTesting( + OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting( &device_settings_service_); profile_.reset(new TestingProfile()); } void DeviceSettingsTestBase::TearDown() { - OwnerSettingsService::SetDeviceSettingsServiceForTesting(NULL); + OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting(NULL); FlushDeviceSettings(); device_settings_service_.UnsetSessionManager(); DBusThreadManager::Shutdown(); @@ -259,8 +259,8 @@ void DeviceSettingsTestBase::InitOwner(const std::string& user_id, ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, profile_.get()); } - OwnerSettingsService* service = - OwnerSettingsServiceFactory::GetForProfile(profile_.get()); + OwnerSettingsServiceChromeOS* service = + OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get()); CHECK(service); if (tpm_is_ready) service->OnTPMTokenReady(true /* token is enabled */); diff --git a/chrome/browser/chromeos/settings/session_manager_operation.cc b/chrome/browser/chromeos/settings/session_manager_operation.cc index 436ea0f..33832aa 100644 --- a/chrome/browser/chromeos/settings/session_manager_operation.cc +++ b/chrome/browser/chromeos/settings/session_manager_operation.cc @@ -251,22 +251,23 @@ SignAndStoreSettingsOperation::SignAndStoreSettingsOperation( SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {} void SignAndStoreSettingsOperation::Run() { - if (!delegate_) { + if (!owner_settings_service_) { ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE); return; } - delegate_->IsOwnerAsync( + owner_settings_service_->IsOwnerAsync( base::Bind(&SignAndStoreSettingsOperation::StartSigning, weak_factory_.GetWeakPtr())); } void SignAndStoreSettingsOperation::StartSigning(bool is_owner) { - if (!delegate_ || !is_owner) { + if (!owner_settings_service_ || !is_owner) { ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE); return; } - bool rv = delegate_->AssembleAndSignPolicyAsync( + bool rv = owner_settings_service_->AssembleAndSignPolicyAsync( + content::BrowserThread::GetBlockingPool(), new_policy_.Pass(), base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettingsBlob, weak_factory_.GetWeakPtr())); diff --git a/chrome/browser/chromeos/settings/session_manager_operation.h b/chrome/browser/chromeos/settings/session_manager_operation.h index a7484b5..66ba738 100644 --- a/chrome/browser/chromeos/settings/session_manager_operation.h +++ b/chrome/browser/chromeos/settings/session_manager_operation.h @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_validator.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" +#include "components/ownership/owner_settings_service.h" #include "net/cert/x509_util_nss.h" namespace enterprise_management { @@ -69,9 +70,9 @@ class SessionManagerOperation { void set_username(const std::string& username) { username_ = username; } - void set_delegate(const base::WeakPtr< - DeviceSettingsService::PrivateKeyDelegate>& delegate) { - delegate_ = delegate; + void set_owner_settings_service(const base::WeakPtr< + ownership::OwnerSettingsService>& owner_settings_service) { + owner_settings_service_ = owner_settings_service; } protected: @@ -92,7 +93,7 @@ class SessionManagerOperation { return session_manager_client_; } - base::WeakPtr<DeviceSettingsService::PrivateKeyDelegate> delegate_; + base::WeakPtr<ownership::OwnerSettingsService> owner_settings_service_; private: // Loads the owner key from disk. Must be run on a thread that can do I/O. diff --git a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc index 6229bd7..3ad70f4 100644 --- a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc +++ b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc @@ -11,8 +11,8 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" #include "chrome/test/base/testing_profile.h" @@ -40,8 +40,8 @@ class SessionManagerOperationTest : public testing::Test { file_thread_(content::BrowserThread::FILE, &message_loop_), owner_key_util_(new ownership::MockOwnerKeyUtil()), validated_(false) { - OwnerSettingsServiceFactory::GetInstance()->SetOwnerKeyUtilForTesting( - owner_key_util_); + OwnerSettingsServiceChromeOSFactory::GetInstance() + ->SetOwnerKeyUtilForTesting(owner_key_util_); } virtual void SetUp() OVERRIDE { @@ -49,7 +49,8 @@ class SessionManagerOperationTest : public testing::Test { policy_.Build(); profile_.reset(new TestingProfile()); - service_ = OwnerSettingsServiceFactory::GetForProfile(profile_.get()); + service_ = + OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get()); } MOCK_METHOD2(OnOperationCompleted, @@ -82,7 +83,7 @@ class SessionManagerOperationTest : public testing::Test { scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_; scoped_ptr<TestingProfile> profile_; - OwnerSettingsService* service_; + OwnerSettingsServiceChromeOS* service_; bool validated_; @@ -220,7 +221,7 @@ TEST_F(SessionManagerOperationTest, SignAndStoreSettings) { base::Bind(&SessionManagerOperationTest::OnOperationCompleted, base::Unretained(this)), policy.Pass()); - op.set_delegate(service_->as_weak_ptr()); + op.set_owner_settings_service(service_->as_weak_ptr()); EXPECT_CALL(*this, OnOperationCompleted( diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 06f1ebf..a31257b 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc @@ -70,7 +70,7 @@ #include "chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h" #include "chrome/browser/policy/schema_registry_service_factory.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/recommendation_restorer_factory.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" @@ -221,7 +221,7 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { policy::ProfilePolicyConnectorFactory::GetInstance(); #if defined(ENABLE_CONFIGURATION_POLICY) #if defined(OS_CHROMEOS) - chromeos::OwnerSettingsServiceFactory::GetInstance(); + chromeos::OwnerSettingsServiceChromeOSFactory::GetInstance(); policy::PolicyCertServiceFactory::GetInstance(); policy::RecommendationRestorerFactory::GetInstance(); policy::UserCloudPolicyManagerFactoryChromeOS::GetInstance(); diff --git a/chrome/browser/ui/webui/flags_ui.cc b/chrome/browser/ui/webui/flags_ui.cc index 88dfe19..148a9c5 100644 --- a/chrome/browser/ui/webui/flags_ui.cc +++ b/chrome/browser/ui/webui/flags_ui.cc @@ -34,8 +34,8 @@ #if defined(OS_CHROMEOS) #include "base/sys_info.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" +#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/owner_flags_storage.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -292,8 +292,8 @@ FlagsUI::FlagsUI(content::WebUI* web_ui) web_ui->AddMessageHandler(handler); #if defined(OS_CHROMEOS) - chromeos::OwnerSettingsService* service = - chromeos::OwnerSettingsServiceFactory::GetForProfile(profile); + chromeos::OwnerSettingsServiceChromeOS* service = + chromeos::OwnerSettingsServiceChromeOSFactory::GetForProfile(profile); if (service) { service->IsOwnerAsync(base::Bind( &FinishInitialization, weak_factory_.GetWeakPtr(), profile, handler)); diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index e5c29c0..9f55b2b 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -782,10 +782,10 @@ 'browser/chromeos/options/wifi_config_view.h', 'browser/chromeos/options/wimax_config_view.cc', 'browser/chromeos/options/wimax_config_view.h', - 'browser/chromeos/ownership/owner_settings_service.cc', - 'browser/chromeos/ownership/owner_settings_service.h', - 'browser/chromeos/ownership/owner_settings_service_factory.cc', - 'browser/chromeos/ownership/owner_settings_service_factory.h', + 'browser/chromeos/ownership/owner_settings_service_chromeos.cc', + 'browser/chromeos/ownership/owner_settings_service_chromeos.h', + 'browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc', + 'browser/chromeos/ownership/owner_settings_service_chromeos_factory.h', 'browser/chromeos/platform_keys/platform_keys.cc', 'browser/chromeos/platform_keys/platform_keys.h', 'browser/chromeos/platform_keys/platform_keys_nss.cc', diff --git a/components/ownership.gypi b/components/ownership.gypi index 46a7a51..6f4befa 100644 --- a/components/ownership.gypi +++ b/components/ownership.gypi @@ -8,11 +8,18 @@ 'type': '<(component)', 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/components/components.gyp:cloud_policy_proto', + '<(DEPTH)/components/components.gyp:keyed_service_core', + '<(DEPTH)/components/components.gyp:policy', + '<(DEPTH)/components/components.gyp:policy_component_common', '<(DEPTH)/crypto/crypto.gyp:crypto', ], 'defines': [ 'OWNERSHIP_IMPLEMENTATION', ], + 'include_dirs': [ + '<(SHARED_INTERMEDIATE_DIR)', + ], 'sources': [ 'ownership/mock_owner_key_util.cc', 'ownership/mock_owner_key_util.h', @@ -20,6 +27,8 @@ 'ownership/owner_key_util.h', 'ownership/owner_key_util_impl.cc', 'ownership/owner_key_util_impl.h', + 'ownership/owner_settings_service.cc', + 'ownership/owner_settings_service.h', ], }], } diff --git a/components/ownership/BUILD.gn b/components/ownership/BUILD.gn index 2e53f12..ad11a79 100644 --- a/components/ownership/BUILD.gn +++ b/components/ownership/BUILD.gn @@ -10,6 +10,8 @@ component("ownership") { "owner_key_util.h", "owner_key_util_impl.cc", "owner_key_util_impl.h", + "owner_settings_service.cc", + "owner_settings_service.h", ] defines = [ @@ -18,6 +20,10 @@ component("ownership") { deps = [ "//base", + "//components/keyed_service/core", + "//components/policy", + "//components/policy/proto", + "//components/policy:policy_component_common", "//crypto", ] } diff --git a/components/ownership/DEPS b/components/ownership/DEPS index bc55362..a169ab8 100644 --- a/components/ownership/DEPS +++ b/components/ownership/DEPS @@ -1,3 +1,7 @@ include_rules = [ +"+components/keyed_service", "+crypto", + +# This is generated from components/policy/proto +"+policy/proto/device_management_backend.pb.h", ] diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc new file mode 100644 index 0000000..09c88d3 --- /dev/null +++ b/components/ownership/owner_settings_service.cc @@ -0,0 +1,118 @@ +// Copyright 2014 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/ownership/owner_settings_service.h" + +#include "base/basictypes.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/task_runner.h" +#include "base/task_runner_util.h" +#include "components/ownership/owner_key_util.h" +#include "crypto/signature_creator.h" + +namespace em = enterprise_management; + +namespace ownership { + +namespace { + +std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy, + crypto::RSAPrivateKey* private_key) { + // Assemble the policy. + em::PolicyFetchResponse policy_response; + if (!policy->SerializeToString(policy_response.mutable_policy_data())) { + LOG(ERROR) << "Failed to encode policy payload."; + return std::string(); + } + + // Generate the signature. + scoped_ptr<crypto::SignatureCreator> signature_creator( + crypto::SignatureCreator::Create(private_key)); + signature_creator->Update( + reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()), + policy_response.policy_data().size()); + std::vector<uint8> signature_bytes; + std::string policy_blob; + if (!signature_creator->Final(&signature_bytes)) { + LOG(ERROR) << "Failed to create policy signature."; + return std::string(); + } + + policy_response.mutable_policy_data_signature()->assign( + reinterpret_cast<const char*>(vector_as_array(&signature_bytes)), + signature_bytes.size()); + return policy_response.SerializeAsString(); +} + +} // namepace + +OwnerSettingsService::OwnerSettingsService( + const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util) + : owner_key_util_(owner_key_util), weak_factory_(this) { +} + +OwnerSettingsService::~OwnerSettingsService() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +bool OwnerSettingsService::IsOwner() { + DCHECK(thread_checker_.CalledOnValidThread()); + return private_key_.get() && private_key_->key(); +} + +void OwnerSettingsService::IsOwnerAsync(const IsOwnerCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (private_key_.get()) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(callback, IsOwner())); + } else { + pending_is_owner_callbacks_.push_back(callback); + } +} + +bool OwnerSettingsService::AssembleAndSignPolicyAsync( + base::TaskRunner* task_runner, + scoped_ptr<em::PolicyData> policy, + const AssembleAndSignPolicyAsyncCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!task_runner || !IsOwner()) + return false; + return base::PostTaskAndReplyWithResult( + task_runner, + FROM_HERE, + base::Bind( + &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()), + callback); +} + +void OwnerSettingsService::ReloadKeypair() { + ReloadKeypairImpl( + base::Bind(&OwnerSettingsService::OnKeypairLoaded, as_weak_ptr())); +} + +void OwnerSettingsService::OnKeypairLoaded( + const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key) { + DCHECK(thread_checker_.CalledOnValidThread()); + + public_key_ = public_key; + private_key_ = private_key; + + const bool is_owner = IsOwner(); + std::vector<IsOwnerCallback> is_owner_callbacks; + is_owner_callbacks.swap(pending_is_owner_callbacks_); + for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin()); + it != is_owner_callbacks.end(); + ++it) { + it->Run(is_owner); + } + + OnPostKeypairLoadedActions(); +} + +} // namespace ownership diff --git a/components/ownership/owner_settings_service.h b/components/ownership/owner_settings_service.h new file mode 100644 index 0000000..ed4a1b5 --- /dev/null +++ b/components/ownership/owner_settings_service.h @@ -0,0 +1,102 @@ +// Copyright 2014 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_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ +#define COMPONENTS_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ + +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/ownership/ownership_export.h" +#include "policy/proto/device_management_backend.pb.h" + +namespace base { +class TaskRunner; +} + +namespace ownership { +class OwnerKeyUtil; +class PrivateKey; +class PublicKey; + +// This class is a common interface for platform-specific classes +// which deal with ownership, keypairs and owner-related settings. +class OWNERSHIP_EXPORT OwnerSettingsService : public KeyedService { + public: + typedef base::Callback<void(std::string policy_blob)> + AssembleAndSignPolicyAsyncCallback; + + typedef base::Callback<void(bool is_owner)> IsOwnerCallback; + + explicit OwnerSettingsService( + const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util); + virtual ~OwnerSettingsService(); + + base::WeakPtr<OwnerSettingsService> as_weak_ptr() { + return weak_factory_.GetWeakPtr(); + } + + // Returns whether current user is owner or not. When this method + // is called too early, incorrect result can be returned because + // private key loading may be in progress. + bool IsOwner(); + + // Determines whether current user is owner or not, responds via + // |callback|. + void IsOwnerAsync(const IsOwnerCallback& callback); + + // Assembles and signs |policy| on the |task_runner|, responds on + // the original thread via |callback|. + bool AssembleAndSignPolicyAsync( + base::TaskRunner* task_runner, + scoped_ptr<enterprise_management::PolicyData> policy, + const AssembleAndSignPolicyAsyncCallback& callback); + + // Signs |settings| with the private half of the owner key and sends + // the resulting policy blob for storage. The + // result of the operation is reported through |callback|. + virtual void SignAndStorePolicyAsync( + scoped_ptr<enterprise_management::PolicyData> policy, + const base::Closure& callback) = 0; + + protected: + void ReloadKeypair(); + + void OnKeypairLoaded(const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key); + + // Platform-specific keypair loading algorithm. + virtual void ReloadKeypairImpl(const base::Callback< + void(const scoped_refptr<PublicKey>& public_key, + const scoped_refptr<PrivateKey>& private_key)>& callback) = 0; + + // Plafrom-specific actions which should be performed when keypair is loaded. + virtual void OnPostKeypairLoadedActions() = 0; + + scoped_refptr<ownership::PublicKey> public_key_; + + scoped_refptr<ownership::PrivateKey> private_key_; + + scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_; + + std::vector<IsOwnerCallback> pending_is_owner_callbacks_; + + base::ThreadChecker thread_checker_; + + private: + base::WeakPtrFactory<OwnerSettingsService> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(OwnerSettingsService); +}; + +} // namespace ownership + +#endif // COMPONENTS_OWNERSHIP_OWNER_SETTINGS_SERVICE_H_ |