From 7d7c1b3430a543c80042839ab6b18546cdc20666 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Sat, 21 May 2022 20:53:36 +0200 Subject: file-backend: Extract TPM code into separate function That way, we have a function we can also call in case we want to provide a synchronous constructor. This also fixes some cases where the `EggTpm2Context` was not properly cleaned up in case of some error paths. --- libsecret/secret-file-backend.c | 157 ++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 79 deletions(-) diff --git a/libsecret/secret-file-backend.c b/libsecret/secret-file-backend.c index 9c9dc12..b13bfd2 100644 --- a/libsecret/secret-file-backend.c +++ b/libsecret/secret-file-backend.c @@ -464,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, @@ -508,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, @@ -602,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 } } -- cgit v1.2.1