summaryrefslogtreecommitdiff
path: root/monitor
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2016-03-24 12:07:43 +0100
committerOndrej Holy <oholy@redhat.com>2016-04-06 16:16:34 +0200
commitbeea21e124d95c2f7cc0130148084e5e86eb46e5 (patch)
tree4804da678468dd33b7ea7b5eebf01ad099ff922f /monitor
parentdd98c02ecde5cc081a2d0e3990780efe3d66edfa (diff)
downloadgvfs-beea21e124d95c2f7cc0130148084e5e86eb46e5.tar.gz
udisks2: Abort mount operation if volume is unlocked
Mount operation for encrypted volumes consists from two udisks2 calls (unlock and mount). Volume monitor is able to mount already unlocked volumes. However password prompt doesn't disappear if the volume is unlocked externally and any reaction causes mount operation failure. The volume may be unlocked externally by e.g. project Tang, see https://github.com/latchset/tang for more details. Abort mount operation and continue with mounting in such situations. https://bugzilla.gnome.org/show_bug.cgi?id=763890
Diffstat (limited to 'monitor')
-rw-r--r--monitor/udisks2/gvfsudisks2volume.c105
1 files changed, 80 insertions, 25 deletions
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
index fac90e5c..8bb572d9 100644
--- a/monitor/udisks2/gvfsudisks2volume.c
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -87,6 +87,30 @@ struct _GVfsUDisks2Volume
MountData *mount_pending_op;
};
+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;
+
+ gchar *passphrase_from_keyring;
+ GPasswordSave password_save;
+
+ gchar *uuid_of_encrypted_to_unlock;
+ gchar *desc_of_encrypted_to_unlock;
+ UDisksEncrypted *encrypted_to_unlock;
+ UDisksFilesystem *filesystem_to_mount;
+
+ gboolean checked_keyring;
+};
+
static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);
static void on_block_changed (GObject *object,
@@ -584,7 +608,22 @@ on_udisks_client_changed (UDisksClient *client,
gpointer user_data)
{
GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (user_data);
+ MountData *data = volume->mount_pending_op;
+
update_volume_on_event (volume);
+
+ if (data && data->mount_operation_aborted_handler_id && data->encrypted_to_unlock)
+ {
+ UDisksBlock *cleartext_block;
+
+ cleartext_block = udisks_client_get_cleartext_block (client, volume->block);
+ if (cleartext_block != NULL)
+ {
+ g_object_set_data (G_OBJECT (data->mount_operation), "x-udisks2-is-unlocked", GINT_TO_POINTER (1));
+ g_signal_emit_by_name (data->mount_operation, "aborted");
+ g_object_unref (cleartext_block);
+ }
+ }
}
/* takes ownership of @mount_point if not NULL */
@@ -882,30 +921,6 @@ static SecretSchema luks_passphrase_schema =
};
#endif
-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;
-
- gchar *passphrase_from_keyring;
- GPasswordSave password_save;
-
- gchar *uuid_of_encrypted_to_unlock;
- gchar *desc_of_encrypted_to_unlock;
- UDisksEncrypted *encrypted_to_unlock;
- UDisksFilesystem *filesystem_to_mount;
-
- gboolean checked_keyring;
-};
-
static void
mount_data_free (MountData *data)
{
@@ -1269,7 +1284,47 @@ on_mount_operation_reply (GMountOperation *mount_operation,
if (result != G_MOUNT_OPERATION_HANDLED)
{
- if (result == G_MOUNT_OPERATION_ABORTED)
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data->mount_operation), "x-udisks2-is-unlocked")) == 1)
+ {
+ UDisksClient *client;
+ UDisksBlock *cleartext_block;
+
+ g_object_set_data (G_OBJECT (data->mount_operation), "x-udisks2-is-unlocked", GINT_TO_POINTER (0));
+
+ client = gvfs_udisks2_volume_monitor_get_udisks_client (data->volume->monitor);
+ cleartext_block = udisks_client_get_cleartext_block (client, data->volume->block);
+ if (cleartext_block != NULL)
+ {
+ UDisksObject *object;
+
+ object = g_dbus_interface_get_object (G_DBUS_INTERFACE (cleartext_block));
+ g_object_unref (cleartext_block);
+ if (object != NULL)
+ {
+ data->filesystem_to_mount = udisks_object_get_filesystem (object);
+ if (data->filesystem_to_mount != NULL)
+ {
+ do_mount (data);
+ goto out;
+ }
+ else
+ {
+ 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");
+ }
+ }
+ else
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No object for D-Bus interface");
+ }
+ }
+ }
+ else if (result == G_MOUNT_OPERATION_ABORTED)
{
/* The user aborted the operation so consider it "handled" */
g_simple_async_result_set_error (data->simple,