• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/cert_loader.h"
19 #include "chromeos/dbus/session_manager_client.h"
20 #include "components/policy/core/common/cloud/cloud_policy_validator.h"
21 
22 namespace crypto {
23 class RSAPrivateKey;
24 }
25 
26 namespace enterprise_management {
27 class ChromeDeviceSettingsProto;
28 class PolicyData;
29 class PolicyFetchResponse;
30 }
31 
32 namespace chromeos {
33 
34 class OwnerKeyUtil;
35 class SessionManagerOperation;
36 
37 // Keeps the public and private halves of the owner key. Both may be missing,
38 // but if the private key is present, the public half will be as well. This
39 // class is immutable and refcounted in order to allow safe access from any
40 // thread.
41 class OwnerKey : public base::RefCountedThreadSafe<OwnerKey> {
42  public:
43   OwnerKey(scoped_ptr<std::vector<uint8> > public_key,
44            scoped_ptr<crypto::RSAPrivateKey> private_key);
45 
public_key()46   const std::vector<uint8>* public_key() {
47     return public_key_.get();
48   }
private_key()49   crypto::RSAPrivateKey* private_key() {
50     return private_key_.get();
51   }
52 
53  private:
54   friend class base::RefCountedThreadSafe<OwnerKey>;
55   ~OwnerKey();
56 
57   scoped_ptr<std::vector<uint8> > public_key_;
58   scoped_ptr<crypto::RSAPrivateKey> private_key_;
59 
60   DISALLOW_COPY_AND_ASSIGN(OwnerKey);
61 };
62 
63 // Deals with the low-level interface to Chromium OS device settings. Device
64 // settings are stored in a protobuf that's protected by a cryptographic
65 // signature generated by a key in the device owner's possession. Key and
66 // settings are brokered by the session_manager daemon.
67 //
68 // The purpose of DeviceSettingsService is to keep track of the current key and
69 // settings blob. For reading and writing device settings, use CrosSettings
70 // instead, which provides a high-level interface that allows for manipulation
71 // of individual settings.
72 //
73 // DeviceSettingsService generates notifications for key and policy update
74 // events so interested parties can reload state as appropriate.
75 class DeviceSettingsService : public SessionManagerClient::Observer,
76                               public CertLoader::Observer {
77  public:
78   // Indicates ownership status of the device.
79   enum OwnershipStatus {
80     // Listed in upgrade order.
81     OWNERSHIP_UNKNOWN = 0,
82     OWNERSHIP_NONE,
83     OWNERSHIP_TAKEN
84   };
85 
86   typedef base::Callback<void(OwnershipStatus)> OwnershipStatusCallback;
87   typedef base::Callback<void(bool)> IsCurrentUserOwnerCallback;
88 
89   // Status codes for Store().
90   enum Status {
91     STORE_SUCCESS,
92     STORE_KEY_UNAVAILABLE,       // Owner key not yet configured.
93     STORE_POLICY_ERROR,          // Failure constructing the settings blob.
94     STORE_OPERATION_FAILED,      // IPC to session_manager daemon failed.
95     STORE_NO_POLICY,             // No settings blob present.
96     STORE_INVALID_POLICY,        // Invalid settings blob.
97     STORE_VALIDATION_ERROR,      // Unrecoverable policy validation failure.
98     STORE_TEMP_VALIDATION_ERROR, // Temporary policy validation failure.
99   };
100 
101   // Observer interface.
102   class Observer {
103    public:
104     virtual ~Observer();
105 
106     // Indicates device ownership status changes.
107     virtual void OwnershipStatusChanged() = 0;
108 
109     // Gets call after updates to the device settings.
110     virtual void DeviceSettingsUpdated() = 0;
111   };
112 
113   // Manage singleton instance.
114   static void Initialize();
115   static bool IsInitialized();
116   static void Shutdown();
117   static DeviceSettingsService* Get();
118 
119   // Creates a device settings service instance. This is meant for unit tests,
120   // production code uses the singleton returned by Get() above.
121   DeviceSettingsService();
122   virtual ~DeviceSettingsService();
123 
124   // To be called on startup once threads are initialized and DBus is ready.
125   void SetSessionManager(SessionManagerClient* session_manager_client,
126                          scoped_refptr<OwnerKeyUtil> owner_key_util);
127 
128   // Prevents the service from making further calls to session_manager_client
129   // and stops any pending operations.
130   void UnsetSessionManager();
131 
132   // Returns the currently active device settings. Returns NULL if the device
133   // settings have not been retrieved from session_manager yet.
policy_data()134   const enterprise_management::PolicyData* policy_data() {
135     return policy_data_.get();
136   }
137   const enterprise_management::ChromeDeviceSettingsProto*
device_settings()138       device_settings() const {
139     return device_settings_.get();
140   }
141 
142   // Returns the currently used owner key.
143   scoped_refptr<OwnerKey> GetOwnerKey();
144 
145   // Returns the status generated by the last operation.
status()146   Status status() {
147     return store_status_;
148   }
149 
150   // Triggers an attempt to pull the public half of the owner key from disk and
151   // load the device settings.
152   void Load();
153 
154   // Signs |settings| with the private half of the owner key and sends the
155   // resulting policy blob to session manager for storage. The result of the
156   // operation is reported through |callback|. If successful, the updated device
157   // settings are present in policy_data() and device_settings() when the
158   // callback runs.
159   void SignAndStore(
160       scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> new_settings,
161       const base::Closure& callback);
162 
163   // Stores a policy blob to session_manager. The result of the operation is
164   // reported through |callback|. If successful, the updated device settings are
165   // present in policy_data() and device_settings() when the callback runs.
166   void Store(scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
167              const base::Closure& callback);
168 
169   // Returns the ownership status. May return OWNERSHIP_UNKNOWN if the disk
170   // hasn't been checked yet.
171   OwnershipStatus GetOwnershipStatus();
172 
173   // Determines the ownership status and reports the result to |callback|. This
174   // is guaranteed to never return OWNERSHIP_UNKNOWN.
175   void GetOwnershipStatusAsync(const OwnershipStatusCallback& callback);
176 
177   // Checks whether we have the private owner key.
178   bool HasPrivateOwnerKey();
179 
180   // Determines whether the current user is the owner. The callback is
181   // guaranteed not to be called before it is possible to determine if the
182   // current user is the owner (by testing existence of the private owner key).
183   void IsCurrentUserOwnerAsync(const IsCurrentUserOwnerCallback& callback);
184 
185   // Sets the identity of the user that's interacting with the service. This is
186   // relevant only for writing settings through SignAndStore().
187   void SetUsername(const std::string& username);
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   // CertLoader::Observer:
200   virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
201                                     bool initial_load) OVERRIDE;
202 
203  private:
204   // Enqueues a new operation. Takes ownership of |operation| and starts it
205   // right away if there is no active operation currently.
206   void Enqueue(SessionManagerOperation* operation);
207 
208   // Enqueues a load operation.
209   void EnqueueLoad(bool force_key_load);
210 
211   // Makes sure there's a reload operation so changes to the settings (and key,
212   // in case force_key_load is set) are getting picked up.
213   void EnsureReload(bool force_key_load);
214 
215   // Runs the next pending operation.
216   void StartNextOperation();
217 
218   // Updates status, policy data and owner key from a finished operation.
219   // Starts the next pending operation if available.
220   void HandleCompletedOperation(const base::Closure& callback,
221                                 SessionManagerOperation* operation,
222                                 Status status);
223 
224   SessionManagerClient* session_manager_client_;
225   scoped_refptr<OwnerKeyUtil> owner_key_util_;
226 
227   base::WeakPtrFactory<DeviceSettingsService> weak_factory_;
228 
229   Status store_status_;
230 
231   std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;
232   std::vector<IsCurrentUserOwnerCallback>
233       pending_is_current_user_owner_callbacks_;
234 
235   std::string username_;
236   scoped_refptr<OwnerKey> owner_key_;
237   // Whether certificates have been loaded by CertLoader.
238   bool certificates_loaded_;
239   // Whether certificates were loaded when the current owner key was set.
240   // Implies that the current user is owner iff the private owner key is set.
241   bool owner_key_loaded_with_certificates_;
242 
243   scoped_ptr<enterprise_management::PolicyData> policy_data_;
244   scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> device_settings_;
245 
246   // The queue of pending operations. The first operation on the queue is
247   // currently active; it gets removed and destroyed once it completes.
248   std::deque<SessionManagerOperation*> pending_operations_;
249 
250   ObserverList<Observer, true> observers_;
251 
252   // For recoverable load errors how many retries are left before we give up.
253   int load_retries_left_;
254 
255   DISALLOW_COPY_AND_ASSIGN(DeviceSettingsService);
256 };
257 
258 // Helper class for tests. Initializes the DeviceSettingsService singleton on
259 // construction and tears it down again on destruction.
260 class ScopedTestDeviceSettingsService {
261  public:
262   ScopedTestDeviceSettingsService();
263   ~ScopedTestDeviceSettingsService();
264 
265  private:
266   DISALLOW_COPY_AND_ASSIGN(ScopedTestDeviceSettingsService);
267 };
268 
269 }  // namespace chromeos
270 
271 #endif  // CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_SERVICE_H_
272