Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / dbus / session_manager_client.cc
blob36a4e28cba52544361fd8bcb4aaa92fcf7a31d8d
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(const std::vector<std::string>& argv) override {
119 dbus::ScopedFileDescriptor local_auth_fd(new dbus::FileDescriptor);
120 dbus::ScopedFileDescriptor remote_auth_fd(new dbus::FileDescriptor);
122 // session_manager's RestartJob call requires the caller to open a socket
123 // pair and pass one end over dbus while holding the local end open for the
124 // duration of the call. session_manager uses this to determine whether the
125 // PID the restart request originates from belongs to the browser itself.
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 // -- BUT --
134 // you have to grab pointers to the contents of {local,remote}_auth_fd
135 // _before_ they're acted on by base::Passed() below. Passing ownership
136 // of the ScopedFileDescriptor objects to the callback actually nulls
137 // out the storage inside the local instances. Since there are
138 // no guarantees about the order of evaluation of arguments in a
139 // function call, merely having them appear earlier among the args
140 // to PostTaskAndReply() is not enough. Relying on this crashed on
141 // some platforms.
142 base::Closure create_credentials_conduit_closure = base::Bind(
143 &CreateValidCredConduit, local_auth_fd.get(), remote_auth_fd.get());
145 base::WorkerPool::PostTaskAndReply(
146 FROM_HERE, create_credentials_conduit_closure,
147 base::Bind(&SessionManagerClientImpl::CallRestartJobWithValidFd,
148 weak_ptr_factory_.GetWeakPtr(), base::Passed(&local_auth_fd),
149 base::Passed(&remote_auth_fd), argv),
150 false);
153 void StartSession(const std::string& user_email) override {
154 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
155 login_manager::kSessionManagerStartSession);
156 dbus::MessageWriter writer(&method_call);
157 writer.AppendString(user_email);
158 writer.AppendString(""); // Unique ID is deprecated
159 session_manager_proxy_->CallMethod(
160 &method_call,
161 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
162 base::Bind(&SessionManagerClientImpl::OnStartSession,
163 weak_ptr_factory_.GetWeakPtr()));
166 void StopSession() override {
167 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
168 login_manager::kSessionManagerStopSession);
169 dbus::MessageWriter writer(&method_call);
170 writer.AppendString(""); // Unique ID is deprecated
171 session_manager_proxy_->CallMethod(
172 &method_call,
173 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
174 base::Bind(&SessionManagerClientImpl::OnStopSession,
175 weak_ptr_factory_.GetWeakPtr()));
178 void StartDeviceWipe() override {
179 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
180 login_manager::kSessionManagerStartDeviceWipe);
181 session_manager_proxy_->CallMethod(
182 &method_call,
183 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
184 base::Bind(&SessionManagerClientImpl::OnDeviceWipe,
185 weak_ptr_factory_.GetWeakPtr()));
188 void RequestLockScreen() override {
189 SimpleMethodCallToSessionManager(login_manager::kSessionManagerLockScreen);
192 void NotifyLockScreenShown() override {
193 SimpleMethodCallToSessionManager(
194 login_manager::kSessionManagerHandleLockScreenShown);
197 void NotifyLockScreenDismissed() override {
198 SimpleMethodCallToSessionManager(
199 login_manager::kSessionManagerHandleLockScreenDismissed);
202 void NotifySupervisedUserCreationStarted() override {
203 SimpleMethodCallToSessionManager(
204 login_manager::kSessionManagerHandleSupervisedUserCreationStarting);
207 void NotifySupervisedUserCreationFinished() override {
208 SimpleMethodCallToSessionManager(
209 login_manager::kSessionManagerHandleSupervisedUserCreationFinished);
212 void RetrieveActiveSessions(const ActiveSessionsCallback& callback) override {
213 dbus::MethodCall method_call(
214 login_manager::kSessionManagerInterface,
215 login_manager::kSessionManagerRetrieveActiveSessions);
217 session_manager_proxy_->CallMethod(
218 &method_call,
219 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
220 base::Bind(&SessionManagerClientImpl::OnRetrieveActiveSessions,
221 weak_ptr_factory_.GetWeakPtr(),
222 login_manager::kSessionManagerRetrieveActiveSessions,
223 callback));
226 void RetrieveDevicePolicy(const RetrievePolicyCallback& callback) override {
227 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
228 login_manager::kSessionManagerRetrievePolicy);
229 session_manager_proxy_->CallMethod(
230 &method_call,
231 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
232 base::Bind(&SessionManagerClientImpl::OnRetrievePolicy,
233 weak_ptr_factory_.GetWeakPtr(),
234 login_manager::kSessionManagerRetrievePolicy,
235 callback));
238 void RetrievePolicyForUser(const std::string& username,
239 const RetrievePolicyCallback& callback) override {
240 CallRetrievePolicyByUsername(
241 login_manager::kSessionManagerRetrievePolicyForUser,
242 username,
243 callback);
246 std::string BlockingRetrievePolicyForUser(
247 const std::string& username) override {
248 dbus::MethodCall method_call(
249 login_manager::kSessionManagerInterface,
250 login_manager::kSessionManagerRetrievePolicyForUser);
251 dbus::MessageWriter writer(&method_call);
252 writer.AppendString(username);
253 scoped_ptr<dbus::Response> response =
254 blocking_method_caller_->CallMethodAndBlock(&method_call);
255 std::string policy;
256 ExtractString(login_manager::kSessionManagerRetrievePolicyForUser,
257 response.get(),
258 &policy);
259 return policy;
262 void RetrieveDeviceLocalAccountPolicy(
263 const std::string& account_name,
264 const RetrievePolicyCallback& callback) override {
265 CallRetrievePolicyByUsername(
266 login_manager::kSessionManagerRetrieveDeviceLocalAccountPolicy,
267 account_name,
268 callback);
271 void StoreDevicePolicy(const std::string& policy_blob,
272 const StorePolicyCallback& callback) override {
273 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
274 login_manager::kSessionManagerStorePolicy);
275 dbus::MessageWriter writer(&method_call);
276 // static_cast does not work due to signedness.
277 writer.AppendArrayOfBytes(
278 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
279 session_manager_proxy_->CallMethod(
280 &method_call,
281 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
282 base::Bind(&SessionManagerClientImpl::OnStorePolicy,
283 weak_ptr_factory_.GetWeakPtr(),
284 login_manager::kSessionManagerStorePolicy,
285 callback));
288 void StorePolicyForUser(const std::string& username,
289 const std::string& policy_blob,
290 const StorePolicyCallback& callback) override {
291 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
292 username,
293 policy_blob,
294 callback);
297 void StoreDeviceLocalAccountPolicy(
298 const std::string& account_name,
299 const std::string& policy_blob,
300 const StorePolicyCallback& callback) override {
301 CallStorePolicyByUsername(
302 login_manager::kSessionManagerStoreDeviceLocalAccountPolicy,
303 account_name,
304 policy_blob,
305 callback);
308 void SetFlagsForUser(const std::string& username,
309 const std::vector<std::string>& flags) override {
310 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
311 login_manager::kSessionManagerSetFlagsForUser);
312 dbus::MessageWriter writer(&method_call);
313 writer.AppendString(username);
314 writer.AppendArrayOfStrings(flags);
315 session_manager_proxy_->CallMethod(
316 &method_call,
317 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
318 dbus::ObjectProxy::EmptyResponseCallback());
321 void GetServerBackedStateKeys(const StateKeysCallback& callback) override {
322 dbus::MethodCall method_call(
323 login_manager::kSessionManagerInterface,
324 login_manager::kSessionManagerGetServerBackedStateKeys);
326 session_manager_proxy_->CallMethod(
327 &method_call,
328 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
329 base::Bind(&SessionManagerClientImpl::OnGetServerBackedStateKeys,
330 weak_ptr_factory_.GetWeakPtr(),
331 callback));
334 protected:
335 void Init(dbus::Bus* bus) override {
336 session_manager_proxy_ = bus->GetObjectProxy(
337 login_manager::kSessionManagerServiceName,
338 dbus::ObjectPath(login_manager::kSessionManagerServicePath));
339 blocking_method_caller_.reset(
340 new BlockingMethodCaller(bus, session_manager_proxy_));
342 // Signals emitted on the session manager's interface.
343 session_manager_proxy_->ConnectToSignal(
344 login_manager::kSessionManagerInterface,
345 login_manager::kOwnerKeySetSignal,
346 base::Bind(&SessionManagerClientImpl::OwnerKeySetReceived,
347 weak_ptr_factory_.GetWeakPtr()),
348 base::Bind(&SessionManagerClientImpl::SignalConnected,
349 weak_ptr_factory_.GetWeakPtr()));
350 session_manager_proxy_->ConnectToSignal(
351 login_manager::kSessionManagerInterface,
352 login_manager::kPropertyChangeCompleteSignal,
353 base::Bind(&SessionManagerClientImpl::PropertyChangeCompleteReceived,
354 weak_ptr_factory_.GetWeakPtr()),
355 base::Bind(&SessionManagerClientImpl::SignalConnected,
356 weak_ptr_factory_.GetWeakPtr()));
357 session_manager_proxy_->ConnectToSignal(
358 login_manager::kSessionManagerInterface,
359 login_manager::kScreenIsLockedSignal,
360 base::Bind(&SessionManagerClientImpl::ScreenIsLockedReceived,
361 weak_ptr_factory_.GetWeakPtr()),
362 base::Bind(&SessionManagerClientImpl::SignalConnected,
363 weak_ptr_factory_.GetWeakPtr()));
364 session_manager_proxy_->ConnectToSignal(
365 login_manager::kSessionManagerInterface,
366 login_manager::kScreenIsUnlockedSignal,
367 base::Bind(&SessionManagerClientImpl::ScreenIsUnlockedReceived,
368 weak_ptr_factory_.GetWeakPtr()),
369 base::Bind(&SessionManagerClientImpl::SignalConnected,
370 weak_ptr_factory_.GetWeakPtr()));
373 private:
374 // Makes a method call to the session manager with no arguments and no
375 // response.
376 void SimpleMethodCallToSessionManager(const std::string& method_name) {
377 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
378 method_name);
379 session_manager_proxy_->CallMethod(
380 &method_call,
381 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
382 dbus::ObjectProxy::EmptyResponseCallback());
385 // Helper for RetrieveDeviceLocalAccountPolicy and RetrievePolicyForUser.
386 void CallRetrievePolicyByUsername(const std::string& method_name,
387 const std::string& username,
388 const RetrievePolicyCallback& callback) {
389 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
390 method_name);
391 dbus::MessageWriter writer(&method_call);
392 writer.AppendString(username);
393 session_manager_proxy_->CallMethod(
394 &method_call,
395 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
396 base::Bind(
397 &SessionManagerClientImpl::OnRetrievePolicy,
398 weak_ptr_factory_.GetWeakPtr(),
399 method_name,
400 callback));
403 void CallStorePolicyByUsername(const std::string& method_name,
404 const std::string& username,
405 const std::string& policy_blob,
406 const StorePolicyCallback& callback) {
407 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
408 method_name);
409 dbus::MessageWriter writer(&method_call);
410 writer.AppendString(username);
411 // static_cast does not work due to signedness.
412 writer.AppendArrayOfBytes(
413 reinterpret_cast<const uint8*>(policy_blob.data()), policy_blob.size());
414 session_manager_proxy_->CallMethod(
415 &method_call,
416 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
417 base::Bind(
418 &SessionManagerClientImpl::OnStorePolicy,
419 weak_ptr_factory_.GetWeakPtr(),
420 method_name,
421 callback));
424 // Calls RestartJob to tell the session manager to restart the browser using
425 // the contents of |argv| as the command line, authorizing the call using
426 // credentials acquired via |remote_auth_fd|. Ownership of |local_auth_fd| is
427 // held for the duration of the dbus call.
428 void CallRestartJobWithValidFd(dbus::ScopedFileDescriptor local_auth_fd,
429 dbus::ScopedFileDescriptor remote_auth_fd,
430 const std::vector<std::string>& argv) {
431 dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
432 login_manager::kSessionManagerRestartJob);
433 dbus::MessageWriter writer(&method_call);
434 writer.AppendFileDescriptor(*remote_auth_fd);
435 writer.AppendArrayOfStrings(argv);
437 // Ownership of local_auth_fd is passed to the callback that is to be
438 // called on completion of this method call. This keeps the browser end
439 // of the socket-pair alive for the duration of the RPC.
440 session_manager_proxy_->CallMethod(
441 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
442 base::Bind(&SessionManagerClientImpl::OnRestartJob,
443 weak_ptr_factory_.GetWeakPtr(),
444 base::Passed(&local_auth_fd)));
447 // Called when kSessionManagerRestartJob method is complete.
448 // Now that the call is complete, local_auth_fd can be closed and discarded,
449 // which will happen automatically when it goes out of scope.
450 void OnRestartJob(dbus::ScopedFileDescriptor local_auth_fd,
451 dbus::Response* response) {
452 LOG_IF(ERROR, !response)
453 << "Failed to call "
454 << login_manager::kSessionManagerRestartJob;
457 // Called when kSessionManagerStartSession method is complete.
458 void OnStartSession(dbus::Response* response) {
459 LOG_IF(ERROR, !response)
460 << "Failed to call "
461 << login_manager::kSessionManagerStartSession;
464 // Called when kSessionManagerStopSession method is complete.
465 void OnStopSession(dbus::Response* response) {
466 LOG_IF(ERROR, !response)
467 << "Failed to call "
468 << login_manager::kSessionManagerStopSession;
471 // Called when kSessionManagerStopSession method is complete.
472 void OnDeviceWipe(dbus::Response* response) {
473 LOG_IF(ERROR, !response)
474 << "Failed to call "
475 << login_manager::kSessionManagerStartDeviceWipe;
478 // Called when kSessionManagerRetrieveActiveSessions method is complete.
479 void OnRetrieveActiveSessions(const std::string& method_name,
480 const ActiveSessionsCallback& callback,
481 dbus::Response* response) {
482 ActiveSessionsMap sessions;
483 bool success = false;
484 if (!response) {
485 LOG(ERROR) << "Failed to call " << method_name;
486 callback.Run(sessions, success);
487 return;
490 dbus::MessageReader reader(response);
491 dbus::MessageReader array_reader(NULL);
493 if (!reader.PopArray(&array_reader)) {
494 LOG(ERROR) << method_name << " response is incorrect: "
495 << response->ToString();
496 } else {
497 while (array_reader.HasMoreData()) {
498 dbus::MessageReader dict_entry_reader(NULL);
499 std::string key;
500 std::string value;
501 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
502 !dict_entry_reader.PopString(&key) ||
503 !dict_entry_reader.PopString(&value)) {
504 LOG(ERROR) << method_name << " response is incorrect: "
505 << response->ToString();
506 } else {
507 sessions[key] = value;
510 success = true;
512 callback.Run(sessions, success);
515 void ExtractString(const std::string& method_name,
516 dbus::Response* response,
517 std::string* extracted) {
518 if (!response) {
519 LOG(ERROR) << "Failed to call " << method_name;
520 return;
522 dbus::MessageReader reader(response);
523 const uint8* values = NULL;
524 size_t length = 0;
525 if (!reader.PopArrayOfBytes(&values, &length)) {
526 LOG(ERROR) << "Invalid response: " << response->ToString();
527 return;
529 // static_cast does not work due to signedness.
530 extracted->assign(reinterpret_cast<const char*>(values), length);
533 // Called when kSessionManagerRetrievePolicy or
534 // kSessionManagerRetrievePolicyForUser method is complete.
535 void OnRetrievePolicy(const std::string& method_name,
536 const RetrievePolicyCallback& callback,
537 dbus::Response* response) {
538 std::string serialized_proto;
539 ExtractString(method_name, response, &serialized_proto);
540 callback.Run(serialized_proto);
543 // Called when kSessionManagerStorePolicy or kSessionManagerStorePolicyForUser
544 // method is complete.
545 void OnStorePolicy(const std::string& method_name,
546 const StorePolicyCallback& callback,
547 dbus::Response* response) {
548 bool success = false;
549 if (!response) {
550 LOG(ERROR) << "Failed to call " << method_name;
551 } else {
552 dbus::MessageReader reader(response);
553 if (!reader.PopBool(&success))
554 LOG(ERROR) << "Invalid response: " << response->ToString();
556 callback.Run(success);
559 // Called when the owner key set signal is received.
560 void OwnerKeySetReceived(dbus::Signal* signal) {
561 dbus::MessageReader reader(signal);
562 std::string result_string;
563 if (!reader.PopString(&result_string)) {
564 LOG(ERROR) << "Invalid signal: " << signal->ToString();
565 return;
567 const bool success = base::StartsWith(result_string, "success",
568 base::CompareCase::INSENSITIVE_ASCII);
569 FOR_EACH_OBSERVER(Observer, observers_, OwnerKeySet(success));
572 // Called when the property change complete signal is received.
573 void PropertyChangeCompleteReceived(dbus::Signal* signal) {
574 dbus::MessageReader reader(signal);
575 std::string result_string;
576 if (!reader.PopString(&result_string)) {
577 LOG(ERROR) << "Invalid signal: " << signal->ToString();
578 return;
580 const bool success = base::StartsWith(result_string, "success",
581 base::CompareCase::INSENSITIVE_ASCII);
582 FOR_EACH_OBSERVER(Observer, observers_, PropertyChangeComplete(success));
585 void ScreenIsLockedReceived(dbus::Signal* signal) {
586 screen_is_locked_ = true;
587 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
590 void ScreenIsUnlockedReceived(dbus::Signal* signal) {
591 screen_is_locked_ = false;
592 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
595 // Called when the object is connected to the signal.
596 void SignalConnected(const std::string& interface_name,
597 const std::string& signal_name,
598 bool success) {
599 LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
602 // Called when kSessionManagerGetServerBackedStateKeys method is complete.
603 void OnGetServerBackedStateKeys(const StateKeysCallback& callback,
604 dbus::Response* response) {
605 std::vector<std::string> state_keys;
606 if (!response) {
607 LOG(ERROR) << "Failed to call "
608 << login_manager::kSessionManagerGetServerBackedStateKeys;
609 } else {
610 dbus::MessageReader reader(response);
611 dbus::MessageReader array_reader(NULL);
613 if (!reader.PopArray(&array_reader)) {
614 LOG(ERROR) << "Bad response: " << response->ToString();
615 } else {
616 while (array_reader.HasMoreData()) {
617 const uint8* data = NULL;
618 size_t size = 0;
619 if (!array_reader.PopArrayOfBytes(&data, &size)) {
620 LOG(ERROR) << "Bad response: " << response->ToString();
621 state_keys.clear();
622 break;
624 state_keys.push_back(
625 std::string(reinterpret_cast<const char*>(data), size));
630 if (!callback.is_null())
631 callback.Run(state_keys);
635 dbus::ObjectProxy* session_manager_proxy_;
636 scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
637 base::ObserverList<Observer> observers_;
639 // Most recent screen-lock state received from session_manager.
640 bool screen_is_locked_;
642 // Note: This should remain the last member so it'll be destroyed and
643 // invalidate its weak pointers before any other members are destroyed.
644 base::WeakPtrFactory<SessionManagerClientImpl> weak_ptr_factory_;
646 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientImpl);
649 // The SessionManagerClient implementation used on Linux desktop,
650 // which does nothing.
651 class SessionManagerClientStubImpl : public SessionManagerClient {
652 public:
653 SessionManagerClientStubImpl() : delegate_(NULL), screen_is_locked_(false) {}
654 ~SessionManagerClientStubImpl() override {}
656 // SessionManagerClient overrides
657 void Init(dbus::Bus* bus) override {}
658 void SetStubDelegate(StubDelegate* delegate) override {
659 delegate_ = delegate;
661 void AddObserver(Observer* observer) override {
662 observers_.AddObserver(observer);
664 void RemoveObserver(Observer* observer) override {
665 observers_.RemoveObserver(observer);
667 bool HasObserver(const Observer* observer) const override {
668 return observers_.HasObserver(observer);
670 bool IsScreenLocked() const override { return screen_is_locked_; }
671 void EmitLoginPromptVisible() override {}
672 void RestartJob(const std::vector<std::string>& argv) override {}
673 void StartSession(const std::string& user_email) override {}
674 void StopSession() override {}
675 void NotifySupervisedUserCreationStarted() override {}
676 void NotifySupervisedUserCreationFinished() override {}
677 void StartDeviceWipe() override {}
678 void RequestLockScreen() override {
679 if (delegate_)
680 delegate_->LockScreenForStub();
682 void NotifyLockScreenShown() override {
683 screen_is_locked_ = true;
684 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked());
686 void NotifyLockScreenDismissed() override {
687 screen_is_locked_ = false;
688 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked());
690 void RetrieveActiveSessions(const ActiveSessionsCallback& callback) override {
692 void RetrieveDevicePolicy(const RetrievePolicyCallback& callback) override {
693 base::FilePath owner_key_path;
694 if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
695 callback.Run("");
696 return;
698 base::FilePath device_policy_path =
699 owner_key_path.DirName().AppendASCII("stub_device_policy");
700 base::PostTaskAndReplyWithResult(
701 base::WorkerPool::GetTaskRunner(false).get(),
702 FROM_HERE,
703 base::Bind(&GetFileContent, device_policy_path),
704 callback);
706 void RetrievePolicyForUser(const std::string& username,
707 const RetrievePolicyCallback& callback) override {
708 base::PostTaskAndReplyWithResult(
709 base::WorkerPool::GetTaskRunner(false).get(),
710 FROM_HERE,
711 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")),
712 callback);
714 std::string BlockingRetrievePolicyForUser(
715 const std::string& username) override {
716 return GetFileContent(GetUserFilePath(username, "stub_policy"));
718 void RetrieveDeviceLocalAccountPolicy(
719 const std::string& account_name,
720 const RetrievePolicyCallback& callback) override {
721 RetrievePolicyForUser(account_name, callback);
723 void StoreDevicePolicy(const std::string& policy_blob,
724 const StorePolicyCallback& callback) override {
725 enterprise_management::PolicyFetchResponse response;
726 base::FilePath owner_key_path;
727 if (!response.ParseFromString(policy_blob) ||
728 !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
729 callback.Run(false);
730 return;
733 if (response.has_new_public_key()) {
734 base::WorkerPool::PostTask(
735 FROM_HERE,
736 base::Bind(&StoreFile, owner_key_path, response.new_public_key()),
737 false);
740 // Chrome will attempt to retrieve the device policy right after storing
741 // during enrollment, so make sure it's written before signaling
742 // completion.
743 // Note also that the owner key will be written before the device policy,
744 // if it was present in the blob.
745 base::FilePath device_policy_path =
746 owner_key_path.DirName().AppendASCII("stub_device_policy");
747 base::WorkerPool::PostTaskAndReply(
748 FROM_HERE,
749 base::Bind(&StoreFile, device_policy_path, policy_blob),
750 base::Bind(callback, true),
751 false);
753 void StorePolicyForUser(const std::string& username,
754 const std::string& policy_blob,
755 const StorePolicyCallback& callback) override {
756 // The session manager writes the user policy key to a well-known
757 // location. Do the same with the stub impl, so that user policy works and
758 // can be tested on desktop builds.
759 enterprise_management::PolicyFetchResponse response;
760 if (!response.ParseFromString(policy_blob)) {
761 callback.Run(false);
762 return;
765 if (response.has_new_public_key()) {
766 base::FilePath key_path = GetUserFilePath(username, "policy.pub");
767 base::WorkerPool::PostTask(
768 FROM_HERE,
769 base::Bind(&StoreFile, key_path, response.new_public_key()),
770 false);
773 // This file isn't read directly by Chrome, but is used by this class to
774 // reload the user policy across restarts.
775 base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy");
776 base::WorkerPool::PostTaskAndReply(
777 FROM_HERE,
778 base::Bind(&StoreFile, stub_policy_path, policy_blob),
779 base::Bind(callback, true),
780 false);
782 void StoreDeviceLocalAccountPolicy(
783 const std::string& account_name,
784 const std::string& policy_blob,
785 const StorePolicyCallback& callback) override {
786 StorePolicyForUser(account_name, policy_blob, callback);
788 void SetFlagsForUser(const std::string& username,
789 const std::vector<std::string>& flags) override {}
791 void GetServerBackedStateKeys(const StateKeysCallback& callback) override {
792 std::vector<std::string> state_keys;
793 for (int i = 0; i < 5; ++i)
794 state_keys.push_back(crypto::SHA256HashString(base::IntToString(i)));
796 if (!callback.is_null())
797 callback.Run(state_keys);
800 private:
801 StubDelegate* delegate_; // Weak pointer; may be NULL.
802 base::ObserverList<Observer> observers_;
803 std::string device_policy_;
804 bool screen_is_locked_;
806 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
809 SessionManagerClient::SessionManagerClient() {
812 SessionManagerClient::~SessionManagerClient() {
815 SessionManagerClient* SessionManagerClient::Create(
816 DBusClientImplementationType type) {
817 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
818 return new SessionManagerClientImpl();
819 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
820 return new SessionManagerClientStubImpl();
823 } // namespace chromeos