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.8.nr.crypt-autohook diff -r -u mutt-1.5.8.orig/crypt-mod-pgp-classic.c mutt-1.5.8/crypt-mod-pgp-classic.c --- mutt-1.5.8.orig/crypt-mod-pgp-classic.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt-mod-pgp-classic.c Sun Mar 13 13:49:21 2005 @@ -106,6 +106,11 @@ pgp_extract_keys_from_attachment_list (fp, tag, top); } +static int crypt_mod_pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) +{ + return pgp_keys_avail (to, cc, bcc); +} + struct crypt_module_specs crypt_mod_pgp_classic = { APPLICATION_PGP, { @@ -127,6 +132,7 @@ crypt_mod_pgp_invoke_getkeys, crypt_mod_pgp_invoke_import, crypt_mod_pgp_extract_keys_from_attachment_list, + crypt_mod_pgp_keys_avail, NULL, /* smime_getkeys */ NULL, /* smime_verify_sender */ diff -r -u mutt-1.5.8.orig/crypt-mod-pgp-gpgme.c mutt-1.5.8/crypt-mod-pgp-gpgme.c --- mutt-1.5.8.orig/crypt-mod-pgp-gpgme.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt-mod-pgp-gpgme.c Sun Mar 13 13:49:21 2005 @@ -113,6 +113,7 @@ NULL, /* pgp_invoke_getkeys */ NULL, /* pgp_invoke_import */ NULL, /* pgp_extract_keys_from_attachment_list */ + NULL, /* pgp_keys_avail */ NULL, /* smime_getkeys */ NULL, /* smime_verify_sender */ diff -r -u mutt-1.5.8.orig/crypt-mod-smime-classic.c mutt-1.5.8/crypt-mod-smime-classic.c --- mutt-1.5.8.orig/crypt-mod-smime-classic.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt-mod-smime-classic.c Sun Mar 13 13:49:21 2005 @@ -108,6 +108,7 @@ NULL, /* pgp_invoke_getkeys */ NULL, /* pgp_invoke_import */ NULL, /* pgp_extract_keys_from_attachment_list */ + NULL, /* pgp_keys_avail */ crypt_mod_smime_getkeys, crypt_mod_smime_verify_sender, diff -r -u mutt-1.5.8.orig/crypt-mod-smime-gpgme.c mutt-1.5.8/crypt-mod-smime-gpgme.c --- mutt-1.5.8.orig/crypt-mod-smime-gpgme.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt-mod-smime-gpgme.c Sun Mar 13 13:49:21 2005 @@ -106,6 +106,7 @@ NULL, /* pgp_invoke_getkeys */ NULL, /* pgp_invoke_import */ NULL, /* pgp_extract_keys_from_attachment_list */ + NULL, /* pgp_keys_avail */ NULL, /* smime_getkeys */ crypt_mod_smime_verify_sender, diff -r -u mutt-1.5.8.orig/crypt-mod.h mutt-1.5.8/crypt-mod.h --- mutt-1.5.8.orig/crypt-mod.h Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt-mod.h Sun Mar 13 13:49:21 2005 @@ -53,6 +53,7 @@ const char *tempf); typedef void (*crypt_func_pgp_extract_keys_from_attachment_list_t) (FILE *fp, int tag, BODY *top); +typedef int (*crypt_func_pgp_keys_avail_t) (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc); typedef int (*crypt_func_send_menu_t) (HEADER *msg, int *redraw); @@ -94,6 +95,7 @@ crypt_func_pgp_invoke_import_t pgp_invoke_import; crypt_func_pgp_extract_keys_from_attachment_list_t pgp_extract_keys_from_attachment_list; + crypt_func_pgp_keys_avail_t pgp_keys_avail; /* S/MIME specific functions. */ diff -r -u mutt-1.5.8.orig/crypt.c mutt-1.5.8/crypt.c --- mutt-1.5.8.orig/crypt.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/crypt.c Sun Mar 13 13:49:21 2005 @@ -702,6 +702,20 @@ unset_option (OPTDONTHANDLEPGPKEYS); } +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.8.orig/cryptglue.c mutt-1.5.8/cryptglue.c --- mutt-1.5.8.orig/cryptglue.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/cryptglue.c Sun Mar 13 13:49:21 2005 @@ -256,6 +256,12 @@ (CRYPT_MOD_CALL (PGP, pgp_extract_keys_from_attachment_list)) (fp, tag, top); } +int crypt_pgp_keys_avail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) +{ + if (CRYPT_MOD_CALL_CHECK (PGP, pgp_keys_avail)) + return (CRYPT_MOD_CALL (PGP, pgp_keys_avail)) (to, cc, bcc); + else return 0; +} /* diff -r -u mutt-1.5.8.orig/init.h mutt-1.5.8/init.h --- mutt-1.5.8.orig/init.h Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/init.h Sun Mar 13 13:49:21 2005 @@ -1300,6 +1300,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.8.orig/mutt.h mutt-1.5.8/mutt.h --- mutt-1.5.8.orig/mutt.h Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/mutt.h Sun Mar 13 13:49:21 2005 @@ -473,6 +473,9 @@ OPTPGPCHECKEXIT, OPTPGPLONGIDS, OPTPGPAUTODEC, + OPTCRYPTAUTOHOOKENCRYPT, + OPTCRYPTAUTOHOOKSIGN, + OPTCRYPTAUTOHOOKSTRONGONLY, #if 0 OPTPGPENCRYPTSELF, #endif diff -r -u mutt-1.5.8.orig/mutt_crypt.h mutt-1.5.8/mutt_crypt.h --- mutt-1.5.8.orig/mutt_crypt.h Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/mutt_crypt.h Sun Mar 13 13:49:21 2005 @@ -143,6 +143,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); @@ -198,6 +201,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.8.orig/pgp.c mutt-1.5.8/pgp.c --- mutt-1.5.8.orig/pgp.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/pgp.c Sun Mar 13 13:49:21 2005 @@ -1060,6 +1060,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.8.orig/pgp.h mutt-1.5.8/pgp.h --- mutt-1.5.8.orig/pgp.h Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/pgp.h Sun Mar 13 13:49:21 2005 @@ -47,8 +47,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.8.orig/pgpkey.c mutt-1.5.8/pgpkey.c --- mutt-1.5.8.orig/pgpkey.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/pgpkey.c Sun Mar 13 13:49:21 2005 @@ -812,7 +812,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; @@ -830,13 +830,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); @@ -914,6 +916,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)) */) { @@ -941,6 +954,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.8.orig/send.c mutt-1.5.8/send.c --- mutt-1.5.8.orig/send.c Sun Mar 13 13:49:21 2005 +++ mutt-1.5.8/send.c Sun Mar 13 13:49:21 2005 @@ -1324,6 +1324,10 @@ if (!(msg->security & (APPLICATION_SMIME|APPLICATION_PGP))) msg->security = 0; } + + + if (WithCrypto && (option (OPTCRYPTAUTOHOOKSIGN) || option (OPTCRYPTAUTOHOOKENCRYPT))) + crypt_autohook (msg); /* * This hook is even called for postponed messages, and can, e.g., be