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

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

Issue 6537027: Revert 75287 - [Sync] Initial support for encrypting any datatype (no UI hook... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/sync/engine/syncapi.h ('k') | chrome/browser/sync/engine/syncapi_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/syncapi.h" 5 #include "chrome/browser/sync/engine/syncapi.h"
6 6
7 #include <algorithm>
8 #include <bitset> 7 #include <bitset>
9 #include <iomanip> 8 #include <iomanip>
10 #include <list> 9 #include <list>
11 #include <queue>
12 #include <string> 10 #include <string>
13 #include <vector> 11 #include <vector>
14 12
15 #include "base/base64.h" 13 #include "base/base64.h"
16 #include "base/logging.h" 14 #include "base/logging.h"
17 #include "base/message_loop.h" 15 #include "base/message_loop.h"
18 #include "base/observer_list.h" 16 #include "base/observer_list.h"
19 #include "base/scoped_ptr.h" 17 #include "base/scoped_ptr.h"
20 #include "base/sha1.h" 18 #include "base/sha1.h"
21 #include "base/string_number_conversions.h" 19 #include "base/string_number_conversions.h"
(...skipping 25 matching lines...) Expand all
47 #include "chrome/browser/sync/protocol/proto_value_conversions.h" 45 #include "chrome/browser/sync/protocol/proto_value_conversions.h"
48 #include "chrome/browser/sync/protocol/service_constants.h" 46 #include "chrome/browser/sync/protocol/service_constants.h"
49 #include "chrome/browser/sync/protocol/session_specifics.pb.h" 47 #include "chrome/browser/sync/protocol/session_specifics.pb.h"
50 #include "chrome/browser/sync/protocol/sync.pb.h" 48 #include "chrome/browser/sync/protocol/sync.pb.h"
51 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" 49 #include "chrome/browser/sync/protocol/theme_specifics.pb.h"
52 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" 50 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"
53 #include "chrome/browser/sync/sessions/sync_session.h" 51 #include "chrome/browser/sync/sessions/sync_session.h"
54 #include "chrome/browser/sync/sessions/sync_session_context.h" 52 #include "chrome/browser/sync/sessions/sync_session_context.h"
55 #include "chrome/browser/sync/syncable/autofill_migration.h" 53 #include "chrome/browser/sync/syncable/autofill_migration.h"
56 #include "chrome/browser/sync/syncable/directory_manager.h" 54 #include "chrome/browser/sync/syncable/directory_manager.h"
57 #include "chrome/browser/sync/syncable/nigori_util.h"
58 #include "chrome/browser/sync/syncable/syncable.h" 55 #include "chrome/browser/sync/syncable/syncable.h"
59 #include "chrome/browser/sync/util/crypto_helpers.h" 56 #include "chrome/browser/sync/util/crypto_helpers.h"
60 #include "chrome/common/deprecated/event_sys.h" 57 #include "chrome/common/deprecated/event_sys.h"
61 #include "chrome/common/net/gaia/gaia_authenticator.h" 58 #include "chrome/common/net/gaia/gaia_authenticator.h"
62 #include "jingle/notifier/listener/mediator_thread_impl.h" 59 #include "jingle/notifier/listener/mediator_thread_impl.h"
63 #include "jingle/notifier/listener/notification_constants.h" 60 #include "jingle/notifier/listener/notification_constants.h"
64 #include "jingle/notifier/listener/talk_mediator.h" 61 #include "jingle/notifier/listener/talk_mediator.h"
65 #include "jingle/notifier/listener/talk_mediator_impl.h" 62 #include "jingle/notifier/listener/talk_mediator_impl.h"
66 #include "net/base/network_change_notifier.h" 63 #include "net/base/network_change_notifier.h"
67 64
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 185
189 std::string encode_output; 186 std::string encode_output;
190 CHECK(base::Base64Encode(base::SHA1HashString(hash_input), &encode_output)); 187 CHECK(base::Base64Encode(base::SHA1HashString(hash_input), &encode_output));
191 return encode_output; 188 return encode_output;
192 } 189 }
193 190
194 sync_pb::PasswordSpecificsData* DecryptPasswordSpecifics( 191 sync_pb::PasswordSpecificsData* DecryptPasswordSpecifics(
195 const sync_pb::EntitySpecifics& specifics, Cryptographer* crypto) { 192 const sync_pb::EntitySpecifics& specifics, Cryptographer* crypto) {
196 if (!specifics.HasExtension(sync_pb::password)) 193 if (!specifics.HasExtension(sync_pb::password))
197 return NULL; 194 return NULL;
198 const sync_pb::PasswordSpecifics& password_specifics = 195 const sync_pb::EncryptedData& encrypted =
199 specifics.GetExtension(sync_pb::password); 196 specifics.GetExtension(sync_pb::password).encrypted();
200 if (!password_specifics.has_encrypted())
201 return NULL;
202 const sync_pb::EncryptedData& encrypted = password_specifics.encrypted();
203 scoped_ptr<sync_pb::PasswordSpecificsData> data( 197 scoped_ptr<sync_pb::PasswordSpecificsData> data(
204 new sync_pb::PasswordSpecificsData); 198 new sync_pb::PasswordSpecificsData);
205 if (!crypto->Decrypt(encrypted, data.get())) 199 if (!crypto->Decrypt(encrypted, data.get()))
206 return NULL; 200 return NULL;
207 return data.release(); 201 return data.release();
208 } 202 }
209 203
210 bool BaseNode::DecryptIfNecessary(Entry* entry) { 204 bool BaseNode::DecryptIfNecessary(Entry* entry) {
211 if (GetIsFolder()) return true; // Ignore the top-level datatype folder. 205 if (GetIsFolder()) return true; // Ignore the top-level password folder.
212 const sync_pb::EntitySpecifics& specifics = 206 const sync_pb::EntitySpecifics& specifics =
213 entry->Get(syncable::SPECIFICS); 207 entry->Get(syncable::SPECIFICS);
214 if (specifics.HasExtension(sync_pb::password)) { 208 if (specifics.HasExtension(sync_pb::password)) {
215 // Passwords have their own legacy encryption structure.
216 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( 209 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics(
217 specifics, GetTransaction()->GetCryptographer())); 210 specifics, GetTransaction()->GetCryptographer()));
218 if (!data.get()) 211 if (!data.get())
219 return false; 212 return false;
220 password_data_.swap(data); 213 password_data_.swap(data);
221 return true;
222 }
223
224 // We assume any node with the encrypted field set has encrypted data.
225 if (!specifics.has_encrypted())
226 return true;
227
228 const sync_pb::EncryptedData& encrypted =
229 specifics.encrypted();
230 std::string plaintext_data = GetTransaction()->GetCryptographer()->
231 DecryptToString(encrypted);
232 if (plaintext_data.length() == 0)
233 return false;
234 if (!unencrypted_data_.ParseFromString(plaintext_data)) {
235 LOG(ERROR) << "Failed to decrypt encrypted node of type " <<
236 syncable::ModelTypeToString(entry->GetModelType()) << ".";
237 return false;
238 } 214 }
239 return true; 215 return true;
240 } 216 }
241 217
242 const sync_pb::EntitySpecifics& BaseNode::GetUnencryptedSpecifics(
243 const syncable::Entry* entry) const {
244 const sync_pb::EntitySpecifics& specifics = entry->Get(SPECIFICS);
245 if (specifics.has_encrypted()) {
246 DCHECK(syncable::GetModelTypeFromSpecifics(unencrypted_data_) !=
247 syncable::UNSPECIFIED);
248 return unencrypted_data_;
249 } else {
250 DCHECK(syncable::GetModelTypeFromSpecifics(unencrypted_data_) ==
251 syncable::UNSPECIFIED);
252 return specifics;
253 }
254 }
255
256 int64 BaseNode::GetParentId() const { 218 int64 BaseNode::GetParentId() const {
257 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), 219 return IdToMetahandle(GetTransaction()->GetWrappedTrans(),
258 GetEntry()->Get(syncable::PARENT_ID)); 220 GetEntry()->Get(syncable::PARENT_ID));
259 } 221 }
260 222
261 int64 BaseNode::GetId() const { 223 int64 BaseNode::GetId() const {
262 return GetEntry()->Get(syncable::META_HANDLE); 224 return GetEntry()->Get(syncable::META_HANDLE);
263 } 225 }
264 226
265 int64 BaseNode::GetModificationTime() const { 227 int64 BaseNode::GetModificationTime() const {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 output->assign(reinterpret_cast<const unsigned char*>(favicon.data()), 309 output->assign(reinterpret_cast<const unsigned char*>(favicon.data()),
348 reinterpret_cast<const unsigned char*>(favicon.data() + 310 reinterpret_cast<const unsigned char*>(favicon.data() +
349 favicon.length())); 311 favicon.length()));
350 } 312 }
351 313
352 int64 BaseNode::GetExternalId() const { 314 int64 BaseNode::GetExternalId() const {
353 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID); 315 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID);
354 } 316 }
355 317
356 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const { 318 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const {
357 DCHECK_EQ(syncable::APPS, GetModelType()); 319 DCHECK(GetModelType() == syncable::APPS);
358 const sync_pb::EntitySpecifics& unencrypted = 320 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::app);
359 GetUnencryptedSpecifics(GetEntry());
360 return unencrypted.GetExtension(sync_pb::app);
361 } 321 }
362 322
363 const sync_pb::AutofillSpecifics& BaseNode::GetAutofillSpecifics() const { 323 const sync_pb::AutofillSpecifics& BaseNode::GetAutofillSpecifics() const {
364 DCHECK_EQ(syncable::AUTOFILL, GetModelType()); 324 DCHECK(GetModelType() == syncable::AUTOFILL);
365 const sync_pb::EntitySpecifics& unencrypted = 325 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::autofill);
366 GetUnencryptedSpecifics(GetEntry());
367 return unencrypted.GetExtension(sync_pb::autofill);
368 } 326 }
369 327
370 const AutofillProfileSpecifics& BaseNode::GetAutofillProfileSpecifics() const { 328 const AutofillProfileSpecifics& BaseNode::GetAutofillProfileSpecifics() const {
371 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE); 329 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE);
372 const sync_pb::EntitySpecifics& unencrypted = 330 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::autofill_profile);
373 GetUnencryptedSpecifics(GetEntry());
374 return unencrypted.GetExtension(sync_pb::autofill_profile);
375 } 331 }
376 332
377 const sync_pb::BookmarkSpecifics& BaseNode::GetBookmarkSpecifics() const { 333 const sync_pb::BookmarkSpecifics& BaseNode::GetBookmarkSpecifics() const {
378 DCHECK_EQ(syncable::BOOKMARKS, GetModelType()); 334 DCHECK(GetModelType() == syncable::BOOKMARKS);
379 const sync_pb::EntitySpecifics& unencrypted = 335 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::bookmark);
380 GetUnencryptedSpecifics(GetEntry());
381 return unencrypted.GetExtension(sync_pb::bookmark);
382 } 336 }
383 337
384 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { 338 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const {
385 DCHECK_EQ(syncable::NIGORI, GetModelType()); 339 DCHECK(GetModelType() == syncable::NIGORI);
386 const sync_pb::EntitySpecifics& unencrypted = 340 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::nigori);
387 GetUnencryptedSpecifics(GetEntry());
388 return unencrypted.GetExtension(sync_pb::nigori);
389 } 341 }
390 342
391 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { 343 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const {
392 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); 344 DCHECK(GetModelType() == syncable::PASSWORDS);
393 DCHECK(password_data_.get()); 345 DCHECK(password_data_.get());
394 return *password_data_; 346 return *password_data_;
395 } 347 }
396 348
397 const sync_pb::PreferenceSpecifics& BaseNode::GetPreferenceSpecifics() const { 349 const sync_pb::PreferenceSpecifics& BaseNode::GetPreferenceSpecifics() const {
398 DCHECK_EQ(syncable::PREFERENCES, GetModelType()); 350 DCHECK(GetModelType() == syncable::PREFERENCES);
399 const sync_pb::EntitySpecifics& unencrypted = 351 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::preference);
400 GetUnencryptedSpecifics(GetEntry());
401 return unencrypted.GetExtension(sync_pb::preference);
402 } 352 }
403 353
404 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { 354 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const {
405 DCHECK_EQ(syncable::THEMES, GetModelType()); 355 DCHECK(GetModelType() == syncable::THEMES);
406 const sync_pb::EntitySpecifics& unencrypted = 356 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::theme);
407 GetUnencryptedSpecifics(GetEntry());
408 return unencrypted.GetExtension(sync_pb::theme);
409 } 357 }
410 358
411 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { 359 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const {
412 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); 360 DCHECK(GetModelType() == syncable::TYPED_URLS);
413 const sync_pb::EntitySpecifics& unencrypted = 361 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::typed_url);
414 GetUnencryptedSpecifics(GetEntry());
415 return unencrypted.GetExtension(sync_pb::typed_url);
416 } 362 }
417 363
418 const sync_pb::ExtensionSpecifics& BaseNode::GetExtensionSpecifics() const { 364 const sync_pb::ExtensionSpecifics& BaseNode::GetExtensionSpecifics() const {
419 DCHECK_EQ(syncable::EXTENSIONS, GetModelType()); 365 DCHECK(GetModelType() == syncable::EXTENSIONS);
420 const sync_pb::EntitySpecifics& unencrypted = 366 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::extension);
421 GetUnencryptedSpecifics(GetEntry());
422 return unencrypted.GetExtension(sync_pb::extension);
423 } 367 }
424 368
425 const sync_pb::SessionSpecifics& BaseNode::GetSessionSpecifics() const { 369 const sync_pb::SessionSpecifics& BaseNode::GetSessionSpecifics() const {
426 DCHECK_EQ(syncable::SESSIONS, GetModelType()); 370 DCHECK(GetModelType() == syncable::SESSIONS);
427 const sync_pb::EntitySpecifics& unencrypted = 371 return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::session);
428 GetUnencryptedSpecifics(GetEntry());
429 return unencrypted.GetExtension(sync_pb::session);
430 } 372 }
431 373
432 syncable::ModelType BaseNode::GetModelType() const { 374 syncable::ModelType BaseNode::GetModelType() const {
433 return GetEntry()->GetModelType(); 375 return GetEntry()->GetModelType();
434 } 376 }
435 377
436 //////////////////////////////////// 378 ////////////////////////////////////
437 // WriteNode member definitions 379 // WriteNode member definitions
438 void WriteNode::EncryptIfNecessary(sync_pb::EntitySpecifics* unencrypted) {
439 syncable::ModelType type = syncable::GetModelTypeFromSpecifics(*unencrypted);
440 DCHECK_NE(type, syncable::UNSPECIFIED);
441 DCHECK_NE(type, syncable::PASSWORDS); // Passwords use their own encryption.
442 DCHECK_NE(type, syncable::NIGORI); // Nigori is encrypted separately.
443
444 syncable::ModelTypeSet encrypted_types =
445 GetEncryptedDataTypes(GetTransaction()->GetWrappedTrans());
446 if (encrypted_types.count(type) == 0) {
447 // This datatype does not require encryption.
448 return;
449 }
450
451 if (unencrypted->has_encrypted()) {
452 // This specifics is already encrypted, our work is done.
453 LOG(WARNING) << "Attempted to encrypt an already encrypted entity"
454 << " specifics of type " << syncable::ModelTypeToString(type)
455 << ". Dropping.";
456 return;
457 }
458 sync_pb::EntitySpecifics encrypted;
459 syncable::AddDefaultExtensionValue(type, &encrypted);
460 VLOG(2) << "Encrypted specifics of type " << syncable::ModelTypeToString(type)
461 << " with content: " << unencrypted->SerializeAsString() << "\n";
462 if (!GetTransaction()->GetCryptographer()->Encrypt(
463 *unencrypted,
464 encrypted.mutable_encrypted())) {
465 LOG(ERROR) << "Could not encrypt data for node of type " <<
466 syncable::ModelTypeToString(type);
467 NOTREACHED();
468 }
469 unencrypted->CopyFrom(encrypted);
470 }
471
472 void WriteNode::SetIsFolder(bool folder) { 380 void WriteNode::SetIsFolder(bool folder) {
473 if (entry_->Get(syncable::IS_DIR) == folder) 381 if (entry_->Get(syncable::IS_DIR) == folder)
474 return; // Skip redundant changes. 382 return; // Skip redundant changes.
475 383
476 entry_->Put(syncable::IS_DIR, folder); 384 entry_->Put(syncable::IS_DIR, folder);
477 MarkForSyncing(); 385 MarkForSyncing();
478 } 386 }
479 387
480 void WriteNode::SetTitle(const std::wstring& title) { 388 void WriteNode::SetTitle(const std::wstring& title) {
481 std::string server_legal_name; 389 std::string server_legal_name;
482 SyncAPINameToServerName(title, &server_legal_name); 390 SyncAPINameToServerName(title, &server_legal_name);
483 391
484 string old_name = entry_->Get(syncable::NON_UNIQUE_NAME); 392 string old_name = entry_->Get(syncable::NON_UNIQUE_NAME);
485 393
486 if (server_legal_name == old_name) 394 if (server_legal_name == old_name)
487 return; // Skip redundant changes. 395 return; // Skip redundant changes.
488 396
489 entry_->Put(syncable::NON_UNIQUE_NAME, server_legal_name); 397 entry_->Put(syncable::NON_UNIQUE_NAME, server_legal_name);
490 MarkForSyncing(); 398 MarkForSyncing();
491 } 399 }
492 400
493 void WriteNode::SetURL(const GURL& url) { 401 void WriteNode::SetURL(const GURL& url) {
494 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics(); 402 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics();
495 new_value.set_url(url.spec()); 403 new_value.set_url(url.spec());
496 SetBookmarkSpecifics(new_value); 404 SetBookmarkSpecifics(new_value);
497 } 405 }
498 406
499 void WriteNode::SetAppSpecifics( 407 void WriteNode::SetAppSpecifics(
500 const sync_pb::AppSpecifics& new_value) { 408 const sync_pb::AppSpecifics& new_value) {
501 DCHECK_EQ(syncable::APPS, GetModelType()); 409 DCHECK(GetModelType() == syncable::APPS);
502 PutAppSpecificsAndMarkForSyncing(new_value); 410 PutAppSpecificsAndMarkForSyncing(new_value);
503 } 411 }
504 412
505 void WriteNode::SetAutofillSpecifics( 413 void WriteNode::SetAutofillSpecifics(
506 const sync_pb::AutofillSpecifics& new_value) { 414 const sync_pb::AutofillSpecifics& new_value) {
507 DCHECK_EQ(syncable::AUTOFILL, GetModelType()); 415 DCHECK(GetModelType() == syncable::AUTOFILL);
508 PutAutofillSpecificsAndMarkForSyncing(new_value); 416 PutAutofillSpecificsAndMarkForSyncing(new_value);
509 } 417 }
510 418
511 void WriteNode::PutAutofillSpecificsAndMarkForSyncing( 419 void WriteNode::PutAutofillSpecificsAndMarkForSyncing(
512 const sync_pb::AutofillSpecifics& new_value) { 420 const sync_pb::AutofillSpecifics& new_value) {
513 sync_pb::EntitySpecifics entity_specifics; 421 sync_pb::EntitySpecifics entity_specifics;
514 entity_specifics.MutableExtension(sync_pb::autofill)->CopyFrom(new_value); 422 entity_specifics.MutableExtension(sync_pb::autofill)->CopyFrom(new_value);
515 EncryptIfNecessary(&entity_specifics);
516 PutSpecificsAndMarkForSyncing(entity_specifics); 423 PutSpecificsAndMarkForSyncing(entity_specifics);
517 } 424 }
518 425
519 void WriteNode::SetAutofillProfileSpecifics( 426 void WriteNode::SetAutofillProfileSpecifics(
520 const sync_pb::AutofillProfileSpecifics& new_value) { 427 const sync_pb::AutofillProfileSpecifics& new_value) {
521 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE); 428 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE);
522 PutAutofillProfileSpecificsAndMarkForSyncing(new_value); 429 PutAutofillProfileSpecificsAndMarkForSyncing(new_value);
523 } 430 }
524 431
525 void WriteNode::PutAutofillProfileSpecificsAndMarkForSyncing( 432 void WriteNode::PutAutofillProfileSpecificsAndMarkForSyncing(
526 const sync_pb::AutofillProfileSpecifics& new_value) { 433 const sync_pb::AutofillProfileSpecifics& new_value) {
527 sync_pb::EntitySpecifics entity_specifics; 434 sync_pb::EntitySpecifics entity_specifics;
528 entity_specifics.MutableExtension(sync_pb::autofill_profile)->CopyFrom( 435 entity_specifics.MutableExtension(sync_pb::autofill_profile)->CopyFrom(
529 new_value); 436 new_value);
530 EncryptIfNecessary(&entity_specifics);
531 PutSpecificsAndMarkForSyncing(entity_specifics); 437 PutSpecificsAndMarkForSyncing(entity_specifics);
532 } 438 }
533 439
534 void WriteNode::SetBookmarkSpecifics( 440 void WriteNode::SetBookmarkSpecifics(
535 const sync_pb::BookmarkSpecifics& new_value) { 441 const sync_pb::BookmarkSpecifics& new_value) {
536 DCHECK_EQ(syncable::BOOKMARKS, GetModelType()); 442 DCHECK(GetModelType() == syncable::BOOKMARKS);
537 PutBookmarkSpecificsAndMarkForSyncing(new_value); 443 PutBookmarkSpecificsAndMarkForSyncing(new_value);
538 } 444 }
539 445
540 void WriteNode::PutBookmarkSpecificsAndMarkForSyncing( 446 void WriteNode::PutBookmarkSpecificsAndMarkForSyncing(
541 const sync_pb::BookmarkSpecifics& new_value) { 447 const sync_pb::BookmarkSpecifics& new_value) {
542 sync_pb::EntitySpecifics entity_specifics; 448 sync_pb::EntitySpecifics entity_specifics;
543 entity_specifics.MutableExtension(sync_pb::bookmark)->CopyFrom(new_value); 449 entity_specifics.MutableExtension(sync_pb::bookmark)->CopyFrom(new_value);
544 EncryptIfNecessary(&entity_specifics);
545 PutSpecificsAndMarkForSyncing(entity_specifics); 450 PutSpecificsAndMarkForSyncing(entity_specifics);
546 } 451 }
547 452
548 void WriteNode::SetNigoriSpecifics( 453 void WriteNode::SetNigoriSpecifics(
549 const sync_pb::NigoriSpecifics& new_value) { 454 const sync_pb::NigoriSpecifics& new_value) {
550 DCHECK_EQ(syncable::NIGORI, GetModelType()); 455 DCHECK(GetModelType() == syncable::NIGORI);
551 PutNigoriSpecificsAndMarkForSyncing(new_value); 456 PutNigoriSpecificsAndMarkForSyncing(new_value);
552 } 457 }
553 458
554 void WriteNode::PutNigoriSpecificsAndMarkForSyncing( 459 void WriteNode::PutNigoriSpecificsAndMarkForSyncing(
555 const sync_pb::NigoriSpecifics& new_value) { 460 const sync_pb::NigoriSpecifics& new_value) {
556 sync_pb::EntitySpecifics entity_specifics; 461 sync_pb::EntitySpecifics entity_specifics;
557 entity_specifics.MutableExtension(sync_pb::nigori)->CopyFrom(new_value); 462 entity_specifics.MutableExtension(sync_pb::nigori)->CopyFrom(new_value);
558 PutSpecificsAndMarkForSyncing(entity_specifics); 463 PutSpecificsAndMarkForSyncing(entity_specifics);
559 } 464 }
560 465
561 void WriteNode::SetPasswordSpecifics( 466 void WriteNode::SetPasswordSpecifics(
562 const sync_pb::PasswordSpecificsData& data) { 467 const sync_pb::PasswordSpecificsData& data) {
563 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); 468 DCHECK(GetModelType() == syncable::PASSWORDS);
469
564 sync_pb::PasswordSpecifics new_value; 470 sync_pb::PasswordSpecifics new_value;
565 if (!GetTransaction()->GetCryptographer()->Encrypt( 471 if (!GetTransaction()->GetCryptographer()->Encrypt(
566 data, 472 data,
567 new_value.mutable_encrypted())) { 473 new_value.mutable_encrypted())) {
568 NOTREACHED(); 474 NOTREACHED();
569 } 475 }
476
570 PutPasswordSpecificsAndMarkForSyncing(new_value); 477 PutPasswordSpecificsAndMarkForSyncing(new_value);
571 } 478 }
572 479
573 void WriteNode::SetPreferenceSpecifics( 480 void WriteNode::SetPreferenceSpecifics(
574 const sync_pb::PreferenceSpecifics& new_value) { 481 const sync_pb::PreferenceSpecifics& new_value) {
575 DCHECK_EQ(syncable::PREFERENCES, GetModelType()); 482 DCHECK(GetModelType() == syncable::PREFERENCES);
576 PutPreferenceSpecificsAndMarkForSyncing(new_value); 483 PutPreferenceSpecificsAndMarkForSyncing(new_value);
577 } 484 }
578 485
579 void WriteNode::SetThemeSpecifics( 486 void WriteNode::SetThemeSpecifics(
580 const sync_pb::ThemeSpecifics& new_value) { 487 const sync_pb::ThemeSpecifics& new_value) {
581 DCHECK_EQ(syncable::THEMES, GetModelType()); 488 DCHECK(GetModelType() == syncable::THEMES);
582 PutThemeSpecificsAndMarkForSyncing(new_value); 489 PutThemeSpecificsAndMarkForSyncing(new_value);
583 } 490 }
584 491
585 void WriteNode::SetSessionSpecifics( 492 void WriteNode::SetSessionSpecifics(
586 const sync_pb::SessionSpecifics& new_value) { 493 const sync_pb::SessionSpecifics& new_value) {
587 DCHECK_EQ(syncable::SESSIONS, GetModelType()); 494 DCHECK(GetModelType() == syncable::SESSIONS);
588 PutSessionSpecificsAndMarkForSyncing(new_value); 495 PutSessionSpecificsAndMarkForSyncing(new_value);
589 } 496 }
590 497
591 void WriteNode::ResetFromSpecifics() {
592 sync_pb::EntitySpecifics new_data;
593 new_data.CopyFrom(GetUnencryptedSpecifics(GetEntry()));
594 EncryptIfNecessary(&new_data);
595 PutSpecificsAndMarkForSyncing(new_data);
596 }
597 498
598 void WriteNode::PutPasswordSpecificsAndMarkForSyncing( 499 void WriteNode::PutPasswordSpecificsAndMarkForSyncing(
599 const sync_pb::PasswordSpecifics& new_value) { 500 const sync_pb::PasswordSpecifics& new_value) {
600 sync_pb::EntitySpecifics entity_specifics; 501 sync_pb::EntitySpecifics entity_specifics;
601 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value); 502 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value);
602 PutSpecificsAndMarkForSyncing(entity_specifics); 503 PutSpecificsAndMarkForSyncing(entity_specifics);
603 } 504 }
604 505
605 void WriteNode::PutPreferenceSpecificsAndMarkForSyncing( 506 void WriteNode::PutPreferenceSpecificsAndMarkForSyncing(
606 const sync_pb::PreferenceSpecifics& new_value) { 507 const sync_pb::PreferenceSpecifics& new_value) {
607 sync_pb::EntitySpecifics entity_specifics; 508 sync_pb::EntitySpecifics entity_specifics;
608 entity_specifics.MutableExtension(sync_pb::preference)->CopyFrom(new_value); 509 entity_specifics.MutableExtension(sync_pb::preference)->CopyFrom(new_value);
609 EncryptIfNecessary(&entity_specifics);
610 PutSpecificsAndMarkForSyncing(entity_specifics); 510 PutSpecificsAndMarkForSyncing(entity_specifics);
611 } 511 }
612 512
613 void WriteNode::SetTypedUrlSpecifics( 513 void WriteNode::SetTypedUrlSpecifics(
614 const sync_pb::TypedUrlSpecifics& new_value) { 514 const sync_pb::TypedUrlSpecifics& new_value) {
615 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); 515 DCHECK(GetModelType() == syncable::TYPED_URLS);
616 PutTypedUrlSpecificsAndMarkForSyncing(new_value); 516 PutTypedUrlSpecificsAndMarkForSyncing(new_value);
617 } 517 }
618 518
619 void WriteNode::SetExtensionSpecifics( 519 void WriteNode::SetExtensionSpecifics(
620 const sync_pb::ExtensionSpecifics& new_value) { 520 const sync_pb::ExtensionSpecifics& new_value) {
621 DCHECK_EQ(syncable::EXTENSIONS, GetModelType()); 521 DCHECK(GetModelType() == syncable::EXTENSIONS);
622 PutExtensionSpecificsAndMarkForSyncing(new_value); 522 PutExtensionSpecificsAndMarkForSyncing(new_value);
623 } 523 }
624 524
625 void WriteNode::PutAppSpecificsAndMarkForSyncing( 525 void WriteNode::PutAppSpecificsAndMarkForSyncing(
626 const sync_pb::AppSpecifics& new_value) { 526 const sync_pb::AppSpecifics& new_value) {
627 sync_pb::EntitySpecifics entity_specifics; 527 sync_pb::EntitySpecifics entity_specifics;
628 entity_specifics.MutableExtension(sync_pb::app)->CopyFrom(new_value); 528 entity_specifics.MutableExtension(sync_pb::app)->CopyFrom(new_value);
629 EncryptIfNecessary(&entity_specifics);
630 PutSpecificsAndMarkForSyncing(entity_specifics); 529 PutSpecificsAndMarkForSyncing(entity_specifics);
631 } 530 }
632 531
633 void WriteNode::PutThemeSpecificsAndMarkForSyncing( 532 void WriteNode::PutThemeSpecificsAndMarkForSyncing(
634 const sync_pb::ThemeSpecifics& new_value) { 533 const sync_pb::ThemeSpecifics& new_value) {
635 sync_pb::EntitySpecifics entity_specifics; 534 sync_pb::EntitySpecifics entity_specifics;
636 entity_specifics.MutableExtension(sync_pb::theme)->CopyFrom(new_value); 535 entity_specifics.MutableExtension(sync_pb::theme)->CopyFrom(new_value);
637 EncryptIfNecessary(&entity_specifics);
638 PutSpecificsAndMarkForSyncing(entity_specifics); 536 PutSpecificsAndMarkForSyncing(entity_specifics);
639 } 537 }
640 538
641 void WriteNode::PutTypedUrlSpecificsAndMarkForSyncing( 539 void WriteNode::PutTypedUrlSpecificsAndMarkForSyncing(
642 const sync_pb::TypedUrlSpecifics& new_value) { 540 const sync_pb::TypedUrlSpecifics& new_value) {
643 sync_pb::EntitySpecifics entity_specifics; 541 sync_pb::EntitySpecifics entity_specifics;
644 entity_specifics.MutableExtension(sync_pb::typed_url)->CopyFrom(new_value); 542 entity_specifics.MutableExtension(sync_pb::typed_url)->CopyFrom(new_value);
645 EncryptIfNecessary(&entity_specifics);
646 PutSpecificsAndMarkForSyncing(entity_specifics); 543 PutSpecificsAndMarkForSyncing(entity_specifics);
647 } 544 }
648 545
649 void WriteNode::PutExtensionSpecificsAndMarkForSyncing( 546 void WriteNode::PutExtensionSpecificsAndMarkForSyncing(
650 const sync_pb::ExtensionSpecifics& new_value) { 547 const sync_pb::ExtensionSpecifics& new_value) {
651 sync_pb::EntitySpecifics entity_specifics; 548 sync_pb::EntitySpecifics entity_specifics;
652 entity_specifics.MutableExtension(sync_pb::extension)->CopyFrom(new_value); 549 entity_specifics.MutableExtension(sync_pb::extension)->CopyFrom(new_value);
653 EncryptIfNecessary(&entity_specifics);
654 PutSpecificsAndMarkForSyncing(entity_specifics); 550 PutSpecificsAndMarkForSyncing(entity_specifics);
655 } 551 }
656 552
553
657 void WriteNode::PutSessionSpecificsAndMarkForSyncing( 554 void WriteNode::PutSessionSpecificsAndMarkForSyncing(
658 const sync_pb::SessionSpecifics& new_value) { 555 const sync_pb::SessionSpecifics& new_value) {
659 sync_pb::EntitySpecifics entity_specifics; 556 sync_pb::EntitySpecifics entity_specifics;
660 entity_specifics.MutableExtension(sync_pb::session)->CopyFrom(new_value); 557 entity_specifics.MutableExtension(sync_pb::session)->CopyFrom(new_value);
661 EncryptIfNecessary(&entity_specifics);
662 PutSpecificsAndMarkForSyncing(entity_specifics); 558 PutSpecificsAndMarkForSyncing(entity_specifics);
663 } 559 }
664 560
561
665 void WriteNode::PutSpecificsAndMarkForSyncing( 562 void WriteNode::PutSpecificsAndMarkForSyncing(
666 const sync_pb::EntitySpecifics& specifics) { 563 const sync_pb::EntitySpecifics& specifics) {
667 // Skip redundant changes. 564 // Skip redundant changes.
668 if (specifics.SerializeAsString() == 565 if (specifics.SerializeAsString() ==
669 entry_->Get(SPECIFICS).SerializeAsString()) { 566 entry_->Get(SPECIFICS).SerializeAsString()) {
670 return; 567 return;
671 } 568 }
672 entry_->Put(SPECIFICS, specifics); 569 entry_->Put(SPECIFICS, specifics);
673 MarkForSyncing(); 570 MarkForSyncing();
674 } 571 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 DCHECK(!entry_) << "Init called twice"; 616 DCHECK(!entry_) << "Init called twice";
720 if (tag.empty()) 617 if (tag.empty())
721 return false; 618 return false;
722 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), 619 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(),
723 syncable::GET_BY_SERVER_TAG, tag); 620 syncable::GET_BY_SERVER_TAG, tag);
724 if (!entry_->good()) 621 if (!entry_->good())
725 return false; 622 return false;
726 if (entry_->Get(syncable::IS_DEL)) 623 if (entry_->Get(syncable::IS_DEL))
727 return false; 624 return false;
728 syncable::ModelType model_type = GetModelType(); 625 syncable::ModelType model_type = GetModelType();
729 DCHECK_EQ(syncable::NIGORI, model_type); 626 DCHECK(model_type == syncable::NIGORI);
730 return true; 627 return true;
731 } 628 }
732 629
733 void WriteNode::PutModelType(syncable::ModelType model_type) { 630 void WriteNode::PutModelType(syncable::ModelType model_type) {
734 // Set an empty specifics of the appropriate datatype. The presence 631 // Set an empty specifics of the appropriate datatype. The presence
735 // of the specific extension will identify the model type. 632 // of the specific extension will identify the model type.
736 DCHECK(GetModelType() == model_type || 633 DCHECK(GetModelType() == model_type ||
737 GetModelType() == syncable::UNSPECIFIED); // Immutable once set. 634 GetModelType() == syncable::UNSPECIFIED); // Immutable once set.
738 635
739 sync_pb::EntitySpecifics specifics; 636 sync_pb::EntitySpecifics specifics;
740 syncable::AddDefaultExtensionValue(model_type, &specifics); 637 syncable::AddDefaultExtensionValue(model_type, &specifics);
741 PutSpecificsAndMarkForSyncing(specifics); 638 PutSpecificsAndMarkForSyncing(specifics);
742 DCHECK_EQ(model_type, GetModelType()); 639 DCHECK(GetModelType() == model_type);
743 } 640 }
744 641
745 // Create a new node with default properties, and bind this WriteNode to it. 642 // Create a new node with default properties, and bind this WriteNode to it.
746 // Return true on success. 643 // Return true on success.
747 bool WriteNode::InitByCreation(syncable::ModelType model_type, 644 bool WriteNode::InitByCreation(syncable::ModelType model_type,
748 const BaseNode& parent, 645 const BaseNode& parent,
749 const BaseNode* predecessor) { 646 const BaseNode* predecessor) {
750 DCHECK(!entry_) << "Init called twice"; 647 DCHECK(!entry_) << "Init called twice";
751 // |predecessor| must be a child of |parent| or NULL. 648 // |predecessor| must be a child of |parent| or NULL.
752 if (predecessor && predecessor->GetParentId() != parent.GetId()) { 649 if (predecessor && predecessor->GetParentId() != parent.GetId()) {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 } 927 }
1031 928
1032 WriteTransaction::~WriteTransaction() { 929 WriteTransaction::~WriteTransaction() {
1033 delete transaction_; 930 delete transaction_;
1034 } 931 }
1035 932
1036 syncable::BaseTransaction* WriteTransaction::GetWrappedTrans() const { 933 syncable::BaseTransaction* WriteTransaction::GetWrappedTrans() const {
1037 return transaction_; 934 return transaction_;
1038 } 935 }
1039 936
937 SyncManager::ExtraChangeRecordData::~ExtraChangeRecordData() {}
938
1040 SyncManager::ChangeRecord::ChangeRecord() 939 SyncManager::ChangeRecord::ChangeRecord()
1041 : id(kInvalidId), action(ACTION_ADD) {} 940 : id(kInvalidId), action(ACTION_ADD) {}
1042 941
1043 SyncManager::ChangeRecord::~ChangeRecord() {} 942 SyncManager::ChangeRecord::~ChangeRecord() {}
1044 943
1045 DictionaryValue* SyncManager::ChangeRecord::ToValue( 944 DictionaryValue* SyncManager::ChangeRecord::ToValue(
1046 const BaseTransaction* trans) const { 945 const BaseTransaction* trans) const {
1047 DictionaryValue* value = new DictionaryValue(); 946 DictionaryValue* value = new DictionaryValue();
1048 std::string action_str; 947 std::string action_str;
1049 switch (action) { 948 switch (action) {
(...skipping 29 matching lines...) Expand all
1079 } 978 }
1080 } 979 }
1081 if (!node_value) { 980 if (!node_value) {
1082 NOTREACHED(); 981 NOTREACHED();
1083 node_value = Value::CreateNullValue(); 982 node_value = Value::CreateNullValue();
1084 } 983 }
1085 value->Set("node", node_value); 984 value->Set("node", node_value);
1086 return value; 985 return value;
1087 } 986 }
1088 987
1089 SyncManager::ExtraPasswordChangeRecordData::ExtraPasswordChangeRecordData() {}
1090
1091 SyncManager::ExtraPasswordChangeRecordData::ExtraPasswordChangeRecordData( 988 SyncManager::ExtraPasswordChangeRecordData::ExtraPasswordChangeRecordData(
1092 const sync_pb::PasswordSpecificsData& data) 989 const sync_pb::PasswordSpecificsData& data)
1093 : unencrypted_(data) { 990 : unencrypted_(data) {}
1094 }
1095 991
1096 SyncManager::ExtraPasswordChangeRecordData::~ExtraPasswordChangeRecordData() {} 992 SyncManager::ExtraPasswordChangeRecordData::~ExtraPasswordChangeRecordData() {}
1097 993
1098 DictionaryValue* SyncManager::ExtraPasswordChangeRecordData::ToValue() const { 994 DictionaryValue* SyncManager::ExtraPasswordChangeRecordData::ToValue() const {
1099 return browser_sync::PasswordSpecificsDataToValue(unencrypted_); 995 return browser_sync::PasswordSpecificsDataToValue(unencrypted_);
1100 } 996 }
1101 997
1102 const sync_pb::PasswordSpecificsData& 998 const sync_pb::PasswordSpecificsData&
1103 SyncManager::ExtraPasswordChangeRecordData::unencrypted() const { 999 SyncManager::ExtraPasswordChangeRecordData::unencrypted() const {
1104 return unencrypted_; 1000 return unencrypted_;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 // Update the set of enabled sync types. Usually called when the user disables 1053 // Update the set of enabled sync types. Usually called when the user disables
1158 // or enables a sync type. 1054 // or enables a sync type.
1159 void UpdateEnabledTypes(const syncable::ModelTypeSet& types); 1055 void UpdateEnabledTypes(const syncable::ModelTypeSet& types);
1160 1056
1161 // Tell the sync engine to start the syncing process. 1057 // Tell the sync engine to start the syncing process.
1162 void StartSyncing(); 1058 void StartSyncing();
1163 1059
1164 // Whether or not the Nigori node is encrypted using an explicit passphrase. 1060 // Whether or not the Nigori node is encrypted using an explicit passphrase.
1165 bool IsUsingExplicitPassphrase(); 1061 bool IsUsingExplicitPassphrase();
1166 1062
1167 // Set the datatypes we want to encrypt and encrypt any nodes as necessary.
1168 void EncryptDataTypes(const syncable::ModelTypeSet& encrypted_types);
1169
1170 // Try to set the current passphrase to |passphrase|, and record whether 1063 // Try to set the current passphrase to |passphrase|, and record whether
1171 // it is an explicit passphrase or implicitly using gaia in the Nigori 1064 // it is an explicit passphrase or implicitly using gaia in the Nigori
1172 // node. 1065 // node.
1173 void SetPassphrase(const std::string& passphrase, bool is_explicit); 1066 void SetPassphrase(const std::string& passphrase, bool is_explicit);
1174 1067
1175 // Call periodically from a database-safe thread to persist recent changes 1068 // Call periodically from a database-safe thread to persist recent changes
1176 // to the syncapi model. 1069 // to the syncapi model.
1177 void SaveChanges(); 1070 void SaveChanges();
1178 1071
1179 // This listener is called upon completion of a syncable transaction, and 1072 // This listener is called upon completion of a syncable transaction, and
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 // See SyncManager::Shutdown for information. 1128 // See SyncManager::Shutdown for information.
1236 void Shutdown(); 1129 void Shutdown();
1237 1130
1238 // Whether we're initialized to the point of being able to accept changes 1131 // Whether we're initialized to the point of being able to accept changes
1239 // (and hence allow transaction creation). See initialized_ for details. 1132 // (and hence allow transaction creation). See initialized_ for details.
1240 bool initialized() const { 1133 bool initialized() const {
1241 base::AutoLock lock(initialized_mutex_); 1134 base::AutoLock lock(initialized_mutex_);
1242 return initialized_; 1135 return initialized_;
1243 } 1136 }
1244 1137
1245 // If this is a deletion for a password, sets the legacy
1246 // ExtraPasswordChangeRecordData field of |buffer|. Otherwise sets
1247 // |buffer|'s specifics field to contain the unencrypted data.
1248 void SetExtraChangeRecordData(int64 id, 1138 void SetExtraChangeRecordData(int64 id,
1249 syncable::ModelType type, 1139 syncable::ModelType type,
1250 ChangeReorderBuffer* buffer, 1140 ChangeReorderBuffer* buffer,
1251 Cryptographer* cryptographer, 1141 Cryptographer* cryptographer,
1252 const syncable::EntryKernel& original, 1142 const syncable::EntryKernel& original,
1253 bool existed_before, 1143 bool existed_before,
1254 bool exists_now); 1144 bool exists_now);
1255 1145
1256 // Called only by our NetworkChangeNotifier. 1146 // Called only by our NetworkChangeNotifier.
1257 virtual void OnIPAddressChanged(); 1147 virtual void OnIPAddressChanged();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 return true; 1253 return true;
1364 if (a.ref(syncable::PARENT_ID) != b.Get(syncable::PARENT_ID)) 1254 if (a.ref(syncable::PARENT_ID) != b.Get(syncable::PARENT_ID))
1365 return true; 1255 return true;
1366 return false; 1256 return false;
1367 } 1257 }
1368 1258
1369 // Determine if any of the fields made visible to clients of the Sync API 1259 // Determine if any of the fields made visible to clients of the Sync API
1370 // differ between the versions of an entry stored in |a| and |b|. A return 1260 // differ between the versions of an entry stored in |a| and |b|. A return
1371 // value of false means that it should be OK to ignore this change. 1261 // value of false means that it should be OK to ignore this change.
1372 static bool VisiblePropertiesDiffer(const syncable::EntryKernel& a, 1262 static bool VisiblePropertiesDiffer(const syncable::EntryKernel& a,
1373 const syncable::Entry& b, 1263 const syncable::Entry& b) {
1374 Cryptographer* cryptographer) {
1375 syncable::ModelType model_type = b.GetModelType(); 1264 syncable::ModelType model_type = b.GetModelType();
1376 // Suppress updates to items that aren't tracked by any browser model. 1265 // Suppress updates to items that aren't tracked by any browser model.
1377 if (model_type == syncable::UNSPECIFIED || 1266 if (model_type == syncable::UNSPECIFIED ||
1378 model_type == syncable::TOP_LEVEL_FOLDER) { 1267 model_type == syncable::TOP_LEVEL_FOLDER) {
1379 return false; 1268 return false;
1380 } 1269 }
1381 if (a.ref(syncable::NON_UNIQUE_NAME) != b.Get(syncable::NON_UNIQUE_NAME)) 1270 if (a.ref(syncable::NON_UNIQUE_NAME) != b.Get(syncable::NON_UNIQUE_NAME))
1382 return true; 1271 return true;
1383 if (a.ref(syncable::IS_DIR) != b.Get(syncable::IS_DIR)) 1272 if (a.ref(syncable::IS_DIR) != b.Get(syncable::IS_DIR))
1384 return true; 1273 return true;
1385 // Check if data has changed (account for encryption). 1274 if (a.ref(SPECIFICS).SerializeAsString() !=
1386 std::string a_str, b_str; 1275 b.Get(SPECIFICS).SerializeAsString()) {
1387 if (a.ref(SPECIFICS).has_encrypted()) {
1388 const sync_pb::EncryptedData& encrypted = a.ref(SPECIFICS).encrypted();
1389 a_str = cryptographer->DecryptToString(encrypted);
1390 } else {
1391 a_str = a.ref(SPECIFICS).SerializeAsString();
1392 }
1393 if (b.Get(SPECIFICS).has_encrypted()) {
1394 const sync_pb::EncryptedData& encrypted = b.Get(SPECIFICS).encrypted();
1395 b_str = cryptographer->DecryptToString(encrypted);
1396 } else {
1397 b_str = b.Get(SPECIFICS).SerializeAsString();
1398 }
1399 if (a_str != b_str) {
1400 return true; 1276 return true;
1401 } 1277 }
1402 if (VisiblePositionsDiffer(a, b)) 1278 if (VisiblePositionsDiffer(a, b))
1403 return true; 1279 return true;
1404 return false; 1280 return false;
1405 } 1281 }
1406 1282
1407 bool ChangeBuffersAreEmpty() { 1283 bool ChangeBuffersAreEmpty() {
1408 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) { 1284 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
1409 if (!change_buffers_[i].IsEmpty()) 1285 if (!change_buffers_[i].IsEmpty())
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set, 1470 syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
1595 const syncable::AutofillMigrationDebugInfo& info) { 1471 const syncable::AutofillMigrationDebugInfo& info) {
1596 return data_->SetAutofillMigrationDebugInfo(property_to_set, info); 1472 return data_->SetAutofillMigrationDebugInfo(property_to_set, info);
1597 } 1473 }
1598 1474
1599 void SyncManager::SetPassphrase(const std::string& passphrase, 1475 void SyncManager::SetPassphrase(const std::string& passphrase,
1600 bool is_explicit) { 1476 bool is_explicit) {
1601 data_->SetPassphrase(passphrase, is_explicit); 1477 data_->SetPassphrase(passphrase, is_explicit);
1602 } 1478 }
1603 1479
1604 void SyncManager::EncryptDataTypes(
1605 const syncable::ModelTypeSet& encrypted_types) {
1606 data_->EncryptDataTypes(encrypted_types);
1607 }
1608
1609 bool SyncManager::IsUsingExplicitPassphrase() { 1480 bool SyncManager::IsUsingExplicitPassphrase() {
1610 return data_ && data_->IsUsingExplicitPassphrase(); 1481 return data_ && data_->IsUsingExplicitPassphrase();
1611 } 1482 }
1612 1483
1613 bool SyncManager::RequestPause() { 1484 bool SyncManager::RequestPause() {
1614 if (data_->syncer_thread()) 1485 if (data_->syncer_thread())
1615 return data_->syncer_thread()->RequestPause(); 1486 return data_->syncer_thread()->RequestPause();
1616 return false; 1487 return false;
1617 } 1488 }
1618 1489
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 NOTREACHED(); 1575 NOTREACHED();
1705 return; 1576 return;
1706 } 1577 }
1707 1578
1708 if (!lookup->initial_sync_ended_for_type(syncable::NIGORI)) 1579 if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
1709 return; 1580 return;
1710 1581
1711 Cryptographer* cryptographer = share_.dir_manager->cryptographer(); 1582 Cryptographer* cryptographer = share_.dir_manager->cryptographer();
1712 cryptographer->Bootstrap(restored_key_for_bootstrapping); 1583 cryptographer->Bootstrap(restored_key_for_bootstrapping);
1713 1584
1714 sync_pb::NigoriSpecifics nigori; 1585 ReadTransaction trans(GetUserShare());
1715 { 1586 ReadNode node(&trans);
1716 ReadTransaction trans(GetUserShare()); 1587 if (!node.InitByTagLookup(kNigoriTag)) {
1717 ReadNode node(&trans); 1588 NOTREACHED();
1718 if (!node.InitByTagLookup(kNigoriTag)) { 1589 return;
1719 NOTREACHED(); 1590 }
1720 return;
1721 }
1722 1591
1723 nigori.CopyFrom(node.GetNigoriSpecifics()); 1592 const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
1724 if (!nigori.encrypted().blob().empty()) { 1593 if (!nigori.encrypted().blob().empty()) {
1725 if (cryptographer->CanDecrypt(nigori.encrypted())) { 1594 if (cryptographer->CanDecrypt(nigori.encrypted())) {
1726 cryptographer->SetKeys(nigori.encrypted()); 1595 cryptographer->SetKeys(nigori.encrypted());
1727 } else { 1596 } else {
1728 cryptographer->SetPendingKeys(nigori.encrypted()); 1597 cryptographer->SetPendingKeys(nigori.encrypted());
1729 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1598 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
1730 OnPassphraseRequired(true)); 1599 OnPassphraseRequired(true));
1731 }
1732 } 1600 }
1733 } 1601 }
1734
1735 // Refresh list of encrypted datatypes.
1736 syncable::ModelTypeSet encrypted_types =
1737 syncable::GetEncryptedDataTypesFromNigori(nigori);
1738
1739 // Ensure any datatypes that need encryption are encrypted.
1740 EncryptDataTypes(encrypted_types);
1741 } 1602 }
1742 1603
1743 void SyncManager::SyncInternal::StartSyncing() { 1604 void SyncManager::SyncInternal::StartSyncing() {
1744 if (syncer_thread()) // NULL during certain unittests. 1605 if (syncer_thread()) // NULL during certain unittests.
1745 syncer_thread()->Start(); // Start the syncer thread. This won't actually 1606 syncer_thread()->Start(); // Start the syncer thread. This won't actually
1746 // result in any syncing until at least the 1607 // result in any syncing until at least the
1747 // DirectoryManager broadcasts the OPENED event, 1608 // DirectoryManager broadcasts the OPENED event,
1748 // and a valid server connection is detected. 1609 // and a valid server connection is detected.
1749 } 1610 }
1750 1611
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 1702
1842 if (!setup_for_test_mode_) { 1703 if (!setup_for_test_mode_) {
1843 UpdateCredentials(credentials); 1704 UpdateCredentials(credentials);
1844 } 1705 }
1845 return true; 1706 return true;
1846 } 1707 }
1847 1708
1848 void SyncManager::SyncInternal::UpdateCredentials( 1709 void SyncManager::SyncInternal::UpdateCredentials(
1849 const SyncCredentials& credentials) { 1710 const SyncCredentials& credentials) {
1850 DCHECK_EQ(MessageLoop::current(), core_message_loop_); 1711 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
1851 DCHECK_EQ(credentials.email, share_.name); 1712 DCHECK(share_.name == credentials.email);
1852 connection_manager()->set_auth_token(credentials.sync_token); 1713 connection_manager()->set_auth_token(credentials.sync_token);
1853 TalkMediatorLogin(credentials.email, credentials.sync_token); 1714 TalkMediatorLogin(credentials.email, credentials.sync_token);
1854 CheckServerReachable(); 1715 CheckServerReachable();
1855 sync_manager_->RequestNudge(); 1716 sync_manager_->RequestNudge();
1856 } 1717 }
1857 1718
1858 void SyncManager::SyncInternal::UpdateEnabledTypes( 1719 void SyncManager::SyncInternal::UpdateEnabledTypes(
1859 const syncable::ModelTypeSet& types) { 1720 const syncable::ModelTypeSet& types) {
1860 DCHECK_EQ(MessageLoop::current(), core_message_loop_); 1721 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
1861 1722
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 OnPassphraseRequired(true)); 1796 OnPassphraseRequired(true));
1936 return; 1797 return;
1937 } 1798 }
1938 1799
1939 // TODO(tim): If this is the first time the user has entered a passphrase 1800 // TODO(tim): If this is the first time the user has entered a passphrase
1940 // since the protocol changed to store passphrase preferences in the cloud, 1801 // since the protocol changed to store passphrase preferences in the cloud,
1941 // make sure we update this preference. See bug 62103. 1802 // make sure we update this preference. See bug 62103.
1942 if (is_explicit) 1803 if (is_explicit)
1943 SetUsingExplicitPassphrasePrefForMigration(); 1804 SetUsingExplicitPassphrasePrefForMigration();
1944 1805
1945 // Nudge the syncer so that encrypted datatype updates that were waiting for 1806 // Nudge the syncer so that passwords updates that were waiting for this
1946 // this passphrase get applied as soon as possible. 1807 // passphrase get applied as soon as possible.
1947 sync_manager_->RequestNudge(); 1808 sync_manager_->RequestNudge();
1948 } else { 1809 } else {
1949 WriteTransaction trans(GetUserShare()); 1810 WriteTransaction trans(GetUserShare());
1950 WriteNode node(&trans); 1811 WriteNode node(&trans);
1951 if (!node.InitByTagLookup(kNigoriTag)) { 1812 if (!node.InitByTagLookup(kNigoriTag)) {
1952 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1813 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1953 NOTREACHED(); 1814 NOTREACHED();
1954 return; 1815 return;
1955 } 1816 }
1956 1817
1957 // Prevent an implicit SetPassphrase request from changing an explicitly 1818 // Prevent an implicit SetPassphrase request from changing an explicitly
1958 // set passphrase. 1819 // set passphrase.
1959 if (!is_explicit && node.GetNigoriSpecifics().using_explicit_passphrase()) 1820 if (!is_explicit && node.GetNigoriSpecifics().using_explicit_passphrase())
1960 return; 1821 return;
1961 1822
1962 cryptographer->AddKey(params); 1823 cryptographer->AddKey(params);
1963 1824
1964 // TODO(tim): Bug 58231. It would be nice if SetPassphrase didn't require 1825 // TODO(tim): Bug 58231. It would be nice if SetPassphrase didn't require
1965 // messing with the Nigori node, because we can't call SetPassphrase until 1826 // messing with the Nigori node, because we can't call SetPassphrase until
1966 // download conditions are met vs Cryptographer init. It seems like it's 1827 // download conditions are met vs Cryptographer init. It seems like it's
1967 // safe to defer this work. 1828 // safe to defer this work.
1968 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics()); 1829 sync_pb::NigoriSpecifics specifics;
1969 specifics.clear_encrypted();
1970 cryptographer->GetKeys(specifics.mutable_encrypted()); 1830 cryptographer->GetKeys(specifics.mutable_encrypted());
1971 specifics.set_using_explicit_passphrase(is_explicit); 1831 specifics.set_using_explicit_passphrase(is_explicit);
1972 node.SetNigoriSpecifics(specifics); 1832 node.SetNigoriSpecifics(specifics);
1973 ReEncryptEverything(&trans); 1833 ReEncryptEverything(&trans);
1974 } 1834 }
1975 1835
1976 std::string bootstrap_token; 1836 std::string bootstrap_token;
1977 cryptographer->GetBootstrapToken(&bootstrap_token); 1837 cryptographer->GetBootstrapToken(&bootstrap_token);
1978 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1838 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
1979 OnPassphraseAccepted(bootstrap_token)); 1839 OnPassphraseAccepted(bootstrap_token));
1980 } 1840 }
1981 1841
1982 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() { 1842 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() {
1983 ReadTransaction trans(&share_); 1843 ReadTransaction trans(&share_);
1984 ReadNode node(&trans); 1844 ReadNode node(&trans);
1985 if (!node.InitByTagLookup(kNigoriTag)) { 1845 if (!node.InitByTagLookup(kNigoriTag)) {
1986 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1846 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1987 NOTREACHED(); 1847 NOTREACHED();
1988 return false; 1848 return false;
1989 } 1849 }
1990 1850
1991 return node.GetNigoriSpecifics().using_explicit_passphrase(); 1851 return node.GetNigoriSpecifics().using_explicit_passphrase();
1992 } 1852 }
1993 1853
1994 void SyncManager::SyncInternal::EncryptDataTypes( 1854 void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
1995 const syncable::ModelTypeSet& encrypted_types) { 1855 // TODO(tim): bug 59242. We shouldn't lookup by data type and instead use
1996 // Verify the encrypted types are all enabled. 1856 // a protocol flag or existence of an EncryptedData message, but for now,
1997 ModelSafeRoutingInfo routes; 1857 // encryption is on if-and-only-if the type is passwords, and we haven't
1998 registrar_->GetModelSafeRoutingInfo(&routes); 1858 // ironed out the protocol for generic encryption.
1999 for (syncable::ModelTypeSet::const_iterator iter = encrypted_types.begin(); 1859 static const char* passwords_tag = "google_chrome_passwords";
2000 iter != encrypted_types.end(); ++iter) { 1860 ReadNode passwords_root(trans);
2001 if (routes.count(*iter) == 0) { 1861 if (!passwords_root.InitByTagLookup(passwords_tag)) {
2002 LOG(WARNING) << "Attempted to encrypt non-enabled datatype " 1862 LOG(WARNING) << "No passwords to reencrypt.";
2003 << syncable::ModelTypeToString(*iter) << ", dropping type.";
2004 routes.erase(*iter);
2005 }
2006 }
2007
2008 WriteTransaction trans(GetUserShare());
2009 WriteNode node(&trans);
2010 if (!node.InitByTagLookup(kNigoriTag)) {
2011 LOG(ERROR) << "Unable to set encrypted datatypes because Nigori node not "
2012 << "found.";
2013 NOTREACHED();
2014 return; 1863 return;
2015 } 1864 }
2016 1865
2017 // Update the Nigori node set of encrypted datatypes so other machines notice. 1866 int64 child_id = passwords_root.GetFirstChildId();
2018 sync_pb::NigoriSpecifics nigori; 1867 while (child_id != kInvalidId) {
2019 nigori.CopyFrom(node.GetNigoriSpecifics()); 1868 WriteNode child(trans);
2020 syncable::FillNigoriEncryptedTypes(encrypted_types, &nigori); 1869 if (!child.InitByIdLookup(child_id)) {
2021 node.SetNigoriSpecifics(nigori);
2022
2023 // TODO(zea): only reencrypt this datatype? ReEncrypting everything is a
2024 // safer approach, and should not impact anything that is already encrypted
2025 // (redundant changes are ignored).
2026 ReEncryptEverything(&trans);
2027 return;
2028 }
2029
2030 void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
2031 syncable::ModelTypeSet encrypted_types =
2032 GetEncryptedDataTypes(trans->GetWrappedTrans());
2033 ModelSafeRoutingInfo routes;
2034 registrar_->GetModelSafeRoutingInfo(&routes);
2035 std::string tag;
2036 for (syncable::ModelTypeSet::iterator iter = encrypted_types.begin();
2037 iter != encrypted_types.end(); ++iter) {
2038 if (*iter == syncable::PASSWORDS || routes.count(*iter) == 0)
2039 continue;
2040 ReadNode type_root(trans);
2041 tag = syncable::ModelTypeToRootTag(*iter);
2042 if (!type_root.InitByTagLookup(tag)) {
2043 NOTREACHED(); 1870 NOTREACHED();
2044 return; 1871 return;
2045 } 1872 }
2046 1873 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
2047 // Iterate through all children of this datatype. 1874 child_id = child.GetSuccessorId();
2048 std::queue<int64> to_visit;
2049 int64 child_id = type_root.GetFirstChildId();
2050 to_visit.push(child_id);
2051 while (!to_visit.empty()) {
2052 child_id = to_visit.front();
2053 to_visit.pop();
2054 if (child_id == kInvalidId)
2055 continue;
2056
2057 WriteNode child(trans);
2058 if (!child.InitByIdLookup(child_id)) {
2059 NOTREACHED();
2060 return;
2061 }
2062 if (child.GetIsFolder()) {
2063 to_visit.push(child.GetFirstChildId());
2064 } else {
2065 // Rewrite the specifics of the node with encrypted data if necessary.
2066 child.ResetFromSpecifics();
2067 }
2068 to_visit.push(child.GetSuccessorId());
2069 }
2070 } 1875 }
2071
2072 if (routes.count(syncable::PASSWORDS) > 0) {
2073 // Passwords are encrypted with their own legacy scheme.
2074 encrypted_types.insert(syncable::PASSWORDS);
2075 ReadNode passwords_root(trans);
2076 std::string passwords_tag =
2077 syncable::ModelTypeToRootTag(syncable::PASSWORDS);
2078 if (!passwords_root.InitByTagLookup(passwords_tag)) {
2079 LOG(WARNING) << "No passwords to reencrypt.";
2080 return;
2081 }
2082
2083 int64 child_id = passwords_root.GetFirstChildId();
2084 while (child_id != kInvalidId) {
2085 WriteNode child(trans);
2086 if (!child.InitByIdLookup(child_id)) {
2087 NOTREACHED();
2088 return;
2089 }
2090 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
2091 child_id = child.GetSuccessorId();
2092 }
2093 }
2094
2095 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2096 OnEncryptionComplete(encrypted_types));
2097 } 1876 }
2098 1877
2099 SyncManager::~SyncManager() { 1878 SyncManager::~SyncManager() {
2100 delete data_; 1879 delete data_;
2101 } 1880 }
2102 1881
2103 void SyncManager::AddObserver(Observer* observer) { 1882 void SyncManager::AddObserver(Observer* observer) {
2104 data_->AddObserver(observer); 1883 data_->AddObserver(observer);
2105 } 1884 }
2106 1885
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2334 nudge_delay, 2113 nudge_delay,
2335 SyncerThread::kLocal, 2114 SyncerThread::kLocal,
2336 model_types); 2115 model_types);
2337 } 2116 }
2338 } 2117 }
2339 2118
2340 void SyncManager::SyncInternal::SetExtraChangeRecordData(int64 id, 2119 void SyncManager::SyncInternal::SetExtraChangeRecordData(int64 id,
2341 syncable::ModelType type, ChangeReorderBuffer* buffer, 2120 syncable::ModelType type, ChangeReorderBuffer* buffer,
2342 Cryptographer* cryptographer, const syncable::EntryKernel& original, 2121 Cryptographer* cryptographer, const syncable::EntryKernel& original,
2343 bool existed_before, bool exists_now) { 2122 bool existed_before, bool exists_now) {
2344 // If this is a deletion and the datatype was encrypted, we need to decrypt it 2123 // If this is a deletion, attach the entity specifics as extra data
2345 // and attach it to the buffer. 2124 // so that the delete can be processed.
2346 if (!exists_now && existed_before) { 2125 if (!exists_now && existed_before) {
2347 sync_pb::EntitySpecifics original_specifics(original.ref(SPECIFICS)); 2126 buffer->SetSpecificsForId(id, original.ref(SPECIFICS));
2348 if (type == syncable::PASSWORDS) { 2127 if (type == syncable::PASSWORDS) {
2349 // Passwords must use their own legacy ExtraPasswordChangeRecordData. 2128 // Need to dig a bit deeper as passwords are encrypted.
2350 scoped_ptr<sync_pb::PasswordSpecificsData> data( 2129 scoped_ptr<sync_pb::PasswordSpecificsData> data(
2351 DecryptPasswordSpecifics(original_specifics, cryptographer)); 2130 DecryptPasswordSpecifics(original.ref(SPECIFICS), cryptographer));
2352 if (!data.get()) { 2131 if (!data.get()) {
2353 NOTREACHED(); 2132 NOTREACHED();
2354 return; 2133 return;
2355 } 2134 }
2356 buffer->SetExtraDataForId(id, new ExtraPasswordChangeRecordData(*data)); 2135 buffer->SetExtraDataForId(id, new ExtraPasswordChangeRecordData(*data));
2357 } else if (original_specifics.has_encrypted()) {
2358 // All other datatypes can just create a new unencrypted specifics and
2359 // attach it.
2360 const sync_pb::EncryptedData& encrypted = original_specifics.encrypted();
2361 if (!cryptographer->Decrypt(encrypted, &original_specifics)) {
2362 NOTREACHED();
2363 return;
2364 }
2365 } 2136 }
2366 buffer->SetSpecificsForId(id, original_specifics);
2367 } 2137 }
2368 } 2138 }
2369 2139
2370 void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncer( 2140 void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncer(
2371 const syncable::DirectoryChangeEvent& event) { 2141 const syncable::DirectoryChangeEvent& event) {
2372 // We only expect one notification per sync step, so change_buffers_ should 2142 // We only expect one notification per sync step, so change_buffers_ should
2373 // contain no pending entries. 2143 // contain no pending entries.
2374 DCHECK_EQ(event.todo, syncable::DirectoryChangeEvent::CALCULATE_CHANGES); 2144 DCHECK_EQ(event.todo, syncable::DirectoryChangeEvent::CALCULATE_CHANGES);
2375 DCHECK(event.writer == syncable::SYNCER || 2145 DCHECK(event.writer == syncable::SYNCER ||
2376 event.writer == syncable::UNITTEST); 2146 event.writer == syncable::UNITTEST);
(...skipping 10 matching lines...) Expand all
2387 2157
2388 // Omit items that aren't associated with a model. 2158 // Omit items that aren't associated with a model.
2389 syncable::ModelType type = e.GetModelType(); 2159 syncable::ModelType type = e.GetModelType();
2390 if (type == syncable::TOP_LEVEL_FOLDER || type == syncable::UNSPECIFIED) 2160 if (type == syncable::TOP_LEVEL_FOLDER || type == syncable::UNSPECIFIED)
2391 continue; 2161 continue;
2392 2162
2393 if (exists_now && !existed_before) 2163 if (exists_now && !existed_before)
2394 change_buffers_[type].PushAddedItem(id); 2164 change_buffers_[type].PushAddedItem(id);
2395 else if (!exists_now && existed_before) 2165 else if (!exists_now && existed_before)
2396 change_buffers_[type].PushDeletedItem(id); 2166 change_buffers_[type].PushDeletedItem(id);
2397 else if (exists_now && existed_before && 2167 else if (exists_now && existed_before && VisiblePropertiesDiffer(*i, e))
2398 VisiblePropertiesDiffer(*i, e, dir_manager()->cryptographer())) {
2399 change_buffers_[type].PushUpdatedItem(id, VisiblePositionsDiffer(*i, e)); 2168 change_buffers_[type].PushUpdatedItem(id, VisiblePositionsDiffer(*i, e));
2400 }
2401 2169
2402 SetExtraChangeRecordData(id, type, &change_buffers_[type], 2170 SetExtraChangeRecordData(id, type, &change_buffers_[type],
2403 dir_manager()->cryptographer(), *i, 2171 dir_manager()->cryptographer(), *i,
2404 existed_before, exists_now); 2172 existed_before, exists_now);
2405 } 2173 }
2406 } 2174 }
2407 2175
2408 SyncManager::Status SyncManager::SyncInternal::GetStatus() { 2176 SyncManager::Status SyncManager::SyncInternal::GetStatus() {
2409 return allstatus_.status(); 2177 return allstatus_.status();
2410 } 2178 }
2411 2179
2412 void SyncManager::SyncInternal::OnSyncEngineEvent( 2180 void SyncManager::SyncInternal::OnSyncEngineEvent(
2413 const SyncEngineEvent& event) { 2181 const SyncEngineEvent& event) {
2414 if (observers_.size() <= 0) 2182 if (observers_.size() <= 0)
2415 return; 2183 return;
2416 2184
2417 // Only send an event if this is due to a cycle ending and this cycle 2185 // Only send an event if this is due to a cycle ending and this cycle
2418 // concludes a canonical "sync" process; that is, based on what is known 2186 // concludes a canonical "sync" process; that is, based on what is known
2419 // locally we are "all happy" and up-to-date. There may be new changes on 2187 // locally we are "all happy" and up-to-date. There may be new changes on
2420 // the server, but we'll get them on a subsequent sync. 2188 // the server, but we'll get them on a subsequent sync.
2421 // 2189 //
2422 // Notifications are sent at the end of every sync cycle, regardless of 2190 // Notifications are sent at the end of every sync cycle, regardless of
2423 // whether we should sync again. 2191 // whether we should sync again.
2424 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) { 2192 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) {
2425 ModelSafeRoutingInfo enabled_types; 2193 ModelSafeRoutingInfo enabled_types;
2426 registrar_->GetModelSafeRoutingInfo(&enabled_types); 2194 registrar_->GetModelSafeRoutingInfo(&enabled_types);
2427 { 2195 if (enabled_types.count(syncable::PASSWORDS) > 0) {
2428 // Check to see if we need to notify the frontend that we have newly 2196 Cryptographer* cryptographer =
2429 // encrypted types or that we require a passphrase. 2197 GetUserShare()->dir_manager->cryptographer();
2430 sync_api::ReadTransaction trans(GetUserShare()); 2198 if (!cryptographer->is_ready() && !cryptographer->has_pending_keys()) {
2431 sync_api::ReadNode node(&trans); 2199 sync_api::ReadTransaction trans(GetUserShare());
2432 if (!node.InitByTagLookup(kNigoriTag)) { 2200 sync_api::ReadNode node(&trans);
2433 DCHECK(!event.snapshot->is_share_usable); 2201 if (!node.InitByTagLookup(kNigoriTag)) {
2434 return; 2202 DCHECK(!event.snapshot->is_share_usable);
2203 return;
2204 }
2205 const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
2206 if (!nigori.encrypted().blob().empty()) {
2207 DCHECK(!cryptographer->CanDecrypt(nigori.encrypted()));
2208 cryptographer->SetPendingKeys(nigori.encrypted());
2209 }
2435 } 2210 }
2436 const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
2437 syncable::ModelTypeSet encrypted_types =
2438 syncable::GetEncryptedDataTypesFromNigori(nigori);
2439 // If passwords are enabled, they're automatically considered encrypted.
2440 if (enabled_types.count(syncable::PASSWORDS) > 0)
2441 encrypted_types.insert(syncable::PASSWORDS);
2442 if (encrypted_types.size() > 0) {
2443 Cryptographer* cryptographer =
2444 GetUserShare()->dir_manager->cryptographer();
2445 if (!cryptographer->is_ready() && !cryptographer->has_pending_keys()) {
2446 if (!nigori.encrypted().blob().empty()) {
2447 DCHECK(!cryptographer->CanDecrypt(nigori.encrypted()));
2448 cryptographer->SetPendingKeys(nigori.encrypted());
2449 }
2450 }
2451 2211
2452 // If we've completed a sync cycle and the cryptographer isn't ready 2212 // If we've completed a sync cycle and the cryptographer isn't ready yet,
2453 // yet, prompt the user for a passphrase. 2213 // prompt the user for a passphrase.
2454 if (cryptographer->has_pending_keys()) { 2214 if (cryptographer->has_pending_keys()) {
2455 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2215 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2456 OnPassphraseRequired(true)); 2216 OnPassphraseRequired(true));
2457 } else if (!cryptographer->is_ready()) { 2217 } else if (!cryptographer->is_ready()) {
2458 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2218 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2459 OnPassphraseRequired(false)); 2219 OnPassphraseRequired(false));
2460 } else {
2461 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2462 OnEncryptionComplete(encrypted_types));
2463 }
2464 } 2220 }
2465 } 2221 }
2466 2222
2467 if (!initialized()) 2223 if (!initialized())
2468 return; 2224 return;
2469 2225
2470 if (!event.snapshot->has_more_to_sync) { 2226 if (!event.snapshot->has_more_to_sync) {
2471 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2227 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2472 OnSyncCycleCompleted(event.snapshot)); 2228 OnSyncCycleCompleted(event.snapshot));
2473 } 2229 }
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2822 2578
2823 void SyncManager::TriggerOnIncomingNotificationForTest( 2579 void SyncManager::TriggerOnIncomingNotificationForTest(
2824 const syncable::ModelTypeBitSet& model_types) { 2580 const syncable::ModelTypeBitSet& model_types) {
2825 IncomingNotificationData notification_data; 2581 IncomingNotificationData notification_data;
2826 notification_data.service_url = model_types.to_string(); 2582 notification_data.service_url = model_types.to_string();
2827 // Here we rely on the default notification method being SERVER. 2583 // Here we rely on the default notification method being SERVER.
2828 data_->OnIncomingNotification(notification_data); 2584 data_->OnIncomingNotification(notification_data);
2829 } 2585 }
2830 2586
2831 } // namespace sync_api 2587 } // namespace sync_api
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncapi.h ('k') | chrome/browser/sync/engine/syncapi_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698