Attached is a patch to an an option for opportunistic PGP encryption (mutt will automatically encrypt email to anyone in your keyring for which it has the required encryption keys). This functionality is similar to that of mozilla's enigmail package. Quick start: add "set pgp_opportunistic_encrypt=yes" to ~/.muttrc and send a message to anyone for whom you have a key. I also tried to think of a nice interface to allow the following behavior (but couldn't come up with one): * Globally default to opportunistic encryption unless either the user overrides the default manually through the pgp menu (this much is done) or the recipient is on a list of "do not opportunistically encrypt" people. The problem I run into is that the way mutt's interface operates, the global option is used to set the initial value of the menu option controlling opportunistic encryption (this is the same way that pgp_autoencrypt works). When it comes time to run the send-hook and change the pgp_opportunistic_encrypt setting, the user's menu choice (which should really override both the per-message send-hook setting and the global setting) cannot be distinguished from the global default. E.g. I may want to opportunistically encrypt messages by default, except not by default to Alice (who keeps her PGP key only at work), and I'd like to be able to *sometimes* manually override even that setting via the pgp menu and encrypt, if I know that she's recieving this message at work. Once I accept the global default as the user's default menu choice, I lose the ability to distinguish between the states "global default is opportunistic encryption, user wants to override any local address settings and opportunistically encrypt" and "global default is opportunistic encryption, user wants to retain default global setting *unless* local address setting overrides global settings". The only way I see to pull this off is to introduce a tri-state option (force don't opportunistically encrypt, force opportunistically encrypt, use default), which seems excessively complicated. The reason pgp_autoencrypt doesn't suffer from the above problem is that people just don't *use* pgp_autoencrypt globally, and the reason that pgp_autosign doesn't suffer from the above problem is that nobody really cares if a message is unnecessarily signed. It's a bit simpler than it sounds. :-) In any event, feedback is welcome. And thank you, mutt coders, for a very nice piece of software. -- Best of luck, Mark Schreiber
diff -u mutt-1.4.2.1/compose.c mutt-1.4.2.1-oppencrypt/compose.c --- mutt-1.4.2.1/compose.c 2002-07-24 04:41:29.000000000 -0400 +++ mutt-1.4.2.1-oppencrypt/compose.c 2004-06-13 20:12:36.216828531 -0400 @@ -113,8 +113,12 @@ addstr (_("Sign, Encrypt")); else if (pgp & PGPENCRYPT) addstr (_("Encrypt")); + else if ((pgp & PGPSIGN) && (pgp & PGPOPPORTUNISTICENCRYPT)) + addstr (_("Sign, Opportunistic Encrypt")); else if (pgp & PGPSIGN) addstr (_("Sign")); + else if (pgp & PGPOPPORTUNISTICENCRYPT) + addstr (_("Opportunistic Encrypt")); else addstr (_("Clear")); clrtoeol (); @@ -130,8 +134,8 @@ pgp_key_t *p; char input_signas[SHORT_STRING]; - switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, or (f)orget it? "), - _("esabf"))) + switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, (o)pportunistic encrypt, or (f)orget it? "), + _("esabof"))) { case 1: /* (e)ncrypt */ bits |= PGPENCRYPT; @@ -164,10 +168,14 @@ break; case 4: /* (b)oth */ - bits = PGPENCRYPT | PGPSIGN; + bits |= PGPENCRYPT | PGPSIGN; break; - case 5: /* (f)orget it */ + case 5: /* (o)pportunstic encrypt */ + bits |= PGPOPPORTUNISTICENCRYPT; + break; + + case 6: /* (f)orget it */ bits = 0; break; } Common subdirectories: mutt-1.4.2.1/contrib and mutt-1.4.2.1-oppencrypt/contrib Only in mutt-1.4.2.1-oppencrypt: cscope.out Common subdirectories: mutt-1.4.2.1/doc and mutt-1.4.2.1-oppencrypt/doc Common subdirectories: mutt-1.4.2.1/imap and mutt-1.4.2.1-oppencrypt/imap diff -u mutt-1.4.2.1/init.h mutt-1.4.2.1-oppencrypt/init.h --- mutt-1.4.2.1/init.h 2002-07-24 04:41:29.000000000 -0400 +++ mutt-1.4.2.1-oppencrypt/init.h 2004-06-13 19:34:05.709496391 -0400 @@ -1186,6 +1186,13 @@ ** \fIpgp-menu\fP, when encryption is not required or signing is ** requested as well. */ + { "pgp_opportunistic_encrypt", DT_BOOL, R_NONE, OPTPGPOPPORTUNISTICENCRYPT, 0 }, + /* + ** .pp Setting this variable will cause Mutt to attempt to PGP/MIME + ** encrypt outgoing messages if it can find all necessary encryption + ** keys in the keychain being used. + */ + { "pgp_ignore_subkeys", DT_BOOL, R_NONE, OPTPGPIGNORESUB, 1}, /* ** .pp Common subdirectories: mutt-1.4.2.1/intl and mutt-1.4.2.1-oppencrypt/intl Common subdirectories: mutt-1.4.2.1/m4 and mutt-1.4.2.1-oppencrypt/m4 diff -u mutt-1.4.2.1/mutt.h mutt-1.4.2.1-oppencrypt/mutt.h --- mutt-1.4.2.1/mutt.h 2002-07-24 05:46:58.000000000 -0400 +++ mutt-1.4.2.1-oppencrypt/mutt.h 2004-06-13 20:07:57.602019486 -0400 @@ -424,6 +424,7 @@ #ifdef HAVE_PGP OPTPGPAUTOSIGN, OPTPGPAUTOENCRYPT, + OPTPGPOPPORTUNISTICENCRYPT, OPTPGPIGNORESUB, OPTPGPLONGIDS, OPTPGPREPLYENCRYPT, @@ -466,6 +467,7 @@ #ifdef HAVE_PGP OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */ OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */ + OPTPGPSILENT, /* (pseudo) do not interact with the user */ #endif @@ -621,7 +623,7 @@ typedef struct header { #ifdef HAVE_PGP - unsigned int pgp : 4; + unsigned int pgp : 5; #endif unsigned int mime : 1; /* has a Mime-Version header? */ diff -u mutt-1.4.2.1/pgp.c mutt-1.4.2.1-oppencrypt/pgp.c --- mutt-1.4.2.1/pgp.c 2002-01-09 10:39:28.000000000 -0500 +++ mutt-1.4.2.1-oppencrypt/pgp.c 2004-06-13 17:37:06.009347518 -0400 @@ -1366,7 +1366,8 @@ { int r; snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox); - if ((r = mutt_yesorno (buf, M_YES)) == M_YES) + if (option(OPTPGPSILENT) || + ((r = mutt_yesorno (buf, M_YES)) == M_YES)) { /* check for e-mail address */ if ((t = strchr (keyID, '@')) && @@ -1394,8 +1395,8 @@ { snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); - if ((key = pgp_ask_for_key (buf, q->mailbox, - KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL) + if (option(OPTPGPSILENT) || ((key = pgp_ask_for_key (buf, q->mailbox, + KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)) { safe_free ((void **)&keylist); rfc822_free_address (&tmp); @@ -1669,7 +1670,24 @@ return b; } +/* returns 0 if we have the appropriate keys for encrypting the message */ +int pgp_test_keys(HEADER *msg) +{ + char * pgpkeylist = NULL; + int return_code = -1; + + set_option (OPTPGPCHECKTRUST); + set_option (OPTPGPSILENT); + pgpkeylist = pgp_findKeys(msg->env->to, msg->env->cc, msg->env->bcc); + if (pgpkeylist) + { + FREE(&pgpkeylist); + return_code = 0; + } + unset_option (OPTPGPSILENT); + return return_code; +} int pgp_get_keys (HEADER *msg, char **pgpkeylist) { diff -u mutt-1.4.2.1/pgp.h mutt-1.4.2.1-oppencrypt/pgp.h --- mutt-1.4.2.1/pgp.h 2001-03-28 09:59:52.000000000 -0500 +++ mutt-1.4.2.1-oppencrypt/pgp.h 2004-06-13 16:08:49.000000000 -0400 @@ -62,6 +62,7 @@ int mutt_parse_pgp_hdr (char *, int); int pgp_decrypt_mime (FILE *, FILE **, BODY *, BODY **); int pgp_get_keys (HEADER *, char **); +int pgp_test_keys (HEADER *); int pgp_protect (HEADER *, char *); int pgp_query (BODY *); /* int pgp_string_matches_hint (const char *s, LIST * hints); */ diff -u mutt-1.4.2.1/pgpkey.c mutt-1.4.2.1-oppencrypt/pgpkey.c --- mutt-1.4.2.1/pgpkey.c 2002-01-15 04:04:28.000000000 -0500 +++ mutt-1.4.2.1-oppencrypt/pgpkey.c 2004-06-13 15:53:14.747908917 -0400 @@ -622,7 +622,7 @@ snprintf (buff, sizeof (buff), _("%s Do you really want to use the key?"), _(s)); - if (mutt_yesorno (buff, 0) != 1) + if (option(OPTPGPSILENT) || (mutt_yesorno (buff, 0) != 1)) { mutt_clear_error (); break; diff -u mutt-1.4.2.1/pgplib.h mutt-1.4.2.1-oppencrypt/pgplib.h --- mutt-1.4.2.1/pgplib.h 2001-06-26 06:25:39.000000000 -0400 +++ mutt-1.4.2.1-oppencrypt/pgplib.h 2004-06-13 18:38:29.879832106 -0400 @@ -23,6 +23,7 @@ #define PGPSIGN (1 << 1) #define PGPKEY (1 << 2) #define PGPGOODSIGN (1 << 3) +#define PGPOPPORTUNISTICENCRYPT (1 << 4) #define KEYFLAG_CANSIGN (1 << 0) #define KEYFLAG_CANENCRYPT (1 << 1) Common subdirectories: mutt-1.4.2.1/po and mutt-1.4.2.1-oppencrypt/po diff -u mutt-1.4.2.1/send.c mutt-1.4.2.1-oppencrypt/send.c --- mutt-1.4.2.1/send.c 2002-01-30 17:50:59.000000000 -0500 +++ mutt-1.4.2.1-oppencrypt/send.c 2004-06-13 20:05:55.175740951 -0400 @@ -1251,6 +1251,11 @@ msg->pgp |= PGPSIGN; if (option (OPTPGPAUTOENCRYPT)) msg->pgp |= PGPENCRYPT; + if (option (OPTPGPOPPORTUNISTICENCRYPT)) + { + int i = PGPOPPORTUNISTICENCRYPT; + msg->pgp |= i; + }; msg->pgp |= set_pgp_flags (cur, ctx); } @@ -1415,6 +1420,13 @@ encode_descriptions (msg->content, 1); #ifdef HAVE_PGP + if ((msg->pgp & PGPOPPORTUNISTICENCRYPT) && !(msg->pgp & PGPENCRYPT)) + { + if (pgp_test_keys (msg) != -1) + msg->pgp |= PGPENCRYPT; + } + + if (msg->pgp) { /* save the decrypted attachments */
Attachment:
pgpxGBSCPOiDr.pgp
Description: PGP signature