diff options
author | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-20 14:45:46 +0000 |
---|---|---|
committer | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-20 14:45:46 +0000 |
commit | 54e6e79cce665b06c965d58852f0c6362b9ba567 (patch) | |
tree | f02a6f7a81c6887236a9924f617af9c7c8e659d9 /chrome/browser/sync | |
parent | 2aec43172688976197ded8e35a485c7351ff30ed (diff) | |
download | chromium_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.cc | 49 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 10 | ||||
-rw-r--r-- | chrome/browser/sync/sync_setup_flow.cc | 17 | ||||
-rw-r--r-- | chrome/browser/sync/sync_setup_flow.h | 5 |
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); |