prompting will be used. */
static char *find_keys (ADDRESS *adrlist, unsigned int app, int oppenc_mode)
{
+ LIST *crypt_hook_list, *crypt_hook = NULL;
char *crypt_hook_val = NULL;
const char *keyID = NULL;
char *keylist = NULL, *t;
ADDRESS *p, *q;
crypt_key_t *k_info;
const char *fqdn = mutt_fqdn (1);
+ char buf[LONG_STRING];
+ int forced_valid;
+ int r;
+ int key_selected;
#if 0
*r_application = APPLICATION_PGP|APPLICATION_SMIME;
for (p = adrlist; p ; p = p->next)
{
- char buf[LONG_STRING];
- int forced_valid = 0;
-
- q = p;
- k_info = NULL;
-
- if ((crypt_hook_val = mutt_crypt_hook (p)) != NULL)
- {
- int r = M_NO;
- if (! oppenc_mode)
- {
- snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"),
- crypt_hook_val, p->mailbox);
- r = mutt_yesorno (buf, M_YES);
- }
- if (oppenc_mode || (r == M_YES))
- {
- if (crypt_is_numerical_keyid (crypt_hook_val))
- {
- keyID = crypt_hook_val;
- if (strncmp (keyID, "0x", 2) == 0)
- keyID += 2;
- goto bypass_selection; /* you don't see this. */
- }
+ key_selected = 0;
+ crypt_hook_list = crypt_hook = mutt_crypt_hook (p);
+ do
+ {
+ q = p;
+ forced_valid = 0;
+ k_info = NULL;
- /* check for e-mail address */
- if ((t = strchr (crypt_hook_val, '@')) &&
- (addr = rfc822_parse_adrlist (NULL, crypt_hook_val)))
- {
- if (fqdn)
- rfc822_qualify (addr, fqdn);
- q = addr;
- }
- else if (! oppenc_mode)
- {
+ if (crypt_hook != NULL)
+ {
+ crypt_hook_val = crypt_hook->data;
+ r = M_NO;
+ if (! oppenc_mode)
+ {
+ snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"),
+ crypt_hook_val, p->mailbox);
+ r = mutt_yesorno (buf, M_YES);
+ }
+ if (oppenc_mode || (r == M_YES))
+ {
+ if (crypt_is_numerical_keyid (crypt_hook_val))
+ {
+ keyID = crypt_hook_val;
+ if (strncmp (keyID, "0x", 2) == 0)
+ keyID += 2;
+ goto bypass_selection; /* you don't see this. */
+ }
+
+ /* check for e-mail address */
+ if ((t = strchr (crypt_hook_val, '@')) &&
+ (addr = rfc822_parse_adrlist (NULL, crypt_hook_val)))
+ {
+ if (fqdn)
+ rfc822_qualify (addr, fqdn);
+ q = addr;
+ }
+ else if (! oppenc_mode)
+ {
#if 0
- k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
- *r_application, &forced_valid);
+ k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
+ *r_application, &forced_valid);
#else
- k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
- app, &forced_valid);
+ k_info = crypt_getkeybystr (crypt_hook_val, KEYFLAG_CANENCRYPT,
+ app, &forced_valid);
#endif
- }
- }
- else if (r == -1)
- {
- FREE (&keylist);
- rfc822_free_address (&addr);
- return NULL;
- }
- }
+ }
+ }
+ else if (r == M_NO)
+ {
+ if (key_selected || (crypt_hook->next != NULL))
+ {
+ crypt_hook = crypt_hook->next;
+ continue;
+ }
+ }
+ else if (r == -1)
+ {
+ FREE (&keylist);
+ rfc822_free_address (&addr);
+ mutt_free_list (&crypt_hook_list);
+ return NULL;
+ }
+ }
- if (k_info == NULL)
- {
- k_info = crypt_getkeybyaddr (q, KEYFLAG_CANENCRYPT,
- app, &forced_valid, oppenc_mode);
- }
+ if (k_info == NULL)
+ {
+ k_info = crypt_getkeybyaddr (q, KEYFLAG_CANENCRYPT,
+ app, &forced_valid, oppenc_mode);
+ }
- if ((k_info == NULL) && (! oppenc_mode))
- {
- snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
-
- k_info = crypt_ask_for_key (buf, q->mailbox,
- KEYFLAG_CANENCRYPT,
+ if ((k_info == NULL) && (! oppenc_mode))
+ {
+ snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
+
+ k_info = crypt_ask_for_key (buf, q->mailbox,
+ KEYFLAG_CANENCRYPT,
#if 0
- *r_application,
+ *r_application,
#else
- app,
+ app,
#endif
- &forced_valid);
- }
+ &forced_valid);
+ }
- if (k_info == NULL)
- {
- FREE (&keylist);
- rfc822_free_address (&addr);
- return NULL;
- }
+ if (k_info == NULL)
+ {
+ FREE (&keylist);
+ rfc822_free_address (&addr);
+ mutt_free_list (&crypt_hook_list);
+ return NULL;
+ }
- keyID = crypt_fpr_or_lkeyid (k_info);
+ keyID = crypt_fpr_or_lkeyid (k_info);
#if 0
- if (k_info->flags & KEYFLAG_ISX509)
- *r_application &= ~APPLICATION_PGP;
- if (!(k_info->flags & KEYFLAG_ISX509))
- *r_application &= ~APPLICATION_SMIME;
+ if (k_info->flags & KEYFLAG_ISX509)
+ *r_application &= ~APPLICATION_PGP;
+ if (!(k_info->flags & KEYFLAG_ISX509))
+ *r_application &= ~APPLICATION_SMIME;
#endif
-
- bypass_selection:
- keylist_size += mutt_strlen (keyID) + 4 + 1;
- safe_realloc (&keylist, keylist_size);
- sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */
- keylist_used ? " " : "", keyID,
- forced_valid? "!":"");
- keylist_used = mutt_strlen (keylist);
- crypt_free_key (&k_info);
- rfc822_free_address (&addr);
+ bypass_selection:
+ keylist_size += mutt_strlen (keyID) + 4 + 1;
+ safe_realloc (&keylist, keylist_size);
+ sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */
+ keylist_used ? " " : "", keyID,
+ forced_valid? "!":"");
+ keylist_used = mutt_strlen (keylist);
+
+ key_selected = 1;
+
+ crypt_free_key (&k_info);
+ rfc822_free_address (&addr);
+
+ if (crypt_hook != NULL)
+ crypt_hook = crypt_hook->next;
+
+ } while (crypt_hook != NULL);
+
+ mutt_free_list (&crypt_hook_list);
}
return (keylist);
}
the key Mutt would normally use. The <command>crypt-hook</command>
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.
+You may use multiple crypt-hooks with the same regexp; multiple
+matching crypt-hooks result in the use of multiple keyids for
+a recipient. During key selection, Mutt will confirm whether each
+crypt-hook is to be used. If all crypt-hooks for a recipient are
+declined, Mutt will use the original recipient address for key selection
+instead.
</para>
<para>
to a certain recipient. The meaning of "key ID" is to be taken
broadly: This can be a different e-mail address, a numerical key ID,
or even just an arbitrary search string.
+You may use multiple
+\fBcrypt-hook\fPs with the same \fIregexp\fP; multiple matching
+\fBcrypt-hook\fPs result in the use of multiple \fIkey-id\fPs for
+a recipient.
+
.TP
\fBpush\fP \fIstring\fP
This command adds the named \fIstring\fP to the keyboard buffer.
ptr->rx.not == not &&
!mutt_strcmp (pattern.data, ptr->rx.pattern))
{
- if (data & (M_FOLDERHOOK | M_SENDHOOK | M_SEND2HOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK | M_REPLYHOOK))
+ if (data & (M_FOLDERHOOK | M_SENDHOOK | M_SEND2HOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK | M_REPLYHOOK | M_CRYPTHOOK))
{
/* these hooks allow multiple commands with the same
* pattern, so if we've already seen this pattern/command pair, just
return (NULL);
}
+static LIST *_mutt_list_hook (const char *match, int hook)
+{
+ HOOK *tmp = Hooks;
+ LIST *matches = NULL;
+
+ for (; tmp; tmp = tmp->next)
+ {
+ if ((tmp->type & hook) &&
+ ((match && regexec (tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.not))
+ matches = mutt_add_list (matches, tmp->command);
+ }
+ return (matches);
+}
+
char *mutt_charset_hook (const char *chs)
{
return _mutt_string_hook (chs, M_CHARSETHOOK);
return _mutt_string_hook (chs, M_ICONVHOOK);
}
-char *mutt_crypt_hook (ADDRESS *adr)
+LIST *mutt_crypt_hook (ADDRESS *adr)
{
- return _mutt_string_hook (adr->mailbox, M_CRYPTHOOK);
+ return _mutt_list_hook (adr->mailbox, M_CRYPTHOOK);
}
#ifdef USE_SOCKET
*/
char *pgp_findKeys (ADDRESS *adrlist, int oppenc_mode)
{
+ LIST *crypt_hook_list, *crypt_hook = NULL;
char *keyID, *keylist = NULL;
size_t keylist_size = 0;
size_t keylist_used = 0;
ADDRESS *addr = NULL;
ADDRESS *p, *q;
pgp_key_t k_info = NULL;
+ char buf[LONG_STRING];
+ int r;
+ int key_selected;
const char *fqdn = mutt_fqdn (1);
for (p = adrlist; p ; p = p->next)
{
- char buf[LONG_STRING];
+ key_selected = 0;
+ crypt_hook_list = crypt_hook = mutt_crypt_hook (p);
+ do
+ {
+ q = p;
+ k_info = NULL;
- q = p;
- k_info = NULL;
+ if (crypt_hook != NULL)
+ {
+ keyID = crypt_hook->data;
+ r = M_NO;
+ if (! oppenc_mode)
+ {
+ snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox);
+ r = mutt_yesorno (buf, M_YES);
+ }
+ if (oppenc_mode || (r == M_YES))
+ {
+ if (crypt_is_numerical_keyid (keyID))
+ {
+ if (strncmp (keyID, "0x", 2) == 0)
+ keyID += 2;
+ goto bypass_selection; /* you don't see this. */
+ }
+
+ /* check for e-mail address */
+ if (strchr (keyID, '@') &&
+ (addr = rfc822_parse_adrlist (NULL, keyID)))
+ {
+ if (fqdn) rfc822_qualify (addr, fqdn);
+ q = addr;
+ }
+ else if (! oppenc_mode)
+ {
+ k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING);
+ }
+ }
+ else if (r == M_NO)
+ {
+ if (key_selected || (crypt_hook->next != NULL))
+ {
+ crypt_hook = crypt_hook->next;
+ continue;
+ }
+ }
+ else if (r == -1)
+ {
+ FREE (&keylist);
+ rfc822_free_address (&addr);
+ mutt_free_list (&crypt_hook_list);
+ return NULL;
+ }
+ }
- if ((keyID = mutt_crypt_hook (p)) != NULL)
- {
- int r = M_NO;
- if (! oppenc_mode)
+ if (k_info == NULL)
{
- snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox);
- r = mutt_yesorno (buf, M_YES);
+ pgp_invoke_getkeys (q);
+ k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING, oppenc_mode);
}
- if (oppenc_mode || (r == M_YES))
+
+ if ((k_info == NULL) && (! oppenc_mode))
{
- if (crypt_is_numerical_keyid (keyID))
- {
- if (strncmp (keyID, "0x", 2) == 0)
- keyID += 2;
- goto bypass_selection; /* you don't see this. */
- }
-
- /* check for e-mail address */
- if (strchr (keyID, '@') &&
- (addr = rfc822_parse_adrlist (NULL, keyID)))
- {
- if (fqdn) rfc822_qualify (addr, fqdn);
- q = addr;
- }
- else if (! oppenc_mode)
- {
- k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING);
- }
+ snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
+ k_info = pgp_ask_for_key (buf, q->mailbox,
+ KEYFLAG_CANENCRYPT, PGP_PUBRING);
}
- else if (r == -1)
+
+ if (k_info == NULL)
{
- FREE (&keylist);
- rfc822_free_address (&addr);
- return NULL;
+ FREE (&keylist);
+ rfc822_free_address (&addr);
+ mutt_free_list (&crypt_hook_list);
+ return NULL;
}
- }
- if (k_info == NULL)
- {
- pgp_invoke_getkeys (q);
- k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING, oppenc_mode);
- }
+ keyID = pgp_fpr_or_lkeyid (k_info);
- if ((k_info == NULL) && (! oppenc_mode))
- {
- snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
- k_info = pgp_ask_for_key (buf, q->mailbox,
- KEYFLAG_CANENCRYPT, PGP_PUBRING);
- }
+ bypass_selection:
+ keylist_size += mutt_strlen (keyID) + 4;
+ safe_realloc (&keylist, keylist_size);
+ sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */
+ keyID);
+ keylist_used = mutt_strlen (keylist);
- if (k_info == NULL)
- {
- FREE (&keylist);
+ key_selected = 1;
+
+ pgp_free_key (&k_info);
rfc822_free_address (&addr);
- return NULL;
- }
- keyID = pgp_fpr_or_lkeyid (k_info);
-
- bypass_selection:
- keylist_size += mutt_strlen (keyID) + 4;
- safe_realloc (&keylist, keylist_size);
- sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */
- keyID);
- keylist_used = mutt_strlen (keylist);
+ if (crypt_hook != NULL)
+ crypt_hook = crypt_hook->next;
- pgp_free_key (&k_info);
- rfc822_free_address (&addr);
+ } while (crypt_hook != NULL);
+ mutt_free_list (&crypt_hook_list);
}
return (keylist);
}
char *mutt_get_body_charset (char *, size_t, BODY *);
const char *mutt_get_name (ADDRESS *);
char *mutt_get_parameter (const char *, PARAMETER *);
-char *mutt_crypt_hook (ADDRESS *);
+LIST *mutt_crypt_hook (ADDRESS *);
char *mutt_make_date (char *, size_t);
const char *mutt_make_version (void);