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/policy/user_cloud_policy_store_chromeos.h" 6 7 #include <vector> 8 9 #include "base/basictypes.h" 10 #include "base/bind.h" 11 #include "base/files/file_util.h" 12 #include "base/files/scoped_temp_dir.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/message_loop/message_loop.h" 15 #include "base/threading/sequenced_worker_pool.h" 16 #include "chromeos/dbus/mock_cryptohome_client.h" 17 #include "chromeos/dbus/mock_session_manager_client.h" 18 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 19 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" 20 #include "components/policy/core/common/cloud/policy_builder.h" 21 #include "policy/policy_constants.h" 22 #include "policy/proto/cloud_policy.pb.h" 23 #include "policy/proto/device_management_local.pb.h" 24 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 namespace em = enterprise_management; 28 29 using testing::AllOf; 30 using testing::AnyNumber; 31 using testing::Eq; 32 using testing::Mock; 33 using testing::Property; 34 using testing::Return; 35 using testing::SaveArg; 36 using testing::_; 37 38 namespace policy { 39 40 namespace { 41 42 const char kLegacyDeviceId[] = "legacy-device-id"; 43 const char kLegacyToken[] = "legacy-token"; 44 const char kSanitizedUsername[] = 45 "0123456789ABCDEF0123456789ABCDEF012345678 (at) example.com"; 46 const char kDefaultHomepage[] = "http://chromium.org"; 47 48 ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) { 49 base::MessageLoop::current()->PostTask( 50 FROM_HERE, base::Bind(arg1, call_status, sanitized_username)); 51 } 52 53 class UserCloudPolicyStoreChromeOSTest : public testing::Test { 54 protected: 55 UserCloudPolicyStoreChromeOSTest() {} 56 57 virtual void SetUp() OVERRIDE { 58 EXPECT_CALL(cryptohome_client_, 59 GetSanitizedUsername(PolicyBuilder::kFakeUsername, _)) 60 .Times(AnyNumber()) 61 .WillRepeatedly( 62 SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_SUCCESS, 63 kSanitizedUsername)); 64 65 ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); 66 store_.reset(new UserCloudPolicyStoreChromeOS(&cryptohome_client_, 67 &session_manager_client_, 68 loop_.message_loop_proxy(), 69 PolicyBuilder::kFakeUsername, 70 user_policy_dir(), 71 token_file(), 72 policy_file())); 73 store_->AddObserver(&observer_); 74 75 // Install the initial public key, so that by default the validation of 76 // the stored/loaded policy blob succeeds. 77 std::vector<uint8> public_key; 78 ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key)); 79 StoreUserPolicyKey(public_key); 80 81 policy_.payload().mutable_homepagelocation()->set_value(kDefaultHomepage); 82 policy_.Build(); 83 } 84 85 virtual void TearDown() OVERRIDE { 86 store_->RemoveObserver(&observer_); 87 store_.reset(); 88 RunUntilIdle(); 89 } 90 91 // Install an expectation on |observer_| for an error code. 92 void ExpectError(CloudPolicyStore::Status error) { 93 EXPECT_CALL(observer_, 94 OnStoreError(AllOf(Eq(store_.get()), 95 Property(&CloudPolicyStore::status, 96 Eq(error))))); 97 } 98 99 // Triggers a store_->Load() operation, handles the expected call to 100 // |session_manager_client_| and sends |response|. 101 void PerformPolicyLoad(const std::string& response) { 102 // Issue a load command. 103 chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback; 104 EXPECT_CALL(session_manager_client_, 105 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _)) 106 .WillOnce(SaveArg<1>(&retrieve_callback)); 107 store_->Load(); 108 RunUntilIdle(); 109 Mock::VerifyAndClearExpectations(&session_manager_client_); 110 ASSERT_FALSE(retrieve_callback.is_null()); 111 112 // Run the callback. 113 retrieve_callback.Run(response); 114 RunUntilIdle(); 115 } 116 117 // Verifies that store_->policy_map() has the HomepageLocation entry with 118 // the |expected_value|. 119 void VerifyPolicyMap(const char* expected_value) { 120 EXPECT_EQ(1U, store_->policy_map().size()); 121 const PolicyMap::Entry* entry = 122 store_->policy_map().Get(key::kHomepageLocation); 123 ASSERT_TRUE(entry); 124 EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value)); 125 } 126 127 void StoreUserPolicyKey(const std::vector<uint8>& public_key) { 128 ASSERT_TRUE(base::CreateDirectory(user_policy_key_file().DirName())); 129 ASSERT_TRUE( 130 base::WriteFile(user_policy_key_file(), 131 reinterpret_cast<const char*>(public_key.data()), 132 public_key.size())); 133 } 134 135 // Stores the current |policy_| and verifies that it is published. 136 // If |new_public_key| is set then it will be persisted after storing but 137 // before loading the policy, so that the signature validation can succeed. 138 // If |previous_value| is set then a previously existing policy with that 139 // value will be expected; otherwise no previous policy is expected. 140 // If |new_value| is set then a new policy with that value is expected after 141 // storing the |policy_| blob. 142 void PerformStorePolicy(const std::vector<uint8>* new_public_key, 143 const char* previous_value, 144 const char* new_value) { 145 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 146 EXPECT_CALL(session_manager_client_, 147 StorePolicyForUser(PolicyBuilder::kFakeUsername, 148 policy_.GetBlob(), _)) 149 .WillOnce(SaveArg<2>(&store_callback)); 150 store_->Store(policy_.policy()); 151 RunUntilIdle(); 152 Mock::VerifyAndClearExpectations(&session_manager_client_); 153 ASSERT_FALSE(store_callback.is_null()); 154 155 // The new policy shouldn't be present yet. 156 PolicyMap previous_policy; 157 EXPECT_EQ(previous_value != NULL, store_->policy() != NULL); 158 if (previous_value) { 159 previous_policy.Set(key::kHomepageLocation, 160 POLICY_LEVEL_MANDATORY, 161 POLICY_SCOPE_USER, 162 new base::StringValue(previous_value), NULL); 163 } 164 EXPECT_TRUE(previous_policy.Equals(store_->policy_map())); 165 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 166 167 // Store the new public key so that the validation after the retrieve 168 // operation completes can verify the signature. 169 if (new_public_key) 170 StoreUserPolicyKey(*new_public_key); 171 172 // Let the store operation complete. 173 chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback; 174 EXPECT_CALL(session_manager_client_, 175 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _)) 176 .WillOnce(SaveArg<1>(&retrieve_callback)); 177 store_callback.Run(true); 178 RunUntilIdle(); 179 EXPECT_TRUE(previous_policy.Equals(store_->policy_map())); 180 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 181 Mock::VerifyAndClearExpectations(&session_manager_client_); 182 ASSERT_FALSE(retrieve_callback.is_null()); 183 184 // Finish the retrieve callback. 185 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 186 retrieve_callback.Run(policy_.GetBlob()); 187 RunUntilIdle(); 188 ASSERT_TRUE(store_->policy()); 189 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 190 store_->policy()->SerializeAsString()); 191 VerifyPolicyMap(new_value); 192 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 193 } 194 195 void VerifyStoreHasValidationError() { 196 EXPECT_FALSE(store_->policy()); 197 EXPECT_TRUE(store_->policy_map().empty()); 198 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 199 } 200 201 void RunUntilIdle() { 202 loop_.RunUntilIdle(); 203 loop_.RunUntilIdle(); 204 } 205 206 base::FilePath user_policy_dir() { 207 return tmp_dir_.path().AppendASCII("var_run_user_policy"); 208 } 209 210 base::FilePath user_policy_key_file() { 211 return user_policy_dir().AppendASCII(kSanitizedUsername) 212 .AppendASCII("policy.pub"); 213 } 214 215 base::FilePath token_file() { 216 return tmp_dir_.path().AppendASCII("token"); 217 } 218 219 base::FilePath policy_file() { 220 return tmp_dir_.path().AppendASCII("policy"); 221 } 222 223 base::MessageLoopForUI loop_; 224 chromeos::MockCryptohomeClient cryptohome_client_; 225 chromeos::MockSessionManagerClient session_manager_client_; 226 UserPolicyBuilder policy_; 227 MockCloudPolicyStoreObserver observer_; 228 scoped_ptr<UserCloudPolicyStoreChromeOS> store_; 229 230 private: 231 base::ScopedTempDir tmp_dir_; 232 233 DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreChromeOSTest); 234 }; 235 236 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) { 237 // Start without any public key to trigger the initial key checks. 238 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 239 // Make the policy blob contain a new public key. 240 policy_.SetDefaultNewSigningKey(); 241 policy_.Build(); 242 std::vector<uint8> new_public_key; 243 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 244 ASSERT_NO_FATAL_FAILURE( 245 PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage)); 246 } 247 248 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreValidationFail) { 249 // Start without any public key to trigger the initial key checks. 250 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 251 // Make the policy blob contain a new public key. 252 policy_.SetDefaultSigningKey(); 253 policy_.Build(); 254 *policy_.policy().mutable_new_public_key_verification_signature() = "garbage"; 255 256 EXPECT_CALL(session_manager_client_, 257 StorePolicyForUser( 258 PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0); 259 store_->Store(policy_.policy()); 260 RunUntilIdle(); 261 Mock::VerifyAndClearExpectations(&session_manager_client_); 262 } 263 264 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreMissingSignatureFailure) { 265 // Start without any public key to trigger the initial key checks. 266 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 267 // Make the policy blob contain a new public key. 268 policy_.SetDefaultSigningKey(); 269 policy_.Build(); 270 policy_.policy().clear_new_public_key_verification_signature(); 271 272 EXPECT_CALL(session_manager_client_, 273 StorePolicyForUser( 274 PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0); 275 store_->Store(policy_.policy()); 276 RunUntilIdle(); 277 Mock::VerifyAndClearExpectations(&session_manager_client_); 278 } 279 280 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithExistingKey) { 281 ASSERT_NO_FATAL_FAILURE( 282 PerformStorePolicy(NULL, NULL, kDefaultHomepage)); 283 } 284 285 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotation) { 286 // Make the policy blob contain a new public key. 287 policy_.SetDefaultNewSigningKey(); 288 policy_.Build(); 289 std::vector<uint8> new_public_key; 290 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 291 ASSERT_NO_FATAL_FAILURE( 292 PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage)); 293 } 294 295 TEST_F(UserCloudPolicyStoreChromeOSTest, 296 StoreWithRotationMissingSignatureError) { 297 // Make the policy blob contain a new public key. 298 policy_.SetDefaultNewSigningKey(); 299 policy_.Build(); 300 policy_.policy().clear_new_public_key_verification_signature(); 301 302 EXPECT_CALL(session_manager_client_, 303 StorePolicyForUser( 304 PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0); 305 store_->Store(policy_.policy()); 306 RunUntilIdle(); 307 Mock::VerifyAndClearExpectations(&session_manager_client_); 308 } 309 310 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotationValidationError) { 311 // Make the policy blob contain a new public key. 312 policy_.SetDefaultNewSigningKey(); 313 policy_.Build(); 314 *policy_.policy().mutable_new_public_key_verification_signature() = "garbage"; 315 316 EXPECT_CALL(session_manager_client_, 317 StorePolicyForUser( 318 PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0); 319 store_->Store(policy_.policy()); 320 RunUntilIdle(); 321 Mock::VerifyAndClearExpectations(&session_manager_client_); 322 } 323 324 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreFail) { 325 // Store policy. 326 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 327 EXPECT_CALL(session_manager_client_, 328 StorePolicyForUser(PolicyBuilder::kFakeUsername, 329 policy_.GetBlob(), _)) 330 .WillOnce(SaveArg<2>(&store_callback)); 331 store_->Store(policy_.policy()); 332 RunUntilIdle(); 333 Mock::VerifyAndClearExpectations(&session_manager_client_); 334 ASSERT_FALSE(store_callback.is_null()); 335 336 // Let the store operation complete. 337 ExpectError(CloudPolicyStore::STATUS_STORE_ERROR); 338 store_callback.Run(false); 339 RunUntilIdle(); 340 EXPECT_FALSE(store_->policy()); 341 EXPECT_TRUE(store_->policy_map().empty()); 342 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, store_->status()); 343 } 344 345 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreValidationError) { 346 policy_.policy_data().clear_policy_type(); 347 policy_.Build(); 348 349 // Store policy. 350 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 351 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 352 EXPECT_CALL(session_manager_client_, 353 StorePolicyForUser(PolicyBuilder::kFakeUsername, 354 policy_.GetBlob(), _)) 355 .Times(0); 356 store_->Store(policy_.policy()); 357 RunUntilIdle(); 358 Mock::VerifyAndClearExpectations(&session_manager_client_); 359 } 360 361 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithoutPolicyKey) { 362 // Make the dbus call to cryptohome fail. 363 Mock::VerifyAndClearExpectations(&cryptohome_client_); 364 EXPECT_CALL(cryptohome_client_, 365 GetSanitizedUsername(PolicyBuilder::kFakeUsername, _)) 366 .Times(AnyNumber()) 367 .WillRepeatedly(SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_FAILURE, 368 std::string())); 369 370 // Store policy. 371 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 372 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 373 EXPECT_CALL(session_manager_client_, 374 StorePolicyForUser(PolicyBuilder::kFakeUsername, 375 policy_.GetBlob(), _)) 376 .Times(0); 377 store_->Store(policy_.policy()); 378 RunUntilIdle(); 379 Mock::VerifyAndClearExpectations(&session_manager_client_); 380 } 381 382 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithInvalidSignature) { 383 // Break the signature. 384 policy_.policy().mutable_policy_data_signature()->append("garbage"); 385 386 // Store policy. 387 chromeos::SessionManagerClient::StorePolicyCallback store_callback; 388 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 389 EXPECT_CALL(session_manager_client_, 390 StorePolicyForUser(PolicyBuilder::kFakeUsername, 391 policy_.GetBlob(), _)) 392 .Times(0); 393 store_->Store(policy_.policy()); 394 RunUntilIdle(); 395 Mock::VerifyAndClearExpectations(&session_manager_client_); 396 } 397 398 TEST_F(UserCloudPolicyStoreChromeOSTest, Load) { 399 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 400 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 401 Mock::VerifyAndClearExpectations(&observer_); 402 403 // Verify that the policy has been loaded. 404 ASSERT_TRUE(store_->policy()); 405 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 406 store_->policy()->SerializeAsString()); 407 VerifyPolicyMap(kDefaultHomepage); 408 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 409 } 410 411 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoPolicy) { 412 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 413 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 414 Mock::VerifyAndClearExpectations(&observer_); 415 416 // Verify no policy has been installed. 417 EXPECT_FALSE(store_->policy()); 418 EXPECT_TRUE(store_->policy_map().empty()); 419 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 420 } 421 422 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidPolicy) { 423 ExpectError(CloudPolicyStore::STATUS_PARSE_ERROR); 424 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("invalid")); 425 426 // Verify no policy has been installed. 427 EXPECT_FALSE(store_->policy()); 428 EXPECT_TRUE(store_->policy_map().empty()); 429 EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status()); 430 } 431 432 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadValidationError) { 433 policy_.policy_data().clear_policy_type(); 434 policy_.Build(); 435 436 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 437 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 438 VerifyStoreHasValidationError(); 439 } 440 441 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) { 442 // The loaded policy can't be verified without the public key. 443 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 444 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 445 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 446 VerifyStoreHasValidationError(); 447 } 448 449 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidSignature) { 450 // Break the signature. 451 policy_.policy().mutable_policy_data_signature()->append("garbage"); 452 ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR); 453 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob())); 454 VerifyStoreHasValidationError(); 455 } 456 457 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationFull) { 458 std::string data; 459 460 em::DeviceCredentials credentials; 461 credentials.set_device_token(kLegacyToken); 462 credentials.set_device_id(kLegacyDeviceId); 463 ASSERT_TRUE(credentials.SerializeToString(&data)); 464 ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size())); 465 466 em::CachedCloudPolicyResponse cached_policy; 467 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 468 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 469 ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size())); 470 471 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 472 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 473 Mock::VerifyAndClearExpectations(&observer_); 474 475 // Verify that legacy user policy and token have been loaded. 476 em::PolicyData expected_policy_data; 477 EXPECT_TRUE(expected_policy_data.ParseFromString( 478 cached_policy.cloud_policy().policy_data())); 479 expected_policy_data.clear_public_key_version(); 480 expected_policy_data.set_request_token(kLegacyToken); 481 expected_policy_data.set_device_id(kLegacyDeviceId); 482 ASSERT_TRUE(store_->policy()); 483 EXPECT_EQ(expected_policy_data.SerializeAsString(), 484 store_->policy()->SerializeAsString()); 485 VerifyPolicyMap(kDefaultHomepage); 486 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 487 } 488 489 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoToken) { 490 std::string data; 491 testing::Sequence seq; 492 493 em::CachedCloudPolicyResponse cached_policy; 494 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 495 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 496 ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size())); 497 498 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 499 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 500 Mock::VerifyAndClearExpectations(&observer_); 501 502 // Verify the legacy cache has been loaded. 503 em::PolicyData expected_policy_data; 504 EXPECT_TRUE(expected_policy_data.ParseFromString( 505 cached_policy.cloud_policy().policy_data())); 506 expected_policy_data.clear_public_key_version(); 507 ASSERT_TRUE(store_->policy()); 508 EXPECT_EQ(expected_policy_data.SerializeAsString(), 509 store_->policy()->SerializeAsString()); 510 VerifyPolicyMap(kDefaultHomepage); 511 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 512 } 513 514 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoPolicy) { 515 std::string data; 516 517 em::DeviceCredentials credentials; 518 credentials.set_device_token(kLegacyToken); 519 credentials.set_device_id(kLegacyDeviceId); 520 ASSERT_TRUE(credentials.SerializeToString(&data)); 521 ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size())); 522 523 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 524 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 525 Mock::VerifyAndClearExpectations(&observer_); 526 527 // Verify that legacy user policy and token have been loaded. 528 em::PolicyData expected_policy_data; 529 expected_policy_data.set_request_token(kLegacyToken); 530 expected_policy_data.set_device_id(kLegacyDeviceId); 531 ASSERT_TRUE(store_->policy()); 532 EXPECT_EQ(expected_policy_data.SerializeAsString(), 533 store_->policy()->SerializeAsString()); 534 EXPECT_TRUE(store_->policy_map().empty()); 535 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 536 } 537 538 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) { 539 // Start without an existing public key. 540 ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false)); 541 542 std::string data; 543 em::CachedCloudPolicyResponse cached_policy; 544 cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy()); 545 ASSERT_TRUE(cached_policy.SerializeToString(&data)); 546 ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size())); 547 548 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 549 ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("")); 550 Mock::VerifyAndClearExpectations(&observer_); 551 552 // Verify the legacy cache has been loaded. 553 em::PolicyData expected_policy_data; 554 EXPECT_TRUE(expected_policy_data.ParseFromString( 555 cached_policy.cloud_policy().policy_data())); 556 expected_policy_data.clear_public_key_version(); 557 ASSERT_TRUE(store_->policy()); 558 EXPECT_EQ(expected_policy_data.SerializeAsString(), 559 store_->policy()->SerializeAsString()); 560 VerifyPolicyMap(kDefaultHomepage); 561 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 562 EXPECT_TRUE(base::PathExists(policy_file())); 563 564 // Now store a new policy using the new homepage location. 565 const char kNewHomepage[] = "http://google.com"; 566 policy_.payload().mutable_homepagelocation()->set_value(kNewHomepage); 567 policy_.SetDefaultNewSigningKey(); 568 policy_.Build(); 569 std::vector<uint8> new_public_key; 570 ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key)); 571 ASSERT_NO_FATAL_FAILURE( 572 PerformStorePolicy(&new_public_key, kDefaultHomepage, kNewHomepage)); 573 VerifyPolicyMap(kNewHomepage); 574 575 // Verify that the legacy cache has been removed. 576 EXPECT_FALSE(base::PathExists(policy_file())); 577 } 578 579 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediately) { 580 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 581 EXPECT_CALL(session_manager_client_, 582 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 583 .WillOnce(Return(policy_.GetBlob())); 584 EXPECT_CALL(cryptohome_client_, 585 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 586 .WillOnce(Return(kSanitizedUsername)); 587 588 EXPECT_FALSE(store_->policy()); 589 store_->LoadImmediately(); 590 // Note: verify that the |observer_| got notified synchronously, without 591 // having to spin the current loop. TearDown() will flush the loop so this 592 // must be done within the test. 593 Mock::VerifyAndClearExpectations(&observer_); 594 Mock::VerifyAndClearExpectations(&session_manager_client_); 595 Mock::VerifyAndClearExpectations(&cryptohome_client_); 596 597 // The policy should become available without having to spin any loops. 598 ASSERT_TRUE(store_->policy()); 599 EXPECT_EQ(policy_.policy_data().SerializeAsString(), 600 store_->policy()->SerializeAsString()); 601 VerifyPolicyMap(kDefaultHomepage); 602 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 603 } 604 605 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoPolicy) { 606 EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); 607 EXPECT_CALL(session_manager_client_, 608 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 609 .WillOnce(Return("")); 610 611 EXPECT_FALSE(store_->policy()); 612 store_->LoadImmediately(); 613 Mock::VerifyAndClearExpectations(&observer_); 614 Mock::VerifyAndClearExpectations(&session_manager_client_); 615 616 EXPECT_FALSE(store_->policy()); 617 EXPECT_TRUE(store_->policy_map().empty()); 618 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 619 } 620 621 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyInvalidBlob) { 622 EXPECT_CALL(observer_, OnStoreError(store_.get())); 623 EXPECT_CALL(session_manager_client_, 624 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 625 .WillOnce(Return("le blob")); 626 627 EXPECT_FALSE(store_->policy()); 628 store_->LoadImmediately(); 629 Mock::VerifyAndClearExpectations(&observer_); 630 Mock::VerifyAndClearExpectations(&session_manager_client_); 631 632 EXPECT_FALSE(store_->policy()); 633 EXPECT_TRUE(store_->policy_map().empty()); 634 EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status()); 635 } 636 637 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyDBusFailure) { 638 EXPECT_CALL(observer_, OnStoreError(store_.get())); 639 EXPECT_CALL(session_manager_client_, 640 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 641 .WillOnce(Return(policy_.GetBlob())); 642 EXPECT_CALL(cryptohome_client_, 643 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 644 .WillOnce(Return("")); 645 646 EXPECT_FALSE(store_->policy()); 647 store_->LoadImmediately(); 648 Mock::VerifyAndClearExpectations(&observer_); 649 Mock::VerifyAndClearExpectations(&session_manager_client_); 650 Mock::VerifyAndClearExpectations(&cryptohome_client_); 651 652 EXPECT_FALSE(store_->policy()); 653 EXPECT_TRUE(store_->policy_map().empty()); 654 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, store_->status()); 655 } 656 657 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoUserPolicyKey) { 658 EXPECT_CALL(observer_, OnStoreError(store_.get())); 659 EXPECT_CALL(session_manager_client_, 660 BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername)) 661 .WillOnce(Return(policy_.GetBlob())); 662 EXPECT_CALL(cryptohome_client_, 663 BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername)) 664 .WillOnce(Return("wrong (at) example.com")); 665 666 EXPECT_FALSE(store_->policy()); 667 store_->LoadImmediately(); 668 Mock::VerifyAndClearExpectations(&observer_); 669 Mock::VerifyAndClearExpectations(&session_manager_client_); 670 Mock::VerifyAndClearExpectations(&cryptohome_client_); 671 672 EXPECT_FALSE(store_->policy()); 673 EXPECT_TRUE(store_->policy_map().empty()); 674 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 675 } 676 677 } // namespace 678 679 } // namespace policy 680