Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: chrome/browser/sync/engine/syncer_util.cc

Issue 2828021: Take 2: sync changes to support encryption (Closed)
Patch Set: fix flaky password test under valgrind Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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"
17 #include "chrome/browser/sync/protocol/sync.pb.h"
16 #include "chrome/browser/sync/syncable/directory_manager.h" 18 #include "chrome/browser/sync/syncable/directory_manager.h"
17 #include "chrome/browser/sync/syncable/model_type.h" 19 #include "chrome/browser/sync/syncable/model_type.h"
18 #include "chrome/browser/sync/syncable/syncable.h" 20 #include "chrome/browser/sync/syncable/syncable.h"
19 #include "chrome/browser/sync/syncable/syncable_changes_version.h" 21 #include "chrome/browser/sync/syncable/syncable_changes_version.h"
20 #include "chrome/browser/sync/util/sync_types.h" 22 #include "chrome/browser/sync/util/sync_types.h"
21 23
22 using syncable::BASE_VERSION; 24 using syncable::BASE_VERSION;
23 using syncable::Blob; 25 using syncable::Blob;
24 using syncable::CHANGES_VERSION; 26 using syncable::CHANGES_VERSION;
25 using syncable::CREATE; 27 using syncable::CREATE;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 // !local_entry.Good() means we don't have a left behind entry for this 242 // !local_entry.Good() means we don't have a left behind entry for this
241 // ID. We successfully committed before. In the future we should get rid 243 // ID. We successfully committed before. In the future we should get rid
242 // of this system and just have client side generated IDs as a whole. 244 // of this system and just have client side generated IDs as a whole.
243 } 245 }
244 } 246 }
245 247
246 // static 248 // static
247 UpdateAttemptResponse SyncerUtil::AttemptToUpdateEntry( 249 UpdateAttemptResponse SyncerUtil::AttemptToUpdateEntry(
248 syncable::WriteTransaction* const trans, 250 syncable::WriteTransaction* const trans,
249 syncable::MutableEntry* const entry, 251 syncable::MutableEntry* const entry,
250 ConflictResolver* resolver) { 252 ConflictResolver* resolver,
253 Cryptographer* cryptographer) {
251 254
252 CHECK(entry->good()); 255 CHECK(entry->good());
253 if (!entry->Get(IS_UNAPPLIED_UPDATE)) 256 if (!entry->Get(IS_UNAPPLIED_UPDATE))
254 return SUCCESS; // No work to do. 257 return SUCCESS; // No work to do.
255 syncable::Id id = entry->Get(ID); 258 syncable::Id id = entry->Get(ID);
256 259
257 if (entry->Get(IS_UNSYNCED)) { 260 if (entry->Get(IS_UNSYNCED)) {
258 LOG(INFO) << "Skipping update, returning conflict for: " << id 261 LOG(INFO) << "Skipping update, returning conflict for: " << id
259 << " ; it's unsynced."; 262 << " ; it's unsynced.";
260 return CONFLICT; 263 return CONFLICT;
(...skipping 21 matching lines...) Expand all
282 Directory::ChildHandles handles; 285 Directory::ChildHandles handles;
283 trans->directory()->GetChildHandles(trans, id, &handles); 286 trans->directory()->GetChildHandles(trans, id, &handles);
284 if (!handles.empty()) { 287 if (!handles.empty()) {
285 // If we have still-existing children, then we need to deal with 288 // If we have still-existing children, then we need to deal with
286 // them before we can process this change. 289 // them before we can process this change.
287 LOG(INFO) << "Not deleting directory; it's not empty " << *entry; 290 LOG(INFO) << "Not deleting directory; it's not empty " << *entry;
288 return CONFLICT; 291 return CONFLICT;
289 } 292 }
290 } 293 }
291 294
295 // We intercept updates to the Nigori node and update the Cryptographer here
296 // because there is no Nigori ChangeProcessor.
297 const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS);
298 if (specifics.HasExtension(sync_pb::nigori)) {
299 const sync_pb::NigoriSpecifics& nigori =
300 specifics.GetExtension(sync_pb::nigori);
301 if (!nigori.encrypted().blob().empty()) {
302 if (cryptographer->CanDecrypt(nigori.encrypted())) {
303 cryptographer->SetKeys(nigori.encrypted());
304 } else {
305 cryptographer->SetPendingKeys(nigori.encrypted());
306 }
307 }
308 }
309
310 // Only apply updates that we can decrypt. Updates that can't be decrypted yet
311 // will stay in conflict until the user provides a passphrase that lets the
312 // Cryptographer decrypt them.
313 if (!entry->Get(SERVER_IS_DIR) && specifics.HasExtension(sync_pb::password)) {
314 const sync_pb::PasswordSpecifics& password =
315 specifics.GetExtension(sync_pb::password);
316 if (!cryptographer->CanDecrypt(password.encrypted())) {
317 // We can't decrypt this node yet.
318 return CONFLICT;
319 }
320 }
321
292 SyncerUtil::UpdateLocalDataFromServerData(trans, entry); 322 SyncerUtil::UpdateLocalDataFromServerData(trans, entry);
293 323
294 return SUCCESS; 324 return SUCCESS;
295 } 325 }
296 326
297 namespace { 327 namespace {
298 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally, 328 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally,
299 // when the server speaks only the old sync_pb::SyncEntity_BookmarkData-based 329 // when the server speaks only the old sync_pb::SyncEntity_BookmarkData-based
300 // protocol. 330 // protocol.
301 void UpdateBookmarkSpecifics(const string& singleton_tag, 331 void UpdateBookmarkSpecifics(const string& singleton_tag,
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 728
699 if (same_id->Get(SERVER_VERSION) > 0) { 729 if (same_id->Get(SERVER_VERSION) > 0) {
700 // Then we've had an update for this entry before. 730 // Then we've had an update for this entry before.
701 if (is_directory != same_id->Get(SERVER_IS_DIR) || 731 if (is_directory != same_id->Get(SERVER_IS_DIR) ||
702 model_type != same_id->GetServerModelType()) { 732 model_type != same_id->GetServerModelType()) {
703 if (same_id->Get(IS_DEL)) { // If we've deleted the item, we don't care. 733 if (same_id->Get(IS_DEL)) { // If we've deleted the item, we don't care.
704 return VERIFY_SKIP; 734 return VERIFY_SKIP;
705 } else { 735 } else {
706 LOG(ERROR) << "Server update doesn't agree with previous updates. "; 736 LOG(ERROR) << "Server update doesn't agree with previous updates. ";
707 LOG(ERROR) << " Entry: " << *same_id; 737 LOG(ERROR) << " Entry: " << *same_id;
708 LOG(ERROR) << " Update: " << SyncerProtoUtil::SyncEntityDebugString(entr y); 738 LOG(ERROR) << " Update: "
739 << SyncerProtoUtil::SyncEntityDebugString(entry);
709 return VERIFY_FAIL; 740 return VERIFY_FAIL;
710 } 741 }
711 } 742 }
712 743
713 if (!deleted && 744 if (!deleted &&
714 (same_id->Get(SERVER_IS_DEL) || 745 (same_id->Get(SERVER_IS_DEL) ||
715 (!same_id->Get(IS_UNSYNCED) && same_id->Get(IS_DEL) && 746 (!same_id->Get(IS_UNSYNCED) && same_id->Get(IS_DEL) &&
716 same_id->Get(BASE_VERSION) > 0))) { 747 same_id->Get(BASE_VERSION) > 0))) {
717 // An undelete. The latter case in the above condition is for 748 // An undelete. The latter case in the above condition is for
718 // when the server does not give us an update following the 749 // when the server does not give us an update following the
719 // commit of a delete, before undeleting. Undeletion is possible 750 // commit of a delete, before undeleting. Undeletion is possible
720 // in the server's storage backend, so it's possible on the client, 751 // in the server's storage backend, so it's possible on the client,
721 // though not expected to be something that is commonly possible. 752 // though not expected to be something that is commonly possible.
722 VerifyResult result = 753 VerifyResult result =
723 SyncerUtil::VerifyUndelete(trans, entry, same_id); 754 SyncerUtil::VerifyUndelete(trans, entry, same_id);
724 if (VERIFY_UNDECIDED != result) 755 if (VERIFY_UNDECIDED != result)
725 return result; 756 return result;
726 } 757 }
727 } 758 }
728 if (same_id->Get(BASE_VERSION) > 0) { 759 if (same_id->Get(BASE_VERSION) > 0) {
729 // We've committed this entry in the past. 760 // We've committed this entry in the past.
730 if (is_directory != same_id->Get(IS_DIR) || 761 if (is_directory != same_id->Get(IS_DIR) ||
731 model_type != same_id->GetModelType()) { 762 model_type != same_id->GetModelType()) {
732 LOG(ERROR) << "Server update doesn't agree with committed item. "; 763 LOG(ERROR) << "Server update doesn't agree with committed item. ";
733 LOG(ERROR) << " Entry: " << *same_id; 764 LOG(ERROR) << " Entry: " << *same_id;
734 LOG(ERROR) << " Update: " << SyncerProtoUtil::SyncEntityDebugString(entry) ; 765 LOG(ERROR) << " Update: "
766 << SyncerProtoUtil::SyncEntityDebugString(entry);
735 return VERIFY_FAIL; 767 return VERIFY_FAIL;
736 } 768 }
737 if (same_id->Get(BASE_VERSION) == entry.version() && 769 if (same_id->Get(BASE_VERSION) == entry.version() &&
738 !same_id->Get(IS_UNSYNCED) && 770 !same_id->Get(IS_UNSYNCED) &&
739 !SyncerProtoUtil::Compare(*same_id, entry)) { 771 !SyncerProtoUtil::Compare(*same_id, entry)) {
740 // TODO(sync): This constraint needs to be relaxed. For now it's OK to 772 // TODO(sync): This constraint needs to be relaxed. For now it's OK to
741 // fail the verification and deal with it when we ApplyUpdates. 773 // fail the verification and deal with it when we ApplyUpdates.
742 LOG(ERROR) << "Server update doesn't match local data with same " 774 LOG(ERROR) << "Server update doesn't match local data with same "
743 "version. A bug should be filed. Entry: " << *same_id << 775 "version. A bug should be filed. Entry: " << *same_id <<
744 "Update: " << SyncerProtoUtil::SyncEntityDebugString(entry); 776 "Update: " << SyncerProtoUtil::SyncEntityDebugString(entry);
745 return VERIFY_FAIL; 777 return VERIFY_FAIL;
746 } 778 }
747 if (same_id->Get(SERVER_VERSION) > entry.version()) { 779 if (same_id->Get(SERVER_VERSION) > entry.version()) {
748 LOG(WARNING) << "We've already seen a more recent update from the server"; 780 LOG(WARNING) << "We've already seen a more recent update from the server";
749 LOG(WARNING) << " Entry: " << *same_id; 781 LOG(WARNING) << " Entry: " << *same_id;
750 LOG(WARNING) << " Update: " << SyncerProtoUtil::SyncEntityDebugString(entr y); 782 LOG(WARNING) << " Update: "
783 << SyncerProtoUtil::SyncEntityDebugString(entry);
751 return VERIFY_SKIP; 784 return VERIFY_SKIP;
752 } 785 }
753 } 786 }
754 return VERIFY_SUCCESS; 787 return VERIFY_SUCCESS;
755 } 788 }
756 789
757 // Assumes we have an existing entry; verify an update that seems to be 790 // Assumes we have an existing entry; verify an update that seems to be
758 // expressing an 'undelete' 791 // expressing an 'undelete'
759 // static 792 // static
760 VerifyResult SyncerUtil::VerifyUndelete(syncable::WriteTransaction* trans, 793 VerifyResult SyncerUtil::VerifyUndelete(syncable::WriteTransaction* trans,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 865
833 // |update_entry| is considered to be somewhere after |candidate|, so store 866 // |update_entry| is considered to be somewhere after |candidate|, so store
834 // it as the upper bound. 867 // it as the upper bound.
835 closest_sibling = candidate.Get(ID); 868 closest_sibling = candidate.Get(ID);
836 } 869 }
837 870
838 return closest_sibling; 871 return closest_sibling;
839 } 872 }
840 873
841 } // namespace browser_sync 874 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_util.h ('k') | chrome/browser/sync/engine/update_applicator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698