| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/prefs/profile_pref_store_manager.h" | 5 #include "chrome/browser/prefs/profile_pref_store_manager.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 const size_t kReportingIdCount = 3u; | 83 const size_t kReportingIdCount = 3u; |
| 84 | 84 |
| 85 } // namespace | 85 } // namespace |
| 86 | 86 |
| 87 class ProfilePrefStoreManagerTest : public testing::Test { | 87 class ProfilePrefStoreManagerTest : public testing::Test { |
| 88 public: | 88 public: |
| 89 ProfilePrefStoreManagerTest() | 89 ProfilePrefStoreManagerTest() |
| 90 : configuration_(kConfiguration, | 90 : configuration_(kConfiguration, |
| 91 kConfiguration + arraysize(kConfiguration)), | 91 kConfiguration + arraysize(kConfiguration)), |
| 92 profile_pref_registry_(new user_prefs::PrefRegistrySyncable), | 92 profile_pref_registry_(new user_prefs::PrefRegistrySyncable), |
| 93 registry_verifier_(profile_pref_registry_) {} | 93 registry_verifier_(profile_pref_registry_), |
| 94 seed_("seed") {} |
| 94 | 95 |
| 95 virtual void SetUp() OVERRIDE { | 96 virtual void SetUp() OVERRIDE { |
| 96 ProfilePrefStoreManager::RegisterPrefs(local_state_.registry()); | 97 ProfilePrefStoreManager::RegisterPrefs(local_state_.registry()); |
| 97 ProfilePrefStoreManager::RegisterProfilePrefs(profile_pref_registry_); | 98 ProfilePrefStoreManager::RegisterProfilePrefs(profile_pref_registry_); |
| 98 for (const PrefHashFilter::TrackedPreferenceMetadata* it = kConfiguration; | 99 for (const PrefHashFilter::TrackedPreferenceMetadata* it = kConfiguration; |
| 99 it != kConfiguration + arraysize(kConfiguration); | 100 it != kConfiguration + arraysize(kConfiguration); |
| 100 ++it) { | 101 ++it) { |
| 101 if (it->strategy == PrefHashFilter::TRACKING_STRATEGY_ATOMIC) { | 102 if (it->strategy == PrefHashFilter::TRACKING_STRATEGY_ATOMIC) { |
| 102 profile_pref_registry_->RegisterStringPref( | 103 profile_pref_registry_->RegisterStringPref( |
| 103 it->name, | 104 it->name, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 125 configuration_.push_back(pref_reset_time_config); | 126 configuration_.push_back(pref_reset_time_config); |
| 126 | 127 |
| 127 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); | 128 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); |
| 128 ReloadConfiguration(); | 129 ReloadConfiguration(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 void ReloadConfiguration() { | 132 void ReloadConfiguration() { |
| 132 manager_.reset(new ProfilePrefStoreManager(profile_dir_.path(), | 133 manager_.reset(new ProfilePrefStoreManager(profile_dir_.path(), |
| 133 configuration_, | 134 configuration_, |
| 134 kReportingIdCount, | 135 kReportingIdCount, |
| 135 "seed", | 136 seed_, |
| 136 "device_id", | 137 "device_id", |
| 137 &local_state_)); | 138 &local_state_)); |
| 138 } | 139 } |
| 139 | 140 |
| 140 virtual void TearDown() OVERRIDE { DestroyPrefStore(); } | 141 virtual void TearDown() OVERRIDE { DestroyPrefStore(); } |
| 141 | 142 |
| 142 protected: | 143 protected: |
| 143 bool WasResetRecorded() { | 144 bool WasResetRecorded() { |
| 144 base::PrefServiceFactory pref_service_factory; | 145 base::PrefServiceFactory pref_service_factory; |
| 145 pref_service_factory.set_user_prefs(pref_store_); | 146 pref_service_factory.set_user_prefs(pref_store_); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 246 |
| 246 base::MessageLoop main_message_loop_; | 247 base::MessageLoop main_message_loop_; |
| 247 std::vector<PrefHashFilter::TrackedPreferenceMetadata> configuration_; | 248 std::vector<PrefHashFilter::TrackedPreferenceMetadata> configuration_; |
| 248 base::ScopedTempDir profile_dir_; | 249 base::ScopedTempDir profile_dir_; |
| 249 TestingPrefServiceSimple local_state_; | 250 TestingPrefServiceSimple local_state_; |
| 250 scoped_refptr<user_prefs::PrefRegistrySyncable> profile_pref_registry_; | 251 scoped_refptr<user_prefs::PrefRegistrySyncable> profile_pref_registry_; |
| 251 RegistryVerifier registry_verifier_; | 252 RegistryVerifier registry_verifier_; |
| 252 MockValidationDelegate mock_validation_delegate_; | 253 MockValidationDelegate mock_validation_delegate_; |
| 253 scoped_ptr<ProfilePrefStoreManager> manager_; | 254 scoped_ptr<ProfilePrefStoreManager> manager_; |
| 254 scoped_refptr<PersistentPrefStore> pref_store_; | 255 scoped_refptr<PersistentPrefStore> pref_store_; |
| 256 |
| 257 std::string seed_; |
| 255 }; | 258 }; |
| 256 | 259 |
| 257 TEST_F(ProfilePrefStoreManagerTest, StoreValues) { | 260 TEST_F(ProfilePrefStoreManagerTest, StoreValues) { |
| 258 InitializePrefs(); | 261 InitializePrefs(); |
| 259 | 262 |
| 260 LoadExistingPrefs(); | 263 LoadExistingPrefs(); |
| 261 | 264 |
| 262 ExpectStringValueEquals(kTrackedAtomic, kFoobar); | 265 ExpectStringValueEquals(kTrackedAtomic, kFoobar); |
| 263 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); | 266 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); |
| 264 EXPECT_FALSE(WasResetRecorded()); | 267 EXPECT_FALSE(WasResetRecorded()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 294 // will be discarded at load time, leaving this preference undefined. | 297 // will be discarded at load time, leaving this preference undefined. |
| 295 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 298 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 296 pref_store_->GetValue(kProtectedAtomic, NULL)); | 299 pref_store_->GetValue(kProtectedAtomic, NULL)); |
| 297 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 300 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 298 WasResetRecorded()); | 301 WasResetRecorded()); |
| 299 | 302 |
| 300 ExpectValidationObserved(kTrackedAtomic); | 303 ExpectValidationObserved(kTrackedAtomic); |
| 301 ExpectValidationObserved(kProtectedAtomic); | 304 ExpectValidationObserved(kProtectedAtomic); |
| 302 } | 305 } |
| 303 | 306 |
| 304 TEST_F(ProfilePrefStoreManagerTest, ResetPrefHashStore) { | |
| 305 InitializePrefs(); | |
| 306 | |
| 307 manager_->ResetPrefHashStore(); | |
| 308 | |
| 309 LoadExistingPrefs(); | |
| 310 | |
| 311 // kTrackedAtomic is loaded as it appears on disk. | |
| 312 ExpectStringValueEquals(kTrackedAtomic, kFoobar); | |
| 313 // If preference tracking is supported, kProtectedAtomic will be undefined | |
| 314 // because the value was discarded due to loss of the hash store contents. | |
| 315 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | |
| 316 pref_store_->GetValue(kProtectedAtomic, NULL)); | |
| 317 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | |
| 318 WasResetRecorded()); | |
| 319 | |
| 320 ExpectValidationObserved(kTrackedAtomic); | |
| 321 ExpectValidationObserved(kProtectedAtomic); | |
| 322 } | |
| 323 | |
| 324 TEST_F(ProfilePrefStoreManagerTest, ResetAllPrefHashStores) { | |
| 325 InitializePrefs(); | |
| 326 | |
| 327 ProfilePrefStoreManager::ResetAllPrefHashStores(&local_state_); | |
| 328 | |
| 329 LoadExistingPrefs(); | |
| 330 | |
| 331 // kTrackedAtomic is loaded as it appears on disk. | |
| 332 ExpectStringValueEquals(kTrackedAtomic, kFoobar); | |
| 333 // If preference tracking is supported, kProtectedAtomic will be undefined | |
| 334 // because the value was discarded due to loss of the hash store contents. | |
| 335 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | |
| 336 pref_store_->GetValue(kProtectedAtomic, NULL)); | |
| 337 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | |
| 338 WasResetRecorded()); | |
| 339 | |
| 340 ExpectValidationObserved(kTrackedAtomic); | |
| 341 ExpectValidationObserved(kProtectedAtomic); | |
| 342 } | |
| 343 | |
| 344 TEST_F(ProfilePrefStoreManagerTest, MigrateFromOneFile) { | 307 TEST_F(ProfilePrefStoreManagerTest, MigrateFromOneFile) { |
| 345 InitializeDeprecatedCombinedProfilePrefStore(); | 308 InitializeDeprecatedCombinedProfilePrefStore(); |
| 346 | 309 |
| 347 LoadExistingPrefs(); | 310 LoadExistingPrefs(); |
| 348 | 311 |
| 349 ExpectStringValueEquals(kTrackedAtomic, kFoobar); | 312 ExpectStringValueEquals(kTrackedAtomic, kFoobar); |
| 350 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); | 313 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); |
| 351 EXPECT_FALSE(WasResetRecorded()); | 314 EXPECT_FALSE(WasResetRecorded()); |
| 352 } | 315 } |
| 353 | 316 |
| 354 TEST_F(ProfilePrefStoreManagerTest, UpdateProfileHashStoreIfRequired) { | |
| 355 scoped_refptr<JsonPrefStore> legacy_prefs( | |
| 356 new JsonPrefStore(ProfilePrefStoreManager::GetPrefFilePathFromProfilePath( | |
| 357 profile_dir_.path()), | |
| 358 main_message_loop_.message_loop_proxy(), | |
| 359 scoped_ptr<PrefFilter>())); | |
| 360 legacy_prefs->SetValue(kTrackedAtomic, new base::StringValue(kFoobar)); | |
| 361 legacy_prefs->SetValue(kProtectedAtomic, new base::StringValue(kHelloWorld)); | |
| 362 legacy_prefs = NULL; | |
| 363 base::RunLoop().RunUntilIdle(); | |
| 364 | |
| 365 // This is a no-op if !kPlatformSupportsPreferenceTracking. | |
| 366 manager_->UpdateProfileHashStoreIfRequired( | |
| 367 main_message_loop_.message_loop_proxy()); | |
| 368 base::RunLoop().RunUntilIdle(); | |
| 369 | |
| 370 // At the moment, UpdateProfileHashStoreIfRequired will accept existing | |
| 371 // values. | |
| 372 LoadExistingPrefs(); | |
| 373 | |
| 374 // These expectations hold whether or not tracking is supported. | |
| 375 ExpectStringValueEquals(kTrackedAtomic, kFoobar); | |
| 376 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); | |
| 377 EXPECT_FALSE(WasResetRecorded()); | |
| 378 } | |
| 379 | |
| 380 TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) { | 317 TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) { |
| 381 base::DictionaryValue master_prefs; | 318 base::DictionaryValue master_prefs; |
| 382 master_prefs.Set(kTrackedAtomic, new base::StringValue(kFoobar)); | 319 master_prefs.Set(kTrackedAtomic, new base::StringValue(kFoobar)); |
| 383 master_prefs.Set(kProtectedAtomic, new base::StringValue(kHelloWorld)); | 320 master_prefs.Set(kProtectedAtomic, new base::StringValue(kHelloWorld)); |
| 384 EXPECT_TRUE(manager_->InitializePrefsFromMasterPrefs(master_prefs)); | 321 EXPECT_TRUE(manager_->InitializePrefsFromMasterPrefs(master_prefs)); |
| 385 | 322 |
| 386 LoadExistingPrefs(); | 323 LoadExistingPrefs(); |
| 387 | 324 |
| 388 // Verify that InitializePrefsFromMasterPrefs correctly applied the MACs | 325 // Verify that InitializePrefsFromMasterPrefs correctly applied the MACs |
| 389 // necessary to authenticate these values. | 326 // necessary to authenticate these values. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 414 PrefHashFilter::TrackedPreferenceMetadata new_protected = { | 351 PrefHashFilter::TrackedPreferenceMetadata new_protected = { |
| 415 kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD, | 352 kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD, |
| 416 PrefHashFilter::TRACKING_STRATEGY_ATOMIC}; | 353 PrefHashFilter::TRACKING_STRATEGY_ATOMIC}; |
| 417 configuration_.push_back(new_protected); | 354 configuration_.push_back(new_protected); |
| 418 ReloadConfiguration(); | 355 ReloadConfiguration(); |
| 419 | 356 |
| 420 // And try loading with the new configuration. | 357 // And try loading with the new configuration. |
| 421 LoadExistingPrefs(); | 358 LoadExistingPrefs(); |
| 422 | 359 |
| 423 // Since there was a valid super MAC we were able to extend the existing trust | 360 // Since there was a valid super MAC we were able to extend the existing trust |
| 424 // to the newly proteted preference. | 361 // to the newly protected preference. |
| 425 ExpectStringValueEquals(kUnprotectedPref, kBarfoo); | 362 ExpectStringValueEquals(kUnprotectedPref, kBarfoo); |
| 426 EXPECT_FALSE(WasResetRecorded()); | 363 EXPECT_FALSE(WasResetRecorded()); |
| 427 | 364 |
| 428 // Ensure everything is written out to disk. | 365 // Ensure everything is written out to disk. |
| 429 DestroyPrefStore(); | 366 DestroyPrefStore(); |
| 430 | 367 |
| 431 // It's protected now, so (if the platform supports it) any tampering should | 368 // It's protected now, so (if the platform supports it) any tampering should |
| 432 // lead to a reset. | 369 // lead to a reset. |
| 433 ReplaceStringInPrefs(kBarfoo, kFoobar); | 370 ReplaceStringInPrefs(kBarfoo, kFoobar); |
| 434 LoadExistingPrefs(); | 371 LoadExistingPrefs(); |
| 435 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 372 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 436 pref_store_->GetValue(kUnprotectedPref, NULL)); | 373 pref_store_->GetValue(kUnprotectedPref, NULL)); |
| 437 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 374 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 438 WasResetRecorded()); | 375 WasResetRecorded()); |
| 439 } | 376 } |
| 440 | 377 |
| 441 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) { | 378 TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) { |
| 442 InitializePrefs(); | 379 InitializePrefs(); |
| 443 | 380 |
| 444 ExpectValidationObserved(kTrackedAtomic); | 381 ExpectValidationObserved(kTrackedAtomic); |
| 445 ExpectValidationObserved(kProtectedAtomic); | 382 ExpectValidationObserved(kProtectedAtomic); |
| 446 | 383 |
| 447 // Now update the configuration to protect it. | 384 // Now update the configuration to protect it. |
| 448 PrefHashFilter::TrackedPreferenceMetadata new_protected = { | 385 PrefHashFilter::TrackedPreferenceMetadata new_protected = { |
| 449 kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD, | 386 kExtraReportingId, kUnprotectedPref, PrefHashFilter::ENFORCE_ON_LOAD, |
| 450 PrefHashFilter::TRACKING_STRATEGY_ATOMIC}; | 387 PrefHashFilter::TRACKING_STRATEGY_ATOMIC}; |
| 451 configuration_.push_back(new_protected); | 388 configuration_.push_back(new_protected); |
| 389 seed_ = "new-seed-to-break-trust"; |
| 452 ReloadConfiguration(); | 390 ReloadConfiguration(); |
| 453 ProfilePrefStoreManager::ResetAllPrefHashStores(&local_state_); | |
| 454 | 391 |
| 455 // And try loading with the new configuration. | 392 // And try loading with the new configuration. |
| 456 LoadExistingPrefs(); | 393 LoadExistingPrefs(); |
| 457 | 394 |
| 458 // If preference tracking is supported, kUnprotectedPref will have been | 395 // If preference tracking is supported, kUnprotectedPref will have been |
| 459 // discarded because new values are not accepted without a valid super MAC. | 396 // discarded because new values are not accepted without a valid super MAC. |
| 460 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 397 EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 461 pref_store_->GetValue(kUnprotectedPref, NULL)); | 398 pref_store_->GetValue(kUnprotectedPref, NULL)); |
| 462 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, | 399 EXPECT_EQ(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking, |
| 463 WasResetRecorded()); | 400 WasResetRecorded()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 476 // Unconfigure protection for kProtectedAtomic | 413 // Unconfigure protection for kProtectedAtomic |
| 477 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it = | 414 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it = |
| 478 configuration_.begin(); | 415 configuration_.begin(); |
| 479 it != configuration_.end(); | 416 it != configuration_.end(); |
| 480 ++it) { | 417 ++it) { |
| 481 if (it->name == kProtectedAtomic) { | 418 if (it->name == kProtectedAtomic) { |
| 482 it->enforcement_level = PrefHashFilter::NO_ENFORCEMENT; | 419 it->enforcement_level = PrefHashFilter::NO_ENFORCEMENT; |
| 483 break; | 420 break; |
| 484 } | 421 } |
| 485 } | 422 } |
| 423 |
| 424 seed_ = "new-seed-to-break-trust"; |
| 486 ReloadConfiguration(); | 425 ReloadConfiguration(); |
| 487 | |
| 488 // Reset the hash stores and then try loading the prefs. | |
| 489 ProfilePrefStoreManager::ResetAllPrefHashStores(&local_state_); | |
| 490 LoadExistingPrefs(); | 426 LoadExistingPrefs(); |
| 491 | 427 |
| 492 // Verify that the value was not reset. | 428 // Verify that the value was not reset. |
| 493 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); | 429 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); |
| 494 EXPECT_FALSE(WasResetRecorded()); | 430 EXPECT_FALSE(WasResetRecorded()); |
| 495 | 431 |
| 496 // Accessing the value of the previously protected pref didn't trigger its | 432 // Accessing the value of the previously protected pref didn't trigger its |
| 497 // move to the unprotected preferences file, though the loading of the pref | 433 // move to the unprotected preferences file, though the loading of the pref |
| 498 // store should still have caused the MAC store to be recalculated. | 434 // store should still have caused the MAC store to be recalculated. |
| 499 LoadExistingPrefs(); | 435 LoadExistingPrefs(); |
| 500 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); | 436 ExpectStringValueEquals(kProtectedAtomic, kHelloWorld); |
| 501 | 437 |
| 502 // Trigger the logic that migrates it back to the unprotected preferences | 438 // Trigger the logic that migrates it back to the unprotected preferences |
| 503 // file. | 439 // file. |
| 504 pref_store_->SetValue(kProtectedAtomic, new base::StringValue(kGoodbyeWorld)); | 440 pref_store_->SetValue(kProtectedAtomic, new base::StringValue(kGoodbyeWorld)); |
| 505 LoadExistingPrefs(); | 441 LoadExistingPrefs(); |
| 506 ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld); | 442 ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld); |
| 507 EXPECT_FALSE(WasResetRecorded()); | 443 EXPECT_FALSE(WasResetRecorded()); |
| 508 } | 444 } |
| OLD | NEW |