| 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 |