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

patch for automatic encryption



Hallo,

I've written a small patch. It should be a (better) replacement for constructs
like this:
source 'gpg --list-keys | perl -e "while(<>){/(\\b|[<(])([^ \\t]+@[^ \\t]+\.[^ 
\t]+)(\\b|[>)])/ and \$a{\$2}=1;}print map qq/send-hook \"~C \$_\" set 
pgp_autoencrypt\n/, keys %a;"|'

The patch introduces 3 new options:

       6.3.128  crypt_autohook_sign

       Type: boolean

       Default: no

       Setting this variable will cause Mutt to sign messages if there is a key 
for
       every recipient. This is done immediately after after executing the 
send-hooks
       (and also only once after getting the initial list of recipients).  Only 
work-
       ing with pgp at the moment.  (Crypto only)

       6.3.129  crypt_autohook_encrypt

       Type: boolean

       Default: no

       Setting this variable will cause Mutt to encrypt messages if there is a 
key for
       every recipient. This is done immediately after after executing the 
send-hooks
       (and also only once after getting the initial list of recipients).  Only 
work-
       ing with pgp at the moment.  (Crypto only)

       The Mutt E-Mail Client                                                   
    91

       6.3.130  crypt_autohook_strongonly

       Type: boolean

       Default: yes

       If this variable is set only 'strong' keys are considered for 
``$crypt_auto-
       hook_encrypt (section 6.3.129  , page 89)'' and ``$crypt_autohook_sign 
(section
       6.3.128  , page 89)'' Only working with pgp at the moment.  (Crypto only)


I like this appoach better than the above snippet for some reasons.

No need to parse gpg output, the existing code from mutt is used.
It should work with any pgp implementation mutt can work with.

It notices keyring changes which happen while mutt is running.

Only strong keys are considered (optional).

It's easier to change with folder- and send-hooks.

If you send a mail to multiple recipients, for some of whom you
have keys and some not, you are not asked for nonexistent keys,
since encryption is not selected.


Feedback is welcome as always.

Nicolas
written by Nicolas Rachinsky <nr@xxxxxxxxxxxx>
http://www.rachinsky.de

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation;  version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

--- mutt-unstable/PATCHES       2002-11-11 13:43:09.000000000 -0800
+++ PATCHES 2002-12-06 23:10:13.000000000 -0800
@@ -0,0 +1 @@
+patch-1.5.6.nr.crypt-autohook-ALPHA
diff -r -u mutt-1.5.6.orig/crypt.c mutt-1.5.6/crypt.c
--- mutt-1.5.6.orig/crypt.c     Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/crypt.c  Tue Oct 26 22:41:28 2004
@@ -751,6 +751,20 @@
 }
 
 
+void crypt_autohook (HEADER *msg)
+{
+  if (!(WithCrypto & APPLICATION_PGP))
+    return;
+
+  if (msg->security & APPLICATION_PGP || !msg->security)
+    if (crypt_pgp_keys_avail (msg->env->to, msg->env->cc, msg->env->bcc))
+    {
+      if (option(OPTCRYPTAUTOHOOKSIGN))
+       msg->security |= SIGN | APPLICATION_PGP;
+      if (option(OPTCRYPTAUTOHOOKENCRYPT))
+       msg->security |= ENCRYPT | APPLICATION_PGP;
+    }
+}
 
 int crypt_get_keys (HEADER *msg, char **keylist)
 {
diff -r -u mutt-1.5.6.orig/cryptglue.c mutt-1.5.6/cryptglue.c
--- mutt-1.5.6.orig/cryptglue.c Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/cryptglue.c      Tue Oct 26 22:41:28 2004
@@ -37,6 +37,7 @@
 #undef BFNC_PGP_FREE_KEY
 #undef BFNC_PGP_MAKE_KEY_ATTACHMENT 
 #undef BFNC_PGP_FINDKEYS
+#undef BFNC_PGP_KEYS_AVAIL
 #undef BFNC_PGP_SIGN_MESSAGE
 #undef BFNC_PGP_ENCRYPT_MESSAGE
 #undef BFNC_PGP_INVOKE_IMPORT
@@ -71,6 +72,7 @@
 # define BFNC_PGP_FREE_KEY                pgp_free_key
 # define BFNC_PGP_MAKE_KEY_ATTACHMENT     pgp_make_key_attachment
 # define BFNC_PGP_FINDKEYS                pgp_findKeys
+# define BFNC_PGP_KEYS_AVAIL              pgp_keys_avail
 # define BFNC_PGP_SIGN_MESSAGE            pgp_sign_message
 # define BFNC_PGP_ENCRYPT_MESSAGE         pgp_encrypt_message
 # define BFNC_PGP_INVOKE_IMPORT           pgp_invoke_import
@@ -229,6 +231,15 @@
   return BFNC_PGP_MAKE_KEY_ATTACHMENT (tempf);
 #else
   return NULL; /* error */ 
+#endif
+}
+
+int crypt_pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+{
+#ifdef BFNC_PGP_KEYS_AVAIL
+  return BFNC_PGP_KEYS_AVAIL (to, cc, bcc);
+#else
+  return 0;
 #endif
 }
 
diff -r -u mutt-1.5.6.orig/init.h mutt-1.5.6/init.h
--- mutt-1.5.6.orig/init.h      Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/init.h   Tue Oct 26 22:45:21 2004
@@ -1241,6 +1241,34 @@
   ** settings can be overridden by use of the \fIsmime-menu\fP.
   ** (Crypto only)
   */
+  { "crypt_autohook_sign",     DT_BOOL, R_NONE, OPTCRYPTAUTOHOOKSIGN, 0 },
+  /*
+  ** .pp
+  ** Setting this variable will cause Mutt to sign messages if
+  ** there is a key for every recipient. This is done immediately after
+  ** after executing the send-hooks (and also only once after getting the
+  ** initial list of recipients).
+  ** Only working with pgp at the moment.
+  ** (Crypto only)
+  */
+  { "crypt_autohook_encrypt",  DT_BOOL, R_NONE, OPTCRYPTAUTOHOOKENCRYPT, 0 },
+  /*
+  ** .pp
+  ** Setting this variable will cause Mutt to encrypt messages if
+  ** there is a key for every recipient. This is done immediately after
+  ** after executing the send-hooks (and also only once after getting the
+  ** initial list of recipients).
+  ** Only working with pgp at the moment.
+  ** (Crypto only)
+  */
+  { "crypt_autohook_strongonly",       DT_BOOL, R_NONE, 
OPTCRYPTAUTOHOOKSTRONGONLY, 1 },
+  /*
+  ** .pp
+  ** If this variable is set only 'strong' keys are considered for
+  ** ``$$crypt_autohook_encrypt'' and ``$$crypt_autohook_sign''
+  ** Only working with pgp at the moment.
+  ** (Crypto only)
+  */
   { "pgp_ignore_subkeys", DT_BOOL, R_NONE, OPTPGPIGNORESUB, 1},
   /*
   ** .pp
diff -r -u mutt-1.5.6.orig/mutt.h mutt-1.5.6/mutt.h
--- mutt-1.5.6.orig/mutt.h      Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/mutt.h   Tue Oct 26 22:41:29 2004
@@ -456,6 +456,9 @@
   OPTPGPCHECKEXIT,
   OPTPGPLONGIDS,
   OPTPGPAUTOTRAD,
+  OPTCRYPTAUTOHOOKENCRYPT,
+  OPTCRYPTAUTOHOOKSIGN,
+  OPTCRYPTAUTOHOOKSTRONGONLY,
 #if 0
   OPTPGPENCRYPTSELF,
 #endif
diff -r -u mutt-1.5.6.orig/mutt_crypt.h mutt-1.5.6/mutt_crypt.h
--- mutt-1.5.6.orig/mutt_crypt.h        Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/mutt_crypt.h     Tue Oct 26 22:41:29 2004
@@ -139,6 +139,9 @@
    Return the list of keys in KEYLIST. */
 int crypt_get_keys (HEADER *msg, char **keylist);
 
+/* enable encryption if there are enough keys */
+void crypt_autohook (HEADER *msg);
+
 /* Forget a passphrase and display a message. */
 void crypt_forget_passphrase (void);
 
@@ -191,6 +194,10 @@
 /* This routine attempts to find the keyids of the recipients of a
    message.  It returns NULL if any of the keys can not be found.  */
 char *crypt_pgp_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
+
+
+/* are there enough keys? */
+int crypt_pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
 /* Create a new body with a PGP signed message from A. */
 BODY *crypt_pgp_sign_message (BODY *a);
diff -r -u mutt-1.5.6.orig/pgp.c mutt-1.5.6/pgp.c
--- mutt-1.5.6.orig/pgp.c       Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/pgp.c    Tue Oct 26 22:41:29 2004
@@ -1008,6 +1008,52 @@
   return 1;
 }
 
+int pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+{
+  ADDRESS *tmp = NULL;
+  ADDRESS **last = &tmp;
+  ADDRESS *p;
+  int i;
+
+  const char *fqdn = mutt_fqdn (1);
+  
+  for (i = 0; i < 3; i++) 
+  {
+    switch (i)
+    {
+      case 0: p = to; break;
+      case 1: p = cc; break;
+      case 2: p = bcc; break;
+      default: abort ();
+    }
+    
+    *last = rfc822_cpy_adr (p);
+    while (*last)
+      last = &((*last)->next);
+  }
+
+  if (fqdn)
+    rfc822_qualify (tmp, fqdn);
+
+  tmp = mutt_remove_duplicates (tmp);
+  
+  for (p = tmp; p ; p = p->next)
+  {
+    if (mutt_crypt_hook (p) != NULL)
+    {
+      continue;
+    }
+
+    if (!pgp_checkkeybyaddr (p, KEYFLAG_CANENCRYPT, PGP_PUBRING))
+    {
+      rfc822_free_address (&tmp);
+      return 0;
+    }
+  }
+  rfc822_free_address (&tmp);
+  return 1;
+}
+
 /* This routine attempts to find the keyids of the recipients of a message.
  * It returns NULL if any of the keys can not be found.
  */
diff -r -u mutt-1.5.6.orig/pgp.h mutt-1.5.6/pgp.h
--- mutt-1.5.6.orig/pgp.h       Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/pgp.h    Tue Oct 26 22:41:29 2004
@@ -48,8 +48,10 @@
 pgp_key_t pgp_ask_for_key (char *, char *, short, pgp_ring_t);
 pgp_key_t pgp_get_candidates (pgp_ring_t, LIST *);
 pgp_key_t pgp_getkeybyaddr (ADDRESS *, short, pgp_ring_t);
+int pgp_checkkeybyaddr (ADDRESS *, short, pgp_ring_t);
 pgp_key_t pgp_getkeybystr (char *, short, pgp_ring_t);
 
+int pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
 void pgp_forget_passphrase (void);
diff -r -u mutt-1.5.6.orig/pgpkey.c mutt-1.5.6/pgpkey.c
--- mutt-1.5.6.orig/pgpkey.c    Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/pgpkey.c Tue Oct 26 22:41:29 2004
@@ -808,7 +808,7 @@
   return NULL;
 }
 
-pgp_key_t pgp_getkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t keyring)
+static pgp_key_t _pgp_getkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t 
keyring, int check_only)
 {
   ADDRESS *r, *p;
   LIST *hints = NULL;
@@ -826,13 +826,15 @@
   pgp_key_t matches = NULL;
   pgp_key_t *last = &matches;
   pgp_uid_t *q;
+  static struct pgp_keyinfo dummy; /*dummy to return a 'valid' pointer when 
called with check_only*/
   
   if (a && a->mailbox)
     hints = pgp_add_string_to_hints (hints, a->mailbox);
   if (a && a->personal)
     hints = pgp_add_string_to_hints (hints, a->personal);
 
-  mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox);
+  if (!check_only)
+    mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox);
   keys = pgp_get_candidates (keyring, hints);
 
   mutt_free_list (&hints);
@@ -910,6 +912,17 @@
   
   if (matches)
   {
+    if (check_only && (the_valid_key || !option (OPTCRYPTAUTOHOOKSTRONGONLY)))
+    {
+      pgp_free_key (&matches);
+      return &dummy;
+    }
+    if (check_only)
+    {
+      pgp_free_key (&matches);
+      return NULL;
+    }
+
     if (the_valid_key && !multi /* && !weak 
        && !(invalid && option (OPTPGPSHOWUNUSABLE)) */)
     {
@@ -937,6 +950,21 @@
 
   return NULL;
 }
+
+int pgp_checkkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t keyring)
+{
+       if(_pgp_getkeybyaddr(a, abilities, keyring, 1))
+               return 1;
+       else
+               return 0;
+}
+
+
+pgp_key_t pgp_getkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t keyring)
+{
+       return _pgp_getkeybyaddr(a, abilities, keyring, 0);
+}
+
 
 pgp_key_t pgp_getkeybystr (char *p, short abilities, pgp_ring_t keyring)
 {
diff -r -u mutt-1.5.6.orig/send.c mutt-1.5.6/send.c
--- mutt-1.5.6.orig/send.c      Tue Oct 26 22:41:28 2004
+++ mutt-1.5.6/send.c   Tue Oct 26 22:41:29 2004
@@ -1210,6 +1210,7 @@
     
     mutt_message_hook (NULL, msg, M_SENDHOOK);
 
+
     /*
      * Unset the replied flag from the message we are composing since it is
      * no longer required.  This is done here because the FCC'd copy of
@@ -1299,6 +1300,10 @@
     if (!(msg->security & (APPLICATION_SMIME|APPLICATION_PGP)))
       msg->security = 0;
   }
+
+  if (WithCrypto && (option (OPTCRYPTAUTOHOOKSIGN) || option 
(OPTCRYPTAUTOHOOKENCRYPT)))
+    crypt_autohook (msg);
+
   /* wait until now to set the real name portion of our return address so
      that $realname can be set in a send-hook */
   if (msg->env->from && !msg->env->from->personal