]> granicus.if.org Git - mutt/commitdiff
Add autocrypt line to the compose menu.
authorKevin McCarthy <kevin@8t8.us>
Fri, 19 Jul 2019 19:54:32 +0000 (12:54 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sat, 3 Aug 2019 21:08:09 +0000 (14:08 -0700)
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.

OPS
autocrypt/autocrypt.c
autocrypt/autocrypt.h
autocrypt/autocrypt_gpgme.c
autocrypt/autocrypt_private.h
compose.c
functions.h
mutt.h
mutt_crypt.h

diff --git a/OPS b/OPS
index 2fad8f12d8a5d3a86fe6dc429751029633661d6d..076b4079f041d3ed05e91e1152941ae384980109 100644 (file)
--- 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"
index 228c24a62d0bd8c648b410ec05049295dd9273f0..dd3ccb82eff6550eeea55db5799d208df265af4b 100644 (file)
@@ -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;
+}
index a2401bc3855a0ff862ca7c3dc6a09568ba00f6a9..2608277da3799b96d7140d9034b11c40b8c727aa 100644 (file)
@@ -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
index 952f648b45f1e1fc89d289e645de5fa5fd47eea1..84bb9ffc4c3a471ccd3f9ee33ed62d47aa76511e 100644 (file)
@@ -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;
+}
index 1ba519204dc29ab9d5eb21d1a02d0df2b66aa296..3e370da6236e56d36e590f7eaf0e202eb3625b4f 100644 (file)
@@ -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
index 4d1b713528e2440613c1a18184e3cf25724c7384..4ae322f64a746074607325d507dab348fc2d641b 100644 (file)
--- 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"
 #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
     }
   }
 
index 5b9459b5600eb0d41d59fb914638e3e8f097419c..6e9ba3905dcbd165b91ab3050fff4a4186b1f421 100644 (file)
@@ -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 706c87fb138350b7bfa89a66b889c449d98b0de6..653eb3ae402c8707b8d7f5af9fe338049b6a232d 100644 (file)
--- 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? */
index bd49bad4b83c571ae99ec4f43380faecec47a657..791822975ecef73740dfea6bf02aa12c7b48441c 100644 (file)
 #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)