NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

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

#include "config.h"
#include <sqlite3.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "module_data.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AutocryptAccount
 Autocrypt account. More...
 
struct  AutocryptPeer
 Autocrypt peer. More...
 
struct  AutocryptPeerHistory
 Autocrypt peer history. More...
 
struct  AutocryptGossipHistory
 Autocrypt gossip history. More...
 

Enumerations

enum  AutocryptRec {
  AUTOCRYPT_REC_OFF , AUTOCRYPT_REC_NO , AUTOCRYPT_REC_DISCOURAGE , AUTOCRYPT_REC_AVAILABLE ,
  AUTOCRYPT_REC_YES
}
 Recommendation. More...
 

Functions

 ARRAY_HEAD (AutocryptAccountArray, struct AutocryptAccount *)
 
void autocrypt_init_keys (struct NeoMutt *n, struct SubMenu *sm_generic)
 Initialise the Autocrypt Keybindings - Implements ::init_keys_api.
 
void dlg_autocrypt (void)
 Display the Autocrypt account Menu -.
 
void mutt_autocrypt_cleanup (struct AutocryptModuleData *mod_data)
 Shutdown Autocrypt.
 
int mutt_autocrypt_generate_gossip_list (struct Email *e)
 Create the gossip list headers.
 
int mutt_autocrypt_init (bool can_create)
 Initialise Autocrypt.
 
int mutt_autocrypt_process_autocrypt_header (struct Email *e, struct Envelope *env)
 Parse an Autocrypt email header.
 
int mutt_autocrypt_process_gossip_header (struct Email *e, struct Envelope *prot_headers)
 Parse an Autocrypt email gossip header.
 
int mutt_autocrypt_set_sign_as_default_key (struct Email *e)
 Set the Autocrypt default key for signing.
 
enum AutocryptRec mutt_autocrypt_ui_recommendation (const struct Email *e, char **keylist)
 Get the recommended action for an Email.
 
int mutt_autocrypt_write_autocrypt_header (struct Envelope *env, FILE *fp)
 Write the Autocrypt header to a file.
 
int mutt_autocrypt_write_gossip_headers (struct Envelope *env, FILE *fp)
 Write the Autocrypt gossip headers to a file.
 

Detailed Description

Autocrypt end-to-end encryption.

Authors
  • Kevin J. McCarthy
  • Richard Russon

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 lib.h.

Enumeration Type Documentation

◆ AutocryptRec

Recommendation.

Enumerator
AUTOCRYPT_REC_OFF 

No recommendations.

AUTOCRYPT_REC_NO 

Do no use Autocrypt.

AUTOCRYPT_REC_DISCOURAGE 

Prefer not to use Autocrypt.

AUTOCRYPT_REC_AVAILABLE 

Autocrypt is available.

AUTOCRYPT_REC_YES 

Autocrypt should be used.

Definition at line 165 of file lib.h.

166{
172};
@ AUTOCRYPT_REC_DISCOURAGE
Prefer not to use Autocrypt.
Definition lib.h:169
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition lib.h:168
@ AUTOCRYPT_REC_OFF
No recommendations.
Definition lib.h:167
@ AUTOCRYPT_REC_AVAILABLE
Autocrypt is available.
Definition lib.h:170
@ AUTOCRYPT_REC_YES
Autocrypt should be used.
Definition lib.h:171

Function Documentation

◆ ARRAY_HEAD()

ARRAY_HEAD ( AutocryptAccountArray ,
struct AutocryptAccount *  )

◆ autocrypt_init_keys()

void autocrypt_init_keys ( struct NeoMutt * n,
struct SubMenu * sm_generic )

Initialise the Autocrypt Keybindings - Implements ::init_keys_api.

Definition at line 75 of file functions.c.

76{
78 ASSERT(mod_data);
79
80 struct MenuDefinition *md = NULL;
81 struct SubMenu *sm = NULL;
82
84 md = km_register_menu(MENU_AUTOCRYPT, "autocrypt");
85 km_menu_add_submenu(md, sm);
86 km_menu_add_submenu(md, sm_generic);
88
89 mod_data->menu_autocrypt = md;
90}
static const struct MenuFuncOp OpAutocrypt[]
Functions for the Autocrypt Account.
Definition functions.c:50
static const struct MenuOpSeq AutocryptDefaultBindings[]
Key bindings for the Autocrypt Account.
Definition functions.c:62
void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
Add a SubMenu to a Menu Definition.
Definition init.c:121
struct SubMenu * km_register_submenu(const struct MenuFuncOp functions[])
Register a submenu.
Definition init.c:87
struct MenuDefinition * km_register_menu(int menu, const char *name)
Register a menu.
Definition init.c:104
void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
Add Keybindings to a Menu.
Definition init.c:134
@ MODULE_ID_AUTOCRYPT
ModuleAutocrypt, Autocrypt
Definition module_api.h:50
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
#define ASSERT(COND)
Definition signal2.h:59
Autocrypt private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_autocrypt
Autocrypt menu definition.
Definition module_data.h:34
Functions for a Dialog or Window.
Definition menu.h:77
Collection of related functions.
Definition menu.h:65
@ MENU_AUTOCRYPT
Autocrypt Account menu.
Definition type.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_cleanup()

void mutt_autocrypt_cleanup ( struct AutocryptModuleData * mod_data)

Shutdown Autocrypt.

Parameters
mod_dataAutocrypt module data

Definition at line 136 of file autocrypt.c.

137{
138 mutt_autocrypt_db_close(mod_data);
139}
void mutt_autocrypt_db_close(struct AutocryptModuleData *mod_data)
Close the Autocrypt SQLite database connection.
Definition db.c:127
+ 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 844 of file autocrypt.c.

845{
846 int rc = -1;
847 struct AutocryptPeer *peer = NULL;
848 struct AutocryptAccount *account = NULL;
849 struct Address *recip = NULL;
850
851 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
852 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
853 return -1;
854
855 struct Envelope *mime_headers = e->body->mime_headers;
856 if (!mime_headers)
857 mime_headers = e->body->mime_headers = mutt_env_new();
859
860 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
861
862 mutt_addrlist_copy(&recips, &e->env->to, false);
863 mutt_addrlist_copy(&recips, &e->env->cc, false);
864
865 TAILQ_FOREACH(recip, &recips, entries)
866 {
867 /* At this point, we just accept missing keys and include what we can. */
868 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
869 continue;
870
871 const char *keydata = NULL;
873 keydata = peer->keydata;
875 keydata = peer->gossip_keydata;
876
877 if (keydata)
878 {
879 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
880 gossip->addr = mutt_str_dup(peer->email_addr);
881 gossip->keydata = mutt_str_dup(keydata);
882 gossip->next = mime_headers->autocrypt_gossip;
883 mime_headers->autocrypt_gossip = gossip;
884 }
885
887 }
888
889 TAILQ_FOREACH(recip, &e->env->reply_to, entries)
890 {
891 const char *addr = NULL;
892 const char *keydata = NULL;
893 if (mutt_autocrypt_db_account_get(recip, &account) > 0)
894 {
895 addr = account->email_addr;
896 keydata = account->keydata;
897 }
898 else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
899 {
900 addr = peer->email_addr;
902 keydata = peer->keydata;
904 keydata = peer->gossip_keydata;
905 }
906
907 if (keydata)
908 {
909 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
910 gossip->addr = mutt_str_dup(addr);
911 gossip->keydata = mutt_str_dup(keydata);
912 gossip->next = mime_headers->autocrypt_gossip;
913 mime_headers->autocrypt_gossip = gossip;
914 }
917 }
918
919 rc = 0;
920
921 mutt_addrlist_clear(&recips);
924 return rc;
925}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition address.c:774
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1469
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition db.c:259
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition db.c:568
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition db.c:240
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition db.c:546
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition autocrypt.c:104
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition envelope.c:45
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition envelope.c:94
void mutt_autocrypthdr_free(struct AutocryptHeader **ptr)
Free an AutocryptHeader.
Definition envelope.c:103
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition gpgme.c:361
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
An email address.
Definition address.h:35
Autocrypt account.
Definition lib.h:114
char * email_addr
Email address.
Definition lib.h:115
char * keydata
PGP Key data.
Definition lib.h:117
Parse Autocrypt header info.
Definition envelope.h:44
struct AutocryptHeader * next
Linked list.
Definition envelope.h:49
char * keydata
PGP Key data.
Definition envelope.h:46
char * addr
Email address.
Definition envelope.h:45
Autocrypt peer.
Definition lib.h:127
char * gossip_keydata
Gossip Key data.
Definition lib.h:136
char * keyid
PGP Key id.
Definition lib.h:131
char * gossip_keyid
Gossip Key id.
Definition lib.h:135
char * keydata
PGP Key data.
Definition lib.h:132
char * email_addr
Email address.
Definition lib.h:128
struct Envelope * mime_headers
Memory hole protected headers.
Definition body.h:76
struct Envelope * env
Envelope information.
Definition email.h:68
struct Body * body
List of MIME parts.
Definition email.h:69
The header of an Email.
Definition envelope.h:57
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
struct AddressList reply_to
Email's 'reply-to'.
Definition envelope.h:64
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition envelope.h:88
struct AddressList cc
Email's 'Cc' list.
Definition envelope.h:61
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ 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 104 of file autocrypt.c.

105{
107 if (mod_data->autocrypt_db)
108 return 0;
109
110 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
111 const char *const c_autocrypt_dir = cs_subset_path(NeoMutt->sub, "autocrypt_dir");
112 if (!c_autocrypt || !c_autocrypt_dir)
113 return -1;
114
115 if (autocrypt_dir_init(can_create))
116 goto bail;
117
119 goto bail;
120
121 if (mutt_autocrypt_db_init(can_create))
122 goto bail;
123
124 return 0;
125
126bail:
127 cs_subset_str_native_set(NeoMutt->sub, "autocrypt", false, NULL);
128 mutt_autocrypt_db_close(mod_data);
129 return -1;
130}
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt SQLite database.
Definition db.c:73
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition autocrypt.c:62
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition helpers.c:168
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition gpgme.c:70
sqlite3 * autocrypt_db
Autocrypt database.
Definition module_data.h:38
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition subset.c:303
+ 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 263 of file autocrypt.c.

264{
265 struct AutocryptHeader *valid_ac_hdr = NULL;
266 struct AutocryptPeer *peer = NULL;
267 struct AutocryptPeerHistory *peerhist = NULL;
268 struct Buffer *keyid = NULL;
269 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
270 int rc = -1;
271
272 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
273 if (!c_autocrypt)
274 return 0;
275
276 if (mutt_autocrypt_init(false) != 0)
277 return -1;
278
279 if (!e || !e->body || !env)
280 return 0;
281
282 /* 1.1 spec says to skip emails with more than one From header */
283 struct Address *from = TAILQ_FIRST(&env->from);
284 if (!from || TAILQ_NEXT(from, entries))
285 return 0;
286
287 /* 1.1 spec also says to skip multipart/report emails */
288 if ((e->body->type == TYPE_MULTIPART) && mutt_istr_equal(e->body->subtype, "report"))
289 {
290 return 0;
291 }
292
293 /* Ignore emails that appear to be more than a week in the future,
294 * since they can block all future updates during that time. */
295 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
296 return 0;
297
298 for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
299 {
300 if (ac_hdr->invalid)
301 continue;
302
303 /* NOTE: this assumes the processing is occurring right after
304 * mutt_parse_rfc822_line() and the from ADDR is still in the same
305 * form (intl) as the autocrypt header addr field */
306 if (!mutt_istr_equal(buf_string(from->mailbox), ac_hdr->addr))
307 continue;
308
309 /* 1.1 spec says ignore all, if more than one valid header is found. */
310 if (valid_ac_hdr)
311 {
312 valid_ac_hdr = NULL;
313 break;
314 }
315 valid_ac_hdr = ac_hdr;
316 }
317
318 if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
319 goto cleanup;
320
321 if (peer)
322 {
323 if (e->date_sent <= peer->autocrypt_timestamp)
324 {
325 rc = 0;
326 goto cleanup;
327 }
328
329 if (e->date_sent > peer->last_seen)
330 {
331 update_db = true;
332 peer->last_seen = e->date_sent;
333 }
334
335 if (valid_ac_hdr)
336 {
337 update_db = true;
339 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
340 if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
341 {
342 import_gpg = true;
343 insert_db_history = true;
344 mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
345 }
346 }
347 }
348 else if (valid_ac_hdr)
349 {
350 import_gpg = true;
351 insert_db = true;
352 insert_db_history = true;
353 }
354
355 if (!(import_gpg || insert_db || update_db))
356 {
357 rc = 0;
358 goto cleanup;
359 }
360
361 if (!peer)
362 {
364 peer->last_seen = e->date_sent;
366 peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
367 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
368 }
369
370 if (import_gpg)
371 {
372 keyid = buf_pool_get();
374 goto cleanup;
375 mutt_str_replace(&peer->keyid, buf_string(keyid));
376 }
377
378 if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
379 goto cleanup;
380
381 if (update_db && mutt_autocrypt_db_peer_update(peer))
382 goto cleanup;
383
384 if (insert_db_history)
385 {
387 peerhist->email_msgid = mutt_str_dup(env->message_id);
388 peerhist->timestamp = e->date_sent;
389 peerhist->keydata = mutt_str_dup(peer->keydata);
390 if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
391 goto cleanup;
392 }
393
394 rc = 0;
395
396cleanup:
399 buf_pool_release(&keyid);
400
401 return rc;
402}
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition db.c:537
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition db.c:640
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition db.c:710
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition db.c:780
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition db.c:771
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition db.c:799
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition gpgme.c:320
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition date.c:457
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:677
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define TAILQ_FIRST(head)
Definition queue.h:780
#define TAILQ_NEXT(elm, field)
Definition queue.h:889
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
bool prefer_encrypt
User prefers encryption.
Definition envelope.h:47
Autocrypt peer history.
Definition lib.h:143
char * email_msgid
Message id of the email.
Definition lib.h:145
char * keydata
PGP Key data.
Definition lib.h:147
sqlite3_int64 timestamp
Timestamp of email.
Definition lib.h:146
sqlite3_int64 autocrypt_timestamp
When the email was sent.
Definition lib.h:130
sqlite3_int64 last_seen
When was the peer last seen.
Definition lib.h:129
bool prefer_encrypt
false = nopref, true = mutual
Definition lib.h:133
char * subtype
content-type subtype
Definition body.h:61
unsigned int type
content-type primary type, ContentType
Definition body.h:40
String manipulation buffer.
Definition buffer.h:36
time_t date_sent
Time when the message was sent (UTC)
Definition email.h:60
char * message_id
Message ID.
Definition envelope.h:73
struct AutocryptHeader * autocrypt
Autocrypt header.
Definition envelope.h:87
struct AddressList from
Email's 'From' list.
Definition envelope.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_process_gossip_header()

int mutt_autocrypt_process_gossip_header ( struct Email * e,
struct Envelope * prot_headers )

Parse an Autocrypt email gossip header.

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

Definition at line 411 of file autocrypt.c.

412{
413 struct AutocryptPeer *peer = NULL;
414 struct AutocryptGossipHistory *gossip_hist = NULL;
415 struct Buffer *keyid = NULL;
416 struct Address *peer_addr = NULL;
417 struct Address ac_hdr_addr = { 0 };
418 ac_hdr_addr.mailbox = buf_new(NULL);
419 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
420 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
421 int rc = -1;
422
423 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
424 if (!c_autocrypt)
425 {
426 rc = 0;
427 goto cleanup;
428 }
429
430 if (mutt_autocrypt_init(false) != 0)
431 goto cleanup;
432
433 if (!e || !e->env || !prot_headers)
434 {
435 rc = 0;
436 goto cleanup;
437 }
438
439 struct Envelope *env = e->env;
440
441 struct Address *from = TAILQ_FIRST(&env->from);
442 if (!from)
443 {
444 rc = 0;
445 goto cleanup;
446 }
447
448 /* Ignore emails that appear to be more than a week in the future,
449 * since they can block all future updates during that time. */
450 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
451 {
452 rc = 0;
453 goto cleanup;
454 }
455
456 keyid = buf_pool_get();
457
458 /* Normalize the recipient list for comparison */
459 mutt_addrlist_copy(&recips, &env->to, false);
460 mutt_addrlist_copy(&recips, &env->cc, false);
461 mutt_addrlist_copy(&recips, &env->reply_to, false);
463
464 for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
465 ac_hdr = ac_hdr->next)
466 {
467 if (ac_hdr->invalid)
468 continue;
469
470 /* normalize for comparison against recipient list */
471 buf_strcpy(ac_hdr_addr.mailbox, ac_hdr->addr);
472 ac_hdr_addr.is_intl = true;
473 ac_hdr_addr.intl_checked = true;
475
476 /* Check to make sure the address is in the recipient list. */
477 TAILQ_FOREACH(peer_addr, &recips, entries)
478 {
479 if (buf_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
480 break;
481 }
482
483 if (!peer_addr)
484 continue;
485
486 if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
487 goto cleanup;
488
489 if (peer)
490 {
491 if (e->date_sent <= peer->gossip_timestamp)
492 {
494 continue;
495 }
496
497 update_db = true;
498 peer->gossip_timestamp = e->date_sent;
499 /* This is slightly different from the autocrypt 1.1 spec.
500 * Avoid setting an empty peer.gossip_keydata with a value that matches
501 * the current peer.keydata. */
502 if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
503 (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
504 {
505 import_gpg = true;
506 insert_db_history = true;
507 mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
508 }
509 }
510 else
511 {
512 import_gpg = true;
513 insert_db = true;
514 insert_db_history = true;
515 }
516
517 if (!peer)
518 {
520 peer->gossip_timestamp = e->date_sent;
521 peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
522 }
523
524 if (import_gpg)
525 {
527 goto cleanup;
529 }
530
531 if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
532 goto cleanup;
533
534 if (update_db && mutt_autocrypt_db_peer_update(peer))
535 goto cleanup;
536
537 if (insert_db_history)
538 {
540 gossip_hist->sender_email_addr = buf_strdup(from->mailbox);
541 gossip_hist->email_msgid = mutt_str_dup(env->message_id);
542 gossip_hist->timestamp = e->date_sent;
543 gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
544 if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
545 goto cleanup;
546 }
547
550 buf_reset(keyid);
551 update_db = false;
552 insert_db = false;
553 insert_db_history = false;
554 import_gpg = false;
555 }
556
557 rc = 0;
558
559cleanup:
560 buf_free(&ac_hdr_addr.mailbox);
561 mutt_addrlist_clear(&recips);
564 buf_pool_release(&keyid);
565
566 return rc;
567}
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition db.c:173
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition db.c:854
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:883
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition db.c:162
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition db.c:863
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
void buf_free(struct Buffer **ptr)
Deallocates a buffer.
Definition buffer.c:319
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition buffer.c:304
bool buf_str_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal.
Definition buffer.c:683
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
bool intl_checked
Checked for IDN?
Definition address.h:40
bool is_intl
International Domain Name.
Definition address.h:39
Autocrypt gossip history.
Definition lib.h:154
char * email_msgid
Sender's email's message id.
Definition lib.h:157
char * sender_email_addr
Sender's email address.
Definition lib.h:156
char * gossip_keydata
Gossip Key data.
Definition lib.h:159
sqlite3_int64 timestamp
Timestamp of sender's email.
Definition lib.h:158
sqlite3_int64 gossip_timestamp
Timestamp of Gossip header.
Definition lib.h:134
+ 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 717 of file autocrypt.c.

718{
719 int rc = -1;
720 struct AutocryptAccount *account = NULL;
722
723 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
724 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
725 return -1;
726
727 struct Address *from = TAILQ_FIRST(&e->env->from);
728 if (!from || TAILQ_NEXT(from, entries))
729 return -1;
730
731 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
732 goto cleanup;
733 if (!account->keyid)
734 goto cleanup;
735 if (!account->enabled)
736 goto cleanup;
737
738 mutt_str_replace(&mod_data->autocrypt_sign_as, account->keyid);
739 mutt_str_replace(&mod_data->autocrypt_default_key, account->keyid);
740
741 rc = 0;
742
743cleanup:
745 return rc;
746}
char * keyid
PGP Key id.
Definition lib.h:116
bool enabled
Is this account enabled.
Definition lib.h:119
char * autocrypt_sign_as
Autocrypt Key id to sign as.
Definition module_data.h:36
char * autocrypt_default_key
Autocrypt default key id (used for postponing messages)
Definition module_data.h:35
+ 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 ( const struct Email * e,
char ** keylist )

Get the recommended action for an Email.

Parameters
[in]eEmail
[out]keylistList of Autocrypt key ids
Return values
enumAutocryptRec Recommendation, 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 578 of file autocrypt.c.

579{
581 struct AutocryptAccount *account = NULL;
582 struct AutocryptPeer *peer = NULL;
583 struct Address *recip = NULL;
584 bool all_encrypt = true, has_discourage = false;
585 const char *matching_key = NULL;
586 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
587 struct Buffer *keylist_buf = NULL;
588
589 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
590 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
591 {
592 if (keylist)
593 {
594 /* L10N: Error displayed if the user tries to force sending an Autocrypt
595 email when the engine is not available. */
596 mutt_message(_("Autocrypt is not available"));
597 }
598 return AUTOCRYPT_REC_OFF;
599 }
600
601 struct Address *from = TAILQ_FIRST(&e->env->from);
602 if (!from || TAILQ_NEXT(from, entries))
603 {
604 if (keylist)
605 mutt_message(_("Autocrypt is not available"));
606 return AUTOCRYPT_REC_OFF;
607 }
608
610 {
611 if (keylist)
612 mutt_message(_("Autocrypt is not available"));
613 return AUTOCRYPT_REC_OFF;
614 }
615
616 if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
617 {
618 if (keylist)
619 {
620 /* L10N: Error displayed if the user tries to force sending an Autocrypt
621 email when the account does not exist or is not enabled.
622 %s is the From email address used to look up the Autocrypt account.
623 */
624 mutt_message(_("Autocrypt is not enabled for %s"), buf_string(from->mailbox));
625 }
626 goto cleanup;
627 }
628
629 keylist_buf = buf_pool_get();
630 buf_addstr(keylist_buf, account->keyid);
631
632 mutt_addrlist_copy(&recips, &e->env->to, false);
633 mutt_addrlist_copy(&recips, &e->env->cc, false);
634 mutt_addrlist_copy(&recips, &e->env->bcc, false);
635
636 rc = AUTOCRYPT_REC_NO;
637 if (TAILQ_EMPTY(&recips))
638 goto cleanup;
639
640 TAILQ_FOREACH(recip, &recips, entries)
641 {
642 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
643 {
644 if (keylist)
645 {
646 /* L10N: s is an email address. Autocrypt is scanning for the keyids
647 to use to encrypt, but it can't find a valid keyid for this address.
648 The message is printed and they are returned to the compose menu. */
649 mutt_message(_("No (valid) autocrypt key found for %s"),
650 buf_string(recip->mailbox));
651 }
652 goto cleanup;
653 }
654
656 {
657 matching_key = peer->keyid;
658
659 if (!(peer->last_seen && peer->autocrypt_timestamp) ||
660 (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
661 {
662 has_discourage = true;
663 all_encrypt = false;
664 }
665
666 if (!account->prefer_encrypt || !peer->prefer_encrypt)
667 all_encrypt = false;
668 }
670 {
671 matching_key = peer->gossip_keyid;
672
673 has_discourage = true;
674 all_encrypt = false;
675 }
676 else
677 {
678 if (keylist)
679 {
680 mutt_message(_("No (valid) autocrypt key found for %s"),
681 buf_string(recip->mailbox));
682 }
683 goto cleanup;
684 }
685
686 if (!buf_is_empty(keylist_buf))
687 buf_addch(keylist_buf, ' ');
688 buf_addstr(keylist_buf, matching_key);
689
691 }
692
693 if (all_encrypt)
695 else if (has_discourage)
697 else
699
700 if (keylist)
701 mutt_str_replace(keylist, buf_string(keylist_buf));
702
703cleanup:
705 mutt_addrlist_clear(&recips);
707 buf_pool_release(&keylist_buf);
708 return rc;
709}
AutocryptRec
Recommendation.
Definition lib.h:166
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
#define mutt_message(...)
Definition logging2.h:93
#define _(a)
Definition message.h:28
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:107
#define TAILQ_EMPTY(head)
Definition queue.h:778
bool prefer_encrypt
false = nopref, true = mutual
Definition lib.h:118
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct AddressList bcc
Email's 'Bcc' list.
Definition envelope.h:62
+ Here is the call graph for this function:
+ 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 784 of file autocrypt.c.

785{
786 int rc = -1;
787 struct AutocryptAccount *account = NULL;
788
789 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
790 if (!c_autocrypt || mutt_autocrypt_init(false) || !env)
791 return -1;
792
793 struct Address *from = TAILQ_FIRST(&env->from);
794 if (!from || TAILQ_NEXT(from, entries))
795 return -1;
796
797 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
798 goto cleanup;
799 if (!account->keydata)
800 goto cleanup;
801 if (!account->enabled)
802 goto cleanup;
803
804 fputs("Autocrypt: ", fp);
806 account->keydata);
807
808 rc = 0;
809
810cleanup:
812 return rc;
813}
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:755
+ 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 822 of file autocrypt.c.

823{
824 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
825 if (!c_autocrypt || mutt_autocrypt_init(false) || !env)
826 return -1;
827
828 for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
829 gossip = gossip->next)
830 {
831 fputs("Autocrypt-Gossip: ", fp);
832 write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
833 }
834
835 return 0;
836}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: