enable storing of GnuPG passphrase
authorPaul Mangan <paul@claws-mail.org>
Sat, 13 Apr 2002 10:21:38 +0000 (10:21 +0000)
committerPaul Mangan <paul@claws-mail.org>
Sat, 13 Apr 2002 10:21:38 +0000 (10:21 +0000)
ChangeLog.claws
configure.in
src/main.c
src/passphrase.c
src/passphrase.h
src/pgptext.c
src/prefs_common.c
src/prefs_common.h
src/rfc2015.c

index e96a29d4e722a76d0e251e95d05c8a29a9d10417..3ae4a6cc6cfaf453e81ea83170cce5587042acb0 100644 (file)
@@ -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 <ravemax@dextrose.com>
+
 2002-04-13 [alfons]    0.7.4claws79
 
        * src/textview.c
index add5cf58be2dc16124556cabe5b18e7679e5d207..d85dd84133e7d48620fc7a636da4da15dcc10da7 100644 (file)
@@ -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
index c27cf00542397fadb4519e34dd9578a072387c58..c74b21ebe7ba22013742aa56c2a6bfa5121973cd 100644 (file)
@@ -47,6 +47,7 @@
 
 #if USE_GPGME
 #  include <gpgme.h>
+#  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);
 
index c36b9ea4a2f0589d11a61d52c48366c1ef6adec9..bf69340f79997200e4d942184e3bbf34f73bb006 100644 (file)
@@ -23,6 +23,7 @@
 #if USE_GPGME
 
 #include <string.h>
+#include <sys/mman.h>
 #include <glib.h>
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdkx.h>  /* GDK_DISPLAY() */
 
 #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 */
index c3c69b70a23b7d4236900d37aaf477a28c3cca97..3f4b2e33d7b764cd4dc1ec44c0cdf3175a33d39a 100644 (file)
 #define GPGMEGTK_PASSPHRASE_H
 
 #include <glib.h>
+#include <gpgme.h>
+
+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 */
index 4ed72ec3f07c7686581deebb94d5abb0b0d66830..dfa7617dc66965ce3d63662563c91305304491ad 100644 (file)
@@ -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;
index 714fed40e14658aa287f94a296f83dd35e0fa614..1c06e38e46a505353be4413860c7d81bf1828ce0 100644 (file)
@@ -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'",
index 72598238be70d0e2eefd690f7e36a5a17cd56ed5..002907ae70aaa07b26823a560b95c0a009d0b1e2 100644 (file)
@@ -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;
index cc177c9177a9565c073cc70b2fb603b248dccd7e..6bb3f7719c2ea6c024820f00d81efcc78535b293 100644 (file)
@@ -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;