NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
autocrypt.c File Reference

Autocrypt end-to-end encryption. More...

#include "config.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "gui/lib.h"
#include "autocrypt/lib.h"
#include "hcache/lib.h"
#include "ncrypt/lib.h"
#include "send/lib.h"
#include "mutt_globals.h"
#include "muttlib.h"
#include "mx.h"
#include "options.h"
+ Include dependency graph for autocrypt.c:

Go to the source code of this file.

Functions

static int autocrypt_dir_init (bool can_create)
 Initialise an Autocrypt directory. More...
 
int mutt_autocrypt_init (bool can_create)
 Initialise Autocrypt. More...
 
void mutt_autocrypt_cleanup (void)
 Shutdown Autocrypt. More...
 
int mutt_autocrypt_account_init (bool prompt)
 Create a new Autocrypt account. More...
 
int mutt_autocrypt_process_autocrypt_header (struct Email *e, struct Envelope *env)
 Parse an Autocrypt email header. More...
 
int mutt_autocrypt_process_gossip_header (struct Email *e, struct Envelope *prot_headers)
 Parse an Autocrypt email gossip header. More...
 
enum AutocryptRec mutt_autocrypt_ui_recommendation (struct Email *e, char **keylist)
 Get the recommended action for an Email. More...
 
int mutt_autocrypt_set_sign_as_default_key (struct Email *e)
 Set the Autocrypt default key for signing. More...
 
static void write_autocrypt_header_line (FILE *fp, const char *addr, bool prefer_encrypt, const char *keydata)
 Write an Autocrypt header to a file. More...
 
int mutt_autocrypt_write_autocrypt_header (struct Envelope *env, FILE *fp)
 Write the Autocrypt header to a file. More...
 
int mutt_autocrypt_write_gossip_headers (struct Envelope *env, FILE *fp)
 Write the Autocrypt gossip headers to a file. More...
 
int mutt_autocrypt_generate_gossip_list (struct Email *e)
 Create the gossip list headers. More...
 
void mutt_autocrypt_scan_mailboxes (void)
 Scan mailboxes for Autocrypt headers. More...
 

Detailed Description

Autocrypt end-to-end encryption.

Authors
  • Kevin J. McCarthy

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file autocrypt.c.

Function Documentation

◆ autocrypt_dir_init()

static int autocrypt_dir_init ( bool  can_create)
static

Initialise an Autocrypt directory.

Parameters
can_createIf true, the directory may be created
Return values
0Success
-1Error

Definition at line 56 of file autocrypt.c.

57 {
58  int rc = 0;
59  struct stat sb;
60 
61  if (stat(C_AutocryptDir, &sb) == 0)
62  return 0;
63 
64  if (!can_create)
65  return -1;
66 
67  struct Buffer *prompt = mutt_buffer_pool_get();
68  /* L10N: s is a directory. NeoMutt is looking for a directory it needs
69  for some reason (e.g. autocrypt, header cache, bcache), but it
70  doesn't exist. The prompt is asking whether to create the directory */
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: mkdir() on the directory %s failed. The second %s is the
77  error message returned by libc */
78  mutt_error(_("Can't create %s: %s"), C_AutocryptDir, strerror(errno));
79  rc = -1;
80  }
81  }
82 
83  mutt_buffer_pool_release(&prompt);
84  return rc;
85 }
char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and SQLite database.
Definition: config.c:40
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_error(...)
Definition: logging.h:84
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_init()

int mutt_autocrypt_init ( bool  can_create)

Initialise Autocrypt.

Parameters
can_createIf true, directories may be created
Return values
0Success
-1Error

Definition at line 93 of file autocrypt.c.

94 {
95  if (AutocryptDB)
96  return 0;
97 
98  if (!C_Autocrypt || !C_AutocryptDir)
99  return -1;
100 
101  OptIgnoreMacroEvents = true;
102  /* The init process can display menus at various points
103  *(e.g. browser, pgp key selection). This allows the screen to be
104  * autocleared after each menu, so the subsequent prompts can be
105  * read. */
106  OptMenuPopClearScreen = true;
107 
108  if (autocrypt_dir_init(can_create))
109  goto bail;
110 
112  goto bail;
113 
114  if (mutt_autocrypt_db_init(can_create))
115  goto bail;
116 
117  OptIgnoreMacroEvents = false;
118  OptMenuPopClearScreen = false;
119 
120  return 0;
121 
122 bail:
123  OptIgnoreMacroEvents = false;
124  OptMenuPopClearScreen = false;
125  C_Autocrypt = false;
127  return -1;
128 }
char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and SQLite database.
Definition: config.c:40
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition: db.c:125
sqlite3 * AutocryptDB
Definition: db.c:50
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition: gpgme.c:65
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:56
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:38
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt SQLite database.
Definition: db.c:77
WHERE bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: options.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_cleanup()

void mutt_autocrypt_cleanup ( void  )

Shutdown Autocrypt.

Definition at line 133 of file autocrypt.c.

134 {
136 }
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition: db.c:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_account_init()

int mutt_autocrypt_account_init ( bool  prompt)

Create a new Autocrypt account.

Parameters
promptPrompt the user
Return values
0Success
-1Error

This is used the first time autocrypt is initialized, and in the account menu.

Definition at line 147 of file autocrypt.c.

148 {
149  struct Address *addr = NULL;
150  struct AutocryptAccount *account = NULL;
151  bool done = false;
152  int rc = -1;
153  bool prefer_encrypt = false;
154 
155  if (prompt)
156  {
157  /* L10N: The first time NeoMutt is started with $autocrypt set, it will
158  create $autocrypt_dir and then prompt to create an autocrypt account
159  with this message. */
160  if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
161  return 0;
162  }
163 
164  struct Buffer *keyid = mutt_buffer_pool_get();
165  struct Buffer *keydata = mutt_buffer_pool_get();
166 
167  if (C_From)
168  {
169  addr = mutt_addr_copy(C_From);
170  if (!addr->personal && C_Realname)
172  }
173 
174  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
175  mutt_addrlist_append(&al, addr);
176 
177  do
178  {
179  /* L10N: Autocrypt is asking for the email address to use for the
180  autocrypt account. This will generate a key and add a record
181  to the database for use in autocrypt operations. */
182  if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
183  goto cleanup;
184 
185  addr = TAILQ_FIRST(&al);
186  if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
187  {
188  /* L10N: 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  mutt_error(_("Please enter a single email address"));
192  done = false;
193  }
194  else
195  done = true;
196  } while (!done);
197 
198  addr = TAILQ_FIRST(&al);
199  if (mutt_autocrypt_db_account_get(addr, &account) < 0)
200  goto cleanup;
201  if (account)
202  {
203  /* L10N: When creating an autocrypt account, this message will be displayed
204  if there is already an account in the database with the email address
205  they just entered. */
206  mutt_error(_("That email address already has an autocrypt account"));
207  goto cleanup;
208  }
209 
210  if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
211  goto cleanup;
212 
213  /* L10N: Autocrypt has a setting "prefer-encrypt".
214  When the recommendation algorithm returns "available" and BOTH sender and
215  recipient choose "prefer-encrypt", encryption will be automatically
216  enabled.
217  Otherwise the UI will show encryption is "available" but the user
218  will be required to enable encryption manually. */
219  if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
220  prefer_encrypt = true;
221 
222  if (mutt_autocrypt_db_account_insert(addr, mutt_b2s(keyid), mutt_b2s(keydata), prefer_encrypt))
223  goto cleanup;
224 
225  rc = 0;
226 
227 cleanup:
228  if (rc == 0)
229  /* L10N: Message displayed after an autocrypt account is successfully created. */
230  mutt_message(_("Autocrypt account creation succeeded"));
231  else
232  /* L10N: Error message displayed if creating an autocrypt account failed
233  or was aborted by the user. */
234  mutt_error(_("Autocrypt account creation aborted"));
235 
237  mutt_addrlist_clear(&al);
238  mutt_buffer_pool_release(&keyid);
239  mutt_buffer_pool_release(&keydata);
240  return rc;
241 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:239
#define mutt_message(...)
Definition: logging.h:83
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
WHERE char * C_Realname
Config: Real name of the user.
Definition: mutt_globals.h:105
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:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:716
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
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
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:108
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: mutt_globals.h:81
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:258
char * personal
Real name of address.
Definition: address.h:36
Autocrypt account.
Definition: lib.h:103
#define mutt_error(...)
Definition: logging.h:84
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:167
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1488
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
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:317
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_process_autocrypt_header()

int mutt_autocrypt_process_autocrypt_header ( struct Email e,
struct Envelope env 
)

Parse an Autocrypt email header.

Parameters
eEmail
envEnvelope
Return values
0Success
-1Error

Definition at line 250 of file autocrypt.c.

251 {
252  struct AutocryptHeader *valid_ac_hdr = NULL;
253  struct AutocryptPeer *peer = NULL;
254  struct AutocryptPeerHistory *peerhist = NULL;
255  struct Buffer *keyid = NULL;
256  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
257  int rc = -1;
258 
259  if (!C_Autocrypt)
260  return 0;
261 
262  if (mutt_autocrypt_init(false))
263  return -1;
264 
265  if (!e || !e->body || !env)
266  return 0;
267 
268  /* 1.1 spec says to skip emails with more than one From header */
269  struct Address *from = TAILQ_FIRST(&env->from);
270  if (!from || TAILQ_NEXT(from, entries))
271  return 0;
272 
273  /* 1.1 spec also says to skip multipart/report emails */
274  if ((e->body->type == TYPE_MULTIPART) &&
275  mutt_istr_equal(e->body->subtype, "report"))
276  {
277  return 0;
278  }
279 
280  /* Ignore emails that appear to be more than a week in the future,
281  * since they can block all future updates during that time. */
282  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
283  return 0;
284 
285  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
286  {
287  if (ac_hdr->invalid)
288  continue;
289 
290  /* NOTE: this assumes the processing is occurring right after
291  * mutt_parse_rfc822_line() and the from ADDR is still in the same
292  * form (intl) as the autocrypt header addr field */
293  if (!mutt_istr_equal(from->mailbox, ac_hdr->addr))
294  continue;
295 
296  /* 1.1 spec says ignore all, if more than one valid header is found. */
297  if (valid_ac_hdr)
298  {
299  valid_ac_hdr = NULL;
300  break;
301  }
302  valid_ac_hdr = ac_hdr;
303  }
304 
305  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
306  goto cleanup;
307 
308  if (peer)
309  {
310  if (e->date_sent <= peer->autocrypt_timestamp)
311  {
312  rc = 0;
313  goto cleanup;
314  }
315 
316  if (e->date_sent > peer->last_seen)
317  {
318  update_db = true;
319  peer->last_seen = e->date_sent;
320  }
321 
322  if (valid_ac_hdr)
323  {
324  update_db = true;
325  peer->autocrypt_timestamp = e->date_sent;
326  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
327  if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
328  {
329  import_gpg = true;
330  insert_db_history = true;
331  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
332  }
333  }
334  }
335  else if (valid_ac_hdr)
336  {
337  import_gpg = true;
338  insert_db = true;
339  insert_db_history = true;
340  }
341 
342  if (!(import_gpg || insert_db || update_db))
343  {
344  rc = 0;
345  goto cleanup;
346  }
347 
348  if (!peer)
349  {
351  peer->last_seen = e->date_sent;
352  peer->autocrypt_timestamp = e->date_sent;
353  peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
354  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
355  }
356 
357  if (import_gpg)
358  {
359  keyid = mutt_buffer_pool_get();
360  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
361  goto cleanup;
362  mutt_str_replace(&peer->keyid, mutt_b2s(keyid));
363  }
364 
365  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
366  goto cleanup;
367 
368  if (update_db && mutt_autocrypt_db_peer_update(peer))
369  goto cleanup;
370 
371  if (insert_db_history)
372  {
374  peerhist->email_msgid = mutt_str_dup(env->message_id);
375  peerhist->timestamp = e->date_sent;
376  peerhist->keydata = mutt_str_dup(peer->keydata);
377  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
378  goto cleanup;
379  }
380 
381  rc = 0;
382 
383 cleanup:
386  mutt_buffer_pool_release(&keyid);
387 
388  return rc;
389 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: db.c:729
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct Body * body
List of MIME parts.
Definition: email.h:91
bool prefer_encrypt
Definition: envelope.h:45
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
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
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: db.c:514
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
An email address.
Definition: address.h:34
struct AutocryptHeader * autocrypt
Definition: envelope.h:85
char * mailbox
Mailbox and host address.
Definition: address.h:37
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:119
char * message_id
Message ID.
Definition: envelope.h:69
Autocrypt peer.
Definition: lib.h:115
char * keydata
Definition: envelope.h:44
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
char * subtype
content-type subtype
Definition: body.h:37
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
#define mutt_b2s(buf)
Definition: buffer.h:41
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:610
struct AutocryptHeader * next
Definition: envelope.h:47
Autocrypt peer history.
Definition: lib.h:131
Parse Autocrypt header info.
Definition: envelope.h:41
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:757
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:122
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:673
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:523
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: db.c:738
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:545
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition: gpgme.c:314
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_process_gossip_header()

int mutt_autocrypt_process_gossip_header ( struct Email e,
struct Envelope prot_headers 
)

Parse an Autocrypt email gossip header.

Parameters
eEmail
prot_headersEnvelope with protected headers
Return values
0Success
-1Error

Definition at line 398 of file autocrypt.c.

399 {
400  struct AutocryptPeer *peer = NULL;
401  struct AutocryptGossipHistory *gossip_hist = NULL;
402  struct Address *peer_addr = NULL;
403  struct Address ac_hdr_addr = { 0 };
404  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
405  int rc = -1;
406 
407  if (!C_Autocrypt)
408  return 0;
409 
410  if (mutt_autocrypt_init(false))
411  return -1;
412 
413  if (!e || !e->env || !prot_headers)
414  return 0;
415 
416  struct Envelope *env = e->env;
417 
418  struct Address *from = TAILQ_FIRST(&env->from);
419  if (!from)
420  return 0;
421 
422  /* Ignore emails that appear to be more than a week in the future,
423  * since they can block all future updates during that time. */
424  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
425  return 0;
426 
427  struct Buffer *keyid = mutt_buffer_pool_get();
428 
429  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
430 
431  /* Normalize the recipient list for comparison */
432  mutt_addrlist_copy(&recips, &env->to, false);
433  mutt_addrlist_copy(&recips, &env->cc, false);
434  mutt_addrlist_copy(&recips, &env->reply_to, false);
436 
437  for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
438  ac_hdr = ac_hdr->next)
439  {
440  if (ac_hdr->invalid)
441  continue;
442 
443  /* normalize for comparison against recipient list */
444  mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
445  ac_hdr_addr.is_intl = true;
446  ac_hdr_addr.intl_checked = true;
447  mutt_autocrypt_db_normalize_addr(&ac_hdr_addr);
448 
449  /* Check to make sure the address is in the recipient list. */
450  TAILQ_FOREACH(peer_addr, &recips, entries)
451  {
452  if (mutt_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
453  break;
454  }
455 
456  if (!peer_addr)
457  continue;
458 
459  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
460  goto cleanup;
461 
462  if (peer)
463  {
464  if (e->date_sent <= peer->gossip_timestamp)
465  {
467  continue;
468  }
469 
470  update_db = true;
471  peer->gossip_timestamp = e->date_sent;
472  /* This is slightly different from the autocrypt 1.1 spec.
473  * Avoid setting an empty peer.gossip_keydata with a value that matches
474  * the current peer.keydata. */
475  if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
476  (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
477  {
478  import_gpg = true;
479  insert_db_history = true;
480  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
481  }
482  }
483  else
484  {
485  import_gpg = true;
486  insert_db = true;
487  insert_db_history = true;
488  }
489 
490  if (!peer)
491  {
493  peer->gossip_timestamp = e->date_sent;
494  peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
495  }
496 
497  if (import_gpg)
498  {
500  goto cleanup;
501  mutt_str_replace(&peer->gossip_keyid, mutt_b2s(keyid));
502  }
503 
504  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
505  goto cleanup;
506 
507  if (update_db && mutt_autocrypt_db_peer_update(peer))
508  goto cleanup;
509 
510  if (insert_db_history)
511  {
512  gossip_hist = mutt_autocrypt_db_gossip_history_new();
513  gossip_hist->sender_email_addr = mutt_str_dup(from->mailbox);
514  gossip_hist->email_msgid = mutt_str_dup(env->message_id);
515  gossip_hist->timestamp = e->date_sent;
516  gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
517  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
518  goto cleanup;
519  }
520 
523  mutt_buffer_reset(keyid);
524  update_db = false;
525  insert_db = false;
526  insert_db_history = false;
527  import_gpg = false;
528  }
529 
530  rc = 0;
531 
532 cleanup:
533  FREE(&ac_hdr_addr.mailbox);
534  mutt_addrlist_clear(&recips);
537  mutt_buffer_pool_release(&keyid);
538 
539  return rc;
540 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: db.c:160
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
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:814
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
char * keydata
Definition: lib.h:121
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:514
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
char * gossip_keydata
Definition: lib.h:125
bool is_intl
International Domain Name.
Definition: address.h:39
sqlite3_int64 gossip_timestamp
Definition: lib.h:123
char * sender_email_addr
Definition: lib.h:145
char * message_id
Message ID.
Definition: envelope.h:69
Autocrypt peer.
Definition: lib.h:115
char * email_msgid
Definition: lib.h:146
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool intl_checked
Checked for IDN?
Definition: address.h:40
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
#define mutt_b2s(buf)
Definition: buffer.h:41
Autocrypt gossip history.
Definition: lib.h:142
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: db.c:610
struct AutocryptHeader * next
Definition: envelope.h:47
char * gossip_keyid
Definition: lib.h:124
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: db.c:805
Parse Autocrypt header info.
Definition: envelope.h:41
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: db.c:171
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: db.c:673
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
#define FREE(x)
Definition: memory.h:40
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:523
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
char * gossip_keydata
Definition: lib.h:148
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: db.c:545
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:834
sqlite3_int64 timestamp
Definition: lib.h:147
The header of an Email.
Definition: envelope.h:54
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition: gpgme.c:314
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_ui_recommendation()

enum AutocryptRec mutt_autocrypt_ui_recommendation ( struct Email e,
char **  keylist 
)

Get the recommended action for an Email.

Parameters
[in]eEmail
[out]keylistList of Autocrypt key ids
Return values
numRecommendation, e.g. AUTOCRYPT_REC_AVAILABLE

If the recommendataion is > NO and keylist is not NULL, keylist will be populated with the autocrypt keyids.

Definition at line 551 of file autocrypt.c.

552 {
554  struct AutocryptAccount *account = NULL;
555  struct AutocryptPeer *peer = NULL;
556  struct Address *recip = NULL;
557  bool all_encrypt = true, has_discourage = false;
558  const char *matching_key = NULL;
559  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
560  struct Buffer *keylist_buf = NULL;
561 
562  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
563  {
564  if (keylist)
565  {
566  /* L10N: Error displayed if the user tries to force sending an Autocrypt
567  email when the engine is not available. */
568  mutt_message(_("Autocrypt is not available"));
569  }
570  return AUTOCRYPT_REC_OFF;
571  }
572 
573  struct Address *from = TAILQ_FIRST(&e->env->from);
574  if (!from || TAILQ_NEXT(from, entries))
575  {
576  if (keylist)
577  mutt_message(_("Autocrypt is not available"));
578  return AUTOCRYPT_REC_OFF;
579  }
580 
581  if (e->security & APPLICATION_SMIME)
582  {
583  if (keylist)
584  mutt_message(_("Autocrypt is not available"));
585  return AUTOCRYPT_REC_OFF;
586  }
587 
588  if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
589  {
590  if (keylist)
591  {
592  /* L10N: Error displayed if the user tries to force sending an Autocrypt
593  email when the account does not exist or is not enabled.
594  %s is the From email address used to look up the Autocrypt account.
595  */
596  mutt_message(_("Autocrypt is not enabled for %s"), NONULL(from->mailbox));
597  }
598  goto cleanup;
599  }
600 
601  keylist_buf = mutt_buffer_pool_get();
602  mutt_buffer_addstr(keylist_buf, account->keyid);
603 
604  mutt_addrlist_copy(&recips, &e->env->to, false);
605  mutt_addrlist_copy(&recips, &e->env->cc, false);
606  mutt_addrlist_copy(&recips, &e->env->bcc, false);
607 
608  rc = AUTOCRYPT_REC_NO;
609  if (TAILQ_EMPTY(&recips))
610  goto cleanup;
611 
612  TAILQ_FOREACH(recip, &recips, entries)
613  {
614  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
615  {
616  if (keylist)
617  {
618  /* L10N: s is an email address. Autocrypt is scanning for the keyids
619  to use to encrypt, but it can't find a valid keyid for this address.
620  The message is printed and they are returned to the compose menu. */
621  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
622  }
623  goto cleanup;
624  }
625 
627  {
628  matching_key = peer->keyid;
629 
630  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
631  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
632  {
633  has_discourage = true;
634  all_encrypt = false;
635  }
636 
637  if (!account->prefer_encrypt || !peer->prefer_encrypt)
638  all_encrypt = false;
639  }
641  {
642  matching_key = peer->gossip_keyid;
643 
644  has_discourage = true;
645  all_encrypt = false;
646  }
647  else
648  {
649  if (keylist)
650  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
651  goto cleanup;
652  }
653 
654  if (!mutt_buffer_is_empty(keylist_buf))
655  mutt_buffer_addch(keylist_buf, ' ');
656  mutt_buffer_addstr(keylist_buf, matching_key);
657 
659  }
660 
661  if (all_encrypt)
662  rc = AUTOCRYPT_REC_YES;
663  else if (has_discourage)
665  else
667 
668  if (keylist)
669  mutt_str_replace(keylist, mutt_b2s(keylist_buf));
670 
671 cleanup:
673  mutt_addrlist_clear(&recips);
675  mutt_buffer_pool_release(&keylist_buf);
676  return rc;
677 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
AutocryptRec
Recommendation.
Definition: lib.h:154
#define NONULL(x)
Definition: string2.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:716
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:239
#define mutt_message(...)
Definition: logging.h:83
Autocrypt should be used.
Definition: lib.h:160
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:1468
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
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
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
No recommendations.
Definition: lib.h:156
char * keyid
Definition: lib.h:106
Do no use Autocrypt.
Definition: lib.h:157
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:119
bool enabled
Definition: lib.h:109
Autocrypt peer.
Definition: lib.h:115
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
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
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition: gpgme.c:352
sqlite3_int64 last_seen
Definition: lib.h:118
char * gossip_keyid
Definition: lib.h:124
Prefer not to use Autocrypt.
Definition: lib.h:158
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
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:258
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:122
Autocrypt account.
Definition: lib.h:103
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:523
Autocrypt is available.
Definition: lib.h:159
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define TAILQ_EMPTY(head)
Definition: queue.h:714
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:630
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:545
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_set_sign_as_default_key()

int mutt_autocrypt_set_sign_as_default_key ( struct Email e)

Set the Autocrypt default key for signing.

Parameters
eEmail
Return values
0Success
-1Error

Definition at line 685 of file autocrypt.c.

686 {
687  int rc = -1;
688  struct AutocryptAccount *account = NULL;
689 
690  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
691  return -1;
692 
693  struct Address *from = TAILQ_FIRST(&e->env->from);
694  if (!from || TAILQ_NEXT(from, entries))
695  return -1;
696 
697  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
698  goto cleanup;
699  if (!account->keyid)
700  goto cleanup;
701  if (!account->enabled)
702  goto cleanup;
703 
706 
707  rc = 0;
708 
709 cleanup:
711  return rc;
712 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
#define TAILQ_FIRST(head)
Definition: queue.h:716
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:239
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
An email address.
Definition: address.h:34
char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: config.c:42
char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: config.c:43
char * keyid
Definition: lib.h:106
bool enabled
Definition: lib.h:109
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:258
Autocrypt account.
Definition: lib.h:103
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ write_autocrypt_header_line()

static void write_autocrypt_header_line ( FILE *  fp,
const char *  addr,
bool  prefer_encrypt,
const char *  keydata 
)
static

Write an Autocrypt header to a file.

Parameters
fpFile to write to
addrEmail address
prefer_encryptWhether encryption is preferred
keydataRaw Autocrypt data

Definition at line 721 of file autocrypt.c.

723 {
724  fprintf(fp, "addr=%s; ", addr);
725  if (prefer_encrypt)
726  fputs("prefer-encrypt=mutual; ", fp);
727  fputs("keydata=\n", fp);
728 
729  while (*keydata)
730  {
731  int count = 0;
732  fputs("\t", fp);
733  while (*keydata && count < 75)
734  {
735  fputc(*keydata, fp);
736  count++;
737  keydata++;
738  }
739  fputs("\n", fp);
740  }
741 }
+ Here is the caller graph for this function:

◆ mutt_autocrypt_write_autocrypt_header()

int mutt_autocrypt_write_autocrypt_header ( struct Envelope env,
FILE *  fp 
)

Write the Autocrypt header to a file.

Parameters
envEnvelope
fpFile to write to
Return values
0Success
-1Error

Definition at line 750 of file autocrypt.c.

751 {
752  int rc = -1;
753  struct AutocryptAccount *account = NULL;
754 
755  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
756  return -1;
757 
758  struct Address *from = TAILQ_FIRST(&env->from);
759  if (!from || TAILQ_NEXT(from, entries))
760  return -1;
761 
762  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
763  goto cleanup;
764  if (!account->keydata)
765  goto cleanup;
766  if (!account->enabled)
767  goto cleanup;
768 
769  fputs("Autocrypt: ", fp);
771  account->keydata);
772 
773  rc = 0;
774 
775 cleanup:
777  return rc;
778 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
#define TAILQ_FIRST(head)
Definition: queue.h:716
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:239
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
An email address.
Definition: address.h:34
char * email_addr
Definition: lib.h:105
bool enabled
Definition: lib.h:109
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:108
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:258
Autocrypt account.
Definition: lib.h:103
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:721
char * keydata
Definition: lib.h:107
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_write_gossip_headers()

int mutt_autocrypt_write_gossip_headers ( struct Envelope env,
FILE *  fp 
)

Write the Autocrypt gossip headers to a file.

Parameters
envEnvelope
fpFile to write to
Return values
0Success
-1Error

Definition at line 787 of file autocrypt.c.

788 {
789  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
790  return -1;
791 
792  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
793  gossip = gossip->next)
794  {
795  fputs("Autocrypt-Gossip: ", fp);
796  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
797  }
798 
799  return 0;
800 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
struct AutocryptHeader * next
Definition: envelope.h:47
Parse Autocrypt header info.
Definition: envelope.h:41
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:721
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_generate_gossip_list()

int mutt_autocrypt_generate_gossip_list ( struct Email e)

Create the gossip list headers.

Parameters
eEmail
Return values
0Success
-1Error

Definition at line 808 of file autocrypt.c.

809 {
810  int rc = -1;
811  struct AutocryptPeer *peer = NULL;
812  struct AutocryptAccount *account = NULL;
813  struct Address *recip = NULL;
814 
815  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
816  return -1;
817 
818  struct Envelope *mime_headers = e->body->mime_headers;
819  if (!mime_headers)
820  mime_headers = e->body->mime_headers = mutt_env_new();
822 
823  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
824 
825  mutt_addrlist_copy(&recips, &e->env->to, false);
826  mutt_addrlist_copy(&recips, &e->env->cc, false);
827 
828  TAILQ_FOREACH(recip, &recips, entries)
829  {
830  /* At this point, we just accept missing keys and include what we can. */
831  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
832  continue;
833 
834  const char *keydata = NULL;
836  keydata = peer->keydata;
838  keydata = peer->gossip_keydata;
839 
840  if (keydata)
841  {
842  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
843  gossip->addr = mutt_str_dup(peer->email_addr);
844  gossip->keydata = mutt_str_dup(keydata);
845  gossip->next = mime_headers->autocrypt_gossip;
846  mime_headers->autocrypt_gossip = gossip;
847  }
848 
850  }
851 
852  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
853  {
854  const char *addr = NULL;
855  const char *keydata = NULL;
856  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
857  {
858  addr = account->email_addr;
859  keydata = account->keydata;
860  }
861  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
862  {
863  addr = peer->email_addr;
865  keydata = peer->keydata;
867  keydata = peer->gossip_keydata;
868  }
869 
870  if (keydata)
871  {
872  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
873  gossip->addr = mutt_str_dup(addr);
874  gossip->keydata = mutt_str_dup(keydata);
875  gossip->next = mime_headers->autocrypt_gossip;
876  mime_headers->autocrypt_gossip = gossip;
877  }
880  }
881 
882  mutt_addrlist_clear(&recips);
885  return rc;
886 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct Body * body
List of MIME parts.
Definition: email.h:91
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:239
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
char * keydata
Definition: lib.h:121
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
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
An email address.
Definition: address.h:34
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:65
char * email_addr
Definition: lib.h:105
char * gossip_keydata
Definition: lib.h:125
Autocrypt peer.
Definition: lib.h:115
char * keydata
Definition: envelope.h:44
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
char * email_addr
Definition: lib.h:117
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition: gpgme.c:352
struct AutocryptHeader * next
Definition: envelope.h:47
char * gossip_keyid
Definition: lib.h:124
char * addr
Definition: envelope.h:43
Parse Autocrypt header info.
Definition: envelope.h:41
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:258
Autocrypt account.
Definition: lib.h:103
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:74
char * keydata
Definition: lib.h:107
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:523
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
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:545
The header of an Email.
Definition: envelope.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_scan_mailboxes()

void mutt_autocrypt_scan_mailboxes ( void  )

Scan mailboxes for Autocrypt headers.

This is invoked during the first autocrypt initialization, to scan one or more mailboxes for autocrypt headers.

Due to the implementation, header-cached headers are not scanned, so this routine just opens up the mailboxes with $header_cache temporarily disabled.

Definition at line 898 of file autocrypt.c.

899 {
900 #ifdef USE_HCACHE
901  char *old_hdrcache = C_HeaderCache;
902  C_HeaderCache = NULL;
903 #endif
904 
905  struct Buffer *folderbuf = mutt_buffer_pool_get();
906 
907  /* L10N: The first time autocrypt is enabled, NeoMutt will ask to scan
908  through one or more mailboxes for Autocrypt: headers. Those headers are
909  then captured in the database as peer records and used for encryption.
910  If this is answered yes, they will be prompted for a mailbox. */
911  enum QuadOption scan =
912  mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
913  while (scan == MUTT_YES)
914  {
915  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
916  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true)) &&
917  (!mutt_buffer_is_empty(folderbuf)))
918  {
919  mutt_buffer_expand_path_regex(folderbuf, false);
920  struct Mailbox *m = mx_path_resolve(mutt_b2s(folderbuf));
921  /* NOTE: I am purposely *not* executing folder hooks here,
922  * as they can do all sorts of things like push into the getch() buffer.
923  * Authentication should be in account-hooks. */
924  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
925  mx_mbox_close(&ctx);
926  mutt_buffer_reset(folderbuf);
927  }
928 
929  /* L10N: This is the second prompt to see if the user would like
930  to scan more than one mailbox for Autocrypt headers.
931  I'm purposely being extra verbose; asking first then prompting
932  for a mailbox. This is because this is a one-time operation
933  and I don't want them to accidentally ctrl-g and abort it. */
934  scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
935  }
936 
937 #ifdef USE_HCACHE
938  C_HeaderCache = old_hdrcache;
939 #endif
940  mutt_buffer_pool_release(&folderbuf);
941 }
The "current" mailbox.
Definition: context.h:38
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:630
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:40
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
#define mutt_b2s(buf)
Definition: buffer.h:41
A mailbox.
Definition: mailbox.h:81
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:88
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function: