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
33namespace em = enterprise_management;
34
35using testing::Mock;
36using testing::_;
37
38namespace chromeos {
39
40class 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
98TEST_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
116TEST_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
132TEST_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
154TEST_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
195TEST_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
219TEST_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