1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
#define CHROME_BROWSER_ASH_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
#include <memory>
#include <string>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
#include "components/ownership/owner_settings_service.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_validator.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"
class PrefService;
namespace ownership {
class OwnerKeyUtil;
class PublicKey;
} // namespace ownership
namespace policy {
namespace off_hours {
class DeviceOffHoursController;
} // namespace off_hours
} // namespace policy
namespace ash {
class SessionManagerOperation;
// Deals with the low-level interface to Chrome OS device settings. Device
// settings are stored in a protobuf that's protected by a cryptographic
// signature generated by a key in the device owner's possession. Key and
// settings are brokered by the session_manager daemon.
//
// The purpose of DeviceSettingsService is to keep track of the current key and
// settings blob. For reading and writing device settings, use CrosSettings
// instead, which provides a high-level interface that allows for manipulation
// of individual settings.
//
// DeviceSettingsService generates notifications for key and policy update
// events so interested parties can reload state as appropriate.
class DeviceSettingsService : public SessionManagerClient::Observer {
public:
// Indicates ownership status of the device (listed in upgrade order).
enum class OwnershipStatus {
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
kOwnershipUnknown = 0,
// Not yet owned.
kOwnershipNone = 1,
// Either consumer ownership or cloud management.
kOwnershipTaken = 2,
kMaxValue = kOwnershipTaken
};
using OwnershipStatusCallback = base::OnceCallback<void(OwnershipStatus)>;
using PolicyDataCallback =
base::OnceCallback<void(enterprise_management::PolicyData*)>;
// Status codes for Load() and Store().
// These values are logged to UMA. Entries should not be renumbered and
// numeric values should never be reused. Please keep in sync with
// "DeviceSettingsStatus" in src/tools/metrics/histograms/enums.xml.
enum Status {
STORE_SUCCESS,
STORE_KEY_UNAVAILABLE, // Owner key not yet configured.
STORE_OPERATION_FAILED, // IPC to session_manager daemon failed.
STORE_NO_POLICY, // No settings blob present.
STORE_INVALID_POLICY, // Invalid settings blob (proto parse failed).
STORE_VALIDATION_ERROR, // Policy validation failure.
kMaxValue = STORE_VALIDATION_ERROR,
};
// Observer interface.
class Observer {
public:
virtual ~Observer();
// Indicates device ownership status changes. This is triggered upon every
// browser start since the transition from uninitialized (OWNERSHIP_UNKNOWN)
// to initialized (either of OWNERSHIP_{NONE,TAKEN}) also counts as an
// ownership change.
virtual void OwnershipStatusChanged();
// Gets called after updates to the device settings.
virtual void DeviceSettingsUpdated();
virtual void OnDeviceSettingsServiceShutdown();
};
// Manage singleton instance.
static void Initialize();
static bool IsInitialized();
static void Shutdown();
static DeviceSettingsService* Get();
// Returns a human-readable string describing |status|.
static const char* StatusToString(Status status);
// Creates a device settings service instance. This is meant for unit tests,
// production code uses the singleton returned by Get() above.
DeviceSettingsService();
DeviceSettingsService(const DeviceSettingsService&) = delete;
DeviceSettingsService& operator=(const DeviceSettingsService&) = delete;
~DeviceSettingsService() override;
// To be called on startup once threads are initialized and D-Bus is ready.
// `local_state` must be valid until `StopProcessing()`. `local_state` may be
// null only in tests.
void StartProcessing(PrefService* local_state,
SessionManagerClient* session_manager_client,
scoped_refptr<ownership::OwnerKeyUtil> owner_key_util);
// Prevents the service from making further calls to session_manager_client
// and stops any pending operations.
void StopProcessing();
// Must only be used with a |device_mode| that has been read and verified by
// the InstallAttributes class.
void SetDeviceMode(policy::DeviceMode device_mode);
const enterprise_management::PolicyData* policy_data() const {
return policy_data_.get();
}
const enterprise_management::PolicyFetchResponse* policy_fetch_response()
const {
return policy_fetch_response_.get();
}
// Returns the currently active device settings. Returns nullptr if the device
// settings have not been retrieved from session_manager yet.
const enterprise_management::ChromeDeviceSettingsProto* device_settings()
const {
return device_settings_.get();
}
// Returns the currently used owner key.
scoped_refptr<ownership::PublicKey> GetPublicKey();
// Returns the status generated by the *last operation*.
// WARNING: It is not correct to take this method as an indication of whether
// DeviceSettingsService contains valid device settings. In order to answer
// that question, simply check whether device_settings() is different from
// nullptr.
Status status() const { return store_status_; }
// Returns the currently device off hours controller. The returned pointer is
// guaranteed to be non-null.
policy::off_hours::DeviceOffHoursController* device_off_hours_controller()
const {
return device_off_hours_controller_.get();
}
void SetDeviceOffHoursControllerForTesting(
std::unique_ptr<policy::off_hours::DeviceOffHoursController> controller);
// Triggers an attempt to pull the public half of the owner key from disk and
// load the device settings.
void Load();
// Attempts to load asynchronously the settings if they haven't been loaded
// already and no request is in the queue. The aim is to avoid additional
// request when not needed. Should NOT be used when the settings need to be
// renewed, like in invalidations flow or when an explicit request from user
// to reload is received.
void LoadIfNotPresent();
// Synchronously pulls the public key and loads the device settings.
void LoadImmediately();
// Stores a policy blob to session_manager. 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.
void Store(std::unique_ptr<enterprise_management::PolicyFetchResponse> policy,
base::OnceClosure callback);
// Returns the ownership status. May return OWNERSHIP_UNKNOWN if the disk
// hasn't been checked yet.
OwnershipStatus GetOwnershipStatus();
// Determines the ownership status and reports the result to |callback|. This
// is guaranteed to never return OWNERSHIP_UNKNOWN.
virtual void GetOwnershipStatusAsync(OwnershipStatusCallback callback);
// Checks whether we have the private owner key.
//
// DEPRECATED (ygorshenin@, crbug.com/433840): this method should
// not be used since private key is a profile-specific resource and
// should be checked and used in a profile-aware manner, through
// OwnerSettingsService.
bool HasPrivateOwnerKey();
// Sets the identity of the user that's interacting with the service. This is
// relevant only for writing settings through SignAndStore().
//
// TODO (ygorshenin@, crbug.com/433840): get rid of the method when
// write path for device settings will be removed from
// DeviceSettingsProvider and all existing clients will be switched
// to OwnerSettingsServiceAsh.
void InitOwner(const std::string& username,
const base::WeakPtr<ownership::OwnerSettingsService>&
owner_settings_service);
const std::string& GetUsername() const;
ownership::OwnerSettingsService* GetOwnerSettingsService() const;
// Mark that the device will establish consumer ownership. If the flag is set
// and ownership is not taken, policy reload will be deferred until InitOwner
// is called. So that the ownership status is flipped after the private part
// of owner is fully loaded.
void MarkWillEstablishConsumerOwnership();
// Returns whether the current user should take ownership of the device
// (effectively whether the user is the first consumer user on the device).
bool GetWillEstablishConsumerOwnership() const {
return will_establish_consumer_ownership_;
}
// Returns if the device is managed according to the device settings.
bool IsDeviceManaged() const;
// Returns if the device policy is loaded and contains the DM token.
bool HasDmToken() const;
// Adds an observer.
void AddObserver(Observer* observer);
// Removes an observer.
void RemoveObserver(Observer* observer);
// SessionManagerClient::Observer:
void OwnerKeySet(bool success) override;
void PropertyChangeComplete(bool success) override;
void SessionStopping() override;
private:
friend class OwnerSettingsServiceAsh;
// Enqueues a new operation. Takes ownership of |operation| and starts it
// right away if there is no active operation currently.
void Enqueue(std::unique_ptr<SessionManagerOperation> operation);
// Enqueues a load operation.
void EnqueueLoad(bool request_key_load);
// Makes sure there's a reload operation so changes to the settings (and key,
// in case |request_key_load| is set) are getting picked up.
void EnsureReload(bool request_key_load);
// Runs the next pending operation.
void StartNextOperation();
// Updates status, policy data and owner key from a finished operation.
void HandleCompletedOperation(base::OnceClosure callback,
SessionManagerOperation* operation,
Status status);
// Same as HandleCompletedOperation(), but also starts the next pending
// operation if available.
void HandleCompletedAsyncOperation(base::OnceClosure callback,
SessionManagerOperation* operation,
Status status);
// Helper method for GetOwnershipStatusAsync to avoid data race upon
// user sign-in.
void ValidateOwnershipStatusAndNotify(OwnershipStatusCallback callback);
// Run OwnershipStatusChanged() for observers.
void NotifyOwnershipStatusChanged() const;
// Run DeviceSettingsUpdated() for observers.
void NotifyDeviceSettingsUpdated() const;
// Processes pending callbacks from GetOwnershipStatusAsync().
void RunPendingOwnershipStatusCallbacks();
raw_ptr<PrefService> local_state_ = nullptr;
raw_ptr<SessionManagerClient> session_manager_client_ = nullptr;
scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_;
Status store_status_ = STORE_SUCCESS;
std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;
std::string username_;
scoped_refptr<ownership::PublicKey> public_key_;
base::WeakPtr<ownership::OwnerSettingsService> owner_settings_service_;
// Ownership status before the current session manager operation.
OwnershipStatus previous_ownership_status_ =
OwnershipStatus::kOwnershipUnknown;
std::unique_ptr<enterprise_management::PolicyFetchResponse>
policy_fetch_response_;
std::unique_ptr<enterprise_management::PolicyData> policy_data_;
std::unique_ptr<enterprise_management::ChromeDeviceSettingsProto>
device_settings_;
policy::DeviceMode device_mode_ = policy::DEVICE_MODE_PENDING;
// The queue of pending operations. The first operation on the queue is
// currently active; it gets removed and destroyed once it completes.
base::circular_deque<std::unique_ptr<SessionManagerOperation>>
pending_operations_;
base::ObserverList<Observer>::Unchecked observers_;
// Whether the device will be establishing consumer ownership.
bool will_establish_consumer_ownership_ = false;
// Whether we received the signal that the session is stopping.
bool session_stopping_ = false;
std::unique_ptr<policy::off_hours::DeviceOffHoursController>
device_off_hours_controller_;
base::WeakPtrFactory<DeviceSettingsService> weak_factory_{this};
};
std::ostream& operator<<(std::ostream&, DeviceSettingsService::OwnershipStatus);
} // namespace ash
#endif // CHROME_BROWSER_ASH_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
|