written by Nicolas Rachinsky 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 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 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 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