]> granicus.if.org Git - neomutt/commitdiff
Add autocrypt line to the compose menu
authorKevin McCarthy <kevin@8t8.us>
Fri, 19 Jul 2019 19:54:32 +0000 (12:54 -0700)
committerRichard Russon <rich@flatcap.org>
Mon, 19 Aug 2019 23:14:27 +0000 (00:14 +0100)
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.

Co-authored-by: Richard Russon <rich@flatcap.org>
autocrypt/autocrypt.c
autocrypt/autocrypt.h
autocrypt/autocrypt_gpgme.c
autocrypt/autocrypt_private.h
compose.c
email/email.h
functions.h
ncrypt/ncrypt.h
opcodes.h

index feb204e8b480d57ae8bd1b44218d1a7205191c37..cf5d7c1934cfc0478c3463b0244ccbc04cb546cd 100644 (file)
@@ -35,6 +35,7 @@
 #include "curs_lib.h"
 #include "globals.h"
 #include "mutt_curses.h"
+#include "ncrypt/ncrypt.h"
 #include "send.h"
 
 static int autocrypt_dir_init(int can_create)
@@ -448,3 +449,76 @@ cleanup:
 
   return rv;
 }
+
+enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *hdr)
+{
+  enum AutocryptRec rv = AUTOCRYPT_REC_OFF;
+  struct AutocryptAccount *account = NULL;
+  struct AutocryptPeer *peer = NULL;
+  struct Address *recip = NULL;
+  int all_encrypt = 1, has_discourage = 0;
+
+  if (!C_Autocrypt || mutt_autocrypt_init(0) || !hdr)
+    return AUTOCRYPT_REC_OFF;
+
+  struct Address *from = TAILQ_FIRST(&hdr->env->from);
+  if (!from || TAILQ_NEXT(from, entries))
+    return AUTOCRYPT_REC_OFF;
+
+  if (hdr->security & APPLICATION_SMIME)
+    return AUTOCRYPT_REC_OFF;
+
+  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
+    goto cleanup;
+
+  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
+
+  mutt_addrlist_copy(&recips, &hdr->env->to, false);
+  mutt_addrlist_copy(&recips, &hdr->env->cc, false);
+  mutt_addrlist_copy(&recips, &hdr->env->bcc, false);
+
+  rv = AUTOCRYPT_REC_NO;
+  if (TAILQ_EMPTY(&recips))
+    goto cleanup;
+
+  TAILQ_FOREACH(recip, &recips, entries)
+  {
+    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);
+  mutt_addrlist_clear(&recips);
+  mutt_autocrypt_db_peer_free(&peer);
+  return rv;
+}
index 82dc6a9b1e9b73f397737b41ed7a4d2a704e1ce7..d3f10fa4f1e71ca07c353cf7f5a760c244005837 100644 (file)
@@ -67,9 +67,19 @@ struct AutocryptGossipHistory
   char *gossip_keydata;
 };
 
+enum AutocryptRec
+{
+  AUTOCRYPT_REC_OFF,
+  AUTOCRYPT_REC_NO,
+  AUTOCRYPT_REC_DISCOURAGE,
+  AUTOCRYPT_REC_AVAILABLE,
+  AUTOCRYPT_REC_YES
+};
+
 int mutt_autocrypt_init (int);
 void mutt_autocrypt_cleanup (void);
 int mutt_autocrypt_process_autocrypt_header (struct Email *hdr, struct Envelope *env);
 int mutt_autocrypt_process_gossip_header (struct Email *hdr, struct Envelope *env);
+enum AutocryptRec mutt_autocrypt_ui_recommendation (struct Email *hdr);
 
 #endif /* MUTT_AUTOCRYPT_AUTOCRYPT_H */
index a4259a8cabf2ff2ff51ed86bea90a168dbc598a3..f8c33be3a0fb9db39291a2ae75b29eb335055061 100644 (file)
@@ -205,3 +205,28 @@ 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 258e4d0850f5c53c81e960f0d806fc3bb48a3490..8481d4536638a434083309a9d8e981aafe6fdb54 100644 (file)
@@ -63,5 +63,6 @@ int mutt_autocrypt_schema_update (void);
 int mutt_autocrypt_gpgme_init (void);
 int mutt_autocrypt_gpgme_create_key (struct Address *addr, struct Buffer *keyid, struct Buffer *keydata);
 int mutt_autocrypt_gpgme_import_key (const char *keydata, struct Buffer *keyid);
+int mutt_autocrypt_gpgme_is_valid_key (const char *keyid);
 
 #endif /* MUTT_AUTOCRYPT_AUTOCRYPT_PRIVATE_H */
index 32a28d58853f376ae2f2a11c8fb2b5ce9309a6df..fc4d5dc4dbbdeebcd97eb627c306d2c6a212cac4 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -85,6 +85,9 @@
 #ifdef USE_IMAP
 #include "imap/imap.h"
 #endif
+#ifdef USE_AUTOCRYPT
+#include "autocrypt/autocrypt.h"
+#endif
 
 /* These Config Variables are only used in compose.c */
 char *C_ComposeFormat; ///< Config: printf-like format string for the Compose panel's status bar
@@ -121,15 +124,19 @@ enum HeaderField
 #endif
   HDR_CRYPT,     ///< "Security:" field (encryption/signing info)
   HDR_CRYPTINFO, ///< "Sign as:" field (encryption/signing info)
+#ifdef USE_AUTOCRYPT
+  HDR_AUTOCRYPT,
+#endif
 #ifdef USE_NNTP
   HDR_NEWSGROUPS, ///< "Newsgroups:" field
   HDR_FOLLOWUPTO, ///< "Followup-To:" field
   HDR_XCOMMENTTO, ///< "X-Comment-To:" field
 #endif
-  HDR_ATTACH = (HDR_FCC + 5), ///< Position to start printing the attachments
+  HDR_ATTACH_TITLE, /* the "-- Attachments" line */
+  HDR_ATTACH        /* where to start printing the attachments */
 };
 
-int HeaderPadding[HDR_XCOMMENTTO + 1] = { 0 };
+int HeaderPadding[HDR_ATTACH_TITLE] = { 0 };
 int MaxHeaderWidth = 0;
 
 #define HDR_XOFFSET MaxHeaderWidth
@@ -164,6 +171,12 @@ 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: "),
+#ifdef USE_AUTOCRYPT
+  /* L10N:
+     The compose menu autocrypt line
+   */
+  N_("Autocrypt: "),
+#endif
 #ifdef USE_NNTP
   /* L10N: Compose menu field.  May not want to translate. */
   N_("Newsgroups: "),
@@ -202,6 +215,41 @@ static struct Mapping ComposeNewsHelp[] = {
 };
 #endif
 
+#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
+
+struct ComposeRedrawData
+{
+  struct Email *email;
+  char *fcc;
+#ifdef USE_AUTOCRYPT
+  enum AutocryptRec autocrypt_rec;
+  int autocrypt_rec_override;
+#endif
+};
+
 /**
  * calc_header_width_padding - Calculate the width needed for the compose labels
  * @param idx      Store the result at this index of HeaderPadding
@@ -235,15 +283,19 @@ static void init_header_padding(void)
     return;
   done = true;
 
-  for (int i = 0; i <= HDR_XCOMMENTTO; i++)
+  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
+  {
+    if (i == HDR_CRYPTINFO)
+      continue;
     calc_header_width_padding(i, _(Prompts[i]), true);
+  }
 
   /* 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]), false);
 
-  for (int i = 0; i <= HDR_XCOMMENTTO; i++)
+  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
   {
     HeaderPadding[i] += MaxHeaderWidth;
     if (HeaderPadding[i] < 0)
@@ -263,12 +315,51 @@ static void snd_make_entry(char *buf, size_t buflen, struct Menu *menu, int line
                       MUTT_FORMAT_STAT_FILE | MUTT_FORMAT_ARROWCURSOR);
 }
 
+#ifdef USE_AUTOCRYPT
+static void autocrypt_compose_menu(struct Email *e)
+{
+  /* L10N:
+     The compose menu autocrypt prompt.
+     (e)ncrypt enables encryption via autocrypt.
+     (c)lear sets cleartext.
+     (a)utomatic defers to the recommendation.
+  */
+  const char *prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic? ");
+
+  /* L10N:
+     The letter corresponding to the compose menu autocrypt prompt
+     (e)ncrypt, (c)lear, (a)utomatic
+   */
+  const char *letters = "eca";
+
+  int choice = mutt_multi_choice(prompt, letters);
+  switch (choice)
+  {
+    case 1:
+      e->security |= (SEC_AUTOCRYPT | SEC_AUTOCRYPT_OVERRIDE);
+      e->security &= ~(SEC_ENCRYPT | SEC_SIGN | SEC_OPPENCRYPT);
+      break;
+    case 2:
+      e->security &= ~SEC_AUTOCRYPT;
+      e->security |= SEC_AUTOCRYPT_OVERRIDE;
+      break;
+    case 3:
+      e->security &= ~SEC_AUTOCRYPT_OVERRIDE;
+      if (C_CryptOpportunisticEncrypt)
+        e->security |= SEC_OPPENCRYPT;
+      break;
+  }
+}
+#endif
+
 /**
  * redraw_crypt_lines - Update the encryption info in the compose window
  * @param e Email
  */
-static void redraw_crypt_lines(struct Email *e)
+static void redraw_crypt_lines(struct ComposeRedrawData *rd)
 {
+  struct Email *e = rd->email;
+
   SET_COLOR(MT_COLOR_COMPOSE_HEADER);
   mutt_window_mvprintw(MuttIndexWindow, HDR_CRYPT, 0, "%*s",
                        HeaderPadding[HDR_CRYPT], _(Prompts[HDR_CRYPT]));
@@ -349,6 +440,64 @@ static void redraw_crypt_lines(struct Email *e)
     NORMAL_COLOR;
     printw("%s", NONULL(C_SmimeEncryptWith));
   }
+
+#ifdef USE_AUTOCRYPT
+  mutt_window_move(MuttIndexWindow, HDR_AUTOCRYPT, 0);
+  mutt_window_clrtoeol(MuttIndexWindow);
+  SET_COLOR(MT_COLOR_COMPOSE_HEADER);
+  printw("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
+  NORMAL_COLOR;
+  if (C_Autocrypt && (e->security & SEC_AUTOCRYPT))
+  {
+    SET_COLOR(MT_COLOR_COMPOSE_SECURITY_ENCRYPT);
+    addstr(_("Encrypt"));
+  }
+  else
+  {
+    SET_COLOR(MT_COLOR_COMPOSE_SECURITY_NONE);
+    addstr(_("Off"));
+  }
+
+  SET_COLOR(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(struct ComposeRedrawData *rd)
+{
+  struct Email *e = rd->email;
+
+  if (C_CryptOpportunisticEncrypt)
+    crypt_opportunistic_encrypt(e);
+
+#ifdef USE_AUTOCRYPT
+  rd->autocrypt_rec = mutt_autocrypt_ui_recommendation(e);
+
+  /* Anything that enables SEC_ENCRYPT or SEC_SIGN, or turns on SMIME
+   * overrides autocrypt, be it oppenc or the user having turned on
+   * those flags manually. */
+  if (e->security & (SEC_ENCRYPT | SEC_SIGN | APPLICATION_SMIME))
+    e->security &= ~(SEC_AUTOCRYPT | SEC_AUTOCRYPT_OVERRIDE);
+  else
+  {
+    if (!(e->security & SEC_AUTOCRYPT_OVERRIDE))
+    {
+      if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
+        e->security |= SEC_AUTOCRYPT;
+      else
+        e->security &= ~SEC_AUTOCRYPT;
+    }
+  }
+  /* TODO:
+   * - autocrypt menu for manually enabling/disabling (turns on override)
+   * - deal with pgp and smime menu and their effects on security->SEC_AUTOCRYPT
+   *   when encryption or signing is enabled or if switch to smime mode
+   */
+#endif
+
+  redraw_crypt_lines(rd);
 }
 
 #ifdef MIXMASTER
@@ -454,8 +603,11 @@ static void draw_envelope_addr(int line, struct AddressList *al)
  * @param e Email
  * @param fcc Fcc field
  */
-static void draw_envelope(struct Email *e, char *fcc)
+static void draw_envelope(struct ComposeRedrawData *rd)
 {
+  struct Email *e = rd->email;
+  char *fcc = rd->fcc;
+
   draw_envelope_addr(HDR_FROM, &e->env->from);
 #ifdef USE_NNTP
   if (!OptNewsSend)
@@ -498,14 +650,14 @@ static void draw_envelope(struct Email *e, char *fcc)
   mutt_paddstr(W, fcc);
 
   if (WithCrypto)
-    redraw_crypt_lines(e);
+    redraw_crypt_lines(rd);
 
 #ifdef MIXMASTER
   redraw_mix_line(&e->chain);
 #endif
 
   SET_COLOR(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;
@@ -662,15 +814,6 @@ static void update_idx(struct Menu *menu, struct AttachCtx *actx, struct AttachP
   menu->current = actx->vcount - 1;
 }
 
-/**
- * struct ComposeRedrawData - Keep track when the compose screen needs redrawing
- */
-struct ComposeRedrawData
-{
-  struct Email *email;
-  char *fcc;
-};
-
 static void compose_status_line(char *buf, size_t buflen, size_t col, int cols,
                                 struct Menu *menu, const char *p);
 
@@ -688,7 +831,7 @@ static void compose_custom_redraw(struct Menu *menu)
   {
     menu_redraw_full(menu);
 
-    draw_envelope(rd->email, rd->fcc);
+    draw_envelope(rd);
     menu->offset = HDR_ATTACH;
     menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH;
   }
@@ -890,7 +1033,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
   int rc = -1;
   bool loop = true;
   bool fcc_set = false; /* has the user edited the Fcc: field ? */
-  struct ComposeRedrawData rd;
+  struct ComposeRedrawData rd = { 0 };
 #ifdef USE_NNTP
   bool news = OptNewsSend; /* is it a news article ? */
 #endif
@@ -918,6 +1061,8 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
   actx->email = e;
   mutt_update_compose_menu(actx, menu, true);
 
+  update_crypt_info(&rd);
+
   while (loop)
   {
 #ifdef USE_NNTP
@@ -928,6 +1073,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
     {
       case OP_COMPOSE_EDIT_FROM:
         edit_address_list(HDR_FROM, &e->env->from);
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 
@@ -937,11 +1083,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
           break;
 #endif
         edit_address_list(HDR_TO, &e->env->to);
-        if (C_CryptOpportunisticEncrypt)
-        {
-          crypt_opportunistic_encrypt(e);
-          redraw_crypt_lines(e);
-        }
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 
@@ -951,11 +1093,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
           break;
 #endif
         edit_address_list(HDR_BCC, &e->env->bcc);
-        if (C_CryptOpportunisticEncrypt)
-        {
-          crypt_opportunistic_encrypt(e);
-          redraw_crypt_lines(e);
-        }
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 
@@ -965,11 +1103,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
           break;
 #endif
         edit_address_list(HDR_CC, &e->env->cc);
-        if (C_CryptOpportunisticEncrypt)
-        {
-          crypt_opportunistic_encrypt(e);
-          redraw_crypt_lines(e);
-        }
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 #ifdef USE_NNTP
@@ -1087,8 +1221,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
             mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
             FREE(&err);
           }
-          if (C_CryptOpportunisticEncrypt)
-            crypt_opportunistic_encrypt(e);
+          update_crypt_info(&rd);
         }
         else
         {
@@ -1953,11 +2086,10 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
           }
           e->security &= ~APPLICATION_SMIME;
           e->security |= APPLICATION_PGP;
-          crypt_opportunistic_encrypt(e);
-          redraw_crypt_lines(e);
+          update_crypt_info(&rd);
         }
         e->security = crypt_pgp_send_menu(e);
-        redraw_crypt_lines(e);
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 
@@ -1987,11 +2119,10 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
           }
           e->security &= ~APPLICATION_PGP;
           e->security |= APPLICATION_SMIME;
-          crypt_opportunistic_encrypt(e);
-          redraw_crypt_lines(e);
+          update_crypt_info(&rd);
         }
         e->security = crypt_smime_send_menu(e);
-        redraw_crypt_lines(e);
+        update_crypt_info(&rd);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
 
@@ -2000,6 +2131,28 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e
         mix_make_chain(&e->chain);
         mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
         break;
+#endif
+#ifdef USE_AUTOCRYPT
+      case OP_COMPOSE_AUTOCRYPT_MENU:
+        if ((WithCrypto & APPLICATION_SMIME) && (e->security & APPLICATION_SMIME))
+        {
+          if (e->security & (SEC_ENCRYPT | SEC_SIGN))
+          {
+            if (mutt_yesorno(_("S/MIME already selected. Clear & continue ? "), MUTT_YES) != MUTT_YES)
+            {
+              mutt_clear_error();
+              break;
+            }
+            e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
+          }
+          e->security &= ~APPLICATION_SMIME;
+          e->security |= APPLICATION_PGP;
+          update_crypt_info(&rd);
+        }
+        autocrypt_compose_menu(e);
+        update_crypt_info(&rd);
+        mutt_message_hook(NULL, e, MUTT_SEND2_HOOK);
+        break;
 #endif
     }
   }
index 6a2db383c3f754b3d0897ec794994d5ae4a81020..49c51c0e5f6c2c8468ea10074a6f401e6c3817ed 100644 (file)
@@ -38,7 +38,7 @@ struct Notify;
  */
 struct Email
 {
-  SecurityFlags security;      ///< bit 0-9: flags, bit 10,11: application, bit 12 traditional pgp
+  SecurityFlags security;      ///< bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp
                                ///< See: ncrypt/ncrypt.h pgplib.h, smime.h
 
   bool mime            : 1;    ///< Has a MIME-Version header?
index bfb5b9c23aa5444f0610609b0662f8d29d478953..b889ebfc8c0341f91aec82f565f8c85b7590f20f 100644 (file)
@@ -451,6 +451,9 @@ const struct Binding OpCompose[] = { /* map: compose */
   { "attach-message",        OP_COMPOSE_ATTACH_MESSAGE,      "A" },
 #ifdef USE_NNTP
   { "attach-news-message",   OP_COMPOSE_ATTACH_NEWS_MESSAGE, NULL },
+#endif
+#ifdef USE_AUTOCRYPT
+  { "autocrypt-menu",        OP_COMPOSE_AUTOCRYPT_MENU,      "o" },
 #endif
   { "copy-file",             OP_SAVE,                        "C" },
   { "detach-file",           OP_DELETE,                      "D" },
index 81f7d158ec192281e7f0022d567f017507c21812..a69e2ca6e9c427c967096596db0901b1a71beb40 100644 (file)
@@ -128,12 +128,14 @@ typedef uint16_t SecurityFlags;           ///< Flags, e.g. #SEC_ENCRYPT
 #define SEC_KEYBLOCK            (1 << 6)  ///< Email has a key attached
 #define SEC_INLINE              (1 << 7)  ///< Email has an inline signature
 #define SEC_OPPENCRYPT          (1 << 8)  ///< Opportunistic encrypt mode
-#define SEC_AUTOCRYPT           (1 << 9)  ///< TODO: should this include the SEC_ENCRYPT and SEC_SIGN flags
-#define APPLICATION_PGP         (1 << 10) ///< Use PGP to encrypt/sign
-#define APPLICATION_SMIME       (1 << 11) ///< Use SMIME to encrypt/sign
-#define PGP_TRADITIONAL_CHECKED (1 << 12) ///< Email has a traditional (inline) signature
+#define SEC_AUTOCRYPT           (1 << 9)  ///< Message will be, or was Autocrypt encrypt+signed
+#define SEC_AUTOCRYPT_OVERRIDE  (1 << 10) ///< Indicates manual set/unset of encryption
 
-#define SEC_ALL_FLAGS          ((1 << 13) - 1)
+#define APPLICATION_PGP         (1 << 11) ///< Use PGP to encrypt/sign
+#define APPLICATION_SMIME       (1 << 12) ///< Use SMIME to encrypt/sign
+#define PGP_TRADITIONAL_CHECKED (1 << 13) ///< Email has a traditional (inline) signature
+
+#define SEC_ALL_FLAGS          ((1 << 14) - 1)
 
 #define PGP_ENCRYPT  (APPLICATION_PGP | SEC_ENCRYPT)
 #define PGP_SIGN     (APPLICATION_PGP | SEC_SIGN)
index 6e7bd22ae109ebbe22bce6225efd0ea24f62a11f..d9bab1d8833a715280f0583242f6dcb708a4d68a 100644 (file)
--- a/opcodes.h
+++ b/opcodes.h
@@ -44,6 +44,7 @@
   _fmt(OP_CHECK_STATS,                    N_("calculate message statistics for all mailboxes")) \
   _fmt(OP_COMPOSE_ATTACH_FILE,            N_("attach files to this message")) \
   _fmt(OP_COMPOSE_ATTACH_MESSAGE,         N_("attach messages to this message")) \
+  _fmt(OP_COMPOSE_AUTOCRYPT_MENU,         N_("show autocrypt compose menu options")) \
   _fmt(OP_COMPOSE_ATTACH_NEWS_MESSAGE,    N_("attach news articles to this message")) \
   _fmt(OP_COMPOSE_EDIT_BCC,               N_("edit the BCC list")) \
   _fmt(OP_COMPOSE_EDIT_CC,                N_("edit the CC list")) \