From 1427bf26a3a280909fe374252d90f088e0beb887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gl=C3=A4=C3=9Fle?= Date: Mon, 6 Jul 2015 19:50:58 +0200 Subject: [PATCH] Add keyfile_contents blob to unlock options --- src/udiskslinuxencrypted.c | 47 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/udiskslinuxencrypted.c b/src/udiskslinuxencrypted.c index fefcba5..05b5ead 100644 --- a/src/udiskslinuxencrypted.c +++ b/src/udiskslinuxencrypted.c @@ -36,6 +36,7 @@ #include "udisksdaemonutil.h" #include "udisksstate.h" #include "udiskslinuxdevice.h" +#include "udisksspawnedjob.h" /** * SECTION:udiskslinuxencrypted @@ -228,6 +229,30 @@ has_option (const gchar *options, /* ---------------------------------------------------------------------------------------------------- */ +static gboolean +lookup_binary_blob(GVariant* dict, const gchar* name, GString** contents) +{ + GVariantIter *iter; + guchar byte; + gsize size = 0; + gsize index = 0; + + if (!g_variant_lookup (dict, name, "a(y)", &iter)) + return FALSE; + + size = g_variant_iter_n_children (iter); + *contents = g_string_sized_new (size); + (*contents)->len = size; + + while (g_variant_iter_loop (iter, "(y)", &byte)) + { + (*contents)->str[index++] = byte; + } + + g_variant_iter_free (iter); + return TRUE; +} + /* runs in thread dedicated to handling @invocation */ static gboolean handle_unlock (UDisksEncrypted *encrypted, @@ -254,7 +279,9 @@ handle_unlock (UDisksEncrypted *encrypted, gchar *crypttab_passphrase = NULL; gchar *crypttab_options = NULL; gchar *escaped_device = NULL; + gboolean use_keyfile = FALSE; gboolean read_only = FALSE; + GString *effective_passphrase = NULL; object = udisks_daemon_util_dup_object (encrypted, &error); if (object == NULL) @@ -368,10 +395,18 @@ handle_unlock (UDisksEncrypted *encrypted, name = g_strdup_printf ("luks-%s", udisks_block_get_id_uuid (block)); escaped_name = udisks_daemon_util_escape_and_quote (name); + if (lookup_binary_blob(options, "keyfile_contents", &effective_passphrase)) + { + use_keyfile = TRUE; + } /* if available, use and prefer the /etc/crypttab passphrase */ - if (is_in_crypttab && crypttab_passphrase != NULL && strlen (crypttab_passphrase) > 0) + else if (is_in_crypttab && crypttab_passphrase != NULL && strlen (crypttab_passphrase) > 0) { - passphrase = crypttab_passphrase; + effective_passphrase = g_string_new (crypttab_passphrase); + } + else + { + effective_passphrase = g_string_new (passphrase); } escaped_device = udisks_daemon_util_escape_and_quote (udisks_block_get_device (block)); @@ -380,7 +415,7 @@ handle_unlock (UDisksEncrypted *encrypted, if (udisks_block_get_read_only (block)) read_only = TRUE; - if (!udisks_daemon_launch_spawned_job_sync (daemon, + if (!udisks_daemon_launch_spawned_job_gstring_sync (daemon, object, "encrypted-unlock", caller_uid, NULL, /* GCancellable */ @@ -388,10 +423,11 @@ handle_unlock (UDisksEncrypted *encrypted, 0, /* uid_t run_as_euid */ NULL, /* gint *out_status */ &error_message, - passphrase, /* input_string */ - "cryptsetup luksOpen %s %s %s", + effective_passphrase, /* input_string */ + "cryptsetup luksOpen %s %s %s %s", escaped_device, escaped_name, + use_keyfile ? "--key-file -" : "", read_only ? "--readonly" : "")) { g_dbus_method_invocation_return_error (invocation, @@ -449,6 +485,7 @@ handle_unlock (UDisksEncrypted *encrypted, g_clear_object (&cleartext_device); g_clear_object (&cleartext_object); g_clear_object (&object); + udisks_string_wipe_and_free(effective_passphrase); return TRUE; /* returning TRUE means that we handled the method invocation */ } -- 2.10.2