NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

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

#include <sqlite3.h>
#include <stdbool.h>
#include <stdio.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

void dlg_select_autocrypt_account (void)
 Display the Autocrypt account Menu. More...
 
void mutt_autocrypt_cleanup (void)
 Shutdown Autocrypt. More...
 
int mutt_autocrypt_generate_gossip_list (struct Email *e)
 Create the gossip list headers. More...
 
int mutt_autocrypt_init (bool can_create)
 Initialise Autocrypt. 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...
 
int mutt_autocrypt_set_sign_as_default_key (struct Email *e)
 Set the Autocrypt default key for signing. More...
 
enum AutocryptRec mutt_autocrypt_ui_recommendation (const struct Email *e, char **keylist)
 Get the recommended action for an Email. 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...
 

Variables

char * AutocryptSignAs
 Autocrypt Key id to sign as. More...
 
char * AutocryptDefaultKey
 Autocrypt default key id (used for postponing messages) 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 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 156 of file lib.h.

157{
163};
@ AUTOCRYPT_REC_DISCOURAGE
Prefer not to use Autocrypt.
Definition: lib.h:160
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition: lib.h:159
@ AUTOCRYPT_REC_OFF
No recommendations.
Definition: lib.h:158
@ AUTOCRYPT_REC_AVAILABLE
Autocrypt is available.
Definition: lib.h:161
@ AUTOCRYPT_REC_YES
Autocrypt should be used.
Definition: lib.h:162

Function Documentation

◆ dlg_select_autocrypt_account()

void dlg_select_autocrypt_account ( void  )

Display the Autocrypt account Menu.

Definition at line 306 of file dlg_autocrypt.c.

307{
308 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
309 if (!c_autocrypt)
310 return;
311
312 if (mutt_autocrypt_init(false))
313 return;
314
317
318 struct Menu *menu = dlg->wdata;
320
321 populate_menu(menu);
322
323 struct AutocryptData ad = { false, menu };
324 dlg->wdata = &ad;
325
326 struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
327 // L10N: Autocrypt Account Management Menu title
328 sbar_set_title(sbar, _("Autocrypt Accounts"));
329
330 // NT_COLOR is handled by the SimpleDialog
333
334 // ---------------------------------------------------------------------------
335 // Event Loop
336 int op = OP_NULL;
337 do
338 {
339 menu_tagging_dispatcher(menu->win, op);
340 window_redraw(NULL);
341
343 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
344 if (op < 0)
345 continue;
346 if (op == OP_NULL)
347 {
349 continue;
350 }
352
353 int rc = autocrypt_function_dispatcher(dlg, op);
354
355 if (rc == FR_UNKNOWN)
356 rc = menu_function_dispatcher(menu->win, op);
357 if (rc == FR_UNKNOWN)
358 rc = global_function_dispatcher(NULL, op);
359 } while (!ad.done);
360 // ---------------------------------------------------------------------------
361
362 simple_dialog_free(&dlg);
363}
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:97
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
static const struct Mapping AutocryptAcctHelp[]
Help Bar for the Autocrypt Account selection dialog.
Definition: dlg_autocrypt.c:87
bool populate_menu(struct Menu *menu)
Add the Autocrypt data to a Menu.
int menu_tagging_dispatcher(struct MuttWindow *win, int op)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition: tagging.c:223
int autocrypt_function_dispatcher(struct MuttWindow *win, int op)
Perform a Autocrypt function - Implements function_dispatcher_t -.
Definition: functions.c:169
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:164
int menu_function_dispatcher(struct MuttWindow *win, int op)
Perform a Menu function - Implements function_dispatcher_t -.
Definition: functions.c:320
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static void autocrypt_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
Create a line for the Autocrypt account menu - Implements Menu::make_entry() -.
static int autocrypt_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
static int autocrypt_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:166
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:129
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1061
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
#define _(a)
Definition: message.h:28
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:604
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:522
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
@ WT_DLG_AUTOCRYPT
Autocrypt Dialog, dlg_select_autocrypt_account()
Definition: mutt_window.h:79
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:55
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:224
Data to pass to the Autocrypt Functions.
Definition: functions.h:34
bool done
Should we close the Dialog?
Definition: functions.h:35
struct Menu * menu
Autocrypt Menu.
Definition: functions.h:36
Definition: lib.h:69
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:96
void * wdata
Private data.
Definition: mutt_window.h:145
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
@ MENU_AUTOCRYPT_ACCT
Autocrypt Account menu.
Definition: type.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 139 of file autocrypt.c.

140{
142}
void mutt_autocrypt_db_close(void)
Close the Autocrypt SQLite database connection.
Definition: db.c:130
+ 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 828 of file autocrypt.c.

829{
830 int rc = -1;
831 struct AutocryptPeer *peer = NULL;
832 struct AutocryptAccount *account = NULL;
833 struct Address *recip = NULL;
834
835 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
836 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
837 return -1;
838
839 struct Envelope *mime_headers = e->body->mime_headers;
840 if (!mime_headers)
841 mime_headers = e->body->mime_headers = mutt_env_new();
843
844 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
845
846 mutt_addrlist_copy(&recips, &e->env->to, false);
847 mutt_addrlist_copy(&recips, &e->env->cc, false);
848
849 TAILQ_FOREACH(recip, &recips, entries)
850 {
851 /* At this point, we just accept missing keys and include what we can. */
852 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
853 continue;
854
855 const char *keydata = NULL;
857 keydata = peer->keydata;
859 keydata = peer->gossip_keydata;
860
861 if (keydata)
862 {
863 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
864 gossip->addr = mutt_str_dup(peer->email_addr);
865 gossip->keydata = mutt_str_dup(keydata);
866 gossip->next = mime_headers->autocrypt_gossip;
867 mime_headers->autocrypt_gossip = gossip;
868 }
869
871 }
872
873 TAILQ_FOREACH(recip, &e->env->reply_to, entries)
874 {
875 const char *addr = NULL;
876 const char *keydata = NULL;
877 if (mutt_autocrypt_db_account_get(recip, &account) > 0)
878 {
879 addr = account->email_addr;
880 keydata = account->keydata;
881 }
882 else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
883 {
884 addr = peer->email_addr;
886 keydata = peer->keydata;
888 keydata = peer->gossip_keydata;
889 }
890
891 if (keydata)
892 {
893 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
894 gossip->addr = mutt_str_dup(addr);
895 gossip->keydata = mutt_str_dup(keydata);
896 gossip->next = mime_headers->autocrypt_gossip;
897 mime_headers->autocrypt_gossip = gossip;
898 }
901 }
902
903 mutt_addrlist_clear(&recips);
906 return rc;
907}
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
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_autocrypt_db_account_get(struct Address *addr, struct AutocryptAccount **account)
Get Autocrypt Account data from the database.
Definition: db.c:263
int mutt_autocrypt_db_peer_get(struct Address *addr, struct AutocryptPeer **peer)
Get peer info from the Autocrypt database.
Definition: db.c:550
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:244
void mutt_autocrypt_db_peer_free(struct AutocryptPeer **ptr)
Free an AutocryptPeer.
Definition: db.c:528
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:43
void mutt_autocrypthdr_free(struct AutocryptHeader **p)
Free an AutocryptHeader.
Definition: envelope.c:75
struct AutocryptHeader * mutt_autocrypthdr_new(void)
Create a new AutocryptHeader.
Definition: envelope.c:66
bool mutt_autocrypt_gpgme_is_valid_key(const char *keyid)
Is a key id valid?
Definition: gpgme.c:357
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
An email address.
Definition: address.h:36
Autocrypt account.
Definition: lib.h:106
char * email_addr
Email address.
Definition: lib.h:107
char * keydata
PGP Key data.
Definition: lib.h:109
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:118
char * gossip_keydata
Gossip Key data.
Definition: lib.h:127
char * keyid
PGP Key id.
Definition: lib.h:122
char * gossip_keyid
Gossip Key id.
Definition: lib.h:126
char * keydata
PGP Key data.
Definition: lib.h:123
char * email_addr
Email address.
Definition: lib.h:119
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:75
struct Envelope * env
Envelope information.
Definition: email.h:66
struct Body * body
List of MIME parts.
Definition: email.h:67
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:90
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
+ 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 97 of file autocrypt.c.

98{
99 if (AutocryptDB)
100 return 0;
101
102 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
103 const char *const c_autocrypt_dir = cs_subset_path(NeoMutt->sub, "autocrypt_dir");
104 if (!c_autocrypt || !c_autocrypt_dir)
105 return -1;
106
108 /* The init process can display menus at various points
109 *(e.g. browser, pgp key selection). This allows the screen to be
110 * autocleared after each menu, so the subsequent prompts can be
111 * read. */
113
114 if (autocrypt_dir_init(can_create))
115 goto bail;
116
118 goto bail;
119
120 if (mutt_autocrypt_db_init(can_create))
121 goto bail;
122
123 OptIgnoreMacroEvents = false;
124 OptMenuPopClearScreen = false;
125
126 return 0;
127
128bail:
129 OptIgnoreMacroEvents = false;
130 OptMenuPopClearScreen = false;
131 cs_subset_str_native_set(NeoMutt->sub, "autocrypt", false, NULL);
133 return -1;
134}
sqlite3 * AutocryptDB
Definition: db.c:52
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt SQLite database.
Definition: db.c:79
static int autocrypt_dir_init(bool can_create)
Initialise an Autocrypt directory.
Definition: autocrypt.c:59
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition: gpgme.c:67
bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: options.h:45
bool OptIgnoreMacroEvents
(pseudo) don't process macro/push/exec events while set
Definition: options.h:43
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:305
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_process_autocrypt_header()

int mutt_autocrypt_process_autocrypt_header ( struct Email e,
struct Envelope env 
)

Parse an Autocrypt email header.

Parameters
eEmail
envEnvelope
Return values
0Success
-1Error

Definition at line 265 of file autocrypt.c.

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

414{
415 struct AutocryptPeer *peer = NULL;
416 struct AutocryptGossipHistory *gossip_hist = NULL;
417 struct Address *peer_addr = NULL;
418 struct Address ac_hdr_addr = { 0 };
419 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
420 int rc = -1;
421
422 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
423 if (!c_autocrypt)
424 return 0;
425
426 if (mutt_autocrypt_init(false))
427 return -1;
428
429 if (!e || !e->env || !prot_headers)
430 return 0;
431
432 struct Envelope *env = e->env;
433
434 struct Address *from = TAILQ_FIRST(&env->from);
435 if (!from)
436 return 0;
437
438 /* Ignore emails that appear to be more than a week in the future,
439 * since they can block all future updates during that time. */
440 if (e->date_sent > (mutt_date_epoch() + (7 * 24 * 60 * 60)))
441 return 0;
442
443 struct Buffer *keyid = mutt_buffer_pool_get();
444
445 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
446
447 /* Normalize the recipient list for comparison */
448 mutt_addrlist_copy(&recips, &env->to, false);
449 mutt_addrlist_copy(&recips, &env->cc, false);
450 mutt_addrlist_copy(&recips, &env->reply_to, false);
452
453 for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
454 ac_hdr = ac_hdr->next)
455 {
456 if (ac_hdr->invalid)
457 continue;
458
459 /* normalize for comparison against recipient list */
460 mutt_str_replace(&ac_hdr_addr.mailbox, ac_hdr->addr);
461 ac_hdr_addr.is_intl = true;
462 ac_hdr_addr.intl_checked = true;
464
465 /* Check to make sure the address is in the recipient list. */
466 TAILQ_FOREACH(peer_addr, &recips, entries)
467 {
468 if (mutt_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
469 break;
470 }
471
472 if (!peer_addr)
473 continue;
474
475 if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
476 goto cleanup;
477
478 if (peer)
479 {
480 if (e->date_sent <= peer->gossip_timestamp)
481 {
483 continue;
484 }
485
486 update_db = true;
487 peer->gossip_timestamp = e->date_sent;
488 /* This is slightly different from the autocrypt 1.1 spec.
489 * Avoid setting an empty peer.gossip_keydata with a value that matches
490 * the current peer.keydata. */
491 if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
492 (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
493 {
494 import_gpg = true;
495 insert_db_history = true;
496 mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
497 }
498 }
499 else
500 {
501 import_gpg = true;
502 insert_db = true;
503 insert_db_history = true;
504 }
505
506 if (!peer)
507 {
509 peer->gossip_timestamp = e->date_sent;
510 peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
511 }
512
513 if (import_gpg)
514 {
516 goto cleanup;
518 }
519
520 if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
521 goto cleanup;
522
523 if (update_db && mutt_autocrypt_db_peer_update(peer))
524 goto cleanup;
525
526 if (insert_db_history)
527 {
529 gossip_hist->sender_email_addr = mutt_str_dup(from->mailbox);
530 gossip_hist->email_msgid = mutt_str_dup(env->message_id);
531 gossip_hist->timestamp = e->date_sent;
532 gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
533 if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
534 goto cleanup;
535 }
536
539 mutt_buffer_reset(keyid);
540 update_db = false;
541 insert_db = false;
542 insert_db_history = false;
543 import_gpg = false;
544 }
545
546 rc = 0;
547
548cleanup:
549 FREE(&ac_hdr_addr.mailbox);
550 mutt_addrlist_clear(&recips);
554
555 return rc;
556}
void mutt_autocrypt_db_normalize_addrlist(struct AddressList *al)
Normalise a list of Email Addresses.
Definition: db.c:176
struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new(void)
Create a new AutocryptGossipHistory.
Definition: db.c:812
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:841
void mutt_autocrypt_db_normalize_addr(struct Address *a)
Normalise an Email Address.
Definition: db.c:165
void mutt_autocrypt_db_gossip_history_free(struct AutocryptGossipHistory **ptr)
Free an AutocryptGossipHistory.
Definition: db.c:821
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
#define FREE(x)
Definition: memory.h:43
bool intl_checked
Checked for IDN?
Definition: address.h:41
bool is_intl
International Domain Name.
Definition: address.h:40
Autocrypt gossip history.
Definition: lib.h:145
char * email_msgid
Sender's email's message id.
Definition: lib.h:148
char * sender_email_addr
Sender's email address.
Definition: lib.h:147
char * gossip_keydata
Gossip Key data.
Definition: lib.h:150
sqlite3_int64 timestamp
Timestamp of sender's email.
Definition: lib.h:149
sqlite3_int64 gossip_timestamp
Timestamp of Gossip header.
Definition: lib.h:125
+ 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 702 of file autocrypt.c.

703{
704 int rc = -1;
705 struct AutocryptAccount *account = NULL;
706
707 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
708 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
709 return -1;
710
711 struct Address *from = TAILQ_FIRST(&e->env->from);
712 if (!from || TAILQ_NEXT(from, entries))
713 return -1;
714
715 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
716 goto cleanup;
717 if (!account->keyid)
718 goto cleanup;
719 if (!account->enabled)
720 goto cleanup;
721
724
725 rc = 0;
726
727cleanup:
729 return rc;
730}
char * AutocryptSignAs
Autocrypt Key id to sign as.
Definition: config.c:35
char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: config.c:36
char * keyid
PGP Key id.
Definition: lib.h:108
bool enabled
Is this account enabled.
Definition: lib.h:111
+ 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
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 567 of file autocrypt.c.

568{
570 struct AutocryptAccount *account = NULL;
571 struct AutocryptPeer *peer = NULL;
572 struct Address *recip = NULL;
573 bool all_encrypt = true, has_discourage = false;
574 const char *matching_key = NULL;
575 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
576 struct Buffer *keylist_buf = NULL;
577
578 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
579 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
580 {
581 if (keylist)
582 {
583 /* L10N: Error displayed if the user tries to force sending an Autocrypt
584 email when the engine is not available. */
585 mutt_message(_("Autocrypt is not available"));
586 }
587 return AUTOCRYPT_REC_OFF;
588 }
589
590 struct Address *from = TAILQ_FIRST(&e->env->from);
591 if (!from || TAILQ_NEXT(from, entries))
592 {
593 if (keylist)
594 mutt_message(_("Autocrypt is not available"));
595 return AUTOCRYPT_REC_OFF;
596 }
597
599 {
600 if (keylist)
601 mutt_message(_("Autocrypt is not available"));
602 return AUTOCRYPT_REC_OFF;
603 }
604
605 if ((mutt_autocrypt_db_account_get(from, &account) <= 0) || !account->enabled)
606 {
607 if (keylist)
608 {
609 /* L10N: Error displayed if the user tries to force sending an Autocrypt
610 email when the account does not exist or is not enabled.
611 %s is the From email address used to look up the Autocrypt account.
612 */
613 mutt_message(_("Autocrypt is not enabled for %s"), NONULL(from->mailbox));
614 }
615 goto cleanup;
616 }
617
618 keylist_buf = mutt_buffer_pool_get();
619 mutt_buffer_addstr(keylist_buf, account->keyid);
620
621 mutt_addrlist_copy(&recips, &e->env->to, false);
622 mutt_addrlist_copy(&recips, &e->env->cc, false);
623 mutt_addrlist_copy(&recips, &e->env->bcc, false);
624
625 rc = AUTOCRYPT_REC_NO;
626 if (TAILQ_EMPTY(&recips))
627 goto cleanup;
628
629 TAILQ_FOREACH(recip, &recips, entries)
630 {
631 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
632 {
633 if (keylist)
634 {
635 /* L10N: s is an email address. Autocrypt is scanning for the keyids
636 to use to encrypt, but it can't find a valid keyid for this address.
637 The message is printed and they are returned to the compose menu. */
638 mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
639 }
640 goto cleanup;
641 }
642
644 {
645 matching_key = peer->keyid;
646
647 if (!(peer->last_seen && peer->autocrypt_timestamp) ||
648 (peer->last_seen - peer->autocrypt_timestamp > (35 * 24 * 60 * 60)))
649 {
650 has_discourage = true;
651 all_encrypt = false;
652 }
653
654 if (!account->prefer_encrypt || !peer->prefer_encrypt)
655 all_encrypt = false;
656 }
658 {
659 matching_key = peer->gossip_keyid;
660
661 has_discourage = true;
662 all_encrypt = false;
663 }
664 else
665 {
666 if (keylist)
667 mutt_message(_("No (valid) autocrypt key found for %s"), recip->mailbox);
668 goto cleanup;
669 }
670
671 if (!mutt_buffer_is_empty(keylist_buf))
672 mutt_buffer_addch(keylist_buf, ' ');
673 mutt_buffer_addstr(keylist_buf, matching_key);
674
676 }
677
678 if (all_encrypt)
680 else if (has_discourage)
682 else
684
685 if (keylist)
686 mutt_str_replace(keylist, mutt_buffer_string(keylist_buf));
687
688cleanup:
690 mutt_addrlist_clear(&recips);
692 mutt_buffer_pool_release(&keylist_buf);
693 return rc;
694}
AutocryptRec
Recommendation.
Definition: lib.h:157
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
#define mutt_message(...)
Definition: logging.h:86
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define NONULL(x)
Definition: string2.h:37
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:110
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
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 768 of file autocrypt.c.

769{
770 int rc = -1;
771 struct AutocryptAccount *account = NULL;
772
773 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
774 if (!c_autocrypt || mutt_autocrypt_init(false) || !env)
775 return -1;
776
777 struct Address *from = TAILQ_FIRST(&env->from);
778 if (!from || TAILQ_NEXT(from, entries))
779 return -1;
780
781 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
782 goto cleanup;
783 if (!account->keydata)
784 goto cleanup;
785 if (!account->enabled)
786 goto cleanup;
787
788 fputs("Autocrypt: ", fp);
790 account->keydata);
791
792 rc = 0;
793
794cleanup:
796 return rc;
797}
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:739
+ 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 806 of file autocrypt.c.

807{
808 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
809 if (!c_autocrypt || mutt_autocrypt_init(false) || !env)
810 return -1;
811
812 for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
813 gossip = gossip->next)
814 {
815 fputs("Autocrypt-Gossip: ", fp);
816 write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
817 }
818
819 return 0;
820}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AutocryptSignAs

char* AutocryptSignAs
extern

Autocrypt Key id to sign as.

Definition at line 35 of file config.c.

◆ AutocryptDefaultKey

char* AutocryptDefaultKey
extern

Autocrypt default key id (used for postponing messages)

Definition at line 36 of file config.c.