--- mutt-1.2.5/hook.c Fri Jan 11 08:32:58 2002 +++ mutt-1.2.5/hook.c Fri Jan 11 08:54:49 2002 @@ -115,7 +115,11 @@ ptr->rx.not == not && !mutt_strcmp (pattern.data, ptr->rx.pattern)) { +#ifdef M_PGPHOOK + if (data & (M_FOLDERHOOK | M_SENDHOOK | M_PGPHOOK)) +#else if (data & (M_FOLDERHOOK | M_SENDHOOK)) +#endif { /* folder-hook and send-hook allow multiple commands with the same pattern, so if we've already seen this pattern/command pair, just @@ -411,8 +415,24 @@ } #ifdef HAVE_PGP -char *mutt_pgp_hook (ADDRESS *adr) +LIST *mutt_pgp_hook (ADDRESS *adr) { - return _mutt_string_hook (adr->mailbox, M_PGPHOOK); + HOOK *hook; + LIST *key_list = NULL; + + if (!adr && !adr->mailbox) + return (NULL); + + for (hook = Hooks; hook; hook = hook->next) + { + if (!hook->command) + continue; + if (!(hook->type & M_PGPHOOK)) + continue; + + if ((regexec (hook->rx.rx, adr->mailbox, 0, NULL, 0) == 0) ^ hook->rx.not) + key_list = mutt_add_list (key_list, hook->command); + } + return (key_list); } #endif /* HAVE_PGP */ --- mutt-1.2.5/init.h Fri Jan 11 08:32:58 2002 +++ mutt-1.2.5/init.h Fri Jan 11 08:54:49 2002 @@ -1066,6 +1066,14 @@ #ifdef HAVE_PGP + { "pgp_autoselectkey", DT_BOOL, R_NONE, OPTPGPAUTOSELECT, 0 }, + /* + ** .pp + ** If set, then a list of keys is not presented for selection when only + ** one matching key is available. This may be useful in conjunction with + ** the \fIpgp-hook\fP command (with ``$$pgp_confirmhook'' set) and the + ** ``$$pgp_ignore_subkeys'' variable. + */ { "pgp_autosign", DT_BOOL, R_NONE, OPTPGPAUTOSIGN, 0 }, /* ** .pp @@ -1082,6 +1090,14 @@ ** to the \fIsend-hook\fP command. It can be overridden by use of the ** \fIpgp-menu\fP, when encryption is not required or signing is ** requested as well. + */ + { "pgp_confirmhook", DT_BOOL, R_NONE, OPTPGPCONFIRMHOOK, 1 }, + /* + ** .pp + ** If set, then you will be prompted for confirmation of keys when using + ** the \fIpgp-hook\fP command. If unset, no such confirmation prompt will + ** be presented. This is generally considered unsafe, especially where + ** typos are concerned. */ { "pgp_entry_format", DT_STR, R_NONE, UL &PgpEntryFormat, UL "%4n %t%f %4l/0x%k %-4a %2c %u" }, /* --- mutt-1.2.5/mutt.h Fri Jan 11 08:32:59 2002 +++ mutt-1.2.5/mutt.h Fri Jan 11 08:54:49 2002 @@ -399,6 +399,8 @@ */ #ifdef HAVE_PGP + OPTPGPAUTOSELECT, + OPTPGPCONFIRMHOOK, OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */ OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */ #endif --- mutt-1.2.5/pgp.c Fri Jan 11 08:32:58 2002 +++ mutt-1.2.5/pgp.c Fri Jan 11 08:54:49 2002 @@ -1154,6 +1154,8 @@ char *keyID, *keylist = NULL, *t; size_t keylist_size = 0; size_t keylist_used = 0; + LIST *hook_list = NULL; + LIST *hook = NULL; ADDRESS *tmp = NULL, *addr = NULL; ADDRESS **last = &tmp; ADDRESS *p, *q; @@ -1187,62 +1189,85 @@ char buf[LONG_STRING]; q = p; - k_info = NULL; - if ((keyID = mutt_pgp_hook (p)) != NULL) + /* + * grab the list of matching hooks (matching on recipient address) + * process each entry singly so that auto key selection still works + */ + hook_list = mutt_pgp_hook (p); + hook = hook_list; + while (1) { int r; - snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox); - if ((r = mutt_yesorno (buf, M_YES)) == M_YES) + + k_info = NULL; + + if (hook) { - /* check for e-mail address */ - if ((t = strchr (keyID, '@')) && - (addr = rfc822_parse_adrlist (NULL, keyID))) + keyID = (char *)hook->data; + snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox); + if (!option(OPTPGPCONFIRMHOOK) || (r = mutt_yesorno (buf, M_YES)) == M_YES) { - if (fqdn) rfc822_qualify (addr, fqdn); - q = addr; + /* check for e-mail address */ + if ((t = strchr (keyID, '@')) && + (addr = rfc822_parse_adrlist (NULL, keyID))) + { + if (fqdn) rfc822_qualify (addr, fqdn); + q = addr; + } + else + k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING); } - else - k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING); - } - else if (r == -1) - { - safe_free ((void **) &keylist); - rfc822_free_address (&tmp); - rfc822_free_address (&addr); - return NULL; + else if (r == -1) + { + safe_free ((void **) &keylist); + rfc822_free_address (&tmp); + rfc822_free_address (&addr); + mutt_free_list (&hook_list); + return NULL; + } } - } - if (k_info == NULL) - pgp_invoke_getkeys (q); + if (k_info == NULL) + pgp_invoke_getkeys (q); - if (k_info == NULL && (k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL) - { - 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 (k_info == NULL && (k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL) { - safe_free ((void **)&keylist); - rfc822_free_address (&tmp); - rfc822_free_address (&addr); - return NULL; + snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); + + if ((key = pgp_ask_for_key (buf, q->mailbox, + KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL) + { + safe_free ((void **)&keylist); + rfc822_free_address (&tmp); + rfc822_free_address (&addr); + mutt_free_list (&hook_list); + return NULL; + } } - } - else - key = k_info; + else + key = k_info; - keyID = pgp_keyid (key); - - keylist_size += mutt_strlen (keyID) + 4; - safe_realloc ((void **)&keylist, keylist_size); - sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", - keyID); - keylist_used = mutt_strlen (keylist); + keyID = pgp_keyid (key); + + keylist_size += mutt_strlen (keyID) + 4; + safe_realloc ((void **)&keylist, keylist_size); + sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", + keyID); + keylist_used = mutt_strlen (keylist); + + pgp_free_key (&key); + rfc822_free_address (&addr); + + if (!hook_list) + break; + + hook = hook->next; + if (!hook) + break; - pgp_free_key (&key); - rfc822_free_address (&addr); + } + mutt_free_list (&hook_list); } rfc822_free_address (&tmp); --- mutt-1.2.5/pgpkey.c Fri Jan 11 08:32:58 2002 +++ mutt-1.2.5/pgpkey.c Fri Jan 11 08:54:49 2002 @@ -381,6 +381,11 @@ : _pgp_compare_trust (a, b)); } + +#define pgp_trusted_id(uid) (!option(OPTPGPCHECKTRUST) \ + || (!(((uid)->parent->flags | pgp_principal_key((uid)->parent)->flags) & KEYFLAG_CANTUSE) \ + && !(((uid)->trust & 0x03) < 3))) + static pgp_key_t *pgp_select_key (pgp_key_t *keys, ADDRESS * p, const char *s) { @@ -395,6 +400,7 @@ pgp_key_t *kp; pgp_uid_t *a; int (*f) (const void *, const void *); + int keymatch = 0; /* count matching keys */ for (i = 0, kp = keys; kp; kp = kp->next) { @@ -418,8 +424,25 @@ for (a = kp->address; a; i++, a = a->next) KeyTable[i] = a; + keymatch++; } + if (keymatch == 1 && option(OPTPGPAUTOSELECT)) + { + /* + * Only one matching key...see if there's an id with enough trust to auto-select + */ + kp = KeyTable[0]->parent; + for (a = kp->address; a; a = a->next) + { + if (pgp_trusted_id(a)) + { + safe_free ((void **) &KeyTable); + return (kp); + } + } + } + switch (PgpSortKeys & SORT_MASK) { case SORT_DATE: --- mutt-1.2.5/protos.h Fri Jan 11 08:32:59 2002 +++ mutt-1.2.5/protos.h Fri Jan 11 08:54:49 2002 @@ -120,7 +120,7 @@ char *mutt_get_parameter (const char *, PARAMETER *); char *mutt_get_send_charset (char *, size_t, BODY *, short); #ifdef HAVE_PGP -char *mutt_pgp_hook (ADDRESS *); +LIST *mutt_pgp_hook (ADDRESS *); #endif /* HAVE_PGP */ char *mutt_make_date (char *, size_t); --- mutt-1.2.5/doc/manual.sgml.head Fri Jan 11 08:33:00 2002 +++ mutt-1.2.5/doc/manual.sgml.head Fri Jan 11 08:54:49 2002 @@ -1298,7 +1298,9 @@ or because, for some reasons, you need to override the key Mutt would normally use. The pgp-hook command provides a method by which you can specify the ID of the public key to be used when encrypting messages to -a certain recipient. +a certain recipient. You may use multiple pgp-hook's with the same +pattern; multiple matching pgp-hook's result in the use of multiple +keyids for recipient. Adding key sequences to the keyboard buffer