summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2019-07-19 12:54:32 -0700
committerKevin McCarthy <kevin@8t8.us>2019-08-03 14:08:09 -0700
commit959628d079b6efaa9c724f9be83af3d6061fdae4 (patch)
treec6d3edc4ca66ae97dab6b3df502bf86a0e57c574
parent009b62c9f773b82b20b6798be3125f471569f14d (diff)
Add autocrypt line to the compose menu.
Remove the hardcoded HDR_ATTACH offset calcuation, and add an explicit enum for the "-- Attachments" line to make loops and padding array sizes easier. Add security and recommendataion fields on the line. Add mutt_autocrypt_ui_recommendation, following the autocrypt spec guidelines.
-rw-r--r--OPS1
-rw-r--r--autocrypt/autocrypt.c72
-rw-r--r--autocrypt/autocrypt.h10
-rw-r--r--autocrypt/autocrypt_gpgme.c26
-rw-r--r--autocrypt/autocrypt_private.h1
-rw-r--r--compose.c242
-rw-r--r--functions.h3
-rw-r--r--mutt.h6
-rw-r--r--mutt_crypt.h10
9 files changed, 323 insertions, 48 deletions
diff --git a/OPS b/OPS
index 2fad8f12..076b4079 100644
--- a/OPS
+++ b/OPS
@@ -16,6 +16,7 @@ OP_CHANGE_DIRECTORY "change directories"
OP_CHECK_NEW "check mailboxes for new mail"
OP_COMPOSE_ATTACH_FILE "attach file(s) to this message"
OP_COMPOSE_ATTACH_MESSAGE "attach message(s) to this message"
+OP_COMPOSE_AUTOCRYPT_MENU "show autocrypt compose menu options"
OP_COMPOSE_EDIT_BCC "edit the BCC list"
OP_COMPOSE_EDIT_CC "edit the CC list"
OP_COMPOSE_EDIT_DESCRIPTION "edit attachment description"
diff --git a/autocrypt/autocrypt.c b/autocrypt/autocrypt.c
index 228c24a6..dd3ccb82 100644
--- a/autocrypt/autocrypt.c
+++ b/autocrypt/autocrypt.c
@@ -22,6 +22,7 @@
#include "mutt.h"
#include "mutt_curses.h"
+#include "mutt_crypt.h"
#include "mime.h"
#include "mutt_idna.h"
#include "autocrypt.h"
@@ -437,3 +438,74 @@ cleanup:
return rv;
}
+
+autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr)
+{
+ autocrypt_rec_t rv = AUTOCRYPT_REC_OFF;
+ AUTOCRYPT_ACCOUNT *account = NULL;
+ AUTOCRYPT_PEER *peer = NULL;
+ ADDRESS *recip, *recips = NULL, *last = NULL;
+ int all_encrypt = 1, has_discourage = 0;
+
+ if (!option (OPTAUTOCRYPT) ||
+ mutt_autocrypt_init (0) ||
+ !hdr ||
+ !hdr->env->from ||
+ hdr->env->from->next)
+ return AUTOCRYPT_REC_OFF;
+
+ if (hdr->security & APPLICATION_SMIME)
+ return AUTOCRYPT_REC_OFF;
+
+ if (mutt_autocrypt_db_account_get (hdr->env->from, &account) <= 0)
+ goto cleanup;
+
+ last = rfc822_append (&recips, hdr->env->to, 0);
+ last = rfc822_append (last ? &last : &recips, hdr->env->cc, 0);
+ rfc822_append (last ? &last : &recips, hdr->env->bcc, 0);
+
+ rv = AUTOCRYPT_REC_NO;
+ if (!recips)
+ goto cleanup;
+
+ for (recip = recips; recip; recip = recip->next)
+ {
+ if (mutt_autocrypt_db_peer_get (recip, &peer) <= 0)
+ goto cleanup;
+
+ if (mutt_autocrypt_gpgme_is_valid_key (peer->keyid))
+ {
+ if (!(peer->last_seen && peer->autocrypt_timestamp) ||
+ (peer->last_seen - peer->autocrypt_timestamp > 35 * 24 * 60 * 60))
+ {
+ has_discourage = 1;
+ all_encrypt = 0;
+ }
+
+ if (!account->prefer_encrypt || !peer->prefer_encrypt)
+ all_encrypt = 0;
+ }
+ else if (mutt_autocrypt_gpgme_is_valid_key (peer->gossip_keyid))
+ {
+ has_discourage = 1;
+ all_encrypt = 0;
+ }
+ else
+ goto cleanup;
+
+ mutt_autocrypt_db_peer_free (&peer);
+ }
+
+ if (all_encrypt)
+ rv = AUTOCRYPT_REC_YES;
+ else if (has_discourage)
+ rv = AUTOCRYPT_REC_DISCOURAGE;
+ else
+ rv = AUTOCRYPT_REC_AVAILABLE;
+
+cleanup:
+ mutt_autocrypt_db_account_free (&account);
+ rfc822_free_address (&recips);
+ mutt_autocrypt_db_peer_free (&peer);
+ return rv;
+}
diff --git a/autocrypt/autocrypt.h b/autocrypt/autocrypt.h
index a2401bc3..2608277d 100644
--- a/autocrypt/autocrypt.h
+++ b/autocrypt/autocrypt.h
@@ -62,9 +62,19 @@ typedef struct
char *gossip_keydata;
} AUTOCRYPT_GOSSIP_HISTORY;
+typedef enum
+{
+ AUTOCRYPT_REC_OFF,
+ AUTOCRYPT_REC_NO,
+ AUTOCRYPT_REC_DISCOURAGE,
+ AUTOCRYPT_REC_AVAILABLE,
+ AUTOCRYPT_REC_YES
+} autocrypt_rec_t;
+
int mutt_autocrypt_init (int);
void mutt_autocrypt_cleanup (void);
int mutt_autocrypt_process_autocrypt_header (HEADER *hdr, ENVELOPE *env);
int mutt_autocrypt_process_gossip_header (HEADER *hdr, ENVELOPE *env);
+autocrypt_rec_t mutt_autocrypt_ui_recommendation (HEADER *hdr);
#endif
diff --git a/autocrypt/autocrypt_gpgme.c b/autocrypt/autocrypt_gpgme.c
index 952f648b..84bb9ffc 100644
--- a/autocrypt/autocrypt_gpgme.c
+++ b/autocrypt/autocrypt_gpgme.c
@@ -212,3 +212,29 @@ cleanup:
mutt_buffer_pool_release (&raw_keydata);
return rv;
}
+
+int mutt_autocrypt_gpgme_is_valid_key (const char *keyid)
+{
+ int rv = 0;
+ gpgme_ctx_t ctx = NULL;
+ gpgme_key_t key = NULL;
+
+ if (!keyid)
+ return 0;
+
+ if (create_gpgme_context (&ctx))
+ goto cleanup;
+
+ if (gpgme_get_key (ctx, keyid, &key, 0))
+ goto cleanup;
+
+ rv = 1;
+ if (key->revoked || key->expired || key->disabled || key->invalid ||
+ !key->can_encrypt)
+ rv = 0;
+
+cleanup:
+ gpgme_key_unref (key);
+ gpgme_release (ctx);
+ return rv;
+}
diff --git a/autocrypt/autocrypt_private.h b/autocrypt/autocrypt_private.h
index 1ba51920..3e370da6 100644
--- a/autocrypt/autocrypt_private.h
+++ b/autocrypt/autocrypt_private.h
@@ -54,5 +54,6 @@ int mutt_autocrypt_schema_update (void);
int mutt_autocrypt_gpgme_init (void);
int mutt_autocrypt_gpgme_create_key (ADDRESS *addr, BUFFER *keyid, BUFFER *keydata);
int mutt_autocrypt_gpgme_import_key (const char *keydata, BUFFER *keyid);
+int mutt_autocrypt_gpgme_is_valid_key (const char *keyid);
#endif
diff --git a/compose.c b/compose.c
index 4d1b7135..4ae322f6 100644
--- a/compose.c
+++ b/compose.c
@@ -26,6 +26,7 @@
#include "mutt_curses.h"
#include "mutt_idna.h"
#include "mutt_menu.h"
+#include "mutt_crypt.h"
#include "rfc1524.h"
#include "mime.h"
#include "attach.h"
@@ -38,6 +39,10 @@
#include "remailer.h"
#endif
+#ifdef USE_AUTOCRYPT
+#include "autocrypt/autocrypt.h"
+#endif
+
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
@@ -68,11 +73,15 @@ enum
HDR_CRYPT,
HDR_CRYPTINFO,
+#ifdef USE_AUTOCRYPT
+ HDR_AUTOCRYPT,
+#endif
- HDR_ATTACH = (HDR_FCC + 5) /* where to start printing the attachments */
+ HDR_ATTACH_TITLE, /* the "-- Attachments" line */
+ HDR_ATTACH /* where to start printing the attachments */
};
-int HeaderPadding[HDR_CRYPTINFO + 1] = {0};
+int HeaderPadding[HDR_ATTACH_TITLE] = {0};
int MaxHeaderWidth = 0;
#define HDR_XOFFSET MaxHeaderWidth
@@ -109,7 +118,13 @@ static const char * const Prompts[] =
* Since it shares the row with "Encrypt with:", it should not be longer
* than 15-20 character cells.
*/
- N_("Sign as: ")
+ N_("Sign as: "),
+#ifdef USE_AUTOCRYPT
+ /* L10N:
+ The compose menu autocrypt line
+ */
+ N_("Autocrypt: ")
+#endif
};
static const struct mapping_t ComposeHelp[] = {
@@ -127,6 +142,41 @@ static const struct mapping_t ComposeHelp[] = {
{ NULL, 0 }
};
+#ifdef USE_AUTOCRYPT
+static const char *AutocryptRecUiFlags[] = {
+ /* L10N: Autocrypt recommendation flag: off.
+ * This is displayed when Autocrypt is turned off. */
+ N_("Off"),
+ /* L10N: Autocrypt recommendation flag: no.
+ * This is displayed when Autocrypt cannot encrypt to the recipients. */
+ N_("No"),
+ /* L10N: Autocrypt recommendation flag: discouraged.
+ * This is displayed when Autocrypt believes encryption should not be used.
+ * This might occur if one of the recipient Autocrypt Keys has not been
+ * used recently, or if the only key available is a Gossip Header key. */
+ N_("Discouraged"),
+ /* L10N: Autocrypt recommendation flag: available.
+ * This is displayed when Autocrypt believes encryption is possible, but
+ * leaves enabling it up to the sender. Probably because "prefer encrypt"
+ * is not set in both the sender and recipient keys. */
+ N_("Available"),
+ /* L10N: Autocrypt recommendation flag: yes.
+ * This is displayed when Autocrypt would normally enable encryption
+ * automatically. */
+ N_("Yes"),
+};
+#endif
+
+typedef struct
+{
+ HEADER *msg;
+ char *fcc;
+#ifdef USE_AUTOCRYPT
+ autocrypt_rec_t autocrypt_rec;
+ int autocrypt_rec_override;
+#endif
+} compose_redraw_data_t;
+
static void calc_header_width_padding (int idx, const char *header, int calc_max)
{
int width;
@@ -154,15 +204,19 @@ static void init_header_padding (void)
return;
done = 1;
- for (i = 0; i <= HDR_CRYPT; i++)
+ for (i = 0; i < HDR_ATTACH_TITLE; i++)
+ {
+ if (i == HDR_CRYPTINFO)
+ continue;
calc_header_width_padding (i, _(Prompts[i]), 1);
+ }
/* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
* doesn't show up by default, and so can make the indentation of
* the other fields look funny. */
calc_header_width_padding (HDR_CRYPTINFO, _(Prompts[HDR_CRYPTINFO]), 0);
- for (i = 0; i <= HDR_CRYPTINFO; i++)
+ for (i = 0; i < HDR_ATTACH_TITLE; i++)
{
HeaderPadding[i] += MaxHeaderWidth;
if (HeaderPadding[i] < 0)
@@ -179,12 +233,50 @@ static void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num)
MUTT_FORMAT_STAT_FILE | MUTT_FORMAT_ARROWCURSOR);
}
+#ifdef USE_AUTOCRYPT
+static void autocrypt_compose_menu (HEADER *msg)
+{
+ char *prompt, *letters;
+ int choice;
+ /* L10N:
+ The compose menu autocrypt prompt.
+ (e)ncrypt enables encryption via autocrypt.
+ (c)lear sets cleartext.
+ (a)utomatic defers to the recommendation.
+ */
+ prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic? ");
-#include "mutt_crypt.h"
+ /* L10N:
+ The letter corresponding to the compose menu autocrypt prompt
+ (e)ncrypt, (c)lear, (a)utomatic
+ */
+ letters = "eca";
-static void redraw_crypt_lines (HEADER *msg)
+ choice = mutt_multi_choice (prompt, letters);
+ switch (choice)
+ {
+ case 1:
+ msg->security |= (AUTOCRYPT | AUTOCRYPT_OVERRIDE);
+ msg->security &= ~(ENCRYPT | SIGN | OPPENCRYPT);
+ break;
+ case 2:
+ msg->security &= ~AUTOCRYPT;
+ msg->security |= AUTOCRYPT_OVERRIDE;
+ break;
+ case 3:
+ msg->security &= ~AUTOCRYPT_OVERRIDE;
+ if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+ msg->security |= OPPENCRYPT;
+ break;
+ }
+}
+#endif
+
+static void redraw_crypt_lines (compose_redraw_data_t *rd)
{
+ HEADER *msg = rd->msg;
+
SETCOLOR (MT_COLOR_COMPOSE_HEADER);
mutt_window_mvprintw (MuttIndexWindow, HDR_CRYPT, 0,
"%*s", HeaderPadding[HDR_CRYPT], _(Prompts[HDR_CRYPT]));
@@ -267,6 +359,65 @@ static void redraw_crypt_lines (HEADER *msg)
NORMAL_COLOR;
printw ("%s", NONULL(SmimeCryptAlg));
}
+
+#ifdef USE_AUTOCRYPT
+ mutt_window_move (MuttIndexWindow, HDR_AUTOCRYPT, 0);
+ mutt_window_clrtoeol (MuttIndexWindow);
+ SETCOLOR (MT_COLOR_COMPOSE_HEADER);
+ printw ("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
+ NORMAL_COLOR;
+ if (option (OPTAUTOCRYPT) && (msg->security & AUTOCRYPT))
+ {
+ SETCOLOR (MT_COLOR_COMPOSE_SECURITY_ENCRYPT);
+ addstr (_("Encrypt"));
+ }
+ else
+ {
+ SETCOLOR (MT_COLOR_COMPOSE_SECURITY_NONE);
+ addstr (_("Off"));
+ }
+
+ SETCOLOR (MT_COLOR_COMPOSE_HEADER);
+ mutt_window_mvprintw (MuttIndexWindow, HDR_AUTOCRYPT, 40, "%s",
+ _("Recommendation: "));
+ NORMAL_COLOR;
+ printw ("%s", _(AutocryptRecUiFlags[rd->autocrypt_rec]));
+#endif
+}
+
+static void update_crypt_info (compose_redraw_data_t *rd)
+{
+ HEADER *msg = rd->msg;
+
+ if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+ crypt_opportunistic_encrypt (msg);
+
+#ifdef USE_AUTOCRYPT
+ rd->autocrypt_rec = mutt_autocrypt_ui_recommendation (msg);
+
+ /* Anything that enables ENCRYPT or SIGN, or turns on SMIME
+ * overrides autocrypt, be it oppenc or the user having turned on
+ * those flags manually. */
+ if (msg->security & (ENCRYPT | SIGN | APPLICATION_SMIME))
+ msg->security &= ~(AUTOCRYPT | AUTOCRYPT_OVERRIDE);
+ else
+ {
+ if (!(msg->security & AUTOCRYPT_OVERRIDE))
+ {
+ if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
+ msg->security |= AUTOCRYPT;
+ else
+ msg->security &= ~AUTOCRYPT;
+ }
+ }
+ /* TODO:
+ * - autocrypt menu for manually enabling/disabling (turns on override)
+ * - deal with pgp and smime menu and their effects on security->AUTOCRYPT
+ * when encryption or signing is enabled or if switch to smime mode
+ */
+#endif
+
+ redraw_crypt_lines (rd);
}
@@ -354,8 +505,11 @@ static void draw_envelope_addr (int line, ADDRESS *addr)
mutt_paddstr (W, buf);
}
-static void draw_envelope (HEADER *msg, char *fcc)
+static void draw_envelope (compose_redraw_data_t *rd)
{
+ HEADER *msg = rd->msg;
+ char *fcc = rd->fcc;
+
draw_envelope_addr (HDR_FROM, msg->env->from);
draw_envelope_addr (HDR_TO, msg->env->to);
draw_envelope_addr (HDR_CC, msg->env->cc);
@@ -376,14 +530,14 @@ static void draw_envelope (HEADER *msg, char *fcc)
mutt_paddstr (W, fcc);
if (WithCrypto)
- redraw_crypt_lines (msg);
+ redraw_crypt_lines (rd);
#ifdef MIXMASTER
redraw_mix_line (msg->chain);
#endif
SETCOLOR (MT_COLOR_STATUS);
- mutt_window_mvaddstr (MuttIndexWindow, HDR_ATTACH - 1, 0, _("-- Attachments"));
+ mutt_window_mvaddstr (MuttIndexWindow, HDR_ATTACH_TITLE, 0, _("-- Attachments"));
mutt_window_clrtoeol (MuttIndexWindow);
NORMAL_COLOR;
@@ -635,12 +789,6 @@ static void compose_status_line (char *buf, size_t buflen, size_t col, int cols,
(unsigned long) menu, 0);
}
-typedef struct
-{
- HEADER *msg;
- char *fcc;
-} compose_redraw_data_t;
-
static void compose_menu_redraw (MUTTMENU *menu)
{
char buf[LONG_STRING];
@@ -653,7 +801,7 @@ static void compose_menu_redraw (MUTTMENU *menu)
{
menu_redraw_full (menu);
- draw_envelope (rd->msg, rd->fcc);
+ draw_envelope (rd);
menu->offset = HDR_ATTACH;
menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH;
}
@@ -711,7 +859,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
/* Sort, SortAux could be changed in mutt_index_menu() */
int oldSort, oldSortAux;
struct stat st;
- compose_redraw_data_t rd;
+ compose_redraw_data_t rd = {0};
init_header_padding ();
@@ -731,39 +879,30 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
actx->hdr = msg;
mutt_update_compose_menu (actx, menu, 1);
+ update_crypt_info (&rd);
+
while (loop)
{
switch (op = mutt_menuLoop (menu))
{
case OP_COMPOSE_EDIT_FROM:
edit_address_list (HDR_FROM, &msg->env->from);
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
case OP_COMPOSE_EDIT_TO:
edit_address_list (HDR_TO, &msg->env->to);
- if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
- {
- crypt_opportunistic_encrypt (msg);
- redraw_crypt_lines (msg);
- }
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
case OP_COMPOSE_EDIT_BCC:
edit_address_list (HDR_BCC, &msg->env->bcc);
- if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
- {
- crypt_opportunistic_encrypt (msg);
- redraw_crypt_lines (msg);
- }
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
case OP_COMPOSE_EDIT_CC:
edit_address_list (HDR_CC, &msg->env->cc);
- if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
- {
- crypt_opportunistic_encrypt (msg);
- redraw_crypt_lines (msg);
- }
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
case OP_COMPOSE_EDIT_SUBJECT:
@@ -822,8 +961,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
mutt_error (_("Bad IDN in \"%s\": '%s'"), tag, err);
FREE (&err);
}
- if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
- crypt_opportunistic_encrypt (msg);
+ update_crypt_info (&rd);
}
else
{
@@ -1437,11 +1575,10 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
}
msg->security &= ~APPLICATION_SMIME;
msg->security |= APPLICATION_PGP;
- crypt_opportunistic_encrypt (msg);
- redraw_crypt_lines (msg);
+ update_crypt_info (&rd);
}
msg->security = crypt_pgp_send_menu (msg);
- redraw_crypt_lines (msg);
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
@@ -1475,11 +1612,10 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
}
msg->security &= ~APPLICATION_PGP;
msg->security |= APPLICATION_SMIME;
- crypt_opportunistic_encrypt (msg);
- redraw_crypt_lines (msg);
+ update_crypt_info (&rd);
}
msg->security = crypt_smime_send_menu(msg);
- redraw_crypt_lines (msg);
+ update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
@@ -1492,6 +1628,30 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
break;
#endif
+#ifdef USE_AUTOCRYPT
+ case OP_COMPOSE_AUTOCRYPT_MENU:
+ if ((WithCrypto & APPLICATION_SMIME)
+ && (msg->security & APPLICATION_SMIME))
+ {
+ if (msg->security & (ENCRYPT | SIGN))
+ {
+ if (mutt_yesorno (_("S/MIME already selected. Clear & continue ? "),
+ MUTT_YES) != MUTT_YES)
+ {
+ mutt_clear_error ();
+ break;
+ }
+ msg->security &= ~(ENCRYPT | SIGN);
+ }
+ msg->security &= ~APPLICATION_SMIME;
+ msg->security |= APPLICATION_PGP;
+ update_crypt_info (&rd);
+ }
+ autocrypt_compose_menu (msg);
+ update_crypt_info (&rd);
+ mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
+ break;
+#endif
}
}
diff --git a/functions.h b/functions.h
index 5b9459b5..6e9ba390 100644
--- a/functions.h
+++ b/functions.h
@@ -362,6 +362,9 @@ const struct binding_t OpCompose[] = { /* map: compose */
{ "print-entry", OP_PRINT, "l" },
{ "edit-mime", OP_COMPOSE_EDIT_MIME, "m" },
{ "new-mime", OP_COMPOSE_NEW_MIME, "n" },
+#ifdef USE_AUTOCRYPT
+ { "autocrypt-menu", OP_COMPOSE_AUTOCRYPT_MENU, "o" },
+#endif
{ "postpone-message", OP_COMPOSE_POSTPONE_MESSAGE, "P" },
{ "edit-reply-to", OP_COMPOSE_EDIT_REPLY_TO, "r" },
{ "rename-attachment",OP_COMPOSE_RENAME_ATTACHMENT, "\017" },
diff --git a/mutt.h b/mutt.h
index 706c87fb..653eb3ae 100644
--- a/mutt.h
+++ b/mutt.h
@@ -822,9 +822,9 @@ typedef struct mutt_thread THREAD;
typedef struct header
{
- unsigned int security : 13; /* bit 0-9: flags
- bit 10-11: application.
- bit 12: traditional pgp.
+ unsigned int security : 14; /* bit 0-10: flags
+ bit 11-12: application.
+ bit 13: traditional pgp.
see: mutt_crypt.h pgplib.h, smime.h */
unsigned int mime : 1; /* has a MIME-Version header? */
diff --git a/mutt_crypt.h b/mutt_crypt.h
index bd49bad4..79182297 100644
--- a/mutt_crypt.h
+++ b/mutt_crypt.h
@@ -40,12 +40,14 @@
#define KEYBLOCK (1 << 6) /* KEY too generic? */
#define INLINE (1 << 7)
#define OPPENCRYPT (1 << 8) /* Opportunistic encrypt mode */
-#define AUTOCRYPT (1 << 9) /* TODO: should this include the ENCRYPT and SIGN flags */
+#define AUTOCRYPT (1 << 9) /* Message will be, or was Autocrypt encrypt+signed */
-#define APPLICATION_PGP (1 << 10)
-#define APPLICATION_SMIME (1 << 11)
+#define AUTOCRYPT_OVERRIDE (1 << 10) /* Indicates manual set/unset of encryption */
-#define PGP_TRADITIONAL_CHECKED (1 << 12)
+#define APPLICATION_PGP (1 << 11)
+#define APPLICATION_SMIME (1 << 12)
+
+#define PGP_TRADITIONAL_CHECKED (1 << 13)
#define PGPENCRYPT (APPLICATION_PGP | ENCRYPT)
#define PGPSIGN (APPLICATION_PGP | SIGN)