| // 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 <cstdarg> // Needed to mock ellipsis |
| #include <string> |
| |
| #include "base/macros.h" |
| #include "base/test/test_simple_task_runner.h" |
| #include "components/os_crypt/key_storage_keyring.h" |
| #include "components/os_crypt/keyring_util_linux.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| #if defined(GOOGLE_CHROME_BUILD) |
| const char kApplicationName[] = "chrome"; |
| #else |
| const char kApplicationName[] = "chromium"; |
| #endif |
| |
| // Replaces some of GnomeKeyringLoader's methods with mocked ones. |
| class MockGnomeKeyringLoader : public GnomeKeyringLoader { |
| public: |
| static void ResetForOSCrypt() { |
| GnomeKeyringLoader::gnome_keyring_find_password_sync_ptr = |
| &mock_gnome_keyring_find_password_sync; |
| GnomeKeyringLoader::gnome_keyring_store_password_sync_ptr = |
| &mock_gnome_keyring_store_password_sync; |
| GnomeKeyringLoader::gnome_keyring_free_password_ptr = |
| &mock_gnome_keyring_free_password; |
| |
| delete s_password_ptr_; |
| s_password_ptr_ = nullptr; |
| |
| // GnomeKeyringLoader does not (re)load keyring is this is true. |
| GnomeKeyringLoader::keyring_loaded = true; |
| } |
| |
| static void SetOSCryptPassword(const char* password) { |
| delete s_password_ptr_; |
| s_password_ptr_ = new std::string(password); |
| } |
| |
| static void TearDown() { |
| delete s_password_ptr_; |
| s_password_ptr_ = nullptr; |
| // Function pointers will be reset the next time loading is requested. |
| GnomeKeyringLoader::keyring_loaded = false; |
| } |
| |
| private: |
| // These methods are used to redirect calls through GnomeKeyringLoader. |
| static GnomeKeyringResult mock_gnome_keyring_find_password_sync( |
| const GnomeKeyringPasswordSchema* schema, |
| gchar** password, |
| ...); |
| |
| static GnomeKeyringResult mock_gnome_keyring_store_password_sync( |
| const GnomeKeyringPasswordSchema* schema, |
| const gchar* keyring, |
| const gchar* display_name, |
| const gchar* password, |
| ...); |
| |
| static void mock_gnome_keyring_free_password(gchar* password); |
| |
| static std::string* s_password_ptr_; |
| }; |
| |
| std::string* MockGnomeKeyringLoader::s_password_ptr_ = nullptr; |
| |
| // static |
| GnomeKeyringResult |
| MockGnomeKeyringLoader::mock_gnome_keyring_find_password_sync( |
| const GnomeKeyringPasswordSchema* schema, |
| gchar** password, |
| ...) { |
| va_list attrs; |
| va_start(attrs, password); |
| EXPECT_STREQ("application", va_arg(attrs, const char*)); |
| EXPECT_STREQ(kApplicationName, va_arg(attrs, const char*)); |
| EXPECT_EQ(nullptr, va_arg(attrs, const char*)); |
| va_end(attrs); |
| |
| if (!s_password_ptr_) |
| return GNOME_KEYRING_RESULT_NO_MATCH; |
| *password = strdup(s_password_ptr_->c_str()); |
| return GNOME_KEYRING_RESULT_OK; |
| } |
| |
| // static |
| GnomeKeyringResult |
| MockGnomeKeyringLoader::mock_gnome_keyring_store_password_sync( |
| const GnomeKeyringPasswordSchema* schema, |
| const gchar* keyring, |
| const gchar* display_name, |
| const gchar* password, |
| ...) { |
| va_list attrs; |
| va_start(attrs, password); |
| EXPECT_STREQ("application", va_arg(attrs, const char*)); |
| EXPECT_STREQ(kApplicationName, va_arg(attrs, const char*)); |
| EXPECT_EQ(nullptr, va_arg(attrs, const char*)); |
| va_end(attrs); |
| |
| delete s_password_ptr_; |
| s_password_ptr_ = new std::string(password); |
| return GNOME_KEYRING_RESULT_OK; |
| } |
| |
| // static |
| void MockGnomeKeyringLoader::mock_gnome_keyring_free_password(gchar* password) { |
| free(password); // We are mocking a C function. |
| } |
| |
| class GnomeKeyringTest : public testing::Test { |
| public: |
| GnomeKeyringTest(); |
| ~GnomeKeyringTest() override; |
| |
| protected: |
| scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| KeyStorageKeyring keyring_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(GnomeKeyringTest); |
| }; |
| |
| GnomeKeyringTest::GnomeKeyringTest() |
| : task_runner_(new base::TestSimpleTaskRunner()), keyring_(task_runner_) { |
| MockGnomeKeyringLoader::ResetForOSCrypt(); |
| } |
| |
| GnomeKeyringTest::~GnomeKeyringTest() { |
| MockGnomeKeyringLoader::TearDown(); |
| } |
| |
| TEST_F(GnomeKeyringTest, KeyringRepeats) { |
| std::string password = keyring_.GetKey(); |
| EXPECT_FALSE(password.empty()); |
| std::string password_repeat = keyring_.GetKey(); |
| EXPECT_EQ(password, password_repeat); |
| } |
| |
| TEST_F(GnomeKeyringTest, KeyringCreatesRandomised) { |
| std::string password = keyring_.GetKey(); |
| MockGnomeKeyringLoader::ResetForOSCrypt(); |
| std::string password_new = keyring_.GetKey(); |
| EXPECT_NE(password, password_new); |
| } |
| |
| } // namespace |