Make sure that cached values of signed settings are trusted.
Verify them at least once since startup. BUG=chromium-os:8645 TEST=Manual Review URL: http://codereview.chromium.org/5185001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67846 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@@ -58,7 +58,7 @@ using __gnu_cxx::hash_set;
|
|||||||
|
|
||||||
namespace __gnu_cxx {
|
namespace __gnu_cxx {
|
||||||
|
|
||||||
// The GNU C++ library provides identiy hash functions for many integral types,
|
// The GNU C++ library provides identity hash functions for many integral types,
|
||||||
// but not for |long long|. This hash function will truncate if |size_t| is
|
// but not for |long long|. This hash function will truncate if |size_t| is
|
||||||
// narrower than |long long|. This is probably good enough for what we will
|
// narrower than |long long|. This is probably good enough for what we will
|
||||||
// use it for.
|
// use it for.
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
namespace chromeos {
|
namespace chromeos {
|
||||||
|
|
||||||
AccountsOptionsHandler::AccountsOptionsHandler()
|
AccountsOptionsHandler::AccountsOptionsHandler()
|
||||||
: CrosOptionsPageUIHandler(new UserCrosSettingsProvider()) {
|
: CrosOptionsPageUIHandler(new UserCrosSettingsProvider) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountsOptionsHandler::~AccountsOptionsHandler() {
|
AccountsOptionsHandler::~AccountsOptionsHandler() {
|
||||||
|
@@ -126,7 +126,8 @@ ExistingUserController::ExistingUserController(
|
|||||||
selected_view_index_(kNotSelected),
|
selected_view_index_(kNotSelected),
|
||||||
num_login_attempts_(0),
|
num_login_attempts_(0),
|
||||||
bubble_(NULL),
|
bubble_(NULL),
|
||||||
user_settings_(new UserCrosSettingsProvider()) {
|
user_settings_(new UserCrosSettingsProvider),
|
||||||
|
method_factory_(this) {
|
||||||
if (delete_scheduled_instance_)
|
if (delete_scheduled_instance_)
|
||||||
delete_scheduled_instance_->Delete();
|
delete_scheduled_instance_->Delete();
|
||||||
|
|
||||||
@@ -302,8 +303,19 @@ void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
|
|||||||
|
|
||||||
void ExistingUserController::LoginOffTheRecord() {
|
void ExistingUserController::LoginOffTheRecord() {
|
||||||
// Check allow_guest in case this call is fired from key accelerator.
|
// Check allow_guest in case this call is fired from key accelerator.
|
||||||
if (!UserCrosSettingsProvider::cached_allow_guest())
|
// Must not proceed without signature verification.
|
||||||
|
bool trusted_setting_available = user_settings_->RequestTrustedAllowGuest(
|
||||||
|
method_factory_.NewRunnableMethod(
|
||||||
|
&ExistingUserController::LoginOffTheRecord));
|
||||||
|
if (!trusted_setting_available) {
|
||||||
|
// Value of AllowGuest setting is still not verified.
|
||||||
|
// Another attempt will be invoked again after verification completion.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (!UserCrosSettingsProvider::cached_allow_guest()) {
|
||||||
|
// Disallowed.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Disable clicking on other windows.
|
// Disable clicking on other windows.
|
||||||
SendSetLoginState(false);
|
SendSetLoginState(false);
|
||||||
@@ -356,11 +368,10 @@ void ExistingUserController::ActivateWizard(const std::string& screen_name) {
|
|||||||
void ExistingUserController::RemoveUser(UserController* source) {
|
void ExistingUserController::RemoveUser(UserController* source) {
|
||||||
ClearErrors();
|
ClearErrors();
|
||||||
|
|
||||||
// TODO(xiyuan): Wait for the cached settings update before using them.
|
// Owner is not allowed to be removed from the device.
|
||||||
if (UserCrosSettingsProvider::cached_owner() == source->user().email()) {
|
// It must be enforced at upper levels.
|
||||||
// Owner is not allowed to be removed from the device.
|
DCHECK(user_settings_->RequestTrustedOwner(NULL));
|
||||||
return;
|
DCHECK(source->user().email() != UserCrosSettingsProvider::cached_owner());
|
||||||
}
|
|
||||||
|
|
||||||
UserManager::Get()->RemoveUser(source->user().email());
|
UserManager::Get()->RemoveUser(source->user().email());
|
||||||
|
|
||||||
@@ -548,9 +559,18 @@ void ExistingUserController::OnPasswordChangeDetected(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must not proceed without signature verification.
|
||||||
|
bool trusted_setting_available = user_settings_->RequestTrustedOwner(
|
||||||
|
method_factory_.NewRunnableMethod(
|
||||||
|
&ExistingUserController::OnPasswordChangeDetected,
|
||||||
|
credentials));
|
||||||
|
if (!trusted_setting_available) {
|
||||||
|
// Value of owner email is still not verified.
|
||||||
|
// Another attempt will be invoked after verification completion.
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO(altimofeev): remove this constrain when full sync for the owner will
|
// TODO(altimofeev): remove this constrain when full sync for the owner will
|
||||||
// be correctly handled.
|
// be correctly handled.
|
||||||
// TODO(xiyuan): Wait for the cached settings update before using them.
|
|
||||||
bool full_sync_disabled = (UserCrosSettingsProvider::cached_owner() ==
|
bool full_sync_disabled = (UserCrosSettingsProvider::cached_owner() ==
|
||||||
controllers_[selected_view_index_]->user().email());
|
controllers_[selected_view_index_]->user().email());
|
||||||
|
|
||||||
|
@@ -166,9 +166,12 @@ class ExistingUserController : public WmMessageListener::Observer,
|
|||||||
// Help application used for help dialogs.
|
// Help application used for help dialogs.
|
||||||
scoped_ptr<HelpAppLauncher> help_app_;
|
scoped_ptr<HelpAppLauncher> help_app_;
|
||||||
|
|
||||||
// A user settings provider instance to trigger settings cache update.
|
// Triggers prefetching of user settings.
|
||||||
scoped_ptr<UserCrosSettingsProvider> user_settings_;
|
scoped_ptr<UserCrosSettingsProvider> user_settings_;
|
||||||
|
|
||||||
|
// Factory of callbacks.
|
||||||
|
ScopedRunnableMethodFactory<ExistingUserController> method_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ExistingUserController);
|
DISALLOW_COPY_AND_ASSIGN(ExistingUserController);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -21,7 +21,8 @@ namespace {
|
|||||||
|
|
||||||
LoginPerformer::LoginPerformer(Delegate* delegate)
|
LoginPerformer::LoginPerformer(Delegate* delegate)
|
||||||
: last_login_failure_(LoginFailure::None()),
|
: last_login_failure_(LoginFailure::None()),
|
||||||
delegate_(delegate) {}
|
delegate_(delegate),
|
||||||
|
method_factory_(this) {}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// LoginPerformer, LoginStatusConsumer implementation:
|
// LoginPerformer, LoginStatusConsumer implementation:
|
||||||
@@ -100,6 +101,18 @@ void LoginPerformer::Login(const std::string& username,
|
|||||||
const std::string& password) {
|
const std::string& password) {
|
||||||
username_ = username;
|
username_ = username;
|
||||||
password_ = password;
|
password_ = password;
|
||||||
|
// Must not proceed without signature verification.
|
||||||
|
UserCrosSettingsProvider user_settings;
|
||||||
|
bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser(
|
||||||
|
method_factory_.NewRunnableMethod(
|
||||||
|
&LoginPerformer::Login,
|
||||||
|
username,
|
||||||
|
password));
|
||||||
|
if (!trusted_setting_available) {
|
||||||
|
// Value of AllowNewUser setting is still not verified.
|
||||||
|
// Another attempt will be invoked after verification completion.
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (UserCrosSettingsProvider::cached_allow_new_user()) {
|
if (UserCrosSettingsProvider::cached_allow_new_user()) {
|
||||||
// Starts authentication if guest login is allowed.
|
// Starts authentication if guest login is allowed.
|
||||||
StartAuthentication();
|
StartAuthentication();
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "base/ref_counted.h"
|
#include "base/ref_counted.h"
|
||||||
|
#include "base/task.h"
|
||||||
#include "chrome/browser/chromeos/login/authenticator.h"
|
#include "chrome/browser/chromeos/login/authenticator.h"
|
||||||
#include "chrome/browser/chromeos/login/login_status_consumer.h"
|
#include "chrome/browser/chromeos/login/login_status_consumer.h"
|
||||||
#include "chrome/browser/chromeos/login/signed_settings_helper.h"
|
#include "chrome/browser/chromeos/login/signed_settings_helper.h"
|
||||||
@@ -107,6 +108,8 @@ class LoginPerformer : public LoginStatusConsumer,
|
|||||||
// Notifications receiver.
|
// Notifications receiver.
|
||||||
Delegate* delegate_;
|
Delegate* delegate_;
|
||||||
|
|
||||||
|
ScopedRunnableMethodFactory<LoginPerformer> method_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
|
DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -73,8 +73,16 @@ void OwnerManager::GenerateKeysAndExportPublic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OwnerManager::ExportKey() {
|
void OwnerManager::ExportKey() {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
VLOG(1) << "Exporting public key";
|
VLOG(1) << "Exporting public key";
|
||||||
if (!utils_->ExportPublicKeyViaDbus(private_key_.get(), this)) {
|
if (utils_->ExportPublicKeyViaDbus(private_key_.get(), this)) {
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
NewRunnableMethod(this,
|
||||||
|
&OwnerManager::SendNotification,
|
||||||
|
NotificationType::OWNERSHIP_TAKEN,
|
||||||
|
NotificationService::NoDetails()));
|
||||||
|
} else {
|
||||||
private_key_.reset(NULL);
|
private_key_.reset(NULL);
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::UI, FROM_HERE,
|
BrowserThread::UI, FROM_HERE,
|
||||||
|
@@ -148,7 +148,8 @@ UserController::UserController(Delegate* delegate, bool is_guest)
|
|||||||
existing_user_view_(NULL),
|
existing_user_view_(NULL),
|
||||||
guest_user_view_(NULL),
|
guest_user_view_(NULL),
|
||||||
label_view_(NULL),
|
label_view_(NULL),
|
||||||
unselected_label_view_(NULL) {
|
unselected_label_view_(NULL),
|
||||||
|
method_factory_(this) {
|
||||||
registrar_.Add(
|
registrar_.Add(
|
||||||
this,
|
this,
|
||||||
NotificationType::LOGIN_USER_IMAGE_CHANGED,
|
NotificationType::LOGIN_USER_IMAGE_CHANGED,
|
||||||
@@ -163,9 +164,7 @@ UserController::UserController(Delegate* delegate,
|
|||||||
is_guest_(false),
|
is_guest_(false),
|
||||||
// Empty 'cached_owner()' means that owner hasn't been cached yet, not
|
// Empty 'cached_owner()' means that owner hasn't been cached yet, not
|
||||||
// that owner has an empty email.
|
// that owner has an empty email.
|
||||||
is_owner_(
|
is_owner_(user.email() == UserCrosSettingsProvider::cached_owner()),
|
||||||
!user.email().empty() &&
|
|
||||||
UserCrosSettingsProvider::cached_owner() == user.email()),
|
|
||||||
show_name_tooltip_(false),
|
show_name_tooltip_(false),
|
||||||
user_(user),
|
user_(user),
|
||||||
delegate_(delegate),
|
delegate_(delegate),
|
||||||
@@ -179,7 +178,9 @@ UserController::UserController(Delegate* delegate,
|
|||||||
existing_user_view_(NULL),
|
existing_user_view_(NULL),
|
||||||
guest_user_view_(NULL),
|
guest_user_view_(NULL),
|
||||||
label_view_(NULL),
|
label_view_(NULL),
|
||||||
unselected_label_view_(NULL) {
|
unselected_label_view_(NULL),
|
||||||
|
method_factory_(this) {
|
||||||
|
DCHECK(!user.email().empty());
|
||||||
registrar_.Add(
|
registrar_.Add(
|
||||||
this,
|
this,
|
||||||
NotificationType::LOGIN_USER_IMAGE_CHANGED,
|
NotificationType::LOGIN_USER_IMAGE_CHANGED,
|
||||||
@@ -552,6 +553,19 @@ void UserController::NavigateAway() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UserController::OnRemoveUser() {
|
void UserController::OnRemoveUser() {
|
||||||
|
// Must not proceed without signature verification.
|
||||||
|
UserCrosSettingsProvider user_settings;
|
||||||
|
bool trusted_owner_available = user_settings.RequestTrustedOwner(
|
||||||
|
method_factory_.NewRunnableMethod(&UserController::OnRemoveUser));
|
||||||
|
if (!trusted_owner_available) {
|
||||||
|
// Value of owner email is still not verified.
|
||||||
|
// Another attempt will be invoked after verification completion.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (user().email() == UserCrosSettingsProvider::cached_owner()) {
|
||||||
|
// Owner is not allowed to be removed from the device.
|
||||||
|
return;
|
||||||
|
}
|
||||||
delegate_->RemoveUser(this);
|
delegate_->RemoveUser(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/string16.h"
|
#include "base/string16.h"
|
||||||
|
#include "base/task.h"
|
||||||
#include "chrome/browser/chromeos/login/new_user_view.h"
|
#include "chrome/browser/chromeos/login/new_user_view.h"
|
||||||
#include "chrome/browser/chromeos/login/user_manager.h"
|
#include "chrome/browser/chromeos/login/user_manager.h"
|
||||||
#include "chrome/browser/chromeos/login/user_view.h"
|
#include "chrome/browser/chromeos/login/user_view.h"
|
||||||
@@ -19,7 +20,6 @@
|
|||||||
#include "views/controls/button/button.h"
|
#include "views/controls/button/button.h"
|
||||||
#include "views/controls/textfield/textfield.h"
|
#include "views/controls/textfield/textfield.h"
|
||||||
#include "views/widget/widget_delegate.h"
|
#include "views/widget/widget_delegate.h"
|
||||||
|
|
||||||
namespace views {
|
namespace views {
|
||||||
class WidgetGtk;
|
class WidgetGtk;
|
||||||
}
|
}
|
||||||
@@ -231,6 +231,8 @@ class UserController : public views::ButtonListener,
|
|||||||
|
|
||||||
NotificationRegistrar registrar_;
|
NotificationRegistrar registrar_;
|
||||||
|
|
||||||
|
ScopedRunnableMethodFactory<UserController> method_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(UserController);
|
DISALLOW_COPY_AND_ASSIGN(UserController);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4,21 +4,87 @@
|
|||||||
|
|
||||||
#include "chrome/browser/chromeos/user_cros_settings_provider.h"
|
#include "chrome/browser/chromeos/user_cros_settings_provider.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "base/hash_tables.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/singleton.h"
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
|
#include "base/task.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "chrome/browser/browser_process.h"
|
#include "chrome/browser/browser_process.h"
|
||||||
|
#include "chrome/browser/browser_thread.h"
|
||||||
#include "chrome/browser/chromeos/cros/cros_library.h"
|
#include "chrome/browser/chromeos/cros/cros_library.h"
|
||||||
#include "chrome/browser/chromeos/cros/login_library.h"
|
#include "chrome/browser/chromeos/cros/login_library.h"
|
||||||
#include "chrome/browser/chromeos/cros_settings.h"
|
#include "chrome/browser/chromeos/cros_settings.h"
|
||||||
#include "chrome/browser/chromeos/cros_settings_names.h"
|
#include "chrome/browser/chromeos/cros_settings_names.h"
|
||||||
|
#include "chrome/browser/chromeos/login/ownership_service.h"
|
||||||
#include "chrome/browser/chromeos/login/user_manager.h"
|
#include "chrome/browser/chromeos/login/user_manager.h"
|
||||||
#include "chrome/browser/prefs/pref_service.h"
|
#include "chrome/browser/prefs/pref_service.h"
|
||||||
|
#include "chrome/common/notification_observer.h"
|
||||||
|
#include "chrome/common/notification_registrar.h"
|
||||||
|
#include "chrome/common/notification_service.h"
|
||||||
|
#include "chrome/common/notification_type.h"
|
||||||
|
|
||||||
namespace chromeos {
|
namespace chromeos {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kTrueIncantation[] = "true";
|
||||||
|
const char kFalseIncantation[] = "false";
|
||||||
|
const char kTrustedSuffix[] = "/trusted";
|
||||||
|
|
||||||
|
// For all our boolean settings following is applicable:
|
||||||
|
// true is default permissive value and false is safe prohibitic value.
|
||||||
|
const char* kBooleanSettings[] = {
|
||||||
|
kAccountsPrefAllowNewUser,
|
||||||
|
kAccountsPrefAllowGuest,
|
||||||
|
kAccountsPrefShowUserNamesOnSignIn
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* kStringSettings[] = {
|
||||||
|
kDeviceOwner
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* kListSettings[] = {
|
||||||
|
kAccountsPrefUsers
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IsControlledBooleanSetting(const std::string& pref_path) {
|
||||||
|
return std::find(kBooleanSettings,
|
||||||
|
kBooleanSettings + arraysize(kBooleanSettings),
|
||||||
|
pref_path) !=
|
||||||
|
kBooleanSettings + arraysize(kBooleanSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsControlledStringSetting(const std::string& pref_path) {
|
||||||
|
return std::find(kStringSettings,
|
||||||
|
kStringSettings + arraysize(kStringSettings),
|
||||||
|
pref_path) !=
|
||||||
|
kStringSettings + arraysize(kStringSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsControlledListSetting(const std::string& pref_path) {
|
||||||
|
return std::find(kListSettings,
|
||||||
|
kListSettings + arraysize(kListSettings),
|
||||||
|
pref_path) !=
|
||||||
|
kListSettings + arraysize(kListSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
|
||||||
|
local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
|
||||||
|
false);
|
||||||
|
if (IsControlledBooleanSetting(pref_path)) {
|
||||||
|
local_state->RegisterBooleanPref(pref_path.c_str(), true);
|
||||||
|
} else if (IsControlledStringSetting(pref_path)) {
|
||||||
|
local_state->RegisterStringPref(pref_path.c_str(), "");
|
||||||
|
} else {
|
||||||
|
DCHECK(IsControlledListSetting(pref_path));
|
||||||
|
local_state->RegisterListPref(pref_path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Value* CreateSettingsBooleanValue(bool value, bool managed) {
|
Value* CreateSettingsBooleanValue(bool value, bool managed) {
|
||||||
DictionaryValue* dict = new DictionaryValue;
|
DictionaryValue* dict = new DictionaryValue;
|
||||||
dict->Set("value", Value::CreateBooleanValue(value));
|
dict->Set("value", Value::CreateBooleanValue(value));
|
||||||
@@ -26,16 +92,30 @@ Value* CreateSettingsBooleanValue(bool value, bool managed) {
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
enum UseValue {
|
||||||
void UpdateCacheBool(const char* name, bool value) {
|
USE_VALUE_SUPPLIED,
|
||||||
|
USE_VALUE_DEFAULT
|
||||||
|
};
|
||||||
|
|
||||||
|
void UpdateCacheBool(const std::string& name,
|
||||||
|
bool value,
|
||||||
|
UseValue use_value) {
|
||||||
PrefService* prefs = g_browser_process->local_state();
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
prefs->SetBoolean(name, value);
|
if (use_value == USE_VALUE_DEFAULT)
|
||||||
|
prefs->ClearPref(name.c_str());
|
||||||
|
else
|
||||||
|
prefs->SetBoolean(name.c_str(), value);
|
||||||
prefs->ScheduleSavePersistentPrefs();
|
prefs->ScheduleSavePersistentPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateCacheString(const char* name, const std::string& value) {
|
void UpdateCacheString(const std::string& name,
|
||||||
|
const std::string& value,
|
||||||
|
UseValue use_value) {
|
||||||
PrefService* prefs = g_browser_process->local_state();
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
prefs->SetString(name, value);
|
if (use_value == USE_VALUE_DEFAULT)
|
||||||
|
prefs->ClearPref(name.c_str());
|
||||||
|
else
|
||||||
|
prefs->SetString(name.c_str(), value);
|
||||||
prefs->ScheduleSavePersistentPrefs();
|
prefs->ScheduleSavePersistentPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,43 +154,333 @@ bool GetUserWhitelist(ListValue* user_list) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UserCrosSettingsTrust : public SignedSettingsHelper::Callback,
|
||||||
|
public NotificationObserver {
|
||||||
|
public:
|
||||||
|
static UserCrosSettingsTrust* GetSharedInstance() {
|
||||||
|
return Singleton<UserCrosSettingsTrust>::get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Working horse for UserCrosSettingsProvider::RequestTrusted* family.
|
||||||
|
bool RequestTrustedEntity(const std::string& name, Task* callback) {
|
||||||
|
if (GetOwnershipStatus() == OWNERSHIP_NONE)
|
||||||
|
return true;
|
||||||
|
if (GetOwnershipStatus() == OWNERSHIP_TAKEN) {
|
||||||
|
DCHECK(g_browser_process);
|
||||||
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
|
DCHECK(prefs);
|
||||||
|
if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (callback)
|
||||||
|
callbacks_[name].push_back(callback);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(const std::string& path, Value* in_value) {
|
||||||
|
if (!UserManager::Get()->current_user_is_owner()) {
|
||||||
|
LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
|
||||||
|
|
||||||
|
// Revert UI change.
|
||||||
|
CrosSettings::Get()->FireObservers(path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsControlledBooleanSetting(path)) {
|
||||||
|
bool bool_value = false;
|
||||||
|
if (in_value->GetAsBoolean(&bool_value)) {
|
||||||
|
std::string value = bool_value ? kTrueIncantation : kFalseIncantation;
|
||||||
|
SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
|
||||||
|
UpdateCacheBool(path, bool_value, USE_VALUE_SUPPLIED);
|
||||||
|
|
||||||
|
VLOG(1) << "Set cros setting " << path << "=" << value;
|
||||||
|
}
|
||||||
|
} else if (path == kDeviceOwner) {
|
||||||
|
VLOG(1) << "Setting owner is not supported. Please use "
|
||||||
|
"'UpdateCachedOwner' instead.";
|
||||||
|
} else if (path == kAccountsPrefUsers) {
|
||||||
|
VLOG(1) << "Setting user whitelist is not implemented. Please use "
|
||||||
|
"whitelist/unwhitelist instead.";
|
||||||
|
} else {
|
||||||
|
LOG(WARNING) << "Try to set unhandled cros setting " << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Listed in upgrade order.
|
||||||
|
enum OwnershipStatus {
|
||||||
|
OWNERSHIP_UNKNOWN = 0,
|
||||||
|
OWNERSHIP_NONE,
|
||||||
|
OWNERSHIP_TAKEN
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to discriminate different sources of ownership status info.
|
||||||
|
enum OwnershipSource {
|
||||||
|
SOURCE_FETCH, // Info comes from FetchOwnershipStatus method.
|
||||||
|
SOURCE_OBSERVE // Info comes from Observe method.
|
||||||
|
};
|
||||||
|
|
||||||
|
// upper bound for number of retries to fetch a signed setting.
|
||||||
|
static const int kNumRetriesLimit = 9;
|
||||||
|
|
||||||
|
UserCrosSettingsTrust() : ownership_status_(OWNERSHIP_UNKNOWN),
|
||||||
|
retries_left_(kNumRetriesLimit) {
|
||||||
|
notification_registrar_.Add(this,
|
||||||
|
NotificationType::OWNERSHIP_TAKEN,
|
||||||
|
NotificationService::AllSources());
|
||||||
|
// Start getting ownership status.
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::FILE,
|
||||||
|
FROM_HERE,
|
||||||
|
NewRunnableMethod(this, &UserCrosSettingsTrust::FetchOwnershipStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
~UserCrosSettingsTrust() {
|
||||||
|
if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
|
||||||
|
CrosLibrary::Get()->EnsureLoaded()) {
|
||||||
|
// Cancels all pending callbacks from us.
|
||||||
|
SignedSettingsHelper::Get()->CancelCallback(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FetchOwnershipStatus() {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
||||||
|
OwnershipStatus status =
|
||||||
|
OwnershipService::GetSharedInstance()->IsAlreadyOwned() ?
|
||||||
|
OWNERSHIP_TAKEN : OWNERSHIP_NONE;
|
||||||
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||||
|
NewRunnableMethod(this, &UserCrosSettingsTrust::SetOwnershipStatus,
|
||||||
|
status, SOURCE_FETCH));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOwnershipStatus(OwnershipStatus new_status,
|
||||||
|
OwnershipSource source) {
|
||||||
|
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||||
|
DCHECK(new_status == OWNERSHIP_TAKEN || new_status == OWNERSHIP_NONE);
|
||||||
|
if (source == SOURCE_FETCH) {
|
||||||
|
DCHECK(ownership_status_ != OWNERSHIP_NONE);
|
||||||
|
if (ownership_status_ == OWNERSHIP_TAKEN) {
|
||||||
|
// OWNERSHIP_TAKEN notification was observed earlier.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ownership_status_ = new_status;
|
||||||
|
if (source == SOURCE_FETCH) {
|
||||||
|
// Start prefetching Boolean and String preferences.
|
||||||
|
for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
|
||||||
|
StartFetchingSetting(kBooleanSettings[i]);
|
||||||
|
for (size_t i = 0; i < arraysize(kStringSettings); ++i)
|
||||||
|
StartFetchingSetting(kStringSettings[i]);
|
||||||
|
} else if (source == SOURCE_OBSERVE) {
|
||||||
|
DCHECK(new_status == OWNERSHIP_TAKEN);
|
||||||
|
if (CrosLibrary::Get()->EnsureLoaded()) {
|
||||||
|
// TODO(dilmah,cmasone): We would not need following piece of code as
|
||||||
|
// long as failure callback from SignedSettings will allow us to
|
||||||
|
// discriminate missing settings from failed signature verification.
|
||||||
|
// Otherwise we must set default values for boolean settings.
|
||||||
|
UserManager::Get()->set_current_user_is_owner(true);
|
||||||
|
for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
|
||||||
|
Set(kBooleanSettings[i], Value::CreateBooleanValue(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns ownership status.
|
||||||
|
// Called on UI thread unlike OwnershipService::IsAlreadyOwned.
|
||||||
|
OwnershipStatus GetOwnershipStatus() {
|
||||||
|
return ownership_status_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartFetchingSetting(const std::string& name) {
|
||||||
|
DCHECK(g_browser_process);
|
||||||
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
|
if (!prefs)
|
||||||
|
return;
|
||||||
|
// Do not trust before fetching complete.
|
||||||
|
prefs->ClearPref((name + kTrustedSuffix).c_str());
|
||||||
|
prefs->ScheduleSavePersistentPrefs();
|
||||||
|
if (CrosLibrary::Get()->EnsureLoaded()) {
|
||||||
|
SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of SignedSettingsHelper::Callback.
|
||||||
|
virtual void OnRetrievePropertyCompleted(bool success,
|
||||||
|
const std::string& name,
|
||||||
|
const std::string& value) {
|
||||||
|
if (!IsControlledBooleanSetting(name) && !IsControlledStringSetting(name)) {
|
||||||
|
NOTREACHED();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
|
||||||
|
|
||||||
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
|
if (!success && GetOwnershipStatus() == OWNERSHIP_TAKEN) {
|
||||||
|
LOG(ERROR) << "On owned device: failed to retrieve cros "
|
||||||
|
"setting, name=" << name;
|
||||||
|
if (retries_left_ > 0) {
|
||||||
|
retries_left_ -= 1;
|
||||||
|
StartFetchingSetting(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG(ERROR) << "No retries left";
|
||||||
|
if (IsControlledBooleanSetting(name)) {
|
||||||
|
// For boolean settings we can just set safe (false) values
|
||||||
|
// and continue as trusted.
|
||||||
|
UpdateCacheBool(name, false, USE_VALUE_SUPPLIED);
|
||||||
|
} else {
|
||||||
|
prefs->ClearPref((name + kTrustedSuffix).c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DCHECK(success || GetOwnershipStatus() == OWNERSHIP_NONE);
|
||||||
|
if (success)
|
||||||
|
VLOG(1) << "Retrieved cros setting " << name << "=" << value;
|
||||||
|
else
|
||||||
|
VLOG(1) << "We are disowned. Going default for cros setting " << name;
|
||||||
|
if (IsControlledBooleanSetting(name)) {
|
||||||
|
// Our boolean settings are true by default (if not explicitly present).
|
||||||
|
UpdateCacheBool(name, (value == kTrueIncantation),
|
||||||
|
success ? USE_VALUE_SUPPLIED : USE_VALUE_DEFAULT);
|
||||||
|
} else if (IsControlledStringSetting(name)) {
|
||||||
|
UpdateCacheString(name, value,
|
||||||
|
success ? USE_VALUE_SUPPLIED : USE_VALUE_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
|
||||||
|
{
|
||||||
|
DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
|
||||||
|
std::vector<Task*>& callbacks_vector = callbacks_[name];
|
||||||
|
for (size_t i = 0; i < callbacks_vector.size(); ++i)
|
||||||
|
MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
|
||||||
|
callbacks_vector.clear();
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
|
CrosSettings::Get()->FireObservers(name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of SignedSettingsHelper::Callback.
|
||||||
|
virtual void OnStorePropertyCompleted(bool success,
|
||||||
|
const std::string& name,
|
||||||
|
const std::string& value) {
|
||||||
|
VLOG(1) << "Store cros setting " << name << "=" << value << ", success="
|
||||||
|
<< success;
|
||||||
|
|
||||||
|
// Reload the setting if store op fails.
|
||||||
|
if (!success)
|
||||||
|
SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of SignedSettingsHelper::Callback.
|
||||||
|
virtual void OnWhitelistCompleted(bool success, const std::string& email) {
|
||||||
|
VLOG(1) << "Add " << email << " to whitelist, success=" << success;
|
||||||
|
|
||||||
|
// Reload the whitelist on settings op failure.
|
||||||
|
if (!success)
|
||||||
|
CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of SignedSettingsHelper::Callback.
|
||||||
|
virtual void OnUnwhitelistCompleted(bool success, const std::string& email) {
|
||||||
|
VLOG(1) << "Remove " << email << " from whitelist, success=" << success;
|
||||||
|
|
||||||
|
// Reload the whitelist on settings op failure.
|
||||||
|
if (!success)
|
||||||
|
CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotificationObserver implementation.
|
||||||
|
virtual void Observe(NotificationType type,
|
||||||
|
const NotificationSource& source,
|
||||||
|
const NotificationDetails& details) {
|
||||||
|
if (type.value == NotificationType::OWNERSHIP_TAKEN) {
|
||||||
|
SetOwnershipStatus(OWNERSHIP_TAKEN, SOURCE_OBSERVE);
|
||||||
|
notification_registrar_.RemoveAll();
|
||||||
|
} else {
|
||||||
|
NOTREACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pending callbacks that need to be invoked after settings verification.
|
||||||
|
base::hash_map< std::string, std::vector< Task* > > callbacks_;
|
||||||
|
|
||||||
|
NotificationRegistrar notification_registrar_;
|
||||||
|
OwnershipStatus ownership_status_;
|
||||||
|
|
||||||
|
// In order to guard against occasional failure to fetch a property
|
||||||
|
// we allow for some number of retries.
|
||||||
|
int retries_left_;
|
||||||
|
|
||||||
|
friend class SignedSettingsHelper;
|
||||||
|
friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
UserCrosSettingsProvider::UserCrosSettingsProvider() {
|
} // namespace chromeos
|
||||||
StartFetchingBoolSetting(kAccountsPrefAllowGuest);
|
|
||||||
StartFetchingBoolSetting(kAccountsPrefAllowNewUser);
|
|
||||||
StartFetchingBoolSetting(kAccountsPrefShowUserNamesOnSignIn);
|
|
||||||
StartFetchingStringSetting(kDeviceOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserCrosSettingsProvider::~UserCrosSettingsProvider() {
|
// We want to use NewRunnableMethod with this class but need to disable
|
||||||
// Cancels all pending callbacks from us.
|
// reference counting since it is singleton.
|
||||||
SignedSettingsHelper::Get()->CancelCallback(this);
|
DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UserCrosSettingsTrust);
|
||||||
|
|
||||||
|
namespace chromeos {
|
||||||
|
|
||||||
|
UserCrosSettingsProvider::UserCrosSettingsProvider() {
|
||||||
|
// Trigger prefetching of settings.
|
||||||
|
UserCrosSettingsTrust::GetSharedInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
|
void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
|
||||||
// Cached signed settings values
|
for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
|
||||||
local_state->RegisterBooleanPref(kAccountsPrefAllowGuest, true);
|
RegisterSetting(local_state, kBooleanSettings[i]);
|
||||||
local_state->RegisterBooleanPref(kAccountsPrefAllowNewUser, true);
|
for (size_t i = 0; i < arraysize(kStringSettings); ++i)
|
||||||
local_state->RegisterBooleanPref(kAccountsPrefShowUserNamesOnSignIn, true);
|
RegisterSetting(local_state, kStringSettings[i]);
|
||||||
local_state->RegisterListPref(kAccountsPrefUsers);
|
for (size_t i = 0; i < arraysize(kListSettings); ++i)
|
||||||
local_state->RegisterStringPref(kDeviceOwner, "");
|
RegisterSetting(local_state, kListSettings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserCrosSettingsProvider::RequestTrustedAllowGuest(Task* callback) {
|
||||||
|
return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
|
||||||
|
kAccountsPrefAllowGuest, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserCrosSettingsProvider::RequestTrustedAllowNewUser(Task* callback) {
|
||||||
|
return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
|
||||||
|
kAccountsPrefAllowNewUser, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserCrosSettingsProvider::RequestTrustedShowUsersOnSignin(Task* callback) {
|
||||||
|
return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
|
||||||
|
kAccountsPrefShowUserNamesOnSignIn, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserCrosSettingsProvider::RequestTrustedOwner(Task* callback) {
|
||||||
|
return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
|
||||||
|
kDeviceOwner, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool UserCrosSettingsProvider::cached_allow_guest() {
|
bool UserCrosSettingsProvider::cached_allow_guest() {
|
||||||
|
// Trigger prefetching if singleton object still does not exist.
|
||||||
|
UserCrosSettingsTrust::GetSharedInstance();
|
||||||
return g_browser_process->local_state()->GetBoolean(kAccountsPrefAllowGuest);
|
return g_browser_process->local_state()->GetBoolean(kAccountsPrefAllowGuest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool UserCrosSettingsProvider::cached_allow_new_user() {
|
bool UserCrosSettingsProvider::cached_allow_new_user() {
|
||||||
|
// Trigger prefetching if singleton object still does not exist.
|
||||||
|
UserCrosSettingsTrust::GetSharedInstance();
|
||||||
return g_browser_process->local_state()->GetBoolean(
|
return g_browser_process->local_state()->GetBoolean(
|
||||||
kAccountsPrefAllowNewUser);
|
kAccountsPrefAllowNewUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool UserCrosSettingsProvider::cached_show_users_on_signin() {
|
bool UserCrosSettingsProvider::cached_show_users_on_signin() {
|
||||||
|
// Trigger prefetching if singleton object still does not exist.
|
||||||
|
UserCrosSettingsTrust::GetSharedInstance();
|
||||||
return g_browser_process->local_state()->GetBoolean(
|
return g_browser_process->local_state()->GetBoolean(
|
||||||
kAccountsPrefShowUserNamesOnSignIn);
|
kAccountsPrefShowUserNamesOnSignIn);
|
||||||
}
|
}
|
||||||
@@ -132,6 +502,8 @@ const ListValue* UserCrosSettingsProvider::cached_whitelist() {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
std::string UserCrosSettingsProvider::cached_owner() {
|
std::string UserCrosSettingsProvider::cached_owner() {
|
||||||
|
// Trigger prefetching if singleton object still does not exist.
|
||||||
|
UserCrosSettingsTrust::GetSharedInstance();
|
||||||
if (!g_browser_process || !g_browser_process->local_state())
|
if (!g_browser_process || !g_browser_process->local_state())
|
||||||
return std::string();
|
return std::string();
|
||||||
return g_browser_process->local_state()->GetString(kDeviceOwner);
|
return g_browser_process->local_state()->GetString(kDeviceOwner);
|
||||||
@@ -154,41 +526,12 @@ bool UserCrosSettingsProvider::IsEmailInCachedWhitelist(
|
|||||||
|
|
||||||
void UserCrosSettingsProvider::DoSet(const std::string& path,
|
void UserCrosSettingsProvider::DoSet(const std::string& path,
|
||||||
Value* in_value) {
|
Value* in_value) {
|
||||||
if (!UserManager::Get()->current_user_is_owner()) {
|
UserCrosSettingsTrust::GetSharedInstance()->Set(path, in_value);
|
||||||
LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
|
|
||||||
|
|
||||||
// Revert UI change.
|
|
||||||
CrosSettings::Get()->FireObservers(path.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path == kAccountsPrefAllowGuest ||
|
|
||||||
path == kAccountsPrefAllowNewUser ||
|
|
||||||
path == kAccountsPrefShowUserNamesOnSignIn) {
|
|
||||||
bool bool_value = false;
|
|
||||||
if (in_value->GetAsBoolean(&bool_value)) {
|
|
||||||
std::string value = bool_value ? "true" : "false";
|
|
||||||
SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
|
|
||||||
UpdateCacheBool(path.c_str(), bool_value);
|
|
||||||
|
|
||||||
VLOG(1) << "Set cros setting " << path << "=" << value;
|
|
||||||
}
|
|
||||||
} else if (path == kDeviceOwner) {
|
|
||||||
VLOG(1) << "Setting owner is not supported. Please use 'UpdateCachedOwner' "
|
|
||||||
"instead.";
|
|
||||||
} else if (path == kAccountsPrefUsers) {
|
|
||||||
VLOG(1) << "Setting user whitelist is not implemented. Please use "
|
|
||||||
"whitelist/unwhitelist instead.";
|
|
||||||
} else {
|
|
||||||
LOG(WARNING) << "Try to set unhandled cros setting " << path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserCrosSettingsProvider::Get(const std::string& path,
|
bool UserCrosSettingsProvider::Get(const std::string& path,
|
||||||
Value** out_value) const {
|
Value** out_value) const {
|
||||||
if (path == kAccountsPrefAllowGuest ||
|
if (IsControlledBooleanSetting(path)) {
|
||||||
path == kAccountsPrefAllowNewUser ||
|
|
||||||
path == kAccountsPrefShowUserNamesOnSignIn) {
|
|
||||||
*out_value = CreateSettingsBooleanValue(
|
*out_value = CreateSettingsBooleanValue(
|
||||||
g_browser_process->local_state()->GetBoolean(path.c_str()),
|
g_browser_process->local_state()->GetBoolean(path.c_str()),
|
||||||
!UserManager::Get()->current_user_is_owner());
|
!UserManager::Get()->current_user_is_owner());
|
||||||
@@ -207,56 +550,9 @@ bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
|
|||||||
return ::StartsWithASCII(path, "cros.accounts.", true);
|
return ::StartsWithASCII(path, "cros.accounts.", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserCrosSettingsProvider::OnWhitelistCompleted(bool success,
|
|
||||||
const std::string& email) {
|
|
||||||
VLOG(1) << "Add " << email << " to whitelist, success=" << success;
|
|
||||||
|
|
||||||
// Reload the whitelist on settings op failure.
|
|
||||||
if (!success)
|
|
||||||
CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::OnUnwhitelistCompleted(bool success,
|
|
||||||
const std::string& email) {
|
|
||||||
VLOG(1) << "Remove " << email << " from whitelist, success=" << success;
|
|
||||||
|
|
||||||
// Reload the whitelist on settings op failure.
|
|
||||||
if (!success)
|
|
||||||
CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::OnStorePropertyCompleted(
|
|
||||||
bool success, const std::string& name, const std::string& value) {
|
|
||||||
VLOG(1) << "Store cros setting " << name << "=" << value << ", success="
|
|
||||||
<< success;
|
|
||||||
|
|
||||||
// Reload the setting if store op fails.
|
|
||||||
if (!success)
|
|
||||||
SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::OnRetrievePropertyCompleted(
|
|
||||||
bool success, const std::string& name, const std::string& value) {
|
|
||||||
if (!success) {
|
|
||||||
LOG(WARNING) << "Failed to retrieve cros setting, name=" << name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VLOG(1) << "Retrieved cros setting " << name << "=" << value;
|
|
||||||
|
|
||||||
if (bool_settings_.count(name)) {
|
|
||||||
UpdateCacheBool(name.c_str(), value == "true" ? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string_settings_.count(name)) {
|
|
||||||
UpdateCacheString(name.c_str(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
CrosSettings::Get()->FireObservers(name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
|
void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
|
||||||
SignedSettingsHelper::Get()->StartWhitelistOp(email, true, this);
|
SignedSettingsHelper::Get()->StartWhitelistOp(
|
||||||
|
email, true, UserCrosSettingsTrust::GetSharedInstance());
|
||||||
|
|
||||||
PrefService* prefs = g_browser_process->local_state();
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
|
ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
|
||||||
@@ -265,7 +561,8 @@ void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
|
void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
|
||||||
SignedSettingsHelper::Get()->StartWhitelistOp(email, false, this);
|
SignedSettingsHelper::Get()->StartWhitelistOp(
|
||||||
|
email, false, UserCrosSettingsTrust::GetSharedInstance());
|
||||||
|
|
||||||
PrefService* prefs = g_browser_process->local_state();
|
PrefService* prefs = g_browser_process->local_state();
|
||||||
ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
|
ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
|
||||||
@@ -276,25 +573,7 @@ void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void UserCrosSettingsProvider::UpdateCachedOwner(const std::string& email) {
|
void UserCrosSettingsProvider::UpdateCachedOwner(const std::string& email) {
|
||||||
UpdateCacheString(kDeviceOwner, email);
|
UpdateCacheString(kDeviceOwner, email, USE_VALUE_SUPPLIED);
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::StartFetchingBoolSetting(
|
|
||||||
const std::string& name) {
|
|
||||||
bool_settings_.insert(name);
|
|
||||||
StartFetchingSetting(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::StartFetchingStringSetting(
|
|
||||||
const std::string& name) {
|
|
||||||
string_settings_.insert(name);
|
|
||||||
StartFetchingSetting(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserCrosSettingsProvider::StartFetchingSetting(
|
|
||||||
const std::string& name) {
|
|
||||||
if (CrosLibrary::Get()->EnsureLoaded())
|
|
||||||
SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chromeos
|
} // namespace chromeos
|
||||||
|
@@ -9,24 +9,33 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "base/hash_tables.h"
|
|
||||||
#include "chrome/browser/chromeos/cros_settings_provider.h"
|
#include "chrome/browser/chromeos/cros_settings_provider.h"
|
||||||
#include "chrome/browser/chromeos/login/signed_settings_helper.h"
|
#include "chrome/browser/chromeos/login/signed_settings_helper.h"
|
||||||
|
|
||||||
class ListValue;
|
class ListValue;
|
||||||
class PrefService;
|
class PrefService;
|
||||||
|
class Task;
|
||||||
|
|
||||||
namespace chromeos {
|
namespace chromeos {
|
||||||
|
|
||||||
class UserCrosSettingsProvider : public CrosSettingsProvider,
|
class UserCrosSettingsProvider : public CrosSettingsProvider {
|
||||||
public SignedSettingsHelper::Callback {
|
|
||||||
public:
|
public:
|
||||||
UserCrosSettingsProvider();
|
UserCrosSettingsProvider();
|
||||||
virtual ~UserCrosSettingsProvider();
|
virtual ~UserCrosSettingsProvider() {}
|
||||||
|
|
||||||
// Registers cached users settings in preferences.
|
// Registers cached users settings in preferences.
|
||||||
static void RegisterPrefs(PrefService* local_state);
|
static void RegisterPrefs(PrefService* local_state);
|
||||||
|
|
||||||
|
// Methods to use when trusted (signature verified) values are required.
|
||||||
|
// Return true if subsequent call to corresponding cached_* getter shall
|
||||||
|
// return trusted value.
|
||||||
|
// Return false if trusted values are unavailable at a moment.
|
||||||
|
// In latter case passed task will be posted when ready.
|
||||||
|
bool RequestTrustedAllowGuest(Task* callback);
|
||||||
|
bool RequestTrustedAllowNewUser(Task* callback);
|
||||||
|
bool RequestTrustedShowUsersOnSignin(Task* callback);
|
||||||
|
bool RequestTrustedOwner(Task* callback);
|
||||||
|
|
||||||
// Helper functions to access cached settings.
|
// Helper functions to access cached settings.
|
||||||
static bool cached_allow_guest();
|
static bool cached_allow_guest();
|
||||||
static bool cached_allow_new_user();
|
static bool cached_allow_new_user();
|
||||||
@@ -43,14 +52,6 @@ class UserCrosSettingsProvider : public CrosSettingsProvider,
|
|||||||
virtual bool Get(const std::string& path, Value** out_value) const;
|
virtual bool Get(const std::string& path, Value** out_value) const;
|
||||||
virtual bool HandlesSetting(const std::string& path);
|
virtual bool HandlesSetting(const std::string& path);
|
||||||
|
|
||||||
// SignedSettingsHelper::Callback overrides.
|
|
||||||
virtual void OnWhitelistCompleted(bool success, const std::string& email);
|
|
||||||
virtual void OnUnwhitelistCompleted(bool success, const std::string& email);
|
|
||||||
virtual void OnStorePropertyCompleted(
|
|
||||||
bool success, const std::string& name, const std::string& value);
|
|
||||||
virtual void OnRetrievePropertyCompleted(
|
|
||||||
bool success, const std::string& name, const std::string& value);
|
|
||||||
|
|
||||||
void WhitelistUser(const std::string& email);
|
void WhitelistUser(const std::string& email);
|
||||||
void UnwhitelistUser(const std::string& email);
|
void UnwhitelistUser(const std::string& email);
|
||||||
|
|
||||||
@@ -61,13 +62,6 @@ class UserCrosSettingsProvider : public CrosSettingsProvider,
|
|||||||
// CrosSettingsProvider implementation.
|
// CrosSettingsProvider implementation.
|
||||||
virtual void DoSet(const std::string& path, Value* value);
|
virtual void DoSet(const std::string& path, Value* value);
|
||||||
|
|
||||||
void StartFetchingBoolSetting(const std::string& name);
|
|
||||||
void StartFetchingStringSetting(const std::string& name);
|
|
||||||
void StartFetchingSetting(const std::string& name);
|
|
||||||
|
|
||||||
base::hash_set<std::string> bool_settings_;
|
|
||||||
base::hash_set<std::string> string_settings_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsProvider);
|
DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsProvider);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1243,6 +1243,9 @@ class NotificationType {
|
|||||||
// os device has failed.
|
// os device has failed.
|
||||||
OWNER_KEY_FETCH_ATTEMPT_FAILED,
|
OWNER_KEY_FETCH_ATTEMPT_FAILED,
|
||||||
|
|
||||||
|
// Sent after device was successfully owned.
|
||||||
|
OWNERSHIP_TAKEN,
|
||||||
|
|
||||||
// This is sent to a ChromeOS settings observer when a system setting is
|
// This is sent to a ChromeOS settings observer when a system setting is
|
||||||
// changed. The source is the CrosSettings and the details a std::string of
|
// changed. The source is the CrosSettings and the details a std::string of
|
||||||
// the changed setting.
|
// the changed setting.
|
||||||
|
Reference in New Issue
Block a user