Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: chrome/browser/prefs/pref_hash_store_impl.cc

Issue 126093007: Introduce a hash_of_hashes dictionary. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: histogram desc Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/pref_hash_store_impl.h" 5 #include "chrome/browser/prefs/pref_hash_store_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
8 #include "base/prefs/pref_registry_simple.h" 9 #include "base/prefs/pref_registry_simple.h"
9 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h" 11 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/values.h" 12 #include "base/values.h"
12 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
13 14
14 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& hash_store_id, 15 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& hash_store_id,
15 const std::string& seed, 16 const std::string& seed,
16 const std::string& device_id, 17 const std::string& device_id,
17 PrefService* local_state) 18 PrefService* local_state)
18 : hash_store_id_(hash_store_id), 19 : hash_store_id_(hash_store_id),
19 pref_hash_calculator_(seed, device_id), 20 pref_hash_calculator_(seed, device_id),
20 local_state_(local_state) {} 21 local_state_(local_state),
22 initial_hashes_dictionary_trusted_(IsHashDictionaryTrusted()) {
23 UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
24 initial_hashes_dictionary_trusted_);
25 }
21 26
22 // static 27 // static
23 void PrefHashStoreImpl::RegisterPrefs(PrefRegistrySimple* registry) { 28 void PrefHashStoreImpl::RegisterPrefs(PrefRegistrySimple* registry) {
24 // Register the top level dictionary to map profile names to dictionaries of 29 // Register the top level dictionary to map profile names to dictionaries of
25 // tracked preferences. 30 // tracked preferences.
26 registry->RegisterDictionaryPref(prefs::kProfilePreferenceHashes); 31 registry->RegisterDictionaryPref(prefs::kProfilePreferenceHashes);
27 } 32 }
28 33
29 PrefHashStore::ValueState PrefHashStoreImpl::CheckValue( 34 PrefHashStore::ValueState PrefHashStoreImpl::CheckValue(
30 const std::string& path, const base::Value* initial_value) const { 35 const std::string& path, const base::Value* initial_value) const {
31 const base::DictionaryValue* pref_hash_dicts = 36 const base::DictionaryValue* pref_hash_dicts =
32 local_state_->GetDictionary(prefs::kProfilePreferenceHashes); 37 local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
33 const base::DictionaryValue* hashed_prefs = NULL; 38 const base::DictionaryValue* hashed_prefs = NULL;
34 pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_, 39 pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_,
35 &hashed_prefs); 40 &hashed_prefs);
36 41
37 std::string last_hash; 42 std::string last_hash;
38 if (!hashed_prefs || !hashed_prefs->GetString(path, &last_hash)) 43 if (!hashed_prefs || !hashed_prefs->GetString(path, &last_hash)) {
39 return PrefHashStore::UNKNOWN_VALUE; 44 // In the absence of a hash for this pref, always trust a NULL value, but
45 // only trust an existing value if the initial hashes dictionary is trusted.
46 return (!initial_value || initial_hashes_dictionary_trusted_) ?
47 TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
48 }
40 49
41 PrefHashCalculator::ValidationResult validation_result = 50 PrefHashCalculator::ValidationResult validation_result =
42 pref_hash_calculator_.Validate(path, initial_value, last_hash); 51 pref_hash_calculator_.Validate(path, initial_value, last_hash);
43 switch (validation_result) { 52 switch (validation_result) {
44 case PrefHashCalculator::VALID: 53 case PrefHashCalculator::VALID:
45 return PrefHashStore::UNCHANGED; 54 return UNCHANGED;
46 case PrefHashCalculator::VALID_LEGACY: 55 case PrefHashCalculator::VALID_LEGACY:
47 return PrefHashStore::MIGRATED; 56 return MIGRATED;
48 case PrefHashCalculator::INVALID: 57 case PrefHashCalculator::INVALID:
49 return initial_value ? PrefHashStore::CHANGED : PrefHashStore::CLEARED; 58 return initial_value ? CHANGED : CLEARED;
50 } 59 }
51 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: " 60 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: "
52 << validation_result; 61 << validation_result;
53 return PrefHashStore::UNKNOWN_VALUE; 62 return UNTRUSTED_UNKNOWN_VALUE;
54 } 63 }
55 64
56 void PrefHashStoreImpl::StoreHash( 65 void PrefHashStoreImpl::StoreHash(
57 const std::string& path, const base::Value* new_value) { 66 const std::string& path, const base::Value* new_value) {
58 { 67 {
59 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); 68 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes);
60 base::DictionaryValue* child_dictionary = NULL;
61 69
62 // Get the dictionary corresponding to the profile name, which may have a 70 // Get the dictionary corresponding to the profile name, which may have a
63 // '.' 71 // '.'
72 base::DictionaryValue* hashes_dict = NULL;
64 if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_, 73 if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_,
65 &child_dictionary)) { 74 &hashes_dict)) {
66 child_dictionary = new base::DictionaryValue; 75 hashes_dict = new base::DictionaryValue;
67 update->SetWithoutPathExpansion(hash_store_id_, child_dictionary); 76 update->SetWithoutPathExpansion(hash_store_id_, hashes_dict);
68 } 77 }
69 78
70 child_dictionary->SetString( 79 hashes_dict->SetString(
71 path, pref_hash_calculator_.Calculate(path, new_value)); 80 path, pref_hash_calculator_.Calculate(path, new_value));
81
82 // Get the dictionary where the hash of hashes are stored.
83 base::DictionaryValue* hash_of_hashes_dict = NULL;
84 if (!update->GetDictionaryWithoutPathExpansion(internals::kHashOfHashesPref,
85 &hash_of_hashes_dict)) {
86 hash_of_hashes_dict = new base::DictionaryValue;
87 update->SetWithoutPathExpansion(internals::kHashOfHashesPref,
88 hash_of_hashes_dict);
89 }
90 // Use the |hash_store_id_| as the hashed path to avoid having the hash
91 // depend on kProfilePreferenceHashes.
92 std::string hash_of_hashes(pref_hash_calculator_.Calculate(hash_store_id_,
93 hashes_dict));
94 hash_of_hashes_dict->SetStringWithoutPathExpansion(hash_store_id_,
95 hash_of_hashes);
72 } 96 }
73 // TODO(erikwright): During tests, pending writes were still waiting when the 97 // TODO(erikwright): During tests, pending writes were still waiting when the
74 // IO thread is already gone. Consider other solutions. 98 // IO thread is already gone. Consider other solutions.
75 local_state_->CommitPendingWrite(); 99 local_state_->CommitPendingWrite();
76 } 100 }
101
102 bool PrefHashStoreImpl::IsHashDictionaryTrusted() const {
103 const base::DictionaryValue* pref_hash_dicts =
104 local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
105 const base::DictionaryValue* hashes_dict = NULL;
106 const base::DictionaryValue* hash_of_hashes_dict = NULL;
107 std::string hash_of_hashes;
108 // The absence of the hashes dictionary isn't trusted. Nor is the absence of
109 // the hash of hashes for this |hash_store_id_|.
110 if (!pref_hash_dicts->GetDictionaryWithoutPathExpansion(
111 hash_store_id_, &hashes_dict) ||
112 !pref_hash_dicts->GetDictionaryWithoutPathExpansion(
113 internals::kHashOfHashesPref, &hash_of_hashes_dict) ||
114 !hash_of_hashes_dict->GetStringWithoutPathExpansion(
115 hash_store_id_, &hash_of_hashes)) {
116 return false;
117 }
118
119 return pref_hash_calculator_.Validate(
120 hash_store_id_, hashes_dict, hash_of_hashes) == PrefHashCalculator::VALID;
121 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698