1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// 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
|