+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
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
#if USE_GPGME
# include <gpgme.h>
+# include "passphrase.h"
#endif
#include "intl.h"
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);
#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);
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
grab_all = yes;
}
-gchar *
-gpgmegtk_passphrase_mbox (const gchar *desc)
+static gchar*
+passphrase_mbox (const gchar *desc)
{
gchar *the_passphrase = NULL;
GtkWidget *vbox;
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 */
#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 */
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)
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)
{
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);
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;
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;
&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,
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;
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"));
= 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;
"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'",
/* 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;
NULL
};
-
-struct passphrase_cb_info_s {
- GpgmeCtx c;
- int did_it;
-};
-
static char *create_boundary (void);
#if 0
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
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);
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;
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);
leave:
if (err) {
+ gpgmegtk_free_passphrase();
debug_print ("signing failed: %s\n", gpgme_strerror (err));
gpgme_data_release (sig);
sig = NULL;