Home | History | Annotate | Download | only in settings
      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 "chrome/browser/chromeos/settings/session_manager_operation.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/bind.h"
     12 #include "base/bind_helpers.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/time/time.h"
     17 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
     18 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
     19 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
     20 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
     21 #include "chrome/test/base/testing_profile.h"
     22 #include "components/ownership/mock_owner_key_util.h"
     23 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
     24 #include "components/policy/core/common/cloud/cloud_policy_validator.h"
     25 #include "components/policy/core/common/cloud/policy_builder.h"
     26 #include "content/public/test/test_browser_thread.h"
     27 #include "content/public/test/test_utils.h"
     28 #include "crypto/rsa_private_key.h"
     29 #include "policy/proto/device_management_backend.pb.h"
     30 #include "testing/gmock/include/gmock/gmock.h"
     31 #include "testing/gtest/include/gtest/gtest.h"
     32 
     33 namespace em = enterprise_management;
     34 
     35 using testing::Mock;
     36 using testing::_;
     37 
     38 namespace chromeos {
     39 
     40 class SessionManagerOperationTest : public testing::Test {
     41  public:
     42   SessionManagerOperationTest()
     43       : ui_thread_(content::BrowserThread::UI, &message_loop_),
     44         file_thread_(content::BrowserThread::FILE, &message_loop_),
     45         owner_key_util_(new ownership::MockOwnerKeyUtil()),
     46         validated_(false) {
     47     OwnerSettingsServiceChromeOSFactory::GetInstance()
     48         ->SetOwnerKeyUtilForTesting(owner_key_util_);
     49   }
     50 
     51   virtual void SetUp() OVERRIDE {
     52     policy_.payload().mutable_pinned_apps()->add_app_id("fake-app");
     53     policy_.Build();
     54 
     55     profile_.reset(new TestingProfile());
     56     service_ =
     57         OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get());
     58   }
     59 
     60   MOCK_METHOD2(OnOperationCompleted,
     61                void(SessionManagerOperation*, DeviceSettingsService::Status));
     62 
     63   void CheckSuccessfulValidation(
     64       policy::DeviceCloudPolicyValidator* validator) {
     65     EXPECT_TRUE(validator->success());
     66     EXPECT_TRUE(validator->payload().get());
     67     EXPECT_EQ(validator->payload()->SerializeAsString(),
     68               policy_.payload().SerializeAsString());
     69     validated_ = true;
     70   }
     71 
     72   void CheckPublicKeyLoaded(SessionManagerOperation* op) {
     73     ASSERT_TRUE(op->public_key().get());
     74     ASSERT_TRUE(op->public_key()->is_loaded());
     75     std::vector<uint8> public_key;
     76     ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key));
     77     EXPECT_EQ(public_key, op->public_key()->data());
     78   }
     79 
     80  protected:
     81   base::MessageLoop message_loop_;
     82   content::TestBrowserThread ui_thread_;
     83   content::TestBrowserThread file_thread_;
     84 
     85   policy::DevicePolicyBuilder policy_;
     86   DeviceSettingsTestHelper device_settings_test_helper_;
     87   scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
     88 
     89   scoped_ptr<TestingProfile> profile_;
     90   OwnerSettingsServiceChromeOS* service_;
     91 
     92   bool validated_;
     93 
     94  private:
     95   DISALLOW_COPY_AND_ASSIGN(SessionManagerOperationTest);
     96 };
     97 
     98 TEST_F(SessionManagerOperationTest, LoadNoPolicyNoKey) {
     99   LoadSettingsOperation op(
    100       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    101                  base::Unretained(this)));
    102 
    103   EXPECT_CALL(*this,
    104               OnOperationCompleted(
    105                   &op, DeviceSettingsService::STORE_KEY_UNAVAILABLE));
    106   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    107   device_settings_test_helper_.Flush();
    108   Mock::VerifyAndClearExpectations(this);
    109 
    110   EXPECT_FALSE(op.policy_data().get());
    111   EXPECT_FALSE(op.device_settings().get());
    112   ASSERT_TRUE(op.public_key().get());
    113   EXPECT_FALSE(op.public_key()->is_loaded());
    114 }
    115 
    116 TEST_F(SessionManagerOperationTest, LoadOwnerKey) {
    117   owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
    118   LoadSettingsOperation op(
    119       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    120                  base::Unretained(this)));
    121 
    122   EXPECT_CALL(*this,
    123               OnOperationCompleted(
    124                   &op, DeviceSettingsService::STORE_NO_POLICY));
    125   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    126   device_settings_test_helper_.Flush();
    127   Mock::VerifyAndClearExpectations(this);
    128 
    129   CheckPublicKeyLoaded(&op);
    130 }
    131 
    132 TEST_F(SessionManagerOperationTest, LoadPolicy) {
    133   owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
    134   device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
    135   LoadSettingsOperation op(
    136       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    137                  base::Unretained(this)));
    138 
    139   EXPECT_CALL(*this,
    140               OnOperationCompleted(
    141                   &op, DeviceSettingsService::STORE_SUCCESS));
    142   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    143   device_settings_test_helper_.Flush();
    144   Mock::VerifyAndClearExpectations(this);
    145 
    146   ASSERT_TRUE(op.policy_data().get());
    147   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    148             op.policy_data()->SerializeAsString());
    149   ASSERT_TRUE(op.device_settings().get());
    150   EXPECT_EQ(policy_.payload().SerializeAsString(),
    151             op.device_settings()->SerializeAsString());
    152 }
    153 
    154 TEST_F(SessionManagerOperationTest, RestartLoad) {
    155   owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
    156   device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
    157   LoadSettingsOperation op(
    158       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    159                  base::Unretained(this)));
    160 
    161   EXPECT_CALL(*this, OnOperationCompleted(&op, _)).Times(0);
    162   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    163   content::RunAllBlockingPoolTasksUntilIdle();
    164   device_settings_test_helper_.FlushRetrieve();
    165   EXPECT_TRUE(op.public_key().get());
    166   EXPECT_TRUE(op.public_key()->is_loaded());
    167   Mock::VerifyAndClearExpectations(this);
    168 
    169   // Now install a different key and policy and restart the operation.
    170   policy_.SetSigningKey(*policy::PolicyBuilder::CreateTestOtherSigningKey());
    171   policy_.payload().mutable_metrics_enabled()->set_metrics_enabled(true);
    172   policy_.Build();
    173   device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
    174   owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
    175 
    176   EXPECT_CALL(*this,
    177               OnOperationCompleted(
    178                   &op, DeviceSettingsService::STORE_SUCCESS));
    179   op.RestartLoad(true);
    180   device_settings_test_helper_.Flush();
    181   Mock::VerifyAndClearExpectations(this);
    182 
    183   // Check that the new keys have been loaded.
    184   CheckPublicKeyLoaded(&op);
    185 
    186   // Verify the new policy.
    187   ASSERT_TRUE(op.policy_data().get());
    188   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    189             op.policy_data()->SerializeAsString());
    190   ASSERT_TRUE(op.device_settings().get());
    191   EXPECT_EQ(policy_.payload().SerializeAsString(),
    192             op.device_settings()->SerializeAsString());
    193 }
    194 
    195 TEST_F(SessionManagerOperationTest, StoreSettings) {
    196   owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
    197   StoreSettingsOperation op(
    198       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    199                  base::Unretained(this)),
    200       policy_.GetCopy());
    201 
    202   EXPECT_CALL(*this,
    203               OnOperationCompleted(
    204                   &op, DeviceSettingsService::STORE_SUCCESS));
    205   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    206   device_settings_test_helper_.Flush();
    207   Mock::VerifyAndClearExpectations(this);
    208 
    209   EXPECT_EQ(device_settings_test_helper_.policy_blob(),
    210             policy_.GetBlob());
    211   ASSERT_TRUE(op.policy_data().get());
    212   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    213             op.policy_data()->SerializeAsString());
    214   ASSERT_TRUE(op.device_settings().get());
    215   EXPECT_EQ(policy_.payload().SerializeAsString(),
    216             op.device_settings()->SerializeAsString());
    217 }
    218 
    219 TEST_F(SessionManagerOperationTest, SignAndStoreSettings) {
    220   owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
    221   service_->OnTPMTokenReady(true /* is ready */);
    222 
    223   scoped_ptr<em::PolicyData> policy(new em::PolicyData(policy_.policy_data()));
    224   SignAndStoreSettingsOperation op(
    225       base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
    226                  base::Unretained(this)),
    227       policy.Pass());
    228   op.set_owner_settings_service(service_->as_weak_ptr());
    229 
    230   EXPECT_CALL(*this,
    231               OnOperationCompleted(
    232                   &op, DeviceSettingsService::STORE_SUCCESS));
    233   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
    234   device_settings_test_helper_.Flush();
    235   Mock::VerifyAndClearExpectations(this);
    236 
    237   // The blob should validate.
    238   scoped_ptr<em::PolicyFetchResponse> policy_response(
    239       new em::PolicyFetchResponse());
    240   ASSERT_TRUE(
    241       policy_response->ParseFromString(
    242           device_settings_test_helper_.policy_blob()));
    243   policy::DeviceCloudPolicyValidator* validator =
    244       policy::DeviceCloudPolicyValidator::Create(
    245           policy_response.Pass(), message_loop_.message_loop_proxy());
    246   validator->ValidateUsername(policy_.policy_data().username(), true);
    247   const base::Time expected_time = base::Time::UnixEpoch() +
    248       base::TimeDelta::FromMilliseconds(policy::PolicyBuilder::kFakeTimestamp);
    249   validator->ValidateTimestamp(
    250       expected_time,
    251       expected_time,
    252       policy::CloudPolicyValidatorBase::TIMESTAMP_REQUIRED);
    253   validator->ValidatePolicyType(policy::dm_protocol::kChromeDevicePolicyType);
    254   validator->ValidatePayload();
    255   std::vector<uint8> public_key;
    256   policy_.GetSigningKey()->ExportPublicKey(&public_key);
    257   // Convert from bytes to string format (which is what ValidateSignature()
    258   // takes).
    259   std::string public_key_as_string = std::string(
    260       reinterpret_cast<const char*>(vector_as_array(&public_key)),
    261       public_key.size());
    262   validator->ValidateSignature(
    263       public_key_as_string,
    264       policy::GetPolicyVerificationKey(),
    265       policy::PolicyBuilder::kFakeDomain,
    266       false);
    267   validator->StartValidation(
    268       base::Bind(&SessionManagerOperationTest::CheckSuccessfulValidation,
    269                  base::Unretained(this)));
    270 
    271   message_loop_.RunUntilIdle();
    272   EXPECT_TRUE(validated_);
    273 
    274   // Loaded device settings should match what the operation received.
    275   ASSERT_TRUE(op.device_settings().get());
    276   EXPECT_EQ(policy_.payload().SerializeAsString(),
    277             op.device_settings()->SerializeAsString());
    278 }
    279 
    280 }  // namespace chromeos
    281