NeoMutt  2021-02-05-666-ge300cd
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 <stdint.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include "private.h"
37 #include "mutt/lib.h"
38 #include "address/lib.h"
39 #include "config/lib.h"
40 #include "email/lib.h"
41 #include "core/lib.h"
42 #include "gui/lib.h"
43 #include "lib.h"
44 #include "ncrypt/lib.h"
45 #include "question/lib.h"
46 #include "send/lib.h"
47 #include "browser.h"
48 #include "muttlib.h"
49 #include "mx.h"
50 #include "options.h"
51 
58 static int autocrypt_dir_init(bool can_create)
59 {
60  int rc = 0;
61  struct stat sb;
62 
63  const char *const c_autocrypt_dir =
64  cs_subset_path(NeoMutt->sub, "autocrypt_dir");
65  if (stat(c_autocrypt_dir, &sb) == 0)
66  return 0;
67 
68  if (!can_create)
69  return -1;
70 
71  struct Buffer *prompt = mutt_buffer_pool_get();
72  /* L10N: s is a directory. NeoMutt is looking for a directory it needs
73  for some reason (e.g. autocrypt, header cache, bcache), but it
74  doesn't exist. The prompt is asking whether to create the directory */
75  mutt_buffer_printf(prompt, _("%s does not exist. Create it?"), c_autocrypt_dir);
77  {
78  if (mutt_file_mkdir(c_autocrypt_dir, S_IRWXU) < 0)
79  {
80  /* L10N: mkdir() on the directory %s failed. The second %s is the
81  error message returned by libc */
82  mutt_error(_("Can't create %s: %s"), c_autocrypt_dir, strerror(errno));
83  rc = -1;
84  }
85  }
86 
87  mutt_buffer_pool_release(&prompt);
88  return rc;
89 }
90 
98 int mutt_autocrypt_init(struct Mailbox *m, bool can_create)
99 {
100  if (AutocryptDB)
101  return 0;
102 
103  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
104  const char *const c_autocrypt_dir =
105  cs_subset_path(NeoMutt->sub, "autocrypt_dir");
106  if (!c_autocrypt || !c_autocrypt_dir)
107  return -1;
108 
109  OptIgnoreMacroEvents = true;
110  /* The init process can display menus at various points
111  *(e.g. browser, pgp key selection). This allows the screen to be
112  * autocleared after each menu, so the subsequent prompts can be
113  * read. */
114  OptMenuPopClearScreen = true;
115 
116  if (autocrypt_dir_init(can_create))
117  goto bail;
118 
120  goto bail;
121 
122  if (mutt_autocrypt_db_init(m, can_create))
123  goto bail;
124 
125  OptIgnoreMacroEvents = false;
126  OptMenuPopClearScreen = false;
127 
128  return 0;
129 
130 bail:
131  OptIgnoreMacroEvents = false;
132  OptMenuPopClearScreen = false;
133  cs_subset_str_native_set(NeoMutt->sub, "autocrypt", false, NULL);
135  return -1;
136 }
137 
142 {
144 }
145 
156 {
157  struct Address *addr = NULL;
158  struct AutocryptAccount *account = NULL;
159  bool done = false;
160  int rc = -1;
161  bool prefer_encrypt = false;
162 
163  if (prompt)
164  {
165  /* L10N: The first time NeoMutt is started with $autocrypt set, it will
166  create $autocrypt_dir and then prompt to create an autocrypt account
167  with this message. */
168  if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
169  return 0;
170  }
171 
172  struct Buffer *keyid = mutt_buffer_pool_get();
173  struct Buffer *keydata = mutt_buffer_pool_get();
174 
175  const struct Address *c_from = cs_subset_address(NeoMutt->sub, "from");
176  if (c_from)
177  {
178  addr = mutt_addr_copy(c_from);
179  const char *const c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
180  if (!addr->personal && c_real_name)
181  addr->personal = mutt_str_dup(c_real_name);
182  }
183 
184  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
185  mutt_addrlist_append(&al, addr);
186 
187  do
188  {
189  /* L10N: Autocrypt is asking for the email address to use for the
190  autocrypt account. This will generate a key and add a record
191  to the database for use in autocrypt operations. */
192  if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
193  goto cleanup;
194 
195  addr = TAILQ_FIRST(&al);
196  if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
197  {
198  /* L10N: Autocrypt prompts for an account email address, and requires
199  a single address. This is shown if they entered something invalid,
200  nothing, or more than one address for some reason. */
201  mutt_error(_("Please enter a single email address"));
202  done = false;
203  }
204  else
205  done = true;
206  } while (!done);
207 
208  addr = TAILQ_FIRST(&al);
209  if (mutt_autocrypt_db_account_get(addr, &account) < 0)
210  goto cleanup;
211  if (account)
212  {
213  /* L10N: When creating an autocrypt account, this message will be displayed
214  if there is already an account in the database with the email address
215  they just entered. */
216  mutt_error(_("That email address already has an autocrypt account"));
217  goto cleanup;
218  }
219 
220  if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
221  goto cleanup;
222 
223  /* L10N: Autocrypt has a setting "prefer-encrypt".
224  When the recommendation algorithm returns "available" and BOTH sender and
225  recipient choose "prefer-encrypt", encryption will be automatically
226  enabled.
227  Otherwise the UI will show encryption is "available" but the user
228  will be required to enable encryption manually. */
229  if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
230  prefer_encrypt = true;
231 
233  mutt_buffer_string(keydata), prefer_encrypt))
234  {
235  goto cleanup;
236  }
237 
238  rc = 0;
239 
240 cleanup:
241  if (rc == 0)
242  {
243  /* L10N: Message displayed after an autocrypt account is successfully created. */
244  mutt_message(_("Autocrypt account creation succeeded"));
245  }
246  else
247  {
248  /* L10N: Error message displayed if creating an autocrypt account failed
249  or was aborted by the user. */
250  mutt_error(_("Autocrypt account creation aborted"));
251  }
252 
254  mutt_addrlist_clear(&al);
255  mutt_buffer_pool_release(&keyid);
256  mutt_buffer_pool_release(&keydata);
257  return rc;
258 }
259 
269  struct Envelope *env)
270 {
271  struct AutocryptHeader *valid_ac_hdr = NULL;
272  struct AutocryptPeer *peer = NULL;
273  struct AutocryptPeerHistory *peerhist = NULL;
274  struct Buffer *keyid = NULL;
275  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
276  int rc = -1;
277 
278  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
279  if (!c_autocrypt)
280  return 0;
281 
282  if (mutt_autocrypt_init(m, false))
283  return -1;
284 
285  if (!e || !e->body || !env)
286  return 0;
287 
288  /* 1.1 spec says to skip emails with more than one From header */
289  struct Address *from = TAILQ_FIRST(&env->from);
290  if (!from || TAILQ_NEXT(from, entries))
291  return 0;
292 
293  /* 1.1 spec also says to skip multipart/report emails */
294  if ((e->body->type == TYPE_MULTIPART) &&
295  mutt_istr_equal(e->body->subtype, "report"))
296  {
297  return 0;
298  }
299 
300  /* Ignore emails that appear to be more than a week in the future,
301  * since they can block all future updates during that time. */
302  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
303  return 0;
304 
305  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
306  {
307  if (ac_hdr->invalid)
308  continue;
309 
310  /* NOTE: this assumes the processing is occurring right after
311  * mutt_parse_rfc822_line() and the from ADDR is still in the same
312  * form (intl) as the autocrypt header addr field */
313  if (!mutt_istr_equal(from->mailbox, ac_hdr->addr))
314  continue;
315 
316  /* 1.1 spec says ignore all, if more than one valid header is found. */
317  if (valid_ac_hdr)
318  {
319  valid_ac_hdr = NULL;
320  break;
321  }
322  valid_ac_hdr = ac_hdr;
323  }
324 
325  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
326  goto cleanup;
327 
328  if (peer)
329  {
330  if (e->date_sent <= peer->autocrypt_timestamp)
331  {
332  rc = 0;
333  goto cleanup;
334  }
335 
336  if (e->date_sent > peer->last_seen)
337  {
338  update_db = true;
339  peer->last_seen = e->date_sent;
340  }
341 
342  if (valid_ac_hdr)
343  {
344  update_db = true;
345  peer->autocrypt_timestamp = e->date_sent;
346  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
347  if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
348  {
349  import_gpg = true;
350  insert_db_history = true;
351  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
352  }
353  }
354  }
355  else if (valid_ac_hdr)
356  {
357  import_gpg = true;
358  insert_db = true;
359  insert_db_history = true;
360  }
361 
362  if (!(import_gpg || insert_db || update_db))
363  {
364  rc = 0;
365  goto cleanup;
366  }
367 
368  if (!peer)
369  {
371  peer->last_seen = e->date_sent;
372  peer->autocrypt_timestamp = e->date_sent;
373  peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
374  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
375  }
376 
377  if (import_gpg)
378  {
379  keyid = mutt_buffer_pool_get();
380  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
381  goto cleanup;
382  mutt_str_replace(&peer->keyid, mutt_buffer_string(keyid));
383  }
384 
385  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
386  goto cleanup;
387 
388  if (update_db && mutt_autocrypt_db_peer_update(peer))
389  goto cleanup;
390 
391  if (insert_db_history)
392  {
394  peerhist->email_msgid = mutt_str_dup(env->message_id);
395  peerhist->timestamp = e->date_sent;
396  peerhist->keydata = mutt_str_dup(peer->keydata);
397  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
398  goto cleanup;
399  }
400 
401  rc = 0;
402 
403 cleanup:
406  mutt_buffer_pool_release(&keyid);
407 
408  return rc;
409 }
410 
420  struct Envelope *prot_headers)
421 {
422  struct AutocryptPeer *peer = NULL;
423  struct AutocryptGossipHistory *gossip_hist = NULL;
424  struct Address *peer_addr = NULL;
425  struct Address ac_hdr_addr = { 0 };
426  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
427  int rc = -1;
428 
429  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
430  if (!c_autocrypt)
431  return 0;
432 
433  if (mutt_autocrypt_init(m, false))
434  return -1;
435 
436  if (!e || !e->env || !prot_headers)
437  return 0;
438 
439  struct Envelope *env = e->env;
440 
441  struct Address *from = TAILQ_FIRST(&env->from);
442  if (!from)
443  return 0;
444 
445  /* Ignore emails that appear to be more than a week in the future,
446  * since they can block all future updates during that time. */
447  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
448  return 0;
449 
450  struct Buffer *keyid = mutt_buffer_pool_get();
451 
452  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
453 
454  /* Normalize the recipient list for comparison */
455  mutt_addrlist_copy(&recips, &env->to, false);
456  mutt_addrlist_copy(&recips, &env->cc, false);
457  mutt_addrlist_copy(&recips, &env->reply_to, false);
459 
460  for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
461  ac_hdr = ac_hdr->next)
462  {
463  if (ac_hdr->invalid)
464  continue;
465 
466  /* normalize for comparison against recipient list */
467  mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
468  ac_hdr_addr.is_intl = true;
469  ac_hdr_addr.intl_checked = true;
470  mutt_autocrypt_db_normalize_addr(&ac_hdr_addr);
471 
472  /* Check to make sure the address is in the recipient list. */
473  TAILQ_FOREACH(peer_addr, &recips, entries)
474  {
475  if (mutt_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
476  break;
477  }
478 
479  if (!peer_addr)
480  continue;
481 
482  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
483  goto cleanup;
484 
485  if (peer)
486  {
487  if (e->date_sent <= peer->gossip_timestamp)
488  {
490  continue;
491  }
492 
493  update_db = true;
494  peer->gossip_timestamp = e->date_sent;
495  /* This is slightly different from the autocrypt 1.1 spec.
496  * Avoid setting an empty peer.gossip_keydata with a value that matches
497  * the current peer.keydata. */
498  if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
499  (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
500  {
501  import_gpg = true;
502  insert_db_history = true;
503  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
504  }
505  }
506  else
507  {
508  import_gpg = true;
509  insert_db = true;
510  insert_db_history = true;
511  }
512 
513  if (!peer)
514  {
516  peer->gossip_timestamp = e->date_sent;
517  peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
518  }
519 
520  if (import_gpg)
521  {
523  goto cleanup;
525  }
526 
527  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
528  goto cleanup;
529 
530  if (update_db && mutt_autocrypt_db_peer_update(peer))
531  goto cleanup;
532 
533  if (insert_db_history)
534  {
535  gossip_hist = mutt_autocrypt_db_gossip_history_new();
536  gossip_hist->sender_email_addr = mutt_str_dup(from->mailbox);
537  gossip_hist->email_msgid = mutt_str_dup(env->message_id);
538  gossip_hist->timestamp = e->date_sent;
539  gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
540  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
541  goto cleanup;
542  }
543 
546  mutt_buffer_reset(keyid);
547  update_db = false;
548  insert_db = false;
549  insert_db_history = false;
550  import_gpg = false;
551  }
552 
553  rc = 0;
554 
555 cleanup:
556  FREE(&ac_hdr_addr.mailbox);
557  mutt_addrlist_clear(&recips);
560  mutt_buffer_pool_release(&keyid);
561 
562  return rc;
563 }
564 
576  struct Email *e, char **keylist)
577 {
579  struct AutocryptAccount *account = NULL;
580  struct AutocryptPeer *peer = NULL;
581  struct Address *recip = NULL;
582  bool all_encrypt = true, has_discourage = false;
583  const char *matching_key = NULL;
584  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
585  struct Buffer *keylist_buf = NULL;
586 
587  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
588  if (!c_autocrypt || mutt_autocrypt_init(m, false) || !e)
589  {
590  if (keylist)
591  {
592  /* L10N: Error displayed if the user tries to force sending an Autocrypt
593  email when the engine is not available. */
594  mutt_message(_("Autocrypt is not available"));
595  }
596  return AUTOCRYPT_REC_OFF;
597  }
598 
599  struct Address *from = TAILQ_FIRST(&e->env->from);
600  if (!from || TAILQ_NEXT(from, entries))
601  {
602  if (keylist)
603  mutt_message(_("Autocrypt is not available"));
604  return AUTOCRYPT_REC_OFF;
605  }
606 
607  if (e->security & APPLICATION_SMIME)
608  {
609  if (keylist)
610  mutt_message(_("Autocrypt is not available"));
611  return AUTOCRYPT_REC_OFF;
612  }
613 
614  if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
615  {
616  if (keylist)
617  {
618  /* L10N: Error displayed if the user tries to force sending an Autocrypt
619  email when the account does not exist or is not enabled.
620  %s is the From email address used to look up the Autocrypt account.
621  */
622  mutt_message(_("Autocrypt is not enabled for %s"), NONULL(from->mailbox));
623  }
624  goto cleanup;
625  }
626 
627  keylist_buf = mutt_buffer_pool_get();
628  mutt_buffer_addstr(keylist_buf, account->keyid);
629 
630  mutt_addrlist_copy(&recips, &e->env->to, false);
631  mutt_addrlist_copy(&recips, &e->env->cc, false);
632  mutt_addrlist_copy(&recips, &e->env->bcc, false);
633 
634  rc = AUTOCRYPT_REC_NO;
635  if (TAILQ_EMPTY(&recips))
636  goto cleanup;
637 
638  TAILQ_FOREACH(recip, &recips, entries)
639  {
640  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
641  {
642  if (keylist)
643  {
644  /* L10N: s is an email address. Autocrypt is scanning for the keyids
645  to use to encrypt, but it can't find a valid keyid for this address.
646  The message is printed and they are returned to the compose menu. */
647  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
648  }
649  goto cleanup;
650  }
651 
653  {
654  matching_key = peer->keyid;
655 
656  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
657  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
658  {
659  has_discourage = true;
660  all_encrypt = false;
661  }
662 
663  if (!account->prefer_encrypt || !peer->prefer_encrypt)
664  all_encrypt = false;
665  }
667  {
668  matching_key = peer->gossip_keyid;
669 
670  has_discourage = true;
671  all_encrypt = false;
672  }
673  else
674  {
675  if (keylist)
676  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
677  goto cleanup;
678  }
679 
680  if (!mutt_buffer_is_empty(keylist_buf))
681  mutt_buffer_addch(keylist_buf, ' ');
682  mutt_buffer_addstr(keylist_buf, matching_key);
683 
685  }
686 
687  if (all_encrypt)
688  rc = AUTOCRYPT_REC_YES;
689  else if (has_discourage)
691  else
693 
694  if (keylist)
695  mutt_str_replace(keylist, mutt_buffer_string(keylist_buf));
696 
697 cleanup:
699  mutt_addrlist_clear(&recips);
701  mutt_buffer_pool_release(&keylist_buf);
702  return rc;
703 }
704 
713 {
714  int rc = -1;
715  struct AutocryptAccount *account = NULL;
716 
717  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
718  if (!c_autocrypt || mutt_autocrypt_init(m, false) || !e)
719  return -1;
720 
721  struct Address *from = TAILQ_FIRST(&e->env->from);
722  if (!from || TAILQ_NEXT(from, entries))
723  return -1;
724 
725  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
726  goto cleanup;
727  if (!account->keyid)
728  goto cleanup;
729  if (!account->enabled)
730  goto cleanup;
731 
734 
735  rc = 0;
736 
737 cleanup:
739  return rc;
740 }
741 
749 static void write_autocrypt_header_line(FILE *fp, const char *addr,
750  bool prefer_encrypt, const char *keydata)
751 {
752  fprintf(fp, "addr=%s; ", addr);
753  if (prefer_encrypt)
754  fputs("prefer-encrypt=mutual; ", fp);
755  fputs("keydata=\n", fp);
756 
757  while (*keydata)
758  {
759  int count = 0;
760  fputs("\t", fp);
761  while (*keydata && count < 75)
762  {
763  fputc(*keydata, fp);
764  count++;
765  keydata++;
766  }
767  fputs("\n", fp);
768  }
769 }
770 
779 int mutt_autocrypt_write_autocrypt_header(struct Mailbox *m, struct Envelope *env, FILE *fp)
780 {
781  int rc = -1;
782  struct AutocryptAccount *account = NULL;
783 
784  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
785  if (!c_autocrypt || mutt_autocrypt_init(m, false) || !env)
786  return -1;
787 
788  struct Address *from = TAILQ_FIRST(&env->from);
789  if (!from || TAILQ_NEXT(from, entries))
790  return -1;
791 
792  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
793  goto cleanup;
794  if (!account->keydata)
795  goto cleanup;
796  if (!account->enabled)
797  goto cleanup;
798 
799  fputs("Autocrypt: ", fp);
801  account->keydata);
802 
803  rc = 0;
804 
805 cleanup:
807  return rc;
808 }
809 
818 int mutt_autocrypt_write_gossip_headers(struct Mailbox *m, struct Envelope *env, FILE *fp)
819 {
820  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
821  if (!c_autocrypt || mutt_autocrypt_init(m, false) || !env)
822  return -1;
823 
824  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
825  gossip = gossip->next)
826  {
827  fputs("Autocrypt-Gossip: ", fp);
828  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
829  }
830 
831  return 0;
832 }
833 
842 {
843  int rc = -1;
844  struct AutocryptPeer *peer = NULL;
845  struct AutocryptAccount *account = NULL;
846  struct Address *recip = NULL;
847 
848  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
849  if (!c_autocrypt || mutt_autocrypt_init(m, false) || !e)
850  return -1;
851 
852  struct Envelope *mime_headers = e->body->mime_headers;
853  if (!mime_headers)
854  mime_headers = e->body->mime_headers = mutt_env_new();
856 
857  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
858 
859  mutt_addrlist_copy(&recips, &e->env->to, false);
860  mutt_addrlist_copy(&recips, &e->env->cc, false);
861 
862  TAILQ_FOREACH(recip, &recips, entries)
863  {
864  /* At this point, we just accept missing keys and include what we can. */
865  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
866  continue;
867 
868  const char *keydata = NULL;
870  keydata = peer->keydata;
872  keydata = peer->gossip_keydata;
873 
874  if (keydata)
875  {
876  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
877  gossip->addr = mutt_str_dup(peer->email_addr);
878  gossip->keydata = mutt_str_dup(keydata);
879  gossip->next = mime_headers->autocrypt_gossip;
880  mime_headers->autocrypt_gossip = gossip;
881  }
882 
884  }
885 
886  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
887  {
888  const char *addr = NULL;
889  const char *keydata = NULL;
890  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
891  {
892  addr = account->email_addr;
893  keydata = account->keydata;
894  }
895  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
896  {
897  addr = peer->email_addr;
899  keydata = peer->keydata;
901  keydata = peer->gossip_keydata;
902  }
903 
904  if (keydata)
905  {
906  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
907  gossip->addr = mutt_str_dup(addr);
908  gossip->keydata = mutt_str_dup(keydata);
909  gossip->next = mime_headers->autocrypt_gossip;
910  mime_headers->autocrypt_gossip = gossip;
911  }
914  }
915 
916  mutt_addrlist_clear(&recips);
919  return rc;
920 }
921 
934 {
935 #ifdef USE_HCACHE
936  const char *c_header_cache = cs_subset_path(NeoMutt->sub, "header_cache");
937  char *old_hdrcache = mutt_str_dup(c_header_cache);
938  c_header_cache = NULL;
939 #endif
940 
941  struct Buffer *folderbuf = mutt_buffer_pool_get();
942 
943  /* L10N: The first time autocrypt is enabled, NeoMutt will ask to scan
944  through one or more mailboxes for Autocrypt: headers. Those headers are
945  then captured in the database as peer records and used for encryption.
946  If this is answered yes, they will be prompted for a mailbox. */
947  enum QuadOption scan =
948  mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
949  while (scan == MUTT_YES)
950  {
951  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
952  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true, m, false,
953  NULL, NULL, MUTT_SEL_NO_FLAGS)) &&
954  (!mutt_buffer_is_empty(folderbuf)))
955  {
956  mutt_buffer_expand_path_regex(folderbuf, false);
957  struct Mailbox *m_ac = mx_path_resolve(mutt_buffer_string(folderbuf));
958  /* NOTE: I am purposely *not* executing folder hooks here,
959  * as they can do all sorts of things like push into the getch() buffer.
960  * Authentication should be in account-hooks. */
962  mx_mbox_close(m_ac);
963  mutt_buffer_reset(folderbuf);
964  }
965 
966  /* L10N: This is the second prompt to see if the user would like
967  to scan more than one mailbox for Autocrypt headers.
968  I'm purposely being extra verbose; asking first then prompting
969  for a mailbox. This is because this is a one-time operation
970  and I don't want them to accidentally ctrl-g and abort it. */
971  scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
972  }
973 
974 #ifdef USE_HCACHE
975  cs_subset_str_native_set(NeoMutt->sub, "header_cache", (intptr_t) old_hdrcache, NULL);
976  old_hdrcache = NULL;
977 #endif
978  mutt_buffer_pool_release(&folderbuf);
979 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Mailbox *m, struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:575
Convenience wrapper for the gui headers.
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
AutocryptRec
Recommendation.
Definition: lib.h:154
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition: db.c:132
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: db.c:167
sqlite3 * AutocryptDB
Definition: db.c:52
#define NONULL(x)
Definition: string2.h:37
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: db.c:736
int mutt_autocrypt_generate_gossip_list(struct Mailbox *m, struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:841
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:723
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition: gpgme.c:67
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:65
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
struct Body * body
List of MIME parts.
Definition: email.h:91
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
Structs that make up an email.
#define mutt_error(...)
Definition: logging.h:88
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:246
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition: db.c:823
Convenience wrapper for the send headers.
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:419
Autocrypt should be used.
Definition: lib.h:160
bool prefer_encrypt
Definition: envelope.h:45
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:1470
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:58
char * email_msgid
Definition: lib.h:134
char * keydata
Definition: lib.h:121
sqlite3_int64 timestamp
Definition: lib.h:135
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
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
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: db.c:521
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:35
struct AutocryptHeader * autocrypt
Definition: envelope.h:85
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:36
char * mailbox
Mailbox and host address.
Definition: address.h:38
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:37
char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: config.c:35
No recommendations.
Definition: lib.h:156
char * email_addr
Definition: lib.h:105
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: helpers.c:49
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:610
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:716
char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: config.c:36
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * keyid
Definition: lib.h:106
char * gossip_keydata
Definition: lib.h:125
int mutt_autocrypt_account_init(bool prompt)
Create a new Autocrypt account.
Definition: autocrypt.c:155
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
Convenience wrapper for the config headers.
GUI component for displaying/selecting items from a list.
bool is_intl
International Domain Name.
Definition: address.h:40
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:134
Do no use Autocrypt.
Definition: lib.h:157
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
sqlite3_int64 gossip_timestamp
Definition: lib.h:123
Some miscellaneous functions.
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:119
char * sender_email_addr
Definition: lib.h:145
char * message_id
Message ID.
Definition: envelope.h:69
bool enabled
Definition: lib.h:109
API for mailboxes.
Autocrypt peer.
Definition: lib.h:115
char * keydata
Definition: envelope.h:44
char * email_msgid
Definition: lib.h:146
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:877
WHERE bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: options.h:39
struct Envelope * env
Envelope information.
Definition: email.h:90
Convenience wrapper for the core headers.
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:275
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
char * email_addr
Definition: lib.h:117
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:108
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
int mutt_autocrypt_set_sign_as_default_key(struct Mailbox *m, struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:712
bool intl_checked
Checked for IDN?
Definition: address.h:41
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:818
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
void mutt_autocrypt_cleanup(void)
Shutdown Autocrypt.
Definition: autocrypt.c:141
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
void mutt_autocrypt_scan_mailboxes(struct Mailbox *m)
Scan mailboxes for Autocrypt headers.
Definition: autocrypt.c:933
int mutt_autocrypt_process_autocrypt_header(struct Mailbox *m, struct Email *e, struct Envelope *env)
Parse an Autocrypt email header.
Definition: autocrypt.c:268
int mutt_autocrypt_init(struct Mailbox *m, bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:98
A mailbox.
Definition: mailbox.h:81
Autocrypt gossip history.
Definition: lib.h:142
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition: gpgme.c:357
sqlite3_int64 last_seen
Definition: lib.h:118
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: db.c:617
Shared constants/structs that are private to Autocrypt.
struct AutocryptHeader * next
Definition: envelope.h:47
#define MUTT_READONLY
Open in read-only mode.
Definition: mxapi.h:63
char * gossip_keyid
Definition: lib.h:124
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
API for encryption/signing of emails.
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:74
Ask the user a question.
int mutt_autocrypt_db_init(struct Mailbox *m, bool can_create)
Initialise the Autocrypt SQLite database.
Definition: db.c:80
Prefer not to use Autocrypt.
Definition: lib.h:158
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: db.c:814
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
char * addr
Definition: envelope.h:43
Autocrypt peer history.
Definition: lib.h:131
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/lib.h pgplib...
Definition: email.h:39
Parse Autocrypt header info.
Definition: envelope.h:41
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition: db.c:764
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:265
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:122
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: db.c:178
char * personal
Real name of address.
Definition: address.h:37
char * keydata
Definition: lib.h:136
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: db.c:680
Autocrypt account.
Definition: lib.h:103
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
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:513
int mutt_autocrypt_write_autocrypt_header(struct Mailbox *m, struct Envelope *env, FILE *fp)
Write the Autocrypt header to a file.
Definition: autocrypt.c:779
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
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:749
char * keydata
Definition: lib.h:107
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1668
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:530
Autocrypt is available.
Definition: lib.h:159
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
Handling of global boolean variables.
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
char * gossip_keydata
Definition: lib.h:148
#define TAILQ_EMPTY(head)
Definition: queue.h:721
Convenience wrapper for the library headers.
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: db.c:745
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:637
char * keyid
Definition: lib.h:120
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: db.c:552
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:843
sqlite3_int64 timestamp
Definition: lib.h:147
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:187
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:1490
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
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:324
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition: gpgme.c:316