summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync
diff options
context:
space:
mode:
authortim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-20 14:45:46 +0000
committertim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-20 14:45:46 +0000
commit54e6e79cce665b06c965d58852f0c6362b9ba567 (patch)
treef02a6f7a81c6887236a9924f617af9c7c8e659d9 /chrome/browser/sync
parent2aec43172688976197ded8e35a485c7351ff30ed (diff)
downloadchromium_src-54e6e79cce665b06c965d58852f0c6362b9ba567.zip
chromium_src-54e6e79cce665b06c965d58852f0c6362b9ba567.tar.gz
chromium_src-54e6e79cce665b06c965d58852f0c6362b9ba567.tar.bz2
sync: fix passphrase bootstrapping and more.
BUG=59684, 59631 TEST=Enable password sync on two clients with default gaia passphrase. Change it to use a secondary on one of the clients, wait for error to surface on other client, restart chrome, notice "sync error", enter passphrase, have things work out. Also, password sync integration test. Review URL: http://codereview.chromium.org/3803012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63212 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync')
-rw-r--r--chrome/browser/sync/engine/syncapi.cc49
-rw-r--r--chrome/browser/sync/profile_sync_service.cc10
-rw-r--r--chrome/browser/sync/sync_setup_flow.cc17
-rw-r--r--chrome/browser/sync/sync_setup_flow.h5
4 files changed, 70 insertions, 11 deletions
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index 4f1b938..45ea2ca 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -1156,6 +1156,15 @@ class SyncManager::SyncInternal
void ReEncryptEverything(WriteTransaction* trans);
+ // Initializes (bootstraps) the Cryptographer if NIGORI has finished
+ // initial sync so that it can immediately start encrypting / decrypting.
+ // If the restored key is incompatible with the current version of the NIGORI
+ // node (which could happen if a restart occurred just after an update to
+ // NIGORI was downloaded and the user must enter a new passphrase to decrypt)
+ // then we will raise OnPassphraseRequired and set pending keys for
+ // decryption. Otherwise, the cryptographer is made ready (is_ready()).
+ void BootstrapEncryption(const std::string& restored_key_for_bootstrapping);
+
// We couple the DirectoryManager and username together in a UserShare member
// so we can return a handle to share_ to clients of the API for use when
// constructing any transaction type.
@@ -1330,8 +1339,6 @@ bool SyncManager::SyncInternal::Init(
setup_for_test_mode_ = setup_for_test_mode;
share_.dir_manager.reset(new DirectoryManager(database_location));
- share_.dir_manager->cryptographer()->Bootstrap(
- restored_key_for_bootstrapping);
connection_manager_.reset(new SyncAPIServerConnectionManager(
sync_server_and_path, port, use_ssl, user_agent, post_factory));
@@ -1363,7 +1370,43 @@ bool SyncManager::SyncInternal::Init(
syncer_thread_ = new SyncerThread(context);
}
- return SignIn(credentials);
+ bool signed_in = SignIn(credentials);
+
+ // Do this once the directory is opened.
+ BootstrapEncryption(restored_key_for_bootstrapping);
+ return signed_in;
+}
+
+void SyncManager::SyncInternal::BootstrapEncryption(
+ const std::string& restored_key_for_bootstrapping) {
+ syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
+ if (!lookup.good()) {
+ NOTREACHED();
+ return;
+ }
+
+ if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
+ return;
+
+ Cryptographer* cryptographer = share_.dir_manager->cryptographer();
+ cryptographer->Bootstrap(restored_key_for_bootstrapping);
+
+ ReadTransaction trans(GetUserShare());
+ ReadNode node(&trans);
+ if (!node.InitByTagLookup(kNigoriTag)) {
+ NOTREACHED();
+ return;
+ }
+
+ const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
+ if (!nigori.encrypted().blob().empty()) {
+ if (cryptographer->CanDecrypt(nigori.encrypted())) {
+ cryptographer->SetKeys(nigori.encrypted());
+ } else {
+ cryptographer->SetPendingKeys(nigori.encrypted());
+ observer_->OnPassphraseRequired();
+ }
+ }
}
void SyncManager::SyncInternal::StartSyncing() {
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 5b92998..c5d5139 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -335,6 +335,8 @@ void ProfileSyncService::ClearPreferences() {
pref_service->ClearPref(prefs::kSyncLastSyncedTime);
pref_service->ClearPref(prefs::kSyncHasSetupCompleted);
pref_service->ClearPref(prefs::kEncryptionBootstrapToken);
+ pref_service->ClearPref(prefs::kSyncUsingSecondaryPassphrase);
+
// TODO(nick): The current behavior does not clear e.g. prefs::kSyncBookmarks.
// Is that really what we want?
pref_service->ScheduleSavePersistentPrefs();
@@ -979,12 +981,11 @@ void ProfileSyncService::Observe(NotificationType type,
break;
}
- if (SetupInProgress()) {
+ if (WizardIsVisible()) {
wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE);
- } else {
- UpdateAuthErrorState(GoogleServiceAuthError(
- GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
}
+
+ FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
break;
}
case NotificationType::SYNC_DATA_TYPES_UPDATED: {
@@ -1004,6 +1005,7 @@ void ProfileSyncService::Observe(NotificationType type,
FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
observed_passphrase_required_ = false;
+
wizard_.Step(SyncSetupWizard::DONE);
break;
}
diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc
index 7e9f325..ee211f5 100644
--- a/chrome/browser/sync/sync_setup_flow.cc
+++ b/chrome/browser/sync/sync_setup_flow.cc
@@ -396,6 +396,16 @@ void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service,
}
// static
+void SyncSetupFlow::GetArgsForEnterPassphrase(
+ const ProfileSyncService* service, DictionaryValue* args) {
+ args->SetString("iframeToShow", "passphrase");
+ if (service->IsUsingSecondaryPassphrase())
+ args->SetString("mode", "enter");
+ else
+ args->SetString("mode", "gaia");
+}
+
+// static
void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service,
DictionaryValue* args) {
args->SetString("iframeToShow", "configure");
@@ -522,10 +532,7 @@ void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) {
}
case SyncSetupWizard::ENTER_PASSPHRASE: {
DictionaryValue args;
- if (service_->IsUsingSecondaryPassphrase())
- args.SetString("mode", "enter");
- else
- args.SetString("mode", "gaia");
+ SyncSetupFlow::GetArgsForEnterPassphrase(service_, &args);
flow_handler_->ShowPassphraseEntry(args);
break;
}
@@ -587,6 +594,8 @@ SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service,
SyncSetupFlow::GetArgsForGaiaLogin(service, &args);
else if (start == SyncSetupWizard::CONFIGURE)
SyncSetupFlow::GetArgsForConfigure(service, &args);
+ else if (start == SyncSetupWizard::ENTER_PASSPHRASE)
+ SyncSetupFlow::GetArgsForEnterPassphrase(service, &args);
std::string json_args;
base::JSONWriter::Write(&args, false, &json_args);
diff --git a/chrome/browser/sync/sync_setup_flow.h b/chrome/browser/sync/sync_setup_flow.h
index 292d01b..2879146 100644
--- a/chrome/browser/sync/sync_setup_flow.h
+++ b/chrome/browser/sync/sync_setup_flow.h
@@ -58,6 +58,11 @@ class SyncSetupFlow : public HtmlDialogUIDelegate {
ProfileSyncService* service,
DictionaryValue* args);
+ // Fills |args| for the enter passphrase screen.
+ static void GetArgsForEnterPassphrase(
+ const ProfileSyncService* service,
+ DictionaryValue* args);
+
// Triggers a state machine transition to advance_state.
void Advance(SyncSetupWizard::State advance_state);