• 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/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 
~PrivateKeyDelegate()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.
policy_data()129   const enterprise_management::PolicyData* policy_data() {
130     return policy_data_.get();
131   }
132   const enterprise_management::ChromeDeviceSettingsProto*
device_settings()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.
status()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