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 |