| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/syncer_util.h" | 5 #include "chrome/browser/sync/engine/syncer_util.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "chrome/browser/sync/engine/conflict_resolver.h" | 11 #include "chrome/browser/sync/engine/conflict_resolver.h" |
| 12 #include "chrome/browser/sync/engine/syncer_proto_util.h" | 12 #include "chrome/browser/sync/engine/syncer_proto_util.h" |
| 13 #include "chrome/browser/sync/engine/syncer_types.h" | 13 #include "chrome/browser/sync/engine/syncer_types.h" |
| 14 #include "chrome/browser/sync/engine/syncproto.h" | 14 #include "chrome/browser/sync/engine/syncproto.h" |
| 15 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" | 15 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" |
| 16 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" | 16 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" |
| 17 #include "chrome/browser/sync/protocol/sync.pb.h" | 17 #include "chrome/browser/sync/protocol/sync.pb.h" |
| 18 #include "chrome/browser/sync/syncable/directory_manager.h" | 18 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 19 #include "chrome/browser/sync/syncable/model_type.h" | 19 #include "chrome/browser/sync/syncable/model_type.h" |
| 20 #include "chrome/browser/sync/syncable/nigori_util.h" |
| 20 #include "chrome/browser/sync/syncable/syncable.h" | 21 #include "chrome/browser/sync/syncable/syncable.h" |
| 21 #include "chrome/browser/sync/syncable/syncable_changes_version.h" | 22 #include "chrome/browser/sync/syncable/syncable_changes_version.h" |
| 22 | 23 |
| 23 using syncable::BASE_VERSION; | 24 using syncable::BASE_VERSION; |
| 24 using syncable::Blob; | 25 using syncable::Blob; |
| 25 using syncable::CHANGES_VERSION; | 26 using syncable::CHANGES_VERSION; |
| 26 using syncable::CREATE; | 27 using syncable::CREATE; |
| 27 using syncable::CREATE_NEW_UPDATE_ITEM; | 28 using syncable::CREATE_NEW_UPDATE_ITEM; |
| 28 using syncable::CTIME; | 29 using syncable::CTIME; |
| 29 using syncable::ComparePathNames; | 30 using syncable::ComparePathNames; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 Directory::ChildHandles handles; | 280 Directory::ChildHandles handles; |
| 280 trans->directory()->GetChildHandles(trans, id, &handles); | 281 trans->directory()->GetChildHandles(trans, id, &handles); |
| 281 if (!handles.empty()) { | 282 if (!handles.empty()) { |
| 282 // If we have still-existing children, then we need to deal with | 283 // If we have still-existing children, then we need to deal with |
| 283 // them before we can process this change. | 284 // them before we can process this change. |
| 284 VLOG(1) << "Not deleting directory; it's not empty " << *entry; | 285 VLOG(1) << "Not deleting directory; it's not empty " << *entry; |
| 285 return CONFLICT; | 286 return CONFLICT; |
| 286 } | 287 } |
| 287 } | 288 } |
| 288 | 289 |
| 289 // We intercept updates to the Nigori node and update the Cryptographer here | 290 // We intercept updates to the Nigori node, update the Cryptographer and |
| 290 // because there is no Nigori ChangeProcessor. | 291 // encrypt any unsynced changes here because there is no Nigori |
| 292 // ChangeProcessor. |
| 291 const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS); | 293 const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS); |
| 292 if (specifics.HasExtension(sync_pb::nigori)) { | 294 if (specifics.HasExtension(sync_pb::nigori)) { |
| 293 const sync_pb::NigoriSpecifics& nigori = | 295 const sync_pb::NigoriSpecifics& nigori = |
| 294 specifics.GetExtension(sync_pb::nigori); | 296 specifics.GetExtension(sync_pb::nigori); |
| 295 if (!nigori.encrypted().blob().empty()) { | 297 if (!nigori.encrypted().blob().empty()) { |
| 296 if (cryptographer->CanDecrypt(nigori.encrypted())) { | 298 if (cryptographer->CanDecrypt(nigori.encrypted())) { |
| 297 cryptographer->SetKeys(nigori.encrypted()); | 299 cryptographer->SetKeys(nigori.encrypted()); |
| 298 } else { | 300 } else { |
| 299 cryptographer->SetPendingKeys(nigori.encrypted()); | 301 cryptographer->SetPendingKeys(nigori.encrypted()); |
| 300 } | 302 } |
| 301 } | 303 } |
| 304 |
| 305 // Make sure any unsynced changes are properly encrypted as necessary. |
| 306 syncable::ModelTypeSet encrypted_types = |
| 307 syncable::GetEncryptedDatatypesFromNigori(nigori); |
| 308 if (!syncable::ProcessUnsyncedChangesForEncryption(trans, encrypted_types, |
| 309 cryptographer)) { |
| 310 // We were unable to encrypt the changes, possibly due to a missing |
| 311 // passphrase. |
| 312 return CONFLICT; |
| 313 } |
| 314 |
| 315 // Note that we don't bother to encrypt any synced data that now requires |
| 316 // encryption. The machine that turned on encryption should encrypt |
| 317 // everything itself. It's possible it could get interrupted during this |
| 318 // process, but we currently reencrypt everything at startup as well, |
| 319 // so as soon as a client is restarted with this datatype encrypted, all the |
| 320 // data should be updated as necessary. |
| 302 } | 321 } |
| 303 | 322 |
| 304 // Only apply updates that we can decrypt. Updates that can't be decrypted yet | 323 // Only apply updates that we can decrypt. Updates that can't be decrypted yet |
| 305 // will stay in conflict until the user provides a passphrase that lets the | 324 // will stay in conflict until the user provides a passphrase that lets the |
| 306 // Cryptographer decrypt them. | 325 // Cryptographer decrypt them. |
| 307 if (!entry->Get(SERVER_IS_DIR) && specifics.HasExtension(sync_pb::password)) { | 326 if (!entry->Get(SERVER_IS_DIR)) { |
| 308 const sync_pb::PasswordSpecifics& password = | 327 if (specifics.has_encrypted() && |
| 309 specifics.GetExtension(sync_pb::password); | 328 !cryptographer->CanDecrypt(specifics.encrypted())) { |
| 310 if (!cryptographer->CanDecrypt(password.encrypted())) { | |
| 311 // We can't decrypt this node yet. | 329 // We can't decrypt this node yet. |
| 312 return CONFLICT; | 330 return CONFLICT; |
| 331 } else if (specifics.HasExtension(sync_pb::password)) { |
| 332 // Passwords use their own legacy encryption scheme. |
| 333 const sync_pb::PasswordSpecifics& password = |
| 334 specifics.GetExtension(sync_pb::password); |
| 335 if (!cryptographer->CanDecrypt(password.encrypted())) { |
| 336 return CONFLICT; |
| 337 } |
| 313 } | 338 } |
| 314 } | 339 } |
| 315 | 340 |
| 316 SyncerUtil::UpdateLocalDataFromServerData(trans, entry); | 341 SyncerUtil::UpdateLocalDataFromServerData(trans, entry); |
| 317 | 342 |
| 318 return SUCCESS; | 343 return SUCCESS; |
| 319 } | 344 } |
| 320 | 345 |
| 321 namespace { | 346 namespace { |
| 322 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally, | 347 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally, |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 | 887 |
| 863 // |update_entry| is considered to be somewhere after |candidate|, so store | 888 // |update_entry| is considered to be somewhere after |candidate|, so store |
| 864 // it as the upper bound. | 889 // it as the upper bound. |
| 865 closest_sibling = candidate.Get(ID); | 890 closest_sibling = candidate.Get(ID); |
| 866 } | 891 } |
| 867 | 892 |
| 868 return closest_sibling; | 893 return closest_sibling; |
| 869 } | 894 } |
| 870 | 895 |
| 871 } // namespace browser_sync | 896 } // namespace browser_sync |
| OLD | NEW |