NeoMutt  2019-12-07-168-gc45f47
Teaching an old dog new tricks
DOXYGEN
autocrypt.c File Reference

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

#include "config.h"
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include "autocrypt_private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "globals.h"
#include "muttlib.h"
#include "mx.h"
#include "options.h"
#include "send.h"
#include "ncrypt/lib.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 53 of file autocrypt.c.

54 {
55  int rc = 0;
56  struct stat sb;
57 
58  if (stat(C_AutocryptDir, &sb) == 0)
59  return 0;
60 
61  if (!can_create)
62  return -1;
63 
64  struct Buffer *prompt = mutt_buffer_pool_get();
65  /* L10N:
66  %s is a directory. NeoMutt is looking for a directory it needs
67  for some reason (e.g. autocrypt, header cache, bcache), but it
68  doesn't exist. The prompt is asking whether to create the directory
69  */
70  mutt_buffer_printf(prompt, _("%s does not exist. Create it?"), C_AutocryptDir);
71  if (mutt_yesorno(mutt_b2s(prompt), MUTT_YES) == MUTT_YES)
72  {
73  if (mutt_file_mkdir(C_AutocryptDir, S_IRWXU) < 0)
74  {
75  /* L10N:
76  mkdir() on the directory %s failed. The second %s is the
77  error message returned by libc
78  */
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 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h: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
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:376
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:873
#define mutt_b2s(buf)
Definition: buffer.h:41
#define mutt_error(...)
Definition: logging.h:84
WHERE char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and sqlite database.
Definition: globals.h:102
+ 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 94 of file autocrypt.c.

95 {
96  if (AutocryptDB)
97  return 0;
98 
99  if (!C_Autocrypt || !C_AutocryptDir)
100  return -1;
101 
102  OptIgnoreMacroEvents = true;
103  /* The init process can display menus at various points
104  *(e.g. browser, pgp key selection). This allows the screen to be
105  * autocleared after each menu, so the subsequent prompts can be
106  * read. */
107  OptMenuPopClearScreen = true;
108 
109  if (autocrypt_dir_init(can_create))
110  goto bail;
111 
113  goto bail;
114 
115  if (mutt_autocrypt_db_init(can_create))
116  goto bail;
117 
118  OptIgnoreMacroEvents = false;
119  OptMenuPopClearScreen = false;
120 
121  return 0;
122 
123 bail:
124  OptIgnoreMacroEvents = false;
125  OptMenuPopClearScreen = false;
126  C_Autocrypt = false;
128  return -1;
129 }
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:53
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:36
WHERE bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: options.h:39
void mutt_autocrypt_db_close(void)
Close the Autocrypt sqlite database connection.
Definition: autocrypt_db.c:130
sqlite3 * AutocryptDB
Definition: autocrypt_db.c:51
WHERE char * C_AutocryptDir
Config: Location of autocrypt files, including the GPG keyring and sqlite database.
Definition: globals.h:102
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt sqlite database.
Definition: autocrypt_db.c:80
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
+ 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 134 of file autocrypt.c.

135 {
137 }
void mutt_autocrypt_db_close(void)
Close the Autocrypt sqlite database connection.
Definition: autocrypt_db.c:130
+ 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 148 of file autocrypt.c.

149 {
150  struct Address *addr = NULL;
151  struct AutocryptAccount *account = NULL;
152  bool done = false;
153  int rc = -1;
154  bool prefer_encrypt = false;
155 
156  if (prompt)
157  {
158  /* L10N:
159  The first time NeoMutt is started with $autocrypt set, it will
160  create $autocrypt_dir and then prompt to create an autocrypt
161  account with this message.
162  */
163  if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
164  return 0;
165  }
166 
167  struct Buffer *keyid = mutt_buffer_pool_get();
168  struct Buffer *keydata = mutt_buffer_pool_get();
169 
170  if (C_From)
171  {
172  addr = mutt_addr_copy(C_From);
173  if (!addr->personal && C_Realname)
175  }
176 
177  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
178  mutt_addrlist_append(&al, addr);
179 
180  do
181  {
182  /* L10N:
183  Autocrypt is asking for the email address to use for the
184  autocrypt account. This will generate a key and add a record
185  to the database for use in autocrypt operations.
186  */
187  if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
188  goto cleanup;
189 
190  addr = TAILQ_FIRST(&al);
191  if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
192  {
193  /* L10N:
194  Autocrypt prompts for an account email address, and requires
195  a single address. This is shown if they entered something invalid,
196  nothing, or more than one address for some reason.
197  */
198  mutt_error(_("Please enter a single email address"));
199  done = false;
200  }
201  else
202  done = true;
203  } while (!done);
204 
205  addr = TAILQ_FIRST(&al);
206  if (mutt_autocrypt_db_account_get(addr, &account) < 0)
207  goto cleanup;
208  if (account)
209  {
210  /* L10N:
211  When creating an autocrypt account, this message will be displayed
212  if there is already an account in the database with the email address
213  they just entered.
214  */
215  mutt_error(_("That email address already has an autocrypt account"));
216  goto cleanup;
217  }
218 
219  if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
220  goto cleanup;
221 
222  /* L10N:
223  Autocrypt has a setting "prefer-encrypt".
224  When the recommendation algorithm returns "available" and BOTH
225  sender and recipient choose "prefer-encrypt", encryption will be
226  automatically enabled.
227  Otherwise the UI will show encryption is "available" but the user
228  will be required to enable encryption manually.
229  */
230  if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
231  prefer_encrypt = true;
232 
233  if (mutt_autocrypt_db_account_insert(addr, mutt_b2s(keyid), mutt_b2s(keydata), prefer_encrypt))
234  goto cleanup;
235 
236  rc = 0;
237 
238 cleanup:
239  if (rc == 0)
240  /* L10N:
241  Message displayed after an autocrypt account is successfully created.
242  */
243  mutt_message(_("Autocrypt account creation succeeded"));
244  else
245  /* L10N:
246  Error message displayed if creating an autocrypt account failed
247  or was aborted by the user.
248  */
249  mutt_error(_("Autocrypt account creation aborted"));
250 
252  mutt_addrlist_clear(&al);
253  mutt_buffer_pool_release(&keyid);
254  mutt_buffer_pool_release(&keydata);
255  return rc;
256 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
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: autocrypt_db.c:244
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
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
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:707
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: globals.h:94
bool prefer_encrypt
Definition: lib.h:55
#define mutt_b2s(buf)
Definition: buffer.h:41
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
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.
char * personal
Real name of address.
Definition: address.h:36
Autocrypt account.
Definition: lib.h:50
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
int mutt_autocrypt_db_account_insert(struct Address *addr, const char *keyid, const char *keydata, bool prefer_encrypt)
Insert an Account into the Autocrypt database.
Definition: autocrypt_db.c:322
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:138
#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:207
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1402
+ 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 265 of file autocrypt.c.

266 {
267  struct AutocryptHeader *valid_ac_hdr = NULL;
268  struct AutocryptPeer *peer = NULL;
269  struct AutocryptPeerHistory *peerhist = NULL;
270  struct Buffer *keyid = NULL;
271  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
272  int rc = -1;
273 
274  if (!C_Autocrypt)
275  return 0;
276 
277  if (mutt_autocrypt_init(false))
278  return -1;
279 
280  if (!e || !e->content || !env)
281  return 0;
282 
283  /* 1.1 spec says to skip emails with more than one From header */
284  struct Address *from = TAILQ_FIRST(&env->from);
285  if (!from || TAILQ_NEXT(from, entries))
286  return 0;
287 
288  /* 1.1 spec also says to skip multipart/report emails */
289  if ((e->content->type == TYPE_MULTIPART) &&
290  (mutt_str_strcasecmp(e->content->subtype, "report") == 0))
291  {
292  return 0;
293  }
294 
295  /* Ignore emails that appear to be more than a week in the future,
296  * since they can block all future updates during that time. */
297  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
298  return 0;
299 
300  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
301  {
302  if (ac_hdr->invalid)
303  continue;
304 
305  /* NOTE: this assumes the processing is occurring right after
306  * mutt_parse_rfc822_line() and the from ADDR is still in the same
307  * form (intl) as the autocrypt header addr field */
308  if (mutt_str_strcasecmp(from->mailbox, ac_hdr->addr) != 0)
309  continue;
310 
311  /* 1.1 spec says ignore all, if more than one valid header is found. */
312  if (valid_ac_hdr)
313  {
314  valid_ac_hdr = NULL;
315  break;
316  }
317  valid_ac_hdr = ac_hdr;
318  }
319 
320  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
321  goto cleanup;
322 
323  if (peer)
324  {
325  if (e->date_sent <= peer->autocrypt_timestamp)
326  {
327  rc = 0;
328  goto cleanup;
329  }
330 
331  if (e->date_sent > peer->last_seen)
332  {
333  update_db = true;
334  peer->last_seen = e->date_sent;
335  }
336 
337  if (valid_ac_hdr)
338  {
339  update_db = true;
340  peer->autocrypt_timestamp = e->date_sent;
341  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
342  if (mutt_str_strcmp(peer->keydata, valid_ac_hdr->keydata) != 0)
343  {
344  import_gpg = true;
345  insert_db_history = true;
346  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
347  }
348  }
349  }
350  else if (valid_ac_hdr)
351  {
352  import_gpg = true;
353  insert_db = true;
354  insert_db_history = true;
355  }
356 
357  if (!(import_gpg || insert_db || update_db))
358  {
359  rc = 0;
360  goto cleanup;
361  }
362 
363  if (!peer)
364  {
366  peer->last_seen = e->date_sent;
367  peer->autocrypt_timestamp = e->date_sent;
368  peer->keydata = mutt_str_strdup(valid_ac_hdr->keydata);
369  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
370  }
371 
372  if (import_gpg)
373  {
374  keyid = mutt_buffer_pool_get();
375  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
376  goto cleanup;
377  mutt_str_replace(&peer->keyid, mutt_b2s(keyid));
378  }
379 
380  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
381  goto cleanup;
382 
383  if (update_db && mutt_autocrypt_db_peer_update(peer))
384  goto cleanup;
385 
386  if (insert_db_history)
387  {
389  peerhist->email_msgid = mutt_str_strdup(env->message_id);
390  peerhist->timestamp = e->date_sent;
391  peerhist->keydata = mutt_str_strdup(peer->keydata);
392  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
393  goto cleanup;
394  }
395 
396  rc = 0;
397 
398 cleanup:
401  mutt_buffer_pool_release(&keyid);
402 
403  return rc;
404 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition: autocrypt_db.c:762
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
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
bool prefer_encrypt
Definition: envelope.h:45
char * email_msgid
Definition: lib.h:81
char * keydata
Definition: lib.h:68
sqlite3_int64 timestamp
Definition: lib.h:82
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
String manipulation buffer.
Definition: buffer.h:33
An email address.
Definition: address.h:34
struct AutocryptHeader * autocrypt
Definition: envelope.h:85
char * mailbox
Mailbox and host address.
Definition: address.h:37
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: autocrypt_db.c:519
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:66
char * message_id
Message ID.
Definition: envelope.h:69
Autocrypt peer.
Definition: lib.h:62
char * keydata
Definition: envelope.h:44
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: autocrypt_db.c:743
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: autocrypt_db.c:678
char * subtype
content-type subtype
Definition: body.h:37
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:81
#define mutt_b2s(buf)
Definition: buffer.h:41
sqlite3_int64 last_seen
Definition: lib.h:65
struct AutocryptHeader * next
Definition: envelope.h:47
Autocrypt peer history.
Definition: lib.h:78
Parse Autocrypt header info.
Definition: envelope.h:41
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: autocrypt_db.c:615
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: autocrypt_db.c:550
unsigned int type
content-type primary type
Definition: body.h:65
bool prefer_encrypt
Definition: lib.h:69
char * keydata
Definition: lib.h:83
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: autocrypt_db.c:528
char * keyid
Definition: lib.h:67
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: autocrypt_db.c:734
+ 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 413 of file autocrypt.c.

414 {
415  struct AutocryptPeer *peer = NULL;
416  struct AutocryptGossipHistory *gossip_hist = NULL;
417  struct Address *peer_addr = NULL;
418  struct Address ac_hdr_addr = { 0 };
419  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
420  int rc = -1;
421 
422  if (!C_Autocrypt)
423  return 0;
424 
425  if (mutt_autocrypt_init(false))
426  return -1;
427 
428  if (!e || !e->env || !prot_headers)
429  return 0;
430 
431  struct Envelope *env = e->env;
432 
433  struct Address *from = TAILQ_FIRST(&env->from);
434  if (!from)
435  return 0;
436 
437  /* Ignore emails that appear to be more than a week in the future,
438  * since they can block all future updates during that time. */
439  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
440  return 0;
441 
442  struct Buffer *keyid = mutt_buffer_pool_get();
443 
444  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
445 
446  /* Normalize the recipient list for comparison */
447  mutt_addrlist_copy(&recips, &env->to, false);
448  mutt_addrlist_copy(&recips, &env->cc, false);
449  mutt_addrlist_copy(&recips, &env->reply_to, false);
451 
452  for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
453  ac_hdr = ac_hdr->next)
454  {
455  if (ac_hdr->invalid)
456  continue;
457 
458  /* normalize for comparison against recipient list */
459  mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
460  ac_hdr_addr.is_intl = true;
461  ac_hdr_addr.intl_checked = true;
462  mutt_autocrypt_db_normalize_addr(&ac_hdr_addr);
463 
464  /* Check to make sure the address is in the recipient list. Since the
465  * addresses are normalized we use strcmp, not mutt_str_strcasecmp. */
466  TAILQ_FOREACH(peer_addr, &recips, entries)
467  {
468  if (mutt_str_strcmp(peer_addr->mailbox, ac_hdr_addr.mailbox) == 0)
469  break;
470  }
471 
472  if (!peer_addr)
473  continue;
474 
475  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
476  goto cleanup;
477 
478  if (peer)
479  {
480  if (e->date_sent <= peer->gossip_timestamp)
481  {
483  continue;
484  }
485 
486  update_db = true;
487  peer->gossip_timestamp = e->date_sent;
488  /* This is slightly different from the autocrypt 1.1 spec.
489  * Avoid setting an empty peer.gossip_keydata with a value that matches
490  * the current peer.keydata. */
491  if ((peer->gossip_keydata &&
492  (mutt_str_strcmp(peer->gossip_keydata, ac_hdr->keydata) != 0)) ||
493  (!peer->gossip_keydata && (mutt_str_strcmp(peer->keydata, ac_hdr->keydata) != 0)))
494  {
495  import_gpg = true;
496  insert_db_history = true;
497  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
498  }
499  }
500  else
501  {
502  import_gpg = true;
503  insert_db = true;
504  insert_db_history = true;
505  }
506 
507  if (!peer)
508  {
510  peer->gossip_timestamp = e->date_sent;
511  peer->gossip_keydata = mutt_str_strdup(ac_hdr->keydata);
512  }
513 
514  if (import_gpg)
515  {
517  goto cleanup;
518  mutt_str_replace(&peer->gossip_keyid, mutt_b2s(keyid));
519  }
520 
521  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
522  goto cleanup;
523 
524  if (update_db && mutt_autocrypt_db_peer_update(peer))
525  goto cleanup;
526 
527  if (insert_db_history)
528  {
529  gossip_hist = mutt_autocrypt_db_gossip_history_new();
530  gossip_hist->sender_email_addr = mutt_str_strdup(from->mailbox);
531  gossip_hist->email_msgid = mutt_str_strdup(env->message_id);
532  gossip_hist->timestamp = e->date_sent;
533  gossip_hist->gossip_keydata = mutt_str_strdup(peer->gossip_keydata);
534  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
535  goto cleanup;
536  }
537 
540  mutt_buffer_reset(keyid);
541  update_db = false;
542  insert_db = false;
543  insert_db_history = false;
544  import_gpg = false;
545  }
546 
547  rc = 0;
548 
549 cleanup:
550  FREE(&ac_hdr_addr.mailbox);
551  mutt_addrlist_clear(&recips);
554  mutt_buffer_pool_release(&keyid);
555 
556  return rc;
557 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: autocrypt_db.c:165
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
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_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
char * keydata
Definition: lib.h:68
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:728
String manipulation buffer.
Definition: buffer.h:33
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition: autocrypt_db.c:819
char * gossip_keydata
Definition: lib.h:72
bool is_intl
International Domain Name.
Definition: address.h:39
sqlite3_int64 gossip_timestamp
Definition: lib.h:70
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: autocrypt_db.c:519
char * sender_email_addr
Definition: lib.h:92
char * message_id
Message ID.
Definition: envelope.h:69
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: autocrypt_db.c:176
Autocrypt peer.
Definition: lib.h:62
char * email_msgid
Definition: lib.h:93
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: autocrypt_db.c:678
bool intl_checked
Checked for IDN?
Definition: address.h:40
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:81
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_autocrypt_db_gossip_history_insert(struct Address *addr, struct AutocryptGossipHistory *gossip_hist)
Insert a gossip history into the Autocrypt database.
Definition: autocrypt_db.c:839
Autocrypt gossip history.
Definition: lib.h:89
struct AutocryptHeader * next
Definition: envelope.h:47
char * gossip_keyid
Definition: lib.h:71
Parse Autocrypt header info.
Definition: envelope.h:41
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: autocrypt_db.c:615
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: autocrypt_db.c:550
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
char * gossip_keydata
Definition: lib.h:95
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: autocrypt_db.c:528
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: autocrypt_db.c:810
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
sqlite3_int64 timestamp
Definition: lib.h:94
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_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 568 of file autocrypt.c.

569 {
571  struct AutocryptAccount *account = NULL;
572  struct AutocryptPeer *peer = NULL;
573  struct Address *recip = NULL;
574  bool all_encrypt = true, has_discourage = false;
575  const char *matching_key = NULL;
576  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
577  struct Buffer *keylist_buf = NULL;
578 
579  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
580  return AUTOCRYPT_REC_OFF;
581 
582  struct Address *from = TAILQ_FIRST(&e->env->from);
583  if (!from || TAILQ_NEXT(from, entries))
584  return AUTOCRYPT_REC_OFF;
585 
586  if (e->security & APPLICATION_SMIME)
587  return AUTOCRYPT_REC_OFF;
588 
589  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
590  goto cleanup;
591 
592  if (!account->enabled)
593  goto cleanup;
594 
595  keylist_buf = mutt_buffer_pool_get();
596  mutt_buffer_addstr(keylist_buf, account->keyid);
597 
598  mutt_addrlist_copy(&recips, &e->env->to, false);
599  mutt_addrlist_copy(&recips, &e->env->cc, false);
600  mutt_addrlist_copy(&recips, &e->env->bcc, false);
601 
602  rc = AUTOCRYPT_REC_NO;
603  if (TAILQ_EMPTY(&recips))
604  goto cleanup;
605 
606  TAILQ_FOREACH(recip, &recips, entries)
607  {
608  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
609  {
610  if (keylist)
611  {
612  /* L10N:
613  %s is an email address. Autocrypt is scanning for the keyids
614  to use to encrypt, but it can't find a valid keyid for this address.
615  The message is printed and they are returned to the compose menu.
616  */
617  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
618  }
619  goto cleanup;
620  }
621 
623  {
624  matching_key = peer->keyid;
625 
626  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
627  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
628  {
629  has_discourage = true;
630  all_encrypt = false;
631  }
632 
633  if (!account->prefer_encrypt || !peer->prefer_encrypt)
634  all_encrypt = false;
635  }
637  {
638  matching_key = peer->gossip_keyid;
639 
640  has_discourage = true;
641  all_encrypt = false;
642  }
643  else
644  {
645  if (keylist)
646  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
647  goto cleanup;
648  }
649 
650  if (!mutt_buffer_is_empty(keylist_buf))
651  mutt_buffer_addch(keylist_buf, ' ');
652  mutt_buffer_addstr(keylist_buf, matching_key);
653 
655  }
656 
657  if (all_encrypt)
658  rc = AUTOCRYPT_REC_YES;
659  else if (has_discourage)
661  else
663 
664  if (keylist)
665  mutt_str_replace(keylist, mutt_b2s(keylist_buf));
666 
667 cleanup:
669  mutt_addrlist_clear(&recips);
671  mutt_buffer_pool_release(&keylist_buf);
672  return rc;
673 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
AutocryptRec
Recommendation.
Definition: lib.h:101
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
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: autocrypt_db.c:244
#define mutt_message(...)
Definition: logging.h:83
Autocrypt should be used.
Definition: lib.h:107
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:1382
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:728
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:103
char * keyid
Definition: lib.h:53
Do no use Autocrypt.
Definition: lib.h:104
sqlite3_int64 autocrypt_timestamp
Definition: lib.h:66
bool enabled
Definition: lib.h:56
Autocrypt peer.
Definition: lib.h:62
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool prefer_encrypt
Definition: lib.h:55
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:136
sqlite3_int64 last_seen
Definition: lib.h:65
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
char * gossip_keyid
Definition: lib.h:71
Prefer not to use Autocrypt.
Definition: lib.h:105
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
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: autocrypt_db.c:550
bool prefer_encrypt
Definition: lib.h:69
Autocrypt account.
Definition: lib.h:50
Autocrypt is available.
Definition: lib.h:106
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
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: autocrypt_db.c:528
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:67
+ 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 681 of file autocrypt.c.

682 {
683  int rc = -1;
684  struct AutocryptAccount *account = NULL;
685 
686  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
687  return -1;
688 
689  struct Address *from = TAILQ_FIRST(&e->env->from);
690  if (!from || TAILQ_NEXT(from, entries))
691  return -1;
692 
693  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
694  goto cleanup;
695  if (!account->keyid)
696  goto cleanup;
697  if (!account->enabled)
698  goto cleanup;
699 
702 
703  rc = 0;
704 
705 cleanup:
707  return rc;
708 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
#define TAILQ_FIRST(head)
Definition: queue.h:716
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: autocrypt_db.c:244
WHERE char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: globals.h:88
An email address.
Definition: address.h:34
char * keyid
Definition: lib.h:53
bool enabled
Definition: lib.h:56
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:89
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
Autocrypt account.
Definition: lib.h:50
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
WHERE char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: globals.h:87
+ 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 717 of file autocrypt.c.

719 {
720  fprintf(fp, "addr=%s; ", addr);
721  if (prefer_encrypt)
722  fputs("prefer-encrypt=mutual; ", fp);
723  fputs("keydata=\n", fp);
724 
725  while (*keydata)
726  {
727  int count = 0;
728  fputs("\t", fp);
729  while (*keydata && count < 75)
730  {
731  fputc(*keydata, fp);
732  count++;
733  keydata++;
734  }
735  fputs("\n", fp);
736  }
737 }
+ 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 746 of file autocrypt.c.

747 {
748  int rc = -1;
749  struct AutocryptAccount *account = NULL;
750 
751  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
752  return -1;
753 
754  struct Address *from = TAILQ_FIRST(&env->from);
755  if (!from || TAILQ_NEXT(from, entries))
756  return -1;
757 
758  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
759  goto cleanup;
760  if (!account->keydata)
761  goto cleanup;
762  if (!account->enabled)
763  goto cleanup;
764 
765  fputs("Autocrypt: ", fp);
767  account->keydata);
768 
769  rc = 0;
770 
771 cleanup:
773  return rc;
774 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
#define TAILQ_FIRST(head)
Definition: queue.h:716
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: autocrypt_db.c:244
An email address.
Definition: address.h:34
char * email_addr
Definition: lib.h:52
bool enabled
Definition: lib.h:56
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool prefer_encrypt
Definition: lib.h:55
Autocrypt account.
Definition: lib.h:50
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:717
char * keydata
Definition: lib.h:54
#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 783 of file autocrypt.c.

784 {
785  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
786  return -1;
787 
788  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
789  gossip = gossip->next)
790  {
791  fputs("Autocrypt-Gossip: ", fp);
792  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
793  }
794 
795  return 0;
796 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
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:717
+ 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 804 of file autocrypt.c.

805 {
806  int rc = -1;
807  struct AutocryptPeer *peer = NULL;
808  struct AutocryptAccount *account = NULL;
809  struct Address *recip = NULL;
810 
811  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
812  return -1;
813 
814  struct Envelope *mime_headers = e->content->mime_headers;
815  if (!mime_headers)
816  mime_headers = e->content->mime_headers = mutt_env_new();
818 
819  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
820 
821  mutt_addrlist_copy(&recips, &e->env->to, false);
822  mutt_addrlist_copy(&recips, &e->env->cc, false);
823 
824  TAILQ_FOREACH(recip, &recips, entries)
825  {
826  /* At this point, we just accept missing keys and include what we can. */
827  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
828  continue;
829 
830  const char *keydata = NULL;
832  keydata = peer->keydata;
834  keydata = peer->gossip_keydata;
835 
836  if (keydata)
837  {
838  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
839  gossip->addr = mutt_str_strdup(peer->email_addr);
840  gossip->keydata = mutt_str_strdup(keydata);
841  gossip->next = mime_headers->autocrypt_gossip;
842  mime_headers->autocrypt_gossip = gossip;
843  }
844 
846  }
847 
848  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
849  {
850  const char *addr = NULL;
851  const char *keydata = NULL;
852  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
853  {
854  addr = account->email_addr;
855  keydata = account->keydata;
856  }
857  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
858  {
859  addr = peer->email_addr;
861  keydata = peer->keydata;
863  keydata = peer->gossip_keydata;
864  }
865 
866  if (keydata)
867  {
868  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
869  gossip->addr = mutt_str_strdup(addr);
870  gossip->keydata = mutt_str_strdup(keydata);
871  gossip->next = mime_headers->autocrypt_gossip;
872  mime_headers->autocrypt_gossip = gossip;
873  }
876  }
877 
878  mutt_addrlist_clear(&recips);
881  return rc;
882 }
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: autocrypt_db.c:263
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:94
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#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_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: autocrypt_db.c:244
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
char * keydata
Definition: lib.h:68
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
struct Body * content
List of MIME parts.
Definition: email.h:90
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:52
char * gossip_keydata
Definition: lib.h:72
Autocrypt peer.
Definition: lib.h:62
char * keydata
Definition: envelope.h:44
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
char * email_addr
Definition: lib.h:64
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
struct AutocryptHeader * next
Definition: envelope.h:47
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
char * gossip_keyid
Definition: lib.h:71
char * addr
Definition: envelope.h:43
Parse Autocrypt header info.
Definition: envelope.h:41
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: autocrypt_db.c:550
Autocrypt account.
Definition: lib.h:50
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:74
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * keydata
Definition: lib.h:54
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: autocrypt_db.c:528
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
char * keyid
Definition: lib.h:67
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 894 of file autocrypt.c.

895 {
896 #ifdef USE_HCACHE
897  char *old_hdrcache = C_HeaderCache;
898  C_HeaderCache = NULL;
899 #endif
900 
901  struct Buffer *folderbuf = mutt_buffer_pool_get();
902 
903  /* L10N:
904  The first time autocrypt is enabled, NeoMutt will ask to scan
905  through one or more mailboxes for Autocrypt: headers.
906  Those headers are then captured in the database as peer records
907  and used for encryption.
908  If this is answered yes, they will be prompted for a mailbox.
909  */
910  int scan = mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
911  while (scan == MUTT_YES)
912  {
913  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
914  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true)) &&
915  (!mutt_buffer_is_empty(folderbuf)))
916  {
917  mutt_buffer_expand_path_regex(folderbuf, false);
918  struct Mailbox *m = mx_path_resolve(mutt_b2s(folderbuf));
919  /* NOTE: I am purposely *not* executing folder hooks here,
920  * as they can do all sorts of things like push into the getch() buffer.
921  * Authentication should be in account-hooks. */
922  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
923  mx_mbox_close(&ctx);
924  mutt_buffer_reset(folderbuf);
925  }
926 
927  /* L10N:
928  This is the second prompt to see if the user would like
929  to scan more than one mailbox for Autocrypt headers.
930  I'm purposely being extra verbose; asking first then prompting
931  for a mailbox. This is because this is a one-time operation
932  and I don't want them to accidentally ctrl-g and abort it.
933  */
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:36
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:591
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h: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:253
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:55
WHERE char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: globals.h:121
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:144
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
#define mutt_b2s(buf)
Definition: buffer.h:41
A mailbox.
Definition: mailbox.h:80
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1644
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:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function: