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