[gnome-disk-utility/udisks2-port] Add support for editing /etc/crypttab entries
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/udisks2-port] Add support for editing /etc/crypttab entries
- Date: Thu, 11 Aug 2011 19:50:51 +0000 (UTC)
commit 01b5c4cec092557d174193bfef6824370ed7d43c
Author: David Zeuthen <davidz redhat com>
Date: Thu Aug 11 15:50:38 2011 -0400
Add support for editing /etc/crypttab entries
Signed-off-by: David Zeuthen <davidz redhat com>
data/ui/palimpsest.ui | 299 ++++++++++++++++++++++
src/palimpsest/gduwindow.c | 603 +++++++++++++++++++++++++++++++++++++++++---
2 files changed, 872 insertions(+), 30 deletions(-)
---
diff --git a/data/ui/palimpsest.ui b/data/ui/palimpsest.ui
index d525b28..efe2ad6 100644
--- a/data/ui/palimpsest.ui
+++ b/data/ui/palimpsest.ui
@@ -287,6 +287,296 @@
<action-widget response="-5">button2</action-widget>
</action-widgets>
</object>
+ <object class="GtkDialog" id="crypttab-dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox7">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area7">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button10">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button9">
+ <property name="label">gtk-apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="crypttab-configure-checkbutton">
+ <property name="label" translatable="yes">Config_ure passphrase and options</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Checked if an entry in the /etc/crypttab file exists for the device</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">24</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkTable" id="crypttab-table">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">10</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="crypttab-name-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Name</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">crypttab-name-entry</property>
+ <attributes>
+ <attribute name="foreground" value="#555555555555"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="crypttab-options-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Options</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">crypttab-options-entry</property>
+ <attributes>
+ <attribute name="foreground" value="#555555555555"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="crypttab-name-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">The name to use for the unlocked device - the device is set up as the name prefixed with <b>/dev/mapper/</b></property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="crypttab-options-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Options to use when unlocking the device</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="crypttab-passphrase-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Passphrase</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">crypttab-passphrase-entry</property>
+ <attributes>
+ <attribute name="foreground" value="#555555555555"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="crypttab-passphrase-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Passphrase of the device or empty to request from user when setting up the device</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="crypttab-show-passphrase-checkbutton">
+ <property name="label" translatable="yes">Sho_w passphrase</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="crypttab-passphrase-path-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Passphrase File</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">crypttab-passphrase-entry</property>
+ <attributes>
+ <attribute name="foreground" value="#555555555555"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="crypttab-passphrase-path-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">middle</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="linkbutton2">
+ <property name="label" translatable="yes">What's this?</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ <property name="uri">man:crypttab</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">button10</action-widget>
+ <action-widget response="-10">button9</action-widget>
+ </action-widgets>
+ </object>
<object class="GtkDialog" id="device-fstab-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
@@ -672,6 +962,15 @@
</object>
</child>
<child>
+ <object class="GtkMenuItem" id="generic-menu-item-configure-crypttab">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">Edit /etc/crypttab entry...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
<object class="GtkMenuItem" id="generic-menu-item-edit-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
diff --git a/src/palimpsest/gduwindow.c b/src/palimpsest/gduwindow.c
index f06c31a..6fb8974 100644
--- a/src/palimpsest/gduwindow.c
+++ b/src/palimpsest/gduwindow.c
@@ -88,6 +88,7 @@ struct _GduWindow
GtkWidget *generic_menu;
GtkWidget *generic_menu_item_configure_fstab;
+ GtkWidget *generic_menu_item_configure_crypttab;
GtkWidget *generic_menu_item_edit_label;
GtkWidget *generic_menu_item_edit_partition;
@@ -123,6 +124,7 @@ static const struct {
{G_STRUCT_OFFSET (GduWindow, devtab_toolbar_deactivate_swap_button), "devtab-action-deactivate-swap"},
{G_STRUCT_OFFSET (GduWindow, generic_menu), "generic-menu"},
{G_STRUCT_OFFSET (GduWindow, generic_menu_item_configure_fstab), "generic-menu-item-configure-fstab"},
+ {G_STRUCT_OFFSET (GduWindow, generic_menu_item_configure_crypttab), "generic-menu-item-configure-crypttab"},
{G_STRUCT_OFFSET (GduWindow, generic_menu_item_edit_label), "generic-menu-item-edit-label"},
{G_STRUCT_OFFSET (GduWindow, generic_menu_item_edit_partition), "generic-menu-item-edit-partition"},
{0, NULL}
@@ -153,9 +155,10 @@ typedef enum
SHOW_FLAGS_ENCRYPTED_UNLOCK_BUTTON = (1<<7),
SHOW_FLAGS_ENCRYPTED_LOCK_BUTTON = (1<<8),
- SHOW_FLAGS_POPUP_MENU_CONFIGURE_FSTAB = (1<<9),
- SHOW_FLAGS_POPUP_MENU_EDIT_LABEL = (1<<10),
- SHOW_FLAGS_POPUP_MENU_EDIT_PARTITION = (1<<11),
+ SHOW_FLAGS_POPUP_MENU_CONFIGURE_FSTAB = (1<<9),
+ SHOW_FLAGS_POPUP_MENU_CONFIGURE_CRYPTTAB = (1<<10),
+ SHOW_FLAGS_POPUP_MENU_EDIT_LABEL = (1<<11),
+ SHOW_FLAGS_POPUP_MENU_EDIT_PARTITION = (1<<12),
} ShowFlags;
static void gdu_window_show_error (GduWindow *window,
@@ -181,6 +184,8 @@ static void on_devtab_action_deactivate_swap_activated (GtkAction *action, gpoin
static void on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
gpointer user_data);
+static void on_generic_menu_item_configure_crypttab (GtkMenuItem *menu_item,
+ gpointer user_data);
static void on_generic_menu_item_edit_label (GtkMenuItem *menu_item,
gpointer user_data);
static void on_generic_menu_item_edit_partition (GtkMenuItem *menu_item,
@@ -323,6 +328,8 @@ update_for_show_flags (GduWindow *window,
gtk_widget_set_visible (GTK_WIDGET (window->generic_menu_item_configure_fstab),
show_flags & SHOW_FLAGS_POPUP_MENU_CONFIGURE_FSTAB);
+ gtk_widget_set_visible (GTK_WIDGET (window->generic_menu_item_configure_crypttab),
+ show_flags & SHOW_FLAGS_POPUP_MENU_CONFIGURE_CRYPTTAB);
gtk_widget_set_visible (GTK_WIDGET (window->generic_menu_item_edit_label),
show_flags & SHOW_FLAGS_POPUP_MENU_EDIT_LABEL);
gtk_widget_set_visible (GTK_WIDGET (window->generic_menu_item_edit_partition),
@@ -839,6 +846,10 @@ gdu_window_constructed (GObject *object)
"activate",
G_CALLBACK (on_generic_menu_item_configure_fstab),
window);
+ g_signal_connect (window->generic_menu_item_configure_crypttab,
+ "activate",
+ G_CALLBACK (on_generic_menu_item_configure_crypttab),
+ window);
g_signal_connect (window->generic_menu_item_edit_label,
"activate",
G_CALLBACK (on_generic_menu_item_edit_label),
@@ -1671,37 +1682,64 @@ update_device_page_for_block (GduWindow *window,
"devtab-volume-encrypted-unlocked-value-label",
str,
SET_MARKUP_FLAGS_NONE);
+
+ *show_flags |= SHOW_FLAGS_POPUP_MENU_CONFIGURE_CRYPTTAB;
}
/* Configuration */
if (TRUE)
{
- const gchar *s;
+ GString *str;
GVariantIter iter;
const gchar *config_type;
- gboolean in_fstab = FALSE;
+ gboolean mentioned_fstab = FALSE;
+ gboolean mentioned_crypttab = FALSE;
+
+ str = g_string_new (NULL);
g_variant_iter_init (&iter, udisks_block_device_get_configuration (block));
while (g_variant_iter_next (&iter, "(&sa{sv})", &config_type, NULL))
{
if (g_strcmp0 (config_type, "fstab") == 0)
- in_fstab = TRUE;
- }
-
- s = NULL;
- if (in_fstab)
- {
- /* Translators: Shown when the device is configured in /etc/fstab.
- * Do not translate "fstab".
- */
- s = _("In /etc/fstab");
+ {
+ if (!mentioned_fstab)
+ {
+ mentioned_fstab = TRUE;
+ if (str->len > 0)
+ g_string_append (str, ", ");
+ /* Translators: Shown when the device is configured in /etc/fstab.
+ * Do not translate "/etc/fstab".
+ */
+ g_string_append (str, _("In /etc/fstab"));
+ }
+ }
+ else if (g_strcmp0 (config_type, "crypttab") == 0)
+ {
+ if (!mentioned_crypttab)
+ {
+ mentioned_crypttab = TRUE;
+ if (str->len > 0)
+ g_string_append (str, ", ");
+ /* Translators: Shown when the device is configured in /etc/crypttab.
+ * Do not translate "/etc/crypttab".
+ */
+ g_string_append (str, _("In /etc/crypttab"));
+ }
+ }
+ else
+ {
+ if (str->len > 0)
+ g_string_append (str, ", ");
+ g_string_append (str, config_type);
+ }
}
set_markup (window,
"devtab-volume-configured-label",
"devtab-volume-configured-value-label",
- s,
+ str->str,
SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
+ g_string_free (str, TRUE);
}
}
@@ -2578,6 +2616,8 @@ on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
gint ui_freq;
gint ui_passno;
GError *error;
+ GVariant *old_item;
+ GVariant *new_item;
ui_configured = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data.configure_checkbutton));
ui_fsname = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (data.device_combobox));
@@ -2589,12 +2629,32 @@ on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
gtk_widget_hide (dialog);
+ old_item = NULL;
+ new_item = NULL;
+
if (configured)
{
+ old_item = g_variant_new ("(s a{sv})", "fstab", data.orig_fstab_entry);
+ }
+
+ if (ui_configured)
+ {
+ GVariantBuilder builder;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&builder, "{sv}", "fsname", g_variant_new_bytestring (ui_fsname));
+ g_variant_builder_add (&builder, "{sv}", "dir", g_variant_new_bytestring (ui_dir));
+ g_variant_builder_add (&builder, "{sv}", "type", g_variant_new_bytestring (ui_type));
+ g_variant_builder_add (&builder, "{sv}", "opts", g_variant_new_bytestring (ui_opts));
+ g_variant_builder_add (&builder, "{sv}", "freq", g_variant_new_int32 (ui_freq));
+ g_variant_builder_add (&builder, "{sv}", "passno", g_variant_new_int32 (ui_passno));
+ new_item = g_variant_new ("(sa{sv})", "fstab", &builder);
+ }
+
+ if (old_item != NULL && new_item == NULL)
+ {
error = NULL;
if (!udisks_block_device_call_remove_configuration_item_sync (block,
- g_variant_new ("(s a{sv})", "fstab",
- data.orig_fstab_entry),
+ old_item,
g_variant_new ("a{sv}", NULL), /* options */
NULL, /* GCancellable */
&error))
@@ -2607,20 +2667,11 @@ on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
goto out;
}
}
-
- if (ui_configured)
+ else if (old_item == NULL && new_item != NULL)
{
- GVariantBuilder builder;
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
- g_variant_builder_add (&builder, "{sv}", "fsname", g_variant_new_bytestring (ui_fsname));
- g_variant_builder_add (&builder, "{sv}", "dir", g_variant_new_bytestring (ui_dir));
- g_variant_builder_add (&builder, "{sv}", "type", g_variant_new_bytestring (ui_type));
- g_variant_builder_add (&builder, "{sv}", "opts", g_variant_new_bytestring (ui_opts));
- g_variant_builder_add (&builder, "{sv}", "freq", g_variant_new_int32 (ui_freq));
- g_variant_builder_add (&builder, "{sv}", "passno", g_variant_new_int32 (ui_passno));
error = NULL;
if (!udisks_block_device_call_add_configuration_item_sync (block,
- g_variant_new ("(sa{sv})", "fstab", &builder),
+ new_item,
g_variant_new ("a{sv}", NULL), /* options */
NULL, /* GCancellable */
&error))
@@ -2633,7 +2684,28 @@ on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
goto out;
}
}
-
+ else if (old_item != NULL && new_item != NULL)
+ {
+ error = NULL;
+ if (!udisks_block_device_call_update_configuration_item_sync (block,
+ old_item,
+ new_item,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable */
+ &error))
+ {
+ gdu_window_show_error (window,
+ _("Error updating /etc/fstab entry"),
+ error);
+ g_error_free (error);
+ g_free (ui_fsname);
+ goto out;
+ }
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
g_free (ui_fsname);
}
@@ -2649,6 +2721,477 @@ on_generic_menu_item_configure_fstab (GtkMenuItem *menu_item,
/* ---------------------------------------------------------------------------------------------------- */
+typedef struct
+{
+ UDisksBlockDevice *block;
+
+ GduWindow *window;
+
+ GtkBuilder *builder;
+ GtkWidget *dialog;
+ GtkWidget *configure_checkbutton;
+ GtkWidget *table;
+
+ GtkWidget *name_entry;
+ GtkWidget *options_entry;
+ GtkWidget *passphrase_label;
+ GtkWidget *passphrase_entry;
+ GtkWidget *show_passphrase_checkbutton;
+ GtkWidget *passphrase_path_value_label;
+
+ GVariant *orig_crypttab_entry;
+} CrypttabDialogData;
+
+static void
+crypttab_dialog_free (CrypttabDialogData *data)
+{
+ g_object_unref (data->window);
+
+ if (data->orig_crypttab_entry != NULL)
+ g_variant_unref (data->orig_crypttab_entry);
+
+ if (data->dialog != NULL)
+ {
+ gtk_widget_hide (data->dialog);
+ gtk_widget_destroy (data->dialog);
+ }
+ g_object_unref (data->builder);
+ g_free (data);
+}
+
+static void
+crypttab_dialog_update (CrypttabDialogData *data)
+{
+ gboolean ui_configured;
+ const gchar *ui_name;
+ const gchar *ui_options;
+ const gchar *ui_passphrase_contents;
+ gboolean configured;
+ const gchar *name;
+ const gchar *passphrase_path;
+ const gchar *passphrase_contents;
+ const gchar *options;
+ gboolean can_apply;
+ gchar *s;
+
+ if (data->orig_crypttab_entry != NULL)
+ {
+ configured = TRUE;
+ g_variant_lookup (data->orig_crypttab_entry, "name", "^&ay", &name);
+ g_variant_lookup (data->orig_crypttab_entry, "options", "^&ay", &options);
+ g_variant_lookup (data->orig_crypttab_entry, "passphrase-path", "^&ay", &passphrase_path);
+ if (!g_variant_lookup (data->orig_crypttab_entry, "passphrase-contents", "^&ay", &passphrase_contents))
+ passphrase_contents = "";
+ }
+ else
+ {
+ configured = FALSE;
+ name = "";
+ options = "";
+ passphrase_path = "";
+ passphrase_contents = "";
+ }
+
+ ui_configured = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->configure_checkbutton));
+ ui_name = gtk_entry_get_text (GTK_ENTRY (data->name_entry));
+ ui_options = gtk_entry_get_text (GTK_ENTRY (data->options_entry));
+ ui_passphrase_contents = gtk_entry_get_text (GTK_ENTRY (data->passphrase_entry));
+
+ if (!configured)
+ {
+ if (strlen (ui_passphrase_contents) > 0)
+ s = g_strdup_printf ("<i>%s</i>", _("Will be created"));
+ else
+ s = g_strdup_printf ("<i>%s</i>", _("None"));
+ }
+ else
+ {
+ if (g_str_has_prefix (passphrase_path, "/dev"))
+ {
+ /* if using a random source (for e.g. setting up swap), don't offer to edit the passphrase */
+ gtk_widget_hide (data->passphrase_label);
+ gtk_widget_hide (data->passphrase_entry);
+ gtk_widget_hide (data->show_passphrase_checkbutton);
+ gtk_widget_set_no_show_all (data->passphrase_label, TRUE);
+ gtk_widget_set_no_show_all (data->passphrase_entry, TRUE);
+ gtk_widget_set_no_show_all (data->show_passphrase_checkbutton, TRUE);
+ s = g_strdup (passphrase_path);
+ }
+ else if (strlen (ui_passphrase_contents) > 0)
+ {
+ if (strlen (passphrase_path) == 0)
+ s = g_strdup_printf ("<i>%s</i>", _("Will be created"));
+ else
+ s = g_strdup (passphrase_path);
+ }
+ else
+ {
+ if (strlen (passphrase_path) == 0)
+ s = g_strdup_printf ("<i>%s</i>", _("None"));
+ else
+ s = g_strdup_printf ("<i>%s</i>", _("Will be deleted"));
+ }
+ }
+ gtk_label_set_markup (GTK_LABEL (data->passphrase_path_value_label), s);
+ g_free (s);
+
+ can_apply = FALSE;
+ if (configured != ui_configured)
+ {
+ can_apply = TRUE;
+ }
+ else if (ui_configured)
+ {
+ if (g_strcmp0 (ui_name, name) != 0 ||
+ g_strcmp0 (ui_options, options) != 0 ||
+ g_strcmp0 (ui_passphrase_contents, passphrase_contents) != 0)
+ {
+ can_apply = TRUE;
+ }
+ }
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+ GTK_RESPONSE_APPLY,
+ can_apply);
+}
+
+static void
+crypttab_dialog_property_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ CrypttabDialogData *data = user_data;
+ crypttab_dialog_update (data);
+}
+
+
+static void
+crypttab_dialog_present (CrypttabDialogData *data)
+{
+ gboolean configured;
+ gchar *name;
+ const gchar *options;
+ const gchar *passphrase_contents;
+ gint response;
+
+ if (data->orig_crypttab_entry != NULL)
+ {
+ configured = TRUE;
+ g_variant_lookup (data->orig_crypttab_entry, "name", "^ay", &name);
+ g_variant_lookup (data->orig_crypttab_entry, "options", "^&ay", &options);
+ if (!g_variant_lookup (data->orig_crypttab_entry, "passphrase-contents", "^&ay", &passphrase_contents))
+ passphrase_contents = "";
+ }
+ else
+ {
+ configured = FALSE;
+ name = g_strdup_printf ("luks-%s", udisks_block_device_get_id_uuid (data->block));
+ options = "";
+ passphrase_contents = "";
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->configure_checkbutton), configured);
+ gtk_entry_set_text (GTK_ENTRY (data->name_entry), name);
+ gtk_entry_set_text (GTK_ENTRY (data->options_entry), options);
+ gtk_entry_set_text (GTK_ENTRY (data->passphrase_entry), passphrase_contents);
+
+ g_object_bind_property (data->show_passphrase_checkbutton,
+ "active",
+ data->passphrase_entry,
+ "visibility",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (data->configure_checkbutton,
+ "active",
+ data->table,
+ "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (data->configure_checkbutton,
+ "notify::active", G_CALLBACK (crypttab_dialog_property_changed), data);
+ g_signal_connect (data->name_entry,
+ "notify::text", G_CALLBACK (crypttab_dialog_property_changed), data);
+ g_signal_connect (data->options_entry,
+ "notify::text", G_CALLBACK (crypttab_dialog_property_changed), data);
+ g_signal_connect (data->passphrase_entry,
+ "notify::text", G_CALLBACK (crypttab_dialog_property_changed), data);
+
+ gtk_widget_show_all (data->dialog);
+
+ crypttab_dialog_update (data);
+
+ response = gtk_dialog_run (GTK_DIALOG (data->dialog));
+
+ if (response == GTK_RESPONSE_APPLY)
+ {
+ gboolean ui_configured;
+ const gchar *ui_name;
+ const gchar *ui_options;
+ const gchar *ui_passphrase_contents;
+ const gchar *old_passphrase_path;
+ GError *error;
+ GVariant *old_item;
+ GVariant *new_item;
+
+ ui_configured = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->configure_checkbutton));
+ ui_name = gtk_entry_get_text (GTK_ENTRY (data->name_entry));
+ ui_options = gtk_entry_get_text (GTK_ENTRY (data->options_entry));
+ ui_passphrase_contents = gtk_entry_get_text (GTK_ENTRY (data->passphrase_entry));
+
+ gtk_widget_hide (data->dialog);
+
+ old_item = NULL;
+ new_item = NULL;
+
+ old_passphrase_path = NULL;
+ if (data->orig_crypttab_entry != NULL)
+ {
+ const gchar *s;
+ if (g_variant_lookup (data->orig_crypttab_entry, "passphrase-path", "^&ay", &s))
+ {
+ if (strlen (s) > 0 && !g_str_has_prefix (s, "/dev"))
+ old_passphrase_path = s;
+ }
+ error = NULL;
+ old_item = g_variant_new ("(s a{sv})", "crypttab",
+ data->orig_crypttab_entry);
+ }
+
+ if (ui_configured)
+ {
+ GVariantBuilder builder;
+ gchar *s;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ s = g_strdup_printf ("UUID=%s", udisks_block_device_get_id_uuid (data->block));
+ g_variant_builder_add (&builder, "{sv}", "device", g_variant_new_bytestring (s));
+ g_free (s);
+ g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_bytestring (ui_name));
+ g_variant_builder_add (&builder, "{sv}", "options", g_variant_new_bytestring (ui_options));
+ if (strlen (ui_passphrase_contents) > 0)
+ {
+ /* use old/existing passphrase file, if available */
+ if (old_passphrase_path != NULL)
+ {
+ g_variant_builder_add (&builder, "{sv}", "passphrase-path",
+ g_variant_new_bytestring (old_passphrase_path));
+ }
+ else
+ {
+ /* otherwise fall back to the requested name */
+ s = g_strdup_printf ("/etc/luks-keys/%s", ui_name);
+ g_variant_builder_add (&builder, "{sv}", "passphrase-path", g_variant_new_bytestring (s));
+ g_free (s);
+ }
+ g_variant_builder_add (&builder, "{sv}", "passphrase-contents",
+ g_variant_new_bytestring (ui_passphrase_contents));
+
+ }
+ else
+ {
+ g_variant_builder_add (&builder, "{sv}", "passphrase-path",
+ g_variant_new_bytestring (""));
+ g_variant_builder_add (&builder, "{sv}", "passphrase-contents",
+ g_variant_new_bytestring (""));
+ }
+
+ new_item = g_variant_new ("(sa{sv})", "crypttab", &builder);
+ }
+
+ if (old_item != NULL && new_item == NULL)
+ {
+ error = NULL;
+ if (!udisks_block_device_call_remove_configuration_item_sync (data->block,
+ old_item,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable */
+ &error))
+ {
+ gdu_window_show_error (data->window,
+ _("Error removing /etc/crypttab entry"),
+ error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+ else if (old_item == NULL && new_item != NULL)
+ {
+ error = NULL;
+ if (!udisks_block_device_call_add_configuration_item_sync (data->block,
+ new_item,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable */
+ &error))
+ {
+ gdu_window_show_error (data->window,
+ _("Error adding /etc/crypttab entry"),
+ error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+ else if (old_item != NULL && new_item != NULL)
+ {
+ error = NULL;
+ if (!udisks_block_device_call_update_configuration_item_sync (data->block,
+ old_item,
+ new_item,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable */
+ &error))
+ {
+ gdu_window_show_error (data->window,
+ _("Error updating /etc/crypttab entry"),
+ error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+ }
+
+ out:
+ crypttab_dialog_free (data);
+ g_free (name);
+}
+
+static void
+crypttab_dialog_on_get_secrets_cb (UDisksBlockDevice *block,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CrypttabDialogData *data = user_data;
+ GError *error;
+ GVariant *configuration;
+ GVariantIter iter;
+ const gchar *configuration_type;
+ GVariant *configuration_dict;
+
+ configuration = NULL;
+ error = NULL;
+ if (!udisks_block_device_call_get_secret_configuration_finish (block,
+ &configuration,
+ res,
+ &error))
+ {
+ gdu_window_show_error (data->window,
+ _("Error retrieving configuration data"),
+ error);
+ g_error_free (error);
+ crypttab_dialog_free (data);
+ goto out;
+ }
+
+ /* there could be multiple crypttab entries - we only consider the first one */
+ g_variant_iter_init (&iter, configuration);
+ while (g_variant_iter_next (&iter, "(&s a{sv})", &configuration_type, &configuration_dict))
+ {
+ if (g_strcmp0 (configuration_type, "crypttab") == 0)
+ {
+ if (data->orig_crypttab_entry != NULL)
+ g_variant_unref (data->orig_crypttab_entry);
+ data->orig_crypttab_entry = configuration_dict;
+ break;
+ }
+ else
+ {
+ g_variant_unref (configuration_dict);
+ }
+ }
+ g_variant_unref (configuration);
+
+ crypttab_dialog_present (data);
+
+ out:
+ ;
+}
+
+static void
+on_generic_menu_item_configure_crypttab (GtkMenuItem *menu_item,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ UDisksObject *object;
+ GtkWidget *dialog;
+ CrypttabDialogData *data;
+ GVariantIter iter;
+ const gchar *configuration_type;
+ GVariant *configuration_dict;
+ gboolean configured;
+ gboolean get_passphrase_contents;
+
+ data = g_new0 (CrypttabDialogData, 1);
+ data->window = g_object_ref (window);
+
+ object = gdu_volume_grid_get_selected_device (GDU_VOLUME_GRID (window->volume_grid));
+ if (object == NULL)
+ object = gdu_volume_grid_get_block_device (GDU_VOLUME_GRID (window->volume_grid));
+ data->block = udisks_object_peek_block_device (object);
+ g_assert (data->block != NULL);
+
+ dialog = gdu_window_new_widget (window, "crypttab-dialog", &data->builder);
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ data->dialog = dialog;
+ data->configure_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-configure-checkbutton"));
+ data->table = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-table"));
+ data->name_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-name-entry"));
+ data->options_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-options-entry"));
+ data->passphrase_label = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-passphrase-label"));
+ data->passphrase_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-passphrase-entry"));
+ data->show_passphrase_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-show-passphrase-checkbutton"));
+ data->passphrase_path_value_label = GTK_WIDGET (gtk_builder_get_object (data->builder, "crypttab-passphrase-path-value-label"));
+
+ /* First check if there's an existing configuration */
+ configured = FALSE;
+ get_passphrase_contents = FALSE;
+ g_variant_iter_init (&iter, udisks_block_device_get_configuration (data->block));
+ while (g_variant_iter_next (&iter, "(&s a{sv})", &configuration_type, &configuration_dict))
+ {
+ if (g_strcmp0 (configuration_type, "crypttab") == 0)
+ {
+ const gchar *passphrase_path;
+ configured = TRUE;
+ g_variant_lookup (configuration_dict, "passphrase-path", "^&ay", &passphrase_path);
+ if (g_strcmp0 (passphrase_path, "") != 0)
+ {
+ /* fetch contents of passphrase file, if it exists (unless special file) */
+ if (!g_str_has_prefix (passphrase_path, "/dev"))
+ {
+ get_passphrase_contents = TRUE;
+ }
+ }
+ data->orig_crypttab_entry = configuration_dict;
+ break;
+ }
+ else
+ {
+ g_variant_unref (configuration_dict);
+ }
+ }
+
+ /* if there is an existing configuration and it has a passphrase, get the actual passphrase
+ * as well (involves polkit dialog)
+ */
+ if (configured && get_passphrase_contents)
+ {
+ udisks_block_device_call_get_secret_configuration (data->block,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) crypttab_dialog_on_get_secrets_cb,
+ data);
+ }
+ else
+ {
+ /* otherwise just set up the dialog */
+ crypttab_dialog_present (data);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
mount_cb (UDisksFilesystem *filesystem,
GAsyncResult *res,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]