Chromium Code Reviews| Index: components/os_crypt/os_crypt_util_linux_unittest.cc |
| diff --git a/components/os_crypt/os_crypt_util_linux_unittest.cc b/components/os_crypt/os_crypt_util_linux_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bca64b6aeeeaa93db976434e09608ff613f46709 |
| --- /dev/null |
| +++ b/components/os_crypt/os_crypt_util_linux_unittest.cc |
| @@ -0,0 +1,149 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <dlfcn.h> |
| +#include <memory> |
| +#include <string> |
| +#include <utility> |
| + |
| +#include "base/logging.h" |
| +#include "base/macros.h" |
| +#include "components/os_crypt/key_storage_linux.h" |
| +#include "components/os_crypt/libsecret_util_posix.h" |
| +#include "components/os_crypt/os_crypt.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace { |
| + |
| +struct MockSecretValue { |
| + public: |
| + std::unique_ptr<std::string> password; |
| + explicit MockSecretValue(const gchar* password); |
|
vabr (Chromium)
2016/05/13 15:10:19
nit: Please separate the methods from each other a
cfroussios
2016/05/13 17:09:13
Done.
|
| + ~MockSecretValue(); |
| +}; |
| + |
| +// Replaces some of LibsecretLoader's methods with mocked ones. |
| +class MockLibsecretLoader : public LibsecretLoader { |
| + public: |
| + // Sets up the minimum mock implementation necessary for |Libsecret| to work. |
|
vabr (Chromium)
2016/05/13 15:10:19
nit: Please separate methods with blank lines.
cfroussios
2016/05/13 17:09:13
Done.
|
| + // Also resets the state to mock a clean database. |
| + static bool ResetForOSCrypt(); |
| + // Shorthand for setting OSCrypt's password in the libsecret mock to a |
| + // specific value |
| + static void SetOSCryptPassword(const char*); |
| +}; |
| + |
| +MockSecretValue::MockSecretValue(const gchar* password) |
| + : password(new std::string(password)) {} |
| +MockSecretValue::~MockSecretValue() = default; |
|
vabr (Chromium)
2016/05/13 15:10:19
nit: Please add a blank line above this one.
cfroussios
2016/05/13 17:09:13
Done.
|
| + |
| +std::unique_ptr<MockSecretValue> stored_password(nullptr); |
|
vabr (Chromium)
2016/05/13 15:10:19
nit: No need to pass nullptr to a unique_ptr, just
vabr (Chromium)
2016/05/13 15:10:19
No non-POD data types as static variables (see my
vabr (Chromium)
2016/05/13 15:10:19
nit: Please use g_ as a prefix for global variable
cfroussios
2016/05/13 17:09:13
Acknowledged.
|
| + |
| +const gchar* mock_secret_value_get_text(MockSecretValue* value) { |
| + return value->password->c_str(); |
| +} |
| + |
| +gboolean mock_secret_password_store_sync(const SecretSchema* schema, |
| + const gchar* collection, |
| + const gchar* label, |
| + const gchar* password, |
| + GCancellable* cancellable, |
| + GError** error, |
| + ...) { |
| + stored_password.reset(new MockSecretValue(password)); |
| + return true; |
| +} |
| + |
| +MockSecretValue* mock_secret_service_lookup_sync(SecretService* service, |
| + const SecretSchema* schema, |
| + GHashTable* attributes, |
| + GCancellable* cancellable, |
| + GError** error) { |
| + return stored_password.get(); |
| +} |
| + |
| +void mock_secret_value_unref(gpointer value) {} |
| + |
| +GList* mock_secret_service_search_sync(SecretService* service, |
| + const SecretSchema* schema, |
| + GHashTable* attributes, |
| + SecretSearchFlags flags, |
| + GCancellable* cancellable, |
| + GError** error) { |
| + *error = nullptr; |
| + return nullptr; |
| +} |
| + |
| +// static |
| +bool MockLibsecretLoader::ResetForOSCrypt() { |
| + // 4 methods used by Libsecret.GetPassword(); |
| + secret_password_store_sync = &mock_secret_password_store_sync; |
| + secret_value_get_text = |
| + (decltype(&::secret_value_get_text)) & mock_secret_value_get_text; |
| + secret_value_unref = &mock_secret_value_unref; |
| + secret_service_lookup_sync = (decltype(&::secret_service_lookup_sync)) & |
| + mock_secret_service_lookup_sync; |
| + // 1 method used by LibsecretLoader::EnsureLibsecretLoaded |
| + secret_service_search_sync = &mock_secret_service_search_sync; |
| + |
| + stored_password.reset(nullptr); |
| + libsecret_loaded_ = true; |
| + |
| + return true; |
| +} |
| + |
| +void MockLibsecretLoader::SetOSCryptPassword(const char* value) { |
| + stored_password.reset(new MockSecretValue(value)); |
| +} |
| + |
| +TEST(LibsecretTest, VerifyPosixMigrationCoexistance) { |
| + const std::string originaltext = "hello"; |
| + std::string ciphertext; |
| + std::string decipheredtext; |
| + std::string decipheredtextV11; |
| + std::string decipheredtextV10; |
| + |
| + // Verify that there are 3 versions currently supported |
| + |
| + KeyStorageMock* key_storage = OSCrypt::UseMockKeyStorage(true); |
| + |
| + ASSERT_TRUE(OSCrypt::EncryptString(originaltext, &ciphertext)); |
|
vabr (Chromium)
2016/05/13 15:10:19
The three blocks do not seem to depend on each oth
cfroussios
2016/05/13 17:09:12
Done.
|
| + ASSERT_EQ(ciphertext.substr(0, 3), "v11"); |
| + ASSERT_TRUE(OSCrypt::DecryptString(ciphertext, &decipheredtextV11)); |
| + ASSERT_EQ(originaltext, decipheredtextV11); |
| + |
| + key_storage->ResetTo(std::string("peanuts")); |
| + ASSERT_TRUE(OSCrypt::EncryptString(originaltext, &ciphertext)); |
| + key_storage->ResetTo(std::string("not_peanuts")); |
| + ciphertext = ciphertext.substr(3).insert(0, "v10"); |
| + ASSERT_TRUE(OSCrypt::DecryptString(ciphertext, &decipheredtextV10)); |
| + ASSERT_EQ(originaltext, decipheredtextV10); |
| + |
| + ciphertext = originaltext; // No encryption |
| + ASSERT_TRUE(OSCrypt::DecryptString(ciphertext, &decipheredtext)); |
| + ASSERT_EQ(originaltext, decipheredtext); |
| + |
| + // Don't force a static configuration on other tests |
| + OSCrypt::UseMockKeyStorage(false); |
|
vabr (Chromium)
2016/05/13 15:10:19
It might be safer to define a test fixture (based
cfroussios
2016/05/13 17:09:12
Done.
|
| +} |
| + |
| +TEST(LibsecretTest, LibsecretRepeats) { |
| + KeyStorageLibsecret libsecret; |
| + MockLibsecretLoader::ResetForOSCrypt(); |
| + std::string password = libsecret.GetKey(); |
| + EXPECT_NE(password, ""); |
|
vabr (Chromium)
2016/05/13 15:10:19
EXPECT_FALSE(password.empty());
cfroussios
2016/05/13 17:09:12
Done.
|
| + std::string password_repeat = libsecret.GetKey(); |
| + EXPECT_EQ(password, password_repeat); |
| +} |
| + |
| +TEST(LibsecretTest, LibsecretCreatesRandomised) { |
| + KeyStorageLibsecret libsecret; |
| + MockLibsecretLoader::ResetForOSCrypt(); |
| + std::string password = libsecret.GetKey(); |
| + MockLibsecretLoader::ResetForOSCrypt(); |
| + std::string password_new = libsecret.GetKey(); |
| + EXPECT_NE(password, password_new); |
| +} |
| + |
| +} // namespace |