From 9f749a4ea6129c256bb3522291eaa43f63c961c1 Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Tue, 5 Dec 2017 17:17:40 +0200 Subject: [PATCH] core: Add Encrypted.Resize method To go with Filesystem.Resize. --- data/org.freedesktop.UDisks2.xml | 16 ++++ doc/udisks2-sections.txt.in.in | 4 + src/udiskslinuxencrypted.c | 134 ++++++++++++++++++++++++++++++ udisks/udisksclient.c | 1 + 4 files changed, 155 insertions(+) diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml index fa53a72..75ec0ea 100644 --- a/data/org.freedesktop.UDisks2.xml +++ b/data/org.freedesktop.UDisks2.xml @@ -2059,6 +2059,20 @@ + + + + + + @@ -2451,6 +2465,8 @@ Locking encrypted device. encrypted-modify Modifying encrypted device. + encrypted-resize + Resizing encrypted device. swapspace-start Starting swapspace. swapspace-stop diff --git a/doc/udisks2-sections.txt.in.in b/doc/udisks2-sections.txt.in.in index 5860d43..13cf728 100644 --- a/doc/udisks2-sections.txt.in.in +++ b/doc/udisks2-sections.txt.in.in @@ -1036,6 +1036,10 @@ udisks_encrypted_call_change_passphrase udisks_encrypted_call_change_passphrase_finish udisks_encrypted_call_change_passphrase_sync udisks_encrypted_complete_change_passphrase +udisks_encrypted_call_resize +udisks_encrypted_call_resize_finish +udisks_encrypted_call_resize_sync +udisks_encrypted_complete_resize UDisksEncryptedProxy UDisksEncryptedProxyClass udisks_encrypted_proxy_new diff --git a/src/udiskslinuxencrypted.c b/src/udiskslinuxencrypted.c index 7b19e84..08e59d1 100644 --- a/src/udiskslinuxencrypted.c +++ b/src/udiskslinuxencrypted.c @@ -43,6 +43,7 @@ #include "udiskscrypttabentry.h" #include "udiskscrypttabmonitor.h" #include "udisksspawnedjob.h" +#include "udiskssimplejob.h" /** * SECTION:udiskslinuxencrypted @@ -802,10 +803,143 @@ handle_change_passphrase (UDisksEncrypted *encrypted, /* ---------------------------------------------------------------------------------------------------- */ +/* runs in thread dedicated to handling method call */ +static gboolean +handle_resize (UDisksEncrypted *encrypted, + GDBusMethodInvocation *invocation, + guint64 size, + GVariant *options) +{ + UDisksObject *object = NULL; + UDisksBlock *block; + UDisksObject *cleartext_object = NULL; + UDisksBlock *cleartext_block; + UDisksDaemon *daemon; + uid_t caller_uid; + const gchar *action_id = NULL; + const gchar *message = NULL; + GError *error = NULL; + UDisksBaseJob *job = NULL; + + object = udisks_daemon_util_dup_object (encrypted, &error); + if (object == NULL) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + block = udisks_object_peek_block (object); + daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object)); + + /* Fail if the device is not a LUKS device */ + if (!(g_strcmp0 (udisks_block_get_id_usage (block), "crypto") == 0 && + g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0)) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Device %s does not appear to be a LUKS device", + udisks_block_get_device (block)); + goto out; + } + + error = NULL; + if (!udisks_daemon_util_get_caller_uid_sync (daemon, invocation, NULL /* GCancellable */, &caller_uid, NULL, NULL, &error)) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_clear_error (&error); + goto out; + } + + /* Fail if device is not unlocked */ + cleartext_object = udisks_daemon_wait_for_object_sync (daemon, + wait_for_cleartext_object, + g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))), + g_free, + 0, /* timeout_seconds */ + NULL); /* error */ + if (cleartext_object == NULL) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Device %s is not unlocked", + udisks_block_get_device (block)); + goto out; + } + cleartext_block = udisks_object_peek_block (cleartext_object); + + action_id = "org.freedesktop.udisks2.modify-device"; + /* Translators: Shown in authentication dialog when the user + * requests resizing a encrypted block device. + * + * Do not translate $(drive), it's a placeholder and + * will be replaced by the name of the drive/device in question + */ + message = N_("Authentication is required to resize the encrypted device $(drive)"); + if (! udisks_daemon_util_setup_by_user (daemon, object, caller_uid)) + { + if (udisks_block_get_hint_system (block)) + { + action_id = "org.freedesktop.udisks2.modify-device-system"; + } + else if (! udisks_daemon_util_on_user_seat (daemon, UDISKS_OBJECT (object), caller_uid)) + { + action_id = "org.freedesktop.udisks2.modify-device-other-seat"; + } + } + + /* Check that the user is actually authorized to resize the device. */ + if (! udisks_daemon_util_check_authorization_sync (daemon, + object, + action_id, + options, + message, + invocation)) + goto out; + + job = udisks_daemon_launch_simple_job (daemon, + UDISKS_OBJECT (object), + "encrypted-resize", + caller_uid, + NULL); + if (job == NULL) + { + g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, + "Failed to create a job object"); + goto out; + } + + /* TODO: implement progress parsing for udisks_job_set_progress(_valid) */ + if (! bd_crypto_luks_resize (udisks_block_get_device (cleartext_block), size / 512, &error)) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Error resizing encrypted device %s: %s", + udisks_block_get_device (cleartext_block), + error->message); + udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), FALSE, error->message); + goto out; + } + + udisks_encrypted_complete_resize (encrypted, invocation); + udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), TRUE, NULL); + + out: + g_clear_object (&cleartext_object); + g_clear_object (&object); + g_clear_error (&error); + return TRUE; /* returning TRUE means that we handled the method invocation */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + static void encrypted_iface_init (UDisksEncryptedIface *iface) { iface->handle_unlock = handle_unlock; iface->handle_lock = handle_lock; iface->handle_change_passphrase = handle_change_passphrase; + iface->handle_resize = handle_resize; } diff --git a/udisks/udisksclient.c b/udisks/udisksclient.c index 7bd5684..980c941 100644 --- a/udisks/udisksclient.c +++ b/udisks/udisksclient.c @@ -2487,6 +2487,7 @@ udisks_client_get_job_description (UDisksClient *client, g_hash_table_insert (hash, (gpointer) "encrypted-unlock", (gpointer) C_("job", "Unlocking Device")); g_hash_table_insert (hash, (gpointer) "encrypted-lock", (gpointer) C_("job", "Locking Device")); g_hash_table_insert (hash, (gpointer) "encrypted-modify", (gpointer) C_("job", "Modifying Encrypted Device")); + g_hash_table_insert (hash, (gpointer) "encrypted-resize", (gpointer) C_("job", "Resizing Encrypted Device")); g_hash_table_insert (hash, (gpointer) "swapspace-start", (gpointer) C_("job", "Starting Swap Device")); g_hash_table_insert (hash, (gpointer) "swapspace-stop", (gpointer) C_("job", "Stopping Swap Device")); g_hash_table_insert (hash, (gpointer) "filesystem-check", (gpointer) C_("job", "Checking Filesystem")); -- 1.8.3.1