summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-26 11:54:26 +0000
committerzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-26 11:54:26 +0000
commit25ae16e2002fa7b2da8803d0690c44c9c5d5d355 (patch)
tree1971d53e29559a49ba3266adf6cd27f158bf7171
parent225b6d78753087dbd3ca0c2aa8a985109ef2fb1a (diff)
downloadchromium_src-25ae16e2002fa7b2da8803d0690c44c9c5d5d355.zip
chromium_src-25ae16e2002fa7b2da8803d0690c44c9c5d5d355.tar.gz
chromium_src-25ae16e2002fa7b2da8803d0690c44c9c5d5d355.tar.bz2
[Sync] Refactor passphrase state handling
We now have an enum describing passphrase state, and cache the current value on the UI thread via a new OnPassphraseStateChanged method. Additionally, we log the OnPassphraseStateChanged event in the debug log info. BUG=139848, 129665 Review URL: https://chromiumcodereview.appspot.com/10824410 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153397 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc37
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h11
-rw-r--r--sync/internal_api/debug_info_event_listener.cc4
-rw-r--r--sync/internal_api/debug_info_event_listener.h1
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer.cc13
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer.h1
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer_unittest.cc14
-rw-r--r--sync/internal_api/public/sync_encryption_handler.h23
-rw-r--r--sync/internal_api/public/util/sync_string_conversions.cc32
-rw-r--r--sync/internal_api/public/util/sync_string_conversions.h1
-rw-r--r--sync/internal_api/sync_encryption_handler_impl.cc42
-rw-r--r--sync/internal_api/sync_encryption_handler_impl.h9
-rw-r--r--sync/internal_api/sync_encryption_handler_impl_unittest.cc1
-rw-r--r--sync/internal_api/sync_manager_impl.cc4
-rw-r--r--sync/internal_api/sync_manager_impl.h1
-rw-r--r--sync/internal_api/sync_manager_impl_unittest.cc53
-rw-r--r--sync/protocol/client_debug_info.proto9
-rw-r--r--sync/test/fake_sync_encryption_handler.cc10
-rw-r--r--sync/test/fake_sync_encryption_handler.h4
19 files changed, 194 insertions, 76 deletions
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 679dad94..adfa8f6 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -48,6 +48,7 @@
#include "sync/internal_api/public/read_transaction.h"
#include "sync/internal_api/public/sync_manager_factory.h"
#include "sync/internal_api/public/util/experiments.h"
+#include "sync/internal_api/public/util/sync_string_conversions.h"
#include "sync/notifier/sync_notifier.h"
#include "sync/protocol/encryption.pb.h"
#include "sync/protocol/sync.pb.h"
@@ -115,6 +116,7 @@ class SyncBackendHost::Core
virtual void OnEncryptionComplete() OVERRIDE;
virtual void OnCryptographerStateChanged(
syncer::Cryptographer* cryptographer) OVERRIDE;
+ virtual void OnPassphraseStateChanged(syncer::PassphraseState state) OVERRIDE;
// syncer::SyncNotifierObserver implementation.
virtual void OnNotificationsEnabled() OVERRIDE;
@@ -325,7 +327,8 @@ SyncBackendHost::SyncBackendHost(
profile_->GetRequestContext()),
content::GetUserAgent(GURL()),
invalidator_storage),
- frontend_(NULL) {
+ frontend_(NULL),
+ cached_passphrase_state_(syncer::IMPLICIT_PASSPHRASE) {
}
SyncBackendHost::SyncBackendHost(Profile* profile)
@@ -340,7 +343,8 @@ SyncBackendHost::SyncBackendHost(Profile* profile)
profile_->GetRequestContext()),
content::GetUserAgent(GURL()),
base::WeakPtr<syncer::InvalidationStateTracker>()),
- frontend_(NULL) {
+ frontend_(NULL),
+ cached_passphrase_state_(syncer::IMPLICIT_PASSPHRASE) {
}
SyncBackendHost::~SyncBackendHost() {
@@ -762,11 +766,11 @@ bool SyncBackendHost::IsUsingExplicitPassphrase() {
// otherwise we have no idea what kind of passphrase we are using. This will
// NOTREACH in sync_manager and return false if we fail to load the nigori
// node.
- // TODO(zea): cache this value here, then make the encryption handler
- // NonThreadSafe and only accessible from the sync thread.
- return IsNigoriEnabled() &&
- core_->sync_manager()->GetEncryptionHandler()->
- IsUsingExplicitPassphrase();
+ // TODO(zea): expose whether the custom passphrase is a frozen implicit
+ // passphrase or not to provide better messaging.
+ return IsNigoriEnabled() && (
+ cached_passphrase_state_ == syncer::CUSTOM_PASSPHRASE ||
+ cached_passphrase_state_ == syncer::FROZEN_IMPLICIT_PASSPHRASE);
}
bool SyncBackendHost::IsCryptographerReady(
@@ -1025,6 +1029,14 @@ void SyncBackendHost::Core::OnCryptographerStateChanged(
// Do nothing.
}
+void SyncBackendHost::Core::OnPassphraseStateChanged(
+ syncer::PassphraseState state) {
+ host_.Call(
+ FROM_HERE,
+ &SyncBackendHost::HandlePassphraseStateChangedOnFrontendLoop,
+ state);
+}
+
void SyncBackendHost::Core::OnActionableError(
const syncer::SyncProtocolError& sync_error) {
if (!sync_loop_)
@@ -1166,6 +1178,9 @@ void SyncBackendHost::Core::DoAssociateNigori() {
sync_manager_->GetEncryptionHandler()->AddObserver(this);
sync_manager_->GetEncryptionHandler()->Init();
host_.Call(FROM_HERE,
+ &SyncBackendHost::HandlePassphraseStateChangedOnFrontendLoop,
+ sync_manager_->GetEncryptionHandler()->GetPassphraseState());
+ host_.Call(FROM_HERE,
&SyncBackendHost::HandleInitializationCompletedOnFrontendLoop,
true);
}
@@ -1519,6 +1534,14 @@ void SyncBackendHost::NotifyEncryptionComplete() {
frontend_->OnEncryptionComplete();
}
+void SyncBackendHost::HandlePassphraseStateChangedOnFrontendLoop(
+ syncer::PassphraseState state) {
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_);
+ DVLOG(1) << "Passphrase state changed to "
+ << syncer::PassphraseStateToString(state);
+ cached_passphrase_state_ = state;
+}
+
void SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop() {
if (!frontend_)
return;
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index 3a42a6a..6e616b6 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -454,6 +454,11 @@ class SyncBackendHost : public BackendDataTypeConfigurer {
// Invoked when sync finishes encrypting new datatypes.
void NotifyEncryptionComplete();
+ // Invoked when the passphrase state has changed. Caches the passphrase state
+ // for later use on the UI thread.
+ void HandlePassphraseStateChangedOnFrontendLoop(
+ syncer::PassphraseState state);
+
void HandleStopSyncingPermanentlyOnFrontendLoop();
// Dispatched to from OnConnectionStatusChange to handle updating
@@ -522,6 +527,12 @@ class SyncBackendHost : public BackendDataTypeConfigurer {
// were cached.
sync_pb::EncryptedData cached_pending_keys_;
+ // The state of the passphrase required to decrypt the bag of encryption keys
+ // in the nigori node. Updated whenever a new nigori node arrives or the user
+ // manually changes their passphrase state. Cached so we can synchronously
+ // check it from the UI thread.
+ syncer::PassphraseState cached_passphrase_state_;
+
// UI-thread cache of the last SyncSessionSnapshot received from syncapi.
syncer::sessions::SyncSessionSnapshot last_snapshot_;
diff --git a/sync/internal_api/debug_info_event_listener.cc b/sync/internal_api/debug_info_event_listener.cc
index c48b7c9..f59a2fa 100644
--- a/sync/internal_api/debug_info_event_listener.cc
+++ b/sync/internal_api/debug_info_event_listener.cc
@@ -96,6 +96,10 @@ void DebugInfoEventListener::OnCryptographerStateChanged(
cryptographer_ready_ = cryptographer->is_ready();
}
+void DebugInfoEventListener::OnPassphraseStateChanged(PassphraseState state) {
+ CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_STATE_CHANGED);
+}
+
void DebugInfoEventListener::OnActionableError(
const SyncProtocolError& sync_error) {
CreateAndAddEvent(sync_pb::DebugEventInfo::ACTIONABLE_ERROR);
diff --git a/sync/internal_api/debug_info_event_listener.h b/sync/internal_api/debug_info_event_listener.h
index 252f64b..b4ace66 100644
--- a/sync/internal_api/debug_info_event_listener.h
+++ b/sync/internal_api/debug_info_event_listener.h
@@ -57,6 +57,7 @@ class DebugInfoEventListener : public SyncManager::Observer,
virtual void OnEncryptionComplete() OVERRIDE;
virtual void OnCryptographerStateChanged(
Cryptographer* cryptographer) OVERRIDE;
+ virtual void OnPassphraseStateChanged(PassphraseState state) OVERRIDE;
// Sync manager events.
void OnNudgeFromDatatype(ModelType datatype);
diff --git a/sync/internal_api/js_sync_encryption_handler_observer.cc b/sync/internal_api/js_sync_encryption_handler_observer.cc
index 1e76575..2db5475 100644
--- a/sync/internal_api/js_sync_encryption_handler_observer.cc
+++ b/sync/internal_api/js_sync_encryption_handler_observer.cc
@@ -95,6 +95,19 @@ void JsSyncEncryptionHandlerObserver::OnCryptographerStateChanged(
JsEventDetails(&details));
}
+void JsSyncEncryptionHandlerObserver::OnPassphraseStateChanged(
+ PassphraseState state) {
+ if (!event_handler_.IsInitialized()) {
+ return;
+ }
+ DictionaryValue details;
+ details.SetString("passphraseState",
+ PassphraseStateToString(state));
+ HandleJsEvent(FROM_HERE,
+ "onPassphraseStateChanged",
+ JsEventDetails(&details));
+}
+
void JsSyncEncryptionHandlerObserver::HandleJsEvent(
const tracked_objects::Location& from_here,
const std::string& name, const JsEventDetails& details) {
diff --git a/sync/internal_api/js_sync_encryption_handler_observer.h b/sync/internal_api/js_sync_encryption_handler_observer.h
index 4562e5f..6099517 100644
--- a/sync/internal_api/js_sync_encryption_handler_observer.h
+++ b/sync/internal_api/js_sync_encryption_handler_observer.h
@@ -43,6 +43,7 @@ class JsSyncEncryptionHandlerObserver : public SyncEncryptionHandler::Observer {
virtual void OnEncryptionComplete() OVERRIDE;
virtual void OnCryptographerStateChanged(
Cryptographer* cryptographer) OVERRIDE;
+ virtual void OnPassphraseStateChanged(PassphraseState state) OVERRIDE;
private:
void HandleJsEvent(const tracked_objects::Location& from_here,
diff --git a/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc b/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc
index 70ebab7..d42f0e5 100644
--- a/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc
+++ b/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc
@@ -154,5 +154,19 @@ TEST_F(JsSyncEncryptionHandlerObserverTest, OnCryptographerStateChanged) {
PumpLoop();
}
+TEST_F(JsSyncEncryptionHandlerObserverTest, OnPassphraseStateChanged) {
+ InSequence dummy;
+
+ DictionaryValue passphrase_state_details;
+ passphrase_state_details.SetString("passphraseState", "IMPLICIT_PASSPHRASE");
+ EXPECT_CALL(mock_js_event_handler_,
+ HandleJsEvent("onPassphraseStateChanged",
+ HasDetailsAsDictionary(passphrase_state_details)));
+
+ js_sync_encryption_handler_observer_.OnPassphraseStateChanged(
+ IMPLICIT_PASSPHRASE);
+ PumpLoop();
+}
+
} // namespace
} // namespace syncer
diff --git a/sync/internal_api/public/sync_encryption_handler.h b/sync/internal_api/public/sync_encryption_handler.h
index 52e2ca3..eefffdf 100644
--- a/sync/internal_api/public/sync_encryption_handler.h
+++ b/sync/internal_api/public/sync_encryption_handler.h
@@ -29,9 +29,20 @@ enum PassphraseRequiredReason {
// decryption.
};
+// The different states for the encryption passphrase. These control if and how
+// the user should be prompted for a decryption passphrase.
+enum PassphraseState {
+ IMPLICIT_PASSPHRASE = 0, // GAIA-based passphrase (deprecated).
+ KEYSTORE_PASSPHRASE = 1, // Keystore passphrase.
+ FROZEN_IMPLICIT_PASSPHRASE = 2, // Frozen GAIA passphrase.
+ CUSTOM_PASSPHRASE = 3, // User-provided passphrase.
+};
+
// Sync's encryption handler. Handles tracking encrypted types, ensuring the
// cryptographer encrypts with the proper key and has the most recent keybag,
// and keeps the nigori node up to date.
+// Implementations of this class must be assumed to be non-thread-safe. All
+// methods must be invoked on the sync thread.
class SyncEncryptionHandler {
public:
// All Observer methods are done synchronously from within a transaction and
@@ -93,6 +104,9 @@ class SyncEncryptionHandler {
// Used primarily for debugging.
virtual void OnCryptographerStateChanged(Cryptographer* cryptographer) = 0;
+ // The passprhase state has changed.
+ virtual void OnPassphraseStateChanged(PassphraseState state) = 0;
+
protected:
virtual ~Observer();
};
@@ -100,8 +114,7 @@ class SyncEncryptionHandler {
SyncEncryptionHandler();
virtual ~SyncEncryptionHandler();
- // Add/Remove SyncEncryptionHandler::Observer's.
- // Must be called from sync thread.
+ // Add/Remove SyncEncryptionHandler::Observers.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
@@ -138,9 +151,9 @@ class SyncEncryptionHandler {
// types are encrypted.
virtual bool EncryptEverythingEnabled() const = 0;
- // Whether the account requires a user-provided passphrase to decrypt
- // encrypted data.
- virtual bool IsUsingExplicitPassphrase() const = 0;
+ // Returns the current state of the passphrase needed to decrypt the
+ // bag of encryption keys in the nigori node.
+ virtual PassphraseState GetPassphraseState() const = 0;
// The set of types that are always encrypted.
static ModelTypeSet SensitiveTypes();
diff --git a/sync/internal_api/public/util/sync_string_conversions.cc b/sync/internal_api/public/util/sync_string_conversions.cc
index 9614203..7e404b7 100644
--- a/sync/internal_api/public/util/sync_string_conversions.cc
+++ b/sync/internal_api/public/util/sync_string_conversions.cc
@@ -4,16 +4,15 @@
#include "sync/internal_api/public/util/sync_string_conversions.h"
+#define ENUM_CASE(x) case x: return #x
+
namespace syncer {
const char* ConnectionStatusToString(ConnectionStatus status) {
switch (status) {
- case CONNECTION_OK:
- return "CONNECTION_OK";
- case CONNECTION_AUTH_ERROR:
- return "CONNECTION_AUTH_ERROR";
- case CONNECTION_SERVER_ERROR:
- return "CONNECTION_SERVER_ERROR";
+ ENUM_CASE(CONNECTION_OK);
+ ENUM_CASE(CONNECTION_AUTH_ERROR);
+ ENUM_CASE(CONNECTION_SERVER_ERROR);
default:
NOTREACHED();
return "INVALID_CONNECTION_STATUS";
@@ -24,16 +23,25 @@ const char* ConnectionStatusToString(ConnectionStatus status) {
const char* PassphraseRequiredReasonToString(
PassphraseRequiredReason reason) {
switch (reason) {
- case REASON_PASSPHRASE_NOT_REQUIRED:
- return "REASON_PASSPHRASE_NOT_REQUIRED";
- case REASON_ENCRYPTION:
- return "REASON_ENCRYPTION";
- case REASON_DECRYPTION:
- return "REASON_DECRYPTION";
+ ENUM_CASE(REASON_PASSPHRASE_NOT_REQUIRED);
+ ENUM_CASE(REASON_ENCRYPTION);
+ ENUM_CASE(REASON_DECRYPTION);
default:
NOTREACHED();
return "INVALID_REASON";
}
}
+const char* PassphraseStateToString(PassphraseState state) {
+ switch (state) {
+ ENUM_CASE(IMPLICIT_PASSPHRASE);
+ ENUM_CASE(KEYSTORE_PASSPHRASE);
+ ENUM_CASE(FROZEN_IMPLICIT_PASSPHRASE);
+ ENUM_CASE(CUSTOM_PASSPHRASE);
+ default:
+ NOTREACHED();
+ return "INVALID_PASSPHRASE_STATE";
+ }
+}
+
} // namespace syncer
diff --git a/sync/internal_api/public/util/sync_string_conversions.h b/sync/internal_api/public/util/sync_string_conversions.h
index 1c55898..9430e38 100644
--- a/sync/internal_api/public/util/sync_string_conversions.h
+++ b/sync/internal_api/public/util/sync_string_conversions.h
@@ -16,6 +16,7 @@ const char* ConnectionStatusToString(ConnectionStatus status);
const char* PassphraseRequiredReasonToString(
PassphraseRequiredReason reason);
+const char* PassphraseStateToString(PassphraseState state);
}
#endif // SYNC_INTERNAL_API_PUBLIC_UTIL_SYNC_STRING_CONVERSIONS_H_
diff --git a/sync/internal_api/sync_encryption_handler_impl.cc b/sync/internal_api/sync_encryption_handler_impl.cc
index b9f5ed1..c632ba57 100644
--- a/sync/internal_api/sync_encryption_handler_impl.cc
+++ b/sync/internal_api/sync_encryption_handler_impl.cc
@@ -40,8 +40,8 @@ static const int kNigoriOverwriteLimit = 10;
SyncEncryptionHandlerImpl::Vault::Vault(
Encryptor* encryptor,
ModelTypeSet encrypted_types)
- : cryptographer(encryptor),
- encrypted_types(encrypted_types) {
+ : cryptographer(encryptor),
+ encrypted_types(encrypted_types) {
}
SyncEncryptionHandlerImpl::Vault::~Vault() {
@@ -54,7 +54,7 @@ SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
user_share_(user_share),
vault_unsafe_(encryptor, SensitiveTypes()),
encrypt_everything_(false),
- explicit_passphrase_(false),
+ passphrase_state_(IMPLICIT_PASSPHRASE),
nigori_overwrite_count_(0) {
}
@@ -390,12 +390,9 @@ bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
return encrypt_everything_;
}
-bool SyncEncryptionHandlerImpl::IsUsingExplicitPassphrase() const {
- // TODO(zea): this is called from the UI thread, so we have to have a
- // transaction while accessing it. Add an OnPassphraseTypeChanged observer
- // and have the SBH cache the value on the UI thread.
- ReadTransaction trans(FROM_HERE, user_share_);
- return explicit_passphrase_;
+PassphraseState SyncEncryptionHandlerImpl::GetPassphraseState() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return passphrase_state_;
}
// Note: this is called from within a syncable transaction, so we need to post
@@ -517,10 +514,15 @@ bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
const sync_pb::NigoriSpecifics& nigori,
syncable::BaseTransaction* const trans) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "Applying nigori node update.";
bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
trans);
- if (nigori.using_explicit_passphrase())
- explicit_passphrase_ = true;
+ if (nigori.using_explicit_passphrase() &&
+ passphrase_state_ != CUSTOM_PASSPHRASE) {
+ passphrase_state_ = CUSTOM_PASSPHRASE;
+ FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
+ OnPassphraseStateChanged(passphrase_state_));
+ }
Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
bool nigori_needs_new_keys = false;
@@ -567,7 +569,8 @@ bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
// Check if the current local encryption state is stricter/newer than the
// nigori state. If so, we need to overwrite the nigori node with the local
// state.
- if (nigori.using_explicit_passphrase() != explicit_passphrase_ ||
+ bool explicit_passphrase = passphrase_state_ == CUSTOM_PASSPHRASE;
+ if (nigori.using_explicit_passphrase() != explicit_passphrase ||
nigori.encrypt_everything() != encrypt_everything_ ||
nigori_types_need_update ||
nigori_needs_new_keys) {
@@ -683,7 +686,7 @@ void SyncEncryptionHandlerImpl::FinishSetPassphrase(
// set the passphrase (for example if we need to preserve the new GAIA
// passphrase).
if (!bootstrap_token.empty()) {
- DVLOG(1) << "Bootstrap token updated.";
+ DVLOG(1) << "Passphrase bootstrap token updated.";
FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
OnBootstrapTokenUpdated(bootstrap_token));
}
@@ -706,8 +709,6 @@ void SyncEncryptionHandlerImpl::FinishSetPassphrase(
return;
}
- FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
- OnPassphraseAccepted());
DCHECK(cryptographer.is_ready());
sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics());
@@ -715,10 +716,19 @@ void SyncEncryptionHandlerImpl::FinishSetPassphrase(
// the same.
if (!cryptographer.GetKeys(specifics.mutable_encrypted()))
NOTREACHED();
- explicit_passphrase_ = is_explicit;
+ if (is_explicit && passphrase_state_ != CUSTOM_PASSPHRASE) {
+ passphrase_state_ = CUSTOM_PASSPHRASE;
+ FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
+ OnPassphraseStateChanged(passphrase_state_));
+ }
specifics.set_using_explicit_passphrase(is_explicit);
nigori_node->SetNigoriSpecifics(specifics);
+ // Must do this after OnPassphraseStateChanged, in order to ensure the PSS
+ // checks the passphrase state after it has been set.
+ FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
+ OnPassphraseAccepted());
+
// Does nothing if everything is already encrypted.
ReEncryptEverything(trans);
}
diff --git a/sync/internal_api/sync_encryption_handler_impl.h b/sync/internal_api/sync_encryption_handler_impl.h
index 8966da7..8f3b7ac 100644
--- a/sync/internal_api/sync_encryption_handler_impl.h
+++ b/sync/internal_api/sync_encryption_handler_impl.h
@@ -57,9 +57,7 @@ class SyncEncryptionHandlerImpl
virtual void SetDecryptionPassphrase(const std::string& passphrase) OVERRIDE;
virtual void EnableEncryptEverything() OVERRIDE;
virtual bool EncryptEverythingEnabled() const OVERRIDE;
- // Can be called from any thread.
- // TODO(zea): enforce this is only called on sync thread.
- virtual bool IsUsingExplicitPassphrase() const OVERRIDE;
+ virtual PassphraseState GetPassphraseState() const OVERRIDE;
// NigoriHandler implementation.
// Note: all methods are invoked while the caller holds a transaction.
@@ -180,8 +178,9 @@ class SyncEncryptionHandlerImpl
// thread.
// Whether all current and future types should be encrypted.
bool encrypt_everything_;
- // Whether the user is using a custom passphrase for encryption.
- bool explicit_passphrase_;
+ // The current state of the passphrase required to decrypt the encryption
+ // keys stored in the nigori node.
+ PassphraseState passphrase_state_;
// The number of times we've automatically (i.e. not via SetPassphrase or
// conflict resolver) updated the nigori's encryption keys in this chrome
diff --git a/sync/internal_api/sync_encryption_handler_impl_unittest.cc b/sync/internal_api/sync_encryption_handler_impl_unittest.cc
index b37afa4..c6ea24f 100644
--- a/sync/internal_api/sync_encryption_handler_impl_unittest.cc
+++ b/sync/internal_api/sync_encryption_handler_impl_unittest.cc
@@ -45,6 +45,7 @@ class SyncEncryptionHandlerObserverMock
void(ModelTypeSet, bool)); // NOLINT
MOCK_METHOD0(OnEncryptionComplete, void()); // NOLINT
MOCK_METHOD1(OnCryptographerStateChanged, void(Cryptographer*)); // NOLINT
+ MOCK_METHOD1(OnPassphraseStateChanged, void(PassphraseState)); // NOLINT
};
} // namespace
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc
index ded97f5..9e832e7 100644
--- a/sync/internal_api/sync_manager_impl.cc
+++ b/sync/internal_api/sync_manager_impl.cc
@@ -558,6 +558,10 @@ void SyncManagerImpl::OnCryptographerStateChanged(
allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys());
}
+void SyncManagerImpl::OnPassphraseStateChanged(PassphraseState state) {
+ // Does nothing.
+}
+
void SyncManagerImpl::StartSyncingNormally(
const ModelSafeRoutingInfo& routing_info) {
// Start the sync scheduler.
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index b0ed231..3a44969 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -128,6 +128,7 @@ class SyncManagerImpl : public SyncManager,
virtual void OnEncryptionComplete() OVERRIDE;
virtual void OnCryptographerStateChanged(
Cryptographer* cryptographer) OVERRIDE;
+ virtual void OnPassphraseStateChanged(PassphraseState state) OVERRIDE;
// Return the currently active (validated) username for use with syncable
// types.
diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
index 36e3da1..b64ecc3 100644
--- a/sync/internal_api/sync_manager_impl_unittest.cc
+++ b/sync/internal_api/sync_manager_impl_unittest.cc
@@ -698,6 +698,7 @@ class SyncEncryptionHandlerObserverMock
void(ModelTypeSet, bool)); // NOLINT
MOCK_METHOD0(OnEncryptionComplete, void()); // NOLINT
MOCK_METHOD1(OnCryptographerStateChanged, void(Cryptographer*)); // NOLINT
+ MOCK_METHOD1(OnPassphraseStateChanged, void(PassphraseState)); // NOLINT
};
} // namespace
@@ -1504,6 +1505,8 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithData) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase", true);
EXPECT_TRUE(EncryptEverythingEnabledForTest());
@@ -1544,8 +1547,8 @@ TEST_F(SyncManagerTest, SetInitialGaiaPass) {
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
false);
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1578,8 +1581,8 @@ TEST_F(SyncManagerTest, UpdateGaiaPass) {
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
false);
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1622,11 +1625,13 @@ TEST_F(SyncManagerTest, SetPassphraseWithPassword) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
true);
- EXPECT_TRUE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(CUSTOM_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1678,8 +1683,8 @@ TEST_F(SyncManagerTest, SupplyPendingGAIAPass) {
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
sync_manager_.GetEncryptionHandler()->SetDecryptionPassphrase("passphrase2");
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1734,8 +1739,8 @@ TEST_F(SyncManagerTest, SupplyPendingOldGAIAPass) {
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_gaia",
false);
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
testing::Mock::VerifyAndClearExpectations(&encryption_observer_);
{
@@ -1756,8 +1761,8 @@ TEST_F(SyncManagerTest, SupplyPendingOldGAIAPass) {
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"old_gaia",
false);
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
Cryptographer* cryptographer = trans.GetCryptographer();
@@ -1806,9 +1811,11 @@ TEST_F(SyncManagerTest, SupplyPendingExplicitPass) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetDecryptionPassphrase("explicit");
- EXPECT_TRUE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(CUSTOM_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1850,8 +1857,8 @@ TEST_F(SyncManagerTest, SupplyPendingGAIAPassUserProvided) {
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"passphrase",
false);
- EXPECT_FALSE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(IMPLICIT_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -1879,11 +1886,13 @@ TEST_F(SyncManagerTest, SetPassphraseWithEmptyPasswordNode) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
true);
- EXPECT_TRUE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(CUSTOM_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_FALSE(EncryptEverythingEnabledForTest());
{
ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare());
@@ -2103,6 +2112,8 @@ TEST_F(SyncManagerTest, UpdateEntryWithEncryption) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
true);
@@ -2299,11 +2310,13 @@ TEST_F(SyncManagerTest, UpdatePasswordNewPassphrase) {
EXPECT_CALL(encryption_observer_, OnPassphraseAccepted());
EXPECT_CALL(encryption_observer_, OnEncryptionComplete());
EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_));
+ EXPECT_CALL(encryption_observer_,
+ OnPassphraseStateChanged(CUSTOM_PASSPHRASE));
sync_manager_.GetEncryptionHandler()->SetEncryptionPassphrase(
"new_passphrase",
true);
- EXPECT_TRUE(
- sync_manager_.GetEncryptionHandler()->IsUsingExplicitPassphrase());
+ EXPECT_EQ(CUSTOM_PASSPHRASE,
+ sync_manager_.GetEncryptionHandler()->GetPassphraseState());
EXPECT_TRUE(ResetUnsyncedEntry(PASSWORDS, client_tag));
}
diff --git a/sync/protocol/client_debug_info.proto b/sync/protocol/client_debug_info.proto
index 30d8da6..ceaf023 100644
--- a/sync/protocol/client_debug_info.proto
+++ b/sync/protocol/client_debug_info.proto
@@ -62,17 +62,18 @@ message DebugEventInfo {
ACTIONABLE_ERROR = 8; // Client received an actionable error.
BOOTSTRAP_TOKEN_UPDATED = 9; // A new cryptographer bootstrap token was
// generated.
+ PASSPHRASE_STATE_CHANGED = 10; // The encryption passphrase state changed.
}
// In a given |DebugEventInfo| only one of the following would be set.
optional EventType type = 1;
optional SyncCycleCompletedEventInfo sync_cycle_completed_event_info = 2;
- // Datatype that caused the nudge.
- optional int32 nudging_datatype = 3;
+ // Datatype that caused the nudge.
+ optional int32 nudging_datatype = 3;
- // Datatypes that were notified from server.
- repeated int32 datatypes_notified_from_server = 4;
+ // Datatypes that were notified from server.
+ repeated int32 datatypes_notified_from_server = 4;
}
message DebugInfo {
diff --git a/sync/test/fake_sync_encryption_handler.cc b/sync/test/fake_sync_encryption_handler.cc
index c589558..fd41a5c 100644
--- a/sync/test/fake_sync_encryption_handler.cc
+++ b/sync/test/fake_sync_encryption_handler.cc
@@ -12,7 +12,7 @@ namespace syncer {
FakeSyncEncryptionHandler::FakeSyncEncryptionHandler()
: encrypted_types_(SensitiveTypes()),
encrypt_everything_(false),
- explicit_passphrase_(false),
+ passphrase_state_(IMPLICIT_PASSPHRASE),
cryptographer_(&encryptor_) {
}
FakeSyncEncryptionHandler::~FakeSyncEncryptionHandler() {}
@@ -27,7 +27,7 @@ void FakeSyncEncryptionHandler::ApplyNigoriUpdate(
if (nigori.encrypt_everything())
EnableEncryptEverything();
if (nigori.using_explicit_passphrase())
- explicit_passphrase_ = true;
+ passphrase_state_ = CUSTOM_PASSPHRASE;
if (cryptographer_.CanDecrypt(nigori.encrypted()))
cryptographer_.InstallKeys(nigori.encrypted());
@@ -74,7 +74,7 @@ void FakeSyncEncryptionHandler::SetEncryptionPassphrase(
const std::string& passphrase,
bool is_explicit) {
if (is_explicit)
- explicit_passphrase_ = true;
+ passphrase_state_ = CUSTOM_PASSPHRASE;
}
void FakeSyncEncryptionHandler::SetDecryptionPassphrase(
@@ -96,8 +96,8 @@ bool FakeSyncEncryptionHandler::EncryptEverythingEnabled() const {
return encrypt_everything_;
}
-bool FakeSyncEncryptionHandler::IsUsingExplicitPassphrase() const {
- return explicit_passphrase_;
+PassphraseState FakeSyncEncryptionHandler::GetPassphraseState() const {
+ return passphrase_state_;
}
} // namespace syncer
diff --git a/sync/test/fake_sync_encryption_handler.h b/sync/test/fake_sync_encryption_handler.h
index 7456a08..7899854 100644
--- a/sync/test/fake_sync_encryption_handler.h
+++ b/sync/test/fake_sync_encryption_handler.h
@@ -37,7 +37,7 @@ class FakeSyncEncryptionHandler : public SyncEncryptionHandler,
virtual void SetDecryptionPassphrase(const std::string& passphrase) OVERRIDE;
virtual void EnableEncryptEverything() OVERRIDE;
virtual bool EncryptEverythingEnabled() const OVERRIDE;
- virtual bool IsUsingExplicitPassphrase() const OVERRIDE;
+ virtual PassphraseState GetPassphraseState() const OVERRIDE;
// NigoriHandler implemenation.
virtual void ApplyNigoriUpdate(
@@ -55,7 +55,7 @@ class FakeSyncEncryptionHandler : public SyncEncryptionHandler,
ObserverList<SyncEncryptionHandler::Observer> observers_;
ModelTypeSet encrypted_types_;
bool encrypt_everything_;
- bool explicit_passphrase_;
+ PassphraseState passphrase_state_;
FakeEncryptor encryptor_;
Cryptographer cryptographer_;