]> granicus.if.org Git - mutt/commitdiff
Basic autocrypt account menu.
authorKevin McCarthy <kevin@8t8.us>
Mon, 29 Jul 2019 02:24:11 +0000 (19:24 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sat, 3 Aug 2019 21:08:09 +0000 (14:08 -0700)
Provide ability to create, delete, and toggle the prefer-encrypt and
enabled flag for an account.

Hook into the index via 'A' <autocrypt-acct-menu>.

15 files changed:
OPS
autocrypt/Makefile.am
autocrypt/autocrypt.c
autocrypt/autocrypt.h
autocrypt/autocrypt_acct_menu.c [new file with mode: 0644]
autocrypt/autocrypt_db.c
autocrypt/autocrypt_private.h
curs_main.c
doc/manual.xml.tail
functions.h
globals.h
init.h
keymap.c
keymap.h
po/POTFILES.in

diff --git a/OPS b/OPS
index 076b4079f041d3ed05e91e1152941ae384980109..a91a14abce540f476db98acf88e055fe55d578cf 100644 (file)
--- a/OPS
+++ b/OPS
@@ -3,6 +3,11 @@ OP_END_COND "end of conditional execution (noop)"
 OP_ATTACH_VIEW_MAILCAP "force viewing of attachment using mailcap"
 OP_ATTACH_VIEW_TEXT "view attachment as text"
 OP_ATTACH_COLLAPSE "Toggle display of subparts"
+OP_AUTOCRYPT_ACCT_MENU "manage autocrypt accounts"
+OP_AUTOCRYPT_CREATE_ACCT "create a new autocrypt account"
+OP_AUTOCRYPT_DELETE_ACCT "delete the current account"
+OP_AUTOCRYPT_TOGGLE_ACTIVE "toggle the current account active/inactive"
+OP_AUTOCRYPT_TOGGLE_PREFER "toggle the current account prefer-encrypt flag"
 OP_BOTTOM_PAGE "move to the bottom of the page"
 OP_BOUNCE_MESSAGE "remail a message to another user"
 OP_BROWSER_NEW_FILE "select a new file in this directory"
index d7f3f0daac9c0a1c8ad3d6b5b27b9b9bff5e8135..aefff20a198366cf018a05adf86e8114bdcf9b41 100644 (file)
@@ -8,4 +8,4 @@ AM_CPPFLAGS = -I$(top_srcdir) -I../intl
 noinst_LIBRARIES = libautocrypt.a
 
 libautocrypt_a_SOURCES = autocrypt.c autocrypt.h autocrypt_db.c autocrypt_private.h \
-       autocrypt_schema.c autocrypt_gpgme.c
+       autocrypt_schema.c autocrypt_gpgme.c autocrypt_acct_menu.c
index 826200355a74b172acba09e82d1ef2a756a4b2db..2c866fca95e1ccff4e7ddbc58dfc3d100f111950 100644 (file)
@@ -100,18 +100,22 @@ void mutt_autocrypt_cleanup (void)
   mutt_autocrypt_db_close ();
 }
 
-/* Creates a brand new account the first time autocrypt is initialized */
-int mutt_autocrypt_account_init (void)
+/* Creates a brand new account.
+ * This is used the first time autocrypt is initialized, and
+ * in the account menu. */
+int mutt_autocrypt_account_init (int prompt)
 {
   ADDRESS *addr = NULL;
   BUFFER *keyid = NULL, *keydata = NULL;
   AUTOCRYPT_ACCOUNT *account = NULL;
   int done = 0, rv = -1, prefer_encrypt = 0;
 
-  dprint (1, (debugfile, "In mutt_autocrypt_account_init\n"));
-  if (mutt_yesorno (_("Create an initial autocrypt account?"),
+  if (prompt)
+  {
+    if (mutt_yesorno (_("Create an initial autocrypt account?"),
                       MUTT_YES) != MUTT_YES)
-    return 0;
+      return 0;
+  }
 
   keyid = mutt_buffer_pool_get ();
   keydata = mutt_buffer_pool_get ();
@@ -152,6 +156,7 @@ int mutt_autocrypt_account_init (void)
   if (account)
   {
     mutt_error _("That email address already has an autocrypt account");
+    mutt_sleep (1);
     goto cleanup;
   }
 
index 787797778937a4cbec81648b5f2184ea9d90f299..a50ec31103ebfafb11d685263fb71768f4cf90c4 100644 (file)
@@ -80,5 +80,6 @@ int mutt_autocrypt_set_sign_as_default_key (HEADER *hdr);
 int mutt_autocrypt_write_autocrypt_header (ENVELOPE *env, FILE *fp);
 int mutt_autocrypt_write_gossip_headers (ENVELOPE *env, FILE *fp);
 int mutt_autocrypt_generate_gossip_list (HEADER *hdr);
+void mutt_autocrypt_account_menu (void);
 
 #endif
diff --git a/autocrypt/autocrypt_acct_menu.c b/autocrypt/autocrypt_acct_menu.c
new file mode 100644 (file)
index 0000000..dd1f0c5
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us>
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with this program; if not, write to the Free Software
+ *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "mutt.h"
+#include "mutt_menu.h"
+#include "mutt_idna.h"
+
+#include "autocrypt.h"
+#include "autocrypt_private.h"
+
+typedef struct entry
+{
+  int tagged;    /* TODO */
+  int num;
+  AUTOCRYPT_ACCOUNT *account;
+  ADDRESS *addr;
+} ENTRY;
+
+static const struct mapping_t AutocryptAcctHelp[] = {
+  { N_("Exit"),   OP_EXIT },
+  /* L10N: Autocrypt Account Menu Help line:
+     create new account
+  */
+  { N_("Create"),   OP_AUTOCRYPT_CREATE_ACCT },
+  /* L10N: Autocrypt Account Menu Help line:
+     delete account
+  */
+  { N_("Delete"),   OP_AUTOCRYPT_DELETE_ACCT },
+  /* L10N: Autocrypt Account Menu Help line:
+     toggle an account active/inactive
+  */
+  { N_("Tgl Active"),  OP_AUTOCRYPT_TOGGLE_ACTIVE },
+  /* L10N: Autocrypt Account Menu Help line:
+     toggle "prefer-encrypt" on an account
+  */
+  { N_("Prf Enc"), OP_AUTOCRYPT_TOGGLE_PREFER },
+  { N_("Help"),   OP_HELP },
+  { NULL,        0 }
+};
+
+static const char *account_format_str (char *dest, size_t destlen, size_t col,
+                                       int cols, char op, const char *src,
+                                       const char *fmt, const char *ifstring,
+                                       const char *elsestring,
+                                       unsigned long data, format_flag flags)
+{
+  ENTRY *entry = (ENTRY *)data;
+  char tmp[SHORT_STRING];
+
+  switch (op)
+  {
+    case 'a':
+      mutt_format_s (dest, destlen, fmt, entry->addr->mailbox);
+      break;
+    case 'k':
+      mutt_format_s (dest, destlen, fmt, entry->account->keyid);
+      break;
+    case 'n':
+      snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
+      snprintf (dest, destlen, tmp, entry->num);
+      break;
+    case 'p':
+      if (entry->account->prefer_encrypt)
+        /* L10N:
+           Autocrypt Account menu.
+           flag that an account has prefer-encrypt set
+        */
+        mutt_format_s (dest, destlen, fmt, _("prefer encrypt"));
+      else
+        /* L10N:
+           Autocrypt Account menu.
+           flag that an account has prefer-encrypt unset;
+           thus encryption will need to be manually enabled.
+        */
+        mutt_format_s (dest, destlen, fmt, _("manual encrypt"));
+      break;
+    case 's':
+      if (entry->account->enabled)
+        /* L10N:
+           Autocrypt Account menu.
+           flag that an account is enabled/active
+        */
+        mutt_format_s (dest, destlen, fmt, _("active"));
+      else
+        /* L10N:
+           Autocrypt Account menu.
+           flag that an account is disabled/inactive
+        */
+        mutt_format_s (dest, destlen, fmt, _("inactive"));
+      break;
+  }
+
+  return (src);
+}
+
+static void account_entry (char *s, size_t slen, MUTTMENU *m, int num)
+{
+  ENTRY *entry = &((ENTRY *) m->data)[num];
+
+  mutt_FormatString (s, slen, 0, MuttIndexWindow->cols,
+                     NONULL (AutocryptAcctFormat), account_format_str,
+                    (unsigned long) entry, MUTT_FORMAT_ARROWCURSOR);
+}
+
+static MUTTMENU *create_menu ()
+{
+  MUTTMENU *menu = NULL;
+  AUTOCRYPT_ACCOUNT **accounts = NULL;
+  ENTRY *entries = NULL;
+  int num_accounts = 0, i;
+  char *helpstr;
+
+  if (mutt_autocrypt_db_account_get_all (&accounts, &num_accounts) < 0)
+    return NULL;
+
+  menu = mutt_new_menu (MENU_AUTOCRYPT_ACCT);
+  menu->make_entry = account_entry;
+  /* menu->tag = account_tag; */
+  /* L10N:
+     Autocrypt Account Management Menu title
+  */
+  menu->title = _("Autocrypt Accounts");
+  helpstr = safe_malloc (STRING);
+  menu->help = mutt_compile_help (helpstr, STRING, MENU_AUTOCRYPT_ACCT,
+                                  AutocryptAcctHelp);
+
+  menu->data = entries = safe_calloc (num_accounts, sizeof(ENTRY));
+  menu->max = num_accounts;
+
+  for (i = 0; i < num_accounts; i++)
+  {
+    entries[i].num = i + 1;
+    /* note: we are transfering the account pointer to the entries
+     * array, and freeing the accounts array below.  the account
+     * will be freed in free_menu().
+     */
+    entries[i].account = accounts[i];
+
+    entries[i].addr = rfc822_new_address ();
+    entries[i].addr->mailbox = safe_strdup (accounts[i]->email_addr);
+    mutt_addrlist_to_local (entries[i].addr);
+  }
+  FREE (&accounts);
+
+  mutt_push_current_menu (menu);
+
+  return menu;
+}
+
+static void free_menu (MUTTMENU **menu)
+{
+  int i;
+  ENTRY *entries;
+
+  entries = (ENTRY *)(*menu)->data;
+  for (i = 0; i < (*menu)->max; i++)
+  {
+    mutt_autocrypt_db_account_free (&entries[i].account);
+    rfc822_free_address (&entries[i].addr);
+  }
+  FREE (&(*menu)->data);
+
+  mutt_pop_current_menu (*menu);
+  FREE (&(*menu)->help);
+  mutt_menuDestroy (menu);
+}
+
+static void toggle_active (ENTRY *entry)
+{
+  entry->account->enabled = !entry->account->enabled;
+  if (mutt_autocrypt_db_account_update (entry->account) != 0)
+  {
+    entry->account->enabled = !entry->account->enabled;
+    mutt_error _("Error updating account record");
+  }
+}
+
+static void toggle_prefer_encrypt (ENTRY *entry)
+{
+  entry->account->prefer_encrypt = !entry->account->prefer_encrypt;
+  if (mutt_autocrypt_db_account_update (entry->account))
+  {
+    entry->account->prefer_encrypt = !entry->account->prefer_encrypt;
+    mutt_error _("Error updating account record");
+  }
+}
+
+void mutt_autocrypt_account_menu (void)
+{
+  MUTTMENU *menu;
+  int done = 0, op;
+  ENTRY *entry;
+  char msg[SHORT_STRING];
+
+  if (!option (OPTAUTOCRYPT))
+    return;
+
+  if (mutt_autocrypt_init (0))
+    return;
+
+  menu = create_menu ();
+  if (!menu)
+    return;
+
+  while (!done)
+  {
+    switch ((op = mutt_menuLoop (menu)))
+    {
+      case OP_EXIT:
+        done = 1;
+        break;
+
+      case OP_AUTOCRYPT_CREATE_ACCT:
+        if (!mutt_autocrypt_account_init (0))
+        {
+          free_menu (&menu);
+          menu = create_menu ();
+        }
+        break;
+
+      case OP_AUTOCRYPT_DELETE_ACCT:
+        if (menu->data)
+        {
+          entry = (ENTRY *)(menu->data) + menu->current;
+          snprintf (msg, sizeof(msg),
+                    /* L10N:
+                       Confirms deleting an autocrypt account
+                    */
+                    _("Really delete account \"%s\"?"),
+                    entry->addr->mailbox);
+         if (mutt_yesorno (msg, MUTT_NO) != MUTT_YES)
+            break;
+
+          if (!mutt_autocrypt_db_account_delete (entry->account))
+          {
+            free_menu (&menu);
+            menu = create_menu ();
+          }
+        }
+        break;
+
+      case OP_AUTOCRYPT_TOGGLE_ACTIVE:
+        if (menu->data)
+        {
+          entry = (ENTRY *)(menu->data) + menu->current;
+          toggle_active (entry);
+          menu->redraw |= REDRAW_FULL;
+        }
+        break;
+
+      case OP_AUTOCRYPT_TOGGLE_PREFER:
+        if (menu->data)
+        {
+          entry = (ENTRY *)(menu->data) + menu->current;
+          toggle_prefer_encrypt (entry);
+          menu->redraw |= REDRAW_FULL;
+        }
+        break;
+    }
+  }
+
+  free_menu (&menu);
+}
index 7fad7068db897da49f1adccc6f83063800b45a01..cadd0dcdb8aa60230243e016cf88dc2bb4dc4780 100644 (file)
@@ -28,6 +28,8 @@
 /* Prepared statements */
 static sqlite3_stmt *AccountGetStmt;
 static sqlite3_stmt *AccountInsertStmt;
+static sqlite3_stmt *AccountUpdateStmt;
+static sqlite3_stmt *AccountDeleteStmt;
 static sqlite3_stmt *PeerGetStmt;
 static sqlite3_stmt *PeerInsertStmt;
 static sqlite3_stmt *PeerUpdateStmt;
@@ -74,7 +76,7 @@ int mutt_autocrypt_db_init (int can_create)
     if (autocrypt_db_create (mutt_b2s (db_path)))
       goto cleanup;
     /* Don't abort the whole init process because account creation failed */
-    mutt_autocrypt_account_init ();
+    mutt_autocrypt_account_init (1);
   }
   else
   {
@@ -108,6 +110,10 @@ void mutt_autocrypt_db_close (void)
   AccountGetStmt = NULL;
   sqlite3_finalize (AccountInsertStmt);
   AccountInsertStmt = NULL;
+  sqlite3_finalize (AccountUpdateStmt);
+  AccountUpdateStmt = NULL;
+  sqlite3_finalize (AccountDeleteStmt);
+  AccountDeleteStmt = NULL;
 
   sqlite3_finalize (PeerGetStmt);
   PeerGetStmt = NULL;
@@ -307,6 +313,159 @@ cleanup:
   return rv;
 }
 
+int mutt_autocrypt_db_account_update (AUTOCRYPT_ACCOUNT *acct)
+{
+  int rv = -1;
+
+  if (!AccountUpdateStmt)
+  {
+    if (sqlite3_prepare_v3 (
+          AutocryptDB,
+          "UPDATE account SET "
+          "keyid = ?, "
+          "keydata = ?, "
+          "prefer_encrypt = ?, "
+          "enabled = ? "
+          "WHERE email_addr = ?;",
+          -1,
+          SQLITE_PREPARE_PERSISTENT,
+          &AccountUpdateStmt,
+          NULL) != SQLITE_OK)
+      goto cleanup;
+  }
+
+  if (sqlite3_bind_text (AccountUpdateStmt,
+                         1,
+                         acct->keyid,
+                         -1,
+                         SQLITE_STATIC) != SQLITE_OK)
+    goto cleanup;
+  if (sqlite3_bind_text (AccountUpdateStmt,
+                         2,
+                         acct->keydata,
+                         -1,
+                         SQLITE_STATIC) != SQLITE_OK)
+    goto cleanup;
+  if (sqlite3_bind_int (AccountUpdateStmt,
+                        3,
+                        acct->prefer_encrypt) != SQLITE_OK)
+    goto cleanup;
+  if (sqlite3_bind_int (AccountUpdateStmt,
+                        4,
+                        acct->enabled) != SQLITE_OK)
+    goto cleanup;
+  if (sqlite3_bind_text (AccountUpdateStmt,
+                         5,
+                         acct->email_addr,
+                         -1,
+                         SQLITE_STATIC) != SQLITE_OK)
+    goto cleanup;
+
+  if (sqlite3_step (AccountUpdateStmt) != SQLITE_DONE)
+    goto cleanup;
+
+  rv = 0;
+
+cleanup:
+  sqlite3_reset (AccountUpdateStmt);
+  return rv;
+}
+
+int mutt_autocrypt_db_account_delete (AUTOCRYPT_ACCOUNT *acct)
+{
+  int rv = -1;
+
+  if (!AccountDeleteStmt)
+  {
+    if (sqlite3_prepare_v3 (
+          AutocryptDB,
+          "DELETE from account "
+          "WHERE email_addr = ?;",
+          -1,
+          SQLITE_PREPARE_PERSISTENT,
+          &AccountDeleteStmt,
+          NULL) != SQLITE_OK)
+      goto cleanup;
+  }
+
+  if (sqlite3_bind_text (AccountDeleteStmt,
+                         1,
+                         acct->email_addr,
+                         -1,
+                         SQLITE_STATIC) != SQLITE_OK)
+    goto cleanup;
+
+  if (sqlite3_step (AccountDeleteStmt) != SQLITE_DONE)
+    goto cleanup;
+
+  rv = 0;
+
+cleanup:
+  sqlite3_reset (AccountDeleteStmt);
+  return rv;
+}
+
+int mutt_autocrypt_db_account_get_all (AUTOCRYPT_ACCOUNT ***accounts, int *num_accounts)
+{
+  int rv = -1, result;
+  sqlite3_stmt *stmt = NULL;
+  AUTOCRYPT_ACCOUNT **results = NULL, *account;
+  int results_len = 0, results_count = 0;
+
+  *accounts = NULL;
+  *num_accounts = 0;
+
+  /* Note, speed is not of the essence for the account management screen,
+   * so we don't bother with a persistent prepared statement */
+  if (sqlite3_prepare_v2 (
+        AutocryptDB,
+        "SELECT "
+        "email_addr, "
+        "keyid, "
+        "keydata, "
+        "prefer_encrypt, "
+        "enabled "
+        "FROM account "
+        "ORDER BY email_addr",
+        -1,
+        &stmt,
+        NULL) != SQLITE_OK)
+    goto cleanup;
+
+  while ((result = sqlite3_step (stmt)) == SQLITE_ROW)
+  {
+    if (results_count == results_len)
+    {
+      results_len += 5;
+      safe_realloc (&results, results_len * sizeof(AUTOCRYPT_ACCOUNT *));
+    }
+
+    results[results_count++] = account = mutt_autocrypt_db_account_new ();
+
+    account->email_addr = strdup_column_text (stmt, 0);
+    account->keyid = strdup_column_text (stmt, 1);
+    account->keydata = strdup_column_text (stmt, 2);
+    account->prefer_encrypt = sqlite3_column_int (stmt, 3);
+    account->enabled = sqlite3_column_int (stmt, 4);
+  }
+
+  if (result == SQLITE_DONE)
+  {
+    *accounts = results;
+    rv = *num_accounts = results_count;
+  }
+  else
+  {
+    while (results_count > 0)
+      mutt_autocrypt_db_account_free (&results[--results_count]);
+    FREE (&results);
+  }
+
+cleanup:
+  sqlite3_finalize (stmt);
+  return rv;
+}
+
 AUTOCRYPT_PEER *mutt_autocrypt_db_peer_new (void)
 {
   return safe_calloc (1, sizeof(AUTOCRYPT_PEER));
index 1c8a038f3a4299567f4d5de1fde2f7141d2fc575..96c487f54f255892a1a17754d58b2d6edf5458fd 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <sqlite3.h>
 
-int mutt_autocrypt_account_init (void);
+int mutt_autocrypt_account_init (int prompt);
 
 int mutt_autocrypt_db_init (int can_create);
 void mutt_autocrypt_db_close (void);
@@ -33,6 +33,9 @@ void mutt_autocrypt_db_account_free (AUTOCRYPT_ACCOUNT **account);
 int mutt_autocrypt_db_account_get (ADDRESS *addr, AUTOCRYPT_ACCOUNT **account);
 int mutt_autocrypt_db_account_insert (ADDRESS *addr, const char *keyid,
                                       const char *keydata, int prefer_encrypt);
+int mutt_autocrypt_db_account_update (AUTOCRYPT_ACCOUNT *acct);
+int mutt_autocrypt_db_account_delete (AUTOCRYPT_ACCOUNT *acct);
+int mutt_autocrypt_db_account_get_all (AUTOCRYPT_ACCOUNT ***accounts, int *num_accounts);
 
 AUTOCRYPT_PEER *mutt_autocrypt_db_peer_new (void);
 void mutt_autocrypt_db_peer_free (AUTOCRYPT_PEER **peer);
index 2054f42d52cebe7cab376cc335e928f081baae21..919cf15405378b5913767e0c3c8682241abc2b61 100644 (file)
 #include "monitor.h"
 #endif
 
+#ifdef USE_AUTOCRYPT
+#include "autocrypt.h"
+#endif
+
 #include "mutt_crypt.h"
 
 
@@ -2562,6 +2566,13 @@ int mutt_index_menu (void)
         mutt_reflow_windows();
        break;
 #endif
+
+#ifdef USE_AUTOCRYPT
+      case OP_AUTOCRYPT_ACCT_MENU:
+        mutt_autocrypt_account_menu ();
+        break;
+#endif
+
       default:
        if (menu->menu == MENU_MAIN)
          km_error_key (MENU_MAIN);
index d6da22e5142638753f1b2756382ae26f8074773b..1ba52231816d74f07a390d8fac40573d9527fb3b 100644 (file)
@@ -24,6 +24,7 @@ __print_map(pgp)
 __print_map(smime)
 __print_map(mixmaster)
 __print_map(editor)
+__print_map(autocrypt account)
 
 </sect1>
 
index 6e9ba3905dcbd165b91ab3050fff4a4186b1f421..419dfc507063e0c615bb92640d69fc57305abd42 100644 (file)
@@ -86,6 +86,9 @@ const struct binding_t OpGeneric[] = { /* map: generic */
 
 const struct binding_t OpMain[] = { /* map: index */
   { "create-alias",            OP_CREATE_ALIAS,                "a" },
+#ifdef USE_AUTOCRYPT
+  { "autocrypt-acct-menu",     OP_AUTOCRYPT_ACCT_MENU,         "A" },
+#endif
   { "bounce-message",          OP_BOUNCE_MESSAGE,              "b" },
   { "break-thread",            OP_MAIN_BREAK_THREAD,           "#" },
   { "change-folder",           OP_MAIN_CHANGE_FOLDER,          "c" },
@@ -500,3 +503,13 @@ const struct binding_t OpMix[] = { /* map: mixmaster */
   { NULL,              0,              NULL }
 };
 #endif /* MIXMASTER */
+
+#ifdef USE_AUTOCRYPT
+const struct binding_t OpAutocryptAcct[] = { /* map: autocrypt account */
+  { "create-account",        OP_AUTOCRYPT_CREATE_ACCT,    "c" },
+  { "delete-account",        OP_AUTOCRYPT_DELETE_ACCT,    "D" },
+  { "toggle-active",         OP_AUTOCRYPT_TOGGLE_ACTIVE,  "a" },
+  { "toggle-prefer-encrypt", OP_AUTOCRYPT_TOGGLE_PREFER,  "p" },
+  { NULL,                    0,                            NULL }
+};
+#endif
index 43de667115946f7809917f26fae96d5233159614..b69d42ea176cab67fe0850c39819aff48b67a4e5 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -41,6 +41,7 @@ WHERE char *AttributionLocale;
 WHERE char *AttachCharset;
 WHERE char *AttachFormat;
 #ifdef USE_AUTOCRYPT
+WHERE char *AutocryptAcctFormat;
 WHERE char *AutocryptDir;
 WHERE char *AutocryptSignAs;  /* This is used in crypt-gpgme.c */
 WHERE char *AutocryptDefaultKey;  /* Used for postponing messages */
diff --git a/init.h b/init.h
index c2b8fa6d30e00adf908e26d5799ad43fe7e291d1..aeef569ef695313f7008121c65064b354320dbeb 100644 (file)
--- a/init.h
+++ b/init.h
@@ -325,6 +325,20 @@ struct option_t MuttVars[] = {
   ** passive encryption protection with keys exchanged via headers.
   ** TODO: add a section in the manual describing this is more detail.
   */
+  { "autocrypt_acct_format", DT_STR, R_MENU, {.p=&AutocryptAcctFormat}, {.p="%4n %-30a %20p %10s"} },
+  /*
+  ** .pp
+  ** This variable describes the format of the ``autocrypt account'' menu.
+  ** The following \fCprintf(3)\fP-style sequences are understood
+  ** .dl
+  ** .dt %a  .dd email address
+  ** .dt %k  .dd gpg keyid
+  ** .dt %n  .dd current entry number
+  ** .dt %p  .dd prefer-encrypt flag
+  ** .dt %s  .dd status flag (active/inactive)
+  ** .de
+  ** .pp
+  */
   { "autocrypt_dir",   DT_PATH, R_NONE, {.p=&AutocryptDir}, {.p="~/.mutt/autocrypt"} },
   /*
   ** .pp
index eabd48ad7fa617fcf941e0f060d95d156ef7b67c..2a9fcf0b5684144dbfff46041fa0ca97651c824b 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -770,6 +770,10 @@ void km_init (void)
   km_bindkey ("l", MENU_MIX, OP_MIX_CHAIN_NEXT);
 #endif
 
+#ifdef USE_AUTOCRYPT
+  create_bindings (OpAutocryptAcct, MENU_AUTOCRYPT_ACCT);
+#endif
+
   /* bindings for the line editor */
   create_bindings (OpEditor, MENU_EDITOR);
 
@@ -1027,6 +1031,11 @@ const struct binding_t *km_get_table (int menu)
       return OpMix;
 #endif
 
+#ifdef USE_AUTOCRYPT
+    case MENU_AUTOCRYPT_ACCT:
+      return OpAutocryptAcct;
+#endif
+
   }
   return NULL;
 }
index 0f11a98492dbd39fdcf437f255a8319165a1b86e..cffafa6c6ffae0e5a32438962faa0deec9312a60 100644 (file)
--- a/keymap.h
+++ b/keymap.h
@@ -77,6 +77,9 @@ enum
   MENU_MIX,
 #endif
 
+#ifdef USE_AUTOCRYPT
+  MENU_AUTOCRYPT_ACCT,
+#endif
 
 
   MENU_MAX
@@ -118,6 +121,10 @@ extern const struct binding_t OpSmime[];
 extern const struct binding_t OpMix[];
 #endif
 
+#ifdef USE_AUTOCRYPT
+extern const struct binding_t OpAutocryptAcct[];
+#endif
+
 #include "keymap_defs.h"
 
 #endif /* KEYMAP_H */
index 9f7a544f106055a536198c3e2ac827c24d7d2a49..8f1f4f80df18a58229fbdcf2db0d1980e3305e66 100644 (file)
@@ -4,6 +4,7 @@ alias.c
 attach.c
 autocrypt/autocrypt.c
 autocrypt/autocrypt_db.c
+autocrypt/autocrypt_acct_menu.c
 autocrypt/autocrypt_gpgme.c
 autocrypt/autocrypt_schema.c
 browser.c