commit 1a6fd48def3ed490c5435bfdf4d5317a319479bd
parent 5290fd9e8d0643cbc37a1089eadb1fdb687b88b6
Author: Jaromil <jaromil@dyne.org>
Date: Mon, 14 Feb 2011 10:24:31 +0100
cleanup of password entry mechanism
using pinentry (with Assuan protocol) instead of our own askpass
a bit less cooler but much more secure.
this also includes partial normalization of variable names
and the redirection of tomb operational output to stderr.
Diffstat:
4 files changed, 75 insertions(+), 411 deletions(-)
diff --git a/doc/Makefile.am b/doc/Makefile.am
@@ -6,4 +6,3 @@ EXTRA_DIST = Luks_on_disk_format.pdf New_methods_in_HD_encryption.pdf TKS1-draft
install-data-hook:
ln -sf $(mandir)/man1/tomb.1 $(mandir)/man1/tomb-open.1
ln -sf $(mandir)/man1/tomb.1 $(mandir)/man1/tomb-status.1
- ln -sf $(mandir)/man1/tomb.1 $(mandir)/man1/tomb-askpass.1-
\ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -1,16 +1,12 @@
bin_SCRIPTS = tomb tomb-open
-bin_PROGRAMS = tomb-status tomb-askpass
+bin_PROGRAMS = tomb-status
tomb_status_SOURCES = tomb-status.c
tomb_status_LDADD = @GTK2_LIBS@ @NOTIFY_LIBS@
tomb_status_CFLAGS = @GTK2_CFLAGS@ @NOTIFY_CFLAGS@
-tomb_askpass_SOURCES = tomb-askpass.c
-tomb_askpass_LDADD = @GTK2_LIBS@
-tomb_askpass_CFLAGS = @GTK2_CFLAGS@
-
EXTRA_DIST = monmort.xpm
pixmapdir = $(datadir)/pixmaps
pixmap_DATA = monmort.xpm
diff --git a/src/tomb b/src/tomb
@@ -27,10 +27,10 @@ DATE=Feb/2011
# standard output message routines
# it's always useful to wrap them, in case we change behaviour later
-notice() { if ! [ $QUIET ]; then echo "[*] $1"; fi }
-act() { if ! [ $QUIET ]; then echo " . $1"; fi }
-error() { if ! [ $QUIET ]; then echo "[!] $1"; fi }
-func() { if [ $DEBUG ]; then echo "[D] $1"; fi }
+notice() { if ! [ $QUIET ]; then echo "[*] $1" >&2; fi }
+act() { if ! [ $QUIET ]; then echo " . $1" >&2; fi }
+error() { if ! [ $QUIET ]; then echo "[!] $1" >&2; fi }
+func() { if [ $DEBUG ]; then echo "[D] $1" >&2; fi }
# which dd command to use
which dcfldd > /dev/null
@@ -157,37 +157,31 @@ ask_usbkey() {
return 0
}
-# user interface (just to ask the password)
+# we use pinentry now
+# comes from gpg project and is much more secure
+# it also conveniently uses the right toolkit
ask_password() {
- xhost 2>&1 >/dev/null
- if [ $? = 0 ]; then # we have access to the X display
-
- which tomb-askpass > /dev/null
- if [ $? = 0 ]; then
- export scolopendro="`tomb-askpass ${1} 2>/dev/null`"
- return
- fi
- which ssh-askpass # 2>&1 > /dev/null
- if [ $? = 0 ]; then
- export scolopendro="`ssh-askpass "Tomb: provide the password to unlock"`"
- return
- fi
-
- else # we'll collect the password from commandline
-
- act "Tomb: provide the password to unlock"
- echo -n " > "
- read -s scolopendro
- export scolopendro
+ # pinentry has no custom icon setting
+ # so we need to temporary modify the gtk theme
+ cp ~/.gtkrc-2.0 ~/.gtkrc-2.0.bak
+ cat <<EOF >> ~/.gtkrc-2.0
+ pixmap_path "/usr/local/share/pixmaps"
+ style "normal" { stock["gtk-dialog-authentication"] = {{"monmort.xpm"}} }
+ widget "*" style "normal"
+EOF
- fi
+ cat <<EOF | pinentry | awk '/^D/ { print $2 }'
+SETTITLE Opening Tomb $1
+SETDESC You need a password to use its key
+SETPROMPT Password:
+GETPIN
+EOF
+
+ # restore gtk as it was
+ cp ~/.gtkrc-2.0.bak ~/.gtkrc-2.0
+ rm ~/.gtkrc-2.0.bak
- # just in case we'd like to have dialog supported too:
- # dialog --backtitle "This file is encrypted for privacy protection" \
- # --title "Security check" --insecure \
- # --passwordbox "Enter password:" 10 30 2> /var/run/.scolopendro
-
}
# popup notification
@@ -247,18 +241,21 @@ check_priv() {
if [ $? = 0 ]; then
func "Using sudo for root execution of 'tomb ${(f)ARGS}'"
# check if sudo has a timestamp active
- sudo -n true 2> /dev/null
- if [ $? != 0 ]; then
- # if not then ask a password
- echo "SETDESC Sudo execution of Tomb ${ARGS[@]}
+ sudok=false
+ sudo -n tomb 2> /dev/null
+ if [ $? != 0 ]; then # if not then ask a password
+ cat <<EOF | pinentry | awk '/^D/ { print $2 }' | sudo -S -v
+SETTITLE Super user privileges required
+SETDESC Sudo execution of Tomb ${ARGS[@]}
SETPROMPT Insert your USER password:
-GETPIN" | pinentry | awk '/^D/ { print $2 }' | sudo -S -v
+GETPIN
+EOF
fi
sudo "tomb" ${(s: :)ARGS}
exit $?
- fi
+ fi # have sudo
return 1
- fi
+ fi # are we root already
return 0
}
@@ -409,17 +406,17 @@ create_tomb() {
# here user is prompted for key password
for c in 1 2 3; do
# 3 tries to write two times a matching password
- ask_password ${FILE}
- scolotemp=$scolopendro
- ask_password "${FILE} (again)"
- if [ "$scolotemp" = "$scolopendro" ]; then
+ tombpass=`exec_as_user tomb -q askpass ${FILE}`
+ tombpasstmp=$tombpass
+ tombpass=`exec_as_user tomb -q askpass "${FILE} (again)"`
+ if [ "$tombpasstmp" = "$tombpass" ]; then
break;
fi
- unset $scolotemp
- unset $scolopendro
+ unset tombpasstmp
+ unset tombpass
done
- if [ -z $scolopendro ]; then
+ if [ -z $tombpass ]; then
error "passwords don't match, aborting operation"
umount ${keytmp}
losetup -d $nstloop
@@ -427,8 +424,9 @@ create_tomb() {
exit 1
fi
- echo "${scolopendro}" | gpg --batch --no-options --no-tty --passphrase-fd 0 \
+ echo "${tombpass}" | gpg --batch --no-options --no-tty --passphrase-fd 0 \
-o "${FILE}.gpg" -c -a ${keytmp}/tomb.tmp
+
if [ $? = 2 ]; then
error "setting password failed: gnupg returns 2"
umount ${keytmp}
@@ -491,7 +489,7 @@ create_tomb() {
cp -v ${FILE}.gpg ${usbkey_mount}/.tomb/
chmod -R go-rwx ${usbkey_mount}/.tomb
umount ${usbkey_mount}
- unset ${usbkey_mount}
+ unset usbkey_mount
notice "Key ${FILE}.gpg succesfully saved on your USB"
act "now we proceed opening your new tomb"
KEY=${FILE}.gpg
@@ -503,6 +501,8 @@ create_tomb() {
else # kept besides (deprecated behaviour)
act "now we proceed opening your new tomb"
KEY=${FILE}.gpg
+ unset CMD2
+ unset CMD3
mount_tomb ${FILE}
fi
@@ -515,7 +515,6 @@ mount_tomb() {
return 1
elif [ -r $CMD2 ]; then
tombfile=`basename $CMD2`
- tombdir=`dirname $CMD2`
else
# try also adding a .tomb extension
tombfile=${tombfile%%\.*}.tomb
@@ -525,6 +524,8 @@ mount_tomb() {
fi
fi
+ tombdir=`dirname $CMD2`
+
file ${tombdir}/${tombfile} | grep -i 'luks encrypted.*cbc-essiv' 2>&1 >/dev/null
if [ $? != 0 ]; then
error "$CMD2 is not a valid tomb file, operation aborted"
@@ -533,7 +534,7 @@ mount_tomb() {
fi
tombname=${tombfile%%\.*}
- act "mounting tomb named after $tombname"
+ act "mounting tomb named $tombname"
if [ $KEY ]; then
tombkey="`basename $KEY`"
@@ -564,14 +565,14 @@ mount_tomb() {
fi
if ! [ $CMD3 ]; then
- tombmount=/media/`basename ${tombfile}`
+ tombmount=/media/${tombfile}
act "mountpoint not specified, using default: $tombmount"
elif ! [ -x $CMD3 ]; then
error "mountpoint $CMD3 doesn't exist, operation aborted."
if [ -n "$usbkey_mount" ]; then
umount $usbkey_mount
rmdir $usbkey_mount
- unset $usbkey_mount
+ unset usbkey_mount
fi
return 1
else
@@ -611,16 +612,16 @@ mount_tomb() {
for c in 1 2 3; do
if [ $c = 1 ]; then
- ask_password ${keyname}
+ tombpass=`exec_as_user tomb -q askpass ${keyname}`
else
- ask_password "$keyname (retry $c)"
+ tombpass=`exec_as_user tomb -q askpass "$keyname (retry $c)"`
fi
- echo "${scolopendro}" \
+ echo "${tombpass}" \
| gpg --batch --passphrase-fd 0 --no-tty --no-options \
- -d "${tombkeypath}" 2>/dev/null \
+ -d "${tombkeypath}" \
| cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
- unset scolopendro
+ unset tombpass
if [ -r /dev/mapper/${mapper} ]; then
break; # password was correct
@@ -631,7 +632,7 @@ mount_tomb() {
if [ -r ${usbkey_mount}/.tomb/${tombkey} ]; then
umount ${usbkey_mount}
rmdir ${usbkey_mount}
- unset ${usbkey_mount}
+ unset usbkey_mount
fi
if ! [ -r /dev/mapper/${mapper} ]; then
@@ -644,7 +645,7 @@ mount_tomb() {
act "encrypted storage filesystem check"
fsck -p -C0 /dev/mapper/${mapper}
act "tomb engraved as $tombname"
- tune2fs -L ${tombname} /dev/mapper/${mapper}
+ tune2fs -L ${tombname} /dev/mapper/${mapper} > /dev/null
mount -o rw,noatime,nodev /dev/mapper/${mapper} ${tombmount}
@@ -681,17 +682,17 @@ encode_key() {
# here user is prompted for key password
for c in 1 2 3; do
# 3 tries to write two times a matching password
- ask_password ${FILE}
- scolotemp=$scolopendro
- ask_password "${FILE} (again)"
- if [ "$scolotemp" = "$scolopendro" ]; then
+ tombpass=`exec_as_user tomb -q askpass ${FILE}`
+ tombpasstmp=$tombpass
+ tombpass=`exec_as_user tomb -q askpass "${FILE} (again)"`
+ if [ "$tombpasstmp" = "$tombpass" ]; then
break;
fi
- unset $scolotemp
- unset $scolopendro
+ unset tombpasstmp
+ unset tombpass
done
- if [ -z $scolopendro ]; then
+ if [ -z $tombpass ]; then
error "passwords don't match, aborting operation."
return 1
fi
@@ -702,7 +703,7 @@ encode_key() {
/^Comment/ {next}
{print $0}' ${tombkey} \
| steghide embed --embedfile - --coverfile ${imagefile} \
- -p ${scolopendro} -z 9 -e serpent cbc
+ -p ${tombpass} -z 9 -e serpent cbc
if [ $? != 0 ]; then
error "encoding error: steghide reports problems"
res=1
@@ -711,7 +712,7 @@ encode_key() {
res=0
fi
- unset scolopendro
+ unset tombpass
return $res
}
@@ -731,11 +732,11 @@ decode_key() {
notice "Decoding a key out of image $imagefile"
for c in 1 2 3; do
if [ $c = 1 ]; then
- ask_password ${keyname}
+ tombpass=`exec_as_user tomb -q askpass ${keyname}`
else
- ask_password "$keyname (retry $c)"
+ tombpass=`exec_as_user tomb -q askpass "$keyname (retry $c)"`
fi
- steghide extract -sf ${imagefile} -p ${scolopendro} -xf - \
+ steghide extract -sf ${imagefile} -p ${tombpass} -xf - \
| awk '
BEGIN {
print "-----BEGIN PGP MESSAGE-----"
@@ -753,7 +754,7 @@ print "-----END PGP MESSAGE-----"
fi
done
- unset scolopendro
+ unset tombpass
if [ $res != 0 ]; then
error "nothing found."
@@ -1030,6 +1031,7 @@ case "$CMD" in
install) check_priv ; install_tomb ;;
+ askpass) ask_password $CMD2 $CMD3 ;;
status) tomb-status ;;
notify) tomb-notify $CMD2 $CMD3 ;;
@@ -1039,4 +1041,4 @@ case "$CMD" in
;;
esac
# return codes from called functions
-return $?
+# return $?
diff --git a/src/tomb-askpass.c b/src/tomb-askpass.c
@@ -1,332 +0,0 @@
-/* Tomb askpass
-
- Derived from gtk-led-askpass.c version 0.9
- by Dafydd Harries <daf@muse.19inch.net>, 2003 2004
- (An ssh-askpass alike software)
-
- Based on ideas from ssh-askpass-gnome, by Damien Miller and Nalin Dahyabhai,
- and on Jim Knoble's x11-ssh-askpass.
-
- 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 3 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
-
- See also:
-
- http://www.cgabriel.org/sw/gtk2-ssh-askpass/
- -- Jim Knoble's x11-ssh-askpass
- http://www.cgabriel.org/sw/gtk2-ssh-askpass/
- -- Christopher Gabriel's gtk2-ssh-askpass
-
- Todo:
-
- - Internationalise. Probably entails autotoolising.
- - Add more eye candy.
- - Implement optional mouse/server grabbing.
- - Alow overriding the title on the command line.
- - Make the LED box a proper GTK+ widget.
-
-*/
-
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-/* The Tomb icon is an artwork by Jordi aka MonMort
- a nomadic graffiti artist from Barcelona */
-#include <monmort.xpm>
-
-/* Title for the dialog. */
-#define TITLE "Unlocking tomb"
-
-/* Width of each LED. */
-#define LED_WIDTH 8
-/* Height of each LED. */
-#define LED_HEIGHT 16
-/* Space around and between LEDs. */
-#define LED_MARGIN 5
-/* Number of LEDs to have. */
-#define LED_COUNT 12
-
-/* How many times to attempt to grab the keyboard before giving up. */
-#define GRAB_TRIES_MAX 10
-/* How long to sleep, in microseconds, in between keyboard grab attempts. */
-#define GRAB_SLEEP 100000
-/* Sleep length, in milliseconds, after Control-U press. */
-#define CLEAR_SLEEP 800
-
-enum {
- LED_STATE_OFF,
- LED_STATE_GREEN,
- LED_STATE_RED,
- LED_STATES
-};
-
-GdkPixbuf *pb_monmort;
-
-GdkColor colours[LED_STATES] = {
- /* LED_STATE_OFF */
- { 0, 0x3333, 0x6666, 0x3333 },
- /* LED_STATE_GREEN */
- { 0, 0x6666, 0xFFFF, 0x6666 },
- /* LED_STATE_RED */
- { 0, 0xDDDD, 0x3333, 0x3333 }
-};
-
-
-void draw_led(GtkWidget *widget, gint state, guint offset)
-{
- GdkGC *gc = gdk_gc_new(widget->window);
-
- /* Draw the border. */
- gdk_draw_rectangle(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
- FALSE,
- LED_MARGIN + offset * (LED_WIDTH + LED_MARGIN),
- LED_MARGIN,
- LED_WIDTH,
- LED_HEIGHT);
-
- gdk_gc_set_rgb_fg_color(gc, &(colours[state]));
-
- /* Draw the inside rectangle. */
- gdk_draw_rectangle(widget->window,
- gc,
- TRUE,
- LED_MARGIN + offset * (LED_WIDTH + LED_MARGIN) + 1,
- LED_MARGIN + 1,
- LED_WIDTH - 1,
- LED_HEIGHT - 1);
-}
-
-gboolean led_area_expose_handler(GtkWidget *led_area, GdkEventExpose *event,
- GString *passphrase)
-{
- gint i, width, height;
- gint length = passphrase->len;
-
- gdk_drawable_get_size(GDK_DRAWABLE(led_area->window), &width, &height);
-
- /* Draw a focus indicator if appropriate. */
- if (GTK_WIDGET_HAS_FOCUS(led_area))
- gtk_paint_focus(led_area->style, led_area->window,
- GTK_WIDGET_STATE(led_area), &(event->area), led_area,
- "", 0, 0, width, height);
-
- /* Draw each LED. */
- for (i = 0; i < LED_COUNT; i++) {
- /* This is the complicated bit. */
- gboolean on = ((length / LED_COUNT) % 2 == 0) ?
- (length % LED_COUNT > i) :
- (length % LED_COUNT <= i);
-
- draw_led(led_area, on ? LED_STATE_GREEN : LED_STATE_OFF, i);
- }
-
- /* TRUE means not to propagate the event. */
- return TRUE;
-}
-
-gboolean timeout_handler(GtkWidget *led_area)
-{
- gtk_widget_queue_draw(led_area);
-
- return FALSE;
-}
-
-void clear(GString *passphrase, GtkWidget *led_area)
-{
- gint i;
-
- /*
- Delete bit by bit to ensure erasure. g_string_erase() will overwrite
- the last character with 0, so we shouldn't need to worry about leaving
- sensitive data in memory. Note that the string may be empty. This is
- so that the interface responds consistently.
- */
- while (passphrase->len > 0)
- g_string_erase(passphrase, passphrase->len - 1, 1);
-
- for (i = 0; i < LED_COUNT; i++)
- draw_led(led_area, LED_STATE_RED, i);
-
- /*
- Remove the redness after a delay. If an exposure is triggered, such as
- by a key getting pressed, then the redraw will simply happen early.
- */
- gtk_timeout_add(CLEAR_SLEEP, (GtkFunction)timeout_handler, led_area);
-}
-
-gboolean led_area_key_press_handler(GtkWidget *led_area, GdkEventKey *event,
- GString *passphrase) {
- /* Obtain Unicode representation of key released. */
- gunichar c = gdk_keyval_to_unicode(event->keyval);
- /* Determine whether the key released was printable. */
- gint isprint = g_unichar_isprint(c);
- /* Obtain default modifier mask. */
- guint modifiers = gtk_accelerator_get_default_mod_mask();
-
- if (event->keyval == GDK_Delete) {
- clear(passphrase, led_area);
- return TRUE;
- }
-
- if ((event->state & modifiers) == GDK_CONTROL_MASK) {
-
- if (event->keyval == GDK_u) {
- /* C-u -- delete everything. */
- clear(passphrase, led_area);
- /* Return early in order to avoid the redraw. */
- return TRUE;
-
- } else {
-
- /* Unrecognised keypress. */
- return FALSE;
- }
-
- } else if (event->keyval == GDK_BackSpace && passphrase->len > 0) {
- /*
- Backspace -- remove last character. See the comment above
- about g_string_erase.
- */
- g_string_erase(passphrase, passphrase->len - 1, 1);
- } else if (isprint) {
- /* Printable character. */
- g_string_append_unichar(passphrase, c);
- } else {
- /* Unrecognized keypress, propagate. */
- return FALSE;
- }
-
- /* Trigger a redraw of the LED area. */
- gtk_widget_queue_draw(led_area);
-
- /* TRUE means not to propagate the event. */
- return TRUE;
-}
-
-gboolean led_area_button_press_handler(GtkWidget *led_area,
- GdkEventButton *event, gpointer data)
-{
- gtk_widget_grab_focus(led_area);
-
- return TRUE;
-}
-
-int main(int argc, char *argv[])
-{
- gint response, grab_tries, i;
- char keyname[256];
- GString *passphrase = g_string_new("");
- GtkWidget *dialog, *alignment, *led_area;
- GList tmplist;
-
- gtk_set_locale();
- gtk_init(&argc, &argv);
-
- if (argc > 1) {
- snprintf(keyname,255,"%s",argv[1]);
- } else {
- sprintf(keyname,"unknown");
- }
- /*
- dialog
- `- vbox (implicit)
- `- aligment
- `- led_area
- */
-
- /* Question dialog with no parent; OK and Cancel buttons. */
- dialog = gtk_message_dialog_new_with_markup
- (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK,
- "Enter the password to unlock\n"
- "<span font=\"Times 24\">%s</span>", keyname);
- gtk_window_set_title(GTK_WINDOW(dialog), TITLE);
-
- // set and show the image icon
- pb_monmort = gdk_pixbuf_new_from_xpm_data(monmort);
- tmplist.data = (gpointer*)pb_monmort;
- tmplist.prev = tmplist.next = NULL;
- gtk_window_set_icon_list(GTK_WINDOW(dialog), &tmplist);
- gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog),
- gtk_image_new_from_pixbuf(pb_monmort));
-
- /* Place the dialog in the middle of the screen. */
- gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
- /* OK is the default action. */
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
-
- /* Add some spacing within the dialog's vbox. */
- gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 3);
-
- /* The alignment widget containing the drawing area. */
- alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), alignment);
-
- /* The drawing area for the LEDs. */
- led_area = gtk_drawing_area_new();
- gtk_container_add(GTK_CONTAINER(alignment), led_area);
- /* Make the LED widget focusable. */
- GTK_WIDGET_SET_FLAGS(led_area, GTK_CAN_FOCUS);
- /* Make the LED widget focused. */
- gtk_widget_grab_focus(led_area);
- /* Make the LED widget receive key press and button press events. */
- gtk_widget_add_events(led_area,
- GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK);
- /* Set a size request. */
- gtk_widget_set_size_request(led_area,
- LED_MARGIN + (LED_WIDTH + LED_MARGIN) * LED_COUNT,
- LED_HEIGHT + LED_MARGIN * 2);
- /* Set up handler for key releases. */
- g_signal_connect(G_OBJECT(led_area), "key_press_event",
- G_CALLBACK(led_area_key_press_handler), passphrase);
- /* Set up handler for button releases. */
- g_signal_connect(G_OBJECT(led_area), "button_press_event",
- G_CALLBACK(led_area_button_press_handler), NULL);
- /* Set up handler for expose events. */
- g_signal_connect(G_OBJECT(led_area), "expose_event",
- G_CALLBACK(led_area_expose_handler), passphrase);
-
-
- /* Show all the widgets. */
- gtk_widget_show_all(dialog);
- /* Put the dialog on the screen now for the grab to work. */
- gtk_widget_show_now(dialog);
-
- /* Grab the keyboard */
- gdk_keyboard_grab(GTK_WIDGET(dialog)->window, FALSE, GDK_CURRENT_TIME);
-
- /* Make the dialog stay on top. */
- gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-
- /* Run the dialog. */
- response = gtk_dialog_run(GTK_DIALOG(dialog));
-
- /* Ungrab the keyboard. */
- gdk_keyboard_ungrab(GDK_CURRENT_TIME);
-
- /* If the OK button was pressed, print the passphrase. */
- if (response == GTK_RESPONSE_OK)
- g_print("%s\n", passphrase->str);
-
- /* Scrub the passphrase, if any. */
- for (i = 0; i < passphrase->len; i++)
- passphrase->str[i] = '\0';
-
- if (response == GTK_RESPONSE_OK)
- return 0;
-
- return 1;
-}
-