From 1d080a254708c7041319e3a20022911ac634982d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Thu, 23 Oct 2008 22:58:32 +0000 Subject: [PATCH] - support for mounting encrypted volumes Changed files: Thunar-volman-setup-crypto.patch -> 1.1 --- Thunar-volman-setup-crypto.patch | 904 +++++++++++++++++++++++++++++++ 1 file changed, 904 insertions(+) create mode 100644 Thunar-volman-setup-crypto.patch diff --git a/Thunar-volman-setup-crypto.patch b/Thunar-volman-setup-crypto.patch new file mode 100644 index 0000000..2735b6e --- /dev/null +++ b/Thunar-volman-setup-crypto.patch @@ -0,0 +1,904 @@ +Index: thunar-volman/tvm-camera-device.h +=================================================================== +--- thunar-volman/tvm-camera-device.h (revision 4898) ++++ thunar-volman/tvm-camera-device.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_camera_device_added (TvmPreferences *preferences, + LibHalContext *context, +@@ -30,6 +30,6 @@ + const gchar *capability, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_CAMERA_DEVICE_H__ */ +Index: thunar-volman/tvm-block-device.h +=================================================================== +--- thunar-volman/tvm-block-device.h (revision 4898) ++++ thunar-volman/tvm-block-device.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_block_device_added (TvmPreferences *preferences, + LibHalContext *context, +@@ -30,6 +30,6 @@ + const gchar *capability, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_BLOCK_DEVICE_H__ */ +Index: thunar-volman/tvm-input-device.h +=================================================================== +--- thunar-volman/tvm-input-device.h (revision 4898) ++++ thunar-volman/tvm-input-device.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_input_device_added (TvmPreferences *preferences, + LibHalContext *context, +@@ -30,6 +30,6 @@ + const gchar *capability, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_INPUT_DEVICE_H__ */ +Index: thunar-volman/tvm-preferences-dialog.h +=================================================================== +--- thunar-volman/tvm-preferences-dialog.h (revision 4898) ++++ thunar-volman/tvm-preferences-dialog.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + typedef struct _TvmPreferencesDialogClass TvmPreferencesDialogClass; + typedef struct _TvmPreferencesDialog TvmPreferencesDialog; +@@ -38,6 +38,6 @@ + + GtkWidget *tvm_preferences_dialog_new (void) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PREFERENCES_DIALOG_H__ */ +Index: thunar-volman/tvm-device.h +=================================================================== +--- thunar-volman/tvm-device.h (revision 4898) ++++ thunar-volman/tvm-device.h (working copy) +@@ -26,7 +26,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + /** + * TvmDeviceCallback: +@@ -53,6 +53,6 @@ + const gchar *udi, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_DEVICE_H__ */ +Index: thunar-volman/tvm-pda-device.h +=================================================================== +--- thunar-volman/tvm-pda-device.h (revision 4898) ++++ thunar-volman/tvm-pda-device.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_pda_device_added (TvmPreferences *preferences, + LibHalContext *context, +@@ -30,6 +30,6 @@ + const gchar *capability, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PDA_DEVICE_H__ */ +Index: thunar-volman/tvm-command-entry.h +=================================================================== +--- thunar-volman/tvm-command-entry.h (revision 4898) ++++ thunar-volman/tvm-command-entry.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + typedef struct _TvmCommandEntryClass TvmCommandEntryClass; + typedef struct _TvmCommandEntry TvmCommandEntry; +@@ -56,6 +56,6 @@ + void tvm_command_entry_set_command (TvmCommandEntry *command_entry, + const gchar *command) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_COMMAND_ENTRY_H__ */ +Index: thunar-volman/xfce-heading.h +=================================================================== +--- thunar-volman/xfce-heading.h (revision 4898) ++++ thunar-volman/xfce-heading.h (working copy) +@@ -23,7 +23,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + typedef struct _XfceHeadingPrivate XfceHeadingPrivate; + typedef struct _XfceHeadingClass XfceHeadingClass; +@@ -77,6 +77,6 @@ + void xfce_heading_set_title (XfceHeading *heading, + const gchar *title); + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__XFCE_HEADING_H__ */ +Index: thunar-volman/tvm-crypto-volume.c +=================================================================== +--- thunar-volman/tvm-crypto-volume.c (revision 0) ++++ thunar-volman/tvm-crypto-volume.c (revision 0) +@@ -0,0 +1,483 @@ ++/* $Id$ */ ++/*- ++ * Copyright (c) 2008 Benedikt Meurer . ++ * Copyright (c) 2008 Colin Leroy . ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#ifdef HAVE_SYS_TYPES_H ++#include ++#endif ++#ifdef HAVE_SYS_STAT_H ++#include ++#endif ++#ifdef HAVE_SYS_WAIT_H ++#include ++#endif ++ ++#ifdef HAVE_MEMORY_H ++#include ++#endif ++#include ++#ifdef HAVE_STRING_H ++#include ++#endif ++#include ++ ++#include ++#include ++#include ++#include ++ ++static void ++tvm_crypto_volume_prompt_update_text (GtkEditable *editable, ++ gchar *new_text, ++ gint new_text_len, ++ gint *position, ++ gpointer data) ++{ ++ gchar **response = (gchar **)data; ++ if (response == NULL) ++ return; ++ g_free(*response); ++ *response = gtk_editable_get_chars(editable, 0, -1); ++} ++ ++typedef struct _CryptoDialogValidate { ++ GtkWidget *dialog; ++ gint response; ++} CryptoDialogValidate; ++ ++void ++tvm_crypto_volume_prompt_validate_text (GtkEntry *entry, ++ gpointer data) ++{ ++ CryptoDialogValidate *validate_data = (CryptoDialogValidate *)data; ++ gtk_dialog_response(GTK_DIALOG(validate_data->dialog), validate_data->response); ++} ++ ++static void ++tvm_crypto_volume_hal_device_removed (LibHalContext *context, ++ const gchar *udi) ++{ ++ const gchar *dialog_udi; ++ GtkWidget *dialog = libhal_ctx_get_user_data (context); ++ ++ /* check if the active UDI of the dialog was removed */ ++ dialog_udi = g_object_get_data (G_OBJECT (dialog), "udi"); ++ if (exo_str_is_equal (dialog_udi, udi)) ++ { ++ /* cancel the dialog */ ++ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); ++ } ++} ++ ++ /** ++ * tvm_crypto_volume_ask_password: ++ * @context : a #LibHalContext. ++ * @udi : the UDI of the device being added, which is watched for removal. ++ * @icon : the icon or %NULL. ++ * @title : the prompt title. ++ * @response_text : the response text. ++ * @visible : whether text typed should be visible. ++ * @default_response : Which response to return on Enter. ++ * @primary_text : the primary prompt text. ++ * @secondary_text : the secondary prompt text. ++ * @first_button_text : the first button text. ++ * @... : %NULL-terminated list of button text, response id pairs. ++ * ++ * Return value: the selected response. ++ **/ ++static gint ++tvm_crypto_volume_ask_password (LibHalContext *context, ++ const gchar *udi, ++ const gchar *icon, ++ const gchar *title, ++ gchar **response_text, ++ gboolean visible, ++ gint default_response, ++ const gchar *primary_text, ++ const gchar *secondary_text, ++ const gchar *first_button_text, ++ ...) ++{ ++ GtkWidget *dialog; ++ GtkWidget *image; ++ GtkWidget *label; ++ GtkWidget *hbox; ++ GtkWidget *vbox; ++ GtkWidget *entry; ++ DBusError derror; ++ va_list args; ++ gint response; ++ CryptoDialogValidate validate_data; ++ ++ g_return_val_if_fail (exo_hal_udi_validate (udi, -1, NULL), 0); ++ g_return_val_if_fail (context != NULL, GTK_RESPONSE_CANCEL); ++ ++ /* allocate a new dialog */ ++ dialog = gtk_dialog_new (); ++ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); ++ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); ++ g_object_set_data_full (G_OBJECT (dialog), "udi", g_strdup (udi), g_free); ++ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 6); ++ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); ++ ++ /* setup the specified title */ ++ if (G_LIKELY (title != NULL)) ++ gtk_window_set_title (GTK_WINDOW (dialog), title); ++ ++ /* setup the specified buttons */ ++ if (G_LIKELY (first_button_text != NULL)) ++ { ++ va_start (args, first_button_text); ++ for (response = va_arg (args, gint); first_button_text != NULL; ) ++ { ++ /* insert the button */ ++ gtk_dialog_add_button (GTK_DIALOG (dialog), first_button_text, response); ++ first_button_text = va_arg (args, const gchar *); ++ if (G_UNLIKELY (first_button_text == NULL)) ++ break; ++ response = va_arg (args, gint); ++ } ++ va_end (args); ++ } ++ ++ /* setup the hbox */ ++ hbox = gtk_hbox_new (FALSE, 12); ++ gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); ++ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); ++ gtk_widget_show (hbox); ++ ++ /* setup the specified icon */ ++ if (G_LIKELY (icon != NULL)) ++ { ++ /* setup an image for the icon */ ++ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_DIALOG); ++ gtk_misc_set_alignment (GTK_MISC (image), 0.0f, 0.0f); ++ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); ++ gtk_widget_show (image); ++ } ++ ++ /* setup the vbox */ ++ vbox = gtk_vbox_new (FALSE, 0); ++ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); ++ gtk_widget_show (vbox); ++ g_object_set_data(G_OBJECT(dialog), "main_vbox", vbox); ++ ++ /* setup the primary text */ ++ label = gtk_label_new (primary_text); ++ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); ++ gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); ++ gtk_label_set_use_markup (GTK_LABEL (label), TRUE); ++ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); ++ gtk_widget_show (label); ++ ++ /* setup the secondary text */ ++ if (G_LIKELY (secondary_text != NULL)) ++ { ++ label = gtk_label_new (secondary_text); ++ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); ++ gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); ++ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); ++ gtk_widget_show (label); ++ g_object_set_data(G_OBJECT(dialog), "secondary_text", label); ++ } ++ ++ entry = gtk_entry_new(); ++ gtk_entry_set_visibility(GTK_ENTRY(entry), visible); ++ gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0); ++ gtk_widget_show (entry); ++ g_object_set_data(G_OBJECT(dialog), "pass_entry", entry); ++ ++ /* initialize D-Bus error */ ++ dbus_error_init (&derror); ++ ++ /* setup HAL to watch the UDI for removal */ ++ libhal_ctx_set_user_data (context, dialog); ++ libhal_ctx_set_device_removed (context, tvm_crypto_volume_hal_device_removed); ++ libhal_device_property_watch_all (context, &derror); ++ ++ /* setup handler for the entered text */ ++ if (response_text) ++ *response_text = NULL; ++ g_signal_connect_after(G_OBJECT(entry), "insert-text", ++ G_CALLBACK(tvm_crypto_volume_prompt_update_text), ++ (gpointer) response_text); ++ validate_data.dialog = dialog; ++ validate_data.response = default_response; ++ g_signal_connect(G_OBJECT(entry), "activate", ++ G_CALLBACK(tvm_crypto_volume_prompt_validate_text), ++ (gpointer) &validate_data); ++ ++ /* run the dialog */ ++ response = gtk_dialog_run (GTK_DIALOG (dialog)); ++ gtk_widget_destroy(dialog); ++ ++ /* cleanup */ ++ libhal_ctx_set_device_removed (context, NULL); ++ libhal_ctx_set_user_data (context, NULL); ++ dbus_error_free (&derror); ++ ++ return response; ++} ++ ++static gboolean ++progress_pulse(gpointer data) ++{ ++ GtkProgressBar *progress = GTK_PROGRESS_BAR(data); ++ g_return_val_if_fail(progress != NULL, FALSE); ++ ++ gtk_progress_bar_pulse(progress); ++ ++ return TRUE; ++} ++ ++static void ++tvm_crypto_volume_dbus_call_done (DBusPendingCall *call, ++ void *user_data) ++{ ++ gtk_main_quit(); ++} ++ ++static gchar * ++tvm_crypto_volume_mount_install_crypto_volume (LibHalContext *context, ++ const gchar *udi, ++ LibHalVolume *volume, ++ const gchar *password, ++ gboolean *pass_error, ++ GError **error) ++{ ++ gchar *plain_udi = NULL; ++ DBusMessage *message = NULL; ++ DBusMessage *result = NULL; ++ DBusConnection *dbus_connection = NULL; ++ DBusPendingCall *call = NULL; ++ DBusError derror; ++ dbus_bool_t send_err; ++ *pass_error = FALSE; ++ GtkWidget *window = NULL; ++ GtkWidget *label, *vbox, *hbox; ++ GtkWidget *wait_progress; ++ GtkWidget *image; ++ guint animator_id; ++ g_clear_error(error); ++ ++ window = gtk_window_new(GTK_WINDOW_TOPLEVEL); ++ gtk_container_set_border_width(GTK_CONTAINER(window), 8); ++ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); ++ gtk_window_set_title(GTK_WINDOW(window), _("Encrypted volume")); ++ gtk_window_set_modal(GTK_WINDOW(window), TRUE); ++ gtk_window_set_resizable(GTK_WINDOW(window), FALSE); ++ ++ vbox = gtk_vbox_new(FALSE, 6); ++ hbox = gtk_hbox_new(FALSE, 6); ++ image = gtk_image_new_from_icon_name ("gtk-dialog-authentication", GTK_ICON_SIZE_DIALOG); ++ gtk_misc_set_alignment (GTK_MISC (image), 0.0f, 0.0f); ++ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); ++ gtk_widget_show (image); ++ ++ label = gtk_label_new(_("Mounting encrypted volume...")); ++ gtk_label_set_use_markup(GTK_LABEL(label), TRUE); ++ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); ++ ++ label = gtk_label_new(_("Setting up the crypto layer...")); ++ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); ++ ++ wait_progress = gtk_progress_bar_new(); ++ gtk_box_pack_start(GTK_BOX(vbox), wait_progress, TRUE, FALSE, 0); ++ ++ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); ++ ++ gtk_container_add(GTK_CONTAINER(window), hbox); ++ gtk_widget_show_all(hbox); ++ animator_id = g_timeout_add(100, progress_pulse, wait_progress); ++ ++ gtk_widget_show_now(window); ++ ++ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, ++ "org.freedesktop.Hal.Device.Volume.Crypto", ++ "Setup"); ++ ++ if (G_UNLIKELY (message == NULL)) ++ { ++ /* out of memory */ ++oom: g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_strerror (ENOMEM)); ++ goto out; ++ } ++ ++ if (!dbus_message_append_args (message, ++ DBUS_TYPE_STRING, &password, ++ DBUS_TYPE_INVALID)) { ++ dbus_message_unref (message); ++ goto oom; ++ } ++ ++ dbus_error_init (&derror); ++ ++ dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror); ++ if (G_UNLIKELY (dbus_connection == NULL)) ++ { ++ /* propagate the error */ ++ dbus_set_g_error (error, &derror); ++ goto out; ++ } ++ ++ send_err = dbus_connection_send_with_reply (dbus_connection, message, &call, -1); ++ if (G_UNLIKELY (send_err == FALSE)) ++ { ++ /* release the result */ ++ dbus_message_unref (message); ++ goto out; ++ } ++ ++ dbus_pending_call_set_notify(call, tvm_crypto_volume_dbus_call_done, NULL, NULL); ++ gtk_main(); ++ ++ result = dbus_pending_call_steal_reply(call); ++ /* release the message */ ++ dbus_message_unref (message); ++ ++ /* release the connection */ ++ dbus_connection_unref (dbus_connection); ++ ++ if (G_UNLIKELY (dbus_set_error_from_message(&derror, result))) ++ { ++ /* try to translate the error appropriately */ ++ if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0) ++ { ++ /* TRANSLATORS: The user tried to setup a crypto layer (LUKS-encrpyted volume) but got Permission denied. */ ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("You are not privileged to setup the crypto layer")); ++ } ++ else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) ++ { ++ /* TRANSLATORS: The user tried to setup a crypto layer (LUKS-encrpyted volume) and typed the wrong password. */ ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Wrong password")); ++ *pass_error = TRUE; ++ } ++ else ++ { ++ /* no precise error message, use the HAL one */ ++ dbus_set_g_error (error, &derror); ++ } ++ ++ /* release the DBus error */ ++ dbus_error_free (&derror); ++ dbus_message_unref (result); ++ plain_udi = NULL; ++ goto out; ++ } ++ else ++ { ++ dbus_message_unref (result); ++ plain_udi = libhal_volume_crypto_get_clear_volume_udi (context, volume); ++ } ++ ++out: ++ g_source_remove(animator_id); ++ gtk_widget_destroy(window); ++ return plain_udi; ++} ++ ++/** ++ * tvm_crypto_volume_setup: ++ * @preferences : a #TvmPreferences. ++ * @context : a #LibHalContext. ++ * @udi : the HAL volume UDI of the newly added crypto volume. ++ * @error : return location for errors or %NULL. ++ * ++ * Tries to setup the crypto layer for the volume with the ++ * specified @udi. ++ * ++ * Return value: %TRUE if handled, %FALSE if not handled or an ++ * unrecoverable error occurred. ++ */ ++gboolean ++tvm_crypto_volume_setup (TvmPreferences *preferences, ++ LibHalContext *context, ++ const gchar *udi, ++ GError **error) ++{ ++ gchar *password = NULL; ++ gboolean pass_error = FALSE; ++ gint num_tries = 0; ++ gchar *plain_udi = NULL; ++ LibHalVolume *volume = NULL; ++ gboolean result = FALSE; ++ ++ g_return_val_if_fail (exo_hal_udi_validate (udi, -1, NULL), FALSE); ++ g_return_val_if_fail (TVM_IS_PREFERENCES (preferences), FALSE); ++ g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ++ g_return_val_if_fail (context != NULL, FALSE); ++ ++ volume = libhal_volume_from_udi (context, udi); ++ g_return_val_if_fail(volume != NULL, FALSE); ++ plain_udi = libhal_volume_crypto_get_clear_volume_udi (context, volume); ++ if (plain_udi != NULL) { ++ libhal_volume_free(volume); ++ libhal_free_string(plain_udi); ++ return TRUE; ++ } ++ ++ for (num_tries = 0; num_tries < 3; num_tries++) { ++ gint response,len; ++ response = tvm_crypto_volume_ask_password (context, udi, "gtk-dialog-authentication", _("Encrypted volume"), ++ &password, FALSE, GTK_RESPONSE_OK, ++ pass_error? _("Wrong password.") ++ :_("This volume is encrypted."), ++ _("Please enter your password to decrypt and mount the volume."), ++ _("Ig_nore"), GTK_RESPONSE_CANCEL, ++ _("_Mount"), GTK_RESPONSE_OK, ++ NULL); ++ if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { ++ g_clear_error(error); ++ num_tries = 3; ++ } else if (password) { ++ plain_udi = tvm_crypto_volume_mount_install_crypto_volume(context, udi, volume, password, &pass_error, error); ++ } ++ if (password) { ++ len = strlen(password); ++ memset(password, 0, len); ++ g_debug("zeroed password %p", password); ++ g_free(password); ++ } ++ if (*error != NULL && !pass_error) { ++ /* display an error message to the user (exo-mount won't do it as it won't see the clear device */ ++ GtkWidget *message = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, ++ GTK_MESSAGE_ERROR, ++ GTK_BUTTONS_CLOSE, ++ "%s.", _("Failed to setup the encrypted volume")); ++ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.", (*error)->message); ++ gtk_dialog_run (GTK_DIALOG (message)); ++ gtk_widget_destroy (message); ++ break; ++ } ++ if (plain_udi != NULL) { ++ libhal_free_string(plain_udi); ++ result = TRUE; ++ break; ++ } ++ } ++ return result; ++} ++ ++ +Index: thunar-volman/tvm-printer-device.h +=================================================================== +--- thunar-volman/tvm-printer-device.h (revision 4898) ++++ thunar-volman/tvm-printer-device.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_printer_device_added (TvmPreferences *preferences, + LibHalContext *context, +@@ -30,6 +30,6 @@ + const gchar *capability, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PRINTER_DEVICE_H__ */ +Index: thunar-volman/tvm-crypto-volume.h +=================================================================== +--- thunar-volman/tvm-crypto-volume.h (revision 0) ++++ thunar-volman/tvm-crypto-volume.h (revision 0) +@@ -0,0 +1,35 @@ ++/* $Id$ */ ++/*- ++ * Copyright (c) 2008 Benedikt Meurer . ++ * Copyright (c) 2008 Colin Leroy . ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __TVM_CRYPTO_VOLUME_H__ ++#define __TVM_CRYPTO_VOLUME_H__ ++ ++#include ++ ++G_BEGIN_DECLS ++ ++gboolean tvm_crypto_volume_setup (TvmPreferences *preferences, ++ LibHalContext *context, ++ const gchar *udi, ++ GError **error) G_GNUC_INTERNAL; ++ ++G_END_DECLS ++ ++#endif /* !__TVM_CRYPTO_VOLUME_H__ */ +Index: thunar-volman/xfce-titled-dialog.h +=================================================================== +--- thunar-volman/xfce-titled-dialog.h (revision 4898) ++++ thunar-volman/xfce-titled-dialog.h (working copy) +@@ -23,7 +23,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + typedef struct _XfceTitledDialogPrivate XfceTitledDialogPrivate; + typedef struct _XfceTitledDialogClass XfceTitledDialogClass; +@@ -70,6 +70,6 @@ + void xfce_titled_dialog_set_subtitle (XfceTitledDialog *titled_dialog, + const gchar *subtitle); + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__XFCE_TITLED_DIALOG_H__ */ +Index: thunar-volman/tvm-preferences.h +=================================================================== +--- thunar-volman/tvm-preferences.h (revision 4898) ++++ thunar-volman/tvm-preferences.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + typedef struct _TvmPreferencesClass TvmPreferencesClass; + typedef struct _TvmPreferences TvmPreferences; +@@ -38,6 +38,6 @@ + + TvmPreferences *tvm_preferences_get (void); + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PREFERENCES_H__ */ +Index: thunar-volman/tvm-pango-extensions.h +=================================================================== +--- thunar-volman/tvm-pango-extensions.h (revision 4898) ++++ thunar-volman/tvm-pango-extensions.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + PangoAttrList *tvm_pango_attr_list_big (void) G_GNUC_CONST G_GNUC_INTERNAL; + PangoAttrList *tvm_pango_attr_list_big_bold (void) G_GNUC_CONST G_GNUC_INTERNAL; +@@ -31,6 +31,6 @@ + PangoAttrList *tvm_pango_attr_list_small_italic (void) G_GNUC_CONST G_GNUC_INTERNAL; + PangoAttrList *tvm_pango_attr_list_underline_single (void) G_GNUC_CONST G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PANGO_EXTENSIONS_H__ */ +Index: thunar-volman/tvm-run.h +=================================================================== +--- thunar-volman/tvm-run.h (revision 4898) ++++ thunar-volman/tvm-run.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + gboolean tvm_run_cdburner (TvmPreferences *preferences, + LibHalContext *context, +@@ -41,6 +41,6 @@ + const gchar *mount_point, + GError **error) G_GNUC_INTERNAL; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_RUN_H__ */ +Index: thunar-volman/Makefile.am +=================================================================== +--- thunar-volman/Makefile.am (revision 4898) ++++ thunar-volman/Makefile.am (working copy) +@@ -21,6 +21,8 @@ + tvm-camera-device.h \ + tvm-command-entry.c \ + tvm-command-entry.h \ ++ tvm-crypto-volume.c \ ++ tvm-crypto-volume.h \ + tvm-device.c \ + tvm-device.h \ + tvm-input-device.c \ +Index: thunar-volman/tvm-prompt.h +=================================================================== +--- thunar-volman/tvm-prompt.h (revision 4898) ++++ thunar-volman/tvm-prompt.h (working copy) +@@ -22,7 +22,7 @@ + + #include + +-G_BEGIN_DECLS; ++G_BEGIN_DECLS + + enum + { +@@ -46,6 +46,6 @@ + const gchar *first_button_text, + ...) G_GNUC_INTERNAL G_GNUC_NULL_TERMINATED; + +-G_END_DECLS; ++G_END_DECLS + + #endif /* !__TVM_PROMPT_H__ */ +Index: thunar-volman/tvm-block-device.c +=================================================================== +--- thunar-volman/tvm-block-device.c (revision 4898) ++++ thunar-volman/tvm-block-device.c (working copy) +@@ -1,6 +1,6 @@ + /* $Id$ */ + /*- +- * Copyright (c) 2007 Benedikt Meurer . ++ * Copyright (c) 2007-2008 Benedikt Meurer . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free +@@ -42,6 +42,7 @@ + #include + + #include ++#include + #include + #include + +@@ -609,6 +610,7 @@ + gboolean autoplay; + gboolean is_cdrom; + gboolean has_filesystem; ++ gboolean has_crypto; + gchar *storage_udi; + gchar *drive_type; + gchar *fsusage; +@@ -749,20 +751,30 @@ + libhal_free_string (storage_udi); + } + +- /* make sure the volume has a mountable filesystem */ ++ /* determine the file system usage of the volume */ + fsusage = libhal_device_get_property_string (context, udi, "volume.fsusage", NULL); +- has_filesystem = (G_LIKELY (fsusage && strcmp (fsusage, "filesystem") == 0)); ++ has_crypto = (G_UNLIKELY (fsusage != NULL && strcmp (fsusage, "crypto") == 0)); ++ has_filesystem = (G_LIKELY (fsusage != NULL && strcmp (fsusage, "filesystem") == 0)); + libhal_free_string (fsusage); +- if (G_UNLIKELY (!has_filesystem)) +- return FALSE; + +- /* check if we should automount drives, otherwise, we're done here */ +- g_object_get (G_OBJECT (preferences), "automount-drives", &automount, NULL); +- if (G_UNLIKELY (!automount)) +- return FALSE; ++ /* check if we have a crypto volume to setup here */ ++ if (G_UNLIKELY (has_crypto)) ++ { ++ /* try to setup the crypto volume */ ++ return tvm_crypto_volume_setup (preferences, context, udi, error); ++ } ++ else if (G_LIKELY (has_filesystem)) ++ { ++ /* check if we should automount drives, otherwise, we're done here */ ++ g_object_get (G_OBJECT (preferences), "automount-drives", &automount, NULL); ++ if (G_UNLIKELY (!automount)) ++ return FALSE; + +- /* try to mount the block device */ +- return tvm_block_device_mount (preferences, context, udi, error); ++ /* try to mount the block device */ ++ return tvm_block_device_mount (preferences, context, udi, error); ++ } ++ ++ return FALSE; + } + + -- 2.43.0