1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_ 6 #define CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_ 7 8 #include <deque> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/callback.h" 14 #include "base/compiler_specific.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/observer_list.h" 18 #include "chromeos/dbus/session_manager_client.h" 19 #include "components/policy/core/common/cloud/cloud_policy_validator.h" 20 #include "crypto/scoped_nss_types.h" 21 #include "policy/proto/device_management_backend.pb.h" 22 23 namespace crypto { 24 class RSAPrivateKey; 25 } 26 27 namespace enterprise_management { 28 class ChromeDeviceSettingsProto; 29 } 30 31 namespace chromeos { 32 33 class OwnerKeyUtil; 34 class PublicKey; 35 class SessionManagerOperation; 36 37 // Deals with the low-level interface to Chromium OS device settings. Device 38 // settings are stored in a protobuf that's protected by a cryptographic 39 // signature generated by a key in the device owner's possession. Key and 40 // settings are brokered by the session_manager daemon. 41 // 42 // The purpose of DeviceSettingsService is to keep track of the current key and 43 // settings blob. For reading and writing device settings, use CrosSettings 44 // instead, which provides a high-level interface that allows for manipulation 45 // of individual settings. 46 // 47 // DeviceSettingsService generates notifications for key and policy update 48 // events so interested parties can reload state as appropriate. 49 class DeviceSettingsService : public SessionManagerClient::Observer { 50 public: 51 // Indicates ownership status of the device. 52 enum OwnershipStatus { 53 // Listed in upgrade order. 54 OWNERSHIP_UNKNOWN = 0, 55 OWNERSHIP_NONE, 56 OWNERSHIP_TAKEN 57 }; 58 59 typedef base::Callback<void(OwnershipStatus)> OwnershipStatusCallback; 60 61 // Status codes for Store(). 62 enum Status { 63 STORE_SUCCESS, 64 STORE_KEY_UNAVAILABLE, // Owner key not yet configured. 65 STORE_POLICY_ERROR, // Failure constructing the settings blob. 66 STORE_OPERATION_FAILED, // IPC to session_manager daemon failed. 67 STORE_NO_POLICY, // No settings blob present. 68 STORE_INVALID_POLICY, // Invalid settings blob. 69 STORE_VALIDATION_ERROR, // Unrecoverable policy validation failure. 70 STORE_TEMP_VALIDATION_ERROR, // Temporary policy validation failure. 71 }; 72 73 // Observer interface. 74 class Observer { 75 public: 76 virtual ~Observer(); 77 78 // Indicates device ownership status changes. 79 virtual void OwnershipStatusChanged() = 0; 80 81 // Gets call after updates to the device settings. 82 virtual void DeviceSettingsUpdated() = 0; 83 }; 84 85 class PrivateKeyDelegate { 86 public: 87 typedef base::Callback<void(bool is_owner)> IsOwnerCallback; 88 typedef base::Callback<void(std::string policy_blob)> 89 AssembleAndSignPolicyCallback; 90 91 virtual ~PrivateKeyDelegate() {} 92 93 // Returns whether current user is owner or not. When this method 94 // is called too early, incorrect result can be returned because 95 // private key loading may be in progress. 96 virtual bool IsOwner() = 0; 97 98 // Determines whether current user is owner or not, responds via 99 // |callback|. 100 virtual void IsOwnerAsync(const IsOwnerCallback& callback) = 0; 101 102 // Assembles and signs |policy|, responds via |callback|. 103 virtual bool AssembleAndSignPolicyAsync( 104 scoped_ptr<enterprise_management::PolicyData> policy, 105 const AssembleAndSignPolicyCallback& callback) = 0; 106 }; 107 108 // Manage singleton instance. 109 static void Initialize(); 110 static bool IsInitialized(); 111 static void Shutdown(); 112 static DeviceSettingsService* Get(); 113 114 // Creates a device settings service instance. This is meant for unit tests, 115 // production code uses the singleton returned by Get() above. 116 DeviceSettingsService(); 117 virtual ~DeviceSettingsService(); 118 119 // To be called on startup once threads are initialized and DBus is ready. 120 void SetSessionManager(SessionManagerClient* session_manager_client, 121 scoped_refptr<OwnerKeyUtil> owner_key_util); 122 123 // Prevents the service from making further calls to session_manager_client 124 // and stops any pending operations. 125 void UnsetSessionManager(); 126 127 // Returns the currently active device settings. Returns NULL if the device 128 // settings have not been retrieved from session_manager yet. 129 const enterprise_management::PolicyData* policy_data() { 130 return policy_data_.get(); 131 } 132 const enterprise_management::ChromeDeviceSettingsProto* 133 device_settings() const { 134 return device_settings_.get(); 135 } 136 137 // Returns the currently used owner key. 138 scoped_refptr<PublicKey> GetPublicKey(); 139 140 // Returns the status generated by the last operation. 141 Status status() { 142 return store_status_; 143 } 144 145 // Triggers an attempt to pull the public half of the owner key from disk and 146 // load the device settings. 147 void Load(); 148 149 // Signs |settings| with the private half of the owner key and sends the 150 // resulting policy blob to session manager for storage. The result of the 151 // operation is reported through |callback|. If successful, the updated device 152 // settings are present in policy_data() and device_settings() when the 153 // callback runs. 154 void SignAndStore( 155 scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> new_settings, 156 const base::Closure& callback); 157 158 // Sets the management related settings in PolicyData. Note that if 159 // |management_mode| is NOT_MANAGED, |request_token| and |device_id| should be 160 // empty strings. 161 void SetManagementSettings( 162 enterprise_management::PolicyData::ManagementMode management_mode, 163 const std::string& request_token, 164 const std::string& device_id, 165 const base::Closure& callback); 166 167 // Stores a policy blob to session_manager. The result of the operation is 168 // reported through |callback|. If successful, the updated device settings are 169 // present in policy_data() and device_settings() when the callback runs. 170 void Store(scoped_ptr<enterprise_management::PolicyFetchResponse> policy, 171 const base::Closure& callback); 172 173 // Returns the ownership status. May return OWNERSHIP_UNKNOWN if the disk 174 // hasn't been checked yet. 175 OwnershipStatus GetOwnershipStatus(); 176 177 // Determines the ownership status and reports the result to |callback|. This 178 // is guaranteed to never return OWNERSHIP_UNKNOWN. 179 void GetOwnershipStatusAsync(const OwnershipStatusCallback& callback); 180 181 // Checks whether we have the private owner key. 182 bool HasPrivateOwnerKey(); 183 184 // Sets the identity of the user that's interacting with the service. This is 185 // relevant only for writing settings through SignAndStore(). 186 void InitOwner(const std::string& username, 187 const base::WeakPtr<PrivateKeyDelegate>& delegate); 188 const std::string& GetUsername() const; 189 190 // Adds an observer. 191 void AddObserver(Observer* observer); 192 // Removes an observer. 193 void RemoveObserver(Observer* observer); 194 195 // SessionManagerClient::Observer: 196 virtual void OwnerKeySet(bool success) OVERRIDE; 197 virtual void PropertyChangeComplete(bool success) OVERRIDE; 198 199 private: 200 // Enqueues a new operation. Takes ownership of |operation| and starts it 201 // right away if there is no active operation currently. 202 void Enqueue(SessionManagerOperation* operation); 203 204 // Enqueues a load operation. 205 void EnqueueLoad(bool force_key_load); 206 207 void EnqueueSignAndStore(scoped_ptr<enterprise_management::PolicyData> policy, 208 const base::Closure& callback); 209 210 // Makes sure there's a reload operation so changes to the settings (and key, 211 // in case force_key_load is set) are getting picked up. 212 void EnsureReload(bool force_key_load); 213 214 // Runs the next pending operation. 215 void StartNextOperation(); 216 217 // Updates status, policy data and owner key from a finished operation. 218 // Starts the next pending operation if available. 219 void HandleCompletedOperation(const base::Closure& callback, 220 SessionManagerOperation* operation, 221 Status status); 222 223 // Updates status and invokes the callback immediately. 224 void HandleError(Status status, const base::Closure& callback); 225 226 // Assembles PolicyData based on |settings| and the current |policy_data_| 227 // and |username_|. 228 scoped_ptr<enterprise_management::PolicyData> AssemblePolicy( 229 const enterprise_management::ChromeDeviceSettingsProto& settings) const; 230 231 // Returns the current management mode. 232 enterprise_management::PolicyData::ManagementMode GetManagementMode() const; 233 234 // Returns true if it is okay to transfer from the current mode to the new 235 // mode. This function should be called in SetManagementMode(). 236 bool CheckManagementModeTransition( 237 enterprise_management::PolicyData::ManagementMode new_mode) const; 238 239 SessionManagerClient* session_manager_client_; 240 scoped_refptr<OwnerKeyUtil> owner_key_util_; 241 242 Status store_status_; 243 244 std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_; 245 246 std::string username_; 247 scoped_refptr<PublicKey> public_key_; 248 base::WeakPtr<PrivateKeyDelegate> delegate_; 249 250 scoped_ptr<enterprise_management::PolicyData> policy_data_; 251 scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> device_settings_; 252 253 // The queue of pending operations. The first operation on the queue is 254 // currently active; it gets removed and destroyed once it completes. 255 std::deque<SessionManagerOperation*> pending_operations_; 256 257 ObserverList<Observer, true> observers_; 258 259 // For recoverable load errors how many retries are left before we give up. 260 int load_retries_left_; 261 262 base::WeakPtrFactory<DeviceSettingsService> weak_factory_; 263 264 DISALLOW_COPY_AND_ASSIGN(DeviceSettingsService); 265 }; 266 267 // Helper class for tests. Initializes the DeviceSettingsService singleton on 268 // construction and tears it down again on destruction. 269 class ScopedTestDeviceSettingsService { 270 public: 271 ScopedTestDeviceSettingsService(); 272 ~ScopedTestDeviceSettingsService(); 273 274 private: 275 DISALLOW_COPY_AND_ASSIGN(ScopedTestDeviceSettingsService); 276 }; 277 278 } // namespace chromeos 279 280 #endif // CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_ 281