summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2009-04-21 17:11:16 +0200
committerTomas Bzatek <tbzatek@redhat.com>2009-04-27 15:05:23 +0200
commit17966e22969c863e81711408d50ff4173621b44b (patch)
tree0fc3bd276440d63ffe4a7b4eb62f447976ee4882
parent83ce37c97ab04ed8699c5bbea56dbd34e28f912e (diff)
downloadgnome-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/TODO4
-rw-r--r--src/gdu-format-tool/format-window-operation.c108
-rw-r--r--src/gdu-format-tool/format-window-operation.h2
-rw-r--r--src/gdu-format-tool/gdu-utils.c113
-rw-r--r--src/gdu-format-tool/gdu-utils.h3
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