NeoMutt  2025-12-11-769-g906513
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 (void)
 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:665
#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:80
Collection of related functions.
Definition menu.h:68
@ 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 ( void )

Shutdown Autocrypt.

Definition at line 135 of file autocrypt.c.

136{
138}
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition db.c:126
+ 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 843 of file autocrypt.c.

844{
845 int rc = -1;
846 struct AutocryptPeer *peer = NULL;
847 struct AutocryptAccount *account = NULL;
848 struct Address *recip = NULL;
849
850 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
851 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
852 return -1;
853
854 struct Envelope *mime_headers = e->body->mime_headers;
855 if (!mime_headers)
856 mime_headers = e->body->mime_headers = mutt_env_new();
858
859 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
860
861 mutt_addrlist_copy(&recips, &e->env->to, false);
862 mutt_addrlist_copy(&recips, &e->env->cc, false);
863
864 TAILQ_FOREACH(recip, &recips, entries)
865 {
866 /* At this point, we just accept missing keys and include what we can. */
867 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
868 continue;
869
870 const char *keydata = NULL;
872 keydata = peer->keydata;
874 keydata = peer->gossip_keydata;
875
876 if (keydata)
877 {
878 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
879 gossip->addr = mutt_str_dup(peer->email_addr);
880 gossip->keydata = mutt_str_dup(keydata);
881 gossip->next = mime_headers->autocrypt_gossip;
882 mime_headers->autocrypt_gossip = gossip;
883 }
884
886 }
887
888 TAILQ_FOREACH(recip, &e->env->reply_to, entries)
889 {
890 const char *addr = NULL;
891 const char *keydata = NULL;
892 if (mutt_autocrypt_db_account_get(recip, &account) > 0)
893 {
894 addr = account->email_addr;
895 keydata = account->keydata;
896 }
897 else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
898 {
899 addr = peer->email_addr;
901 keydata = peer->keydata;
903 keydata = peer->gossip_keydata;
904 }
905
906 if (keydata)
907 {
908 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
909 gossip->addr = mutt_str_dup(addr);
910 gossip->keydata = mutt_str_dup(keydata);
911 gossip->next = mime_headers->autocrypt_gossip;
912 mime_headers->autocrypt_gossip = gossip;
913 }
916 }
917
918 rc = 0;
919
920 mutt_addrlist_clear(&recips);
923 return rc;
924}
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:260
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition db.c:569
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition db.c:241
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition db.c:547
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);
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 262 of file autocrypt.c.

263{
264 struct AutocryptHeader *valid_ac_hdr = NULL;
265 struct AutocryptPeer *peer = NULL;
266 struct AutocryptPeerHistory *peerhist = NULL;
267 struct Buffer *keyid = NULL;
268 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
269 int rc = -1;
270
271 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
272 if (!c_autocrypt)
273 return 0;
274
275 if (mutt_autocrypt_init(false))
276 return -1;
277
278 if (!e || !e->body || !env)
279 return 0;
280
281 /* 1.1 spec says to skip emails with more than one From header */
282 struct Address *from = TAILQ_FIRST(&env->from);
283 if (!from || TAILQ_NEXT(from, entries))
284 return 0;
285
286 /* 1.1 spec also says to skip multipart/report emails */
287 if ((e->body->type == TYPE_MULTIPART) && mutt_istr_equal(e->body->subtype, "report"))
288 {
289 return 0;
290 }
291
292 /* Ignore emails that appear to be more than a week in the future,
293 * since they can block all future updates during that time. */
294 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
295 return 0;
296
297 for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
298 {
299 if (ac_hdr->invalid)
300 continue;
301
302 /* NOTE: this assumes the processing is occurring right after
303 * mutt_parse_rfc822_line() and the from ADDR is still in the same
304 * form (intl) as the autocrypt header addr field */
305 if (!mutt_istr_equal(buf_string(from->mailbox), ac_hdr->addr))
306 continue;
307
308 /* 1.1 spec says ignore all, if more than one valid header is found. */
309 if (valid_ac_hdr)
310 {
311 valid_ac_hdr = NULL;
312 break;
313 }
314 valid_ac_hdr = ac_hdr;
315 }
316
317 if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
318 goto cleanup;
319
320 if (peer)
321 {
322 if (e->date_sent <= peer->autocrypt_timestamp)
323 {
324 rc = 0;
325 goto cleanup;
326 }
327
328 if (e->date_sent > peer->last_seen)
329 {
330 update_db = true;
331 peer->last_seen = e->date_sent;
332 }
333
334 if (valid_ac_hdr)
335 {
336 update_db = true;
338 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
339 if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
340 {
341 import_gpg = true;
342 insert_db_history = true;
343 mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
344 }
345 }
346 }
347 else if (valid_ac_hdr)
348 {
349 import_gpg = true;
350 insert_db = true;
351 insert_db_history = true;
352 }
353
354 if (!(import_gpg || insert_db || update_db))
355 {
356 rc = 0;
357 goto cleanup;
358 }
359
360 if (!peer)
361 {
363 peer->last_seen = e->date_sent;
365 peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
366 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
367 }
368
369 if (import_gpg)
370 {
371 keyid = buf_pool_get();
373 goto cleanup;
374 mutt_str_replace(&peer->keyid, buf_string(keyid));
375 }
376
377 if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
378 goto cleanup;
379
380 if (update_db && mutt_autocrypt_db_peer_update(peer))
381 goto cleanup;
382
383 if (insert_db_history)
384 {
386 peerhist->email_msgid = mutt_str_dup(env->message_id);
387 peerhist->timestamp = e->date_sent;
388 peerhist->keydata = mutt_str_dup(peer->keydata);
389 if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
390 goto cleanup;
391 }
392
393 rc = 0;
394
395cleanup:
398 buf_pool_release(&keyid);
399
400 return rc;
401}
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition db.c:538
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition db.c:641
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition db.c:711
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition db.c:781
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition db.c:772
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition db.c:800
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 410 of file autocrypt.c.

411{
412 struct AutocryptPeer *peer = NULL;
413 struct AutocryptGossipHistory *gossip_hist = NULL;
414 struct Buffer *keyid = NULL;
415 struct Address *peer_addr = NULL;
416 struct Address ac_hdr_addr = { 0 };
417 ac_hdr_addr.mailbox = buf_new(NULL);
418 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
419 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
420 int rc = -1;
421
422 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
423 if (!c_autocrypt)
424 {
425 rc = 0;
426 goto cleanup;
427 }
428
429 if (mutt_autocrypt_init(false))
430 goto cleanup;
431
432 if (!e || !e->env || !prot_headers)
433 {
434 rc = 0;
435 goto cleanup;
436 }
437
438 struct Envelope *env = e->env;
439
440 struct Address *from = TAILQ_FIRST(&env->from);
441 if (!from)
442 {
443 rc = 0;
444 goto cleanup;
445 }
446
447 /* Ignore emails that appear to be more than a week in the future,
448 * since they can block all future updates during that time. */
449 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
450 {
451 rc = 0;
452 goto cleanup;
453 }
454
455 keyid = buf_pool_get();
456
457 /* Normalize the recipient list for comparison */
458 mutt_addrlist_copy(&recips, &env->to, false);
459 mutt_addrlist_copy(&recips, &env->cc, false);
460 mutt_addrlist_copy(&recips, &env->reply_to, false);
462
463 for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
464 ac_hdr = ac_hdr->next)
465 {
466 if (ac_hdr->invalid)
467 continue;
468
469 /* normalize for comparison against recipient list */
470 buf_strcpy(ac_hdr_addr.mailbox, ac_hdr->addr);
471 ac_hdr_addr.is_intl = true;
472 ac_hdr_addr.intl_checked = true;
474
475 /* Check to make sure the address is in the recipient list. */
476 TAILQ_FOREACH(peer_addr, &recips, entries)
477 {
478 if (buf_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
479 break;
480 }
481
482 if (!peer_addr)
483 continue;
484
485 if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
486 goto cleanup;
487
488 if (peer)
489 {
490 if (e->date_sent <= peer->gossip_timestamp)
491 {
493 continue;
494 }
495
496 update_db = true;
497 peer->gossip_timestamp = e->date_sent;
498 /* This is slightly different from the autocrypt 1.1 spec.
499 * Avoid setting an empty peer.gossip_keydata with a value that matches
500 * the current peer.keydata. */
501 if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
502 (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
503 {
504 import_gpg = true;
505 insert_db_history = true;
506 mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
507 }
508 }
509 else
510 {
511 import_gpg = true;
512 insert_db = true;
513 insert_db_history = true;
514 }
515
516 if (!peer)
517 {
519 peer->gossip_timestamp = e->date_sent;
520 peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
521 }
522
523 if (import_gpg)
524 {
526 goto cleanup;
528 }
529
530 if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
531 goto cleanup;
532
533 if (update_db && mutt_autocrypt_db_peer_update(peer))
534 goto cleanup;
535
536 if (insert_db_history)
537 {
539 gossip_hist->sender_email_addr = buf_strdup(from->mailbox);
540 gossip_hist->email_msgid = mutt_str_dup(env->message_id);
541 gossip_hist->timestamp = e->date_sent;
542 gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
543 if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
544 goto cleanup;
545 }
546
549 buf_reset(keyid);
550 update_db = false;
551 insert_db = false;
552 insert_db_history = false;
553 import_gpg = false;
554 }
555
556 rc = 0;
557
558cleanup:
559 buf_free(&ac_hdr_addr.mailbox);
560 mutt_addrlist_clear(&recips);
563 buf_pool_release(&keyid);
564
565 return rc;
566}
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition db.c:174
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition db.c:855
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:884
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition db.c:163
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition db.c:864
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 716 of file autocrypt.c.

717{
718 int rc = -1;
719 struct AutocryptAccount *account = NULL;
721
722 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
723 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
724 return -1;
725
726 struct Address *from = TAILQ_FIRST(&e->env->from);
727 if (!from || TAILQ_NEXT(from, entries))
728 return -1;
729
730 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
731 goto cleanup;
732 if (!account->keyid)
733 goto cleanup;
734 if (!account->enabled)
735 goto cleanup;
736
737 mutt_str_replace(&mod_data->autocrypt_sign_as, account->keyid);
738 mutt_str_replace(&mod_data->autocrypt_default_key, account->keyid);
739
740 rc = 0;
741
742cleanup:
744 return rc;
745}
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 577 of file autocrypt.c.

578{
580 struct AutocryptAccount *account = NULL;
581 struct AutocryptPeer *peer = NULL;
582 struct Address *recip = NULL;
583 bool all_encrypt = true, has_discourage = false;
584 const char *matching_key = NULL;
585 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
586 struct Buffer *keylist_buf = NULL;
587
588 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
589 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
590 {
591 if (keylist)
592 {
593 /* L10N: Error displayed if the user tries to force sending an Autocrypt
594 email when the engine is not available. */
595 mutt_message(_("Autocrypt is not available"));
596 }
597 return AUTOCRYPT_REC_OFF;
598 }
599
600 struct Address *from = TAILQ_FIRST(&e->env->from);
601 if (!from || TAILQ_NEXT(from, entries))
602 {
603 if (keylist)
604 mutt_message(_("Autocrypt is not available"));
605 return AUTOCRYPT_REC_OFF;
606 }
607
609 {
610 if (keylist)
611 mutt_message(_("Autocrypt is not available"));
612 return AUTOCRYPT_REC_OFF;
613 }
614
615 if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
616 {
617 if (keylist)
618 {
619 /* L10N: Error displayed if the user tries to force sending an Autocrypt
620 email when the account does not exist or is not enabled.
621 %s is the From email address used to look up the Autocrypt account.
622 */
623 mutt_message(_("Autocrypt is not enabled for %s"), buf_string(from->mailbox));
624 }
625 goto cleanup;
626 }
627
628 keylist_buf = buf_pool_get();
629 buf_addstr(keylist_buf, account->keyid);
630
631 mutt_addrlist_copy(&recips, &e->env->to, false);
632 mutt_addrlist_copy(&recips, &e->env->cc, false);
633 mutt_addrlist_copy(&recips, &e->env->bcc, false);
634
635 rc = AUTOCRYPT_REC_NO;
636 if (TAILQ_EMPTY(&recips))
637 goto cleanup;
638
639 TAILQ_FOREACH(recip, &recips, entries)
640 {
641 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
642 {
643 if (keylist)
644 {
645 /* L10N: s is an email address. Autocrypt is scanning for the keyids
646 to use to encrypt, but it can't find a valid keyid for this address.
647 The message is printed and they are returned to the compose menu. */
648 mutt_message(_("No (valid) autocrypt key found for %s"),
649 buf_string(recip->mailbox));
650 }
651 goto cleanup;
652 }
653
655 {
656 matching_key = peer->keyid;
657
658 if (!(peer->last_seen && peer->autocrypt_timestamp) ||
659 (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
660 {
661 has_discourage = true;
662 all_encrypt = false;
663 }
664
665 if (!account->prefer_encrypt || !peer->prefer_encrypt)
666 all_encrypt = false;
667 }
669 {
670 matching_key = peer->gossip_keyid;
671
672 has_discourage = true;
673 all_encrypt = false;
674 }
675 else
676 {
677 if (keylist)
678 {
679 mutt_message(_("No (valid) autocrypt key found for %s"),
680 buf_string(recip->mailbox));
681 }
682 goto cleanup;
683 }
684
685 if (!buf_is_empty(keylist_buf))
686 buf_addch(keylist_buf, ' ');
687 buf_addstr(keylist_buf, matching_key);
688
690 }
691
692 if (all_encrypt)
694 else if (has_discourage)
696 else
698
699 if (keylist)
700 mutt_str_replace(keylist, buf_string(keylist_buf));
701
702cleanup:
704 mutt_addrlist_clear(&recips);
706 buf_pool_release(&keylist_buf);
707 return rc;
708}
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:100
#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 783 of file autocrypt.c.

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

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