NeoMutt  2023-05-17-56-ga67199
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:317
#define mutt_debug(LEVEL,...)
Definition: logging2.h:87
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:803
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1077
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#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:73
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:605
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:523
@ 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:48
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:70
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:77
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:97
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 829 of file autocrypt.c.

830{
831 int rc = -1;
832 struct AutocryptPeer *peer = NULL;
833 struct AutocryptAccount *account = NULL;
834 struct Address *recip = NULL;
835
836 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
837 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
838 return -1;
839
840 struct Envelope *mime_headers = e->body->mime_headers;
841 if (!mime_headers)
842 mime_headers = e->body->mime_headers = mutt_env_new();
844
845 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
846
847 mutt_addrlist_copy(&recips, &e->env->to, false);
848 mutt_addrlist_copy(&recips, &e->env->cc, false);
849
850 TAILQ_FOREACH(recip, &recips, entries)
851 {
852 /* At this point, we just accept missing keys and include what we can. */
853 if (mutt_autocrypt_db_peer_get(recip, &peer) <= 0)
854 continue;
855
856 const char *keydata = NULL;
858 keydata = peer->keydata;
860 keydata = peer->gossip_keydata;
861
862 if (keydata)
863 {
864 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
865 gossip->addr = mutt_str_dup(peer->email_addr);
866 gossip->keydata = mutt_str_dup(keydata);
867 gossip->next = mime_headers->autocrypt_gossip;
868 mime_headers->autocrypt_gossip = gossip;
869 }
870
872 }
873
874 TAILQ_FOREACH(recip, &e->env->reply_to, entries)
875 {
876 const char *addr = NULL;
877 const char *keydata = NULL;
878 if (mutt_autocrypt_db_account_get(recip, &account) > 0)
879 {
880 addr = account->email_addr;
881 keydata = account->keydata;
882 }
883 else if (mutt_autocrypt_db_peer_get(recip, &peer) > 0)
884 {
885 addr = peer->email_addr;
887 keydata = peer->keydata;
889 keydata = peer->gossip_keydata;
890 }
891
892 if (keydata)
893 {
894 struct AutocryptHeader *gossip = mutt_autocrypthdr_new();
895 gossip->addr = mutt_str_dup(addr);
896 gossip->keydata = mutt_str_dup(keydata);
897 gossip->next = mime_headers->autocrypt_gossip;
898 mime_headers->autocrypt_gossip = gossip;
899 }
902 }
903
904 mutt_addrlist_clear(&recips);
907 return rc;
908}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:750
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1449
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:556
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:534
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:251
#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
Handle to the open Autocrypt database.
Definition: db.c:53
int mutt_autocrypt_db_init(bool can_create)
Initialise the Autocrypt SQLite database.
Definition: db.c:80
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
bool OptMenuPopClearScreen
(pseudo) clear the screen when popping the last menu
Definition: globals.c:74
bool OptIgnoreMacroEvents
(pseudo) don't process macro/push/exec events while set
Definition: globals.c:72
int mutt_autocrypt_gpgme_init(void)
Initialise GPGME.
Definition: gpgme.c:67
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:310
+ 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 266 of file autocrypt.c.

267{
268 struct AutocryptHeader *valid_ac_hdr = NULL;
269 struct AutocryptPeer *peer = NULL;
270 struct AutocryptPeerHistory *peerhist = NULL;
271 struct Buffer *keyid = NULL;
272 bool update_db = false, insert_db = false, insert_db_history = false, import_gpg = false;
273 int rc = -1;
274
275 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
276 if (!c_autocrypt)
277 return 0;
278
279 if (mutt_autocrypt_init(false))
280 return -1;
281
282 if (!e || !e->body || !env)
283 return 0;
284
285 /* 1.1 spec says to skip emails with more than one From header */
286 struct Address *from = TAILQ_FIRST(&env->from);
287 if (!from || TAILQ_NEXT(from, entries))
288 return 0;
289
290 /* 1.1 spec also says to skip multipart/report emails */
291 if ((e->body->type == TYPE_MULTIPART) && mutt_istr_equal(e->body->subtype, "report"))
292 {
293 return 0;
294 }
295
296 /* Ignore emails that appear to be more than a week in the future,
297 * since they can block all future updates during that time. */
298 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
299 return 0;
300
301 for (struct AutocryptHeader *ac_hdr = env->autocrypt; ac_hdr; ac_hdr = ac_hdr->next)
302 {
303 if (ac_hdr->invalid)
304 continue;
305
306 /* NOTE: this assumes the processing is occurring right after
307 * mutt_parse_rfc822_line() and the from ADDR is still in the same
308 * form (intl) as the autocrypt header addr field */
309 if (!mutt_istr_equal(buf_string(from->mailbox), ac_hdr->addr))
310 continue;
311
312 /* 1.1 spec says ignore all, if more than one valid header is found. */
313 if (valid_ac_hdr)
314 {
315 valid_ac_hdr = NULL;
316 break;
317 }
318 valid_ac_hdr = ac_hdr;
319 }
320
321 if (mutt_autocrypt_db_peer_get(from, &peer) < 0)
322 goto cleanup;
323
324 if (peer)
325 {
326 if (e->date_sent <= peer->autocrypt_timestamp)
327 {
328 rc = 0;
329 goto cleanup;
330 }
331
332 if (e->date_sent > peer->last_seen)
333 {
334 update_db = true;
335 peer->last_seen = e->date_sent;
336 }
337
338 if (valid_ac_hdr)
339 {
340 update_db = true;
342 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
343 if (!mutt_str_equal(peer->keydata, valid_ac_hdr->keydata))
344 {
345 import_gpg = true;
346 insert_db_history = true;
347 mutt_str_replace(&peer->keydata, valid_ac_hdr->keydata);
348 }
349 }
350 }
351 else if (valid_ac_hdr)
352 {
353 import_gpg = true;
354 insert_db = true;
355 insert_db_history = true;
356 }
357
358 if (!(import_gpg || insert_db || update_db))
359 {
360 rc = 0;
361 goto cleanup;
362 }
363
364 if (!peer)
365 {
367 peer->last_seen = e->date_sent;
369 peer->keydata = mutt_str_dup(valid_ac_hdr->keydata);
370 peer->prefer_encrypt = valid_ac_hdr->prefer_encrypt;
371 }
372
373 if (import_gpg)
374 {
375 keyid = buf_pool_get();
377 goto cleanup;
378 mutt_str_replace(&peer->keyid, buf_string(keyid));
379 }
380
381 if (insert_db && mutt_autocrypt_db_peer_insert(from, peer))
382 goto cleanup;
383
384 if (update_db && mutt_autocrypt_db_peer_update(peer))
385 goto cleanup;
386
387 if (insert_db_history)
388 {
390 peerhist->email_msgid = mutt_str_dup(env->message_id);
391 peerhist->timestamp = e->date_sent;
392 peerhist->keydata = mutt_str_dup(peer->keydata);
393 if (mutt_autocrypt_db_peer_history_insert(from, peerhist))
394 goto cleanup;
395 }
396
397 rc = 0;
398
399cleanup:
402 buf_pool_release(&keyid);
403
404 return rc;
405}
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: db.c:525
int mutt_autocrypt_db_peer_insert(struct Address *addr, struct AutocryptPeer *peer)
Insert a peer into the Autocrypt database.
Definition: db.c:624
int mutt_autocrypt_db_peer_update(struct AutocryptPeer *peer)
Update the peer info in an Autocrypt database.
Definition: db.c:690
void mutt_autocrypt_db_peer_history_free(struct AutocryptPeerHistory **ptr)
Free an AutocryptPeerHistory.
Definition: db.c:755
struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new(void)
Create a new AutocryptPeerHistory.
Definition: db.c:746
int mutt_autocrypt_db_peer_history_insert(struct Address *addr, struct AutocryptPeerHistory *peerhist)
Insert peer history into the Autocrypt database.
Definition: db.c:774
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:90
int mutt_autocrypt_gpgme_import_key(const char *keydata, struct Buffer *keyid)
Read a key from GPGME.
Definition: gpgme.c:317
@ 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:446
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
struct Buffer * 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 414 of file autocrypt.c.

415{
416 struct AutocryptPeer *peer = NULL;
417 struct AutocryptGossipHistory *gossip_hist = NULL;
418 struct Address *peer_addr = NULL;
419 struct Address ac_hdr_addr = { 0 };
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 return 0;
426
427 if (mutt_autocrypt_init(false))
428 return -1;
429
430 if (!e || !e->env || !prot_headers)
431 return 0;
432
433 struct Envelope *env = e->env;
434
435 struct Address *from = TAILQ_FIRST(&env->from);
436 if (!from)
437 return 0;
438
439 /* Ignore emails that appear to be more than a week in the future,
440 * since they can block all future updates during that time. */
441 if (e->date_sent > (mutt_date_now() + (7 * 24 * 60 * 60)))
442 return 0;
443
444 struct Buffer *keyid = buf_pool_get();
445
446 struct AddressList recips = TAILQ_HEAD_INITIALIZER(recips);
447
448 /* Normalize the recipient list for comparison */
449 mutt_addrlist_copy(&recips, &env->to, false);
450 mutt_addrlist_copy(&recips, &env->cc, false);
451 mutt_addrlist_copy(&recips, &env->reply_to, false);
453
454 for (struct AutocryptHeader *ac_hdr = prot_headers->autocrypt_gossip; ac_hdr;
455 ac_hdr = ac_hdr->next)
456 {
457 if (ac_hdr->invalid)
458 continue;
459
460 /* normalize for comparison against recipient list */
461 buf_strcpy(ac_hdr_addr.mailbox, ac_hdr->addr);
462 ac_hdr_addr.is_intl = true;
463 ac_hdr_addr.intl_checked = true;
465
466 /* Check to make sure the address is in the recipient list. */
467 TAILQ_FOREACH(peer_addr, &recips, entries)
468 {
469 if (buf_str_equal(peer_addr->mailbox, ac_hdr_addr.mailbox))
470 break;
471 }
472
473 if (!peer_addr)
474 continue;
475
476 if (mutt_autocrypt_db_peer_get(peer_addr, &peer) < 0)
477 goto cleanup;
478
479 if (peer)
480 {
481 if (e->date_sent <= peer->gossip_timestamp)
482 {
484 continue;
485 }
486
487 update_db = true;
488 peer->gossip_timestamp = e->date_sent;
489 /* This is slightly different from the autocrypt 1.1 spec.
490 * Avoid setting an empty peer.gossip_keydata with a value that matches
491 * the current peer.keydata. */
492 if ((peer->gossip_keydata && !mutt_str_equal(peer->gossip_keydata, ac_hdr->keydata)) ||
493 (!peer->gossip_keydata && !mutt_str_equal(peer->keydata, ac_hdr->keydata)))
494 {
495 import_gpg = true;
496 insert_db_history = true;
497 mutt_str_replace(&peer->gossip_keydata, ac_hdr->keydata);
498 }
499 }
500 else
501 {
502 import_gpg = true;
503 insert_db = true;
504 insert_db_history = true;
505 }
506
507 if (!peer)
508 {
510 peer->gossip_timestamp = e->date_sent;
511 peer->gossip_keydata = mutt_str_dup(ac_hdr->keydata);
512 }
513
514 if (import_gpg)
515 {
517 goto cleanup;
519 }
520
521 if (insert_db && mutt_autocrypt_db_peer_insert(peer_addr, peer))
522 goto cleanup;
523
524 if (update_db && mutt_autocrypt_db_peer_update(peer))
525 goto cleanup;
526
527 if (insert_db_history)
528 {
530 gossip_hist->sender_email_addr = buf_strdup(from->mailbox);
531 gossip_hist->email_msgid = mutt_str_dup(env->message_id);
532 gossip_hist->timestamp = e->date_sent;
533 gossip_hist->gossip_keydata = mutt_str_dup(peer->gossip_keydata);
534 if (mutt_autocrypt_db_gossip_history_insert(peer_addr, gossip_hist))
535 goto cleanup;
536 }
537
540 buf_reset(keyid);
541 update_db = false;
542 insert_db = false;
543 insert_db_history = false;
544 import_gpg = false;
545 }
546
547 rc = 0;
548
549cleanup:
550 FREE(&ac_hdr_addr.mailbox);
551 mutt_addrlist_clear(&recips);
554 buf_pool_release(&keyid);
555
556 return rc;
557}
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:827
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:856
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:836
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
bool buf_str_equal(struct Buffer *a, struct Buffer *b)
Return if two buffers are equal.
Definition: buffer.c:647
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:401
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:536
#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 703 of file autocrypt.c.

704{
705 int rc = -1;
706 struct AutocryptAccount *account = NULL;
707
708 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
709 if (!c_autocrypt || mutt_autocrypt_init(false) || !e)
710 return -1;
711
712 struct Address *from = TAILQ_FIRST(&e->env->from);
713 if (!from || TAILQ_NEXT(from, entries))
714 return -1;
715
716 if (mutt_autocrypt_db_account_get(from, &account) <= 0)
717 goto cleanup;
718 if (!account->keyid)
719 goto cleanup;
720 if (!account->enabled)
721 goto cleanup;
722
725
726 rc = 0;
727
728cleanup:
730 return rc;
731}
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
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 568 of file autocrypt.c.

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

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

808{
809 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
810 if (!c_autocrypt || mutt_autocrypt_init(false) || !env)
811 return -1;
812
813 for (struct AutocryptHeader *gossip = env->autocrypt_gossip; gossip;
814 gossip = gossip->next)
815 {
816 fputs("Autocrypt-Gossip: ", fp);
817 write_autocrypt_header_line(fp, gossip->addr, 0, gossip->keydata);
818 }
819
820 return 0;
821}
+ 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.