From: Paul Mangan Date: Sat, 13 Apr 2002 10:21:38 +0000 (+0000) Subject: enable storing of GnuPG passphrase X-Git-Tag: rel_0_7_5~40 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=249bb0f0146e95523d80794f8502bbe346f32d0f enable storing of GnuPG passphrase --- diff --git a/ChangeLog.claws b/ChangeLog.claws index e96a29d4e..3ae4a6cc6 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,14 @@ +2002-04-13 [paul] 0.7.4claws80 + + * src/main.c + src/passphrase.[ch] + src/pgptext.c + src/prefs_common.[ch] + src/rfc2015.c + enable storing of GnuPG passphrase for the whole + session or a user-defined number of minutes. patch + submitted by Ravemax + 2002-04-13 [alfons] 0.7.4claws79 * src/textview.c diff --git a/configure.in b/configure.in index add5cf58b..d85dd8413 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ MINOR_VERSION=7 MICRO_VERSION=4 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws79 +EXTRA_VERSION=claws80 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl set $target diff --git a/src/main.c b/src/main.c index c27cf0054..c74b21ebe 100644 --- a/src/main.c +++ b/src/main.c @@ -47,6 +47,7 @@ #if USE_GPGME # include +# include "passphrase.h" #endif #include "intl.h" @@ -414,6 +415,10 @@ void app_will_exit(GtkWidget *widget, gpointer data) inc_autocheck_timer_remove(); +#if USE_GPGME + gpgmegtk_free_passphrase(); +#endif + if (prefs_common.clean_on_exit) main_window_empty_trash(mainwin, prefs_common.ask_on_clean); diff --git a/src/passphrase.c b/src/passphrase.c index c36b9ea4a..bf69340f7 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -23,6 +23,7 @@ #if USE_GPGME #include +#include #include #include #include /* GDK_DISPLAY() */ @@ -40,12 +41,14 @@ #include "intl.h" #include "passphrase.h" +#include "prefs_common.h" #include "manage_window.h" static int grab_all = 0; static gboolean pass_ack; +static gchar* lastPass = NULL; static void passphrase_ok_cb(GtkWidget *widget, gpointer data); static void passphrase_cancel_cb(GtkWidget *widget, gpointer data); @@ -53,6 +56,9 @@ static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data); static void passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data); +static gchar* passphrase_mbox (const gchar *desc); + + static GtkWidget *create_description (const gchar *desc); void @@ -61,8 +67,8 @@ gpgmegtk_set_passphrase_grab (gint yes) grab_all = yes; } -gchar * -gpgmegtk_passphrase_mbox (const gchar *desc) +static gchar* +passphrase_mbox (const gchar *desc) { gchar *the_passphrase = NULL; GtkWidget *vbox; @@ -260,4 +266,61 @@ create_description (const gchar *desc) return label; } +static int free_passphrase(gpointer _unused) +{ + if (lastPass != NULL) { + munlock(lastPass, strlen(lastPass)); + g_free(lastPass); + lastPass = NULL; // necessary? + g_message("%% passphrase removed"); + } + + return FALSE; +} + +const char* +gpgmegtk_passphrase_cb (void *opaque, const char *desc, void *r_hd) +{ + struct passphrase_cb_info_s *info = opaque; + GpgmeCtx ctx = info ? info->c : NULL; + const char *pass; + + if (!desc) { + /* FIXME: cleanup by looking at *r_hd */ + return NULL; + } + if (prefs_common.store_passphrase + && strncmp(desc, "TRY_AGAIN", 9) && (lastPass != NULL)) + return g_strdup(lastPass); + + gpgmegtk_set_passphrase_grab (prefs_common.passphrase_grab); + g_message ("%% requesting passphrase for `%s': ", desc ); + pass = passphrase_mbox (desc); + gpgmegtk_free_passphrase(); + if (!pass) { + g_message ("%% cancel passphrase entry"); + gpgme_cancel (ctx); + } + else { + if (prefs_common.store_passphrase) { + lastPass = g_strdup(pass); + if (mlock(lastPass, strlen(lastPass)) == -1) + g_message("%% locking passphrase failed"); + + if (prefs_common.store_passphrase_timeout > 0) { + gtk_timeout_add(prefs_common.store_passphrase_timeout*60*1000, + free_passphrase, NULL); + } + } + g_message ("%% sending passphrase"); + } + + return pass; +} + +void gpgmegtk_free_passphrase() +{ + (void)free_passphrase(NULL); // could be inline +} + #endif /* USE_GPGME */ diff --git a/src/passphrase.h b/src/passphrase.h index c3c69b70a..3f4b2e33d 100644 --- a/src/passphrase.h +++ b/src/passphrase.h @@ -20,8 +20,15 @@ #define GPGMEGTK_PASSPHRASE_H #include +#include + +struct passphrase_cb_info_s { + GpgmeCtx c; + int did_it; +}; void gpgmegtk_set_passphrase_grab (gint yesno); -gchar *gpgmegtk_passphrase_mbox (const gchar *desc); +const char* gpgmegtk_passphrase_cb(void *opaque, const char *desc, void *r_hd); +void gpgmegtk_free_passphrase(); #endif /* GPGMEGTK_PASSPHRASE_H */ diff --git a/src/pgptext.c b/src/pgptext.c index 4ed72ec3f..dfa7617dc 100644 --- a/src/pgptext.c +++ b/src/pgptext.c @@ -63,12 +63,6 @@ static char *mime_version_name[] = { NULL }; - -struct passphrase_cb_info_s { - GpgmeCtx c; - int did_it; -}; - /* stolen from rfc2015.c */ static int gpg_name_cmp(const char *a, const char *b) @@ -82,31 +76,6 @@ gpg_name_cmp(const char *a, const char *b) return *a != *b; } -static const char * -passphrase_cb (void *opaque, const char *desc, void *r_hd) -{ - struct passphrase_cb_info_s *info = opaque; - GpgmeCtx ctx = info ? info->c : NULL; - const char *pass; - - if (!desc) { - /* FIXME: cleanup by looking at *r_hd */ - return NULL; - } - - gpgmegtk_set_passphrase_grab (prefs_common.passphrase_grab); - debug_print ("requesting passphrase for `%s': ", desc); - pass = gpgmegtk_passphrase_mbox (desc); - if (!pass) { - debug_print ("cancel passphrase entry\n"); - gpgme_cancel (ctx); - } - else - debug_print ("sending passphrase\n"); - - return pass; -} - static GpgmeData pgptext_decrypt (MimeInfo *partinfo, FILE *fp) { @@ -139,7 +108,7 @@ pgptext_decrypt (MimeInfo *partinfo, FILE *fp) if (!getenv("GPG_AGENT_INFO")) { info.c = ctx; - gpgme_set_passphrase_cb (ctx, passphrase_cb, &info); + gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } err = gpgme_op_decrypt (ctx, cipher, plain); @@ -147,6 +116,7 @@ pgptext_decrypt (MimeInfo *partinfo, FILE *fp) leave: gpgme_data_release (cipher); if (err) { + gpgmegtk_free_passphrase(); debug_print ("decryption failed: %s\n", gpgme_strerror (err)); gpgme_data_release (plain); plain = NULL; diff --git a/src/prefs_common.c b/src/prefs_common.c index 714fed40e..1c06e38e4 100644 --- a/src/prefs_common.c +++ b/src/prefs_common.c @@ -194,6 +194,9 @@ static struct Message { static struct Privacy { GtkWidget *checkbtn_auto_check_signatures; GtkWidget *checkbtn_gpg_signature_popup; + GtkWidget *checkbtn_store_passphrase; + GtkWidget *spinbtn_store_passphrase; + GtkObject *spinbtn_store_passphrase_adj; GtkWidget *checkbtn_passphrase_grab; GtkWidget *checkbtn_gpg_warning; GtkWidget *optmenu_default_signkey; @@ -667,6 +670,12 @@ static PrefParam param[] = { &prefs_common.gpg_signature_popup, P_BOOL, &privacy.checkbtn_gpg_signature_popup, prefs_set_data_from_toggle, prefs_set_toggle}, + {"store_passphrase", "FALSE", &prefs_common.store_passphrase, P_BOOL, + &privacy.checkbtn_store_passphrase, + prefs_set_data_from_toggle, prefs_set_toggle}, + {"store_passphrase_timeout", "0", &prefs_common.store_passphrase_timeout, + P_INT, &privacy.spinbtn_store_passphrase, + prefs_set_data_from_spinbtn, prefs_set_spinbtn}, #ifndef __MINGW32__ {"passphrase_grab", "FALSE", &prefs_common.passphrase_grab, P_BOOL, &privacy.checkbtn_passphrase_grab, @@ -2356,6 +2365,14 @@ static void prefs_privacy_create(void) GtkWidget *hbox1; GtkWidget *checkbtn_auto_check_signatures; GtkWidget *checkbtn_gpg_signature_popup; + GtkWidget *hbox_stpass; + GtkWidget *checkbtn_store_passphrase; + GtkWidget *label_stpass1; + GtkObject *spinbtn_store_passphrase_adj; + GtkWidget *spinbtn_store_passphrase; + GtkWidget *label_stpass2; + GtkWidget *hbox_stpassinfo; + GtkWidget *label_stpassinfo; GtkWidget *checkbtn_passphrase_grab; GtkWidget *checkbtn_gpg_warning; GtkWidget *label; @@ -2378,6 +2395,43 @@ static void prefs_privacy_create(void) PACK_CHECK_BUTTON (vbox2, checkbtn_gpg_signature_popup, _("Show signature check result in a popup window")); + hbox_stpass = gtk_hbox_new(FALSE, 8); + gtk_box_pack_start(GTK_BOX(vbox2), hbox_stpass, FALSE, FALSE, 0); + + PACK_CHECK_BUTTON (hbox_stpass, checkbtn_store_passphrase, + _("Store passphrase temporarily")); + + label_stpass1 = gtk_label_new(_("- remove after")); + gtk_box_pack_start(GTK_BOX(hbox_stpass), label_stpass1, FALSE, FALSE, 0); + + spinbtn_store_passphrase_adj = gtk_adjustment_new(0, 0, 1440, 1, 5, 5); + spinbtn_store_passphrase = gtk_spin_button_new( + GTK_ADJUSTMENT(spinbtn_store_passphrase_adj), 1, 0); + gtk_box_pack_start(GTK_BOX(hbox_stpass), spinbtn_store_passphrase, FALSE, + FALSE, 0); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinbtn_store_passphrase), + TRUE); + gtk_widget_set_usize(spinbtn_store_passphrase, 50, -1); + + label_stpass2 = gtk_label_new(_("minute(s)")); + gtk_box_pack_start(GTK_BOX(hbox_stpass), label_stpass2, FALSE, FALSE, 0); + gtk_widget_show_all(hbox_stpass); + + hbox_stpassinfo = gtk_hbox_new(FALSE, 8); + gtk_box_pack_start(GTK_BOX(vbox2), hbox_stpassinfo, FALSE, FALSE, 0); + + label_stpassinfo = gtk_label_new + (_("(A setting of '0' will store the passphrase\n" + " for the whole session)")); + gtk_box_pack_start (GTK_BOX (hbox_stpassinfo), label_stpassinfo, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label_stpassinfo), GTK_JUSTIFY_LEFT); + gtk_widget_show_all(hbox_stpassinfo); + + SET_TOGGLE_SENSITIVITY(checkbtn_store_passphrase, label_stpass1); + SET_TOGGLE_SENSITIVITY(checkbtn_store_passphrase, spinbtn_store_passphrase); + SET_TOGGLE_SENSITIVITY(checkbtn_store_passphrase, label_stpass2); + SET_TOGGLE_SENSITIVITY(checkbtn_store_passphrase, label_stpassinfo); + #ifndef __MINGW32__ PACK_CHECK_BUTTON (vbox2, checkbtn_passphrase_grab, _("Grab input while entering a passphrase")); @@ -2410,6 +2464,9 @@ static void prefs_privacy_create(void) = checkbtn_auto_check_signatures; privacy.checkbtn_gpg_signature_popup = checkbtn_gpg_signature_popup; + privacy.checkbtn_store_passphrase = checkbtn_store_passphrase; + privacy.spinbtn_store_passphrase = spinbtn_store_passphrase; + privacy.spinbtn_store_passphrase_adj = spinbtn_store_passphrase_adj; privacy.checkbtn_passphrase_grab = checkbtn_passphrase_grab; privacy.checkbtn_gpg_warning = checkbtn_gpg_warning; privacy.optmenu_default_signkey = optmenu; @@ -2709,7 +2766,7 @@ static void prefs_other_create(void) "netscape -remote 'openURL(%s,raise)'", "netscape '%s'", "gnome-moz-remote --raise --newwin '%s'", - "kfmclient openProfile webbrowsing '%s'", + "kfmclient openURL '%s'", "opera -newwindow '%s'", "kterm -e w3m '%s'", "kterm -e lynx '%s'", diff --git a/src/prefs_common.h b/src/prefs_common.h index 72598238b..002907ae7 100644 --- a/src/prefs_common.h +++ b/src/prefs_common.h @@ -198,6 +198,8 @@ struct _PrefsCommon /* Privacy */ gboolean auto_check_signatures; gboolean gpg_signature_popup; + gboolean store_passphrase; + gint store_passphrase_timeout; gboolean passphrase_grab; gchar *default_signkey; gboolean gpg_warning; diff --git a/src/rfc2015.c b/src/rfc2015.c index cc177c917..6bb3f7719 100644 --- a/src/rfc2015.c +++ b/src/rfc2015.c @@ -61,12 +61,6 @@ static char *mime_version_name[] = { NULL }; - -struct passphrase_cb_info_s { - GpgmeCtx c; - int did_it; -}; - static char *create_boundary (void); #if 0 @@ -335,31 +329,6 @@ leave: gpgmegtk_sig_status_destroy (statuswindow); } -static const char * -passphrase_cb (void *opaque, const char *desc, void **r_hd) -{ - struct passphrase_cb_info_s *info = opaque; - GpgmeCtx ctx = info ? info->c : NULL; - const char *pass; - - if (!desc) { - /* FIXME: cleanup by looking at **r_hd */ - return NULL; - } - - gpgmegtk_set_passphrase_grab (prefs_common.passphrase_grab); - debug_print ("%% requesting passphrase for `%s': ", desc ); - pass = gpgmegtk_passphrase_mbox (desc); - if (!pass) { - debug_print ("%% cancel passphrase entry"); - gpgme_cancel (ctx); - } - else - debug_print ("%% sending passphrase"); - - return pass; -} - /* * Copy a gpgme data object to a temporary file and * return this filename @@ -434,7 +403,7 @@ pgp_decrypt (MimeInfo *partinfo, FILE *fp) if (!getenv("GPG_AGENT_INFO")) { info.c = ctx; - gpgme_set_passphrase_cb (ctx, passphrase_cb, &info); + gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } err = gpgme_op_decrypt (ctx, cipher, plain); @@ -442,6 +411,7 @@ pgp_decrypt (MimeInfo *partinfo, FILE *fp) leave: gpgme_data_release (cipher); if (err) { + gpgmegtk_free_passphrase(); debug_print ("decryption failed: %s\n", gpgme_strerror (err)); gpgme_data_release (plain); plain = NULL; @@ -963,7 +933,7 @@ pgp_sign (GpgmeData plain, GSList *key_list) if (!getenv("GPG_AGENT_INFO")) { info.c = ctx; - gpgme_set_passphrase_cb (ctx, passphrase_cb, &info); + gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } gpgme_set_textmode (ctx, 1); gpgme_set_armor (ctx, 1); @@ -983,6 +953,7 @@ pgp_sign (GpgmeData plain, GSList *key_list) leave: if (err) { + gpgmegtk_free_passphrase(); debug_print ("signing failed: %s\n", gpgme_strerror (err)); gpgme_data_release (sig); sig = NULL;