Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / chromeos / dbus / session_manager_client.cc
blob6965cd1d1a8d0bb47fbfe217a790bc46c462e1ec
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.
5 #include "chromeos/dbus/session_manager_client.h"
7 #include <sys/socket.h>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/location.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/task_runner_util.h"
18 #include "base/threading/worker_pool.h"
19 #include "chromeos/chromeos_paths.h"
20 #include "chromeos/dbus/blocking_method_caller.h"
21 #include "chromeos/dbus/cryptohome_client.h"
22 #include "crypto/sha2.h"
23 #include "dbus/bus.h"
24 #include "dbus/message.h"
25 #include "dbus/object_path.h"
26 #include "dbus/object_proxy.h"
27 #include "policy/proto/device_management_backend.pb.h"
28 #include "third_party/cros_system_api/dbus/service_constants.h"
30 namespace chromeos {
32 namespace {
34 // Returns a location for |file| that is specific to the given |username|.
35 // These paths will be relative to DIR_USER_POLICY_KEYS, and can be used only
36 // to store stub files.
37 base::FilePath GetUserFilePath(const std::string& username, const char* file) {
38 base::FilePath keys_path;
39 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &keys_path))
40 return base::FilePath();
41 const std::string sanitized =
42 CryptohomeClient::GetStubSanitizedUsername(username);
43 return keys_path.AppendASCII(sanitized).AppendASCII(file);
46 // Helper to asynchronously retrieve a file's content.
47 std::string GetFileContent(const base::FilePath& path) {
48 std::string result;
49 if (!path.empty())
50 base::ReadFileToString(path, &result);
51 return result;
54 // Helper to write a file in a background thread.
55 void StoreFile(const base::FilePath& path, const std::string& data) {
56 const int size = static_cast<int>(data.size());
57 if (path.empty() ||
58 !base::CreateDirectory(path.DirName()) ||
59 base::WriteFile(path, data.data(), size) != size) {
60 LOG(WARNING) << "Failed to write to " << path.value();
64 // Creates a pair of file descriptors that form a conduit for trustworthy
65 // transfer of credentials between Chrome and the session_manager
66 void CreateValidCredConduit(dbus::FileDescriptor* local_auth_fd,
67 dbus::FileDescriptor* remote_auth_fd) {
68 int sockets[2] = {-1, -1};
69 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
70 PLOG(ERROR) << "Failed to create a unix domain socketpair";
71 return;
74 local_auth_fd->PutValue(sockets[0]);
75 local_auth_fd->CheckValidity();
77 remote_auth_fd->PutValue(sockets[1]);
78 remote_auth_fd->CheckValidity();
81 } // namespace
83 // The SessionManagerClient implementation used in production.
84 class SessionManagerClientImpl : public SessionManagerClient {
85 public:
86 SessionManagerClientImpl()
87 : session_manager_proxy_(NULL),
88 screen_is_locked_(false),
89 weak_ptr_factory_(this) {}
91 ~SessionManagerClientImpl() override {}
93 // SessionManagerClient overrides:
94 void SetStubDelegate(StubDelegate* delegate) override {
95 // Do nothing; this isn't a stub implementation.
98 void AddObserver(Observer* observer) override {
99 observers_.AddObserver(observer);
102 void RemoveObserver(Observer* observer) override {
103 observers_.RemoveObserver(observer);
106 bool HasObserver(const Observer* observer) const override {
107 return observers_.HasObserver(observer);
110 bool IsScreenLocked() const override { return screen_is_locked_; }
112 void EmitLoginPromptVisible() override {
113 SimpleMethodCallToSessionManager(
114 login_manager::kSessionManagerEmitLoginPromptVisible);
115 FOR_EACH_OBSERVER(Observer, observers_, EmitLoginPromptVisibleCalled());
118 void RestartJob(int pid, const std::string& command_line) override {
119 dbus::ScopedFileDescriptor local_auth_fd(new dbus::FileDescriptor());
120 dbus::ScopedFileDescriptor remote_auth_fd(new dbus::FileDescriptor());
122 // The session_manager provides a new method to replace RestartJob, called
123 // RestartJobWithAuth, that is able to be used correctly within a PID
124 // namespace. To use it, the caller must create a unix domain socket pair
125 // and pass one end over dbus while holding the local end open for the
126 // duration of the call.
127 // Here, we call CreateValidCredConduit() to create the socket pair,
128 // and then pass both ends along to CallRestartJobWithValidFd(), which
129 // takes care of them from there.
130 // NB: PostTaskAndReply ensures that the second callback (which owns the
131 // ScopedFileDescriptor objects) outlives the first, so passing the
132 // bare pointers to CreateValidCredConduit is safe.
133 base::WorkerPool::PostTaskAndReply(
134 FROM_HERE, base::Bind(&CreateValidCredConduit, local_auth_fd.get(),
135 remote_auth_fd.get()),
136 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd,
137 weak_ptr_factory_.GetWeakPtr(), base::Passed(&local_auth_fd),
138 base::Passed(&remote_auth_fd), command_line),
139 false);
142 void StartSession(const std::string& user_email) override {
143 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
144 login_manager::kSessionManagerStartSession);
145 dbus::MessageWriter writer(&method_call);
146 writer.AppendString(user_email);
147 writer.AppendString(""); // Unique ID is deprecated
148 session_manager_proxy_->CallMethod(
149 &method_call,
150 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
151 base::Bind(&SessionManagerClientImpl::OnStartSession,
152 weak_ptr_factory_.GetWeakPtr()));
155 void StopSession() override {
156 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
157 login_manager::kSessionManagerStopSession);
158 dbus::MessageWriter writer(&method_call);
159 writer.AppendString(""); // Unique ID is deprecated
160 session_manager_proxy_->CallMethod(
161 &method_call,
162 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
163 base::Bind(&SessionManagerClientImpl::OnStopSession,
164 weak_ptr_factory_.GetWeakPtr()));
167 void StartDeviceWipe() override {
168 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
169 login_manager::kSessionManagerStartDeviceWipe);
170 session_manager_proxy_->CallMethod(
171 &method_call,
172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
173 base::Bind(&SessionManagerClientImpl::OnDeviceWipe,
174 weak_ptr_factory_.GetWeakPtr()));
177 void RequestLockScreen() override {
178 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
181 void NotifyLockScreenShown() override {
182 SimpleMethodCallToSessionManager(
183 login_manager::kSessionManagerHandleLockScreenShown);
186 void NotifyLockScreenDismissed() override {
187 SimpleMethodCallToSessionManager(
188 login_manager::kSessionManagerHandleLockScreenDismissed);
191 void NotifySupervisedUserCreationStarted() override {
192 SimpleMethodCallToSessionManager(
193 login_manager::kSessionManagerHandleSupervisedUserCreationStarting);
196 void NotifySupervisedUserCreationFinished() override {
197 SimpleMethodCallToSessionManager(
198 login_manager::kSessionManagerHandleSupervisedUserCreationFinished);
201 void RetrieveActiveSessions(const ActiveSessionsCallback& callback) override {
202 dbus::MethodCall method_call(
203 login_manager::kSessionManagerInterface,
204 login_manager::kSessionManagerRetrieveActiveSessions);
206 session_manager_proxy_->CallMethod(
207 &method_call,
208 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
209 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions,
210 weak_ptr_factory_.GetWeakPtr(),
211 login_manager::kSessionManagerRetrieveActiveSessions,
212 callback));
215 void RetrieveDevicePolicy(const RetrievePolicyCallback& callback) override {
216 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
217 login_manager::kSessionManagerRetrievePolicy);
218 session_manager_proxy_->CallMethod(
219 &method_call,
220 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
221 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
222 weak_ptr_factory_.GetWeakPtr(),
223 login_manager::kSessionManagerRetrievePolicy,
224 callback));
227 void RetrievePolicyForUser(const std::string& username,
228 const RetrievePolicyCallback& callback) override {
229 CallRetrievePolicyByUsername(
230 login_manager::kSessionManagerRetrievePolicyForUser,
231 username,
232 callback);
235 std::string BlockingRetrievePolicyForUser(
236 const std::string& username) override {
237 dbus::MethodCall method_call(
238 login_manager::kSessionManagerInterface,
239 login_manager::kSessionManagerRetrievePolicyForUser);
240 dbus::MessageWriter writer(&method_call);
241 writer.AppendString(username);
242 scoped_ptr<dbus::Response> response =
243 blocking_method_caller_->CallMethodAndBlock(&method_call);
244 std::string policy;
245 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser,
246 response.get(),
247 &policy);
248 return policy;
251 void RetrieveDeviceLocalAccountPolicy(
252 const std::string& account_name,
253 const RetrievePolicyCallback& callback) override {
254 CallRetrievePolicyByUsername(
255 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
256 account_name,
257 callback);
260 void StoreDevicePolicy(const std::string& policy_blob,
261 const StorePolicyCallback& callback) override {
262 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
263 login_manager::kSessionManagerStorePolicy);
264 dbus::MessageWriter writer(&method_call);
265 // static_cast does not work due to signedness.
266 writer.AppendArrayOfBytes(
267 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
268 session_manager_proxy_->CallMethod(
269 &method_call,
270 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
271 base::Bind(&SessionManagerClientImpl::OnStorePolicy,
272 weak_ptr_factory_.GetWeakPtr(),
273 login_manager::kSessionManagerStorePolicy,
274 callback));
277 void StorePolicyForUser(const std::string& username,
278 const std::string& policy_blob,
279 const StorePolicyCallback& callback) override {
280 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
281 username,
282 policy_blob,
283 callback);
286 void StoreDeviceLocalAccountPolicy(
287 const std::string& account_name,
288 const std::string& policy_blob,
289 const StorePolicyCallback& callback) override {
290 CallStorePolicyByUsername(
291 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
292 account_name,
293 policy_blob,
294 callback);
297 void SetFlagsForUser(const std::string& username,
298 const std::vector<std::string>& flags) override {
299 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
300 login_manager::kSessionManagerSetFlagsForUser);
301 dbus::MessageWriter writer(&method_call);
302 writer.AppendString(username);
303 writer.AppendArrayOfStrings(flags);
304 session_manager_proxy_->CallMethod(
305 &method_call,
306 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
307 dbus::ObjectProxy::EmptyResponseCallback());
310 void GetServerBackedStateKeys(const StateKeysCallback& callback) override {
311 dbus::MethodCall method_call(
312 login_manager::kSessionManagerInterface,
313 login_manager::kSessionManagerGetServerBackedStateKeys);
315 session_manager_proxy_->CallMethod(
316 &method_call,
317 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
318 base::Bind(&SessionManagerClientImpl::OnGetServerBackedStateKeys,
319 weak_ptr_factory_.GetWeakPtr(),
320 callback));
323 protected:
324 void Init(dbus::Bus* bus) override {
325 session_manager_proxy_ = bus->GetObjectProxy(
326 login_manager::kSessionManagerServiceName,
327 dbus::ObjectPath(login_manager::kSessionManagerServicePath));
328 blocking_method_caller_.reset(
329 new BlockingMethodCaller(bus, session_manager_proxy_));
331 // Signals emitted on the session manager's interface.
332 session_manager_proxy_->ConnectToSignal(
333 login_manager::kSessionManagerInterface,
334 login_manager::kOwnerKeySetSignal,
335 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
336 weak_ptr_factory_.GetWeakPtr()),
337 base::Bind(&SessionManagerClientImpl::SignalConnected,
338 weak_ptr_factory_.GetWeakPtr()));
339 session_manager_proxy_->ConnectToSignal(
340 login_manager::kSessionManagerInterface,
341 login_manager::kPropertyChangeCompleteSignal,
342 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
343 weak_ptr_factory_.GetWeakPtr()),
344 base::Bind(&SessionManagerClientImpl::SignalConnected,
345 weak_ptr_factory_.GetWeakPtr()));
346 session_manager_proxy_->ConnectToSignal(
347 login_manager::kSessionManagerInterface,
348 login_manager::kScreenIsLockedSignal,
349 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived,
350 weak_ptr_factory_.GetWeakPtr()),
351 base::Bind(&SessionManagerClientImpl::SignalConnected,
352 weak_ptr_factory_.GetWeakPtr()));
353 session_manager_proxy_->ConnectToSignal(
354 login_manager::kSessionManagerInterface,
355 login_manager::kScreenIsUnlockedSignal,
356 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
357 weak_ptr_factory_.GetWeakPtr()),
358 base::Bind(&SessionManagerClientImpl::SignalConnected,
359 weak_ptr_factory_.GetWeakPtr()));
362 private:
363 // Makes a method call to the session manager with no arguments and no
364 // response.
365 void SimpleMethodCallToSessionManager(const std::string& method_name) {
366 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
367 method_name);
368 session_manager_proxy_->CallMethod(
369 &method_call,
370 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
371 dbus::ObjectProxy::EmptyResponseCallback());
374 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
375 void CallRetrievePolicyByUsername(const std::string& method_name,
376 const std::string& username,
377 const RetrievePolicyCallback& callback) {
378 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
379 method_name);
380 dbus::MessageWriter writer(&method_call);
381 writer.AppendString(username);
382 session_manager_proxy_->CallMethod(
383 &method_call,
384 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
385 base::Bind(
386 &SessionManagerClientImpl::OnRetrievePolicy,
387 weak_ptr_factory_.GetWeakPtr(),
388 method_name,
389 callback));
392 void CallStorePolicyByUsername(const std::string& method_name,
393 const std::string& username,
394 const std::string& policy_blob,
395 const StorePolicyCallback& callback) {
396 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
397 method_name);
398 dbus::MessageWriter writer(&method_call);
399 writer.AppendString(username);
400 // static_cast does not work due to signedness.
401 writer.AppendArrayOfBytes(
402 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
403 session_manager_proxy_->CallMethod(
404 &method_call,
405 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
406 base::Bind(
407 &SessionManagerClientImpl::OnStorePolicy,
408 weak_ptr_factory_.GetWeakPtr(),
409 method_name,
410 callback));
413 // Calls RestartJobWithAuth to tell the session manager to restart the
414 // browser using the contents of command_line, authorizing the call
415 // using credentials acquired via remote_auth_fd.
416 // Ownership of local_auth_fd is held for the duration of the dbus call.
417 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd,
418 dbus::ScopedFileDescriptor remote_auth_fd,
419 const std::string& command_line) {
420 dbus::MethodCall method_call(
421 login_manager::kSessionManagerInterface,
422 login_manager::kSessionManagerRestartJobWithAuth);
423 dbus::MessageWriter writer(&method_call);
424 writer.AppendFileDescriptor(*remote_auth_fd);
425 writer.AppendString(command_line);
427 // Ownership of local_auth_fd is passed to the callback that is to be
428 // called on completion of this method call. This keeps the browser end
429 // of the socket-pair alive for the duration of the RPC.
430 session_manager_proxy_->CallMethod(
431 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
432 base::Bind(&SessionManagerClientImpl::OnRestartJob,
433 weak_ptr_factory_.GetWeakPtr(),
434 base::Passed(&local_auth_fd)));
437 // Called when kSessionManagerRestartJob method is complete.
438 // Now that the call is complete, local_auth_fd can be closed and discarded,
439 // which will happen automatically when it goes out of scope.
440 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd,
441 dbus::Response* response) {
442 LOG_IF(ERROR, !response)
443 << "Failed to call "
444 << login_manager::kSessionManagerRestartJob;
447 // Called when kSessionManagerStartSession method is complete.
448 void OnStartSession(dbus::Response* response) {
449 LOG_IF(ERROR, !response)
450 << "Failed to call "
451 << login_manager::kSessionManagerStartSession;
454 // Called when kSessionManagerStopSession method is complete.
455 void OnStopSession(dbus::Response* response) {
456 LOG_IF(ERROR, !response)
457 << "Failed to call "
458 << login_manager::kSessionManagerStopSession;
461 // Called when kSessionManagerStopSession method is complete.
462 void OnDeviceWipe(dbus::Response* response) {
463 LOG_IF(ERROR, !response)
464 << "Failed to call "
465 << login_manager::kSessionManagerStartDeviceWipe;
468 // Called when kSessionManagerRetrieveActiveSessions method is complete.
469 void OnRetrieveActiveSessions(const std::string& method_name,
470 const ActiveSessionsCallback& callback,
471 dbus::Response* response) {
472 ActiveSessionsMap sessions;
473 bool success = false;
474 if (!response) {
475 LOG(ERROR) << "Failed to call " << method_name;
476 callback.Run(sessions, success);
477 return;
480 dbus::MessageReader reader(response);
481 dbus::MessageReader array_reader(NULL);
483 if (!reader.PopArray(&array_reader)) {
484 LOG(ERROR) << method_name << " response is incorrect: "
485 << response->ToString();
486 } else {
487 while (array_reader.HasMoreData()) {
488 dbus::MessageReader dict_entry_reader(NULL);
489 std::string key;
490 std::string value;
491 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
492 !dict_entry_reader.PopString(&key) ||
493 !dict_entry_reader.PopString(&value)) {
494 LOG(ERROR) << method_name << " response is incorrect: "
495 << response->ToString();
496 } else {
497 sessions[key] = value;
500 success = true;
502 callback.Run(sessions, success);
505 void ExtractString(const std::string& method_name,
506 dbus::Response* response,
507 std::string* extracted) {
508 if (!response) {
509 LOG(ERROR) << "Failed to call " << method_name;
510 return;
512 dbus::MessageReader reader(response);
513 const uint8* values = NULL;
514 size_t length = 0;
515 if (!reader.PopArrayOfBytes(&values, &length)) {
516 LOG(ERROR) << "Invalid response: " << response->ToString();
517 return;
519 // static_cast does not work due to signedness.
520 extracted->assign(reinterpret_cast<const char*>(values), length);
523 // Called when kSessionManagerRetrievePolicy or
524 // kSessionManagerRetrievePolicyForUser method is complete.
525 void OnRetrievePolicy(const std::string& method_name,
526 const RetrievePolicyCallback& callback,
527 dbus::Response* response) {
528 std::string serialized_proto;
529 ExtractString(method_name, response, &serialized_proto);
530 callback.Run(serialized_proto);
533 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
534 // method is complete.
535 void OnStorePolicy(const std::string& method_name,
536 const StorePolicyCallback& callback,
537 dbus::Response* response) {
538 bool success = false;
539 if (!response) {
540 LOG(ERROR) << "Failed to call " << method_name;
541 } else {
542 dbus::MessageReader reader(response);
543 if (!reader.PopBool(&success))
544 LOG(ERROR) << "Invalid response: " << response->ToString();
546 callback.Run(success);
549 // Called when the owner key set signal is received.
550 void OwnerKeySetReceived(dbus::Signal* signal) {
551 dbus::MessageReader reader(signal);
552 std::string result_string;
553 if (!reader.PopString(&result_string)) {
554 LOG(ERROR) << "Invalid signal: " << signal->ToString();
555 return;
557 const bool success = StartsWithASCII(result_string, "success", false);
558 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
561 // Called when the property change complete signal is received.
562 void PropertyChangeCompleteReceived(dbus::Signal* signal) {
563 dbus::MessageReader reader(signal);
564 std::string result_string;
565 if (!reader.PopString(&result_string)) {
566 LOG(ERROR) << "Invalid signal: " << signal->ToString();
567 return;
569 const bool success = StartsWithASCII(result_string, "success", false);
570 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
573 void ScreenIsLockedReceived(dbus::Signal* signal) {
574 screen_is_locked_ = true;
575 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
578 void ScreenIsUnlockedReceived(dbus::Signal* signal) {
579 screen_is_locked_ = false;
580 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
583 // Called when the object is connected to the signal.
584 void SignalConnected(const std::string& interface_name,
585 const std::string& signal_name,
586 bool success) {
587 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
590 // Called when kSessionManagerGetServerBackedStateKeys method is complete.
591 void OnGetServerBackedStateKeys(const StateKeysCallback& callback,
592 dbus::Response* response) {
593 std::vector<std::string> state_keys;
594 if (!response) {
595 LOG(ERROR) << "Failed to call "
596 << login_manager::kSessionManagerStartSession;
597 } else {
598 dbus::MessageReader reader(response);
599 dbus::MessageReader array_reader(NULL);
601 if (!reader.PopArray(&array_reader)) {
602 LOG(ERROR) << "Bad response: " << response->ToString();
603 } else {
604 while (array_reader.HasMoreData()) {
605 const uint8* data = NULL;
606 size_t size = 0;
607 if (!array_reader.PopArrayOfBytes(&data, &size)) {
608 LOG(ERROR) << "Bad response: " << response->ToString();
609 state_keys.clear();
610 break;
612 state_keys.push_back(
613 std::string(reinterpret_cast<const char*>(data), size));
618 if (!callback.is_null())
619 callback.Run(state_keys);
623 dbus::ObjectProxy* session_manager_proxy_;
624 scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
625 ObserverList<Observer> observers_;
627 // Most recent screen-lock state received from session_manager.
628 bool screen_is_locked_;
630 // Note: This should remain the last member so it'll be destroyed and
631 // invalidate its weak pointers before any other members are destroyed.
632 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
634 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
637 // The SessionManagerClient implementation used on Linux desktop,
638 // which does nothing.
639 class SessionManagerClientStubImpl : public SessionManagerClient {
640 public:
641 SessionManagerClientStubImpl() : delegate_(NULL), screen_is_locked_(false) {}
642 ~SessionManagerClientStubImpl() override {}
644 // SessionManagerClient overrides
645 void Init(dbus::Bus* bus) override {}
646 void SetStubDelegate(StubDelegate* delegate) override {
647 delegate_ = delegate;
649 void AddObserver(Observer* observer) override {
650 observers_.AddObserver(observer);
652 void RemoveObserver(Observer* observer) override {
653 observers_.RemoveObserver(observer);
655 bool HasObserver(const Observer* observer) const override {
656 return observers_.HasObserver(observer);
658 bool IsScreenLocked() const override { return screen_is_locked_; }
659 void EmitLoginPromptVisible() override {}
660 void RestartJob(int pid, const std::string& command_line) override {}
661 void StartSession(const std::string& user_email) override {}
662 void StopSession() override {}
663 void NotifySupervisedUserCreationStarted() override {}
664 void NotifySupervisedUserCreationFinished() override {}
665 void StartDeviceWipe() override {}
666 void RequestLockScreen() override {
667 if (delegate_)
668 delegate_->LockScreenForStub();
670 void NotifyLockScreenShown() override {
671 screen_is_locked_ = true;
672 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
674 void NotifyLockScreenDismissed() override {
675 screen_is_locked_ = false;
676 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
678 void RetrieveActiveSessions(const ActiveSessionsCallback& callback) override {
680 void RetrieveDevicePolicy(const RetrievePolicyCallback& callback) override {
681 base::FilePath owner_key_path;
682 if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
683 callback.Run("");
684 return;
686 base::FilePath device_policy_path =
687 owner_key_path.DirName().AppendASCII("stub_device_policy");
688 base::PostTaskAndReplyWithResult(
689 base::WorkerPool::GetTaskRunner(false).get(),
690 FROM_HERE,
691 base::Bind(&GetFileContent, device_policy_path),
692 callback);
694 void RetrievePolicyForUser(const std::string& username,
695 const RetrievePolicyCallback& callback) override {
696 base::PostTaskAndReplyWithResult(
697 base::WorkerPool::GetTaskRunner(false).get(),
698 FROM_HERE,
699 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")),
700 callback);
702 std::string BlockingRetrievePolicyForUser(
703 const std::string& username) override {
704 return GetFileContent(GetUserFilePath(username, "stub_policy"));
706 void RetrieveDeviceLocalAccountPolicy(
707 const std::string& account_name,
708 const RetrievePolicyCallback& callback) override {
709 RetrievePolicyForUser(account_name, callback);
711 void StoreDevicePolicy(const std::string& policy_blob,
712 const StorePolicyCallback& callback) override {
713 enterprise_management::PolicyFetchResponse response;
714 base::FilePath owner_key_path;
715 if (!response.ParseFromString(policy_blob) ||
716 !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
717 callback.Run(false);
718 return;
721 if (response.has_new_public_key()) {
722 base::WorkerPool::PostTask(
723 FROM_HERE,
724 base::Bind(&StoreFile, owner_key_path, response.new_public_key()),
725 false);
728 // Chrome will attempt to retrieve the device policy right after storing
729 // during enrollment, so make sure it's written before signaling
730 // completion.
731 // Note also that the owner key will be written before the device policy,
732 // if it was present in the blob.
733 base::FilePath device_policy_path =
734 owner_key_path.DirName().AppendASCII("stub_device_policy");
735 base::WorkerPool::PostTaskAndReply(
736 FROM_HERE,
737 base::Bind(&StoreFile, device_policy_path, policy_blob),
738 base::Bind(callback, true),
739 false);
741 void StorePolicyForUser(const std::string& username,
742 const std::string& policy_blob,
743 const StorePolicyCallback& callback) override {
744 // The session manager writes the user policy key to a well-known
745 // location. Do the same with the stub impl, so that user policy works and
746 // can be tested on desktop builds.
747 enterprise_management::PolicyFetchResponse response;
748 if (!response.ParseFromString(policy_blob)) {
749 callback.Run(false);
750 return;
753 if (response.has_new_public_key()) {
754 base::FilePath key_path = GetUserFilePath(username, "policy.pub");
755 base::WorkerPool::PostTask(
756 FROM_HERE,
757 base::Bind(&StoreFile, key_path, response.new_public_key()),
758 false);
761 // This file isn't read directly by Chrome, but is used by this class to
762 // reload the user policy across restarts.
763 base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy");
764 base::WorkerPool::PostTaskAndReply(
765 FROM_HERE,
766 base::Bind(&StoreFile, stub_policy_path, policy_blob),
767 base::Bind(callback, true),
768 false);
770 void StoreDeviceLocalAccountPolicy(
771 const std::string& account_name,
772 const std::string& policy_blob,
773 const StorePolicyCallback& callback) override {
774 StorePolicyForUser(account_name, policy_blob, callback);
776 void SetFlagsForUser(const std::string& username,
777 const std::vector<std::string>& flags) override {}
779 void GetServerBackedStateKeys(const StateKeysCallback& callback) override {
780 std::vector<std::string> state_keys;
781 for (int i = 0; i < 5; ++i)
782 state_keys.push_back(crypto::SHA256HashString(base::IntToString(i)));
784 if (!callback.is_null())
785 callback.Run(state_keys);
788 private:
789 StubDelegate* delegate_; // Weak pointer; may be NULL.
790 ObserverList<Observer> observers_;
791 std::string device_policy_;
792 bool screen_is_locked_;
794 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
797 SessionManagerClient::SessionManagerClient() {
800 SessionManagerClient::~SessionManagerClient() {
803 SessionManagerClient* SessionManagerClient::Create(
804 DBusClientImplementationType type) {
805 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
806 return new SessionManagerClientImpl();
807 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
808 return new SessionManagerClientStubImpl();
811 } // namespace chromeos