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 #include "chrome/browser/chromeos/settings/device_settings_service.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/stl_util.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h"
17 #include "chrome/browser/chromeos/policy/off_hours/off_hours_policy_applier.h"
18 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
19 #include "components/ownership/owner_key_util.h"
20 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
21 #include "components/policy/proto/chrome_device_policy.pb.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_source.h"
25 
26 #include "crypto/rsa_private_key.h"
27 
28 namespace em = enterprise_management;
29 
30 using ownership::OwnerKeyUtil;
31 using ownership::PublicKey;
32 
33 namespace chromeos {
34 
~Observer()35 DeviceSettingsService::Observer::~Observer() {}
36 
OwnershipStatusChanged()37 void DeviceSettingsService::Observer::OwnershipStatusChanged() {}
38 
DeviceSettingsUpdated()39 void DeviceSettingsService::Observer::DeviceSettingsUpdated() {}
40 
OnDeviceSettingsServiceShutdown()41 void DeviceSettingsService::Observer::OnDeviceSettingsServiceShutdown() {}
42 
43 static DeviceSettingsService* g_device_settings_service = NULL;
44 
45 // static
Initialize()46 void DeviceSettingsService::Initialize() {
47   CHECK(!g_device_settings_service);
48   g_device_settings_service = new DeviceSettingsService();
49 }
50 
51 // static
IsInitialized()52 bool DeviceSettingsService::IsInitialized() {
53   return g_device_settings_service;
54 }
55 
56 // static
Shutdown()57 void DeviceSettingsService::Shutdown() {
58   DCHECK(g_device_settings_service);
59   delete g_device_settings_service;
60   g_device_settings_service = NULL;
61 }
62 
63 // static
Get()64 DeviceSettingsService* DeviceSettingsService::Get() {
65   CHECK(g_device_settings_service);
66   return g_device_settings_service;
67 }
68 
69 // static
StatusToString(Status status)70 const char* DeviceSettingsService::StatusToString(Status status) {
71   switch (status) {
72     case STORE_SUCCESS:
73       return "SUCCESS";
74     case STORE_KEY_UNAVAILABLE:
75       return "KEY_UNAVAILABLE";
76     case STORE_OPERATION_FAILED:
77       return "OPERATION_FAILED";
78     case STORE_NO_POLICY:
79       return "NO_POLICY";
80     case STORE_INVALID_POLICY:
81       return "INVALID_POLICY";
82     case STORE_VALIDATION_ERROR:
83       return "VALIDATION_ERROR";
84   }
85   return "UNKNOWN";
86 }
87 
DeviceSettingsService()88 DeviceSettingsService::DeviceSettingsService() {
89   device_off_hours_controller_ =
90       std::make_unique<policy::off_hours::DeviceOffHoursController>();
91 }
92 
~DeviceSettingsService()93 DeviceSettingsService::~DeviceSettingsService() {
94   DCHECK(pending_operations_.empty());
95   for (auto& observer : observers_)
96     observer.OnDeviceSettingsServiceShutdown();
97 }
98 
SetSessionManager(SessionManagerClient * session_manager_client,scoped_refptr<OwnerKeyUtil> owner_key_util)99 void DeviceSettingsService::SetSessionManager(
100     SessionManagerClient* session_manager_client,
101     scoped_refptr<OwnerKeyUtil> owner_key_util) {
102   DCHECK(session_manager_client);
103   DCHECK(owner_key_util.get());
104   DCHECK(!session_manager_client_);
105   DCHECK(!owner_key_util_.get());
106 
107   session_manager_client_ = session_manager_client;
108   owner_key_util_ = owner_key_util;
109 
110   session_manager_client_->AddObserver(this);
111 
112   StartNextOperation();
113 }
114 
UnsetSessionManager()115 void DeviceSettingsService::UnsetSessionManager() {
116   pending_operations_.clear();
117 
118   if (session_manager_client_)
119     session_manager_client_->RemoveObserver(this);
120   session_manager_client_ = NULL;
121   owner_key_util_.reset();
122 }
123 
SetDeviceMode(policy::DeviceMode device_mode)124 void DeviceSettingsService::SetDeviceMode(policy::DeviceMode device_mode) {
125   if (device_mode_ == device_mode)
126     return;
127 
128   // Device mode can only change if was not set yet.
129   DCHECK(policy::DEVICE_MODE_PENDING == device_mode_ ||
130          policy::DEVICE_MODE_NOT_SET == device_mode_);
131   device_mode_ = device_mode;
132   if (GetOwnershipStatus() != OWNERSHIP_UNKNOWN) {
133     RunPendingOwnershipStatusCallbacks();
134   }
135 }
136 
GetPublicKey()137 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() {
138   return public_key_;
139 }
140 
SetDeviceOffHoursControllerForTesting(std::unique_ptr<policy::off_hours::DeviceOffHoursController> controller)141 void DeviceSettingsService::SetDeviceOffHoursControllerForTesting(
142     std::unique_ptr<policy::off_hours::DeviceOffHoursController> controller) {
143   device_off_hours_controller_ = std::move(controller);
144 }
145 
Load()146 void DeviceSettingsService::Load() {
147   EnqueueLoad(false);
148 }
149 
LoadImmediately()150 void DeviceSettingsService::LoadImmediately() {
151   bool request_key_load = true;
152   bool cloud_validations = true;
153   if (device_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD) {
154     request_key_load = false;
155     cloud_validations = false;
156   }
157   std::unique_ptr<SessionManagerOperation> operation(new LoadSettingsOperation(
158       request_key_load, cloud_validations, true /*force_immediate_load*/,
159       base::Bind(&DeviceSettingsService::HandleCompletedOperation,
160                  weak_factory_.GetWeakPtr(), base::Closure())));
161   operation->Start(session_manager_client_, owner_key_util_, public_key_);
162 }
163 
Store(std::unique_ptr<em::PolicyFetchResponse> policy,const base::Closure & callback)164 void DeviceSettingsService::Store(
165     std::unique_ptr<em::PolicyFetchResponse> policy,
166     const base::Closure& callback) {
167   // On Active Directory managed devices policy is written only by authpolicyd.
168   CHECK(device_mode_ != policy::DEVICE_MODE_ENTERPRISE_AD);
169   Enqueue(std::make_unique<StoreSettingsOperation>(
170       base::Bind(&DeviceSettingsService::HandleCompletedAsyncOperation,
171                  weak_factory_.GetWeakPtr(), callback),
172       std::move(policy)));
173 }
174 
175 DeviceSettingsService::OwnershipStatus
GetOwnershipStatus()176     DeviceSettingsService::GetOwnershipStatus() {
177   if (public_key_.get())
178     return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
179   if (device_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD)
180     return OWNERSHIP_TAKEN;
181   return OWNERSHIP_UNKNOWN;
182 }
183 
GetOwnershipStatusAsync(const OwnershipStatusCallback & callback)184 void DeviceSettingsService::GetOwnershipStatusAsync(
185     const OwnershipStatusCallback& callback) {
186   if (GetOwnershipStatus() != OWNERSHIP_UNKNOWN) {
187     // Report status immediately.
188     base::ThreadTaskRunnerHandle::Get()->PostTask(
189         FROM_HERE, base::BindOnce(callback, GetOwnershipStatus()));
190   } else {
191     // If the key hasn't been loaded yet, enqueue the callback to be fired when
192     // the next SessionManagerOperation completes. If no operation is pending,
193     // start a load operation to fetch the key and report the result.
194     pending_ownership_status_callbacks_.push_back(callback);
195     if (pending_operations_.empty())
196       EnqueueLoad(false);
197   }
198 }
199 
HasPrivateOwnerKey()200 bool DeviceSettingsService::HasPrivateOwnerKey() {
201   return owner_settings_service_ && owner_settings_service_->IsOwner();
202 }
203 
InitOwner(const std::string & username,const base::WeakPtr<ownership::OwnerSettingsService> & owner_settings_service)204 void DeviceSettingsService::InitOwner(
205     const std::string& username,
206     const base::WeakPtr<ownership::OwnerSettingsService>&
207         owner_settings_service) {
208   // When InitOwner() is called twice with the same |username| it's
209   // worth to reload settings since owner key may become available.
210   if (!username_.empty() && username_ != username)
211     return;
212   username_ = username;
213   owner_settings_service_ = owner_settings_service;
214 
215   // Reset the flag since consumer ownership should be established now.
216   will_establish_consumer_ownership_ = false;
217 
218   EnsureReload(true);
219 }
220 
GetUsername() const221 const std::string& DeviceSettingsService::GetUsername() const {
222   return username_;
223 }
224 
225 ownership::OwnerSettingsService*
GetOwnerSettingsService() const226 DeviceSettingsService::GetOwnerSettingsService() const {
227   return owner_settings_service_.get();
228 }
229 
MarkWillEstablishConsumerOwnership()230 void DeviceSettingsService::MarkWillEstablishConsumerOwnership() {
231   will_establish_consumer_ownership_ = true;
232 }
233 
AddObserver(Observer * observer)234 void DeviceSettingsService::AddObserver(Observer* observer) {
235   observers_.AddObserver(observer);
236 }
237 
RemoveObserver(Observer * observer)238 void DeviceSettingsService::RemoveObserver(Observer* observer) {
239   observers_.RemoveObserver(observer);
240 }
241 
OwnerKeySet(bool success)242 void DeviceSettingsService::OwnerKeySet(bool success) {
243   if (!success) {
244     LOG(ERROR) << "Owner key change failed.";
245     return;
246   }
247 
248   public_key_.reset();
249 
250   if (GetOwnershipStatus() == OWNERSHIP_TAKEN ||
251       !will_establish_consumer_ownership_) {
252     EnsureReload(true);
253   }
254 }
255 
PropertyChangeComplete(bool success)256 void DeviceSettingsService::PropertyChangeComplete(bool success) {
257   if (!success) {
258     LOG(ERROR) << "Policy update failed.";
259     return;
260   }
261 
262   if (GetOwnershipStatus() == OWNERSHIP_TAKEN ||
263       !will_establish_consumer_ownership_) {
264     EnsureReload(false);
265   }
266 }
267 
Enqueue(std::unique_ptr<SessionManagerOperation> operation)268 void DeviceSettingsService::Enqueue(
269     std::unique_ptr<SessionManagerOperation> operation) {
270   const bool was_empty = pending_operations_.empty();
271   pending_operations_.push_back(std::move(operation));
272   if (was_empty)
273     StartNextOperation();
274 }
275 
EnqueueLoad(bool request_key_load)276 void DeviceSettingsService::EnqueueLoad(bool request_key_load) {
277   bool cloud_validations = true;
278   if (device_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD) {
279     request_key_load = false;
280     cloud_validations = false;
281   }
282   Enqueue(std::make_unique<LoadSettingsOperation>(
283       request_key_load, cloud_validations, false /*force_immediate_load*/,
284       base::Bind(&DeviceSettingsService::HandleCompletedAsyncOperation,
285                  weak_factory_.GetWeakPtr(), base::Closure())));
286 }
287 
EnsureReload(bool request_key_load)288 void DeviceSettingsService::EnsureReload(bool request_key_load) {
289   if (!pending_operations_.empty())
290     pending_operations_.front()->RestartLoad(request_key_load);
291   else
292     EnqueueLoad(request_key_load);
293 }
294 
StartNextOperation()295 void DeviceSettingsService::StartNextOperation() {
296   if (!pending_operations_.empty() && session_manager_client_ &&
297       owner_key_util_.get()) {
298     pending_operations_.front()->Start(
299         session_manager_client_, owner_key_util_, public_key_);
300   }
301 }
302 
HandleCompletedAsyncOperation(const base::Closure & callback,SessionManagerOperation * operation,Status status)303 void DeviceSettingsService::HandleCompletedAsyncOperation(
304     const base::Closure& callback,
305     SessionManagerOperation* operation,
306     Status status) {
307   DCHECK_EQ(operation, pending_operations_.front().get());
308   HandleCompletedOperation(callback, operation, status);
309   // Only remove the pending operation here, so new operations triggered by
310   // any of the callbacks above are queued up properly.
311   pending_operations_.pop_front();
312 
313   StartNextOperation();
314 }
315 
HandleCompletedOperation(const base::Closure & callback,SessionManagerOperation * operation,Status status)316 void DeviceSettingsService::HandleCompletedOperation(
317     const base::Closure& callback,
318     SessionManagerOperation* operation,
319     Status status) {
320   store_status_ = status;
321   if (status == STORE_SUCCESS) {
322     policy_data_ = std::move(operation->policy_data());
323     device_settings_ = std::move(operation->device_settings());
324     // Update "OffHours" policy state and apply "OffHours" policy to current
325     // proto only during "OffHours" mode. When "OffHours" mode begins and ends
326     // DeviceOffHoursController requests DeviceSettingsService to asynchronously
327     // reload device policies. (See |DeviceOffHoursController| class
328     // description)
329     device_off_hours_controller_->UpdateOffHoursPolicy(*device_settings_);
330     if (device_off_hours_controller_->is_off_hours_mode()) {
331       std::unique_ptr<em::ChromeDeviceSettingsProto> off_device_settings =
332           policy::off_hours::ApplyOffHoursPolicyToProto(*device_settings_);
333       if (off_device_settings)
334         device_settings_.swap(off_device_settings);
335     }
336   } else if (status != STORE_KEY_UNAVAILABLE) {
337     LOG(ERROR) << "Session manager operation failed: " << status << " ("
338                << StatusToString(status) << ")";
339   }
340 
341   public_key_ = scoped_refptr<PublicKey>(operation->public_key());
342   if (GetOwnershipStatus() != previous_ownership_status_) {
343     previous_ownership_status_ = GetOwnershipStatus();
344     NotifyOwnershipStatusChanged();
345   }
346   NotifyDeviceSettingsUpdated();
347   RunPendingOwnershipStatusCallbacks();
348 
349   // The completion callback happens after the notification so clients can
350   // filter self-triggered updates.
351   if (!callback.is_null())
352     callback.Run();
353 }
354 
NotifyOwnershipStatusChanged() const355 void DeviceSettingsService::NotifyOwnershipStatusChanged() const {
356   for (auto& observer : observers_)
357     observer.OwnershipStatusChanged();
358 }
359 
NotifyDeviceSettingsUpdated() const360 void DeviceSettingsService::NotifyDeviceSettingsUpdated() const {
361   for (auto& observer : observers_)
362     observer.DeviceSettingsUpdated();
363 }
364 
RunPendingOwnershipStatusCallbacks()365 void DeviceSettingsService::RunPendingOwnershipStatusCallbacks() {
366   std::vector<OwnershipStatusCallback> callbacks;
367   callbacks.swap(pending_ownership_status_callbacks_);
368   for (const auto& callback : callbacks) {
369     callback.Run(GetOwnershipStatus());
370   }
371 }
372 
ScopedTestDeviceSettingsService()373 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() {
374   DeviceSettingsService::Initialize();
375 }
376 
~ScopedTestDeviceSettingsService()377 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() {
378   // Clean pending operations.
379   DeviceSettingsService::Get()->UnsetSessionManager();
380   DeviceSettingsService::Shutdown();
381 }
382 
383 }  // namespace chromeos
384