NeoMutt  2020-06-26-89-g172cd3
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 "mutt_globals.h"
#include "muttlib.h"
#include "mx.h"
#include "options.h"
#include "autocrypt/lib.h"
#include "hcache/lib.h"
#include "ncrypt/lib.h"
#include "send/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 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
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:377
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
+ 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
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:1461
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:108
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#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:377
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
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: mutt_globals.h:82
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
#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:162
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1481
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->content || !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->content->type == TYPE_MULTIPART) && mutt_istr_equal(e->content->subtype, "report"))
275  {
276  return 0;
277  }
278 
279  /* Ignore emails that appear to be more than a week in the future,
280  * since they can block all future updates during that time. */
281  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
282  return 0;
283 
284  for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
285  {
286  if (ac_hdr->invalid)
287  continue;
288 
289  /* NOTE: this assumes the processing is occurring right after
290  * mutt_parse_rfc822_line() and the from ADDR is still in the same
291  * form (intl) as the autocrypt header addr field */
292  if (!mutt_istr_equal(from->mailbox, ac_hdr->addr))
293  continue;
294 
295  /* 1.1 spec says ignore all, if more than one valid header is found. */
296  if (valid_ac_hdr)
297  {
298  valid_ac_hdr = NULL;
299  break;
300  }
301  valid_ac_hdr = ac_hdr;
302  }
303 
304  if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
305  goto cleanup;
306 
307  if (peer)
308  {
309  if (e->date_sent <= peer->autocrypt_timestamp)
310  {
311  rc = 0;
312  goto cleanup;
313  }
314 
315  if (e->date_sent > peer->last_seen)
316  {
317  update_db = true;
318  peer->last_seen = e->date_sent;
319  }
320 
321  if (valid_ac_hdr)
322  {
323  update_db = true;
324  peer->autocrypt_timestamp = e->date_sent;
325  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
326  if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
327  {
328  import_gpg = true;
329  insert_db_history = true;
330  mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
331  }
332  }
333  }
334  else if (valid_ac_hdr)
335  {
336  import_gpg = true;
337  insert_db = true;
338  insert_db_history = true;
339  }
340 
341  if (!(import_gpg || insert_db || update_db))
342  {
343  rc = 0;
344  goto cleanup;
345  }
346 
347  if (!peer)
348  {
350  peer->last_seen = e->date_sent;
351  peer->autocrypt_timestamp = e->date_sent;
352  peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
353  peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
354  }
355 
356  if (import_gpg)
357  {
358  keyid = mutt_buffer_pool_get();
359  if (mutt_autocrypt_gpgme_import_key(peer->keydata, keyid))
360  goto cleanup;
361  mutt_str_replace(&peer->keyid, mutt_b2s(keyid));
362  }
363 
364  if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
365  goto cleanup;
366 
367  if (update_db && mutt_autocrypt_db_peer_update(peer))
368  goto cleanup;
369 
370  if (insert_db_history)
371  {
373  peerhist->email_msgid = mutt_str_dup(env->message_id);
374  peerhist->timestamp = e->date_sent;
375  peerhist->keydata = mutt_str_dup(peer->keydata);
376  if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
377  goto cleanup;
378  }
379 
380  rc = 0;
381 
382 cleanup:
385  mutt_buffer_pool_release(&keyid);
386 
387  return rc;
388 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:414
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
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 Body * content
List of MIME parts.
Definition: email.h:90
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:375
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:888
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: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:451
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 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 397 of file autocrypt.c.

398 {
399  struct AutocryptPeer *peer = NULL;
400  struct AutocryptGossipHistory *gossip_hist = NULL;
401  struct Address *peer_addr = NULL;
402  struct Address ac_hdr_addr = { 0 };
403  bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
404  int rc = -1;
405 
406  if (!C_Autocrypt)
407  return 0;
408 
409  if (mutt_autocrypt_init(false))
410  return -1;
411 
412  if (!e || !e->env || !prot_headers)
413  return 0;
414 
415  struct Envelope *env = e->env;
416 
417  struct Address *from = TAILQ_FIRST(&env->from);
418  if (!from)
419  return 0;
420 
421  /* Ignore emails that appear to be more than a week in the future,
422  * since they can block all future updates during that time. */
423  if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
424  return 0;
425 
426  struct Buffer *keyid = mutt_buffer_pool_get();
427 
428  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
429 
430  /* Normalize the recipient list for comparison */
431  mutt_addrlist_copy(&recips, &env->to, false);
432  mutt_addrlist_copy(&recips, &env->cc, false);
433  mutt_addrlist_copy(&recips, &env->reply_to, false);
435 
436  for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
437  ac_hdr = ac_hdr->next)
438  {
439  if (ac_hdr->invalid)
440  continue;
441 
442  /* normalize for comparison against recipient list */
443  mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
444  ac_hdr_addr.is_intl = true;
445  ac_hdr_addr.intl_checked = true;
446  mutt_autocrypt_db_normalize_addr(&ac_hdr_addr);
447 
448  /* Check to make sure the address is in the recipient list. */
449  TAILQ_FOREACH(peer_addr, &recips, entries)
450  {
451  if (mutt_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
452  break;
453  }
454 
455  if (!peer_addr)
456  continue;
457 
458  if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
459  goto cleanup;
460 
461  if (peer)
462  {
463  if (e->date_sent <= peer->gossip_timestamp)
464  {
466  continue;
467  }
468 
469  update_db = true;
470  peer->gossip_timestamp = e->date_sent;
471  /* This is slightly different from the autocrypt 1.1 spec.
472  * Avoid setting an empty peer.gossip_keydata with a value that matches
473  * the current peer.keydata. */
474  if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
475  (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
476  {
477  import_gpg = true;
478  insert_db_history = true;
479  mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
480  }
481  }
482  else
483  {
484  import_gpg = true;
485  insert_db = true;
486  insert_db_history = true;
487  }
488 
489  if (!peer)
490  {
492  peer->gossip_timestamp = e->date_sent;
493  peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
494  }
495 
496  if (import_gpg)
497  {
499  goto cleanup;
500  mutt_str_replace(&peer->gossip_keyid, mutt_b2s(keyid));
501  }
502 
503  if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
504  goto cleanup;
505 
506  if (update_db && mutt_autocrypt_db_peer_update(peer))
507  goto cleanup;
508 
509  if (insert_db_history)
510  {
511  gossip_hist = mutt_autocrypt_db_gossip_history_new();
512  gossip_hist->sender_email_addr = mutt_str_dup(from->mailbox);
513  gossip_hist->email_msgid = mutt_str_dup(env->message_id);
514  gossip_hist->timestamp = e->date_sent;
515  gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
516  if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
517  goto cleanup;
518  }
519 
522  mutt_buffer_reset(keyid);
523  update_db = false;
524  insert_db = false;
525  insert_db_history = false;
526  import_gpg = false;
527  }
528 
529  rc = 0;
530 
531 cleanup:
532  FREE(&ac_hdr_addr.mailbox);
533  mutt_addrlist_clear(&recips);
536  mutt_buffer_pool_release(&keyid);
537 
538  return rc;
539 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:414
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:1461
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:375
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:89
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:81
#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:451
#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 550 of file autocrypt.c.

551 {
553  struct AutocryptAccount *account = NULL;
554  struct AutocryptPeer *peer = NULL;
555  struct Address *recip = NULL;
556  bool all_encrypt = true, has_discourage = false;
557  const char *matching_key = NULL;
558  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
559  struct Buffer *keylist_buf = NULL;
560 
561  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
562  return AUTOCRYPT_REC_OFF;
563 
564  struct Address *from = TAILQ_FIRST(&e->env->from);
565  if (!from || TAILQ_NEXT(from, entries))
566  return AUTOCRYPT_REC_OFF;
567 
568  if (e->security & APPLICATION_SMIME)
569  return AUTOCRYPT_REC_OFF;
570 
571  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
572  goto cleanup;
573 
574  if (!account->enabled)
575  goto cleanup;
576 
577  keylist_buf = mutt_buffer_pool_get();
578  mutt_buffer_addstr(keylist_buf, account->keyid);
579 
580  mutt_addrlist_copy(&recips, &e->env->to, false);
581  mutt_addrlist_copy(&recips, &e->env->cc, false);
582  mutt_addrlist_copy(&recips, &e->env->bcc, false);
583 
584  rc = AUTOCRYPT_REC_NO;
585  if (TAILQ_EMPTY(&recips))
586  goto cleanup;
587 
588  TAILQ_FOREACH(recip, &recips, entries)
589  {
590  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
591  {
592  if (keylist)
593  {
594  /* L10N: s is an email address. Autocrypt is scanning for the keyids
595  to use to encrypt, but it can't find a valid keyid for this address.
596  The message is printed and they are returned to the compose menu. */
597  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
598  }
599  goto cleanup;
600  }
601 
603  {
604  matching_key = peer->keyid;
605 
606  if (!(peer->last_seen && peer->autocrypt_timestamp) ||
607  (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
608  {
609  has_discourage = true;
610  all_encrypt = false;
611  }
612 
613  if (!account->prefer_encrypt || !peer->prefer_encrypt)
614  all_encrypt = false;
615  }
617  {
618  matching_key = peer->gossip_keyid;
619 
620  has_discourage = true;
621  all_encrypt = false;
622  }
623  else
624  {
625  if (keylist)
626  mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
627  goto cleanup;
628  }
629 
630  if (!mutt_buffer_is_empty(keylist_buf))
631  mutt_buffer_addch(keylist_buf, ' ');
632  mutt_buffer_addstr(keylist_buf, matching_key);
633 
635  }
636 
637  if (all_encrypt)
638  rc = AUTOCRYPT_REC_YES;
639  else if (has_discourage)
641  else
643 
644  if (keylist)
645  mutt_str_replace(keylist, mutt_b2s(keylist_buf));
646 
647 cleanup:
649  mutt_addrlist_clear(&recips);
651  mutt_buffer_pool_release(&keylist_buf);
652  return rc;
653 }
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:93
AutocryptRec
Recommendation.
Definition: lib.h:154
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:1461
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:89
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:93
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:451
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 661 of file autocrypt.c.

662 {
663  int rc = -1;
664  struct AutocryptAccount *account = NULL;
665 
666  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
667  return -1;
668 
669  struct Address *from = TAILQ_FIRST(&e->env->from);
670  if (!from || TAILQ_NEXT(from, entries))
671  return -1;
672 
673  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
674  goto cleanup;
675  if (!account->keyid)
676  goto cleanup;
677  if (!account->enabled)
678  goto cleanup;
679 
682 
683  rc = 0;
684 
685 cleanup:
687  return rc;
688 }
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:89
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:451
#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 697 of file autocrypt.c.

699 {
700  fprintf(fp, "addr=%s; ", addr);
701  if (prefer_encrypt)
702  fputs("prefer-encrypt=mutual; ", fp);
703  fputs("keydata=\n", fp);
704 
705  while (*keydata)
706  {
707  int count = 0;
708  fputs("\t", fp);
709  while (*keydata && count < 75)
710  {
711  fputc(*keydata, fp);
712  count++;
713  keydata++;
714  }
715  fputs("\n", fp);
716  }
717 }
+ 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 726 of file autocrypt.c.

727 {
728  int rc = -1;
729  struct AutocryptAccount *account = NULL;
730 
731  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
732  return -1;
733 
734  struct Address *from = TAILQ_FIRST(&env->from);
735  if (!from || TAILQ_NEXT(from, entries))
736  return -1;
737 
738  if (mutt_autocrypt_db_account_get(from, &account) <= 0)
739  goto cleanup;
740  if (!account->keydata)
741  goto cleanup;
742  if (!account->enabled)
743  goto cleanup;
744 
745  fputs("Autocrypt: ", fp);
747  account->keydata);
748 
749  rc = 0;
750 
751 cleanup:
753  return rc;
754 }
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:697
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 763 of file autocrypt.c.

764 {
765  if (!C_Autocrypt || mutt_autocrypt_init(false) || !env)
766  return -1;
767 
768  for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
769  gossip = gossip->next)
770  {
771  fputs("Autocrypt-Gossip: ", fp);
772  write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
773  }
774 
775  return 0;
776 }
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:697
+ 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 784 of file autocrypt.c.

785 {
786  int rc = -1;
787  struct AutocryptPeer *peer = NULL;
788  struct AutocryptAccount *account = NULL;
789  struct Address *recip = NULL;
790 
791  if (!C_Autocrypt || mutt_autocrypt_init(false) || !e)
792  return -1;
793 
794  struct Envelope *mime_headers = e->content->mime_headers;
795  if (!mime_headers)
796  mime_headers = e->content->mime_headers = mutt_env_new();
798 
799  struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
800 
801  mutt_addrlist_copy(&recips, &e->env->to, false);
802  mutt_addrlist_copy(&recips, &e->env->cc, false);
803 
804  TAILQ_FOREACH(recip, &recips, entries)
805  {
806  /* At this point, we just accept missing keys and include what we can. */
807  if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
808  continue;
809 
810  const char *keydata = NULL;
812  keydata = peer->keydata;
814  keydata = peer->gossip_keydata;
815 
816  if (keydata)
817  {
818  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
819  gossip->addr = mutt_str_dup(peer->email_addr);
820  gossip->keydata = mutt_str_dup(keydata);
821  gossip->next = mime_headers->autocrypt_gossip;
822  mime_headers->autocrypt_gossip = gossip;
823  }
824 
826  }
827 
828  TAILQ_FOREACH(recip, &e->env->reply_to, entries)
829  {
830  const char *addr = NULL;
831  const char *keydata = NULL;
832  if (mutt_autocrypt_db_account_get(recip, &account) > 0)
833  {
834  addr = account->email_addr;
835  keydata = account->keydata;
836  }
837  else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
838  {
839  addr = peer->email_addr;
841  keydata = peer->keydata;
843  keydata = peer->gossip_keydata;
844  }
845 
846  if (keydata)
847  {
848  struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
849  gossip->addr = mutt_str_dup(addr);
850  gossip->keydata = mutt_str_dup(keydata);
851  gossip->next = mime_headers->autocrypt_gossip;
852  mime_headers->autocrypt_gossip = gossip;
853  }
856  }
857 
858  mutt_addrlist_clear(&recips);
861  return rc;
862 }
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 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:1461
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
struct Body * content
List of MIME parts.
Definition: email.h:90
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
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:89
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 874 of file autocrypt.c.

875 {
876 #ifdef USE_HCACHE
877  char *old_hdrcache = C_HeaderCache;
878  C_HeaderCache = NULL;
879 #endif
880 
881  struct Buffer *folderbuf = mutt_buffer_pool_get();
882 
883  /* L10N: The first time autocrypt is enabled, NeoMutt will ask to scan
884  through one or more mailboxes for Autocrypt: headers. Those headers are
885  then captured in the database as peer records and used for encryption.
886  If this is answered yes, they will be prompted for a mailbox. */
887  enum QuadOption scan =
888  mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
889  while (scan == MUTT_YES)
890  {
891  // L10N: The prompt for a mailbox to scan for Autocrypt: headers
892  if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true)) &&
893  (!mutt_buffer_is_empty(folderbuf)))
894  {
895  mutt_buffer_expand_path_regex(folderbuf, false);
896  struct Mailbox *m = mx_path_resolve(mutt_b2s(folderbuf));
897  /* NOTE: I am purposely *not* executing folder hooks here,
898  * as they can do all sorts of things like push into the getch() buffer.
899  * Authentication should be in account-hooks. */
900  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
901  mx_mbox_close(&ctx);
902  mutt_buffer_reset(folderbuf);
903  }
904 
905  /* L10N: This is the second prompt to see if the user would like
906  to scan more than one mailbox for Autocrypt headers.
907  I'm purposely being extra verbose; asking first then prompting
908  for a mailbox. This is because this is a one-time operation
909  and I don't want them to accidentally ctrl-g and abort it. */
910  scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
911  }
912 
913 #ifdef USE_HCACHE
914  C_HeaderCache = old_hdrcache;
915 #endif
916  mutt_buffer_pool_release(&folderbuf);
917 }
The "current" mailbox.
Definition: context.h:37
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:604
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:37
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:267
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:55
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:377
#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:1670
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
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function: