[gnome-disk-utility] Check keyring for LUKS passphrase and put it in passphrase entry if available
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Check keyring for LUKS passphrase and put it in passphrase entry if available
- Date: Thu, 26 Apr 2012 20:21:36 +0000 (UTC)
commit a1d23726503212b0f5b1ce17153dea1e11c17235
Author: David Zeuthen <davidz redhat com>
Date: Thu Apr 26 16:17:59 2012 -0400
Check keyring for LUKS passphrase and put it in passphrase entry if available
Also show a cluebar if this is the case. See
http://people.freedesktop.org/~david/disks-luks-passphrase-from-keyring.png
for a screenshot and
https://bugzilla.gnome.org/show_bug.cgi?id=674161
for where it was decided that it was useful for GVfs to store the
passphrase in the keyring (in addition to /etc/crypttab).
Signed-off-by: David Zeuthen <davidz redhat com>
configure.ac | 2 +
data/ui/unlock-device-dialog.ui | 40 ++++----
src/palimpsest/Makefile.am | 2 +
src/palimpsest/gduunlockdialog.c | 210 +++++++++++++++++++++++++++-----------
4 files changed, 175 insertions(+), 79 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index da614fb..5bf50fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,10 +30,12 @@ GNOME_MAINTAINER_MODE_DEFINES
GLIB2_REQUIRED=2.31.0
UDISKS2_REQUIRED=1.90.0
GTK3_REQUIRED=3.3.11
+KEYRING1_REQUIRED=3.4.0
PKG_CHECK_MODULES(GLIB2, [gio-unix-2.0 >= $GLIB2_REQUIRED])
PKG_CHECK_MODULES(UDISKS2, [udisks2 >= $UDISKS2_REQUIRED])
PKG_CHECK_MODULES(GTK3, [gtk+-3.0 >= $GTK3_REQUIRED])
+PKG_CHECK_MODULES(KEYRING1, [gnome-keyring-1 >= $KEYRING1_REQUIRED])
dnl **********************************
dnl *** Check for libsystemd-login ***
diff --git a/data/ui/unlock-device-dialog.ui b/data/ui/unlock-device-dialog.ui
index aa4e42e..d2085b6 100644
--- a/data/ui/unlock-device-dialog.ui
+++ b/data/ui/unlock-device-dialog.ui
@@ -14,6 +14,21 @@
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
+ <object class="GtkBox" id="infobar-vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -24,7 +39,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -56,6 +71,7 @@
<object class="GtkEntry" id="unlock-device-passphrase-entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="hexpand">True</property>
<property name="visibility">False</property>
<property name="invisible_char">â</property>
<property name="activates_default">True</property>
@@ -71,6 +87,7 @@
<child>
<object class="GtkCheckButton" id="unlock-device-show-passphrase-check-button">
<property name="label" translatable="yes">Sho_w passphrase</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -89,26 +106,11 @@
<child>
<placeholder/>
</child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
@@ -118,6 +120,7 @@
<child>
<object class="GtkButton" id="button5">
<property name="label">gtk-cancel</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -133,6 +136,7 @@
<child>
<object class="GtkButton" id="button6">
<property name="label" translatable="yes">_Unlock</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
@@ -151,7 +155,7 @@
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
</object>
diff --git a/src/palimpsest/Makefile.am b/src/palimpsest/Makefile.am
index 69f73d5..d06f2ae 100644
--- a/src/palimpsest/Makefile.am
+++ b/src/palimpsest/Makefile.am
@@ -62,6 +62,7 @@ palimpsest_CFLAGS = \
$(GLIB2_CFLAGS) \
$(UDISKS2_CFLAGS) \
$(GTK3_CFLAGS) \
+ $(KEYRING1_CFLAGS) \
$(LIBSYSTEMD_LOGIN_CFLAGS) \
$(WARN_CFLAGS) \
-lm \
@@ -71,6 +72,7 @@ palimpsest_LDADD = \
$(GLIB2_LIBS) \
$(UDISKS2_LIBS) \
$(GTK3_LIBS) \
+ $(KEYRING1_LIBS) \
$(LIBSYSTEMD_LOGIN_LIBS) \
$(NULL)
diff --git a/src/palimpsest/gduunlockdialog.c b/src/palimpsest/gduunlockdialog.c
index f1e7fa9..01b73b9 100644
--- a/src/palimpsest/gduunlockdialog.c
+++ b/src/palimpsest/gduunlockdialog.c
@@ -23,6 +23,7 @@
#include "config.h"
#include <glib/gi18n.h>
+#include <gnome-keyring.h>
#include "gduapplication.h"
#include "gduwindow.h"
@@ -30,6 +31,54 @@
#include "gduvolumegrid.h"
#include "gduutils.h"
+/* From GVfs's monitor/udisks2/gvfsudisks2volume.c */
+static GnomeKeyringPasswordSchema luks_passphrase_schema =
+{
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ {
+ {"gvfs-luks-uuid", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING},
+ {NULL, 0}
+ }
+};
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ UDisksObject *object;
+ UDisksBlock *block;
+ UDisksEncrypted *encrypted;
+
+ GduWindow *window;
+ GtkBuilder *builder;
+
+ GtkWidget *dialog;
+ GtkWidget *infobar_vbox;
+ GtkWidget *entry;
+ GtkWidget *show_passphrase_check_button;
+
+ gchar *passphrase;
+} DialogData;
+
+static void
+dialog_data_free (DialogData *data)
+{
+ if (data->dialog != NULL)
+ {
+ gtk_widget_hide (data->dialog);
+ gtk_widget_destroy (data->dialog);
+ }
+ if (data->object != NULL)
+ g_object_unref (data->object);
+ if (data->window != NULL)
+ g_object_unref (data->window);
+ if (data->builder != NULL)
+ g_object_unref (data->builder);
+
+ g_free (data->passphrase);
+ g_free (data);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -37,7 +86,7 @@ unlock_cb (UDisksEncrypted *encrypted,
GAsyncResult *res,
gpointer user_data)
{
- GduWindow *window = GDU_WINDOW (user_data);
+ DialogData *data = user_data;
GError *error;
error = NULL;
@@ -46,83 +95,122 @@ unlock_cb (UDisksEncrypted *encrypted,
res,
&error))
{
- gdu_window_show_error (window,
+ gdu_window_show_error (data->window,
_("Error unlocking encrypted device"),
error);
g_error_free (error);
}
- g_object_unref (window);
+ dialog_data_free (data);
}
-void
-gdu_unlock_dialog_show (GduWindow *window,
- UDisksObject *object)
+static void
+do_unlock (DialogData *data)
{
- gint response;
- GtkBuilder *builder;
- GtkWidget *dialog;
- GtkWidget *entry;
- GtkWidget *show_passphrase_check_button;
- UDisksBlock *block;
- UDisksEncrypted *encrypted;
- const gchar *passphrase;
- gboolean has_passphrase;
-
- dialog = NULL;
- builder = NULL;
-
- /* TODO: look up passphrase from gnome-keyring? */
+ udisks_encrypted_call_unlock (data->encrypted,
+ data->passphrase,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) unlock_cb,
+ data);
+}
- block = udisks_object_peek_block (object);
- encrypted = udisks_object_peek_encrypted (object);
+static void
+show_dialog (DialogData *data)
+{
+ gint response;
- passphrase = "";
- has_passphrase = FALSE;
- if (gdu_utils_has_configuration (block, "crypttab", &has_passphrase) && has_passphrase)
- goto do_call;
+ gtk_widget_show_all (data->dialog);
+ gtk_widget_grab_focus (data->entry);
- dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
- "unlock-device-dialog.ui",
- "unlock-device-dialog",
- &builder));
- entry = GTK_WIDGET (gtk_builder_get_object (builder, "unlock-device-passphrase-entry"));
- show_passphrase_check_button = GTK_WIDGET (gtk_builder_get_object (builder, "unlock-device-show-passphrase-check-button"));
+ response = gtk_dialog_run (GTK_DIALOG (data->dialog));
+ if (response == GTK_RESPONSE_OK)
+ {
+ gtk_widget_hide (data->dialog);
+ data->passphrase = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->entry)));
+ do_unlock (data);
+ }
+ else
+ {
+ /* otherwise, we are done */
+ dialog_data_free (data);
+ }
+}
- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+static void
+luks_find_passphrase_cb (GnomeKeyringResult result,
+ const gchar *string,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_passphrase_check_button), FALSE);
- gtk_entry_set_text (GTK_ENTRY (entry), "");
+ /* Don't fail if a keyring error occured... but if we do find a
+ * passphrase then put it into the entry field and show a
+ * cluebar
+ */
+ if (result == GNOME_KEYRING_RESULT_OK)
+ {
+ GtkWidget *infobar;
+ infobar = gdu_utils_create_info_bar (GTK_MESSAGE_INFO,
+ _("The encryption passphrase was retrieved from the keyring"),
+ NULL);
+ gtk_box_pack_start (GTK_BOX (data->infobar_vbox), infobar, TRUE, TRUE, 0);
+ gtk_entry_set_text (GTK_ENTRY (data->entry), string);
+ }
+ else
+ {
+ gtk_widget_hide (data->infobar_vbox);
+ gtk_widget_set_no_show_all (data->infobar_vbox, TRUE);
+ }
+ show_dialog (data);
+}
- g_object_bind_property (show_passphrase_check_button,
+void
+gdu_unlock_dialog_show (GduWindow *window,
+ UDisksObject *object)
+{
+ gboolean has_passphrase_in_crypttab = FALSE;
+ DialogData *data;
+
+ data = g_new0 (DialogData, 1);
+ data->object = g_object_ref (object);
+ data->block = udisks_object_peek_block (object);
+ data->encrypted = udisks_object_peek_encrypted (object);
+ data->window = g_object_ref (window);
+
+ data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
+ "unlock-device-dialog.ui",
+ "unlock-device-dialog",
+ &data->builder));
+ data->infobar_vbox = GTK_WIDGET (gtk_builder_get_object (data->builder, "infobar-vbox"));
+ data->entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "unlock-device-passphrase-entry"));
+ data->show_passphrase_check_button = GTK_WIDGET (gtk_builder_get_object (data->builder, "unlock-device-show-passphrase-check-button"));
+
+ gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->window));
+ gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->show_passphrase_check_button), FALSE);
+ gtk_entry_set_text (GTK_ENTRY (data->entry), "");
+
+ g_object_bind_property (data->show_passphrase_check_button,
"active",
- entry,
+ data->entry,
"visibility",
G_BINDING_SYNC_CREATE);
- gtk_widget_show_all (dialog);
- gtk_widget_grab_focus (entry);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- if (response != GTK_RESPONSE_OK)
- goto out;
-
- passphrase = gtk_entry_get_text (GTK_ENTRY (entry));
-
- do_call:
- udisks_encrypted_call_unlock (encrypted,
- passphrase,
- g_variant_new ("a{sv}", NULL), /* options */
- NULL, /* cancellable */
- (GAsyncReadyCallback) unlock_cb,
- g_object_ref (window));
-
- out:
- if (dialog != NULL)
+ if (gdu_utils_has_configuration (data->block, "crypttab", &has_passphrase_in_crypttab) &&
+ has_passphrase_in_crypttab)
+ {
+ data->passphrase = g_strdup ("");
+ do_unlock (data);
+ }
+ else
{
- gtk_widget_hide (dialog);
- gtk_widget_destroy (dialog);
+ /* see if there's a passphrase in the keyring */
+ gnome_keyring_find_password (&luks_passphrase_schema,
+ luks_find_passphrase_cb,
+ data,
+ NULL, /* GDestroyNotify */
+ "gvfs-luks-uuid", udisks_block_get_id_uuid (data->block),
+ NULL); /* sentinel */
}
- if (builder != NULL)
- g_object_unref (builder);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]