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

Unified Diff: chrome/browser/sync/engine/syncapi.cc

Issue 7108067: [Sync] Ensure cryptographer ready before encrypting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/engine/syncapi.cc
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index ef3f5b43659ceff68594c5bb28996f9b732dd60e..49ccba0a509bd6d44546ba1974083ea286eaeed2 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -202,7 +202,7 @@ UserShare::~UserShare() {}
////////////////////////////////////
// BaseNode member definitions.
-BaseNode::BaseNode() {}
+BaseNode::BaseNode() : password_data_(new sync_pb::PasswordSpecificsData) {}
BaseNode::~BaseNode() {}
@@ -245,8 +245,10 @@ bool BaseNode::DecryptIfNecessary() {
// Passwords have their own legacy encryption structure.
scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics(
specifics, GetTransaction()->GetCryptographer()));
- if (!data.get())
+ if (!data.get()) {
+ LOG(ERROR) << "Failed to decrypt password specifics.";
return false;
+ }
password_data_.swap(data);
return true;
}
@@ -259,9 +261,8 @@ bool BaseNode::DecryptIfNecessary() {
specifics.encrypted();
std::string plaintext_data = GetTransaction()->GetCryptographer()->
DecryptToString(encrypted);
- if (plaintext_data.length() == 0)
- return false;
- if (!unencrypted_data_.ParseFromString(plaintext_data)) {
+ if (plaintext_data.length() == 0 ||
+ !unencrypted_data_.ParseFromString(plaintext_data)) {
LOG(ERROR) << "Failed to decrypt encrypted node of type " <<
syncable::ModelTypeToString(GetModelType()) << ".";
return false;
@@ -404,7 +405,6 @@ const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const {
const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const {
DCHECK_EQ(syncable::PASSWORDS, GetModelType());
- DCHECK(password_data_.get());
return *password_data_;
}
@@ -571,7 +571,9 @@ void WriteNode::SetPasswordSpecifics(
sync_pb::PasswordSpecifics new_value;
if (!cryptographer->Encrypt(data, new_value.mutable_encrypted())) {
- NOTREACHED();
+ NOTREACHED() << "Failed to encrypt password, possibly due to sync node "
+ << "corruption";
+ return;
}
sync_pb::EntitySpecifics entity_specifics;
@@ -1203,6 +1205,12 @@ class SyncManager::SyncInternal
// Whether or not the Nigori node is encrypted using an explicit passphrase.
bool IsUsingExplicitPassphrase();
+ // Update the Cryptographer from the current nigori node.
+ // Note: opens a transaction and can trigger an ON_PASSPHRASE_REQUIRED, so
+ // should only be called after syncapi is fully initialized.
+ // Returns true if cryptographer is ready, false otherwise.
+ bool UpdateCryptographerFromNigori();
+
// Set the datatypes we want to encrypt and encrypt any nodes as necessary.
void EncryptDataTypes(const syncable::ModelTypeSet& encrypted_types);
@@ -1800,50 +1808,42 @@ bool SyncManager::SyncInternal::Init(
void SyncManager::SyncInternal::BootstrapEncryption(
const std::string& restored_key_for_bootstrapping) {
+ // Cryptographer should only be accessed while holding a transaction.
+ ReadTransaction trans(GetUserShare());
+ Cryptographer* cryptographer = trans.GetCryptographer();
+
+ // Set the bootstrap token before bailing out if nigori node is not there.
+ // This could happen if server asked us to migrate nigri.
+ cryptographer->Bootstrap(restored_key_for_bootstrapping);
+}
+
+bool SyncManager::SyncInternal::UpdateCryptographerFromNigori() {
syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
if (!lookup.good()) {
- LOG(INFO) << "BootstrapEncryption: lookup not good so bailing out";
- NOTREACHED();
- return;
+ NOTREACHED() << "BootstrapEncryption: lookup not good so bailing out";
+ return false;
}
+ if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
+ return false; // Should only happen during first time sync.
- sync_pb::NigoriSpecifics nigori;
- syncable::ModelTypeSet encrypted_types;
- {
- // Cryptographer should only be accessed while holding a transaction.
- ReadTransaction trans(GetUserShare());
- Cryptographer* cryptographer = trans.GetCryptographer();
-
- // Set the bootstrap token before bailing out if nigori node is not there.
- // This could happen if server asked us to migrate nigri.
- cryptographer->Bootstrap(restored_key_for_bootstrapping);
-
- if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
- return;
-
- ReadNode node(&trans);
- if (!node.InitByTagLookup(kNigoriTag)) {
- NOTREACHED();
- return;
- }
-
- nigori.CopyFrom(node.GetNigoriSpecifics());
- Cryptographer::UpdateResult result = cryptographer->Update(nigori);
- if (result == Cryptographer::NEEDS_PASSPHRASE) {
- ObserverList<SyncManager::Observer> temp_obs_list;
- CopyObservers(&temp_obs_list);
- FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
- OnPassphraseRequired(sync_api::REASON_DECRYPTION));
- }
+ ReadTransaction trans(GetUserShare());
+ Cryptographer* cryptographer = trans.GetCryptographer();
- // Refresh list of encrypted datatypes.
- encrypted_types = GetEncryptedTypes(&trans);
+ ReadNode node(&trans);
+ if (!node.InitByTagLookup(kNigoriTag)) {
+ NOTREACHED();
+ return false;
+ }
+ Cryptographer::UpdateResult result =
+ cryptographer->Update(node.GetNigoriSpecifics());
+ if (result == Cryptographer::NEEDS_PASSPHRASE) {
+ ObserverList<SyncManager::Observer> temp_obs_list;
+ CopyObservers(&temp_obs_list);
+ FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
+ OnPassphraseRequired(sync_api::REASON_DECRYPTION));
}
-
-
- // Ensure any datatypes that need encryption are encrypted.
- EncryptDataTypes(encrypted_types);
+ return cryptographer->is_ready();
}
void SyncManager::SyncInternal::StartSyncingNormally() {
@@ -2089,14 +2089,19 @@ void SyncManager::SyncInternal::EncryptDataTypes(
WriteTransaction trans(GetUserShare());
WriteNode node(&trans);
if (!node.InitByTagLookup(kNigoriTag)) {
- LOG(ERROR) << "Unable to set encrypted datatypes because Nigori node not "
- << "found.";
- NOTREACHED();
+ NOTREACHED() << "Unable to set encrypted datatypes because Nigori node not "
+ << "found.";
return;
}
Cryptographer* cryptographer = trans.GetCryptographer();
+ if (!cryptographer->is_initialized()) {
+ NOTREACHED() << "Attempting to encrypt datatypes when cryptographer not "
+ << "initialized.";
+ return;
+ }
+
// Update the Nigori node set of encrypted datatypes so other machines notice.
// Note, we merge the current encrypted types with those requested. Once a
// datatypes is marked as needing encryption, it is never unmarked.
@@ -3002,12 +3007,17 @@ UserShare* SyncManager::GetUserShare() const {
return data_->GetUserShare();
}
+void SyncManager::RefreshEncryption() {
+ DCHECK(data_->initialized());
+ if (data_->UpdateCryptographerFromNigori())
+ data_->EncryptDataTypes(syncable::ModelTypeSet());
+}
+
syncable::ModelTypeSet SyncManager::GetEncryptedDataTypes() const {
sync_api::ReadTransaction trans(GetUserShare());
return GetEncryptedTypes(&trans);
}
-
bool SyncManager::HasUnsyncedItems() const {
sync_api::ReadTransaction trans(GetUserShare());
return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0);
« 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