From c74621784bbbc2c29fb9c4632b82a5bdc0028769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gl=C3=A4=C3=9Fle?= Date: Mon, 6 Jul 2015 21:48:42 +0200 Subject: [PATCH] Add --key-file option to udisksctl unlock --- doc/man/udisksctl.xml | 1 + tools/udisksctl.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/doc/man/udisksctl.xml b/doc/man/udisksctl.xml index 39c9d46..ed5487c 100644 --- a/doc/man/udisksctl.xml +++ b/doc/man/udisksctl.xml @@ -70,6 +70,7 @@ --block-device DEVICE --no-user-interaction + --key-file PATH diff --git a/tools/udisksctl.c b/tools/udisksctl.c index 3e85e15..168a680 100644 --- a/tools/udisksctl.c +++ b/tools/udisksctl.c @@ -987,6 +987,7 @@ encrypted_is_unlocked (UDisksObject *encrypted_object) static gchar *opt_unlock_lock_object_path = NULL; static gchar *opt_unlock_lock_device = NULL; static gboolean opt_unlock_lock_no_user_interaction = FALSE; +static gchar *opt_unlock_keyfile = NULL; static const GOptionEntry command_unlock_entries[] = { @@ -1018,6 +1019,15 @@ static const GOptionEntry command_unlock_entries[] = NULL }, { + "key-file", + 0, /* no short option */ + 0, + G_OPTION_ARG_STRING, + &opt_unlock_keyfile, + "Keyfile for unlocking", + NULL + }, + { NULL } }; @@ -1056,6 +1066,21 @@ static const GOptionEntry command_lock_entries[] = } }; +static GVariant* +pack_binary_blob(const gchar* data, gsize size) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(y)")); + + for (gsize i = 0; i < size; i++) + { + g_variant_builder_add (&builder, "(y)", data[i]); + } + + return g_variant_builder_end (&builder); +} + static gint handle_command_unlock_lock (gint *argc, gchar **argv[], @@ -1078,6 +1103,9 @@ handle_command_unlock_lock (gint *argc, GVariant *options; GVariantBuilder builder; gchar *passphrase; + gchar *keyfile_contents = NULL; + gsize keyfile_size = 0; + GError *error = NULL; ret = 1; opt_unlock_lock_object_path = NULL; @@ -1100,7 +1128,7 @@ handle_command_unlock_lock (gint *argc, else g_option_context_set_summary (o, "Lock an encrypted device."); g_option_context_add_main_entries (o, - is_unlock ? command_lock_entries : command_unlock_entries, + is_unlock ? command_unlock_entries : command_lock_entries, NULL /* GETTEXT_PACKAGE*/); complete_objects = FALSE; @@ -1240,22 +1268,37 @@ handle_command_unlock_lock (gint *argc, "{sv}", "auth.no_user_interaction", g_variant_new_boolean (TRUE)); } + if (opt_unlock_keyfile) + { + if (!g_file_get_contents (opt_unlock_keyfile, + &keyfile_contents, + &keyfile_size, + &error)) + { + g_printerr ("Error unlocking %s: %s\n", + udisks_block_get_device (block), + error->message); + goto out; + } + g_variant_builder_add (&builder, + "{sv}", + "keyfile_contents", + pack_binary_blob(keyfile_contents, keyfile_size)); + } options = g_variant_builder_end (&builder); g_variant_ref_sink (options); - if (is_unlock) + if (is_unlock && !opt_unlock_keyfile) passphrase = read_passphrase (); try_again: if (is_unlock) { - GError *error; gchar *cleartext_object_path; UDisksObject *cleartext_object; - error = NULL; if (!udisks_encrypted_call_unlock_sync (encrypted, - passphrase, + passphrase ? passphrase : "", options, &cleartext_object_path, NULL, /* GCancellable */ @@ -1287,9 +1330,6 @@ handle_command_unlock_lock (gint *argc, } else { - GError *error; - - error = NULL; if (!udisks_encrypted_call_lock_sync (encrypted, options, NULL, /* GCancellable */ @@ -1323,6 +1363,11 @@ handle_command_unlock_lock (gint *argc, memset (passphrase, '\0', strlen (passphrase)); g_free (passphrase); } + if (keyfile_contents != NULL) + { + memset (keyfile_contents, '\0', keyfile_size); + g_free (keyfile_contents); + } if (options != NULL) g_variant_unref (options); g_option_context_free (o); -- 2.10.2