| 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 |
| 7 #include "base/bind.h" | 9 #include "base/bind.h" |
| 8 #include "base/callback.h" | 10 #include "base/callback.h" |
| 9 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 11 #include "base/location.h" | 13 #include "base/location.h" |
| 12 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 13 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 14 #include "base/task_runner_util.h" | |
| 15 #include "base/threading/worker_pool.h" | 16 #include "base/threading/worker_pool.h" |
| 16 #include "chromeos/chromeos_paths.h" | 17 #include "chromeos/chromeos_paths.h" |
| 17 #include "chromeos/dbus/blocking_method_caller.h" | 18 #include "chromeos/dbus/blocking_method_caller.h" |
| 18 #include "chromeos/dbus/cryptohome_client.h" | 19 #include "chromeos/dbus/cryptohome_client.h" |
| 19 #include "dbus/bus.h" | 20 #include "dbus/bus.h" |
| 20 #include "dbus/message.h" | 21 #include "dbus/message.h" |
| 21 #include "dbus/object_path.h" | 22 #include "dbus/object_path.h" |
| 22 #include "dbus/object_proxy.h" | 23 #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 | |
| 62 // The SessionManagerClient implementation used in production. | 28 // The SessionManagerClient implementation used in production. |
| 63 class SessionManagerClientImpl : public SessionManagerClient { | 29 class SessionManagerClientImpl : public SessionManagerClient { |
| 64 public: | 30 public: |
| 65 SessionManagerClientImpl() | 31 SessionManagerClientImpl() |
| 66 : session_manager_proxy_(NULL), | 32 : session_manager_proxy_(NULL), |
| 67 weak_ptr_factory_(this) {} | 33 weak_ptr_factory_(this) {} |
| 68 | 34 |
| 69 virtual ~SessionManagerClientImpl() { | 35 virtual ~SessionManagerClientImpl() { |
| 70 } | 36 } |
| 71 | 37 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 197 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 232 base::Bind(&SessionManagerClientImpl::OnStorePolicy, | 198 base::Bind(&SessionManagerClientImpl::OnStorePolicy, |
| 233 weak_ptr_factory_.GetWeakPtr(), | 199 weak_ptr_factory_.GetWeakPtr(), |
| 234 login_manager::kSessionManagerStorePolicy, | 200 login_manager::kSessionManagerStorePolicy, |
| 235 callback)); | 201 callback)); |
| 236 } | 202 } |
| 237 | 203 |
| 238 virtual void StorePolicyForUser( | 204 virtual void StorePolicyForUser( |
| 239 const std::string& username, | 205 const std::string& username, |
| 240 const std::string& policy_blob, | 206 const std::string& policy_blob, |
| 207 const std::string& ignored_policy_key, |
| 241 const StorePolicyCallback& callback) OVERRIDE { | 208 const StorePolicyCallback& callback) OVERRIDE { |
| 242 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, | 209 CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser, |
| 243 username, | 210 username, |
| 244 policy_blob, | 211 policy_blob, |
| 245 callback); | 212 callback); |
| 246 } | 213 } |
| 247 | 214 |
| 248 virtual void StoreDeviceLocalAccountPolicy( | 215 virtual void StoreDeviceLocalAccountPolicy( |
| 249 const std::string& account_name, | 216 const std::string& account_name, |
| 250 const std::string& policy_blob, | 217 const std::string& policy_blob, |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 virtual void NotifyLockScreenShown() OVERRIDE { | 541 virtual void NotifyLockScreenShown() OVERRIDE { |
| 575 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); | 542 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsLocked()); |
| 576 } | 543 } |
| 577 virtual void NotifyLockScreenDismissed() OVERRIDE { | 544 virtual void NotifyLockScreenDismissed() OVERRIDE { |
| 578 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); | 545 FOR_EACH_OBSERVER(Observer, observers_, ScreenIsUnlocked()); |
| 579 } | 546 } |
| 580 virtual void RetrieveActiveSessions( | 547 virtual void RetrieveActiveSessions( |
| 581 const ActiveSessionsCallback& callback) OVERRIDE {} | 548 const ActiveSessionsCallback& callback) OVERRIDE {} |
| 582 virtual void RetrieveDevicePolicy( | 549 virtual void RetrieveDevicePolicy( |
| 583 const RetrievePolicyCallback& callback) OVERRIDE { | 550 const RetrievePolicyCallback& callback) OVERRIDE { |
| 584 base::FilePath owner_key_path; | 551 callback.Run(device_policy_); |
| 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); | |
| 596 } | 552 } |
| 597 virtual void RetrievePolicyForUser( | 553 virtual void RetrievePolicyForUser( |
| 598 const std::string& username, | 554 const std::string& username, |
| 599 const RetrievePolicyCallback& callback) OVERRIDE { | 555 const RetrievePolicyCallback& callback) OVERRIDE { |
| 600 base::PostTaskAndReplyWithResult( | 556 callback.Run(user_policies_[username]); |
| 601 base::WorkerPool::GetTaskRunner(false), | |
| 602 FROM_HERE, | |
| 603 base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")), | |
| 604 callback); | |
| 605 } | 557 } |
| 606 virtual std::string BlockingRetrievePolicyForUser( | 558 virtual std::string BlockingRetrievePolicyForUser( |
| 607 const std::string& username) OVERRIDE { | 559 const std::string& username) OVERRIDE { |
| 608 return GetFileContent(GetUserFilePath(username, "stub_policy")); | 560 return user_policies_[username]; |
| 609 } | 561 } |
| 610 virtual void RetrieveDeviceLocalAccountPolicy( | 562 virtual void RetrieveDeviceLocalAccountPolicy( |
| 611 const std::string& account_name, | 563 const std::string& account_name, |
| 612 const RetrievePolicyCallback& callback) OVERRIDE { | 564 const RetrievePolicyCallback& callback) OVERRIDE { |
| 613 RetrievePolicyForUser(account_name, callback); | 565 callback.Run(user_policies_[account_name]); |
| 614 } | 566 } |
| 615 virtual void StoreDevicePolicy(const std::string& policy_blob, | 567 virtual void StoreDevicePolicy(const std::string& policy_blob, |
| 616 const StorePolicyCallback& callback) OVERRIDE { | 568 const StorePolicyCallback& callback) OVERRIDE { |
| 617 enterprise_management::PolicyFetchResponse response; | 569 device_policy_ = policy_blob; |
| 618 base::FilePath owner_key_path; | 570 callback.Run(true); |
| 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); | |
| 644 } | 571 } |
| 645 virtual void StorePolicyForUser( | 572 virtual void StorePolicyForUser( |
| 646 const std::string& username, | 573 const std::string& username, |
| 647 const std::string& policy_blob, | 574 const std::string& policy_blob, |
| 575 const std::string& policy_key, |
| 648 const StorePolicyCallback& callback) OVERRIDE { | 576 const StorePolicyCallback& callback) OVERRIDE { |
| 577 if (policy_key.empty()) { |
| 578 user_policies_[username] = policy_blob; |
| 579 callback.Run(true); |
| 580 return; |
| 581 } |
| 649 // The session manager writes the user policy key to a well-known | 582 // The session manager writes the user policy key to a well-known |
| 650 // location. Do the same with the stub impl, so that user policy works and | 583 // location. Do the same with the stub impl, so that user policy works and |
| 651 // can be tested on desktop builds. | 584 // can be tested on desktop builds. |
| 652 enterprise_management::PolicyFetchResponse response; | 585 // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get |
| 653 if (!response.ParseFromString(policy_blob)) { | 586 // the policy key directly, after moving the policy protobufs to a top-level |
| 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)) { |
| 654 callback.Run(false); | 591 callback.Run(false); |
| 655 return; | 592 return; |
| 656 } | 593 } |
| 657 | 594 const std::string sanitized = |
| 658 if (response.has_new_public_key()) { | 595 CryptohomeClient::GetStubSanitizedUsername(username); |
| 659 base::FilePath key_path = GetUserFilePath(username, "policy.pub"); | 596 key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub"); |
| 660 base::WorkerPool::PostTask( | 597 // Assume that the key write is successful. |
| 661 FROM_HERE, | 598 user_policies_[username] = policy_blob; |
| 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"); | |
| 669 base::WorkerPool::PostTaskAndReply( | 599 base::WorkerPool::PostTaskAndReply( |
| 670 FROM_HERE, | 600 FROM_HERE, |
| 671 base::Bind(&StoreFile, stub_policy_path, policy_blob), | 601 base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground, |
| 602 key_path, policy_key), |
| 672 base::Bind(callback, true), | 603 base::Bind(callback, true), |
| 673 false); | 604 false); |
| 674 } | 605 } |
| 675 virtual void StoreDeviceLocalAccountPolicy( | 606 virtual void StoreDeviceLocalAccountPolicy( |
| 676 const std::string& account_name, | 607 const std::string& account_name, |
| 677 const std::string& policy_blob, | 608 const std::string& policy_blob, |
| 678 const StorePolicyCallback& callback) OVERRIDE { | 609 const StorePolicyCallback& callback) OVERRIDE { |
| 679 StorePolicyForUser(account_name, policy_blob, callback); | 610 user_policies_[account_name] = policy_blob; |
| 611 callback.Run(true); |
| 680 } | 612 } |
| 681 virtual void SetFlagsForUser(const std::string& username, | 613 virtual void SetFlagsForUser(const std::string& username, |
| 682 const std::vector<std::string>& flags) OVERRIDE { | 614 const std::vector<std::string>& flags) OVERRIDE { |
| 683 } | 615 } |
| 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 |
| 684 private: | 626 private: |
| 685 StubDelegate* delegate_; // Weak pointer; may be NULL. | 627 StubDelegate* delegate_; // Weak pointer; may be NULL. |
| 686 ObserverList<Observer> observers_; | 628 ObserverList<Observer> observers_; |
| 687 std::string device_policy_; | 629 std::string device_policy_; |
| 630 std::map<std::string, std::string> user_policies_; |
| 688 | 631 |
| 689 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); | 632 DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl); |
| 690 }; | 633 }; |
| 691 | 634 |
| 692 SessionManagerClient::SessionManagerClient() { | 635 SessionManagerClient::SessionManagerClient() { |
| 693 } | 636 } |
| 694 | 637 |
| 695 SessionManagerClient::~SessionManagerClient() { | 638 SessionManagerClient::~SessionManagerClient() { |
| 696 } | 639 } |
| 697 | 640 |
| 698 SessionManagerClient* SessionManagerClient::Create( | 641 SessionManagerClient* SessionManagerClient::Create( |
| 699 DBusClientImplementationType type) { | 642 DBusClientImplementationType type) { |
| 700 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 643 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
| 701 return new SessionManagerClientImpl(); | 644 return new SessionManagerClientImpl(); |
| 702 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 645 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
| 703 return new SessionManagerClientStubImpl(); | 646 return new SessionManagerClientStubImpl(); |
| 704 } | 647 } |
| 705 | 648 |
| 706 } // namespace chromeos | 649 } // namespace chromeos |
| OLD | NEW |