| OLD | NEW |
| 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 "components/user_prefs/tracked/pref_hash_store_impl.h" | 5 #include "components/user_prefs/tracked/pref_hash_store_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 bool HasHash(const std::string& path) const override; | 36 bool HasHash(const std::string& path) const override; |
| 37 void ImportHash(const std::string& path, const base::Value* hash) override; | 37 void ImportHash(const std::string& path, const base::Value* hash) override; |
| 38 void ClearHash(const std::string& path) override; | 38 void ClearHash(const std::string& path) override; |
| 39 bool IsSuperMACValid() const override; | 39 bool IsSuperMACValid() const override; |
| 40 bool StampSuperMac() override; | 40 bool StampSuperMac() override; |
| 41 | 41 |
| 42 private: | 42 private: |
| 43 bool GetSplitMacs(const std::string& path, | 43 bool GetSplitMacs(const std::string& path, |
| 44 std::map<std::string, std::string>* split_macs) const; | 44 std::map<std::string, std::string>* split_macs) const; |
| 45 | 45 |
| 46 HashStoreContents* contents() { | |
| 47 return outer_->legacy_hash_store_contents_ | |
| 48 ? outer_->legacy_hash_store_contents_.get() | |
| 49 : contents_.get(); | |
| 50 } | |
| 51 | |
| 52 const HashStoreContents* contents() const { | |
| 53 return outer_->legacy_hash_store_contents_ | |
| 54 ? outer_->legacy_hash_store_contents_.get() | |
| 55 : contents_.get(); | |
| 56 } | |
| 57 | |
| 58 PrefHashStoreImpl* outer_; | 46 PrefHashStoreImpl* outer_; |
| 59 std::unique_ptr<HashStoreContents> contents_; | 47 std::unique_ptr<HashStoreContents> contents_; |
| 60 | 48 |
| 61 bool super_mac_valid_; | 49 bool super_mac_valid_; |
| 62 bool super_mac_dirty_; | 50 bool super_mac_dirty_; |
| 63 | 51 |
| 64 DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl); | 52 DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl); |
| 65 }; | 53 }; |
| 66 | 54 |
| 67 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed, | 55 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed, |
| 68 const std::string& device_id, | 56 const std::string& device_id, |
| 69 bool use_super_mac) | 57 bool use_super_mac) |
| 70 : pref_hash_calculator_(seed, device_id), use_super_mac_(use_super_mac) { | 58 : pref_hash_calculator_(seed, device_id), use_super_mac_(use_super_mac) { |
| 71 } | 59 } |
| 72 | 60 |
| 73 PrefHashStoreImpl::~PrefHashStoreImpl() { | 61 PrefHashStoreImpl::~PrefHashStoreImpl() { |
| 74 } | 62 } |
| 75 | 63 |
| 76 void PrefHashStoreImpl::set_legacy_hash_store_contents( | |
| 77 std::unique_ptr<HashStoreContents> legacy_hash_store_contents) { | |
| 78 legacy_hash_store_contents_ = std::move(legacy_hash_store_contents); | |
| 79 } | |
| 80 | |
| 81 std::unique_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction( | 64 std::unique_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction( |
| 82 std::unique_ptr<HashStoreContents> storage) { | 65 std::unique_ptr<HashStoreContents> storage) { |
| 83 return std::unique_ptr<PrefHashStoreTransaction>( | 66 return std::unique_ptr<PrefHashStoreTransaction>( |
| 84 new PrefHashStoreTransactionImpl(this, std::move(storage))); | 67 new PrefHashStoreTransactionImpl(this, std::move(storage))); |
| 85 } | 68 } |
| 86 | 69 |
| 87 PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl( | 70 PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl( |
| 88 PrefHashStoreImpl* outer, | 71 PrefHashStoreImpl* outer, |
| 89 std::unique_ptr<HashStoreContents> storage) | 72 std::unique_ptr<HashStoreContents> storage) |
| 90 : outer_(outer), | 73 : outer_(outer), |
| 91 contents_(std::move(storage)), | 74 contents_(std::move(storage)), |
| 92 super_mac_valid_(false), | 75 super_mac_valid_(false), |
| 93 super_mac_dirty_(false) { | 76 super_mac_dirty_(false) { |
| 94 if (!outer_->use_super_mac_) | 77 if (!outer_->use_super_mac_) |
| 95 return; | 78 return; |
| 96 | 79 |
| 97 // The store must be initialized and have a valid super MAC to be trusted. | 80 // The store must be initialized and have a valid super MAC to be trusted. |
| 98 | 81 |
| 99 const base::DictionaryValue* store_contents = contents()->GetContents(); | 82 const base::DictionaryValue* store_contents = contents_->GetContents(); |
| 100 if (!store_contents) | 83 if (!store_contents) |
| 101 return; | 84 return; |
| 102 | 85 |
| 103 std::string super_mac = contents()->GetSuperMac(); | 86 std::string super_mac = contents_->GetSuperMac(); |
| 104 if (super_mac.empty()) | 87 if (super_mac.empty()) |
| 105 return; | 88 return; |
| 106 | 89 |
| 107 super_mac_valid_ = outer_->pref_hash_calculator_.Validate( | 90 super_mac_valid_ = outer_->pref_hash_calculator_.Validate( |
| 108 contents()->hash_store_id(), store_contents, | 91 contents_->hash_store_id(), store_contents, |
| 109 super_mac) == PrefHashCalculator::VALID; | 92 super_mac) == PrefHashCalculator::VALID; |
| 110 } | 93 } |
| 111 | 94 |
| 112 PrefHashStoreImpl::PrefHashStoreTransactionImpl:: | 95 PrefHashStoreImpl::PrefHashStoreTransactionImpl:: |
| 113 ~PrefHashStoreTransactionImpl() { | 96 ~PrefHashStoreTransactionImpl() { |
| 114 if (super_mac_dirty_ && outer_->use_super_mac_) { | 97 if (super_mac_dirty_ && outer_->use_super_mac_) { |
| 115 // Get the dictionary of hashes (or NULL if it doesn't exist). | 98 // Get the dictionary of hashes (or NULL if it doesn't exist). |
| 116 const base::DictionaryValue* hashes_dict = contents()->GetContents(); | 99 const base::DictionaryValue* hashes_dict = contents_->GetContents(); |
| 117 contents()->SetSuperMac(outer_->pref_hash_calculator_.Calculate( | 100 contents_->SetSuperMac(outer_->pref_hash_calculator_.Calculate( |
| 118 contents()->hash_store_id(), hashes_dict)); | 101 contents_->hash_store_id(), hashes_dict)); |
| 119 } | 102 } |
| 120 } | 103 } |
| 121 | 104 |
| 122 PrefHashStoreTransaction::ValueState | 105 PrefHashStoreTransaction::ValueState |
| 123 PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue( | 106 PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue( |
| 124 const std::string& path, | 107 const std::string& path, |
| 125 const base::Value* initial_value) const { | 108 const base::Value* initial_value) const { |
| 126 const base::DictionaryValue* hashes_dict = contents()->GetContents(); | 109 const base::DictionaryValue* hashes_dict = contents_->GetContents(); |
| 127 | 110 |
| 128 std::string last_hash; | 111 std::string last_hash; |
| 129 if (hashes_dict) | 112 if (hashes_dict) |
| 130 hashes_dict->GetString(path, &last_hash); | 113 hashes_dict->GetString(path, &last_hash); |
| 131 | 114 |
| 132 if (last_hash.empty()) { | 115 if (last_hash.empty()) { |
| 133 // In the absence of a hash for this pref, always trust a NULL value, but | 116 // In the absence of a hash for this pref, always trust a NULL value, but |
| 134 // only trust an existing value if the initial hashes dictionary is trusted. | 117 // only trust an existing value if the initial hashes dictionary is trusted. |
| 135 if (!initial_value) | 118 if (!initial_value) |
| 136 return TRUSTED_NULL_VALUE; | 119 return TRUSTED_NULL_VALUE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 153 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: " | 136 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: " |
| 154 << validation_result; | 137 << validation_result; |
| 155 return UNTRUSTED_UNKNOWN_VALUE; | 138 return UNTRUSTED_UNKNOWN_VALUE; |
| 156 } | 139 } |
| 157 | 140 |
| 158 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash( | 141 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash( |
| 159 const std::string& path, | 142 const std::string& path, |
| 160 const base::Value* new_value) { | 143 const base::Value* new_value) { |
| 161 const std::string mac = | 144 const std::string mac = |
| 162 outer_->pref_hash_calculator_.Calculate(path, new_value); | 145 outer_->pref_hash_calculator_.Calculate(path, new_value); |
| 163 (*contents()->GetMutableContents())->SetString(path, mac); | 146 (*contents_->GetMutableContents())->SetString(path, mac); |
| 164 super_mac_dirty_ = true; | 147 super_mac_dirty_ = true; |
| 165 } | 148 } |
| 166 | 149 |
| 167 PrefHashStoreTransaction::ValueState | 150 PrefHashStoreTransaction::ValueState |
| 168 PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue( | 151 PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue( |
| 169 const std::string& path, | 152 const std::string& path, |
| 170 const base::DictionaryValue* initial_split_value, | 153 const base::DictionaryValue* initial_split_value, |
| 171 std::vector<std::string>* invalid_keys) const { | 154 std::vector<std::string>* invalid_keys) const { |
| 172 DCHECK(invalid_keys && invalid_keys->empty()); | 155 DCHECK(invalid_keys && invalid_keys->empty()); |
| 173 | 156 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 | 209 |
| 227 return invalid_keys->empty() | 210 return invalid_keys->empty() |
| 228 ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED) | 211 ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED) |
| 229 : CHANGED; | 212 : CHANGED; |
| 230 } | 213 } |
| 231 | 214 |
| 232 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash( | 215 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash( |
| 233 const std::string& path, | 216 const std::string& path, |
| 234 const base::DictionaryValue* split_value) { | 217 const base::DictionaryValue* split_value) { |
| 235 std::unique_ptr<HashStoreContents::MutableDictionary> mutable_dictionary = | 218 std::unique_ptr<HashStoreContents::MutableDictionary> mutable_dictionary = |
| 236 contents()->GetMutableContents(); | 219 contents_->GetMutableContents(); |
| 237 (*mutable_dictionary)->Remove(path, NULL); | 220 (*mutable_dictionary)->Remove(path, NULL); |
| 238 | 221 |
| 239 if (split_value) { | 222 if (split_value) { |
| 240 std::string keyed_path(path); | 223 std::string keyed_path(path); |
| 241 keyed_path.push_back('.'); | 224 keyed_path.push_back('.'); |
| 242 const size_t common_part_length = keyed_path.length(); | 225 const size_t common_part_length = keyed_path.length(); |
| 243 for (base::DictionaryValue::Iterator it(*split_value); !it.IsAtEnd(); | 226 for (base::DictionaryValue::Iterator it(*split_value); !it.IsAtEnd(); |
| 244 it.Advance()) { | 227 it.Advance()) { |
| 245 // Keep the common part from the old |keyed_path| and replace the key to | 228 // Keep the common part from the old |keyed_path| and replace the key to |
| 246 // get the new |keyed_path|. | 229 // get the new |keyed_path|. |
| 247 keyed_path.replace(common_part_length, std::string::npos, it.key()); | 230 keyed_path.replace(common_part_length, std::string::npos, it.key()); |
| 248 (*mutable_dictionary) | 231 (*mutable_dictionary) |
| 249 ->SetString(keyed_path, outer_->pref_hash_calculator_.Calculate( | 232 ->SetString(keyed_path, outer_->pref_hash_calculator_.Calculate( |
| 250 keyed_path, &it.value())); | 233 keyed_path, &it.value())); |
| 251 } | 234 } |
| 252 } | 235 } |
| 253 super_mac_dirty_ = true; | 236 super_mac_dirty_ = true; |
| 254 } | 237 } |
| 255 | 238 |
| 256 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( | 239 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( |
| 257 const std::string& key, | 240 const std::string& key, |
| 258 std::map<std::string, std::string>* split_macs) const { | 241 std::map<std::string, std::string>* split_macs) const { |
| 259 DCHECK(split_macs); | 242 DCHECK(split_macs); |
| 260 DCHECK(split_macs->empty()); | 243 DCHECK(split_macs->empty()); |
| 261 | 244 |
| 262 const base::DictionaryValue* hashes_dict = contents()->GetContents(); | 245 const base::DictionaryValue* hashes_dict = contents_->GetContents(); |
| 263 const base::DictionaryValue* split_mac_dictionary = NULL; | 246 const base::DictionaryValue* split_mac_dictionary = NULL; |
| 264 if (!hashes_dict || !hashes_dict->GetDictionary(key, &split_mac_dictionary)) | 247 if (!hashes_dict || !hashes_dict->GetDictionary(key, &split_mac_dictionary)) |
| 265 return false; | 248 return false; |
| 266 for (base::DictionaryValue::Iterator it(*split_mac_dictionary); !it.IsAtEnd(); | 249 for (base::DictionaryValue::Iterator it(*split_mac_dictionary); !it.IsAtEnd(); |
| 267 it.Advance()) { | 250 it.Advance()) { |
| 268 std::string mac_string; | 251 std::string mac_string; |
| 269 if (!it.value().GetAsString(&mac_string)) { | 252 if (!it.value().GetAsString(&mac_string)) { |
| 270 NOTREACHED(); | 253 NOTREACHED(); |
| 271 continue; | 254 continue; |
| 272 } | 255 } |
| 273 split_macs->insert(make_pair(it.key(), mac_string)); | 256 split_macs->insert(make_pair(it.key(), mac_string)); |
| 274 } | 257 } |
| 275 return true; | 258 return true; |
| 276 } | 259 } |
| 277 | 260 |
| 278 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::HasHash( | 261 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::HasHash( |
| 279 const std::string& path) const { | 262 const std::string& path) const { |
| 280 const base::DictionaryValue* hashes_dict = contents()->GetContents(); | 263 const base::DictionaryValue* hashes_dict = contents_->GetContents(); |
| 281 return hashes_dict && hashes_dict->Get(path, NULL); | 264 return hashes_dict && hashes_dict->Get(path, NULL); |
| 282 } | 265 } |
| 283 | 266 |
| 284 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash( | 267 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash( |
| 285 const std::string& path, | 268 const std::string& path, |
| 286 const base::Value* hash) { | 269 const base::Value* hash) { |
| 287 DCHECK(hash); | 270 DCHECK(hash); |
| 288 | 271 |
| 289 (*contents()->GetMutableContents())->Set(path, hash->DeepCopy()); | 272 (*contents_->GetMutableContents())->Set(path, hash->DeepCopy()); |
| 290 | 273 |
| 291 if (super_mac_valid_) | 274 if (super_mac_valid_) |
| 292 super_mac_dirty_ = true; | 275 super_mac_dirty_ = true; |
| 293 } | 276 } |
| 294 | 277 |
| 295 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash( | 278 void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash( |
| 296 const std::string& path) { | 279 const std::string& path) { |
| 297 if ((*contents()->GetMutableContents())->RemovePath(path, NULL) && | 280 if ((*contents_->GetMutableContents())->RemovePath(path, NULL) && |
| 298 super_mac_valid_) { | 281 super_mac_valid_) { |
| 299 super_mac_dirty_ = true; | 282 super_mac_dirty_ = true; |
| 300 } | 283 } |
| 301 } | 284 } |
| 302 | 285 |
| 303 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::IsSuperMACValid() const { | 286 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::IsSuperMACValid() const { |
| 304 return super_mac_valid_; | 287 return super_mac_valid_; |
| 305 } | 288 } |
| 306 | 289 |
| 307 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() { | 290 bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() { |
| 308 if (!outer_->use_super_mac_ || super_mac_valid_) | 291 if (!outer_->use_super_mac_ || super_mac_valid_) |
| 309 return false; | 292 return false; |
| 310 super_mac_dirty_ = true; | 293 super_mac_dirty_ = true; |
| 311 return true; | 294 return true; |
| 312 } | 295 } |
| OLD | NEW |