sync with 0.8.1cvs12
[claws.git] / src / passphrase.c
index 5b70cf5..f88d1b9 100644 (file)
 #  include <config.h>
 #endif
 
+#if USE_GPGME
+
 #include <string.h>
+#include <sys/types.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 *last_pass = NULL;
 
 static void passphrase_ok_cb(GtkWidget *widget, gpointer data);
 static void passphrase_cancel_cb(GtkWidget *widget, gpointer data);
@@ -50,6 +57,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
@@ -58,8 +68,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;
@@ -82,12 +92,15 @@ gpgmegtk_passphrase_mbox (const gchar *desc)
                        GTK_SIGNAL_FUNC(passphrase_deleted), NULL);
     gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
                        GTK_SIGNAL_FUNC(passphrase_key_pressed), NULL);
+    MANAGE_WINDOW_SIGNALS_CONNECT(window);
+    manage_window_set_transient(GTK_WINDOW(window));
 
     vbox = gtk_vbox_new(FALSE, 8);
     gtk_container_add(GTK_CONTAINER(window), vbox);
 
     if (desc) {
-        GtkWidget *label = create_description (desc);
+        GtkWidget *label;
+        label = create_description (desc);
         gtk_box_pack_start (GTK_BOX(vbox), label, TRUE, TRUE, 0);
     }
 
@@ -167,6 +180,8 @@ gpgmegtk_passphrase_mbox (const gchar *desc)
         gdk_flush();
     }
 
+    manage_window_focus_out(window, NULL, NULL);
+
     if (pass_ack) {
         the_passphrase = gtk_entry_get_text(GTK_ENTRY(pass_entry));
         if (the_passphrase) /* Hmmm: Do we really need this? */
@@ -222,7 +237,7 @@ linelen (const gchar *s)
 static GtkWidget *
 create_description (const gchar *desc)
 {
-    const gchar *cmd=NULL, *uid=NULL, *info=NULL;
+    const gchar *cmd = NULL, *uid = NULL, *info = NULL;
     gchar *buf;
     GtkWidget *label;
 
@@ -251,3 +266,62 @@ create_description (const gchar *desc)
 
     return label;
 }
+
+static int free_passphrase(gpointer _unused)
+{
+    if (last_pass != NULL) {
+        munlock(last_pass, strlen(last_pass));
+        g_free(last_pass);
+        last_pass = NULL;
+        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 && last_pass != NULL &&
+        strncmp(desc, "TRY_AGAIN", 9) != 0)
+        return g_strdup(last_pass);
+
+    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) {
+            last_pass = g_strdup(pass);
+            if (mlock(last_pass, strlen(last_pass)) == -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 */