diff options
author | Ondrej Holy <oholy@redhat.com> | 2016-03-24 12:07:43 +0100 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2016-04-06 16:16:34 +0200 |
commit | beea21e124d95c2f7cc0130148084e5e86eb46e5 (patch) | |
tree | 4804da678468dd33b7ea7b5eebf01ad099ff922f /monitor | |
parent | dd98c02ecde5cc081a2d0e3990780efe3d66edfa (diff) | |
download | gvfs-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.c | 105 |
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, |