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
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_OS_CRYPT_SYNC_LIBSECRET_UTIL_LINUX_H_
#define COMPONENTS_OS_CRYPT_SYNC_LIBSECRET_UTIL_LINUX_H_
#include <libsecret/secret.h>
#include <list>
#include <memory>
#include <string>
#include "base/component_export.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
// Utility for dynamically loading libsecret.
class LibsecretLoader {
public:
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_attributes)
secret_item_get_attributes;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_created)
secret_item_get_created;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_modified)
secret_item_get_modified;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_get_secret)
secret_item_get_secret;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_item_load_secret_sync)
secret_item_load_secret_sync;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_password_clear_sync)
secret_password_clear_sync;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_password_store_sync)
secret_password_store_sync;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_service_search_sync)
secret_service_search_sync;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_value_get_text)
secret_value_get_text;
static COMPONENT_EXPORT(OS_CRYPT) decltype(&::secret_value_unref)
secret_value_unref;
// Wrapper for secret_service_search_sync that prevents common leaks. See
// https://crbug.com/393395.
class COMPONENT_EXPORT(OS_CRYPT) SearchHelper {
public:
SearchHelper();
SearchHelper(const SearchHelper&) = delete;
SearchHelper& operator=(const SearchHelper&) = delete;
~SearchHelper();
// Search must be called exactly once for success() and results() to be
// populated.
void Search(const SecretSchema* schema, GHashTable* attrs, int flags);
bool success() { return !error_; }
GList* results() { return results_.get(); }
GError* error() { return error_.get(); }
private:
struct GErrorDeleter {
inline void operator()(GError* error) { g_error_free(error); }
};
struct GListDeleter {
inline void operator()(GList* list) {
g_list_free_full(list, &g_object_unref);
}
};
// |results_| and |error_| are C-style objects owned by this instance.
std::unique_ptr<GList, GListDeleter> results_ = nullptr;
std::unique_ptr<GError, GErrorDeleter> error_ = nullptr;
};
LibsecretLoader() = delete;
LibsecretLoader(const LibsecretLoader&) = delete;
LibsecretLoader& operator=(const LibsecretLoader&) = delete;
// Loads the libsecret library and checks that it responds to queries.
// Returns false if either step fails.
// Repeated calls check the responsiveness every time, but do not load the
// the library again if already successful.
static COMPONENT_EXPORT(OS_CRYPT) bool EnsureLibsecretLoaded();
// Ensure that the default keyring is accessible. This won't prevent the user
// from locking their keyring while Chrome is running.
static COMPONENT_EXPORT(OS_CRYPT) void EnsureKeyringUnlocked();
protected:
static COMPONENT_EXPORT(OS_CRYPT) bool libsecret_loaded_;
private:
struct FunctionInfo {
const char* name;
// This field is not a raw_ptr<> because it only every points at statically-
// allocated memory which is never freed, so it cannot dangle.
RAW_PTR_EXCLUSION void** pointer;
};
static const FunctionInfo kFunctions[];
// Load the libsecret binaries. Returns true on success.
// If successful, the result is cached and the function can be safely called
// multiple times.
// Checking |LibsecretIsAvailable| is necessary after this to verify that the
// service responds to queries.
static bool LoadLibsecret();
// True if the libsecret binaries have been loaded and the library responds
// to queries.
static bool LibsecretIsAvailable();
};
class COMPONENT_EXPORT(OS_CRYPT) LibsecretAttributesBuilder {
public:
LibsecretAttributesBuilder();
LibsecretAttributesBuilder(const LibsecretAttributesBuilder&) = delete;
LibsecretAttributesBuilder& operator=(const LibsecretAttributesBuilder&) =
delete;
~LibsecretAttributesBuilder();
void Append(const std::string& name, const std::string& value);
void Append(const std::string& name, int64_t value);
// GHashTable, its keys and values returned from Get() are destroyed in
// |LibsecretAttributesBuilder| destructor.
GHashTable* Get() { return attrs_; }
private:
// |name_values_| is a storage for strings referenced in |attrs_|.
// TODO(crbug.com/41251661): Make implementation more robust by not depending
// on the implementation details of containers. External objects keep
// references to the objects stored in this container. Using a vector here
// will fail the ASan tests, because it may move the objects and break the
// references.
std::list<std::string> name_values_;
raw_ptr<GHashTable> attrs_;
};
#endif // COMPONENTS_OS_CRYPT_SYNC_LIBSECRET_UTIL_LINUX_H_
|