diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2009-04-21 17:11:16 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2009-04-27 15:05:23 +0200 |
commit | 17966e22969c863e81711408d50ff4173621b44b (patch) | |
tree | 0fc3bd276440d63ffe4a7b4eb62f447976ee4882 | |
parent | 83ce37c97ab04ed8699c5bbea56dbd34e28f912e (diff) | |
download | gnome-disk-utility-17966e22969c863e81711408d50ff4173621b44b.tar.gz gnome-disk-utility-17966e22969c863e81711408d50ff4173621b44b.tar.xz gnome-disk-utility-17966e22969c863e81711408d50ff4173621b44b.zip |
lock the LUKS device before formatting
-rw-r--r-- | src/gdu-format-tool/TODO | 4 | ||||
-rw-r--r-- | src/gdu-format-tool/format-window-operation.c | 108 | ||||
-rw-r--r-- | src/gdu-format-tool/format-window-operation.h | 2 | ||||
-rw-r--r-- | src/gdu-format-tool/gdu-utils.c | 113 | ||||
-rw-r--r-- | src/gdu-format-tool/gdu-utils.h | 3 |
5 files changed, 167 insertions, 63 deletions
diff --git a/src/gdu-format-tool/TODO b/src/gdu-format-tool/TODO index c3c8242..742110a 100644 --- a/src/gdu-format-tool/TODO +++ b/src/gdu-format-tool/TODO @@ -11,9 +11,10 @@ Short-term: DONE, NEEDS_TESTING - !! set partition type too !! (only for MBR?) OK - check label length before formatting (should be done automatically) -- DK returning wrong values for FAT and NTFS DONE - get rid of the Revert button - - call luks_lock() beside unmount, that would allow formatting active LUKS devices + DONE - call luks_lock() beside unmount, that would allow formatting active LUKS devices DONE - install to libexec DONE - add Palimpsest button + - display mount warning and perform unmount of all nested partitions, in case of LUKS Standalone mode: DONE - refresh volume selector on hotplug/unplug @@ -58,3 +59,4 @@ Bugs: - gdu_presentable_get_toplevel() always returns valid presentable even if it's already toplevel (i.e. /dev/md0), never returns NULL - gdu_device_drive_get_media_compatibility() returns const char* pointers - check and document properly - BUG !! gdu_device_op_partition_create() and gdu_device_op_partition_table_create() should spawn their finish callbacks only after device is ready (and pool up-to-date) so we can start another operation right away + SOLVED - find a way to reliably detect active LUKS on the device diff --git a/src/gdu-format-tool/format-window-operation.c b/src/gdu-format-tool/format-window-operation.c index 0c21c3c..a1a61f8 100644 --- a/src/gdu-format-tool/format-window-operation.c +++ b/src/gdu-format-tool/format-window-operation.c @@ -51,7 +51,7 @@ device_needs_partition_table (GduDevice *device) media_compat = gdu_device_drive_get_media_compatibility (device); for (; *media_compat; media_compat++) { - g_print (" compat '%s'\n", *media_compat); + g_debug (" compat '%s'\n", *media_compat); /* http://hal.freedesktop.org/docs/DeviceKit-disks/Device.html#Device:drive-media-compatibility */ if (strstr (*media_compat, "optical") == *media_compat || strstr (*media_compat, "floppy") == *media_compat) { @@ -147,6 +147,8 @@ static void part_table_new_auth_end_callback (PolKitGnomeAction *action, gboolea static void part_table_new_action_callback (GtkAction *action, gpointer user_data); static void part_new_auth_end_callback (PolKitGnomeAction *action, gboolean gained_privilege, gpointer user_data); static void part_new_action_callback (GtkAction *action, gpointer user_data); +static void luks_lock_auth_end_callback (PolKitGnomeAction *action, gboolean gained_privilege, gpointer user_data); +static void luks_lock_action_callback (GtkAction *action, gpointer user_data); void update_ui_progress (FormatDialogPrivate *priv, @@ -197,7 +199,13 @@ update_ui_progress (FormatDialogPrivate *priv, data->part_new_action = polkit_gnome_action_new_default ("part_new", data->pk_part_new_action, NULL, NULL); g_signal_connect (data->part_new_action, "auth-end", G_CALLBACK (part_new_auth_end_callback), data); g_signal_connect (data->part_new_action, "activate", G_CALLBACK (part_new_action_callback), data); - } + + data->pk_luks_lock_action = polkit_action_new (); + polkit_action_set_action_id (data->pk_luks_lock_action, "org.freedesktop.devicekit.disks.luks-lock-others"); + data->luks_lock_action = polkit_gnome_action_new_default ("luks_lock", data->pk_luks_lock_action, NULL, NULL); + g_signal_connect (data->luks_lock_action, "auth-end", G_CALLBACK (luks_lock_auth_end_callback), data); + g_signal_connect (data->luks_lock_action, "activate", G_CALLBACK (luks_lock_action_callback), data); +} } else { @@ -207,6 +215,7 @@ update_ui_progress (FormatDialogPrivate *priv, g_signal_handlers_disconnect_matched (data->part_modify_action, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); g_signal_handlers_disconnect_matched (data->part_table_new_action, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); g_signal_handlers_disconnect_matched (data->part_new_action, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); + g_signal_handlers_disconnect_matched (data->luks_lock_action, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); /* destroy PolicyKit actions */ polkit_action_unref (data->pk_unmount_action); @@ -219,6 +228,8 @@ update_ui_progress (FormatDialogPrivate *priv, g_object_unref (data->part_table_new_action); polkit_action_unref (data->pk_part_new_action); g_object_unref (data->part_new_action); + polkit_action_unref (data->pk_luks_lock_action); + g_object_unref (data->luks_lock_action); g_signal_handlers_disconnect_matched (data->presentable, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); if (data->job_progress_pulse_timer_id > 0) { @@ -604,6 +615,71 @@ format_auth_end_callback (PolKitGnomeAction *action, /* ---------------------------------------------------------------------------------------------------- */ +static void +luks_lock_completed (GduDevice *device, + GError *error, + gpointer user_data) +{ + FormatProcessData *data = user_data; + + g_return_if_fail (data != NULL); + + g_debug ("luks_lock_completed"); + update_ui_controls (data->priv); + + if (error != NULL) { + nautilus_gdu_show_error (GTK_WIDGET (data->priv->dialog), + data->presentable, + error, + _("Error while locking the device")); + free_format_action_data (data); + g_error_free (error); + } + else + { + /* TODO: maybe perform a refresh? */ + g_debug (" formatting..."); + if (data->priv->job_cancelled) + return; + gtk_action_activate (GTK_ACTION (data->format_action)); + } +} + +static void +luks_lock_action_callback (GtkAction *action, gpointer user_data) +{ + FormatProcessData *data = user_data; + + g_return_if_fail (data != NULL); + g_debug ("luks_lock_action_callback"); + + if (data->priv->job_cancelled) + return; + + gdu_device_op_luks_lock (data->device, luks_lock_completed, data); +} + +static void +luks_lock_auth_end_callback (PolKitGnomeAction *action, + gboolean gained_privilege, + gpointer user_data) +{ + FormatProcessData *data = user_data; + + g_return_if_fail (data != NULL); + g_debug ("luks_lock_auth_end_callback"); + + if (! gained_privilege) { + /* cancel the whole operation */ + free_format_action_data (data); + } + else { + /* positive reply should be handled by luks_lock_action_callback */ + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + static gboolean unmount_show_busy (gpointer user_data) { @@ -652,11 +728,18 @@ unmount_action_completed (GduDevice *device, } else { - /* TODO: maybe perform a refresh? */ - g_debug (" formatting..."); if (data->priv->job_cancelled) return; - gtk_action_activate (GTK_ACTION (data->format_action)); + /* TODO: maybe perform a refresh? */ + if (is_active_luks (data->priv->pool, data->priv->presentable)) { + g_debug ("device is active luks, locking first...\n"); + /* gtk_action_activate (GTK_ACTION (data->luks_lock_action)); */ + /* TODO: detect, when we need org.freedesktop.devicekit.disks.luks-lock-others */ + luks_lock_action_callback (GTK_ACTION (data->luks_lock_action), data); + } else { + g_debug (" formatting..."); + gtk_action_activate (GTK_ACTION (data->format_action)); + } } } @@ -976,6 +1059,7 @@ do_format (FormatDialogPrivate *priv) "This action cannot be undone."), drive_name); } + } update_ui_progress (priv, data, TRUE); @@ -1000,6 +1084,16 @@ do_format (FormatDialogPrivate *priv) } } + if (gdu_device_is_mounted (data->device)) { + /* unmount the device before formatting */ + gtk_action_activate (GTK_ACTION (data->unmount_action)); + } else + if (is_active_luks (priv->pool, priv->presentable)) { + g_debug ("device is active luks, locking first...\n"); + /* gtk_action_activate (GTK_ACTION (data->luks_lock_action)); */ + /* TODO: detect, when we need org.freedesktop.devicekit.disks.luks-lock-others */ + luks_lock_action_callback (GTK_ACTION (data->luks_lock_action), data); + } else if (create_new_part_table && device_needs_partition_table (data->device)) { /* device is zeroed, create partition table first */ gtk_action_activate (GTK_ACTION (data->part_table_new_action)); @@ -1007,10 +1101,6 @@ do_format (FormatDialogPrivate *priv) if (create_new_partition && device_needs_partition_table (data->device)) { /* device has partition table but has no partition */ gtk_action_activate (GTK_ACTION (data->part_new_action)); - } else - if (gdu_device_is_mounted (data->device)) { - /* unmount the device before formatting */ - gtk_action_activate (GTK_ACTION (data->unmount_action)); } else { gtk_action_activate (GTK_ACTION (data->format_action)); } diff --git a/src/gdu-format-tool/format-window-operation.h b/src/gdu-format-tool/format-window-operation.h index 39feaea..abcb62e 100644 --- a/src/gdu-format-tool/format-window-operation.h +++ b/src/gdu-format-tool/format-window-operation.h @@ -57,6 +57,8 @@ typedef struct { PolKitGnomeAction *part_table_new_action; PolKitAction *pk_part_new_action; PolKitGnomeAction *part_new_action; + PolKitAction *pk_luks_lock_action; + PolKitGnomeAction *luks_lock_action; } FormatProcessData; diff --git a/src/gdu-format-tool/gdu-utils.c b/src/gdu-format-tool/gdu-utils.c index 982900e..a0837c1 100644 --- a/src/gdu-format-tool/gdu-utils.c +++ b/src/gdu-format-tool/gdu-utils.c @@ -34,80 +34,66 @@ #include "gdu-utils.h" -static GduPresentable * -_find_presentable (char *mount_path, char *device_path) + +GduPresentable * +find_presentable_from_mount_path (char *mount_path) { GduPool *pool; - GList *presentables, *presentables_w; + GList *devices, *l; GduPresentable *presentable = NULL; - GduPresentable *pres_w; GduDevice *device; const char *device_mount; - const char *device_file; GFile *file1, *file2; + g_return_val_if_fail (mount_path != NULL, NULL); + g_return_val_if_fail (strlen (mount_path) > 1, NULL); + pool = gdu_pool_new (); - presentables = gdu_pool_get_presentables (pool); - - presentables_w = presentables; - while (presentables_w != NULL) { - pres_w = presentables_w->data; -#if 0 - if (pres_w) - g_print ("presentable '%s', ref count = %d [%p]\n", gdu_presentable_get_name (pres_w), ((GObject*)pres_w)->ref_count, pres_w); -#endif - if (! presentable && pres_w) { - device = gdu_presentable_get_device (pres_w); - if (device) { - device_mount = gdu_device_get_mount_path (device); - device_file = gdu_device_get_device_file (device); - - /* match mount_path */ - if (mount_path && device_mount && strlen (device_mount) > 1) { - /* compare via GFile routines */ - file1 = g_file_new_for_commandline_arg (mount_path); - file2 = g_file_new_for_path (device_mount); - if (g_file_equal (file1, file2)) - presentable = g_object_ref (pres_w); - g_object_unref (file1); - g_object_unref (file2); - if (presentable) - break; - } - /* match device_path */ - if (device_path && device_file && strlen (device_file) > 1) { - if (strcmp (device_file, device_path) == 0) { - presentable = g_object_ref (pres_w); - break; - } - } - g_object_unref (device); - } + devices = gdu_pool_get_devices (pool); + + for (l = devices; l != NULL; l = l->next) { + device = GDU_DEVICE (l->data); + device_mount = gdu_device_get_mount_path (device); + + if (mount_path && device_mount && strlen (device_mount) > 1) { + /* compare via GFile routines */ + file1 = g_file_new_for_commandline_arg (mount_path); + file2 = g_file_new_for_path (device_mount); + if (g_file_equal (file1, file2)) + presentable = gdu_pool_get_volume_by_device (pool, device); /* auto-ref here */ + g_object_unref (file1); + g_object_unref (file2); + if (presentable) + break; } - presentables_w = g_list_next (presentables_w); } - g_list_foreach (presentables, (GFunc) g_object_unref, NULL); - g_list_free (presentables); + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); g_object_unref (pool); return presentable; } GduPresentable * -find_presentable_from_mount_path (char *mount_path) -{ - g_return_val_if_fail (mount_path != NULL, NULL); - g_return_val_if_fail (strlen (mount_path) > 1, NULL); - return _find_presentable (mount_path, NULL); -} - -GduPresentable * find_presentable_from_device_path (char *device_path) { + GduPool *pool; + GduDevice *device; + GduPresentable *presentable = NULL; + g_return_val_if_fail (device_path != NULL, NULL); g_return_val_if_fail (strlen (device_path) > 1, NULL); - return _find_presentable (NULL, device_path); + + pool = gdu_pool_new (); + device = gdu_pool_get_by_device_file (pool, device_path); + if (device) { + presentable = gdu_pool_get_volume_by_device (pool, device); + g_object_unref (device); + } + g_object_unref (pool); + + return presentable; } @@ -131,3 +117,24 @@ g_icon_get_string (GIcon *icon) return g_strdup (icon_text); } + +gboolean +is_active_luks (GduPool *pool, GduPresentable *presentable) +{ + gboolean res; + GduDevice *device; + + res = FALSE; + device = gdu_presentable_get_device (presentable); + + if (GDU_IS_VOLUME (presentable) && device && strcmp (gdu_device_id_get_usage (device), "crypto") == 0) { + GList *enclosed_presentables; + enclosed_presentables = gdu_pool_get_enclosed_presentables (pool, presentable); + res = (enclosed_presentables != NULL) && (g_list_length (enclosed_presentables) == 1); + g_list_foreach (enclosed_presentables, (GFunc) g_object_unref, NULL); + g_list_free (enclosed_presentables); + g_object_unref (device); + } + + return res; +} diff --git a/src/gdu-format-tool/gdu-utils.h b/src/gdu-format-tool/gdu-utils.h index 9c1f594..d0b7cda 100644 --- a/src/gdu-format-tool/gdu-utils.h +++ b/src/gdu-format-tool/gdu-utils.h @@ -39,6 +39,9 @@ GduPresentable * find_presentable_from_device_path (char *device_path); char * g_icon_get_string (GIcon *icon); +gboolean is_active_luks (GduPool *pool, + GduPresentable *presentable); + G_END_DECLS #endif |