NeoMutt  2021-02-05-89-gabe350
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 <stdbool.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include "private.h"
36 #include "mutt/lib.h"
37 #include "address/lib.h"
38 #include "config/lib.h"
39 #include "email/lib.h"
40 #include "gui/lib.h"
41 #include "autocrypt/lib.h"
42 #include "hcache/lib.h"
43 #include "ncrypt/lib.h"
44 #include "send/lib.h"
45 #include "context.h"
46 #include "mutt_globals.h"
47 #include "muttlib.h"
48 #include "mx.h"
49 #include "options.h"
50 
57 static int autocrypt_dir_init(bool can_create)
58 {
59  int rc = 0;
60  struct stat sb;
61 
62  if (stat(C_AutocryptDir, &sb) == 0)
63  return 0;
64 
65  if (!can_create)
66  return -1;
67 
68  struct Buffer *prompt = mutt_buffer_pool_get();
69  /* L10N: s is a directory. NeoMutt is looking for a directory it needs
70  for some reason (e.g. autocrypt, header cache, bcache), but it
71  doesn't exist. The prompt is asking whether to create the directory */
72  mutt_buffer_printf(prompt, _("%s does not exist. Create it?"), C_AutocryptDir);
74  {
75  if (mutt_file_mkdir(C_AutocryptDir, S_IRWXU) < 0)
76  {
77  /* L10N: mkdir() on the directory %s failed. The second %s is the
78  error message returned by libc */
79  mutt_error(_("Can't create %s: %s"), C_AutocryptDir, strerror(errno));
80  rc = -1;
81  }
82  }
83 
84  mutt_buffer_pool_release(&prompt);
85  return rc;
86 }
87 
95 int mutt_autocrypt_init(struct Mailbox *m, 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  /* The init process can display menus at various points
105  *(e.g. browser, pgp key selection). This allows the screen to be
106  * autocleared after each menu, so the subsequent prompts can be
107  * read. */
108  OptMenuPopClearScreen = true;
109 
110  if (autocrypt_dir_init(can_create))
111  goto bail;
112 
114  goto bail;
115 
116  if (mutt_autocrypt_db_init(m, can_create))
117  goto bail;
118 
119  OptIgnoreMacroEvents = false;
120  OptMenuPopClearScreen = false;
121 
122  return 0;
123 
124 bail:
125  OptIgnoreMacroEvents = false;
126  OptMenuPopClearScreen = false;
127  C_Autocrypt = false;
129  return -1;
130 }
131 
136 {
138 }
139 
150 {
151  struct Address *addr = NULL;
152  struct AutocryptAccount *account = NULL;
153  bool done = false;
154  int rc = -1;
155  bool prefer_encrypt = false;
156 
157  if (prompt)
158  {
159  /* L10N: The first time NeoMutt is started with $autocrypt set, it will
160  create $autocrypt_dir and then prompt to create an autocrypt account
161  with this message. */
162  if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
163  return 0;
164  }
165 
166  struct Buffer *keyid = mutt_buffer_pool_get();
167  struct Buffer *keydata = mutt_buffer_pool_get();
168 
169  if (C_From)
170  {
171  addr = mutt_addr_copy(C_From);
172  if (!addr->personal && C_RealName)
174  }
175 
176  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
177  mutt_addrlist_append(&al, addr);
178 
179  do
180  {
181  /* L10N: Autocrypt is asking for the email address to use for the
182  autocrypt account. This will generate a key and add a record
183  to the database for use in autocrypt operations. */
184  if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
185  goto cleanup;
186 
187  addr = TAILQ_FIRST(&al);
188  if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
189  {
190  /* L10N: Autocrypt prompts for an account email address, and requires
191  a single address. This is shown if they entered something invalid,
192  nothing, or more than one address for some reason. */
193  mutt_error(_("Please enter a single email address"));
194  done = false;
195  }
196  else
197  done = true;
198  } while (!done);
199 
200  addr = TAILQ_FIRST(&al);
201  if (mutt_autocrypt_db_account_get(addr, &account) < 0)
202  goto cleanup;
203  if (account)
204  {
205  /* L10N: 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  mutt_error(_("That email address already has an autocrypt account"));
209  goto cleanup;
210  }
211 
212  if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
213  goto cleanup;
214 
215  /* L10N: Autocrypt has a setting "prefer-encrypt".
216  When the recommendation algorithm returns "available" and BOTH sender and
217  recipient choose "prefer-encrypt", encryption will be automatically
218  enabled.
219  Otherwise the UI will show encryption is "available" but the user
220  will be required to enable encryption manually. */
221  if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
222  prefer_encrypt = true;
223 
225  mutt_buffer_string(keydata), prefer_encrypt))
226  {
227  goto cleanup;
228  }
229 
230  rc = 0;
231 
232 cleanup:
233  if (rc == 0)
234  /* L10N: Message displayed after an autocrypt account is successfully created. */
235  mutt_message(_("Autocrypt account creation succeeded"));
236  else
237  /* L10N: Error message displayed if creating an autocrypt account failed
238  or was aborted by the user. */
239  mutt_error(_("Autocrypt account creation aborted"));
240 
242  mutt_addrlist_clear(&al);
243  mutt_buffer_pool_release(&keyid);
244  mutt_buffer_pool_release(&keydata);
245  return rc;
246 }
247 
257  struct Envelope *env)
258 {
259  struct AutocryptHeader *valid_ac_hdr = NULL;
260  struct AutocryptPeer *peer = NULL;
261  struct AutocryptPeerHistory *peerhist = NULL;
262  struct Buffer *keyid = NULL;
263  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
264  int rc = -1;
265 
266  if (!C_Autocrypt)
267  return 0;
268 
269  if (mutt_autocrypt_init(m, false))
270  return -1;
271 
272  if (!e || !e->body || !env)
273  return 0;
274 
275  /* 1.1 spec says to skip emails with more than one From header */
276  struct Address *from = TAILQ_FIRST(&env->from);
277  if (!from || TAILQ_NEXT(from, entries))
278  return 0;
279 
280  /* 1.1 spec also says to skip multipart/report emails */
281  if ((e->body->type == TYPE_MULTIPART) &&
282  mutt_istr_equal(e->body->subtype, "report"))
283  {
284  return 0;
285  }
286 
287  /* Ignore emails that appear to be more than a week in the future,
288  * since they can block all future updates during that time. */
289  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
290  return 0;
291 
292  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
293  {
294  if (ac_hdr->invalid)
295  continue;
296 
297  /* NOTE: this assumes the processing is occurring right after
298  * mutt_parse_rfc822_line() and the from ADDR is still in the same
299  * form (intl) as the autocrypt header addr field */
300  if (!mutt_istr_equal(from->mailbox, ac_hdr->addr))
301  continue;
302 
303  /* 1.1 spec says ignore all, if more than one valid header is found. */
304  if (valid_ac_hdr)
305  {
306  valid_ac_hdr = NULL;
307  break;
308  }
309  valid_ac_hdr = ac_hdr;
310  }
311 
312  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
313  goto cleanup;
314 
315  if (peer)
316  {
317  if (e->date_sent <= peer->autocrypt_timestamp)
318  {
319  rc = 0;
320  goto cleanup;
321  }
322 
323  if (e->date_sent > peer->last_seen)
324  {
325  update_db = true;
326  peer->last_seen = e->date_sent;
327  }
328 
329  if (valid_ac_hdr)
330  {
331  update_db = true;
332  peer->autocrypt_timestamp = e->date_sent;
333  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
334  if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
335  {
336  import_gpg = true;
337  insert_db_history = true;
338  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
339  }
340  }
341  }
342  else if (valid_ac_hdr)
343  {
344  import_gpg = true;
345  insert_db = true;
346  insert_db_history = true;
347  }
348 
349  if (!(import_gpg || insert_db || update_db))
350  {
351  rc = 0;
352  goto cleanup;
353  }
354 
355  if (!peer)
356  {
358  peer->last_seen = e->date_sent;
359  peer->autocrypt_timestamp = e->date_sent;
360  peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
361  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
362  }
363 
364  if (import_gpg)
365  {
366  keyid = mutt_buffer_pool_get();
367  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
368  goto cleanup;
369  mutt_str_replace(&peer->keyid, mutt_buffer_string(keyid));
370  }
371 
372  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
373  goto cleanup;
374 
375  if (update_db && mutt_autocrypt_db_peer_update(peer))
376  goto cleanup;
377 
378  if (insert_db_history)
379  {
381  peerhist->email_msgid = mutt_str_dup(env->message_id);
382  peerhist->timestamp = e->date_sent;
383  peerhist->keydata = mutt_str_dup(peer->keydata);
384  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
385  goto cleanup;
386  }
387 
388  rc = 0;
389 
390 cleanup:
393  mutt_buffer_pool_release(&keyid);
394 
395  return rc;
396 }
397 
407  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(m, 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. */
459  TAILQ_FOREACH(peer_addr, &recips, entries)
460  {
461  if (mutt_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
462  break;
463  }
464 
465  if (!peer_addr)
466  continue;
467 
468  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
469  goto cleanup;
470 
471  if (peer)
472  {
473  if (e->date_sent <= peer->gossip_timestamp)
474  {
476  continue;
477  }
478 
479  update_db = true;
480  peer->gossip_timestamp = e->date_sent;
481  /* This is slightly different from the autocrypt 1.1 spec.
482  * Avoid setting an empty peer.gossip_keydata with a value that matches
483  * the current peer.keydata. */
484  if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
485  (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
486  {
487  import_gpg = true;
488  insert_db_history = true;
489  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
490  }
491  }
492  else
493  {
494  import_gpg = true;
495  insert_db = true;
496  insert_db_history = true;
497  }
498 
499  if (!peer)
500  {
502  peer->gossip_timestamp = e->date_sent;
503  peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
504  }
505 
506  if (import_gpg)
507  {
509  goto cleanup;
511  }
512 
513  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
514  goto cleanup;
515 
516  if (update_db && mutt_autocrypt_db_peer_update(peer))
517  goto cleanup;
518 
519  if (insert_db_history)
520  {
521  gossip_hist = mutt_autocrypt_db_gossip_history_new();
522  gossip_hist->sender_email_addr = mutt_str_dup(from->mailbox);
523  gossip_hist->email_msgid = mutt_str_dup(env->message_id);
524  gossip_hist->timestamp = e->date_sent;
525  gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
526  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
527  goto cleanup;
528  }
529 
532  mutt_buffer_reset(keyid);
533  update_db = false;
534  insert_db = false;
535  insert_db_history = false;
536  import_gpg = false;
537  }
538 
539  rc = 0;
540 
541 cleanup:
542  FREE(&ac_hdr_addr.mailbox);
543  mutt_addrlist_clear(&recips);
546  mutt_buffer_pool_release(&keyid);
547 
548  return rc;
549 }
550 
562  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  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
571  struct Buffer *keylist_buf = NULL;
572 
573  if (!C_Autocrypt || mutt_autocrypt_init(m, false) || !e)
574  {
575  if (keylist)
576  {
577  /* L10N: Error displayed if the user tries to force sending an Autocrypt
578  email when the engine is not available. */
579  mutt_message(_("Autocrypt is not available"));
580  }
581  return AUTOCRYPT_REC_OFF;
582  }
583 
584  struct Address *from = TAILQ_FIRST(&e->env->from);
585  if (!from || TAILQ_NEXT(from, entries))
586  {
587  if (keylist)
588  mutt_message(_("Autocrypt is not available"));
589  return AUTOCRYPT_REC_OFF;
590  }
591 
592  if (e->security & APPLICATION_SMIME)
593  {
594  if (keylist)
595  mutt_message(_("Autocrypt is not available"));
596  return AUTOCRYPT_REC_OFF;
597  }
598 
599  if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
600  {
601  if (keylist)
602  {
603  /* L10N: Error displayed if the user tries to force sending an Autocrypt
604  email when the account does not exist or is not enabled.
605  %s is the From email address used to look up the Autocrypt account.
606  */
607  mutt_message(_("Autocrypt is not enabled for %s"), NONULL(from->mailbox));
608  }
609  goto cleanup;
610  }
611 
612  keylist_buf = mutt_buffer_pool_get();
613  mutt_buffer_addstr(keylist_buf, account->keyid);
614 
615  mutt_addrlist_copy(&recips, &e->env->to, false);
616  mutt_addrlist_copy(&recips, &e->env->cc, false);
617  mutt_addrlist_copy(&recips, &e->env->bcc, false);
618 
619  rc = AUTOCRYPT_REC_NO;
620  if (TAILQ_EMPTY(&recips))
621  goto cleanup;
622 
623  TAILQ_FOREACH(recip, &recips, entries)
624  {
625  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
626  {
627  if (keylist)
628  {
629  /* L10N: s is an email address. Autocrypt is scanning for the keyids
630  to use to encrypt, but it can't find a valid keyid for this address.
631  The message is printed and they are returned to the compose menu. */
632  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
633  }
634  goto cleanup;
635  }
636 
638  {
639  matching_key = peer->keyid;
640 
641  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
642  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
643  {
644  has_discourage = true;
645  all_encrypt = false;
646  }
647 
648  if (!account->prefer_encrypt || !peer->prefer_encrypt)
649  all_encrypt = false;
650  }
652  {
653  matching_key = peer->gossip_keyid;
654 
655  has_discourage = true;
656  all_encrypt = false;
657  }
658  else
659  {
660  if (keylist)
661  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
662  goto cleanup;
663  }
664 
665  if (!mutt_buffer_is_empty(keylist_buf))
666  mutt_buffer_addch(keylist_buf, ' ');
667  mutt_buffer_addstr(keylist_buf, matching_key);
668 
670  }
671 
672  if (all_encrypt)
673  rc = AUTOCRYPT_REC_YES;
674  else if (has_discourage)
676  else
678 
679  if (keylist)
680  mutt_str_replace(keylist, mutt_buffer_string(keylist_buf));
681 
682 cleanup:
684  mutt_addrlist_clear(&recips);
686  mutt_buffer_pool_release(&keylist_buf);
687  return rc;
688 }
689 
698 {
699  int rc = -1;
700  struct AutocryptAccount *account = NULL;
701 
702  if (!C_Autocrypt || mutt_autocrypt_init(m, false) || !e)
703  return -1;
704 
705  struct Address *from = TAILQ_FIRST(&e->env->from);
706  if (!from || TAILQ_NEXT(from, entries))
707  return -1;
708 
709  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
710  goto cleanup;
711  if (!account->keyid)
712  goto cleanup;
713  if (!account->enabled)
714  goto cleanup;
715 
718 
719  rc = 0;
720 
721 cleanup:
723  return rc;
724 }
725 
733 static void write_autocrypt_header_line(FILE *fp, const char *addr,
734  bool prefer_encrypt, const char *keydata)
735 {
736  fprintf(fp, "addr=%s; ", addr);
737  if (prefer_encrypt)
738  fputs("prefer-encrypt=mutual; ", fp);
739  fputs("keydata=\n", fp);
740 
741  while (*keydata)
742  {
743  int count = 0;
744  fputs("\t", fp);
745  while (*keydata && count < 75)
746  {
747  fputc(*keydata, fp);
748  count++;
749  keydata++;
750  }
751  fputs("\n", fp);
752  }
753 }
754 
763 int mutt_autocrypt_write_autocrypt_header(struct Mailbox *m, struct Envelope *env, FILE *fp)
764 {
765  int rc = -1;
766  struct AutocryptAccount *account = NULL;
767 
768  if (!C_Autocrypt || mutt_autocrypt_init(m, false) || !env)
769  return -1;
770 
771  struct Address *from = TAILQ_FIRST(&env->from);
772  if (!from || TAILQ_NEXT(from, entries))
773  return -1;
774 
775  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
776  goto cleanup;
777  if (!account->keydata)
778  goto cleanup;
779  if (!account->enabled)
780  goto cleanup;
781 
782  fputs("Autocrypt: ", fp);
784  account->keydata);
785 
786  rc = 0;
787 
788 cleanup:
790  return rc;
791 }
792 
801 int mutt_autocrypt_write_gossip_headers(struct Mailbox *m, struct Envelope *env, FILE *fp)
802 {
803  if (!C_Autocrypt || mutt_autocrypt_init(m, false) || !env)
804  return -1;
805 
806  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
807  gossip = gossip->next)
808  {
809  fputs("Autocrypt-Gossip: ", fp);
810  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
811  }
812 
813  return 0;
814 }
815 
824 {
825  int rc = -1;
826  struct AutocryptPeer *peer = NULL;
827  struct AutocryptAccount *account = NULL;
828  struct Address *recip = NULL;
829 
830  if (!C_Autocrypt || mutt_autocrypt_init(m, false) || !e)
831  return -1;
832 
833  struct Envelope *mime_headers = e->body->mime_headers;
834  if (!mime_headers)
835  mime_headers = e->body->mime_headers = mutt_env_new();
837 
838  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
839 
840  mutt_addrlist_copy(&recips, &e->env->to, false);
841  mutt_addrlist_copy(&recips, &e->env->cc, false);
842 
843  TAILQ_FOREACH(recip, &recips, entries)
844  {
845  /* At this point, we just accept missing keys and include what we can. */
846  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
847  continue;
848 
849  const char *keydata = NULL;
851  keydata = peer->keydata;
853  keydata = peer->gossip_keydata;
854 
855  if (keydata)
856  {
857  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
858  gossip->addr = mutt_str_dup(peer->email_addr);
859  gossip->keydata = mutt_str_dup(keydata);
860  gossip->next = mime_headers->autocrypt_gossip;
861  mime_headers->autocrypt_gossip = gossip;
862  }
863 
865  }
866 
867  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
868  {
869  const char *addr = NULL;
870  const char *keydata = NULL;
871  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
872  {
873  addr = account->email_addr;
874  keydata = account->keydata;
875  }
876  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
877  {
878  addr = peer->email_addr;
880  keydata = peer->keydata;
882  keydata = peer->gossip_keydata;
883  }
884 
885  if (keydata)
886  {
887  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
888  gossip->addr = mutt_str_dup(addr);
889  gossip->keydata = mutt_str_dup(keydata);
890  gossip->next = mime_headers->autocrypt_gossip;
891  mime_headers->autocrypt_gossip = gossip;
892  }
895  }
896 
897  mutt_addrlist_clear(&recips);
900  return rc;
901 }
902 
915 {
916 #ifdef USE_HCACHE
917  char *old_hdrcache = C_HeaderCache;
918  C_HeaderCache = NULL;
919 #endif
920 
921  struct Buffer *folderbuf = mutt_buffer_pool_get();
922 
923  /* L10N: The first time autocrypt is enabled, NeoMutt will ask to scan
924  through one or more mailboxes for Autocrypt: headers. Those headers are
925  then captured in the database as peer records and used for encryption.
926  If this is answered yes, they will be prompted for a mailbox. */
927  enum QuadOption scan =
928  mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
929  while (scan == MUTT_YES)
930  {
931  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
932  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true, m, false,
933  NULL, NULL, MUTT_SEL_NO_FLAGS)) &&
934  (!mutt_buffer_is_empty(folderbuf)))
935  {
936  mutt_buffer_expand_path_regex(folderbuf, false);
937  struct Mailbox *m_ac = mx_path_resolve(mutt_buffer_string(folderbuf));
938  /* NOTE: I am purposely *not* executing folder hooks here,
939  * as they can do all sorts of things like push into the getch() buffer.
940  * Authentication should be in account-hooks. */
941  struct Context *ctx = mx_mbox_open(m_ac, MUTT_READONLY);
942  mx_mbox_close(&ctx);
943  mutt_buffer_reset(folderbuf);
944  }
945 
946  /* L10N: This is the second prompt to see if the user would like
947  to scan more than one mailbox for Autocrypt headers.
948  I'm purposely being extra verbose; asking first then prompting
949  for a mailbox. This is because this is a one-time operation
950  and I don't want them to accidentally ctrl-g and abort it. */
951  scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
952  }
953 
954 #ifdef USE_HCACHE
955  C_HeaderCache = old_hdrcache;
956 #endif
957  mutt_buffer_pool_release(&folderbuf);
958 }
mutt_autocrypt_db_normalize_addr
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: db.c:162
Envelope
The header of an Email.
Definition: envelope.h:54
mutt_autocrypt_db_peer_history_free
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: db.c:740
Email::date_sent
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
AutocryptHeader::next
struct AutocryptHeader * next
Definition: envelope.h:47
MUTT_READONLY
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:54
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
AUTOCRYPT_REC_NO
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition: lib.h:158
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
mutt_autocrypt_db_account_insert
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: db.c:319
Mailbox
A mailbox.
Definition: mailbox.h:81
Envelope::message_id
char * message_id
Message ID.
Definition: envelope.h:69
C_RealName
WHERE char * C_RealName
Config: Real name of the user.
Definition: mutt_globals.h:105
mutt_autocrypt_db_gossip_history_insert
int mutt_autocrypt_db_gossip_history_insert(struct Address *addr, struct AutocryptGossipHistory *gossip_hist)
Insert a gossip history into the Autocrypt database.
Definition: db.c:836
APPLICATION_SMIME
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
autocrypt_dir_init
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:57
AutocryptDB
sqlite3 * AutocryptDB
Definition: db.c:50
mutt_autocrypt_db_peer_history_new
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: db.c:731
AutocryptAccount
Autocrypt account.
Definition: lib.h:104
Address::personal
char * personal
Real name of address.
Definition: address.h:36
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_addrlist_append
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1488
mutt_autocrypt_db_gossip_history_free
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition: db.c:816
mutt_autocrypt_process_gossip_header
int mutt_autocrypt_process_gossip_header(struct Mailbox *m, struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:406
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
AutocryptPeer::keyid
char * keyid
Definition: lib.h:121
mutt_autocrypt_account_init
int mutt_autocrypt_account_init(bool prompt)
Create a new Autocrypt account.
Definition: autocrypt.c:149
MUTT_SEL_NO_FLAGS
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:41
mutt_autocrypt_generate_gossip_list
int mutt_autocrypt_generate_gossip_list(struct Mailbox *m, struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:823
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Envelope::autocrypt
struct AutocryptHeader * autocrypt
Definition: envelope.h:85
mutt_autocrypt_db_account_free
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:241
lib.h
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
AutocryptPeer::email_addr
char * email_addr
Definition: lib.h:118
mutt_globals.h
AutocryptPeer::autocrypt_timestamp
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:120
FREE
#define FREE(x)
Definition: memory.h:40
C_Autocrypt
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
options.h
AUTOCRYPT_REC_YES
@ AUTOCRYPT_REC_YES
Autocrypt should be used.
Definition: lib.h:161
AutocryptAccount::email_addr
char * email_addr
Definition: lib.h:106
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
OptIgnoreMacroEvents
WHERE bool OptIgnoreMacroEvents
(pseudo) don't process macro/push/exec events while set
Definition: options.h:38
AutocryptHeader::addr
char * addr
Definition: envelope.h:43
mutt_autocrypt_gpgme_select_or_create_key
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.
Definition: gpgme.c:273
AutocryptAccount::prefer_encrypt
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:109
AutocryptPeer::keydata
char * keydata
Definition: lib.h:122
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
mx_path_resolve
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
mutt_autocrypt_db_peer_new
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: db.c:516
mutt_autocrypt_set_sign_as_default_key
int mutt_autocrypt_set_sign_as_default_key(struct Mailbox *m, struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:697
mutt_edit_address
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:168
mutt_autocrypt_cleanup
void mutt_autocrypt_cleanup(void)
Shutdown Autocrypt.
Definition: autocrypt.c:135
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
lib.h
Envelope::reply_to
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:62
mutt_buffer_expand_path_regex
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
mutt_autocrypt_db_peer_insert
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: db.c:612
mutt_buffer_addch
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
AutocryptGossipHistory
Autocrypt gossip history.
Definition: lib.h:143
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
AutocryptPeer::gossip_keydata
char * gossip_keydata
Definition: lib.h:126
mutt_autocrypthdr_new
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:65
AutocryptAccount::keyid
char * keyid
Definition: lib.h:107
AutocryptGossipHistory::email_msgid
char * email_msgid
Definition: lib.h:147
OptMenuPopClearScreen
WHERE bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: options.h:40
AutocryptDefaultKey
char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: config.c:43
mutt_autocrypt_scan_mailboxes
void mutt_autocrypt_scan_mailboxes(struct Mailbox *m)
Scan mailboxes for Autocrypt headers.
Definition: autocrypt.c:914
lib.h
muttlib.h
mx_mbox_close
enum MxStatus mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:632
lib.h
AutocryptPeer::prefer_encrypt
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:123
AutocryptPeerHistory
Autocrypt peer history.
Definition: lib.h:132
AUTOCRYPT_REC_OFF
@ AUTOCRYPT_REC_OFF
No recommendations.
Definition: lib.h:157
AutocryptGossipHistory::sender_email_addr
char * sender_email_addr
Definition: lib.h:146
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
mutt_autocrypt_process_autocrypt_header
int mutt_autocrypt_process_autocrypt_header(struct Mailbox *m, struct Email *e, struct Envelope *env)
Parse an Autocrypt email header.
Definition: autocrypt.c:256
mutt_autocrypt_db_peer_history_insert
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition: db.c:759
AutocryptAccount::enabled
bool enabled
Definition: lib.h:110
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_autocrypt_db_init
int mutt_autocrypt_db_init(struct Mailbox *m, bool can_create)
Initialise the Autocrypt SQLite database.
Definition: db.c:78
mutt_autocrypt_gpgme_init
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition: gpgme.c:65
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
mutt_autocrypthdr_free
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:74
Address::is_intl
bool is_intl
International Domain Name.
Definition: address.h:39
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
AutocryptPeerHistory::timestamp
sqlite3_int64 timestamp
Definition: lib.h:136
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
AUTOCRYPT_REC_DISCOURAGE
@ AUTOCRYPT_REC_DISCOURAGE
Prefer not to use Autocrypt.
Definition: lib.h:159
Email::security
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:39
mutt_date_epoch
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
mutt_autocrypt_write_gossip_headers
int mutt_autocrypt_write_gossip_headers(struct Mailbox *m, struct Envelope *env, FILE *fp)
Write the Autocrypt gossip headers to a file.
Definition: autocrypt.c:801
mutt_autocrypt_db_normalize_addrlist
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: db.c:173
C_AutocryptDir
char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and SQLite database.
Definition: config.c:40
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
lib.h
lib.h
mutt_autocrypt_init
int mutt_autocrypt_init(struct Mailbox *m, bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:95
AutocryptPeer
Autocrypt peer.
Definition: lib.h:116
mutt_file_mkdir
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
mutt_addr_copy
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:716
mutt_autocrypt_db_account_get
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:260
AutocryptHeader::prefer_encrypt
bool prefer_encrypt
Definition: envelope.h:45
lib.h
AutocryptPeerHistory::keydata
char * keydata
Definition: lib.h:137
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
AutocryptPeer::gossip_timestamp
sqlite3_int64 gossip_timestamp
Definition: lib.h:124
TAILQ_NEXT
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
mutt_autocrypt_db_gossip_history_new
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: db.c:807
AutocryptPeer::last_seen
sqlite3_int64 last_seen
Definition: lib.h:119
AutocryptAccount::keydata
char * keydata
Definition: lib.h:108
mutt_autocrypt_gpgme_import_key
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition: gpgme.c:314
mutt_autocrypt_db_peer_free
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:525
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
mx_mbox_open
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:309
AutocryptHeader
Parse Autocrypt header info.
Definition: envelope.h:41
C_HeaderCache
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:40
context.h
mutt_autocrypt_write_autocrypt_header
int mutt_autocrypt_write_autocrypt_header(struct Mailbox *m, struct Envelope *env, FILE *fp)
Write the Autocrypt header to a file.
Definition: autocrypt.c:763
mutt_autocrypt_db_peer_update
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: db.c:675
C_From
WHERE struct Address * C_From
Config: Default 'From' address to use, if isn't otherwise set.
Definition: mutt_globals.h:81
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
private.h
AutocryptPeer::gossip_keyid
char * gossip_keyid
Definition: lib.h:125
mutt_buffer_enter_fname
int mutt_buffer_enter_fname(const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:772
AutocryptHeader::keydata
char * keydata
Definition: envelope.h:44
mx.h
mutt_autocrypt_ui_recommendation
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Mailbox *m, struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:561
lib.h
AutocryptGossipHistory::timestamp
sqlite3_int64 timestamp
Definition: lib.h:148
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
TYPE_MULTIPART
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_autocrypt_gpgme_is_valid_key
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition: gpgme.c:355
write_autocrypt_header_line
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:733
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
AutocryptGossipHistory::gossip_keydata
char * gossip_keydata
Definition: lib.h:149
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
AutocryptRec
AutocryptRec
Recommendation.
Definition: lib.h:155
AUTOCRYPT_REC_AVAILABLE
@ AUTOCRYPT_REC_AVAILABLE
Autocrypt is available.
Definition: lib.h:160
AutocryptPeerHistory::email_msgid
char * email_msgid
Definition: lib.h:135
mutt_autocrypt_db_close
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition: db.c:127
mutt_autocrypt_db_peer_get
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: db.c:547
AutocryptSignAs
char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: config.c:42
Address
An email address.
Definition: address.h:34
Body::mime_headers
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
Address::intl_checked
bool intl_checked
Checked for IDN?
Definition: address.h:40
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
Envelope::autocrypt_gossip
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
mutt_error
#define mutt_error(...)
Definition: logging.h:84