mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 12:48:51 +00:00
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.
This commit is contained in:
parent
7b461f5514
commit
7d7c1b3430
@ -464,6 +464,77 @@ on_bus_get (GObject *source_object,
|
|||||||
g_object_unref (fd_list);
|
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
|
static void
|
||||||
secret_file_backend_real_init_async (GAsyncInitable *initable,
|
secret_file_backend_real_init_async (GAsyncInitable *initable,
|
||||||
int io_priority,
|
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);
|
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
|
||||||
} else {
|
} else {
|
||||||
#ifdef WITH_TPM
|
#ifdef WITH_TPM
|
||||||
EggTpm2Context *context;
|
GBytes *decrypted = NULL;
|
||||||
GFile *tpm2_file;
|
gconstpointer data;
|
||||||
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;
|
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 {
|
decrypted = load_password_from_tpm (file, cancellable, &error);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
decrypted = egg_tpm2_decrypt_master_password (context,
|
|
||||||
encrypted,
|
|
||||||
&error);
|
|
||||||
g_bytes_unref (encrypted);
|
|
||||||
egg_tpm2_finalize (context);
|
|
||||||
if (!decrypted) {
|
if (!decrypted) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gconstpointer data;
|
|
||||||
gsize size;
|
|
||||||
data = g_bytes_get_data (decrypted, &size);
|
data = g_bytes_get_data (decrypted, &size);
|
||||||
password = secret_value_new (data,
|
password = secret_value_new (data,size, "text/plain");
|
||||||
size,
|
|
||||||
"text/plain");
|
|
||||||
g_bytes_unref (decrypted);
|
g_bytes_unref (decrypted);
|
||||||
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
||||||
io_priority,
|
io_priority,
|
||||||
@ -602,16 +602,15 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
|
|||||||
"password", password,
|
"password", password,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_object_unref (tpm2_file);
|
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
secret_value_unref (password);
|
secret_value_unref (password);
|
||||||
|
return;
|
||||||
#else
|
#else
|
||||||
g_task_return_new_error (task,
|
g_task_return_new_error (task,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
"master password is not retrievable");
|
"master password is not retrievable");
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user