summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2023-01-15 10:16:50 +0000
committerNiels De Graef <nielsdegraef@gmail.com>2023-01-15 10:16:50 +0000
commit33a4de59a2a3357cea5bd339489340a9c615024d (patch)
tree2eda37593a074e3a64fab0db6b41b049dda4fa37
parent179dc316c1a72ee7f478d82dacf79468245b0827 (diff)
parent7d7c1b3430a543c80042839ab6b18546cdc20666 (diff)
downloadlibsecret-33a4de59a2a3357cea5bd339489340a9c615024d.tar.gz
Merge branch 'nielsdg/extract-get-secret-file-func' into 'master'
file-backend: Extract functions from the initializer code See merge request GNOME/libsecret!107
-rw-r--r--libsecret/secret-file-backend.c245
1 files changed, 128 insertions, 117 deletions
diff --git a/libsecret/secret-file-backend.c b/libsecret/secret-file-backend.c
index 7145f72..b13bfd2 100644
--- a/libsecret/secret-file-backend.c
+++ b/libsecret/secret-file-backend.c
@@ -60,6 +60,51 @@ enum {
PROP_FLAGS
};
+/* Gets the GFile for this backend and makes sure the parent dirs exist */
+static GFile *
+get_secret_file (GCancellable *cancellable, GError **error)
+{
+ const char *envvar = NULL;
+ char *path = NULL;
+ GFile *file = NULL;
+ GFile *dir = NULL;
+ gboolean ret;
+
+ envvar = g_getenv ("SECRET_FILE_TEST_PATH");
+ if (envvar != NULL && *envvar != '\0') {
+ path = g_strdup (envvar);
+ } else {
+ path = g_build_filename (g_get_user_data_dir (),
+ "keyrings",
+ SECRET_COLLECTION_DEFAULT ".keyring",
+ NULL);
+ }
+
+ file = g_file_new_for_path (path);
+ g_free (path);
+
+ dir = g_file_get_parent (file);
+ if (dir == NULL) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "not a valid path");
+ g_object_unref (file);
+ return NULL;
+ }
+
+ ret = g_file_make_directory_with_parents (dir, cancellable, error);
+ g_object_unref (dir);
+ if (!ret) {
+ if (!g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ g_object_unref (file);
+ return NULL;
+ }
+
+ g_clear_error (error);
+ }
+
+ return file;
+}
+
static void
secret_file_backend_init (SecretFileBackend *self)
{
@@ -419,6 +464,77 @@ on_bus_get (GObject *source_object,
g_object_unref (fd_list);
}
+#ifdef WITH_TPM
+static GBytes *
+load_password_from_tpm (GFile *file, GCancellable *cancellable, GError **error)
+{
+ EggTpm2Context *context = NULL;
+ char *path = NULL;
+ char *tpm2_file_path = NULL;
+ GFile *tpm2_file = NULL;
+ gboolean status;
+ GBytes *encrypted = NULL;
+ GBytes *decrypted = NULL;
+
+ context = egg_tpm2_initialize (error);
+ if (!context)
+ return NULL;
+
+ path = g_file_get_path (file);
+ tpm2_file_path = g_strdup_printf ("%s.tpm2", path);
+ g_free (path);
+
+ tpm2_file = g_file_new_for_path (tpm2_file_path);
+ status = g_file_test (tpm2_file_path, G_FILE_TEST_EXISTS);
+ g_free (tpm2_file_path);
+
+ if (!status) {
+ gconstpointer contents;
+ gsize size;
+
+ encrypted = egg_tpm2_generate_master_password (context, error);
+ if (!encrypted)
+ return NULL;
+
+ contents = g_bytes_get_data (encrypted, &size);
+ status = g_file_replace_contents (tpm2_file,
+ contents,
+ size,
+ NULL,
+ FALSE,
+ G_FILE_CREATE_PRIVATE,
+ NULL,
+ cancellable,
+ error);
+ if (!status)
+ goto out;
+ } else {
+ char *contents;
+ gsize length;
+
+ status = g_file_load_contents (tpm2_file,
+ cancellable,
+ &contents,
+ &length,
+ NULL,
+ error);
+ if (!status)
+ goto out;
+
+ encrypted = g_bytes_new_take (contents, length);
+ }
+
+ decrypted = egg_tpm2_decrypt_master_password (context, encrypted, error);
+
+out:
+ g_clear_object (&tpm2_file);
+ g_clear_pointer (&encrypted, g_bytes_unref);
+ egg_tpm2_finalize (context);
+
+ return decrypted;
+}
+#endif /* WITH_TPM */
+
static void
secret_file_backend_real_init_async (GAsyncInitable *initable,
int io_priority,
@@ -426,55 +542,22 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *path;
- GFile *file;
- GFile *dir;
+ const char *envvar = NULL;
+ GFile *file = NULL;
SecretValue *password;
- const gchar *envvar;
GTask *task;
GError *error = NULL;
InitClosure *init;
- gboolean ret;
task = g_task_new (initable, cancellable, callback, user_data);
- envvar = g_getenv ("SECRET_FILE_TEST_PATH");
- if (envvar != NULL && *envvar != '\0')
- path = g_strdup (envvar);
- else {
- path = g_build_filename (g_get_user_data_dir (),
- "keyrings",
- SECRET_COLLECTION_DEFAULT ".keyring",
- NULL);
- }
-
- file = g_file_new_for_path (path);
- g_free (path);
-
- dir = g_file_get_parent (file);
- if (dir == NULL) {
- g_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- "not a valid path");
- g_object_unref (file);
+ file = get_secret_file (cancellable, &error);
+ if (file == NULL) {
+ g_task_return_error (task, g_steal_pointer (&error));
g_object_unref (task);
return;
}
- ret = g_file_make_directory_with_parents (dir, cancellable, &error);
- g_object_unref (dir);
- if (!ret) {
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
- g_clear_error (&error);
- else {
- g_task_return_error (task, error);
- g_object_unref (file);
- g_object_unref (task);
- return;
- }
- }
-
envvar = g_getenv ("SECRET_FILE_TEST_PASSWORD");
if (envvar != NULL && *envvar != '\0') {
password = secret_value_new (envvar, -1, "text/plain");
@@ -496,90 +579,19 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
} else {
#ifdef WITH_TPM
- EggTpm2Context *context;
- GFile *tpm2_file;
- gchar *tpm2_file_path;
- gboolean status;
- GBytes *encrypted;
- GBytes *decrypted;
-
- context = egg_tpm2_initialize (&error);
- if (!context) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- path = g_file_get_path (file);
- tpm2_file_path = g_strdup_printf ("%s.tpm2", path);
- g_free(path);
- tpm2_file = g_file_new_for_path (tpm2_file_path);
- status = g_file_test (tpm2_file_path, G_FILE_TEST_EXISTS);
- g_free (tpm2_file_path);
-
- if (!status) {
- encrypted = egg_tpm2_generate_master_password (
- context,
- &error);
- if (!encrypted) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- gconstpointer contents;
- gsize size;
- contents = g_bytes_get_data (encrypted, &size);
- status = g_file_replace_contents (tpm2_file,
- contents,
- size,
- NULL,
- FALSE,
- G_FILE_CREATE_PRIVATE,
- NULL,
- cancellable,
- &error);
- if (!status) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- } else {
- char *contents;
- gsize length;
- status = g_file_load_contents (tpm2_file,
- cancellable,
- &contents,
- &length,
- NULL,
- &error);
- if (!status) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- encrypted = g_bytes_new_take (contents, length);
- }
+ GBytes *decrypted = NULL;
+ gconstpointer data;
+ gsize size;
- decrypted = egg_tpm2_decrypt_master_password (context,
- encrypted,
- &error);
- g_bytes_unref (encrypted);
- egg_tpm2_finalize (context);
+ decrypted = load_password_from_tpm (file, cancellable, &error);
if (!decrypted) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
- gconstpointer data;
- gsize size;
- data = g_bytes_get_data(decrypted, &size);
- password = secret_value_new (data,
- size,
- "text/plain");
+ data = g_bytes_get_data (decrypted, &size);
+ password = secret_value_new (data,size, "text/plain");
g_bytes_unref (decrypted);
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
io_priority,
@@ -590,16 +602,15 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
"password", password,
NULL);
- g_object_unref (tpm2_file);
g_object_unref (file);
secret_value_unref (password);
+ return;
#else
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
"master password is not retrievable");
g_object_unref (task);
- return;
#endif
}
}