NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
autocrypt.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <errno.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include "autocrypt_private.h"
34 #include "mutt/mutt.h"
35 #include "address/lib.h"
36 #include "config/lib.h"
37 #include "email/lib.h"
38 #include "autocrypt.h"
39 #include "curs_lib.h"
40 #include "globals.h"
41 #include "mutt_curses.h"
42 #include "muttlib.h"
43 #include "mx.h"
44 #include "ncrypt/ncrypt.h"
45 #include "options.h"
46 #include "send.h"
47 
54 static int autocrypt_dir_init(bool can_create)
55 {
56  int rc = 0;
57  struct stat sb;
58 
59  if (!stat(C_AutocryptDir, &sb))
60  return 0;
61 
62  if (!can_create)
63  return -1;
64 
65  struct Buffer *prompt = mutt_buffer_pool_get();
66  /* L10N:
67  %s is a directory. NeoMutt is looking for a directory it needs
68  for some reason (e.g. autocrypt, header cache, bcache), but it
69  doesn't exist. The prompt is asking whether to create the directory
70  */
71  mutt_buffer_printf(prompt, _("%s does not exist. Create it?"), C_AutocryptDir);
72  if (mutt_yesorno(mutt_b2s(prompt), MUTT_YES) == MUTT_YES)
73  {
74  if (mutt_file_mkdir(C_AutocryptDir, S_IRWXU) < 0)
75  {
76  /* L10N:
77  mkdir() on the directory %s failed. The second %s is the
78  error message returned by libc
79  */
80  mutt_error(_("Can't create %s: %s"), C_AutocryptDir, strerror(errno));
81  rc = -1;
82  }
83  }
84 
85  mutt_buffer_pool_release(&prompt);
86  return rc;
87 }
88 
95 int mutt_autocrypt_init(bool can_create)
96 {
97  if (AutocryptDB)
98  return 0;
99 
100  if (!C_Autocrypt || !C_AutocryptDir)
101  return -1;
102 
103  OptIgnoreMacroEvents = true;
104 
105  if (autocrypt_dir_init(can_create))
106  goto bail;
107 
109  goto bail;
110 
111  if (mutt_autocrypt_db_init(can_create))
112  goto bail;
113 
114  OptIgnoreMacroEvents = false;
115 
116  return 0;
117 
118 bail:
119  OptIgnoreMacroEvents = false;
120  C_Autocrypt = false;
122  return -1;
123 }
124 
129 {
131 }
132 
143 {
144  struct Address *addr = NULL;
145  struct AutocryptAccount *account = NULL;
146  bool done = false;
147  int rc = -1;
148  bool prefer_encrypt = false;
149 
150  if (prompt)
151  {
152  /* L10N:
153  The first time NeoMutt is started with $autocrypt set, it will
154  create $autocrypt_dir and then prompt to create an autocrypt
155  account with this message.
156  */
157  if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
158  return 0;
159  }
160 
161  struct Buffer *keyid = mutt_buffer_pool_get();
162  struct Buffer *keydata = mutt_buffer_pool_get();
163 
164  if (C_From)
165  {
166  addr = mutt_addr_copy(C_From);
167  if (!addr->personal && C_Realname)
169  }
170 
171  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
172  mutt_addrlist_append(&al, addr);
173 
174  do
175  {
176  /* L10N:
177  Autocrypt is asking for the email address to use for the
178  autocrypt account. This will generate a key and add a record
179  to the database for use in autocrypt operations.
180  */
181  if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
182  goto cleanup;
183 
184  addr = TAILQ_FIRST(&al);
185  if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
186  {
187  /* L10N:
188  Autocrypt prompts for an account email address, and requires
189  a single address. This is shown if they entered something invalid,
190  nothing, or more than one address for some reason.
191  */
192  mutt_error(_("Please enter a single email address"));
193  done = false;
194  }
195  else
196  done = true;
197  } while (!done);
198 
199  addr = TAILQ_FIRST(&al);
200  if (mutt_autocrypt_db_account_get(addr, &account) < 0)
201  goto cleanup;
202  if (account)
203  {
204  /* L10N:
205  When creating an autocrypt account, this message will be displayed
206  if there is already an account in the database with the email address
207  they just entered.
208  */
209  mutt_error(_("That email address already has an autocrypt account"));
210  goto cleanup;
211  }
212 
213  if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
214  goto cleanup;
215 
216  /* L10N:
217  Autocrypt has a setting "prefer-encrypt".
218  When the recommendation algorithm returns "available" and BOTH
219  sender and recipient choose "prefer-encrypt", encryption will be
220  automatically enabled.
221  Otherwise the UI will show encryption is "available" but the user
222  will be required to enable encryption manually.
223  */
224  if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
225  prefer_encrypt = true;
226 
227  if (mutt_autocrypt_db_account_insert(addr, mutt_b2s(keyid), mutt_b2s(keydata), prefer_encrypt))
228  goto cleanup;
229 
230  rc = 0;
231 
232 cleanup:
233  if (rc == 0)
234  /* L10N:
235  Message displayed after an autocrypt account is successfully created.
236  */
237  mutt_message(_("Autocrypt account creation succeeded"));
238  else
239  /* L10N:
240  Error message displayed if creating an autocrypt account failed
241  or was aborted by the user.
242  */
243  mutt_error(_("Autocrypt account creation aborted"));
244 
246  mutt_addrlist_clear(&al);
247  mutt_buffer_pool_release(&keyid);
248  mutt_buffer_pool_release(&keydata);
249  return rc;
250 }
251 
260 {
261  struct AutocryptHeader *valid_ac_hdr = NULL;
262  struct AutocryptPeer *peer = NULL;
263  struct AutocryptPeerHistory *peerhist = NULL;
264  struct Buffer *keyid = NULL;
265  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
266  int rc = -1;
267 
268  if (!C_Autocrypt)
269  return 0;
270 
271  if (mutt_autocrypt_init(false))
272  return -1;
273 
274  if (!e || !e->content || !env)
275  return 0;
276 
277  /* 1.1 spec says to skip emails with more than one From header */
278  struct Address *from = TAILQ_FIRST(&env->from);
279  if (!from || TAILQ_NEXT(from, entries))
280  return 0;
281 
282  /* 1.1 spec also says to skip multipart/report emails */
283  if ((e->content->type == TYPE_MULTIPART) &&
284  (mutt_str_strcasecmp(e->content->subtype, "report") == 0))
285  {
286  return 0;
287  }
288 
289  /* Ignore emails that appear to be more than a week in the future,
290  * since they can block all future updates during that time. */
291  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
292  return 0;
293 
294  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
295  {
296  if (ac_hdr->invalid)
297  continue;
298 
299  /* NOTE: this assumes the processing is occurring right after
300  * mutt_parse_rfc822_line() and the from ADDR is still in the same
301  * form (intl) as the autocrypt header addr field */
302  if (mutt_str_strcasecmp(from->mailbox, ac_hdr->addr) != 0)
303  continue;
304 
305  /* 1.1 spec says ignore all, if more than one valid header is found. */
306  if (valid_ac_hdr)
307  {
308  valid_ac_hdr = NULL;
309  break;
310  }
311  valid_ac_hdr = ac_hdr;
312  }
313 
314  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
315  goto cleanup;
316 
317  if (peer)
318  {
319  if (e->date_sent <= peer->autocrypt_timestamp)
320  {
321  rc = 0;
322  goto cleanup;
323  }
324 
325  if (e->date_sent > peer->last_seen)
326  {
327  update_db = true;
328  peer->last_seen = e->date_sent;
329  }
330 
331  if (valid_ac_hdr)
332  {
333  update_db = true;
334  peer->autocrypt_timestamp = e->date_sent;
335  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
336  if (mutt_str_strcmp(peer->keydata, valid_ac_hdr->keydata) != 0)
337  {
338  import_gpg = true;
339  insert_db_history = true;
340  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
341  }
342  }
343  }
344  else if (valid_ac_hdr)
345  {
346  import_gpg = true;
347  insert_db = true;
348  insert_db_history = true;
349  }
350 
351  if (!(import_gpg || insert_db || update_db))
352  {
353  rc = 0;
354  goto cleanup;
355  }
356 
357  if (!peer)
358  {
360  peer->last_seen = e->date_sent;
361  peer->autocrypt_timestamp = e->date_sent;
362  peer->keydata = mutt_str_strdup(valid_ac_hdr->keydata);
363  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
364  }
365 
366  if (import_gpg)
367  {
368  keyid = mutt_buffer_pool_get();
369  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
370  goto cleanup;
371  mutt_str_replace(&peer->keyid, mutt_b2s(keyid));
372  }
373 
374  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
375  goto cleanup;
376 
377  if (update_db && mutt_autocrypt_db_peer_update(peer))
378  goto cleanup;
379 
380  if (insert_db_history)
381  {
383  peerhist->email_msgid = mutt_str_strdup(env->message_id);
384  peerhist->timestamp = e->date_sent;
385  peerhist->keydata = mutt_str_strdup(peer->keydata);
386  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
387  goto cleanup;
388  }
389 
390  rc = 0;
391 
392 cleanup:
395  mutt_buffer_pool_release(&keyid);
396 
397  return rc;
398 }
399 
407 int mutt_autocrypt_process_gossip_header(struct Email *e, struct Envelope *prot_headers)
408 {
409  struct AutocryptPeer *peer = NULL;
410  struct AutocryptGossipHistory *gossip_hist = NULL;
411  struct Address *peer_addr = NULL;
412  struct Address ac_hdr_addr = { 0 };
413  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
414  int rc = -1;
415 
416  if (!C_Autocrypt)
417  return 0;
418 
419  if (mutt_autocrypt_init(false))
420  return -1;
421 
422  if (!e || !e->env || !prot_headers)
423  return 0;
424 
425  struct Envelope *env = e->env;
426 
427  struct Address *from = TAILQ_FIRST(&env->from);
428  if (!from)
429  return 0;
430 
431  /* Ignore emails that appear to be more than a week in the future,
432  * since they can block all future updates during that time. */
433  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
434  return 0;
435 
436  struct Buffer *keyid = mutt_buffer_pool_get();
437 
438  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
439 
440  /* Normalize the recipient list for comparison */
441  mutt_addrlist_copy(&recips, &env->to, false);
442  mutt_addrlist_copy(&recips, &env->cc, false);
443  mutt_addrlist_copy(&recips, &env->reply_to, false);
445 
446  for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
447  ac_hdr = ac_hdr->next)
448  {
449  if (ac_hdr->invalid)
450  continue;
451 
452  /* normalize for comparison against recipient list */
453  mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
454  ac_hdr_addr.is_intl = true;
455  ac_hdr_addr.intl_checked = true;
456  mutt_autocrypt_db_normalize_addr(&ac_hdr_addr);
457 
458  /* Check to make sure the address is in the recipient list. Since the
459  * addresses are normalized we use strcmp, not mutt_str_strcasecmp. */
460  TAILQ_FOREACH(peer_addr, &recips, entries)
461  {
462  if (mutt_str_strcmp(peer_addr->mailbox, ac_hdr_addr.mailbox) == 0)
463  break;
464  }
465 
466  if (!peer_addr)
467  continue;
468 
469  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
470  goto cleanup;
471 
472  if (peer)
473  {
474  if (e->date_sent <= peer->gossip_timestamp)
475  {
477  continue;
478  }
479 
480  update_db = true;
481  peer->gossip_timestamp = e->date_sent;
482  /* This is slightly different from the autocrypt 1.1 spec.
483  * Avoid setting an empty peer.gossip_keydata with a value that matches
484  * the current peer.keydata. */
485  if ((peer->gossip_keydata &&
486  (mutt_str_strcmp(peer->gossip_keydata, ac_hdr->keydata) != 0)) ||
487  (!peer->gossip_keydata && (mutt_str_strcmp(peer->keydata, ac_hdr->keydata) != 0)))
488  {
489  import_gpg = true;
490  insert_db_history = true;
491  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
492  }
493  }
494  else
495  {
496  import_gpg = true;
497  insert_db = true;
498  insert_db_history = true;
499  }
500 
501  if (!peer)
502  {
504  peer->gossip_timestamp = e->date_sent;
505  peer->gossip_keydata = mutt_str_strdup(ac_hdr->keydata);
506  }
507 
508  if (import_gpg)
509  {
511  goto cleanup;
512  mutt_str_replace(&peer->gossip_keyid, mutt_b2s(keyid));
513  }
514 
515  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
516  goto cleanup;
517 
518  if (update_db && mutt_autocrypt_db_peer_update(peer))
519  goto cleanup;
520 
521  if (insert_db_history)
522  {
523  gossip_hist = mutt_autocrypt_db_gossip_history_new();
524  gossip_hist->sender_email_addr = mutt_str_strdup(from->mailbox);
525  gossip_hist->email_msgid = mutt_str_strdup(env->message_id);
526  gossip_hist->timestamp = e->date_sent;
527  gossip_hist->gossip_keydata = mutt_str_strdup(peer->gossip_keydata);
528  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
529  goto cleanup;
530  }
531 
534  mutt_buffer_reset(keyid);
535  update_db = false;
536  insert_db = false;
537  insert_db_history = false;
538  import_gpg = false;
539  }
540 
541  rc = 0;
542 
543 cleanup:
544  FREE(&ac_hdr_addr.mailbox);
545  mutt_addrlist_clear(&recips);
548  mutt_buffer_pool_release(&keyid);
549 
550  return rc;
551 }
552 
562 enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
563 {
565  struct AutocryptAccount *account = NULL;
566  struct AutocryptPeer *peer = NULL;
567  struct Address *recip = NULL;
568  bool all_encrypt = true, has_discourage = false;
569  const char *matching_key = NULL;
570 
571  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
572  return AUTOCRYPT_REC_OFF;
573 
574  struct Address *from = TAILQ_FIRST(&e->env->from);
575  if (!from || TAILQ_NEXT(from, entries))
576  return AUTOCRYPT_REC_OFF;
577 
578  if (e->security & APPLICATION_SMIME)
579  return AUTOCRYPT_REC_OFF;
580 
581  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
582  goto cleanup;
583 
584  if (!account->enabled)
585  goto cleanup;
586 
587  struct Buffer *keylist_buf = mutt_buffer_pool_get();
588  mutt_buffer_addstr(keylist_buf, account->keyid);
589 
590  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
591 
592  mutt_addrlist_copy(&recips, &e->env->to, false);
593  mutt_addrlist_copy(&recips, &e->env->cc, false);
594  mutt_addrlist_copy(&recips, &e->env->bcc, false);
595 
596  rc = AUTOCRYPT_REC_NO;
597  if (TAILQ_EMPTY(&recips))
598  goto cleanup;
599 
600  TAILQ_FOREACH(recip, &recips, entries)
601  {
602  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
603  {
604  if (keylist)
605  {
606  /* L10N:
607  %s is an email address. Autocrypt is scanning for the keyids
608  to use to encrypt, but it can't find a valid keyid for this address.
609  The message is printed and they are returned to the compose menu.
610  */
611  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
612  }
613  goto cleanup;
614  }
615 
617  {
618  matching_key = peer->keyid;
619 
620  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
621  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
622  {
623  has_discourage = true;
624  all_encrypt = false;
625  }
626 
627  if (!account->prefer_encrypt || !peer->prefer_encrypt)
628  all_encrypt = false;
629  }
631  {
632  matching_key = peer->gossip_keyid;
633 
634  has_discourage = true;
635  all_encrypt = false;
636  }
637  else
638  {
639  if (keylist)
640  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
641  goto cleanup;
642  }
643 
644  if (!mutt_buffer_is_empty(keylist_buf))
645  mutt_buffer_addch(keylist_buf, ' ');
646  mutt_buffer_addstr(keylist_buf, matching_key);
647 
649  }
650 
651  if (all_encrypt)
652  rc = AUTOCRYPT_REC_YES;
653  else if (has_discourage)
655  else
657 
658  if (keylist)
659  mutt_str_replace(keylist, mutt_b2s(keylist_buf));
660 
661 cleanup:
663  mutt_addrlist_clear(&recips);
665  mutt_buffer_pool_release(&keylist_buf);
666  return rc;
667 }
668 
676 {
677  int rc = -1;
678  struct AutocryptAccount *account = NULL;
679 
680  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
681  return -1;
682 
683  struct Address *from = TAILQ_FIRST(&e->env->from);
684  if (!from || TAILQ_NEXT(from, entries))
685  return -1;
686 
687  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
688  goto cleanup;
689  if (!account->keyid)
690  goto cleanup;
691  if (!account->enabled)
692  goto cleanup;
693 
696 
697  rc = 0;
698 
699 cleanup:
701  return rc;
702 }
703 
711 static void write_autocrypt_header_line(FILE *fp, const char *addr,
712  bool prefer_encrypt, const char *keydata)
713 {
714  fprintf(fp, "addr=%s; ", addr);
715  if (prefer_encrypt)
716  fputs("prefer-encrypt=mutual; ", fp);
717  fputs("keydata=\n", fp);
718 
719  while (*keydata)
720  {
721  int count = 0;
722  fputs("\t", fp);
723  while (*keydata && count < 75)
724  {
725  fputc(*keydata, fp);
726  count++;
727  keydata++;
728  }
729  fputs("\n", fp);
730  }
731 }
732 
741 {
742  int rc = -1;
743  struct AutocryptAccount *account = NULL;
744 
745  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
746  return -1;
747 
748  struct Address *from = TAILQ_FIRST(&env->from);
749  if (!from || TAILQ_NEXT(from, entries))
750  return -1;
751 
752  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
753  goto cleanup;
754  if (!account->keydata)
755  goto cleanup;
756  if (!account->enabled)
757  goto cleanup;
758 
759  fputs("Autocrypt: ", fp);
761  account->keydata);
762 
763  rc = 0;
764 
765 cleanup:
767  return rc;
768 }
769 
778 {
779  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
780  return -1;
781 
782  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
783  gossip = gossip->next)
784  {
785  fputs("Autocrypt-Gossip: ", fp);
786  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
787  }
788 
789  return 0;
790 }
791 
799 {
800  int rc = -1;
801  struct AutocryptPeer *peer = NULL;
802  struct AutocryptAccount *account = NULL;
803  struct Address *recip = NULL;
804 
805  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
806  return -1;
807 
808  struct Envelope *mime_headers = e->content->mime_headers;
809  if (!mime_headers)
810  mime_headers = e->content->mime_headers = mutt_env_new();
812 
813  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
814 
815  mutt_addrlist_copy(&recips, &e->env->to, false);
816  mutt_addrlist_copy(&recips, &e->env->cc, false);
817 
818  TAILQ_FOREACH(recip, &recips, entries)
819  {
820  /* At this point, we just accept missing keys and include what we can. */
821  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
822  continue;
823 
824  const char *keydata = NULL;
826  keydata = peer->keydata;
828  keydata = peer->gossip_keydata;
829 
830  if (keydata)
831  {
832  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
833  gossip->addr = mutt_str_strdup(peer->email_addr);
834  gossip->keydata = mutt_str_strdup(keydata);
835  gossip->next = mime_headers->autocrypt_gossip;
836  mime_headers->autocrypt_gossip = gossip;
837  }
838 
840  }
841 
842  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
843  {
844  const char *addr = NULL;
845  const char *keydata = NULL;
846  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
847  {
848  addr = account->email_addr;
849  keydata = account->keydata;
850  }
851  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
852  {
853  addr = peer->email_addr;
855  keydata = peer->keydata;
857  keydata = peer->gossip_keydata;
858  }
859 
860  if (keydata)
861  {
862  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
863  gossip->addr = mutt_str_strdup(addr);
864  gossip->keydata = mutt_str_strdup(keydata);
865  gossip->next = mime_headers->autocrypt_gossip;
866  mime_headers->autocrypt_gossip = gossip;
867  }
870  }
871 
872  mutt_addrlist_clear(&recips);
875  return rc;
876 }
877 
889 {
890 #ifdef USE_HCACHE
891  char *old_hdrcache = C_HeaderCache;
892  C_HeaderCache = NULL;
893 #endif
894 
895  struct Buffer *folderbuf = mutt_buffer_pool_get();
896 
897  /* L10N:
898  The first time autocrypt is enabled, NeoMutt will ask to scan
899  through one or more mailboxes for Autocrypt: headers.
900  Those headers are then captured in the database as peer records
901  and used for encryption.
902  If this is answered yes, they will be prompted for a mailbox.
903  */
904  int scan = mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
905  while (scan == MUTT_YES)
906  {
907  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
908  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true)) &&
909  (!mutt_buffer_is_empty(folderbuf)))
910  {
911  mutt_buffer_expand_path_regex(folderbuf, false);
912  struct Mailbox *m = mx_path_resolve(mutt_b2s(folderbuf));
913  /* NOTE: I am purposely *not* executing folder hooks here,
914  * as they can do all sorts of things like push into the getch() buffer.
915  * Authentication should be in account-hooks. */
916  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
917  mx_mbox_close(&ctx);
918  mutt_buffer_reset(folderbuf);
919  }
920 
921  /* L10N:
922  This is the second prompt to see if the user would like
923  to scan more than one mailbox for Autocrypt headers.
924  I'm purposely being extra verbose; asking first then prompting
925  for a mailbox. This is because this is a one-time operation
926  and I don't want them to accidentally ctrl-g and abort it.
927  */
928  scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
929  }
930 
931 #ifdef USE_HCACHE
932  C_HeaderCache = old_hdrcache;
933 #endif
934  mutt_buffer_pool_release(&folderbuf);
935 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:95
The "current" mailbox.
Definition: context.h:36
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition: autocrypt_db.c:762
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: autocrypt_db.c:165
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:205
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
Define wrapper functions around Curses/Slang.
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
The envelope/body of an email.
Definition: email.h:39
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
#define TAILQ_FIRST(head)
Definition: queue.h:717
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:719
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
GUI miscellaneous curses (window drawing) routines.
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:558
Structs that make up an email.
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: autocrypt_db.c:244
#define mutt_message(...)
Definition: logging.h:83
bool prefer_encrypt
Definition: envelope.h:45
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1381
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:54
WHERE char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: globals.h:93
char * keydata
Definition: autocrypt.h:68
sqlite3_int64 timestamp
Definition: autocrypt.h:82
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:727
struct Body * content
List of MIME parts.
Definition: email.h:92
String manipulation buffer.
Definition: buffer.h:33
int mutt_autocrypt_process_gossip_header(struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:407
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:65
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:254
struct AutocryptHeader * autocrypt
Definition: envelope.h:85
char * mailbox
Mailbox and host address.
Definition: address.h:37
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:36
char * email_addr
Definition: autocrypt.h:52
Autocrypt is available.
Definition: autocrypt.h:106
AutocryptRec
Recommendation.
Definition: autocrypt.h:101
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:53
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:706
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition: autocrypt_db.c:819
WHERE char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: globals.h:126
char * gossip_keydata
Definition: autocrypt.h:72
int mutt_autocrypt_account_init(bool prompt)
Create a new Autocrypt account.
Definition: autocrypt.c:142
Convenience wrapper for the config headers.
bool is_intl
International Domain Name.
Definition: address.h:39
Prepare and send an email.
Hundreds of global variables to back the user variables.
Email Address Handling.
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
sqlite3_int64 gossip_timestamp
Definition: autocrypt.h:70
Some miscellaneous functions.
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: autocrypt_db.c:519
sqlite3_int64 autocrypt_timestamp
Definition: autocrypt.h:66
char * message_id
Message ID.
Definition: envelope.h:69
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
void mutt_autocrypt_scan_mailboxes(void)
Scan mailboxes for Autocrypt headers.
Definition: autocrypt.c:888
API for mailboxes.
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: autocrypt_db.c:176
Autocrypt peer.
Definition: autocrypt.h:62
char * keydata
Definition: envelope.h:44
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:871
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: globals.h:99
struct Envelope * env
Envelope information.
Definition: email.h:91
void mutt_autocrypt_db_close(void)
Close the Autocrypt sqlite database connection.
Definition: autocrypt_db.c:130
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: autocrypt_db.c:743
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
No recommendations.
Definition: autocrypt.h:103
char * email_addr
Definition: autocrypt.h:64
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
bool prefer_encrypt
Definition: autocrypt.h:55
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: autocrypt_db.c:678
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
bool intl_checked
Checked for IDN?
Definition: address.h:40
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:675
char * subtype
content-type subtype
Definition: body.h:37
Prefer not to use Autocrypt.
Definition: autocrypt.h:105
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:83
void mutt_autocrypt_cleanup(void)
Shutdown Autocrypt.
Definition: autocrypt.c:128
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_autocrypt_process_autocrypt_header(struct Email *e, struct Envelope *env)
Parse an Autocrypt email header.
Definition: autocrypt.c:259
int mutt_autocrypt_db_gossip_history_insert(struct Address *addr, struct AutocryptGossipHistory *gossip_hist)
Insert a gossip history into the Autocrypt database.
Definition: autocrypt_db.c:839
A mailbox.
Definition: mailbox.h:92
Autocrypt gossip history.
Definition: autocrypt.h:89
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
sqlite3_int64 last_seen
Definition: autocrypt.h:65
struct AutocryptHeader * next
Definition: envelope.h:47
sqlite3 * AutocryptDB
Definition: autocrypt_db.c:51
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Autocrypt should be used.
Definition: autocrypt.h:107
char * gossip_keyid
Definition: autocrypt.h:71
Do no use Autocrypt.
Definition: autocrypt.h:104
int mutt_autocrypt_gpgme_select_or_create_key(struct Address *addr, struct Buffer *keyid, struct Buffer *keydata)
Ask the user to select or create an Autocrypt key.
API for encryption/signing of emails.
char * addr
Definition: envelope.h:43
Autocrypt peer history.
Definition: autocrypt.h:78
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
Parse Autocrypt header info.
Definition: envelope.h:41
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: autocrypt_db.c:615
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: autocrypt_db.c:550
unsigned int type
content-type primary type
Definition: body.h:65
bool prefer_encrypt
Definition: autocrypt.h:69
char * personal
Real name of address.
Definition: address.h:36
Autocrypt account.
Definition: autocrypt.h:50
Shared constants/structs that are private to Autocrypt.
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:562
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:74
int mutt_autocrypt_generate_gossip_list(struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:798
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
Autocrypt end-to-end encryption.
static void write_autocrypt_header_line(FILE *fp, const char *addr, bool prefer_encrypt, const char *keydata)
Write an Autocrypt header to a file.
Definition: autocrypt.c:711
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * keydata
Definition: autocrypt.h:54
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1539
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
WHERE char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and sqlite database.
Definition: globals.h:107
int mutt_autocrypt_db_account_insert(struct Address *addr, const char *keyid, const char *keydata, bool prefer_encrypt)
Insert an Account into the Autocrypt database.
Definition: autocrypt_db.c:322
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_NEXT(elm, field)
Definition: queue.h:816
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:143
Handling of global boolean variables.
#define TAILQ_EMPTY(head)
Definition: queue.h:715
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: autocrypt_db.c:528
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt sqlite database.
Definition: autocrypt_db.c:80
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:631
char * keyid
Definition: autocrypt.h:67
int mutt_autocrypt_write_gossip_headers(struct Envelope *env, FILE *fp)
Write the Autocrypt gossip headers to a file.
Definition: autocrypt.c:777
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: autocrypt_db.c:810
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:82
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: autocrypt_db.c:734
sqlite3_int64 timestamp
Definition: autocrypt.h:94
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:210
The header of an Email.
Definition: envelope.h:54
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1401
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
WHERE char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: globals.h:92
int mutt_autocrypt_write_autocrypt_header(struct Envelope *env, FILE *fp)
Write the Autocrypt header to a file.
Definition: autocrypt.c:740