<<< Date Index >>>     <<< Thread Index >>>

[PATCH] Memory locking for PGP passphrases



Here is a patch to enable memory locking for PGP passphrases.  The
same trick can be used for other passphrases, but for now this is just
for classic PGP.

I have somewhat mixed feelings about how useful memory locking really
is, but this patch is fairly harmless: the worst thing that can happen
is that the memory won't be locked, which is where we are now.

David
Index: PATCHES
===================================================================
RCS file: /home/roessler/cvs/mutt/PATCHES,v
retrieving revision 3.6
diff -u -r3.6 PATCHES
--- PATCHES     9 Dec 2002 17:44:54 -0000       3.6
+++ PATCHES     27 Sep 2006 19:34:55 -0000
@@ -0,0 +1 @@
+patch-1.5.13.dms.mlock.1
Index: configure.in
===================================================================
RCS file: /home/roessler/cvs/mutt/configure.in,v
retrieving revision 3.56
diff -u -r3.56 configure.in
--- configure.in        1 Sep 2006 19:26:39 -0000       3.56
+++ configure.in        27 Sep 2006 19:34:56 -0000
@@ -1115,6 +1115,21 @@
        MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS utf8.o wcwidth.o"
 fi
 
+AC_ARG_ENABLE(mlock,AC_HELP_STRING([--disable-mlock],[Do not try to lock 
passphrases into memory]),mlock=$enableval,mlock=yes)
+
+if test x"$mlock" == xyes ; then
+        AC_CACHE_CHECK([for memory locking], mutt_cv_mlock, mutt_cv_mlock=no
+                AC_TRY_LINK([
+#include <sys/mman.h>
+#include <unistd.h>
+],[long ps=sysconf(_SC_PAGESIZE); mlock(0,ps);],mutt_cv_mlock=yes))
+
+   if test x$mutt_cv_mlock = xyes; then
+           AC_DEFINE(HAVE_MLOCK,1,
+               [Define if mlock() can be used to lock memory.])
+   fi
+fi
+
 AC_CACHE_CHECK([for nl_langinfo and CODESET], mutt_cv_langinfo_codeset,
   [AC_TRY_LINK([#include <langinfo.h>],
     [char* cs = nl_langinfo(CODESET);],
Index: init.c
===================================================================
RCS file: /home/roessler/cvs/mutt/init.c,v
retrieving revision 3.57
diff -u -r3.57 init.c
--- init.c      5 Jul 2006 00:31:38 -0000       3.57
+++ init.c      27 Sep 2006 19:34:57 -0000
@@ -2873,6 +2873,10 @@
   Editor = safe_strdup (p);
   Visual = safe_strdup (p);
 
+#ifdef CRYPT_BACKEND_CLASSIC_PGP
+  pgp_init_passphrase();
+#endif
+
   if ((p = getenv ("REPLYTO")) != NULL)
   {
     BUFFER buf, token;
Index: main.c
===================================================================
RCS file: /home/roessler/cvs/mutt/main.c,v
retrieving revision 3.36
diff -u -r3.36 main.c
--- main.c      11 Jul 2006 23:38:30 -0000      3.36
+++ main.c      27 Sep 2006 19:34:57 -0000
@@ -450,6 +450,13 @@
        "-USE_HCACHE  "
 #endif
 
+       "\n"
+
+#if HAVE_MLOCK
+       "+HAVE_MLOCK  "
+#else
+       "-HAVE_MLOCK  "
+#endif
        );
 
 #ifdef ISPELL
Index: pgp.c
===================================================================
RCS file: /home/roessler/cvs/mutt/pgp.c,v
retrieving revision 3.61
diff -u -r3.61 pgp.c
--- pgp.c       22 Nov 2005 12:31:58 -0000      3.61
+++ pgp.c       27 Sep 2006 19:34:58 -0000
@@ -56,18 +56,55 @@
 # include <sys/resource.h>
 #endif
 
+#ifdef HAVE_MLOCK
+#include <sys/mman.h>
+#endif
+
 #ifdef CRYPT_BACKEND_CLASSIC_PGP
 
 #include "mutt_crypt.h"
 #include "mutt_menu.h"
 
 
-char PgpPass[LONG_STRING];
-time_t PgpExptime = 0; /* when does the cached passphrase expire? */
+static char *PgpPass = NULL;
+static size_t PgpPassLen = 0;
+static time_t PgpExptime = 0; /* when does the cached passphrase expire? */
+
+void pgp_init_passphrase(void)
+{
+#ifdef HAVE_MLOCK
+  if(!PgpPass)
+    {
+      long ps=sysconf(_SC_PAGESIZE);
+      /* We ask for the page size + LONG_STRING to guarantee that we
+        have enough space to find a page size boundary for mlock() */
+      if(ps>0 && ps>=LONG_STRING)
+       {
+         char *temp=safe_malloc(ps+LONG_STRING);
+         int err;
+
+         PgpPass=(char *)((((unsigned long)temp+ps-1)/ps)*ps);
+         PgpPassLen=ps+LONG_STRING-(PgpPass-temp);
+
+         err=mlock(PgpPass,PgpPassLen);
+         if(err==-1)
+           dprint (2, (debugfile,
+                       "pgp_init_passphrase: unable to lock memory: %s\n",
+                       strerror(errno)));
+       }
+    }
+#endif
+
+  if(!PgpPass)
+    {
+      PgpPass=safe_malloc(LONG_STRING);
+      PgpPassLen=LONG_STRING;
+    }
+}
 
 void pgp_void_passphrase (void)
 {
-  memset (PgpPass, 0, sizeof (PgpPass));
+  memset (PgpPass, 0, PgpPassLen);
   PgpExptime = 0;
 }
 
@@ -87,7 +124,7 @@
   
   pgp_void_passphrase ();
 
-  if (mutt_get_password (_("Enter PGP passphrase:"), PgpPass, sizeof 
(PgpPass)) == 0)
+  if (mutt_get_password (_("Enter PGP passphrase:"), PgpPass, PgpPassLen) == 0)
     {
       PgpExptime = time (NULL) + PgpTimeout;
       return (1);
Index: pgp.h
===================================================================
RCS file: /home/roessler/cvs/mutt/pgp.h,v
retrieving revision 3.9
diff -u -r3.9 pgp.h
--- pgp.h       17 Sep 2005 20:46:10 -0000      3.9
+++ pgp.h       27 Sep 2006 19:34:58 -0000
@@ -51,6 +51,7 @@
 
 char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
+void pgp_init_passphrase(void);
 void pgp_forget_passphrase (void);
 int pgp_application_pgp_handler (BODY *, STATE *);
 int pgp_encrypted_handler (BODY *, STATE *);