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 "chromeos/dbus/session_manager/session_manager_client.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <cstring>
11 #include <memory>
12 #include <utility>
13
14 #include "base/bind.h"
15 #include "base/callback.h"
16 #include "base/callback_helpers.h"
17 #include "base/files/file_path.h"
18 #include "base/files/file_util.h"
19 #include "base/files/scoped_file.h"
20 #include "base/location.h"
21 #include "base/logging.h"
22 #include "base/macros.h"
23 #include "base/memory/platform_shared_memory_region.h"
24 #include "base/memory/read_only_shared_memory_region.h"
25 #include "base/memory/writable_shared_memory_region.h"
26 #include "base/metrics/histogram_macros.h"
27 #include "base/optional.h"
28 #include "base/path_service.h"
29 #include "base/strings/string_util.h"
30 #include "base/threading/thread_task_runner_handle.h"
31 #include "base/unguessable_token.h"
32 #include "chromeos/dbus/blocking_method_caller.h"
33 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
34 #include "chromeos/dbus/cryptohome/rpc.pb.h"
35 #include "chromeos/dbus/login_manager/arc.pb.h"
36 #include "chromeos/dbus/login_manager/login_screen_storage.pb.h"
37 #include "chromeos/dbus/login_manager/policy_descriptor.pb.h"
38 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
39 #include "components/policy/proto/device_management_backend.pb.h"
40 #include "dbus/bus.h"
41 #include "dbus/message.h"
42 #include "dbus/object_path.h"
43 #include "dbus/object_proxy.h"
44 #include "dbus/scoped_dbus_error.h"
45 #include "third_party/cros_system_api/dbus/service_constants.h"
46
47 namespace chromeos {
48
49 namespace {
50
51 SessionManagerClient* g_instance = nullptr;
52
53 using RetrievePolicyResponseType =
54 SessionManagerClient::RetrievePolicyResponseType;
55
56 constexpr char kEmptyAccountId[] = "";
57 // The timeout used when starting the android container is 90 seconds
58 constexpr int kStartArcTimeout = 90 * 1000;
59
60 // 10MB. It's the current restriction enforced by session manager.
61 const size_t kSharedMemoryDataSizeLimit = 10 * 1024 * 1024;
62
63 // Helper to get the enum type of RetrievePolicyResponseType based on error
64 // name.
GetPolicyResponseTypeByError(base::StringPiece error_name)65 RetrievePolicyResponseType GetPolicyResponseTypeByError(
66 base::StringPiece error_name) {
67 if (error_name == login_manager::dbus_error::kNone) {
68 return RetrievePolicyResponseType::SUCCESS;
69 } else if (error_name == login_manager::dbus_error::kGetServiceFail ||
70 error_name == login_manager::dbus_error::kSessionDoesNotExist) {
71 // TODO(crbug.com/765644): Remove kSessionDoesNotExist case once Chrome OS
72 // has switched to kGetServiceFail.
73 return RetrievePolicyResponseType::GET_SERVICE_FAIL;
74 } else if (error_name == login_manager::dbus_error::kSigEncodeFail) {
75 return RetrievePolicyResponseType::POLICY_ENCODE_ERROR;
76 }
77 return RetrievePolicyResponseType::OTHER_ERROR;
78 }
79
80 // Logs UMA stat for retrieve policy request, corresponding to D-Bus method name
81 // used.
LogPolicyResponseUma(login_manager::PolicyAccountType account_type,RetrievePolicyResponseType response)82 void LogPolicyResponseUma(login_manager::PolicyAccountType account_type,
83 RetrievePolicyResponseType response) {
84 switch (account_type) {
85 case login_manager::ACCOUNT_TYPE_DEVICE:
86 UMA_HISTOGRAM_ENUMERATION("Enterprise.RetrievePolicyResponse.Device",
87 response, RetrievePolicyResponseType::COUNT);
88 break;
89 case login_manager::ACCOUNT_TYPE_DEVICE_LOCAL_ACCOUNT:
90 UMA_HISTOGRAM_ENUMERATION(
91 "Enterprise.RetrievePolicyResponse.DeviceLocalAccount", response,
92 RetrievePolicyResponseType::COUNT);
93 break;
94 case login_manager::ACCOUNT_TYPE_USER:
95 UMA_HISTOGRAM_ENUMERATION("Enterprise.RetrievePolicyResponse.User",
96 response, RetrievePolicyResponseType::COUNT);
97 break;
98 case login_manager::ACCOUNT_TYPE_SESSIONLESS_USER:
99 UMA_HISTOGRAM_ENUMERATION(
100 "Enterprise.RetrievePolicyResponse.UserDuringLogin", response,
101 RetrievePolicyResponseType::COUNT);
102 break;
103 }
104 }
105
106 // Creates a PolicyDescriptor object to store/retrieve Chrome policy.
MakeChromePolicyDescriptor(login_manager::PolicyAccountType account_type,const std::string & account_id)107 login_manager::PolicyDescriptor MakeChromePolicyDescriptor(
108 login_manager::PolicyAccountType account_type,
109 const std::string& account_id) {
110 login_manager::PolicyDescriptor descriptor;
111 descriptor.set_account_type(account_type);
112 descriptor.set_account_id(account_id);
113 descriptor.set_domain(login_manager::POLICY_DOMAIN_CHROME);
114 return descriptor;
115 }
116
117 // Creates a pipe that contains the given data. The data will be prefixed by a
118 // size_t sized variable containing the size of the data to read. Since we don't
119 // pass this pipe's read end anywhere, we can be sure that the only FD that can
120 // read from that pipe will be closed on browser's exit, therefore the password
121 // won't be leaked if the browser crashes.
CreatePasswordPipe(const std::string & data)122 base::ScopedFD CreatePasswordPipe(const std::string& data) {
123 // 64k of data, minus 64 bits for a preceding size. This number was chosen to
124 // fit all the data in a single pipe buffer and avoid blocking on write.
125 // (http://man7.org/linux/man-pages/man7/pipe.7.html)
126 const size_t kPipeDataSizeLimit = 1024 * 64 - sizeof(size_t);
127
128 int pipe_fds[2];
129 if (data.size() > kPipeDataSizeLimit ||
130 !base::CreateLocalNonBlockingPipe(pipe_fds)) {
131 DLOG(ERROR) << "Failed to create pipe";
132 return base::ScopedFD();
133 }
134 base::ScopedFD pipe_read_end(pipe_fds[0]);
135 base::ScopedFD pipe_write_end(pipe_fds[1]);
136
137 const size_t data_size = data.size();
138
139 base::WriteFileDescriptor(pipe_write_end.get(),
140 reinterpret_cast<const char*>(&data_size),
141 sizeof(data_size));
142 base::WriteFileDescriptor(pipe_write_end.get(), data.c_str(), data.size());
143
144 return pipe_read_end;
145 }
146
147 // Creates a read-only shared memory region that contains the given data.
CreateSharedMemoryRegionFDWithData(const std::string & data)148 base::ScopedFD CreateSharedMemoryRegionFDWithData(const std::string& data) {
149 if (data.size() > kSharedMemoryDataSizeLimit) {
150 LOG(ERROR) << "Couldn't create shared memory, data is too big.";
151 return base::ScopedFD();
152 }
153 auto region = base::WritableSharedMemoryRegion::Create(data.size());
154 base::WritableSharedMemoryMapping mapping = region.Map();
155 if (!mapping.IsValid())
156 return base::ScopedFD();
157 memcpy(mapping.memory(), data.data(), data.size());
158 return base::WritableSharedMemoryRegion::TakeHandleForSerialization(
159 std::move(region))
160 .PassPlatformHandle()
161 .readonly_fd;
162 }
163
164 // Reads |secret_size| bytes from a given shared memory region. Puts result into
165 // |secret|. |fd| should point at a read-only shared memory region.
ReadSecretFromSharedMemory(base::ScopedFD fd,size_t secret_size,std::vector<uint8_t> * secret)166 bool ReadSecretFromSharedMemory(base::ScopedFD fd,
167 size_t secret_size,
168 std::vector<uint8_t>* secret) {
169 if (secret_size > kSharedMemoryDataSizeLimit) {
170 LOG(ERROR) << "Couldn't read secret from the shared memory, "
171 "secret's size is too big.";
172 return false;
173 }
174 auto platform_region(base::subtle::PlatformSharedMemoryRegion::Take(
175 std::move(fd), base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly,
176 secret_size, base::UnguessableToken::Create()));
177 if (!platform_region.IsValid())
178 return false;
179 auto region =
180 base::ReadOnlySharedMemoryRegion::Deserialize(std::move(platform_region));
181 if (!region.IsValid())
182 return false;
183 base::ReadOnlySharedMemoryMapping mapping = region.Map();
184 if (!mapping.IsValid())
185 return false;
186 secret->resize(secret_size);
187 memcpy(secret->data(), mapping.memory(), secret->size());
188 return true;
189 }
190
191 } // namespace
192
193 // The SessionManagerClient implementation used in production.
194 class SessionManagerClientImpl : public SessionManagerClient {
195 public:
196 SessionManagerClientImpl() = default;
197 ~SessionManagerClientImpl() override = default;
198
199 // SessionManagerClient overrides:
SetStubDelegate(StubDelegate * delegate)200 void SetStubDelegate(StubDelegate* delegate) override {
201 // Do nothing; this isn't a stub implementation.
202 }
203
AddObserver(Observer * observer)204 void AddObserver(Observer* observer) override {
205 observers_.AddObserver(observer);
206 }
207
RemoveObserver(Observer * observer)208 void RemoveObserver(Observer* observer) override {
209 observers_.RemoveObserver(observer);
210 }
211
HasObserver(const Observer * observer) const212 bool HasObserver(const Observer* observer) const override {
213 return observers_.HasObserver(observer);
214 }
215
WaitForServiceToBeAvailable(WaitForServiceToBeAvailableCallback callback)216 void WaitForServiceToBeAvailable(
217 WaitForServiceToBeAvailableCallback callback) override {
218 session_manager_proxy_->WaitForServiceToBeAvailable(std::move(callback));
219 }
220
IsScreenLocked() const221 bool IsScreenLocked() const override { return screen_is_locked_; }
222
EmitLoginPromptVisible()223 void EmitLoginPromptVisible() override {
224 SimpleMethodCallToSessionManager(
225 login_manager::kSessionManagerEmitLoginPromptVisible);
226 for (auto& observer : observers_)
227 observer.EmitLoginPromptVisibleCalled();
228 }
229
EmitAshInitialized()230 void EmitAshInitialized() override {
231 SimpleMethodCallToSessionManager(
232 login_manager::kSessionManagerEmitAshInitialized);
233 }
234
RestartJob(int socket_fd,const std::vector<std::string> & argv,VoidDBusMethodCallback callback)235 void RestartJob(int socket_fd,
236 const std::vector<std::string>& argv,
237 VoidDBusMethodCallback callback) override {
238 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
239 login_manager::kSessionManagerRestartJob);
240 dbus::MessageWriter writer(&method_call);
241 writer.AppendFileDescriptor(socket_fd);
242 writer.AppendArrayOfStrings(argv);
243 session_manager_proxy_->CallMethod(
244 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
245 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
246 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
247 }
248
SaveLoginPassword(const std::string & password)249 void SaveLoginPassword(const std::string& password) override {
250 dbus::MethodCall method_call(
251 login_manager::kSessionManagerInterface,
252 login_manager::kSessionManagerSaveLoginPassword);
253 dbus::MessageWriter writer(&method_call);
254
255 base::ScopedFD fd = CreatePasswordPipe(password);
256 if (fd.get() == -1) {
257 LOG(WARNING) << "Could not create password pipe.";
258 return;
259 }
260
261 writer.AppendFileDescriptor(fd.get());
262
263 session_manager_proxy_->CallMethod(&method_call,
264 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
265 base::DoNothing());
266 }
267
LoginScreenStorageStore(const std::string & key,const login_manager::LoginScreenStorageMetadata & metadata,const std::string & data,LoginScreenStorageStoreCallback callback)268 void LoginScreenStorageStore(
269 const std::string& key,
270 const login_manager::LoginScreenStorageMetadata& metadata,
271 const std::string& data,
272 LoginScreenStorageStoreCallback callback) override {
273 dbus::MethodCall method_call(
274 login_manager::kSessionManagerInterface,
275 login_manager::kSessionManagerLoginScreenStorageStore);
276 dbus::MessageWriter writer(&method_call);
277 writer.AppendString(key);
278
279 const std::string metadata_blob = metadata.SerializeAsString();
280 writer.AppendArrayOfBytes(
281 reinterpret_cast<const uint8_t*>(metadata_blob.data()),
282 metadata_blob.size());
283 writer.AppendUint64(data.size());
284
285 base::ScopedFD fd = CreateSharedMemoryRegionFDWithData(data);
286 if (!fd.is_valid()) {
287 std::string error = "Could not create shared memory.";
288 std::move(callback).Run(std::move(error));
289 return;
290 }
291 writer.AppendFileDescriptor(fd.get());
292
293 session_manager_proxy_->CallMethod(
294 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
295 base::BindOnce(&SessionManagerClientImpl::OnLoginScreenStorageStore,
296 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
297 }
298
LoginScreenStorageRetrieve(const std::string & key,LoginScreenStorageRetrieveCallback callback)299 void LoginScreenStorageRetrieve(
300 const std::string& key,
301 LoginScreenStorageRetrieveCallback callback) override {
302 dbus::MethodCall method_call(
303 login_manager::kSessionManagerInterface,
304 login_manager::kSessionManagerLoginScreenStorageRetrieve);
305 dbus::MessageWriter writer(&method_call);
306 writer.AppendString(key);
307 session_manager_proxy_->CallMethod(
308 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
309 base::BindOnce(&SessionManagerClientImpl::OnLoginScreenStorageRetrieve,
310 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
311 }
312
LoginScreenStorageListKeys(LoginScreenStorageListKeysCallback callback)313 void LoginScreenStorageListKeys(
314 LoginScreenStorageListKeysCallback callback) override {
315 dbus::MethodCall method_call(
316 login_manager::kSessionManagerInterface,
317 login_manager::kSessionManagerLoginScreenStorageListKeys);
318 session_manager_proxy_->CallMethod(
319 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
320 base::BindOnce(&SessionManagerClientImpl::OnLoginScreenStorageListKeys,
321 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
322 }
323
LoginScreenStorageDelete(const std::string & key)324 void LoginScreenStorageDelete(const std::string& key) override {
325 dbus::MethodCall method_call(
326 login_manager::kSessionManagerInterface,
327 login_manager::kSessionManagerLoginScreenStorageDelete);
328 dbus::MessageWriter writer(&method_call);
329 writer.AppendString(key);
330 session_manager_proxy_->CallMethod(&method_call,
331 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
332 base::DoNothing());
333 }
334
StartSession(const cryptohome::AccountIdentifier & cryptohome_id)335 void StartSession(
336 const cryptohome::AccountIdentifier& cryptohome_id) override {
337 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
338 login_manager::kSessionManagerStartSession);
339 dbus::MessageWriter writer(&method_call);
340 writer.AppendString(cryptohome_id.account_id());
341 writer.AppendString(""); // Unique ID is deprecated
342 session_manager_proxy_->CallMethod(&method_call,
343 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
344 base::DoNothing());
345 }
346
StopSession(login_manager::SessionStopReason reason)347 void StopSession(login_manager::SessionStopReason reason) override {
348 dbus::MethodCall method_call(
349 login_manager::kSessionManagerInterface,
350 login_manager::kSessionManagerStopSessionWithReason);
351 dbus::MessageWriter writer(&method_call);
352 writer.AppendUint32(static_cast<uint32_t>(reason));
353 session_manager_proxy_->CallMethod(&method_call,
354 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
355 base::DoNothing());
356 }
357
StartDeviceWipe()358 void StartDeviceWipe() override {
359 SimpleMethodCallToSessionManager(
360 login_manager::kSessionManagerStartDeviceWipe);
361 }
362
StartRemoteDeviceWipe(const enterprise_management::SignedData & signed_command)363 void StartRemoteDeviceWipe(
364 const enterprise_management::SignedData& signed_command) override {
365 dbus::MethodCall method_call(
366 login_manager::kSessionManagerInterface,
367 login_manager::kSessionManagerStartRemoteDeviceWipe);
368 dbus::MessageWriter writer(&method_call);
369 writer.AppendProtoAsArrayOfBytes(signed_command);
370 session_manager_proxy_->CallMethod(&method_call,
371 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
372 base::DoNothing());
373 }
374
ClearForcedReEnrollmentVpd(VoidDBusMethodCallback callback)375 void ClearForcedReEnrollmentVpd(VoidDBusMethodCallback callback) override {
376 dbus::MethodCall method_call(
377 login_manager::kSessionManagerInterface,
378 login_manager::kSessionManagerClearForcedReEnrollmentVpd);
379 dbus::MessageWriter writer(&method_call);
380 session_manager_proxy_->CallMethod(
381 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
382 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
383 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
384 }
385
StartTPMFirmwareUpdate(const std::string & update_mode)386 void StartTPMFirmwareUpdate(const std::string& update_mode) override {
387 dbus::MethodCall method_call(
388 login_manager::kSessionManagerInterface,
389 login_manager::kSessionManagerStartTPMFirmwareUpdate);
390 dbus::MessageWriter writer(&method_call);
391 writer.AppendString(update_mode);
392 session_manager_proxy_->CallMethod(&method_call,
393 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
394 base::DoNothing());
395 }
396
RequestLockScreen()397 void RequestLockScreen() override {
398 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
399 }
400
NotifyLockScreenShown()401 void NotifyLockScreenShown() override {
402 SimpleMethodCallToSessionManager(
403 login_manager::kSessionManagerHandleLockScreenShown);
404 }
405
NotifyLockScreenDismissed()406 void NotifyLockScreenDismissed() override {
407 SimpleMethodCallToSessionManager(
408 login_manager::kSessionManagerHandleLockScreenDismissed);
409 }
410
RetrieveActiveSessions(ActiveSessionsCallback callback)411 void RetrieveActiveSessions(ActiveSessionsCallback callback) override {
412 dbus::MethodCall method_call(
413 login_manager::kSessionManagerInterface,
414 login_manager::kSessionManagerRetrieveActiveSessions);
415
416 session_manager_proxy_->CallMethod(
417 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
418 base::BindOnce(&SessionManagerClientImpl::OnRetrieveActiveSessions,
419 weak_ptr_factory_.GetWeakPtr(),
420 login_manager::kSessionManagerRetrieveActiveSessions,
421 std::move(callback)));
422 }
423
RetrieveDevicePolicy(RetrievePolicyCallback callback)424 void RetrieveDevicePolicy(RetrievePolicyCallback callback) override {
425 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
426 login_manager::ACCOUNT_TYPE_DEVICE, kEmptyAccountId);
427 CallRetrievePolicy(descriptor, std::move(callback));
428 }
429
BlockingRetrieveDevicePolicy(std::string * policy_out)430 RetrievePolicyResponseType BlockingRetrieveDevicePolicy(
431 std::string* policy_out) override {
432 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
433 login_manager::ACCOUNT_TYPE_DEVICE, kEmptyAccountId);
434 return BlockingRetrievePolicy(descriptor, policy_out);
435 }
436
RetrievePolicyForUser(const cryptohome::AccountIdentifier & cryptohome_id,RetrievePolicyCallback callback)437 void RetrievePolicyForUser(const cryptohome::AccountIdentifier& cryptohome_id,
438 RetrievePolicyCallback callback) override {
439 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
440 login_manager::ACCOUNT_TYPE_USER, cryptohome_id.account_id());
441 CallRetrievePolicy(descriptor, std::move(callback));
442 }
443
BlockingRetrievePolicyForUser(const cryptohome::AccountIdentifier & cryptohome_id,std::string * policy_out)444 RetrievePolicyResponseType BlockingRetrievePolicyForUser(
445 const cryptohome::AccountIdentifier& cryptohome_id,
446 std::string* policy_out) override {
447 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
448 login_manager::ACCOUNT_TYPE_USER, cryptohome_id.account_id());
449 return BlockingRetrievePolicy(descriptor, policy_out);
450 }
451
RetrievePolicyForUserWithoutSession(const cryptohome::AccountIdentifier & cryptohome_id,RetrievePolicyCallback callback)452 void RetrievePolicyForUserWithoutSession(
453 const cryptohome::AccountIdentifier& cryptohome_id,
454 RetrievePolicyCallback callback) override {
455 login_manager::PolicyDescriptor descriptor =
456 MakeChromePolicyDescriptor(login_manager::ACCOUNT_TYPE_SESSIONLESS_USER,
457 cryptohome_id.account_id());
458 CallRetrievePolicy(descriptor, std::move(callback));
459 }
460
RetrieveDeviceLocalAccountPolicy(const std::string & account_name,RetrievePolicyCallback callback)461 void RetrieveDeviceLocalAccountPolicy(
462 const std::string& account_name,
463 RetrievePolicyCallback callback) override {
464 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
465 login_manager::ACCOUNT_TYPE_DEVICE_LOCAL_ACCOUNT, account_name);
466 CallRetrievePolicy(descriptor, std::move(callback));
467 }
468
BlockingRetrieveDeviceLocalAccountPolicy(const std::string & account_name,std::string * policy_out)469 RetrievePolicyResponseType BlockingRetrieveDeviceLocalAccountPolicy(
470 const std::string& account_name,
471 std::string* policy_out) override {
472 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
473 login_manager::ACCOUNT_TYPE_DEVICE_LOCAL_ACCOUNT, account_name);
474 return BlockingRetrievePolicy(descriptor, policy_out);
475 }
476
RetrievePolicy(const login_manager::PolicyDescriptor & descriptor,RetrievePolicyCallback callback)477 void RetrievePolicy(const login_manager::PolicyDescriptor& descriptor,
478 RetrievePolicyCallback callback) override {
479 CallRetrievePolicy(descriptor, std::move(callback));
480 }
481
BlockingRetrievePolicy(const login_manager::PolicyDescriptor & descriptor,std::string * policy_out)482 RetrievePolicyResponseType BlockingRetrievePolicy(
483 const login_manager::PolicyDescriptor& descriptor,
484 std::string* policy_out) override {
485 return CallBlockingRetrievePolicy(descriptor, policy_out);
486 }
487
StoreDevicePolicy(const std::string & policy_blob,VoidDBusMethodCallback callback)488 void StoreDevicePolicy(const std::string& policy_blob,
489 VoidDBusMethodCallback callback) override {
490 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
491 login_manager::ACCOUNT_TYPE_DEVICE, kEmptyAccountId);
492 CallStorePolicy(descriptor, policy_blob, std::move(callback));
493 }
494
StorePolicyForUser(const cryptohome::AccountIdentifier & cryptohome_id,const std::string & policy_blob,VoidDBusMethodCallback callback)495 void StorePolicyForUser(const cryptohome::AccountIdentifier& cryptohome_id,
496 const std::string& policy_blob,
497 VoidDBusMethodCallback callback) override {
498 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
499 login_manager::ACCOUNT_TYPE_USER, cryptohome_id.account_id());
500 CallStorePolicy(descriptor, policy_blob, std::move(callback));
501 }
502
StoreDeviceLocalAccountPolicy(const std::string & account_name,const std::string & policy_blob,VoidDBusMethodCallback callback)503 void StoreDeviceLocalAccountPolicy(const std::string& account_name,
504 const std::string& policy_blob,
505 VoidDBusMethodCallback callback) override {
506 login_manager::PolicyDescriptor descriptor = MakeChromePolicyDescriptor(
507 login_manager::ACCOUNT_TYPE_DEVICE_LOCAL_ACCOUNT, account_name);
508 CallStorePolicy(descriptor, policy_blob, std::move(callback));
509 }
510
StorePolicy(const login_manager::PolicyDescriptor & descriptor,const std::string & policy_blob,VoidDBusMethodCallback callback)511 void StorePolicy(const login_manager::PolicyDescriptor& descriptor,
512 const std::string& policy_blob,
513 VoidDBusMethodCallback callback) override {
514 CallStorePolicy(descriptor, policy_blob, std::move(callback));
515 }
516
SupportsBrowserRestart() const517 bool SupportsBrowserRestart() const override { return true; }
518
SetFlagsForUser(const cryptohome::AccountIdentifier & cryptohome_id,const std::vector<std::string> & flags)519 void SetFlagsForUser(const cryptohome::AccountIdentifier& cryptohome_id,
520 const std::vector<std::string>& flags) override {
521 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
522 login_manager::kSessionManagerSetFlagsForUser);
523 dbus::MessageWriter writer(&method_call);
524 writer.AppendString(cryptohome_id.account_id());
525 writer.AppendArrayOfStrings(flags);
526 session_manager_proxy_->CallMethod(&method_call,
527 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
528 base::DoNothing());
529 }
530
GetServerBackedStateKeys(StateKeysCallback callback)531 void GetServerBackedStateKeys(StateKeysCallback callback) override {
532 dbus::MethodCall method_call(
533 login_manager::kSessionManagerInterface,
534 login_manager::kSessionManagerGetServerBackedStateKeys);
535
536 // Infinite timeout needed because the state keys are not generated as long
537 // as the time sync hasn't been done (which requires network).
538 // TODO(igorcov): Since this is a resource allocated that could last a long
539 // time, we will need to change the behavior to either listen to
540 // LastSyncInfo event from tlsdated or communicate through signals with
541 // session manager in this particular flow.
542 session_manager_proxy_->CallMethod(
543 &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
544 base::BindOnce(&SessionManagerClientImpl::OnGetServerBackedStateKeys,
545 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
546 }
547
StartArcMiniContainer(const login_manager::StartArcMiniContainerRequest & request,VoidDBusMethodCallback callback)548 void StartArcMiniContainer(
549 const login_manager::StartArcMiniContainerRequest& request,
550 VoidDBusMethodCallback callback) override {
551 DCHECK(!callback.is_null());
552 dbus::MethodCall method_call(
553 login_manager::kSessionManagerInterface,
554 login_manager::kSessionManagerStartArcMiniContainer);
555 dbus::MessageWriter writer(&method_call);
556
557 writer.AppendProtoAsArrayOfBytes(request);
558
559 session_manager_proxy_->CallMethod(
560 &method_call, kStartArcTimeout,
561 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
562 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
563 }
564
UpgradeArcContainer(const login_manager::UpgradeArcContainerRequest & request,VoidDBusMethodCallback callback)565 void UpgradeArcContainer(
566 const login_manager::UpgradeArcContainerRequest& request,
567 VoidDBusMethodCallback callback) override {
568 DCHECK(!callback.is_null());
569 dbus::MethodCall method_call(
570 login_manager::kSessionManagerInterface,
571 login_manager::kSessionManagerUpgradeArcContainer);
572 dbus::MessageWriter writer(&method_call);
573
574 writer.AppendProtoAsArrayOfBytes(request);
575
576 session_manager_proxy_->CallMethod(
577 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
578 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
579 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
580 }
581
StopArcInstance(const std::string & account_id,bool should_backup_log,VoidDBusMethodCallback callback)582 void StopArcInstance(const std::string& account_id,
583 bool should_backup_log,
584 VoidDBusMethodCallback callback) override {
585 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
586 login_manager::kSessionManagerStopArcInstance);
587
588 dbus::MessageWriter writer(&method_call);
589 writer.AppendString(account_id);
590 writer.AppendBool(should_backup_log);
591
592 session_manager_proxy_->CallMethod(
593 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
594 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
595 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
596 }
597
SetArcCpuRestriction(login_manager::ContainerCpuRestrictionState restriction_state,VoidDBusMethodCallback callback)598 void SetArcCpuRestriction(
599 login_manager::ContainerCpuRestrictionState restriction_state,
600 VoidDBusMethodCallback callback) override {
601 dbus::MethodCall method_call(
602 login_manager::kSessionManagerInterface,
603 login_manager::kSessionManagerSetArcCpuRestriction);
604 dbus::MessageWriter writer(&method_call);
605 writer.AppendUint32(restriction_state);
606 session_manager_proxy_->CallMethod(
607 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
608 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
609 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
610 }
611
EmitArcBooted(const cryptohome::AccountIdentifier & cryptohome_id,VoidDBusMethodCallback callback)612 void EmitArcBooted(const cryptohome::AccountIdentifier& cryptohome_id,
613 VoidDBusMethodCallback callback) override {
614 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
615 login_manager::kSessionManagerEmitArcBooted);
616 dbus::MessageWriter writer(&method_call);
617 writer.AppendString(cryptohome_id.account_id());
618 session_manager_proxy_->CallMethod(
619 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
620 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
621 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
622 }
623
GetArcStartTime(DBusMethodCallback<base::TimeTicks> callback)624 void GetArcStartTime(DBusMethodCallback<base::TimeTicks> callback) override {
625 dbus::MethodCall method_call(
626 login_manager::kSessionManagerInterface,
627 login_manager::kSessionManagerGetArcStartTimeTicks);
628
629 session_manager_proxy_->CallMethod(
630 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
631 base::BindOnce(&SessionManagerClientImpl::OnGetArcStartTime,
632 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
633 }
634
EnableAdbSideload(EnableAdbSideloadCallback callback)635 void EnableAdbSideload(EnableAdbSideloadCallback callback) override {
636 dbus::MethodCall method_call(
637 login_manager::kSessionManagerInterface,
638 login_manager::kSessionManagerEnableAdbSideload);
639
640 session_manager_proxy_->CallMethodWithErrorResponse(
641 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
642 base::BindOnce(&SessionManagerClientImpl::OnEnableAdbSideload,
643 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
644 }
645
QueryAdbSideload(QueryAdbSideloadCallback callback)646 void QueryAdbSideload(QueryAdbSideloadCallback callback) override {
647 dbus::MethodCall method_call(
648 login_manager::kSessionManagerInterface,
649 login_manager::kSessionManagerQueryAdbSideload);
650
651 session_manager_proxy_->CallMethodWithErrorResponse(
652 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
653 base::BindOnce(&SessionManagerClientImpl::OnQueryAdbSideload,
654 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
655 }
656
Init(dbus::Bus * bus)657 void Init(dbus::Bus* bus) {
658 session_manager_proxy_ = bus->GetObjectProxy(
659 login_manager::kSessionManagerServiceName,
660 dbus::ObjectPath(login_manager::kSessionManagerServicePath));
661 blocking_method_caller_.reset(
662 new BlockingMethodCaller(bus, session_manager_proxy_));
663
664 // Signals emitted on the session manager's interface.
665 session_manager_proxy_->ConnectToSignal(
666 login_manager::kSessionManagerInterface,
667 login_manager::kOwnerKeySetSignal,
668 base::BindRepeating(&SessionManagerClientImpl::OwnerKeySetReceived,
669 weak_ptr_factory_.GetWeakPtr()),
670 base::BindOnce(&SessionManagerClientImpl::SignalConnected,
671 weak_ptr_factory_.GetWeakPtr()));
672 session_manager_proxy_->ConnectToSignal(
673 login_manager::kSessionManagerInterface,
674 login_manager::kPropertyChangeCompleteSignal,
675 base::BindRepeating(
676 &SessionManagerClientImpl::PropertyChangeCompleteReceived,
677 weak_ptr_factory_.GetWeakPtr()),
678 base::BindOnce(&SessionManagerClientImpl::SignalConnected,
679 weak_ptr_factory_.GetWeakPtr()));
680 session_manager_proxy_->ConnectToSignal(
681 login_manager::kSessionManagerInterface,
682 login_manager::kScreenIsLockedSignal,
683 base::BindRepeating(&SessionManagerClientImpl::ScreenIsLockedReceived,
684 weak_ptr_factory_.GetWeakPtr()),
685 base::BindOnce(&SessionManagerClientImpl::SignalConnected,
686 weak_ptr_factory_.GetWeakPtr()));
687 session_manager_proxy_->ConnectToSignal(
688 login_manager::kSessionManagerInterface,
689 login_manager::kScreenIsUnlockedSignal,
690 base::BindRepeating(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
691 weak_ptr_factory_.GetWeakPtr()),
692 base::BindOnce(&SessionManagerClientImpl::SignalConnected,
693 weak_ptr_factory_.GetWeakPtr()));
694 session_manager_proxy_->ConnectToSignal(
695 login_manager::kSessionManagerInterface,
696 login_manager::kArcInstanceStopped,
697 base::BindRepeating(
698 &SessionManagerClientImpl::ArcInstanceStoppedReceived,
699 weak_ptr_factory_.GetWeakPtr()),
700 base::BindOnce(&SessionManagerClientImpl::SignalConnected,
701 weak_ptr_factory_.GetWeakPtr()));
702 }
703
704 private:
705 // Makes a method call to the session manager with no arguments and no
706 // response.
SimpleMethodCallToSessionManager(const std::string & method_name)707 void SimpleMethodCallToSessionManager(const std::string& method_name) {
708 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
709 method_name);
710 session_manager_proxy_->CallMethod(&method_call,
711 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
712 base::DoNothing());
713 }
714
715 // Called when the method call without result is completed.
OnVoidMethod(VoidDBusMethodCallback callback,dbus::Response * response)716 void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) {
717 std::move(callback).Run(response);
718 }
719
720 // Non-blocking call to Session Manager to retrieve policy.
CallRetrievePolicy(const login_manager::PolicyDescriptor & descriptor,RetrievePolicyCallback callback)721 void CallRetrievePolicy(const login_manager::PolicyDescriptor& descriptor,
722 RetrievePolicyCallback callback) {
723 dbus::MethodCall method_call(
724 login_manager::kSessionManagerInterface,
725 login_manager::kSessionManagerRetrievePolicyEx);
726 dbus::MessageWriter writer(&method_call);
727 const std::string descriptor_blob = descriptor.SerializeAsString();
728 // static_cast does not work due to signedness.
729 writer.AppendArrayOfBytes(
730 reinterpret_cast<const uint8_t*>(descriptor_blob.data()),
731 descriptor_blob.size());
732 session_manager_proxy_->CallMethodWithErrorResponse(
733 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
734 base::BindOnce(&SessionManagerClientImpl::OnRetrievePolicy,
735 weak_ptr_factory_.GetWeakPtr(),
736 descriptor.account_type(), std::move(callback)));
737 }
738
739 // Blocking call to Session Manager to retrieve policy.
CallBlockingRetrievePolicy(const login_manager::PolicyDescriptor & descriptor,std::string * policy_out)740 RetrievePolicyResponseType CallBlockingRetrievePolicy(
741 const login_manager::PolicyDescriptor& descriptor,
742 std::string* policy_out) {
743 dbus::MethodCall method_call(
744 login_manager::kSessionManagerInterface,
745 login_manager::kSessionManagerRetrievePolicyEx);
746 dbus::MessageWriter writer(&method_call);
747 const std::string descriptor_blob = descriptor.SerializeAsString();
748 // static_cast does not work due to signedness.
749 writer.AppendArrayOfBytes(
750 reinterpret_cast<const uint8_t*>(descriptor_blob.data()),
751 descriptor_blob.size());
752 dbus::ScopedDBusError error;
753 std::unique_ptr<dbus::Response> response =
754 blocking_method_caller_->CallMethodAndBlockWithError(&method_call,
755 &error);
756 RetrievePolicyResponseType result = RetrievePolicyResponseType::SUCCESS;
757 if (error.is_set() && error.name()) {
758 result = GetPolicyResponseTypeByError(error.name());
759 }
760 if (result == RetrievePolicyResponseType::SUCCESS) {
761 ExtractPolicyResponseString(descriptor.account_type(), response.get(),
762 policy_out);
763 } else {
764 policy_out->clear();
765 }
766 LogPolicyResponseUma(descriptor.account_type(), result);
767 return result;
768 }
769
CallStorePolicy(const login_manager::PolicyDescriptor & descriptor,const std::string & policy_blob,VoidDBusMethodCallback callback)770 void CallStorePolicy(const login_manager::PolicyDescriptor& descriptor,
771 const std::string& policy_blob,
772 VoidDBusMethodCallback callback) {
773 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
774 login_manager::kSessionManagerStorePolicyEx);
775 dbus::MessageWriter writer(&method_call);
776 const std::string descriptor_blob = descriptor.SerializeAsString();
777 // static_cast does not work due to signedness.
778 writer.AppendArrayOfBytes(
779 reinterpret_cast<const uint8_t*>(descriptor_blob.data()),
780 descriptor_blob.size());
781 writer.AppendArrayOfBytes(
782 reinterpret_cast<const uint8_t*>(policy_blob.data()),
783 policy_blob.size());
784 // TODO(crbug/1155533) On grunt devices, initially storing device policy may
785 // take about 45s, which is longer than the default timeout for dbus calls.
786 // We need to investiage why this is happening. In the meantime, increase
787 // the timeout to make sure enrollment does not fail.
788 session_manager_proxy_->CallMethod(
789 &method_call, /*timeout_ms=*/90000,
790 base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
791 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
792 }
793
794 // Called when kSessionManagerRetrieveActiveSessions method is complete.
OnRetrieveActiveSessions(const std::string & method_name,ActiveSessionsCallback callback,dbus::Response * response)795 void OnRetrieveActiveSessions(const std::string& method_name,
796 ActiveSessionsCallback callback,
797 dbus::Response* response) {
798 if (!response) {
799 std::move(callback).Run(base::nullopt);
800 return;
801 }
802
803 dbus::MessageReader reader(response);
804 dbus::MessageReader array_reader(nullptr);
805 if (!reader.PopArray(&array_reader)) {
806 LOG(ERROR) << method_name
807 << " response is incorrect: " << response->ToString();
808 std::move(callback).Run(base::nullopt);
809 return;
810 }
811
812 ActiveSessionsMap sessions;
813 while (array_reader.HasMoreData()) {
814 dbus::MessageReader dict_entry_reader(nullptr);
815 std::string key;
816 std::string value;
817 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
818 !dict_entry_reader.PopString(&key) ||
819 !dict_entry_reader.PopString(&value)) {
820 LOG(ERROR) << method_name
821 << " response is incorrect: " << response->ToString();
822 } else {
823 sessions[key] = value;
824 }
825 }
826 std::move(callback).Run(std::move(sessions));
827 }
828
OnLoginScreenStorageStore(LoginScreenStorageStoreCallback callback,dbus::Response * response)829 void OnLoginScreenStorageStore(LoginScreenStorageStoreCallback callback,
830 dbus::Response* response) {
831 std::move(callback).Run(base::nullopt);
832 }
833
OnLoginScreenStorageRetrieve(LoginScreenStorageRetrieveCallback callback,dbus::Response * response)834 void OnLoginScreenStorageRetrieve(LoginScreenStorageRetrieveCallback callback,
835 dbus::Response* response) {
836 if (!response) {
837 std::move(callback).Run(base::nullopt /* data */,
838 "LoginScreenStorageRetrieve() D-Bus method "
839 "returned an empty response");
840 return;
841 }
842
843 dbus::MessageReader reader(response);
844 base::ScopedFD result_fd;
845 uint64_t result_size;
846 if (!reader.PopUint64(&result_size) ||
847 !reader.PopFileDescriptor(&result_fd)) {
848 std::string error = "Invalid response: " + response->ToString();
849 std::move(callback).Run(base::nullopt /* data */, error);
850 return;
851 }
852 std::vector<uint8_t> result_data;
853 if (!ReadSecretFromSharedMemory(std::move(result_fd), result_size,
854 &result_data)) {
855 std::string error = "Couldn't read retrieved data from shared memory.";
856 std::move(callback).Run(base::nullopt /* data */, error);
857 return;
858 }
859 std::move(callback).Run(std::string(result_data.begin(), result_data.end()),
860 base::nullopt /* error */);
861 }
862
OnLoginScreenStorageListKeys(LoginScreenStorageListKeysCallback callback,dbus::Response * response)863 void OnLoginScreenStorageListKeys(LoginScreenStorageListKeysCallback callback,
864 dbus::Response* response) {
865 if (!response) {
866 // TODO(voit): Add more granular error handling: key is not found error vs
867 // general 'something went wrong' error.
868 std::move(callback).Run({} /* keys */,
869 "LoginScreenStorageListKeys() D-Bus method "
870 "returned an empty response");
871 return;
872 }
873 dbus::MessageReader reader(response);
874 std::vector<std::string> keys;
875 if (!reader.PopArrayOfStrings(&keys)) {
876 std::string error = "Invalid response: " + response->ToString();
877 std::move(callback).Run({} /* keys */, error);
878 return;
879 }
880 std::move(callback).Run(std::move(keys), base::nullopt /* error */);
881 }
882
883 // Reads an array of policy data bytes data as std::string.
ExtractPolicyResponseString(login_manager::PolicyAccountType account_type,dbus::Response * response,std::string * extracted)884 void ExtractPolicyResponseString(
885 login_manager::PolicyAccountType account_type,
886 dbus::Response* response,
887 std::string* extracted) {
888 if (!response) {
889 LOG(ERROR) << "Failed to call RetrievePolicyEx for account type "
890 << account_type;
891 return;
892 }
893 dbus::MessageReader reader(response);
894 const uint8_t* values = nullptr;
895 size_t length = 0;
896 if (!reader.PopArrayOfBytes(&values, &length)) {
897 LOG(ERROR) << "Invalid response: " << response->ToString();
898 return;
899 }
900 // static_cast does not work due to signedness.
901 extracted->assign(reinterpret_cast<const char*>(values), length);
902 }
903
904 // Called when kSessionManagerRetrievePolicy or
905 // kSessionManagerRetrievePolicyForUser method is complete.
OnRetrievePolicy(login_manager::PolicyAccountType account_type,RetrievePolicyCallback callback,dbus::Response * response,dbus::ErrorResponse * error)906 void OnRetrievePolicy(login_manager::PolicyAccountType account_type,
907 RetrievePolicyCallback callback,
908 dbus::Response* response,
909 dbus::ErrorResponse* error) {
910 if (!response) {
911 RetrievePolicyResponseType response_type =
912 GetPolicyResponseTypeByError(error ? error->GetErrorName() : "");
913 LogPolicyResponseUma(account_type, response_type);
914 std::move(callback).Run(response_type, std::string());
915 return;
916 }
917
918 dbus::MessageReader reader(response);
919 std::string proto_blob;
920 ExtractPolicyResponseString(account_type, response, &proto_blob);
921 LogPolicyResponseUma(account_type, RetrievePolicyResponseType::SUCCESS);
922 std::move(callback).Run(RetrievePolicyResponseType::SUCCESS, proto_blob);
923 }
924
925 // Called when the owner key set signal is received.
OwnerKeySetReceived(dbus::Signal * signal)926 void OwnerKeySetReceived(dbus::Signal* signal) {
927 dbus::MessageReader reader(signal);
928 std::string result_string;
929 if (!reader.PopString(&result_string)) {
930 LOG(ERROR) << "Invalid signal: " << signal->ToString();
931 return;
932 }
933 const bool success = base::StartsWith(result_string, "success",
934 base::CompareCase::INSENSITIVE_ASCII);
935 for (auto& observer : observers_)
936 observer.OwnerKeySet(success);
937 }
938
939 // Called when the property change complete signal is received.
PropertyChangeCompleteReceived(dbus::Signal * signal)940 void PropertyChangeCompleteReceived(dbus::Signal* signal) {
941 dbus::MessageReader reader(signal);
942 std::string result_string;
943 if (!reader.PopString(&result_string)) {
944 LOG(ERROR) << "Invalid signal: " << signal->ToString();
945 return;
946 }
947 const bool success = base::StartsWith(result_string, "success",
948 base::CompareCase::INSENSITIVE_ASCII);
949 for (auto& observer : observers_)
950 observer.PropertyChangeComplete(success);
951 }
952
ScreenIsLockedReceived(dbus::Signal * signal)953 void ScreenIsLockedReceived(dbus::Signal* signal) {
954 screen_is_locked_ = true;
955 }
956
ScreenIsUnlockedReceived(dbus::Signal * signal)957 void ScreenIsUnlockedReceived(dbus::Signal* signal) {
958 screen_is_locked_ = false;
959 }
960
ArcInstanceStoppedReceived(dbus::Signal * signal)961 void ArcInstanceStoppedReceived(dbus::Signal* signal) {
962 for (auto& observer : observers_)
963 observer.ArcInstanceStopped();
964 }
965
966 // Called when the object is connected to the signal.
SignalConnected(const std::string & interface_name,const std::string & signal_name,bool success)967 void SignalConnected(const std::string& interface_name,
968 const std::string& signal_name,
969 bool success) {
970 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
971 }
972
973 // Called when kSessionManagerGetServerBackedStateKeys method is complete.
OnGetServerBackedStateKeys(StateKeysCallback callback,dbus::Response * response)974 void OnGetServerBackedStateKeys(StateKeysCallback callback,
975 dbus::Response* response) {
976 std::vector<std::string> state_keys;
977 if (response) {
978 dbus::MessageReader reader(response);
979 dbus::MessageReader array_reader(nullptr);
980
981 if (!reader.PopArray(&array_reader)) {
982 LOG(ERROR) << "Bad response: " << response->ToString();
983 } else {
984 while (array_reader.HasMoreData()) {
985 const uint8_t* data = nullptr;
986 size_t size = 0;
987 if (!array_reader.PopArrayOfBytes(&data, &size)) {
988 LOG(ERROR) << "Bad response: " << response->ToString();
989 state_keys.clear();
990 break;
991 }
992 state_keys.emplace_back(reinterpret_cast<const char*>(data), size);
993 }
994 }
995 }
996
997 std::move(callback).Run(state_keys);
998 }
999
OnGetArcStartTime(DBusMethodCallback<base::TimeTicks> callback,dbus::Response * response)1000 void OnGetArcStartTime(DBusMethodCallback<base::TimeTicks> callback,
1001 dbus::Response* response) {
1002 if (!response) {
1003 std::move(callback).Run(base::nullopt);
1004 return;
1005 }
1006
1007 dbus::MessageReader reader(response);
1008 int64_t ticks = 0;
1009 if (!reader.PopInt64(&ticks)) {
1010 LOG(ERROR) << "Invalid response: " << response->ToString();
1011 std::move(callback).Run(base::nullopt);
1012 return;
1013 }
1014
1015 std::move(callback).Run(base::TimeTicks::FromInternalValue(ticks));
1016 }
1017
OnEnableAdbSideload(EnableAdbSideloadCallback callback,dbus::Response * response,dbus::ErrorResponse * error)1018 void OnEnableAdbSideload(EnableAdbSideloadCallback callback,
1019 dbus::Response* response,
1020 dbus::ErrorResponse* error) {
1021 if (!response) {
1022 LOG(ERROR) << "Failed to call EnableAdbSideload: "
1023 << (error ? error->ToString() : "(null)");
1024 if (error && error->GetErrorName() == DBUS_ERROR_NOT_SUPPORTED) {
1025 std::move(callback).Run(AdbSideloadResponseCode::NEED_POWERWASH);
1026 } else {
1027 std::move(callback).Run(AdbSideloadResponseCode::FAILED);
1028 }
1029 return;
1030 }
1031
1032 bool succeeded;
1033 dbus::MessageReader reader(response);
1034 if (!reader.PopBool(&succeeded)) {
1035 LOG(ERROR) << "Failed to enable sideloading";
1036 std::move(callback).Run(AdbSideloadResponseCode::FAILED);
1037 return;
1038 }
1039 std::move(callback).Run(AdbSideloadResponseCode::SUCCESS);
1040 }
1041
OnQueryAdbSideload(QueryAdbSideloadCallback callback,dbus::Response * response,dbus::ErrorResponse * error)1042 void OnQueryAdbSideload(QueryAdbSideloadCallback callback,
1043 dbus::Response* response,
1044 dbus::ErrorResponse* error) {
1045 if (!response) {
1046 LOG(ERROR) << "Failed to call QueryAdbSideload: "
1047 << (error ? error->ToString() : "(null)");
1048 if (error && error->GetErrorName() == DBUS_ERROR_NOT_SUPPORTED) {
1049 std::move(callback).Run(AdbSideloadResponseCode::NEED_POWERWASH, false);
1050 } else {
1051 std::move(callback).Run(AdbSideloadResponseCode::FAILED, false);
1052 }
1053 return;
1054 }
1055
1056 bool is_allowed;
1057 dbus::MessageReader reader(response);
1058 if (!reader.PopBool(&is_allowed)) {
1059 LOG(ERROR) << "Failed to interpret the response";
1060 std::move(callback).Run(AdbSideloadResponseCode::FAILED, false);
1061 return;
1062 }
1063 std::move(callback).Run(AdbSideloadResponseCode::SUCCESS, is_allowed);
1064 }
1065
1066 dbus::ObjectProxy* session_manager_proxy_ = nullptr;
1067 std::unique_ptr<BlockingMethodCaller> blocking_method_caller_;
1068 base::ObserverList<Observer>::Unchecked observers_{
1069 SessionManagerClient::kObserverListPolicy};
1070
1071 // Most recent screen-lock state received from session_manager.
1072 bool screen_is_locked_ = false;
1073
1074 // Note: This should remain the last member so it'll be destroyed and
1075 // invalidate its weak pointers before any other members are destroyed.
1076 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_{this};
1077
1078 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
1079 };
1080
SessionManagerClient()1081 SessionManagerClient::SessionManagerClient() {
1082 DCHECK(!g_instance);
1083 g_instance = this;
1084 }
1085
~SessionManagerClient()1086 SessionManagerClient::~SessionManagerClient() {
1087 DCHECK_EQ(this, g_instance);
1088 g_instance = nullptr;
1089 }
1090
1091 // static
Initialize(dbus::Bus * bus)1092 void SessionManagerClient::Initialize(dbus::Bus* bus) {
1093 DCHECK(bus);
1094 (new SessionManagerClientImpl)->Init(bus);
1095 }
1096
1097 // static
InitializeFake()1098 void SessionManagerClient::InitializeFake() {
1099 // Do not create a new fake if it was initialized early in a browser test (for
1100 // early setup calls dependent on SessionManagerClient).
1101 if (!FakeSessionManagerClient::Get()) {
1102 new FakeSessionManagerClient(
1103 FakeSessionManagerClient::PolicyStorageType::kOnDisk);
1104 }
1105 }
1106
1107 // static
InitializeFakeInMemory()1108 void SessionManagerClient::InitializeFakeInMemory() {
1109 if (!FakeSessionManagerClient::Get()) {
1110 new FakeSessionManagerClient(
1111 FakeSessionManagerClient::PolicyStorageType::kInMemory);
1112 }
1113 }
1114
1115 // static
Shutdown()1116 void SessionManagerClient::Shutdown() {
1117 DCHECK(g_instance);
1118 delete g_instance;
1119 }
1120
1121 // static
Get()1122 SessionManagerClient* SessionManagerClient::Get() {
1123 return g_instance;
1124 }
1125
1126 } // namespace chromeos
1127