OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/sync/engine/syncapi.h" | 5 #include "chrome/browser/sync/engine/syncapi.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <bitset> | 8 #include <bitset> |
9 #include <iomanip> | 9 #include <iomanip> |
10 #include <list> | 10 #include <list> |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 UserShare::UserShare() {} | 198 UserShare::UserShare() {} |
199 | 199 |
200 UserShare::~UserShare() {} | 200 UserShare::~UserShare() {} |
201 | 201 |
202 //////////////////////////////////// | 202 //////////////////////////////////// |
203 // BaseNode member definitions. | 203 // BaseNode member definitions. |
204 | 204 |
205 BaseNode::BaseNode() {} | 205 BaseNode::BaseNode() : password_data_(new sync_pb::PasswordSpecificsData) {} |
206 | 206 |
207 BaseNode::~BaseNode() {} | 207 BaseNode::~BaseNode() {} |
208 | 208 |
209 std::string BaseNode::GenerateSyncableHash( | 209 std::string BaseNode::GenerateSyncableHash( |
210 syncable::ModelType model_type, const std::string& client_tag) { | 210 syncable::ModelType model_type, const std::string& client_tag) { |
211 // blank PB with just the extension in it has termination symbol, | 211 // blank PB with just the extension in it has termination symbol, |
212 // handy for delimiter | 212 // handy for delimiter |
213 sync_pb::EntitySpecifics serialized_type; | 213 sync_pb::EntitySpecifics serialized_type; |
214 syncable::AddDefaultExtensionValue(model_type, &serialized_type); | 214 syncable::AddDefaultExtensionValue(model_type, &serialized_type); |
215 std::string hash_input; | 215 std::string hash_input; |
(...skipping 22 matching lines...) Expand all Loading... |
238 } | 238 } |
239 | 239 |
240 bool BaseNode::DecryptIfNecessary() { | 240 bool BaseNode::DecryptIfNecessary() { |
241 if (GetIsFolder()) return true; // Ignore the top-level datatype folder. | 241 if (GetIsFolder()) return true; // Ignore the top-level datatype folder. |
242 const sync_pb::EntitySpecifics& specifics = | 242 const sync_pb::EntitySpecifics& specifics = |
243 GetEntry()->Get(syncable::SPECIFICS); | 243 GetEntry()->Get(syncable::SPECIFICS); |
244 if (specifics.HasExtension(sync_pb::password)) { | 244 if (specifics.HasExtension(sync_pb::password)) { |
245 // Passwords have their own legacy encryption structure. | 245 // Passwords have their own legacy encryption structure. |
246 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( | 246 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( |
247 specifics, GetTransaction()->GetCryptographer())); | 247 specifics, GetTransaction()->GetCryptographer())); |
248 if (!data.get()) | 248 if (!data.get()) { |
| 249 LOG(ERROR) << "Failed to decrypt password specifics."; |
249 return false; | 250 return false; |
| 251 } |
250 password_data_.swap(data); | 252 password_data_.swap(data); |
251 return true; | 253 return true; |
252 } | 254 } |
253 | 255 |
254 // We assume any node with the encrypted field set has encrypted data. | 256 // We assume any node with the encrypted field set has encrypted data. |
255 if (!specifics.has_encrypted()) | 257 if (!specifics.has_encrypted()) |
256 return true; | 258 return true; |
257 | 259 |
258 const sync_pb::EncryptedData& encrypted = | 260 const sync_pb::EncryptedData& encrypted = |
259 specifics.encrypted(); | 261 specifics.encrypted(); |
260 std::string plaintext_data = GetTransaction()->GetCryptographer()-> | 262 std::string plaintext_data = GetTransaction()->GetCryptographer()-> |
261 DecryptToString(encrypted); | 263 DecryptToString(encrypted); |
262 if (plaintext_data.length() == 0) | 264 if (plaintext_data.length() == 0 || |
263 return false; | 265 !unencrypted_data_.ParseFromString(plaintext_data)) { |
264 if (!unencrypted_data_.ParseFromString(plaintext_data)) { | |
265 LOG(ERROR) << "Failed to decrypt encrypted node of type " << | 266 LOG(ERROR) << "Failed to decrypt encrypted node of type " << |
266 syncable::ModelTypeToString(GetModelType()) << "."; | 267 syncable::ModelTypeToString(GetModelType()) << "."; |
267 return false; | 268 return false; |
268 } | 269 } |
269 return true; | 270 return true; |
270 } | 271 } |
271 | 272 |
272 const sync_pb::EntitySpecifics& BaseNode::GetUnencryptedSpecifics( | 273 const sync_pb::EntitySpecifics& BaseNode::GetUnencryptedSpecifics( |
273 const syncable::Entry* entry) const { | 274 const syncable::Entry* entry) const { |
274 const sync_pb::EntitySpecifics& specifics = entry->Get(SPECIFICS); | 275 const sync_pb::EntitySpecifics& specifics = entry->Get(SPECIFICS); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 return GetEntitySpecifics().GetExtension(sync_pb::bookmark); | 398 return GetEntitySpecifics().GetExtension(sync_pb::bookmark); |
398 } | 399 } |
399 | 400 |
400 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { | 401 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { |
401 DCHECK_EQ(syncable::NIGORI, GetModelType()); | 402 DCHECK_EQ(syncable::NIGORI, GetModelType()); |
402 return GetEntitySpecifics().GetExtension(sync_pb::nigori); | 403 return GetEntitySpecifics().GetExtension(sync_pb::nigori); |
403 } | 404 } |
404 | 405 |
405 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { | 406 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { |
406 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); | 407 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); |
407 DCHECK(password_data_.get()); | |
408 return *password_data_; | 408 return *password_data_; |
409 } | 409 } |
410 | 410 |
411 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { | 411 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { |
412 DCHECK_EQ(syncable::THEMES, GetModelType()); | 412 DCHECK_EQ(syncable::THEMES, GetModelType()); |
413 return GetEntitySpecifics().GetExtension(sync_pb::theme); | 413 return GetEntitySpecifics().GetExtension(sync_pb::theme); |
414 } | 414 } |
415 | 415 |
416 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { | 416 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { |
417 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); | 417 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 scoped_ptr<sync_pb::PasswordSpecificsData> old_plaintext( | 564 scoped_ptr<sync_pb::PasswordSpecificsData> old_plaintext( |
565 DecryptPasswordSpecifics(GetEntry()->Get(SPECIFICS), cryptographer)); | 565 DecryptPasswordSpecifics(GetEntry()->Get(SPECIFICS), cryptographer)); |
566 if (old_plaintext.get() && | 566 if (old_plaintext.get() && |
567 old_plaintext->SerializeAsString() == data.SerializeAsString() && | 567 old_plaintext->SerializeAsString() == data.SerializeAsString() && |
568 cryptographer->CanDecryptUsingDefaultKey(old_ciphertext)) { | 568 cryptographer->CanDecryptUsingDefaultKey(old_ciphertext)) { |
569 return; | 569 return; |
570 } | 570 } |
571 | 571 |
572 sync_pb::PasswordSpecifics new_value; | 572 sync_pb::PasswordSpecifics new_value; |
573 if (!cryptographer->Encrypt(data, new_value.mutable_encrypted())) { | 573 if (!cryptographer->Encrypt(data, new_value.mutable_encrypted())) { |
574 NOTREACHED(); | 574 LOG(ERROR) << "Failed to encrypt password, possibly due to sync node " |
| 575 << "corruption"; |
| 576 return; |
575 } | 577 } |
576 | 578 |
577 sync_pb::EntitySpecifics entity_specifics; | 579 sync_pb::EntitySpecifics entity_specifics; |
578 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value); | 580 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value); |
579 SetEntitySpecifics(entity_specifics); | 581 SetEntitySpecifics(entity_specifics); |
580 } | 582 } |
581 | 583 |
582 void WriteNode::SetThemeSpecifics( | 584 void WriteNode::SetThemeSpecifics( |
583 const sync_pb::ThemeSpecifics& new_value) { | 585 const sync_pb::ThemeSpecifics& new_value) { |
584 sync_pb::EntitySpecifics entity_specifics; | 586 sync_pb::EntitySpecifics entity_specifics; |
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 return; | 1824 return; |
1823 } | 1825 } |
1824 | 1826 |
1825 nigori.CopyFrom(node.GetNigoriSpecifics()); | 1827 nigori.CopyFrom(node.GetNigoriSpecifics()); |
1826 Cryptographer::UpdateResult result = cryptographer->Update(nigori); | 1828 Cryptographer::UpdateResult result = cryptographer->Update(nigori); |
1827 if (result == Cryptographer::NEEDS_PASSPHRASE) { | 1829 if (result == Cryptographer::NEEDS_PASSPHRASE) { |
1828 ObserverList<SyncManager::Observer> temp_obs_list; | 1830 ObserverList<SyncManager::Observer> temp_obs_list; |
1829 CopyObservers(&temp_obs_list); | 1831 CopyObservers(&temp_obs_list); |
1830 FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list, | 1832 FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list, |
1831 OnPassphraseRequired(sync_api::REASON_DECRYPTION)); | 1833 OnPassphraseRequired(sync_api::REASON_DECRYPTION)); |
| 1834 return; |
| 1835 } |
| 1836 |
| 1837 if (!cryptographer->is_ready()) { |
| 1838 NOTREACHED() << "Cryptographer failed to initialize."; |
| 1839 return; |
1832 } | 1840 } |
1833 | 1841 |
1834 // Refresh list of encrypted datatypes. | 1842 // Refresh list of encrypted datatypes. |
1835 encrypted_types = GetEncryptedTypes(&trans); | 1843 encrypted_types = GetEncryptedTypes(&trans); |
1836 } | 1844 } |
1837 | 1845 |
1838 | |
1839 | |
1840 // Ensure any datatypes that need encryption are encrypted. | 1846 // Ensure any datatypes that need encryption are encrypted. |
1841 EncryptDataTypes(encrypted_types); | 1847 EncryptDataTypes(encrypted_types); |
1842 } | 1848 } |
1843 | 1849 |
1844 void SyncManager::SyncInternal::StartSyncingNormally() { | 1850 void SyncManager::SyncInternal::StartSyncingNormally() { |
1845 // Start the syncer thread. This won't actually | 1851 // Start the syncer thread. This won't actually |
1846 // result in any syncing until at least the | 1852 // result in any syncing until at least the |
1847 // DirectoryManager broadcasts the OPENED event, | 1853 // DirectoryManager broadcasts the OPENED event, |
1848 // and a valid server connection is detected. | 1854 // and a valid server connection is detected. |
1849 if (syncer_thread()) // NULL during certain unittests. | 1855 if (syncer_thread()) // NULL during certain unittests. |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 } | 2084 } |
2079 | 2085 |
2080 void SyncManager::SyncInternal::EncryptDataTypes( | 2086 void SyncManager::SyncInternal::EncryptDataTypes( |
2081 const syncable::ModelTypeSet& encrypted_types) { | 2087 const syncable::ModelTypeSet& encrypted_types) { |
2082 VLOG(1) << "Attempting to encrypt datatypes " | 2088 VLOG(1) << "Attempting to encrypt datatypes " |
2083 << syncable::ModelTypeSetToString(encrypted_types); | 2089 << syncable::ModelTypeSetToString(encrypted_types); |
2084 | 2090 |
2085 WriteTransaction trans(GetUserShare()); | 2091 WriteTransaction trans(GetUserShare()); |
2086 WriteNode node(&trans); | 2092 WriteNode node(&trans); |
2087 if (!node.InitByTagLookup(kNigoriTag)) { | 2093 if (!node.InitByTagLookup(kNigoriTag)) { |
2088 LOG(ERROR) << "Unable to set encrypted datatypes because Nigori node not " | 2094 NOTREACHED() << "Unable to set encrypted datatypes because Nigori node not " |
2089 << "found."; | 2095 << "found."; |
2090 NOTREACHED(); | |
2091 return; | 2096 return; |
2092 } | 2097 } |
2093 | 2098 |
2094 Cryptographer* cryptographer = trans.GetCryptographer(); | 2099 Cryptographer* cryptographer = trans.GetCryptographer(); |
2095 | 2100 |
| 2101 if (!cryptographer->is_ready()) { |
| 2102 NOTREACHED() << "Attempting to encrypt datatypes when cryptographer not " |
| 2103 << "ready."; |
| 2104 return; |
| 2105 } |
| 2106 |
2096 // Update the Nigori node set of encrypted datatypes so other machines notice. | 2107 // Update the Nigori node set of encrypted datatypes so other machines notice. |
2097 // Note, we merge the current encrypted types with those requested. Once a | 2108 // Note, we merge the current encrypted types with those requested. Once a |
2098 // datatypes is marked as needing encryption, it is never unmarked. | 2109 // datatypes is marked as needing encryption, it is never unmarked. |
2099 sync_pb::NigoriSpecifics nigori; | 2110 sync_pb::NigoriSpecifics nigori; |
2100 nigori.CopyFrom(node.GetNigoriSpecifics()); | 2111 nigori.CopyFrom(node.GetNigoriSpecifics()); |
2101 syncable::ModelTypeSet current_encrypted_types = GetEncryptedTypes(&trans); | 2112 syncable::ModelTypeSet current_encrypted_types = GetEncryptedTypes(&trans); |
2102 syncable::ModelTypeSet newly_encrypted_types; | 2113 syncable::ModelTypeSet newly_encrypted_types; |
2103 std::set_union(current_encrypted_types.begin(), current_encrypted_types.end(), | 2114 std::set_union(current_encrypted_types.begin(), current_encrypted_types.end(), |
2104 encrypted_types.begin(), encrypted_types.end(), | 2115 encrypted_types.begin(), encrypted_types.end(), |
2105 std::inserter(newly_encrypted_types, | 2116 std::inserter(newly_encrypted_types, |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3027 void SyncManager::TriggerOnIncomingNotificationForTest( | 3038 void SyncManager::TriggerOnIncomingNotificationForTest( |
3028 const syncable::ModelTypeBitSet& model_types) { | 3039 const syncable::ModelTypeBitSet& model_types) { |
3029 syncable::ModelTypePayloadMap model_types_with_payloads = | 3040 syncable::ModelTypePayloadMap model_types_with_payloads = |
3030 syncable::ModelTypePayloadMapFromBitSet(model_types, | 3041 syncable::ModelTypePayloadMapFromBitSet(model_types, |
3031 std::string()); | 3042 std::string()); |
3032 | 3043 |
3033 data_->OnIncomingNotification(model_types_with_payloads); | 3044 data_->OnIncomingNotification(model_types_with_payloads); |
3034 } | 3045 } |
3035 | 3046 |
3036 } // namespace sync_api | 3047 } // namespace sync_api |
OLD | NEW |