[gvfs/wip/udisks2] udisks2: handle display, unlock/mount and unmount/lock of LUKS devices
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/udisks2] udisks2: handle display, unlock/mount and unmount/lock of LUKS devices
- Date: Wed, 5 Oct 2011 17:46:23 +0000 (UTC)
commit 5c2fc336ee9aaeb339b05b568ca5e8a3e415a390
Author: David Zeuthen <davidz redhat com>
Date: Wed Oct 5 13:45:33 2011 -0400
udisks2: handle display, unlock/mount and unmount/lock of LUKS devices
Signed-off-by: David Zeuthen <davidz redhat com>
monitor/udisks2/gvfsudisks2mount.c | 109 +++++++--
monitor/udisks2/gvfsudisks2volume.c | 354 +++++++++++++++++++++++++---
monitor/udisks2/gvfsudisks2volumemonitor.c | 156 ++++---------
3 files changed, 449 insertions(+), 170 deletions(-)
---
diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c
index 03cba80..4835dcd 100644
--- a/monitor/udisks2/gvfsudisks2mount.c
+++ b/monitor/udisks2/gvfsudisks2mount.c
@@ -580,6 +580,9 @@ typedef struct
GVfsUDisks2Mount *mount;
+ UDisksEncrypted *encrypted;
+ UDisksFilesystem *filesystem;
+
GCancellable *cancellable;
gulong cancelled_handler_id;
gboolean is_cancelled;
@@ -614,6 +617,8 @@ unmount_data_free (UnmountData *data)
g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
g_clear_object (&data->cancellable);
g_clear_object (&data->mount_operation);
+ g_clear_object (&data->encrypted);
+ g_clear_object (&data->filesystem);
g_free (data);
}
@@ -724,6 +729,24 @@ unmount_show_busy (UnmountData *data,
}
static void
+lock_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ UDisksEncrypted *encrypted = UDISKS_ENCRYPTED (source_object);
+ UnmountData *data = user_data;
+ GError *error;
+
+ error = NULL;
+ if (!udisks_encrypted_call_lock_finish (encrypted,
+ res,
+ &error))
+ g_simple_async_result_take_error (data->simple, error);
+ g_simple_async_result_complete (data->simple);
+ unmount_data_free (data);
+}
+
+static void
unmount_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
@@ -754,7 +777,19 @@ unmount_cb (GObject *source_object,
else
{
gvfs_udisks2_volume_monitor_update (data->mount->monitor);
- g_simple_async_result_complete (data->simple);
+ if (data->encrypted != NULL)
+ {
+ udisks_encrypted_call_lock (data->encrypted,
+ g_variant_new ("a{sv}", NULL), /* options */
+ data->cancellable,
+ lock_cb,
+ data);
+ goto out;
+ }
+ else
+ {
+ g_simple_async_result_complete (data->simple);
+ }
}
unmount_data_free (data);
@@ -832,8 +867,6 @@ static void
unmount_do (UnmountData *data,
gboolean force)
{
- UDisksBlock *block;
- UDisksFilesystem *filesystem;
GVariantBuilder builder;
if (data->mount->volume == NULL)
@@ -842,25 +875,6 @@ unmount_do (UnmountData *data,
goto out;
}
- block = gvfs_udisks2_volume_get_block (data->mount->volume);
- if (block == NULL)
- {
- unmount_do_command (data, force);
- goto out;
- }
-
- filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))));
- if (filesystem == NULL)
- {
- g_simple_async_result_set_error (data->simple,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "No filesystem interface on D-Bus object");
- g_simple_async_result_complete (data->simple);
- unmount_data_free (data);
- goto out;
- }
-
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
if (data->mount_operation == NULL)
{
@@ -874,7 +888,7 @@ unmount_do (UnmountData *data,
"{sv}",
"force", g_variant_new_boolean (TRUE));
}
- udisks_filesystem_call_unmount (filesystem,
+ udisks_filesystem_call_unmount (data->filesystem,
g_variant_builder_end (&builder),
data->cancellable,
unmount_cb,
@@ -894,6 +908,8 @@ gvfs_udisks2_mount_unmount_with_operation (GMount *_mount,
{
GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
UnmountData *data;
+ UDisksBlock *block;
+ UDisksObject *object;
/* first emit the ::mount-pre-unmount signal */
g_signal_emit_by_name (mount->monitor, "mount-pre-unmount", mount);
@@ -913,11 +929,54 @@ gvfs_udisks2_mount_unmount_with_operation (GMount *_mount,
/* burn mounts are really never mounted so complete successfully immediately */
g_simple_async_result_complete_in_idle (data->simple);
unmount_data_free (data);
+ goto out;
}
- else
+
+ block = gvfs_udisks2_volume_get_block (data->mount->volume);
+ if (block != NULL)
{
- unmount_do (data, FALSE);
+ object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block)));
+ data->filesystem = udisks_object_get_filesystem (object);
+ if (data->filesystem == NULL)
+ {
+ UDisksBlock *cleartext_block;
+
+ data->encrypted = udisks_object_get_encrypted (object);
+ if (data->encrypted == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No filesystem or encrypted interface on D-Bus object");
+ g_simple_async_result_complete (data->simple);
+ unmount_data_free (data);
+ goto out;
+ }
+
+ cleartext_block = udisks_client_get_cleartext_block (gvfs_udisks2_volume_monitor_get_udisks_client (mount->monitor),
+ block);
+ if (cleartext_block != NULL)
+ {
+ data->filesystem = udisks_object_get_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (cleartext_block))));
+ g_object_unref (cleartext_block);
+ if (data->filesystem == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No filesystem interface on D-Bus object for cleartext device");
+ g_simple_async_result_complete (data->simple);
+ unmount_data_free (data);
+ goto out;
+ }
+ }
+ }
+ g_assert (data->filesystem != NULL);
}
+ unmount_do (data, FALSE /* force */);
+
+ out:
+ ;
}
static gboolean
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
index 1f48d75..fa9cb28 100644
--- a/monitor/udisks2/gvfsudisks2volume.c
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -83,6 +83,9 @@ static void on_block_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data);
+static void on_udisks_client_changed (UDisksClient *client,
+ gpointer user_data);
+
G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Volume, gvfs_udisks2_volume, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, gvfs_udisks2_volume_volume_iface_init))
@@ -91,6 +94,10 @@ gvfs_udisks2_volume_finalize (GObject *object)
{
GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (object);
+ g_signal_handlers_disconnect_by_func (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
+ G_CALLBACK (on_udisks_client_changed),
+ volume);
+
if (volume->mount != NULL)
{
gvfs_udisks2_mount_unset_volume (volume->mount, volume);
@@ -207,17 +214,36 @@ update_volume (GVfsUDisks2Volume *volume)
if (volume->block != NULL)
{
const gchar *hint;
+ UDisksBlock *block;
+ UDisksBlock *cleartext_block;
+
+ /* If unlocked, use the values from the unlocked block device for presentation */
+ cleartext_block = udisks_client_get_cleartext_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
+ volume->block);
+ if (cleartext_block != NULL)
+ block = cleartext_block;
+ else
+ block = volume->block;
- volume->dev = makedev (udisks_block_get_major (volume->block), udisks_block_get_minor (volume->block));
- volume->device_file = udisks_block_dup_device (volume->block);
+ volume->dev = makedev (udisks_block_get_major (block), udisks_block_get_minor (block));
+ volume->device_file = udisks_block_dup_device (block);
- if (strlen (udisks_block_get_id_label (volume->block)) > 0)
+ if (strlen (udisks_block_get_id_label (block)) > 0)
{
- volume->name = g_strdup (udisks_block_get_id_label (volume->block));
+ volume->name = g_strdup (udisks_block_get_id_label (block));
+ }
+ else if (g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0)
+ {
+ s = udisks_util_get_size_for_display (udisks_block_get_size (volume->block), FALSE, FALSE);
+ /* Translators: This is used for encrypted volumes.
+ * The first %s is the formatted size (e.g. "42.0 MB").
+ */
+ volume->name = g_strdup_printf (_("%s Encrypted"), s);
+ g_free (s);
}
else
{
- s = g_format_size (udisks_block_get_size (volume->block));
+ s = udisks_util_get_size_for_display (udisks_block_get_size (block), FALSE, FALSE);
/* Translators: This is used for volume with no filesystem label.
* The first %s is the formatted size (e.g. "42.0 MB").
*/
@@ -226,7 +252,7 @@ update_volume (GVfsUDisks2Volume *volume)
}
udisks_drive = udisks_client_get_drive_for_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
- volume->block);
+ volume->block);
if (udisks_drive != NULL)
{
gchar *drive_desc;
@@ -285,6 +311,27 @@ update_volume (GVfsUDisks2Volume *volume)
g_clear_object (&volume->icon);
volume->icon = g_themed_icon_new_with_default_fallbacks (hint);
}
+
+ /* Add an emblem, depending on whether the encrypted volume is locked or unlocked */
+ if (g_strcmp0 (udisks_block_get_id_type (volume->block), "crypto_LUKS") == 0 && volume->icon != NULL)
+ {
+ GEmblem *emblem;
+ GIcon *padlock;
+ GIcon *emblemed_icon;
+ if (cleartext_block != NULL)
+ padlock = g_themed_icon_new ("changes-allow");
+ else
+ padlock = g_themed_icon_new ("changes-prevent");
+ emblem = g_emblem_new_with_origin (padlock, G_EMBLEM_ORIGIN_DEVICE);
+ emblemed_icon = g_emblemed_icon_new (volume->icon, emblem);
+ g_object_unref (padlock);
+ g_object_unref (emblem);
+
+ g_object_unref (volume->icon);
+ volume->icon = emblemed_icon;
+ }
+
+ g_clear_object (&cleartext_block);
}
else
{
@@ -338,6 +385,8 @@ update_volume (GVfsUDisks2Volume *volume)
return changed;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
on_block_changed (GObject *object,
GParamSpec *pspec,
@@ -348,6 +397,18 @@ on_block_changed (GObject *object,
emit_changed (volume);
}
+static void
+on_udisks_client_changed (UDisksClient *client,
+ gpointer user_data)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (user_data);
+ /* This is a little too broad - technically we only need to do this if our block
+ * device has gained or lost a cleartext device...
+ */
+ if (update_volume (volume))
+ emit_changed (volume);
+}
+
/* takes ownership of @mount_point if not NULL */
GVfsUDisks2Volume *
gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor *monitor,
@@ -383,9 +444,20 @@ gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor *monitor,
update_volume (volume);
+ /* For LUKS devices, we also need to listen for changes on any possible cleartext device */
+ if (volume->block != NULL && g_strcmp0 (udisks_block_get_id_type (volume->block), "crypto_LUKS") == 0)
+ {
+ g_signal_connect (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
+ "changed",
+ G_CALLBACK (on_udisks_client_changed),
+ volume);
+ }
+
return volume;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
void
gvfs_udisks2_volume_removed (GVfsUDisks2Volume *volume)
{
@@ -588,31 +660,53 @@ struct MountData
GSimpleAsyncResult *simple;
GVfsUDisks2Volume *volume;
-
GCancellable *cancellable;
+ gulong mount_operation_reply_handler_id;
+ gulong mount_operation_aborted_handler_id;
GMountOperation *mount_operation;
+
+ gchar *passphrase;
+
+ UDisksEncrypted *encrypted_to_unlock;
+ UDisksFilesystem *filesystem_to_mount;
+
};
static void
mount_data_free (MountData *data)
{
+ if (data->volume->mount_pending_op == data)
+ data->volume->mount_pending_op = NULL;
+
g_object_unref (data->simple);
g_clear_object (&data->volume);
g_clear_object (&data->cancellable);
- g_clear_object (&data->mount_operation);
+
+ if (data->mount_operation != NULL)
+ {
+ if (data->mount_operation_reply_handler_id != 0)
+ g_signal_handler_disconnect (data->mount_operation, data->mount_operation_reply_handler_id);
+ if (data->mount_operation_aborted_handler_id != 0)
+ g_signal_handler_disconnect (data->mount_operation, data->mount_operation_aborted_handler_id);
+ g_object_unref (data->mount_operation);
+ }
+
+ g_free (data->passphrase);
+
+ g_clear_object (&data->encrypted_to_unlock);
+ g_clear_object (&data->filesystem_to_mount);
g_free (data);
}
static void
mount_cancel_pending_op (MountData *data)
{
+ g_cancellable_cancel (data->cancellable);
/* send an ::aborted signal to make the dialog go away */
if (data->mount_operation != NULL)
g_signal_emit_by_name (data->mount_operation, "aborted");
- g_cancellable_cancel (data->cancellable);
- data->volume->mount_pending_op = NULL;
}
/* ------------------------------ */
@@ -649,11 +743,11 @@ do_mount_command (MountData *data)
/* TODO: for e.g. NFS and CIFS mounts we could do GMountOperation stuff and pipe a
* password to mount(8)'s stdin channel
+ *
+ * TODO: if this fails because the user is not authorized (e.g. EPERM), we could
+ * run it through a polkit-ified setuid root helper
*/
- /* we are no longer pending */
- data->volume->mount_pending_op = NULL;
-
if (WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0)
{
gvfs_udisks2_volume_monitor_update (data->volume->monitor);
@@ -684,9 +778,6 @@ mount_cb (GObject *source_object,
gchar *mount_path;
GError *error;
- /* we are no longer pending */
- data->volume->mount_pending_op = NULL;
-
error = NULL;
if (!udisks_filesystem_call_mount_finish (UDISKS_FILESYSTEM (source_object),
&mount_path,
@@ -707,6 +798,200 @@ mount_cb (GObject *source_object,
}
static void
+do_mount (MountData *data)
+{
+ GVariantBuilder builder;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ if (data->mount_operation == NULL)
+ {
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+ }
+ udisks_filesystem_call_mount (data->filesystem_to_mount,
+ g_variant_builder_end (&builder),
+ data->cancellable,
+ mount_cb,
+ data);
+}
+
+/* ------------------------------ */
+
+static void
+unlock_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MountData *data = user_data;
+ gchar *cleartext_device = NULL;
+ GError *error;
+
+ error = NULL;
+ if (!udisks_encrypted_call_unlock_finish (UDISKS_ENCRYPTED (source_object),
+ &cleartext_device,
+ res,
+ &error))
+ {
+ gvfs_udisks2_utils_udisks_error_to_gio_error (error);
+ g_simple_async_result_take_error (data->simple, error);
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+ else
+ {
+ UDisksObject *object;
+
+ gvfs_udisks2_volume_monitor_update (data->volume->monitor);
+
+ object = udisks_client_peek_object (gvfs_udisks2_volume_monitor_get_udisks_client (data->volume->monitor),
+ cleartext_device);
+ data->filesystem_to_mount = object != NULL ? udisks_object_get_filesystem (object) : NULL;
+ if (data->filesystem_to_mount == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("The unlocked device does not have a recognizable filesystem on it"));
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+
+ /* TODO: save in keyring depending on ASK_SAVE */
+
+ /* OK, ready to rock */
+ do_mount (data);
+ }
+
+ out:
+ g_free (cleartext_device);
+}
+
+static void do_unlock (MountData *data);
+
+static void
+on_mount_operation_reply (GMountOperation *mount_operation,
+ GMountOperationResult result,
+ gpointer user_data)
+{
+ MountData *data = user_data;
+
+ /* we got what we wanted; don't listen to any other signals from the mount operation */
+ if (data->mount_operation_reply_handler_id != 0)
+ {
+ g_signal_handler_disconnect (data->mount_operation, data->mount_operation_reply_handler_id);
+ data->mount_operation_reply_handler_id = 0;
+ }
+ if (data->mount_operation_aborted_handler_id != 0)
+ {
+ g_signal_handler_disconnect (data->mount_operation, data->mount_operation_aborted_handler_id);
+ data->mount_operation_aborted_handler_id = 0;
+ }
+
+ if (result != G_MOUNT_OPERATION_HANDLED)
+ {
+ if (result == G_MOUNT_OPERATION_ABORTED)
+ {
+ /* The user aborted the operation so consider it "handled" */
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED_HANDLED,
+ "Password dialog aborted (user should never see this error since it is G_IO_ERROR_FAILED_HANDLED)");
+ }
+ else
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED,
+ "Expected G_MOUNT_OPERATION_HANDLED but got %d", result);
+ }
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+
+ data->passphrase = g_strdup (g_mount_operation_get_password (mount_operation));
+
+ /* TODO: check ASK_SAVE */
+ do_unlock (data);
+
+ out:
+ ;
+}
+
+static void
+on_mount_operation_aborted (GMountOperation *mount_operation,
+ gpointer user_data)
+{
+ on_mount_operation_reply (mount_operation, G_MOUNT_OPERATION_ABORTED, user_data);
+}
+
+static void
+do_unlock (MountData *data)
+{
+ GVariantBuilder builder;
+
+ /* TODO: lookup passphrase in keyring */
+
+ if (data->passphrase == NULL)
+ {
+ gchar *message;
+
+ if (data->mount_operation == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("A passphrase is required to access the volume"));
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+
+ data->mount_operation_reply_handler_id = g_signal_connect (data->mount_operation,
+ "reply",
+ G_CALLBACK (on_mount_operation_reply),
+ data);
+ data->mount_operation_aborted_handler_id = g_signal_connect (data->mount_operation,
+ "aborted",
+ G_CALLBACK (on_mount_operation_aborted),
+ data);
+ message = g_strdup_printf (_("Enter a password to unlock the volume\n"
+ "The device %s contains encrypted data."),
+ udisks_block_get_device (data->volume->block));
+ g_signal_emit_by_name (data->mount_operation,
+ "ask-password",
+ message,
+ NULL,
+ NULL,
+ G_ASK_PASSWORD_NEED_PASSWORD |
+ 0/*G_ASK_PASSWORD_SAVING_SUPPORTED*/);
+ g_free (message);
+ goto out;
+ }
+
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ if (data->mount_operation == NULL)
+ {
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+ }
+ udisks_encrypted_call_unlock (data->encrypted_to_unlock,
+ data->passphrase,
+ g_variant_builder_end (&builder),
+ data->cancellable,
+ unlock_cb,
+ data);
+ out:
+ ;
+}
+
+
+static void
gvfs_udisks2_volume_mount (GVolume *_volume,
GMountMountFlags flags,
GMountOperation *mount_operation,
@@ -715,8 +1000,9 @@ gvfs_udisks2_volume_mount (GVolume *_volume,
gpointer user_data)
{
GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ UDisksObject *object;
+ UDisksBlock *block;
UDisksFilesystem *filesystem;
- GVariantBuilder builder;
MountData *data;
data = g_new0 (MountData, 1);
@@ -746,30 +1032,36 @@ gvfs_udisks2_volume_mount (GVolume *_volume,
goto out;
}
- filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (volume->block))));
+ /* if encrypted and already unlocked, just mount the cleartext block device */
+ block = udisks_client_get_cleartext_block (gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor),
+ volume->block);
+ if (block != NULL)
+ g_object_unref (block);
+ else
+ block = volume->block;
+
+ object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block)));
+ filesystem = udisks_object_peek_filesystem (object);
if (filesystem == NULL)
{
+ data->encrypted_to_unlock = udisks_object_get_encrypted (object);
+ if (data->encrypted_to_unlock != NULL)
+ {
+ do_unlock (data);
+ goto out;
+ }
+
g_simple_async_result_set_error (data->simple,
G_IO_ERROR,
G_IO_ERROR_FAILED,
- "No filesystem interface on D-Bus object");
+ "No .Filesystem or .Encrypted interface on D-Bus object");
g_simple_async_result_complete (data->simple);
mount_data_free (data);
goto out;
}
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
- if (data->mount_operation == NULL)
- {
- g_variant_builder_add (&builder,
- "{sv}",
- "auth.no_user_interaction", g_variant_new_boolean (TRUE));
- }
- udisks_filesystem_call_mount (filesystem,
- g_variant_builder_end (&builder),
- data->cancellable,
- mount_cb,
- data);
+ data->filesystem_to_mount = g_object_ref (filesystem);
+ do_mount (data);
out:
;
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c
index a64d31e..62c7c10 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.c
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.c
@@ -90,30 +90,8 @@ static void update_discs (GVfsUDisks2VolumeMonitor *monitor,
GList **removed_mounts);
-static void on_object_added (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data);
-
-static void on_object_removed (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data);
-
-static void on_interface_added (GDBusObjectManager *manager,
- GDBusObject *object,
- GDBusInterface *interface,
- gpointer user_data);
-
-static void on_interface_removed (GDBusObjectManager *manager,
- GDBusObject *object,
- GDBusInterface *interface,
- gpointer user_data);
-
-static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
- GDBusObjectProxy *object_proxy,
- GDBusProxy *interface_proxy,
- GVariant *changed_properties,
- const gchar *const *invalidated_properties,
- gpointer user_data);
+static void on_client_changed (UDisksClient *client,
+ gpointer user_data);
static void mountpoints_changed (GUnixMountMonitor *mount_monitor,
gpointer user_data);
@@ -136,27 +114,13 @@ static void
gvfs_udisks2_volume_monitor_finalize (GObject *object)
{
GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (object);
- GDBusObjectManager *object_manager;
g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mountpoints_changed, monitor);
g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mounts_changed, monitor);
g_clear_object (&monitor->mount_monitor);
- object_manager = udisks_client_get_object_manager (monitor->client);
- g_signal_handlers_disconnect_by_func (object_manager,
- G_CALLBACK (on_object_added),
- monitor);
- g_signal_handlers_disconnect_by_func (object_manager,
- G_CALLBACK (on_object_removed),
- monitor);
- g_signal_handlers_disconnect_by_func (object_manager,
- G_CALLBACK (on_interface_added),
- monitor);
- g_signal_handlers_disconnect_by_func (object_manager,
- G_CALLBACK (on_interface_removed),
- monitor);
- g_signal_handlers_disconnect_by_func (object_manager,
- G_CALLBACK (on_interface_proxy_properties_changed),
+ g_signal_handlers_disconnect_by_func (monitor->client,
+ G_CALLBACK (on_client_changed),
monitor);
g_clear_object (&monitor->client);
@@ -337,31 +301,12 @@ gvfs_udisks2_volume_monitor_constructor (GType type,
static void
gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor)
{
- GDBusObjectManager *object_manager;
-
- monitor->client = get_udisks_client_sync (NULL);
monitor->gudev_client = g_udev_client_new (NULL); /* don't listen to any changes */
- object_manager = udisks_client_get_object_manager (monitor->client);
- g_signal_connect (object_manager,
- "object-added",
- G_CALLBACK (on_object_added),
- monitor);
- g_signal_connect (object_manager,
- "object-removed",
- G_CALLBACK (on_object_removed),
- monitor);
- g_signal_connect (object_manager,
- "interface-added",
- G_CALLBACK (on_interface_added),
- monitor);
- g_signal_connect (object_manager,
- "interface-removed",
- G_CALLBACK (on_interface_removed),
- monitor);
- g_signal_connect (object_manager,
- "interface-proxy-properties-changed",
- G_CALLBACK (on_interface_proxy_properties_changed),
+ monitor->client = get_udisks_client_sync (NULL);
+ g_signal_connect (monitor->client,
+ "changed",
+ G_CALLBACK (on_client_changed),
monitor);
monitor->mount_monitor = g_unix_mount_monitor_new ();
@@ -541,57 +486,10 @@ object_list_emit (GVfsUDisks2VolumeMonitor *monitor,
/* ---------------------------------------------------------------------------------------------------- */
static void
-on_object_added (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
- // g_debug ("on_object_added %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
- update_all (monitor, TRUE);
-}
-
-static void
-on_object_removed (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
- // g_debug ("on_object_removed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
- update_all (monitor, TRUE);
-}
-
-static void
-on_interface_added (GDBusObjectManager *manager,
- GDBusObject *object,
- GDBusInterface *interface,
- gpointer user_data)
-{
- GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
- // g_debug ("on_interface_added %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
- update_all (monitor, TRUE);
-}
-
-static void
-on_interface_removed (GDBusObjectManager *manager,
- GDBusObject *object,
- GDBusInterface *interface,
- gpointer user_data)
+on_client_changed (UDisksClient *client,
+ gpointer user_data)
{
GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
- // g_debug ("on_interface_removed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
- update_all (monitor, TRUE);
-}
-
-static void
-on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
- GDBusObjectProxy *object_proxy,
- GDBusProxy *interface_proxy,
- GVariant *changed_properties,
- const gchar *const *invalidated_properties,
- gpointer user_data)
-{
- GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
- // g_debug ("on_interface_proxy_properties_changed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy)));
update_all (monitor, TRUE);
}
@@ -724,10 +622,40 @@ should_include_volume_check_mount_points (GVfsUDisks2VolumeMonitor *monitor,
static gboolean
should_include_volume (GVfsUDisks2VolumeMonitor *monitor,
- UDisksBlock *block)
+ UDisksBlock *block,
+ gboolean allow_encrypted_cleartext)
{
gboolean ret = FALSE;
+ /* show encrypted volumes... */
+ if (g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0)
+ {
+ UDisksBlock *cleartext_block;
+ /* ... unless the volume is unlocked and we don't want to show the cleartext volume */
+ cleartext_block = udisks_client_get_cleartext_block (monitor->client, block);
+ if (cleartext_block != NULL)
+ {
+ ret = should_include_volume (monitor, cleartext_block, TRUE);
+ g_object_unref (cleartext_block);
+ }
+ else
+ {
+ ret = TRUE;
+ }
+ goto out;
+ }
+
+ if (!allow_encrypted_cleartext)
+ {
+ /* ... but not unlocked volumes (because the volume for the encrypted part morphs
+ * into the cleartext part when unlocked)
+ */
+ if (g_strcmp0 (udisks_block_get_crypto_backing_device (block), "/") != 0)
+ {
+ goto out;
+ }
+ }
+
/* Check should_include_mount() for all mount points, if any - e.g. if a volume
* is mounted in a place where the mount is to be ignored, we ignore the volume
* as well
@@ -1162,7 +1090,7 @@ update_volumes (GVfsUDisks2VolumeMonitor *monitor,
UDisksBlock *block = udisks_object_peek_block (UDISKS_OBJECT (l->data));
if (block == NULL)
continue;
- if (should_include_volume (monitor, block))
+ if (should_include_volume (monitor, block, FALSE))
new_block_volumes = g_list_prepend (new_block_volumes, block);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]