| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/dbus/session_manager_client.h" | 5 #include "chromeos/dbus/session_manager_client.h" |
| 6 | 6 |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/callback.h" | 8 #include "base/callback.h" |
| 11 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 12 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 13 #include "base/location.h" | 11 #include "base/location.h" |
| 14 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 15 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/task_runner_util.h" |
| 16 #include "base/threading/worker_pool.h" | 15 #include "base/threading/worker_pool.h" |
| 17 #include "chromeos/chromeos_paths.h" | 16 #include "chromeos/chromeos_paths.h" |
| 18 #include "chromeos/dbus/blocking_method_caller.h" | 17 #include "chromeos/dbus/blocking_method_caller.h" |
| 19 #include "chromeos/dbus/cryptohome_client.h" | 18 #include "chromeos/dbus/cryptohome_client.h" |
| 20 #include "dbus/bus.h" | 19 #include "dbus/bus.h" |
| 21 #include "dbus/message.h" | 20 #include "dbus/message.h" |
| 22 #include "dbus/object_path.h" | 21 #include "dbus/object_path.h" |
| 23 #include "dbus/object_proxy.h" | 22 #include "dbus/object_proxy.h" |
| 23 #include "policy/proto/device_management_backend.pb.h" |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | 24 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 25 | 25 |
| 26 namespace chromeos { | 26 namespace chromeos { |
| 27 | 27 |
| 28 namespace { |
| 29 |
| 30 // Returns a location for |file| that is specific to the given |username|. |
| 31 // These paths will be relative to DIR_USER_POLICY_KEYS, and can be used only |
| 32 // to store stub files. |
| 33 base::FilePath GetUserFilePath(const std::string& username, const char* file) { |
| 34 base::FilePath keys_path; |
| 35 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &keys_path)) |
| 36 return base::FilePath(); |
| 37 const std::string sanitized = |
| 38 CryptohomeClient::GetStubSanitizedUsername(username); |
| 39 return keys_path.AppendASCII(sanitized).AppendASCII(file); |
| 40 } |
| 41 |
| 42 // Helper to asynchronously retrieve a file's content. |
| 43 std::string GetFileContent(const base::FilePath& path) { |
| 44 std::string result; |
| 45 if (!path.empty()) |
| 46 base::ReadFileToString(path, &result); |
| 47 return result; |
| 48 } |
| 49 |
| 50 // Helper to write a file in a background thread. |
| 51 void StoreFile(const base::FilePath& path, const std::string& data) { |
| 52 const int size = static_cast<int>(data.size()); |
| 53 if (path.empty() || |
| 54 !base::CreateDirectory(path.DirName()) || |
| 55 base::WriteFile(path, data.data(), size) != size) { |
| 56 LOG(WARNING) << "Failed to write to " << path.value(); |
| 57 } |
| 58 } |
| 59 |
| 60 } // namespace |
| 61 |
| 28 // The SessionManagerClient implementation used in production. | 62 // The SessionManagerClient implementation used in production. |
| 29 class SessionManagerClientImpl : public SessionManagerClient { | 63 class SessionManagerClientImpl : public SessionManagerClient { |
| 30 public: | 64 public: |
| 31 SessionManagerClientImpl() | 65 SessionManagerClientImpl() |
| 32 : session_manager_proxy_(NULL), | 66 : session_manager_proxy_(NULL), |
| 33 weak_ptr_factory_(this) {} | 67 weak_ptr_factory_(this) {} |
| 34 | 68 |
| 35 virtual ~SessionManagerClientImpl() { | 69 virtual ~SessionManagerClientImpl() { |
| 36 } | 70 } |
| 37 | 71 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 231 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 198 base::Bind(&SessionManagerClientImpl::OnStorePolicy, | 232 base::Bind(&SessionManagerClientImpl::OnStorePolicy, |
| 199 weak_ptr_factory_.GetWeakPtr(), | 233 weak_ptr_factory_.GetWeakPtr(), |
| 200 login_manager::kSessionManagerStorePolicy, | 234 login_manager::kSessionManagerStorePolicy, |
| 201 callback)); | 235 callback)); |
| 202 } | 236 } |
| 203 | 237 |
| 204 virtual void StorePolicyForUser( | 238 virtual void StorePolicyForUser( |
| 205 const std::string& username, | 239 const std::string& username, |
| 206 const std::string& policy_blob, | 240 const std::string& policy_blob, |
| 207 const std::string& ignored_policy_key, | |
| 208 const StorePolicyCallback& callback) OVERRIDE { | 241 const StorePolicyCallback& callback) OVERRIDE { |
| 209 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, | 242 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, |
| 210 username, | 243 username, |
| 211 policy_blob, | 244 policy_blob, |
| 212 callback); | 245 callback); |
| 213 } | 246 } |
| 214 | 247 |
| 215 virtual void StoreDeviceLocalAccountPolicy( | 248 virtual void StoreDeviceLocalAccountPolicy( |
| 216 const std::string& account_name, | 249 const std::string& account_name, |
| 217 const std::string& policy_blob, | 250 const std::string& policy_blob, |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 virtual void NotifyLockScreenShown() OVERRIDE { | 574 virtual void NotifyLockScreenShown() OVERRIDE { |
| 542 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); | 575 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); |
| 543 } | 576 } |
| 544 virtual void NotifyLockScreenDismissed() OVERRIDE { | 577 virtual void NotifyLockScreenDismissed() OVERRIDE { |
| 545 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); | 578 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); |
| 546 } | 579 } |
| 547 virtual void RetrieveActiveSessions( | 580 virtual void RetrieveActiveSessions( |
| 548 const ActiveSessionsCallback& callback) OVERRIDE {} | 581 const ActiveSessionsCallback& callback) OVERRIDE {} |
| 549 virtual void RetrieveDevicePolicy( | 582 virtual void RetrieveDevicePolicy( |
| 550 const RetrievePolicyCallback& callback) OVERRIDE { | 583 const RetrievePolicyCallback& callback) OVERRIDE { |
| 551 callback.Run(device_policy_); | 584 base::FilePath owner_key_path; |
| 585 if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) { |
| 586 callback.Run(""); |
| 587 return; |
| 588 } |
| 589 base::FilePath device_policy_path = |
| 590 owner_key_path.DirName().AppendASCII("stub_device_policy"); |
| 591 base::PostTaskAndReplyWithResult( |
| 592 base::WorkerPool::GetTaskRunner(false), |
| 593 FROM_HERE, |
| 594 base::Bind(&GetFileContent, device_policy_path), |
| 595 callback); |
| 552 } | 596 } |
| 553 virtual void RetrievePolicyForUser( | 597 virtual void RetrievePolicyForUser( |
| 554 const std::string& username, | 598 const std::string& username, |
| 555 const RetrievePolicyCallback& callback) OVERRIDE { | 599 const RetrievePolicyCallback& callback) OVERRIDE { |
| 556 callback.Run(user_policies_[username]); | 600 base::PostTaskAndReplyWithResult( |
| 601 base::WorkerPool::GetTaskRunner(false), |
| 602 FROM_HERE, |
| 603 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")), |
| 604 callback); |
| 557 } | 605 } |
| 558 virtual std::string BlockingRetrievePolicyForUser( | 606 virtual std::string BlockingRetrievePolicyForUser( |
| 559 const std::string& username) OVERRIDE { | 607 const std::string& username) OVERRIDE { |
| 560 return user_policies_[username]; | 608 return GetFileContent(GetUserFilePath(username, "stub_policy")); |
| 561 } | 609 } |
| 562 virtual void RetrieveDeviceLocalAccountPolicy( | 610 virtual void RetrieveDeviceLocalAccountPolicy( |
| 563 const std::string& account_name, | 611 const std::string& account_name, |
| 564 const RetrievePolicyCallback& callback) OVERRIDE { | 612 const RetrievePolicyCallback& callback) OVERRIDE { |
| 565 callback.Run(user_policies_[account_name]); | 613 RetrievePolicyForUser(account_name, callback); |
| 566 } | 614 } |
| 567 virtual void StoreDevicePolicy(const std::string& policy_blob, | 615 virtual void StoreDevicePolicy(const std::string& policy_blob, |
| 568 const StorePolicyCallback& callback) OVERRIDE { | 616 const StorePolicyCallback& callback) OVERRIDE { |
| 569 device_policy_ = policy_blob; | 617 enterprise_management::PolicyFetchResponse response; |
| 570 callback.Run(true); | 618 base::FilePath owner_key_path; |
| 619 if (!response.ParseFromString(policy_blob) || |
| 620 !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) { |
| 621 callback.Run(false); |
| 622 return; |
| 623 } |
| 624 |
| 625 if (response.has_new_public_key()) { |
| 626 base::WorkerPool::PostTask( |
| 627 FROM_HERE, |
| 628 base::Bind(&StoreFile, owner_key_path, response.new_public_key()), |
| 629 false); |
| 630 } |
| 631 |
| 632 // Chrome will attempt to retrieve the device policy right after storing |
| 633 // during enrollment, so make sure it's written before signaling |
| 634 // completion. |
| 635 // Note also that the owner key will be written before the device policy, |
| 636 // if it was present in the blob. |
| 637 base::FilePath device_policy_path = |
| 638 owner_key_path.DirName().AppendASCII("stub_device_policy"); |
| 639 base::WorkerPool::PostTaskAndReply( |
| 640 FROM_HERE, |
| 641 base::Bind(&StoreFile, device_policy_path, policy_blob), |
| 642 base::Bind(callback, true), |
| 643 false); |
| 571 } | 644 } |
| 572 virtual void StorePolicyForUser( | 645 virtual void StorePolicyForUser( |
| 573 const std::string& username, | 646 const std::string& username, |
| 574 const std::string& policy_blob, | 647 const std::string& policy_blob, |
| 575 const std::string& policy_key, | |
| 576 const StorePolicyCallback& callback) OVERRIDE { | 648 const StorePolicyCallback& callback) OVERRIDE { |
| 577 if (policy_key.empty()) { | |
| 578 user_policies_[username] = policy_blob; | |
| 579 callback.Run(true); | |
| 580 return; | |
| 581 } | |
| 582 // The session manager writes the user policy key to a well-known | 649 // The session manager writes the user policy key to a well-known |
| 583 // location. Do the same with the stub impl, so that user policy works and | 650 // location. Do the same with the stub impl, so that user policy works and |
| 584 // can be tested on desktop builds. | 651 // can be tested on desktop builds. |
| 585 // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get | 652 enterprise_management::PolicyFetchResponse response; |
| 586 // the policy key directly, after moving the policy protobufs to a top-level | 653 if (!response.ParseFromString(policy_blob)) { |
| 587 // directory. The |policy_key| argument to this method can then be removed. | |
| 588 // http://crbug.com/240269 | |
| 589 base::FilePath key_path; | |
| 590 if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) { | |
| 591 callback.Run(false); | 654 callback.Run(false); |
| 592 return; | 655 return; |
| 593 } | 656 } |
| 594 const std::string sanitized = | 657 |
| 595 CryptohomeClient::GetStubSanitizedUsername(username); | 658 if (response.has_new_public_key()) { |
| 596 key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub"); | 659 base::FilePath key_path = GetUserFilePath(username, "policy.pub"); |
| 597 // Assume that the key write is successful. | 660 base::WorkerPool::PostTask( |
| 598 user_policies_[username] = policy_blob; | 661 FROM_HERE, |
| 662 base::Bind(&StoreFile, key_path, response.new_public_key()), |
| 663 false); |
| 664 } |
| 665 |
| 666 // This file isn't read directly by Chrome, but is used by this class to |
| 667 // reload the user policy across restarts. |
| 668 base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy"); |
| 599 base::WorkerPool::PostTaskAndReply( | 669 base::WorkerPool::PostTaskAndReply( |
| 600 FROM_HERE, | 670 FROM_HERE, |
| 601 base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground, | 671 base::Bind(&StoreFile, stub_policy_path, policy_blob), |
| 602 key_path, policy_key), | |
| 603 base::Bind(callback, true), | 672 base::Bind(callback, true), |
| 604 false); | 673 false); |
| 605 } | 674 } |
| 606 virtual void StoreDeviceLocalAccountPolicy( | 675 virtual void StoreDeviceLocalAccountPolicy( |
| 607 const std::string& account_name, | 676 const std::string& account_name, |
| 608 const std::string& policy_blob, | 677 const std::string& policy_blob, |
| 609 const StorePolicyCallback& callback) OVERRIDE { | 678 const StorePolicyCallback& callback) OVERRIDE { |
| 610 user_policies_[account_name] = policy_blob; | 679 StorePolicyForUser(account_name, policy_blob, callback); |
| 611 callback.Run(true); | |
| 612 } | 680 } |
| 613 virtual void SetFlagsForUser(const std::string& username, | 681 virtual void SetFlagsForUser(const std::string& username, |
| 614 const std::vector<std::string>& flags) OVERRIDE { | 682 const std::vector<std::string>& flags) OVERRIDE { |
| 615 } | 683 } |
| 616 | |
| 617 static void StoreFileInBackground(const base::FilePath& path, | |
| 618 const std::string& data) { | |
| 619 const int size = static_cast<int>(data.size()); | |
| 620 if (!base::CreateDirectory(path.DirName()) || | |
| 621 base::WriteFile(path, data.data(), size) != size) { | |
| 622 LOG(WARNING) << "Failed to write policy key to " << path.value(); | |
| 623 } | |
| 624 } | |
| 625 | |
| 626 private: | 684 private: |
| 627 StubDelegate* delegate_; // Weak pointer; may be NULL. | 685 StubDelegate* delegate_; // Weak pointer; may be NULL. |
| 628 ObserverList<Observer> observers_; | 686 ObserverList<Observer> observers_; |
| 629 std::string device_policy_; | 687 std::string device_policy_; |
| 630 std::map<std::string, std::string> user_policies_; | |
| 631 | 688 |
| 632 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); | 689 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); |
| 633 }; | 690 }; |
| 634 | 691 |
| 635 SessionManagerClient::SessionManagerClient() { | 692 SessionManagerClient::SessionManagerClient() { |
| 636 } | 693 } |
| 637 | 694 |
| 638 SessionManagerClient::~SessionManagerClient() { | 695 SessionManagerClient::~SessionManagerClient() { |
| 639 } | 696 } |
| 640 | 697 |
| 641 SessionManagerClient* SessionManagerClient::Create( | 698 SessionManagerClient* SessionManagerClient::Create( |
| 642 DBusClientImplementationType type) { | 699 DBusClientImplementationType type) { |
| 643 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 700 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
| 644 return new SessionManagerClientImpl(); | 701 return new SessionManagerClientImpl(); |
| 645 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 702 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
| 646 return new SessionManagerClientStubImpl(); | 703 return new SessionManagerClientStubImpl(); |
| 647 } | 704 } |
| 648 | 705 |
| 649 } // namespace chromeos | 706 } // namespace chromeos |
| OLD | NEW |