diff options
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 4 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.cc | 2 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.h | 1 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run_unittest.cc | 19 | ||||
-rw-r--r-- | chrome/browser/metrics/variations/variations_seed_store.cc | 20 | ||||
-rw-r--r-- | chrome/browser/metrics/variations/variations_seed_store.h | 10 | ||||
-rw-r--r-- | chrome/browser/metrics/variations/variations_seed_store_unittest.cc | 39 | ||||
-rw-r--r-- | chrome/browser/metrics/variations/variations_service.cc | 6 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 3 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 1 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences.cc | 19 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences.h | 9 |
12 files changed, 103 insertions, 30 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index df7f182..77205a8 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -940,6 +940,10 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() { if (!master_prefs_->variations_seed.empty()) { local_state_->SetString(prefs::kVariationsSeed, master_prefs_->variations_seed); + if (!master_prefs_->variations_seed_signature.empty()) { + local_state_->SetString(prefs::kVariationsSeedSignature, + master_prefs_->variations_seed_signature); + } // Set the variation seed date to the current system time. If the user's // clock is incorrect, this may cause some field trial expiry checks to // not do the right thing until the next seed update from the server, diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index add798e..ef33f3e 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc @@ -564,6 +564,8 @@ void SetupMasterPrefsFromInstallPrefs( &out_prefs->import_bookmarks_path); out_prefs->variations_seed = install_prefs.GetVariationsSeed(); + out_prefs->variations_seed_signature = + install_prefs.GetVariationsSeedSignature(); install_prefs.GetString( installer::master_preferences::kDistroSuppressDefaultBrowserPromptPref, diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h index c1570cb..58911f3 100644 --- a/chrome/browser/first_run/first_run.h +++ b/chrome/browser/first_run/first_run.h @@ -79,6 +79,7 @@ struct MasterPrefs { std::vector<GURL> bookmarks; std::string import_bookmarks_path; std::string variations_seed; + std::string variations_seed_signature; std::string suppress_default_browser_prompt_for_version; }; diff --git a/chrome/browser/first_run/first_run_unittest.cc b/chrome/browser/first_run/first_run_unittest.cc index badf91b..bccc9e8 100644 --- a/chrome/browser/first_run/first_run_unittest.cc +++ b/chrome/browser/first_run/first_run_unittest.cc @@ -7,6 +7,7 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/test/scoped_path_override.h" +#include "base/values.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/first_run/first_run_internal.h" #include "chrome/common/chrome_paths.h" @@ -42,18 +43,36 @@ TEST_F(FirstRunTest, RemoveSentinel) { TEST_F(FirstRunTest, SetupMasterPrefsFromInstallPrefs_VariationsSeed) { installer::MasterPreferences install_prefs("{ \"variations_seed\":\"xyz\" }"); + EXPECT_EQ(1U, install_prefs.master_dictionary().size()); MasterPrefs out_prefs; internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); EXPECT_EQ("xyz", out_prefs.variations_seed); + // Variations prefs should have been extracted (removed) from the dictionary. + EXPECT_TRUE(install_prefs.master_dictionary().empty()); } TEST_F(FirstRunTest, SetupMasterPrefsFromInstallPrefs_NoVariationsSeed) { installer::MasterPreferences install_prefs("{ }"); + EXPECT_TRUE(install_prefs.master_dictionary().empty()); MasterPrefs out_prefs; internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); EXPECT_TRUE(out_prefs.variations_seed.empty()); + EXPECT_TRUE(out_prefs.variations_seed_signature.empty()); +} + +TEST_F(FirstRunTest, SetupMasterPrefsFromInstallPrefs_VariationsSeedSignature) { + installer::MasterPreferences install_prefs( + "{ \"variations_seed\":\"xyz\", \"variations_seed_signature\":\"abc\" }"); + EXPECT_EQ(2U, install_prefs.master_dictionary().size()); + + MasterPrefs out_prefs; + internal::SetupMasterPrefsFromInstallPrefs(install_prefs, &out_prefs); + EXPECT_EQ("xyz", out_prefs.variations_seed); + EXPECT_EQ("abc", out_prefs.variations_seed_signature); + // Variations prefs should have been extracted (removed) from the dictionary. + EXPECT_TRUE(install_prefs.master_dictionary().empty()); } } // namespace first_run diff --git a/chrome/browser/metrics/variations/variations_seed_store.cc b/chrome/browser/metrics/variations/variations_seed_store.cc index 2bf3b54..45ce323 100644 --- a/chrome/browser/metrics/variations/variations_seed_store.cc +++ b/chrome/browser/metrics/variations/variations_seed_store.cc @@ -63,9 +63,7 @@ bool VariationsSeedStore::LoadSeed(VariationsSeed* seed) { !seed->ParseFromString(seed_data)) { VLOG(1) << "Variations seed data in local pref is corrupt, clearing the " << "pref."; - local_state_->ClearPref(prefs::kVariationsSeed); - local_state_->ClearPref(prefs::kVariationsSeedDate); - local_state_->ClearPref(prefs::kVariationsSeedHash); + ClearPrefs(); RecordVariationSeedEmptyHistogram(VARIATIONS_SEED_CORRUPT); return false; } @@ -74,8 +72,10 @@ bool VariationsSeedStore::LoadSeed(VariationsSeed* seed) { return true; } -bool VariationsSeedStore::StoreSeedData(const std::string& seed_data, - const base::Time& date_fetched) { +bool VariationsSeedStore::StoreSeedData( + const std::string& seed_data, + const std::string& base64_seed_signature, + const base::Time& date_fetched) { if (seed_data.empty()) { VLOG(1) << "Variations seed data is empty, rejecting the seed."; return false; @@ -96,6 +96,8 @@ bool VariationsSeedStore::StoreSeedData(const std::string& seed_data, local_state_->SetString(prefs::kVariationsSeedHash, HashSeed(seed_data)); local_state_->SetInt64(prefs::kVariationsSeedDate, date_fetched.ToInternalValue()); + local_state_->SetString(prefs::kVariationsSeedSignature, + base64_seed_signature); variations_serial_number_ = seed.serial_number(); return true; @@ -107,6 +109,14 @@ void VariationsSeedStore::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterStringPref(prefs::kVariationsSeedHash, std::string()); registry->RegisterInt64Pref(prefs::kVariationsSeedDate, base::Time().ToInternalValue()); + registry->RegisterStringPref(prefs::kVariationsSeedSignature, std::string()); +} + +void VariationsSeedStore::ClearPrefs() { + local_state_->ClearPref(prefs::kVariationsSeed); + local_state_->ClearPref(prefs::kVariationsSeedDate); + local_state_->ClearPref(prefs::kVariationsSeedHash); + local_state_->ClearPref(prefs::kVariationsSeedSignature); } } // namespace chrome_variations diff --git a/chrome/browser/metrics/variations/variations_seed_store.h b/chrome/browser/metrics/variations/variations_seed_store.h index 80c5d64..5f8ddd7 100644 --- a/chrome/browser/metrics/variations/variations_seed_store.h +++ b/chrome/browser/metrics/variations/variations_seed_store.h @@ -30,10 +30,11 @@ class VariationsSeedStore { bool LoadSeed(VariationsSeed* seed); // Stores the given seed data (serialized protobuf data) to local state, along - // with the date when it was fetched. The |seed_data| will be Base64 encoded - // for storage. If the string is invalid, the existing prefs are left as is - // and the function returns false. + // with a base64-encoded digital signature for seed and the date when it was + // fetched. The |seed_data| will be base64 encoded for storage. If the string + // is invalid, the existing prefs are left as is and false is returned. bool StoreSeedData(const std::string& seed_data, + const std::string& base64_seed_signature, const base::Time& date_fetched); // Returns the serial number of the last loaded or stored seed. @@ -45,6 +46,9 @@ class VariationsSeedStore { static void RegisterPrefs(PrefRegistrySimple* registry); private: + // Clears all prefs related to variations seed storage. + void ClearPrefs(); + // The pref service used to persist the variations seed. PrefService* local_state_; diff --git a/chrome/browser/metrics/variations/variations_seed_store_unittest.cc b/chrome/browser/metrics/variations/variations_seed_store_unittest.cc index 738386b..03965f6 100644 --- a/chrome/browser/metrics/variations/variations_seed_store_unittest.cc +++ b/chrome/browser/metrics/variations/variations_seed_store_unittest.cc @@ -53,6 +53,13 @@ std::string SerializeSeedBase64(const VariationsSeed& seed, std::string* hash) { return base64_serialized_seed; } +// Checks whether the pref with name |pref_name| is at its default value in +// |prefs|. +bool PrefHasDefaultValue(const TestingPrefServiceSimple& prefs, + const char* pref_name) { + return prefs.FindPreference(pref_name)->IsDefaultValue(); +} + } // namespace TEST(VariationsSeedStoreTest, LoadSeed) { @@ -74,7 +81,7 @@ TEST(VariationsSeedStoreTest, LoadSeed) { // Check that the loaded data is the same as the original. EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); // Make sure the pref hasn't been changed. - EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); + EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); // Check that loading a seed with the correct hash works. @@ -90,24 +97,22 @@ TEST(VariationsSeedStoreTest, LoadSeed) { prefs.SetString(prefs::kVariationsSeed, SerializeSeedBase64(different_seed, &different_hash)); ASSERT_NE(different_hash, prefs.GetString(prefs::kVariationsSeedHash)); - EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); + EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); - EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); - EXPECT_TRUE( - prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue()); - EXPECT_TRUE( - prefs.FindPreference(prefs::kVariationsSeedHash)->IsDefaultValue()); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedHash)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); // Check that loading a bad seed returns false and clears the pref. prefs.ClearPref(prefs::kVariationsSeed); prefs.SetString(prefs::kVariationsSeed, "this should fail"); - EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); + EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); - EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); - EXPECT_TRUE( - prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue()); - EXPECT_TRUE( - prefs.FindPreference(prefs::kVariationsSeedHash)->IsDefaultValue()); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedHash)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); // Check that having no seed in prefs results in a return value of false. prefs.ClearPref(prefs::kVariationsSeed); @@ -124,9 +129,9 @@ TEST(VariationsSeedStoreTest, StoreSeedData) { VariationsSeedStore seed_store(&prefs); - EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, now)); + EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), now)); // Make sure the pref was actually set. - EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); + EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); std::string decoded_serialized_seed; @@ -137,8 +142,8 @@ TEST(VariationsSeedStoreTest, StoreSeedData) { // Check if trying to store a bad seed leaves the pref unchanged. prefs.ClearPref(prefs::kVariationsSeed); - EXPECT_FALSE(seed_store.StoreSeedData("should fail", now)); - EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); + EXPECT_FALSE(seed_store.StoreSeedData("should fail", std::string(), now)); + EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); } } // namespace chrome_variations diff --git a/chrome/browser/metrics/variations/variations_service.cc b/chrome/browser/metrics/variations/variations_service.cc index e800b7e..1494d3b 100644 --- a/chrome/browser/metrics/variations/variations_service.cc +++ b/chrome/browser/metrics/variations/variations_service.cc @@ -422,7 +422,11 @@ void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { bool success = request->GetResponseAsString(&seed_data); DCHECK(success); - if (seed_store_.StoreSeedData(seed_data, response_date)) + std::string seed_signature; + request->GetResponseHeaders()->EnumerateHeader(NULL, + "X-Seed-Signature", + &seed_signature); + if (seed_store_.StoreSeedData(seed_data, seed_signature, response_date)) RecordLastFetchTime(); } diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 1b05dc1..c87909e 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1391,6 +1391,9 @@ const char kVariationsSeedDate[] = "variations_seed_date"; // SHA-1 hash of the serialized variations seed data (hex encoded). const char kVariationsSeedHash[] = "variations_seed_hash"; +// Digital signature of the binary variations seed data, base64-encoded. +const char kVariationsSeedSignature[] = "variations_seed_signature"; + // An enum value to indicate the execution phase the browser was in. const char kStabilityExecutionPhase[] = "user_experience_metrics.stability.execution_phase"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index de08c4c..732a438 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -445,6 +445,7 @@ extern const char kVariationsRestrictParameter[]; extern const char kVariationsSeed[]; extern const char kVariationsSeedDate[]; extern const char kVariationsSeedHash[]; +extern const char kVariationsSeedSignature[]; extern const char kDeviceOpenNetworkConfiguration[]; diff --git a/chrome/installer/util/master_preferences.cc b/chrome/installer/util/master_preferences.cc index 76b544f..625a32d 100644 --- a/chrome/installer/util/master_preferences.cc +++ b/chrome/installer/util/master_preferences.cc @@ -311,9 +311,22 @@ bool MasterPreferences::GetExtensionsBlock( } std::string MasterPreferences::GetVariationsSeed() const { - std::string variations_seed; - master_dictionary_->GetString(prefs::kVariationsSeed, &variations_seed); - return variations_seed; + return ExtractPrefString(prefs::kVariationsSeed); +} + +std::string MasterPreferences::GetVariationsSeedSignature() const { + return ExtractPrefString(prefs::kVariationsSeedSignature); +} + +std::string MasterPreferences::ExtractPrefString( + const std::string& name) const { + std::string result; + scoped_ptr<base::Value> pref_value; + if (master_dictionary_->Remove(name, &pref_value)) { + if (!pref_value->GetAsString(&result)) + NOTREACHED(); + } + return result; } // static diff --git a/chrome/installer/util/master_preferences.h b/chrome/installer/util/master_preferences.h index 1b27c7e..b068b46 100644 --- a/chrome/installer/util/master_preferences.h +++ b/chrome/installer/util/master_preferences.h @@ -159,6 +159,9 @@ class MasterPreferences { // Returns the variations seed entry from the master prefs. std::string GetVariationsSeed() const; + // Returns the variations seed signature entry from the master prefs. + std::string GetVariationsSeedSignature() const; + // Returns true iff the master preferences were successfully read from a file. bool read_from_file() const { return preferences_read_from_file_; @@ -200,7 +203,11 @@ class MasterPreferences { // found in older master_preferences files. void EnforceLegacyPreferences(); - protected: + // Removes the specified string pref from the master preferences and returns + // its value. Should be used for master prefs that shouldn't be automatically + // copied over to profile preferences. + std::string ExtractPrefString(const std::string& name) const; + scoped_ptr<base::DictionaryValue> master_dictionary_; base::DictionaryValue* distribution_; bool preferences_read_from_file_; |