NeoMutt  2022-04-29-178-g3b62e6
Teaching an old dog new tricks
DOXYGEN
private.h File Reference

Shared constants/structs that are private to Autocrypt. More...

#include <sqlite3.h>
#include <stdbool.h>
+ Include dependency graph for private.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AccountEntry
 An entry in the Autocrypt account Menu. More...
 

Functions

int mutt_autocrypt_account_init (bool prompt)
 Create a new Autocrypt account. More...
 
void mutt_autocrypt_scan_mailboxes (void)
 Scan mailboxes for Autocrypt headers. More...
 
int mutt_autocrypt_db_account_delete (struct AutocryptAccount *acct)
 Delete an Account from the Autocrypt database. More...
 
void mutt_autocrypt_db_account_free (struct AutocryptAccount **ptr)
 Free an AutocryptAccount. More...
 
int mutt_autocrypt_db_account_get (struct Address *addr, struct AutocryptAccount **account)
 Get Autocrypt Account data from the database. More...
 
int mutt_autocrypt_db_account_get_all (struct AutocryptAccount ***accounts, int *num_accounts)
 Get all accounts from an Autocrypt database. More...
 
int mutt_autocrypt_db_account_insert (struct Address *addr, const char *keyid, const char *keydata, bool prefer_encrypt)
 Insert an Account into the Autocrypt database. More...
 
struct AutocryptAccountmutt_autocrypt_db_account_new (void)
 Create a new AutocryptAccount. More...
 
int mutt_autocrypt_db_account_update (struct AutocryptAccount *acct)
 Update Account info in the Autocrypt database. More...
 
void mutt_autocrypt_db_close (void)
 Close the Autocrypt SQLite database connection. More...
 
void mutt_autocrypt_db_gossip_history_free (struct AutocryptGossipHistory **ptr)
 Free an AutocryptGossipHistory. More...
 
int mutt_autocrypt_db_gossip_history_insert (struct Address *addr, struct AutocryptGossipHistory *gossip_hist)
 Insert a gossip history into the Autocrypt database. More...
 
struct AutocryptGossipHistorymutt_autocrypt_db_gossip_history_new (void)
 Create a new AutocryptGossipHistory. More...
 
int mutt_autocrypt_db_init (bool can_create)
 Initialise the Autocrypt SQLite database. More...
 
void mutt_autocrypt_db_normalize_addr (struct Address *a)
 Normalise an Email Address. More...
 
void mutt_autocrypt_db_normalize_addrlist (struct AddressList *al)
 Normalise a list of Email Addresses. More...
 
void mutt_autocrypt_db_peer_free (struct AutocryptPeer **ptr)
 Free an AutocryptPeer. More...
 
int mutt_autocrypt_db_peer_get (struct Address *addr, struct AutocryptPeer **peer)
 Get peer info from the Autocrypt database. More...
 
void mutt_autocrypt_db_peer_history_free (struct AutocryptPeerHistory **ptr)
 Free an AutocryptPeerHistory. More...
 
int mutt_autocrypt_db_peer_history_insert (struct Address *addr, struct AutocryptPeerHistory *peerhist)
 Insert peer history into the Autocrypt database. More...
 
struct AutocryptPeerHistorymutt_autocrypt_db_peer_history_new (void)
 Create a new AutocryptPeerHistory. More...
 
int mutt_autocrypt_db_peer_insert (struct Address *addr, struct AutocryptPeer *peer)
 Insert a peer into the Autocrypt database. More...
 
struct AutocryptPeermutt_autocrypt_db_peer_new (void)
 Create a new AutocryptPeer. More...
 
int mutt_autocrypt_db_peer_update (struct AutocryptPeer *peer)
 Update the peer info in an Autocrypt database. More...
 
int mutt_autocrypt_schema_init (void)
 Set up an Autocrypt database. More...
 
int mutt_autocrypt_schema_update (void)
 Update the version number of the Autocrypt database schema. More...
 
int mutt_autocrypt_gpgme_create_key (struct Address *addr, struct Buffer *keyid, struct Buffer *keydata)
 Create a GPGME key. More...
 
int mutt_autocrypt_gpgme_import_key (const char *keydata, struct Buffer *keyid)
 Read a key from GPGME. More...
 
int mutt_autocrypt_gpgme_init (void)
 Initialise GPGME. More...
 
bool mutt_autocrypt_gpgme_is_valid_key (const char *keyid)
 Is a key id valid? More...
 
int mutt_autocrypt_gpgme_select_key (struct Buffer *keyid, struct Buffer *keydata)
 Select a Autocrypt key. More...
 
int mutt_autocrypt_gpgme_select_or_create_key (struct Address *addr, struct Buffer *keyid, struct Buffer *keydata)
 Ask the user to select or create an Autocrypt key. More...
 
bool populate_menu (struct Menu *menu)
 Add the Autocrypt data to a Menu. More...
 

Variables

sqlite3 * AutocryptDB
 

Detailed Description

Shared constants/structs that are private to Autocrypt.

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

Function Documentation

◆ mutt_autocrypt_account_init()

int mutt_autocrypt_account_init ( bool  prompt)

Create a new Autocrypt account.

Parameters
promptPrompt the user
Return values
0Success
-1Error

This is used the first time autocrypt is initialized, and in the account menu.

Definition at line 153 of file autocrypt.c.

154{
155 struct Address *addr = NULL;
156 struct AutocryptAccount *account = NULL;
157 bool done = false;
158 int rc = -1;
159 bool prefer_encrypt = false;
160
161 if (prompt)
162 {
163 /* L10N: The first time NeoMutt is started with $autocrypt set, it will
164 create $autocrypt_dir and then prompt to create an autocrypt account
165 with this message. */
166 if (mutt_yesorno(_("Create an initial autocrypt account?"), MUTT_YES) != MUTT_YES)
167 return 0;
168 }
169
170 struct Buffer *keyid = mutt_buffer_pool_get();
171 struct Buffer *keydata = mutt_buffer_pool_get();
172
173 const struct Address *c_from = cs_subset_address(NeoMutt->sub, "from");
174 if (c_from)
175 {
176 addr = mutt_addr_copy(c_from);
177 const char *const c_real_name = cs_subset_string(NeoMutt->sub, "real_name");
178 if (!addr->personal && c_real_name)
179 addr->personal = mutt_str_dup(c_real_name);
180 }
181
182 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
183 mutt_addrlist_append(&al, addr);
184
185 do
186 {
187 /* L10N: Autocrypt is asking for the email address to use for the
188 autocrypt account. This will generate a key and add a record
189 to the database for use in autocrypt operations. */
190 if (mutt_edit_address(&al, _("Autocrypt account address: "), false) != 0)
191 goto cleanup;
192
193 addr = TAILQ_FIRST(&al);
194 if (!addr || !addr->mailbox || TAILQ_NEXT(addr, entries))
195 {
196 /* L10N: Autocrypt prompts for an account email address, and requires
197 a single address. This is shown if they entered something invalid,
198 nothing, or more than one address for some reason. */
199 mutt_error(_("Please enter a single email address"));
200 done = false;
201 }
202 else
203 done = true;
204 } while (!done);
205
206 addr = TAILQ_FIRST(&al);
207 if (mutt_autocrypt_db_account_get(addr, &account) < 0)
208 goto cleanup;
209 if (account)
210 {
211 /* L10N: When creating an autocrypt account, this message will be displayed
212 if there is already an account in the database with the email address
213 they just entered. */
214 mutt_error(_("That email address already has an autocrypt account"));
215 goto cleanup;
216 }
217
218 if (mutt_autocrypt_gpgme_select_or_create_key(addr, keyid, keydata))
219 goto cleanup;
220
221 /* L10N: Autocrypt has a setting "prefer-encrypt".
222 When the recommendation algorithm returns "available" and BOTH sender and
223 recipient choose "prefer-encrypt", encryption will be automatically
224 enabled.
225 Otherwise the UI will show encryption is "available" but the user
226 will be required to enable encryption manually. */
227 if (mutt_yesorno(_("Prefer encryption?"), MUTT_NO) == MUTT_YES)
228 prefer_encrypt = true;
229
231 mutt_buffer_string(keydata), prefer_encrypt))
232 {
233 goto cleanup;
234 }
235
236 rc = 0;
237
238cleanup:
239 if (rc == 0)
240 {
241 /* L10N: Message displayed after an autocrypt account is successfully created. */
242 mutt_message(_("Autocrypt account creation succeeded"));
243 }
244 else
245 {
246 /* L10N: Error message displayed if creating an autocrypt account failed
247 or was aborted by the user. */
248 mutt_error(_("Autocrypt account creation aborted"));
249 }
250
254 mutt_buffer_pool_release(&keydata);
255 return rc;
256}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1490
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:716
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_account_insert(struct Address *addr, const char *keyid, const char *keydata, bool prefer_encrypt)
Insert an Account into the Autocrypt database.
Definition: db.c:322
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:244
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: helpers.c:49
int mutt_autocrypt_gpgme_select_or_create_key(struct Address *addr, struct Buffer *keyid, struct Buffer *keydata)
Ask the user to select or create an Autocrypt key.
Definition: gpgme.c:275
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
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
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:38
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:194
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:178
An email address.
Definition: address.h:36
char * mailbox
Mailbox and host address.
Definition: address.h:38
char * personal
Real name of address.
Definition: address.h:37
Autocrypt account.
Definition: lib.h:106
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:110
String manipulation buffer.
Definition: buffer.h:34
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_scan_mailboxes()

void mutt_autocrypt_scan_mailboxes ( void  )

Scan mailboxes for Autocrypt headers.

This is invoked during the first autocrypt initialization, to scan one or more mailboxes for autocrypt headers.

Due to the implementation, header-cached headers are not scanned, so this routine just opens up the mailboxes with $header_cache temporarily disabled.

Definition at line 919 of file autocrypt.c.

920{
921#ifdef USE_HCACHE
922 const char *c_header_cache = cs_subset_path(NeoMutt->sub, "header_cache");
923 char *old_hdrcache = mutt_str_dup(c_header_cache);
924 c_header_cache = NULL;
925#endif
926
927 struct Buffer *folderbuf = mutt_buffer_pool_get();
928
929 /* L10N: The first time autocrypt is enabled, NeoMutt will ask to scan
930 through one or more mailboxes for Autocrypt: headers. Those headers are
931 then captured in the database as peer records and used for encryption.
932 If this is answered yes, they will be prompted for a mailbox. */
933 enum QuadOption scan = mutt_yesorno(_("Scan a mailbox for autocrypt headers?"), MUTT_YES);
934 while (scan == MUTT_YES)
935 {
936 struct Mailbox *m_cur = get_current_mailbox();
937 // L10N: The prompt for a mailbox to scan for Autocrypt: headers
938 if ((!mutt_buffer_enter_fname(_("Scan mailbox"), folderbuf, true, m_cur,
939 false, NULL, NULL, MUTT_SEL_NO_FLAGS)) &&
940 (!mutt_buffer_is_empty(folderbuf)))
941 {
942 mutt_buffer_expand_path_regex(folderbuf, false);
943 struct Mailbox *m_ac = mx_path_resolve(mutt_buffer_string(folderbuf));
944 /* NOTE: I am purposely *not* executing folder hooks here,
945 * as they can do all sorts of things like push into the getch() buffer.
946 * Authentication should be in account-hooks. */
947 if (mx_mbox_open(m_ac, MUTT_READONLY))
948 {
949 mx_mbox_close(m_ac);
950 }
951 mutt_buffer_reset(folderbuf);
952 }
953
954 /* L10N: This is the second prompt to see if the user would like
955 to scan more than one mailbox for Autocrypt headers.
956 I'm purposely being extra verbose; asking first then prompting
957 for a mailbox. This is because this is a one-time operation
958 and I don't want them to accidentally ctrl-g and abort it. */
959 scan = mutt_yesorno(_("Scan another mailbox for autocrypt headers?"), MUTT_YES);
960 }
961
962#ifdef USE_HCACHE
963 cs_subset_str_native_set(NeoMutt->sub, "header_cache", (intptr_t) old_hdrcache, NULL);
964 old_hdrcache = NULL;
965#endif
966 mutt_buffer_pool_release(&folderbuf);
967}
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: lib.h:55
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:250
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:81
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_buffer_enter_fname(const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:446
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:624
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:135
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1677
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:615
#define MUTT_READONLY
Open in read-only mode.
Definition: mxapi.h:64
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
A mailbox.
Definition: mailbox.h:79
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_db_account_delete()

int mutt_autocrypt_db_account_delete ( struct AutocryptAccount acct)

Delete an Account from the Autocrypt database.

Parameters
acctAccount to delete
Return values
0Success
-1Error

Definition at line 419 of file db.c.

420{
421 int rc = -1;
422
424 {
425 if (sqlite3_prepare_v3(AutocryptDB,
426 "DELETE from account "
427 "WHERE email_addr = ?;",
428 -1, SQLITE_PREPARE_PERSISTENT, &AccountDeleteStmt, NULL) != SQLITE_OK)
429 {
430 goto cleanup;
431 }
432 }
433
434 if (sqlite3_bind_text(AccountDeleteStmt, 1, acct->email_addr, -1, SQLITE_STATIC) != SQLITE_OK)
435 goto cleanup;
436
437 if (sqlite3_step(AccountDeleteStmt) != SQLITE_DONE)
438 goto cleanup;
439
440 rc = 0;
441
442cleanup:
443 sqlite3_reset(AccountDeleteStmt);
444 return rc;
445}
sqlite3 * AutocryptDB
Definition: db.c:52
static sqlite3_stmt * AccountDeleteStmt
Definition: db.c:45
char * email_addr
Email address.
Definition: lib.h:107
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_account_free()

void mutt_autocrypt_db_account_free ( struct AutocryptAccount **  ptr)

Free an AutocryptAccount.

Parameters
ptrAccount to free

Definition at line 244 of file db.c.

245{
246 if (!ptr || !*ptr)
247 return;
248
249 struct AutocryptAccount *ac = *ptr;
250 FREE(&ac->email_addr);
251 FREE(&ac->keyid);
252 FREE(&ac->keydata);
253 FREE(ptr);
254}
#define FREE(x)
Definition: memory.h:43
char * keydata
PGP Key data.
Definition: lib.h:109
char * keyid
PGP Key id.
Definition: lib.h:108
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_account_get()

int mutt_autocrypt_db_account_get ( struct Address addr,
struct AutocryptAccount **  account 
)

Get Autocrypt Account data from the database.

Parameters
[in]addrEmail Address to lookup
[out]accountMatched account
Return values
0Success
-1Error

Definition at line 263 of file db.c.

264{
265 int rc = -1;
266
267 struct Address *norm_addr = copy_normalize_addr(addr);
268 *account = NULL;
269
270 if (!AccountGetStmt)
271 {
272 if (sqlite3_prepare_v3(AutocryptDB,
273 "SELECT "
274 "email_addr, "
275 "keyid, "
276 "keydata, "
277 "prefer_encrypt, "
278 "enabled "
279 "FROM account "
280 "WHERE email_addr = ?",
281 -1, SQLITE_PREPARE_PERSISTENT, &AccountGetStmt, NULL) != SQLITE_OK)
282 {
283 goto cleanup;
284 }
285 }
286
287 if (sqlite3_bind_text(AccountGetStmt, 1, norm_addr->mailbox, -1, SQLITE_STATIC) != SQLITE_OK)
288 goto cleanup;
289
290 int result = sqlite3_step(AccountGetStmt);
291 if (result != SQLITE_ROW)
292 {
293 if (result == SQLITE_DONE)
294 rc = 0;
295 goto cleanup;
296 }
297
299 (*account)->email_addr = strdup_column_text(AccountGetStmt, 0);
300 (*account)->keyid = strdup_column_text(AccountGetStmt, 1);
301 (*account)->keydata = strdup_column_text(AccountGetStmt, 2);
302 (*account)->prefer_encrypt = sqlite3_column_int(AccountGetStmt, 3);
303 (*account)->enabled = sqlite3_column_int(AccountGetStmt, 4);
304
305 rc = 1;
306
307cleanup:
308 mutt_addr_free(&norm_addr);
309 sqlite3_reset(AccountGetStmt);
310 return rc;
311}
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
struct AutocryptAccount * mutt_autocrypt_db_account_new(void)
Create a new AutocryptAccount.
Definition: db.c:235
static struct Address * copy_normalize_addr(struct Address *addr)
Copy a normalised Email Address.
Definition: db.c:202
static sqlite3_stmt * AccountGetStmt
Definition: db.c:42
static char * strdup_column_text(sqlite3_stmt *stmt, int index)
Copy a string from the database.
Definition: db.c:225
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_account_get_all()

int mutt_autocrypt_db_account_get_all ( struct AutocryptAccount ***  accounts,
int *  num_accounts 
)

Get all accounts from an Autocrypt database.

Parameters
[out]accountsList of accounts
[out]num_accountsNumber of accounts
Return values
0Success
-1Error

Definition at line 454 of file db.c.

455{
456 int rc = -1, result;
457 sqlite3_stmt *stmt = NULL;
458 struct AutocryptAccount **results = NULL;
459 int results_len = 0, results_count = 0;
460
461 *accounts = NULL;
462 *num_accounts = 0;
463
464 /* Note, speed is not of the essence for the account management screen,
465 * so we don't bother with a persistent prepared statement */
466 if (sqlite3_prepare_v2(AutocryptDB,
467 "SELECT "
468 "email_addr, "
469 "keyid, "
470 "keydata, "
471 "prefer_encrypt, "
472 "enabled "
473 "FROM account "
474 "ORDER BY email_addr",
475 -1, &stmt, NULL) != SQLITE_OK)
476 {
477 goto cleanup;
478 }
479
480 while ((result = sqlite3_step(stmt)) == SQLITE_ROW)
481 {
482 if (results_count == results_len)
483 {
484 results_len += 5;
485 mutt_mem_realloc(&results, results_len * sizeof(struct AutocryptAccount *));
486 }
487
489 results[results_count++] = account;
490
491 account->email_addr = strdup_column_text(stmt, 0);
492 account->keyid = strdup_column_text(stmt, 1);
493 account->keydata = strdup_column_text(stmt, 2);
494 account->prefer_encrypt = sqlite3_column_int(stmt, 3);
495 account->enabled = sqlite3_column_int(stmt, 4);
496 }
497
498 if (result == SQLITE_DONE)
499 {
500 *accounts = results;
501 rc = *num_accounts = results_count;
502 }
503 else
504 {
505 while (results_count > 0)
506 mutt_autocrypt_db_account_free(&results[--results_count]);
507 FREE(&results);
508 }
509
510cleanup:
511 sqlite3_finalize(stmt);
512 return rc;
513}
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
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_db_account_insert()

int mutt_autocrypt_db_account_insert ( struct Address addr,
const char *  keyid,
const char *  keydata,
bool  prefer_encrypt 
)

Insert an Account into the Autocrypt database.

Parameters
addrEmail Address for the account
keyidAutocrypt KeyID
keydataAutocrypt key data
prefer_encryptWhether the account prefers encryption
Return values
0Success
-1Error

Definition at line 322 of file db.c.

324{
325 int rc = -1;
326
327 struct Address *norm_addr = copy_normalize_addr(addr);
328
330 {
331 if (sqlite3_prepare_v3(AutocryptDB,
332 "INSERT INTO account "
333 "(email_addr, "
334 "keyid, "
335 "keydata, "
336 "prefer_encrypt, "
337 "enabled) "
338 "VALUES (?, ?, ?, ?, ?);",
339 -1, SQLITE_PREPARE_PERSISTENT, &AccountInsertStmt, NULL) != SQLITE_OK)
340 {
341 goto cleanup;
342 }
343 }
344
345 if (sqlite3_bind_text(AccountInsertStmt, 1, norm_addr->mailbox, -1, SQLITE_STATIC) != SQLITE_OK)
346 goto cleanup;
347 if (sqlite3_bind_text(AccountInsertStmt, 2, keyid, -1, SQLITE_STATIC) != SQLITE_OK)
348 goto cleanup;
349 if (sqlite3_bind_text(AccountInsertStmt, 3, keydata, -1, SQLITE_STATIC) != SQLITE_OK)
350 goto cleanup;
351 if (sqlite3_bind_int(AccountInsertStmt, 4, prefer_encrypt) != SQLITE_OK)
352 goto cleanup;
353 if (sqlite3_bind_int(AccountInsertStmt, 5, 1) != SQLITE_OK)
354 goto cleanup;
355
356 if (sqlite3_step(AccountInsertStmt) != SQLITE_DONE)
357 goto cleanup;
358
359 rc = 0;
360
361cleanup:
362 mutt_addr_free(&norm_addr);
363 sqlite3_reset(AccountInsertStmt);
364 return rc;
365}
static sqlite3_stmt * AccountInsertStmt
Definition: db.c:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_account_new()

struct AutocryptAccount * mutt_autocrypt_db_account_new ( void  )

Create a new AutocryptAccount.

Return values
ptrNew AutocryptAccount

Definition at line 235 of file db.c.

236{
237 return mutt_mem_calloc(1, sizeof(struct AutocryptAccount));
238}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_account_update()

int mutt_autocrypt_db_account_update ( struct AutocryptAccount acct)

Update Account info in the Autocrypt database.

Parameters
acctAutocrypt Account data
Return values
0Success
-1Error

Definition at line 373 of file db.c.

374{
375 int rc = -1;
376
378 {
379 if (sqlite3_prepare_v3(AutocryptDB,
380 "UPDATE account SET "
381 "keyid = ?, "
382 "keydata = ?, "
383 "prefer_encrypt = ?, "
384 "enabled = ? "
385 "WHERE email_addr = ?;",
386 -1, SQLITE_PREPARE_PERSISTENT, &AccountUpdateStmt, NULL) != SQLITE_OK)
387 {
388 goto cleanup;
389 }
390 }
391
392 if (sqlite3_bind_text(AccountUpdateStmt, 1, acct->keyid, -1, SQLITE_STATIC) != SQLITE_OK)
393 goto cleanup;
394 if (sqlite3_bind_text(AccountUpdateStmt, 2, acct->keydata, -1, SQLITE_STATIC) != SQLITE_OK)
395 goto cleanup;
396 if (sqlite3_bind_int(AccountUpdateStmt, 3, acct->prefer_encrypt) != SQLITE_OK)
397 goto cleanup;
398 if (sqlite3_bind_int(AccountUpdateStmt, 4, acct->enabled) != SQLITE_OK)
399 goto cleanup;
400 if (sqlite3_bind_text(AccountUpdateStmt, 5, acct->email_addr, -1, SQLITE_STATIC) != SQLITE_OK)
401 goto cleanup;
402
403 if (sqlite3_step(AccountUpdateStmt) != SQLITE_DONE)
404 goto cleanup;
405
406 rc = 0;
407
408cleanup:
409 sqlite3_reset(AccountUpdateStmt);
410 return rc;
411}
static sqlite3_stmt * AccountUpdateStmt
Definition: db.c:44
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_close()

void mutt_autocrypt_db_close ( void  )

Close the Autocrypt SQLite database connection.

Definition at line 130 of file db.c.

131{
132 if (!AutocryptDB)
133 return;
134
135 sqlite3_finalize(AccountGetStmt);
136 AccountGetStmt = NULL;
137 sqlite3_finalize(AccountInsertStmt);
138 AccountInsertStmt = NULL;
139 sqlite3_finalize(AccountUpdateStmt);
140 AccountUpdateStmt = NULL;
141 sqlite3_finalize(AccountDeleteStmt);
142 AccountDeleteStmt = NULL;
143
144 sqlite3_finalize(PeerGetStmt);
145 PeerGetStmt = NULL;
146 sqlite3_finalize(PeerInsertStmt);
147 PeerInsertStmt = NULL;
148 sqlite3_finalize(PeerUpdateStmt);
149 PeerUpdateStmt = NULL;
150
151 sqlite3_finalize(PeerHistoryInsertStmt);
153
154 sqlite3_finalize(GossipHistoryInsertStmt);
156
157 sqlite3_close_v2(AutocryptDB);
158 AutocryptDB = NULL;
159}
static sqlite3_stmt * PeerUpdateStmt
Definition: db.c:48
static sqlite3_stmt * PeerGetStmt
Definition: db.c:46
static sqlite3_stmt * PeerHistoryInsertStmt
Definition: db.c:49
static sqlite3_stmt * GossipHistoryInsertStmt
Definition: db.c:50
static sqlite3_stmt * PeerInsertStmt
Definition: db.c:47
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_gossip_history_free()

void mutt_autocrypt_db_gossip_history_free ( struct AutocryptGossipHistory **  ptr)

Free an AutocryptGossipHistory.

Parameters
ptrAutocryptGossipHistory to free

Definition at line 821 of file db.c.

822{
823 if (!ptr || !*ptr)
824 return;
825
826 struct AutocryptGossipHistory *gh = *ptr;
827 FREE(&gh->peer_email_addr);
829 FREE(&gh->email_msgid);
830 FREE(&gh->gossip_keydata);
831 FREE(ptr);
832}
Autocrypt gossip history.
Definition: lib.h:145
char * peer_email_addr
Email addressof the peer.
Definition: lib.h:146
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
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_gossip_history_insert()

int mutt_autocrypt_db_gossip_history_insert ( struct Address addr,
struct AutocryptGossipHistory gossip_hist 
)

Insert a gossip history into the Autocrypt database.

Parameters
addrEmail Address
gossip_histGossip history to insert
Return values
0Success
-1Error

Definition at line 841 of file db.c.

843{
844 int rc = -1;
845
846 struct Address *norm_addr = copy_normalize_addr(addr);
847
849 {
850 if (sqlite3_prepare_v3(AutocryptDB,
851 "INSERT INTO gossip_history "
852 "(peer_email_addr, "
853 "sender_email_addr, "
854 "email_msgid, "
855 "timestamp, "
856 "gossip_keydata) "
857 "VALUES (?, ?, ?, ?, ?);",
858 -1, SQLITE_PREPARE_PERSISTENT,
859 &GossipHistoryInsertStmt, NULL) != SQLITE_OK)
860 {
861 goto cleanup;
862 }
863 }
864
865 if (sqlite3_bind_text(GossipHistoryInsertStmt, 1, norm_addr->mailbox, -1,
866 SQLITE_STATIC) != SQLITE_OK)
867 {
868 goto cleanup;
869 }
870 if (sqlite3_bind_text(GossipHistoryInsertStmt, 2, gossip_hist->sender_email_addr,
871 -1, SQLITE_STATIC) != SQLITE_OK)
872 {
873 if (sqlite3_bind_text(GossipHistoryInsertStmt, 3, gossip_hist->email_msgid,
874 -1, SQLITE_STATIC) != SQLITE_OK)
875 {
876 goto cleanup;
877 }
878 }
879 if (sqlite3_bind_int64(GossipHistoryInsertStmt, 4, gossip_hist->timestamp) != SQLITE_OK)
880 goto cleanup;
881 if (sqlite3_bind_text(GossipHistoryInsertStmt, 5, gossip_hist->gossip_keydata,
882 -1, SQLITE_STATIC) != SQLITE_OK)
883 {
884 goto cleanup;
885 }
886
887 if (sqlite3_step(GossipHistoryInsertStmt) != SQLITE_DONE)
888 goto cleanup;
889
890 rc = 0;
891
892cleanup:
893 mutt_addr_free(&norm_addr);
894 sqlite3_reset(GossipHistoryInsertStmt);
895 return rc;
896}
sqlite3_int64 timestamp
Timestamp of sender's email.
Definition: lib.h:149
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_gossip_history_new()

struct AutocryptGossipHistory * mutt_autocrypt_db_gossip_history_new ( void  )

Create a new AutocryptGossipHistory.

Return values
ptrNew AutocryptGossipHistory

Definition at line 812 of file db.c.

813{
814 return mutt_mem_calloc(1, sizeof(struct AutocryptGossipHistory));
815}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_init()

int mutt_autocrypt_db_init ( bool  can_create)

Initialise the Autocrypt SQLite database.

Parameters
can_createIf true, the directory may be created
Return values
0Success
-1Error

Definition at line 79 of file db.c.

80{
81 int rc = -1;
82
83 if (AutocryptDB)
84 return 0;
85
86 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
87 const char *const c_autocrypt_dir = cs_subset_path(NeoMutt->sub, "autocrypt_dir");
88 if (!c_autocrypt || !c_autocrypt_dir)
89 return -1;
90
91 struct Buffer *db_path = mutt_buffer_pool_get();
92 mutt_buffer_concat_path(db_path, c_autocrypt_dir, "autocrypt.db");
93
94 struct stat st = { 0 };
95 if (stat(mutt_buffer_string(db_path), &st) == 0)
96 {
97 if (sqlite3_open_v2(mutt_buffer_string(db_path), &AutocryptDB,
98 SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK)
99 {
100 /* L10N: Error message if autocrypt couldn't open the SQLite database
101 for some reason. The %s is the full path of the database file. */
102 mutt_error(_("Unable to open autocrypt database %s"), mutt_buffer_string(db_path));
103 goto cleanup;
104 }
105
107 goto cleanup;
108 }
109 else
110 {
111 if (!can_create)
112 goto cleanup;
114 goto cleanup;
115 /* Don't abort the whole init process because account creation failed */
118 }
119
120 rc = 0;
121
122cleanup:
123 mutt_buffer_pool_release(&db_path);
124 return rc;
125}
static int autocrypt_db_create(const char *db_path)
Create an Autocrypt SQLite database.
Definition: db.c:60
int mutt_autocrypt_schema_update(void)
Update the version number of the Autocrypt database schema.
Definition: schema.c:106
int mutt_autocrypt_account_init(bool prompt)
Create a new Autocrypt account.
Definition: autocrypt.c:153
void mutt_autocrypt_scan_mailboxes(void)
Scan mailboxes for Autocrypt headers.
Definition: autocrypt.c:919
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:372
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_normalize_addr()

void mutt_autocrypt_db_normalize_addr ( struct Address a)

Normalise an Email Address.

Parameters
aAddress to normalise

Definition at line 165 of file db.c.

166{
170}
bool mutt_addr_to_local(struct Address *a)
Convert an Address from Punycode.
Definition: address.c:1351
bool mutt_addr_to_intl(struct Address *a)
Convert an Address to Punycode.
Definition: address.c:1276
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
Definition: string.c:384
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_normalize_addrlist()

void mutt_autocrypt_db_normalize_addrlist ( struct AddressList *  al)

Normalise a list of Email Addresses.

Parameters
alList of Addresses to normalise

Definition at line 176 of file db.c.

177{
179
180 struct Address *np = NULL;
181 TAILQ_FOREACH(np, al, entries)
182 {
184 }
185
186 mutt_addrlist_to_intl(al, NULL);
187}
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1388
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_free()

void mutt_autocrypt_db_peer_free ( struct AutocryptPeer **  ptr)

Free an AutocryptPeer.

Parameters
ptrAutocryptPeer to free

Definition at line 528 of file db.c.

529{
530 if (!ptr || !*ptr)
531 return;
532
533 struct AutocryptPeer *peer = *ptr;
534 FREE(&peer->email_addr);
535 FREE(&peer->keyid);
536 FREE(&peer->keydata);
537 FREE(&peer->gossip_keyid);
538 FREE(&peer->gossip_keydata);
539 FREE(ptr);
540}
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
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_get()

int mutt_autocrypt_db_peer_get ( struct Address addr,
struct AutocryptPeer **  peer 
)

Get peer info from the Autocrypt database.

Parameters
[in]addrEmail Address to look up
[out]peerMatching Autocrypt Peer
Return values
0Success, no matches
1Success, a match
-1Error

Definition at line 550 of file db.c.

551{
552 int rc = -1;
553
554 struct Address *norm_addr = copy_normalize_addr(addr);
555 *peer = NULL;
556
557 if (!PeerGetStmt)
558 {
559 if (sqlite3_prepare_v3(AutocryptDB,
560 "SELECT "
561 "email_addr, "
562 "last_seen, "
563 "autocrypt_timestamp, "
564 "keyid, "
565 "keydata, "
566 "prefer_encrypt, "
567 "gossip_timestamp, "
568 "gossip_keyid, "
569 "gossip_keydata "
570 "FROM peer "
571 "WHERE email_addr = ?",
572 -1, SQLITE_PREPARE_PERSISTENT, &PeerGetStmt, NULL) != SQLITE_OK)
573 {
574 goto cleanup;
575 }
576 }
577
578 if (sqlite3_bind_text(PeerGetStmt, 1, norm_addr->mailbox, -1, SQLITE_STATIC) != SQLITE_OK)
579 goto cleanup;
580
581 int result = sqlite3_step(PeerGetStmt);
582 if (result != SQLITE_ROW)
583 {
584 if (result == SQLITE_DONE)
585 rc = 0;
586 goto cleanup;
587 }
588
590 (*peer)->email_addr = strdup_column_text(PeerGetStmt, 0);
591 (*peer)->last_seen = sqlite3_column_int64(PeerGetStmt, 1);
592 (*peer)->autocrypt_timestamp = sqlite3_column_int64(PeerGetStmt, 2);
593 (*peer)->keyid = strdup_column_text(PeerGetStmt, 3);
594 (*peer)->keydata = strdup_column_text(PeerGetStmt, 4);
595 (*peer)->prefer_encrypt = sqlite3_column_int(PeerGetStmt, 5);
596 (*peer)->gossip_timestamp = sqlite3_column_int64(PeerGetStmt, 6);
597 (*peer)->gossip_keyid = strdup_column_text(PeerGetStmt, 7);
598 (*peer)->gossip_keydata = strdup_column_text(PeerGetStmt, 8);
599
600 rc = 1;
601
602cleanup:
603 mutt_addr_free(&norm_addr);
604 sqlite3_reset(PeerGetStmt);
605 return rc;
606}
struct AutocryptPeer * mutt_autocrypt_db_peer_new(void)
Create a new AutocryptPeer.
Definition: db.c:519
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_history_free()

void mutt_autocrypt_db_peer_history_free ( struct AutocryptPeerHistory **  ptr)

Free an AutocryptPeerHistory.

Parameters
ptrAutocryptPeerHistory to free

Definition at line 743 of file db.c.

744{
745 if (!ptr || !*ptr)
746 return;
747
748 struct AutocryptPeerHistory *ph = *ptr;
749 FREE(&ph->peer_email_addr);
750 FREE(&ph->email_msgid);
751 FREE(&ph->keydata);
752 FREE(ptr);
753}
Autocrypt peer history.
Definition: lib.h:134
char * peer_email_addr
Email address of the peer.
Definition: lib.h:135
char * email_msgid
Message id of the email.
Definition: lib.h:136
char * keydata
PGP Key data.
Definition: lib.h:138
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_history_insert()

int mutt_autocrypt_db_peer_history_insert ( struct Address addr,
struct AutocryptPeerHistory peerhist 
)

Insert peer history into the Autocrypt database.

Parameters
addrEmail Address
peerhistPeer history to insert
Return values
0Success
-1Error

Definition at line 762 of file db.c.

764{
765 int rc = -1;
766
767 struct Address *norm_addr = copy_normalize_addr(addr);
768
770 {
771 if (sqlite3_prepare_v3(AutocryptDB,
772 "INSERT INTO peer_history "
773 "(peer_email_addr, "
774 "email_msgid, "
775 "timestamp, "
776 "keydata) "
777 "VALUES (?, ?, ?, ?);",
778 -1, SQLITE_PREPARE_PERSISTENT,
779 &PeerHistoryInsertStmt, NULL) != SQLITE_OK)
780 {
781 goto cleanup;
782 }
783 }
784
785 if (sqlite3_bind_text(PeerHistoryInsertStmt, 1, norm_addr->mailbox, -1, SQLITE_STATIC) != SQLITE_OK)
786 goto cleanup;
787 if (sqlite3_bind_text(PeerHistoryInsertStmt, 2, peerhist->email_msgid, -1,
788 SQLITE_STATIC) != SQLITE_OK)
789 {
790 goto cleanup;
791 }
792 if (sqlite3_bind_int64(PeerHistoryInsertStmt, 3, peerhist->timestamp) != SQLITE_OK)
793 goto cleanup;
794 if (sqlite3_bind_text(PeerHistoryInsertStmt, 4, peerhist->keydata, -1, SQLITE_STATIC) != SQLITE_OK)
795 goto cleanup;
796
797 if (sqlite3_step(PeerHistoryInsertStmt) != SQLITE_DONE)
798 goto cleanup;
799
800 rc = 0;
801
802cleanup:
803 mutt_addr_free(&norm_addr);
804 sqlite3_reset(PeerHistoryInsertStmt);
805 return rc;
806}
sqlite3_int64 timestamp
Timestamp of email.
Definition: lib.h:137
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_history_new()

struct AutocryptPeerHistory * mutt_autocrypt_db_peer_history_new ( void  )

Create a new AutocryptPeerHistory.

Return values
ptrNew AutocryptPeerHistory

Definition at line 734 of file db.c.

735{
736 return mutt_mem_calloc(1, sizeof(struct AutocryptPeerHistory));
737}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_insert()

int mutt_autocrypt_db_peer_insert ( struct Address addr,
struct AutocryptPeer peer 
)

Insert a peer into the Autocrypt database.

Parameters
addrEmail Address
peerAutocryptPeer to insert
Return values
0Success
-1Error

Definition at line 615 of file db.c.

616{
617 int rc = -1;
618 struct Address *norm_addr = NULL;
619
620 norm_addr = copy_normalize_addr(addr);
621
622 if (!PeerInsertStmt)
623 {
624 if (sqlite3_prepare_v3(AutocryptDB,
625 "INSERT INTO peer "
626 "(email_addr, "
627 "last_seen, "
628 "autocrypt_timestamp, "
629 "keyid, "
630 "keydata, "
631 "prefer_encrypt, "
632 "gossip_timestamp, "
633 "gossip_keyid, "
634 "gossip_keydata) "
635 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);",
636 -1, SQLITE_PREPARE_PERSISTENT, &PeerInsertStmt, NULL) != SQLITE_OK)
637 {
638 goto cleanup;
639 }
640 }
641
642 if (sqlite3_bind_text(PeerInsertStmt, 1, norm_addr->mailbox, -1, SQLITE_STATIC) != SQLITE_OK)
643 goto cleanup;
644 if (sqlite3_bind_int64(PeerInsertStmt, 2, peer->last_seen) != SQLITE_OK)
645 goto cleanup;
646 if (sqlite3_bind_int64(PeerInsertStmt, 3, peer->autocrypt_timestamp) != SQLITE_OK)
647 goto cleanup;
648 if (sqlite3_bind_text(PeerInsertStmt, 4, peer->keyid, -1, SQLITE_STATIC) != SQLITE_OK)
649 goto cleanup;
650 if (sqlite3_bind_text(PeerInsertStmt, 5, peer->keydata, -1, SQLITE_STATIC) != SQLITE_OK)
651 goto cleanup;
652 if (sqlite3_bind_int(PeerInsertStmt, 6, peer->prefer_encrypt) != SQLITE_OK)
653 goto cleanup;
654 if (sqlite3_bind_int64(PeerInsertStmt, 7, peer->gossip_timestamp) != SQLITE_OK)
655 goto cleanup;
656 if (sqlite3_bind_text(PeerInsertStmt, 8, peer->gossip_keyid, -1, SQLITE_STATIC) != SQLITE_OK)
657 goto cleanup;
658 if (sqlite3_bind_text(PeerInsertStmt, 9, peer->gossip_keydata, -1, SQLITE_STATIC) != SQLITE_OK)
659 goto cleanup;
660
661 if (sqlite3_step(PeerInsertStmt) != SQLITE_DONE)
662 goto cleanup;
663
664 rc = 0;
665
666cleanup:
667 mutt_addr_free(&norm_addr);
668 sqlite3_reset(PeerInsertStmt);
669 return rc;
670}
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
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_db_peer_new()

struct AutocryptPeer * mutt_autocrypt_db_peer_new ( void  )

Create a new AutocryptPeer.

Return values
ptrNew AutocryptPeer

Definition at line 519 of file db.c.

520{
521 return mutt_mem_calloc(1, sizeof(struct AutocryptPeer));
522}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_db_peer_update()

int mutt_autocrypt_db_peer_update ( struct AutocryptPeer peer)

Update the peer info in an Autocrypt database.

Parameters
peerAutocryptPeer to update
Return values
0Success
-1Error

Definition at line 678 of file db.c.

679{
680 int rc = -1;
681
682 if (!PeerUpdateStmt)
683 {
684 if (sqlite3_prepare_v3(AutocryptDB,
685 "UPDATE peer SET "
686 "last_seen = ?, "
687 "autocrypt_timestamp = ?, "
688 "keyid = ?, "
689 "keydata = ?, "
690 "prefer_encrypt = ?, "
691 "gossip_timestamp = ?, "
692 "gossip_keyid = ?, "
693 "gossip_keydata = ? "
694 "WHERE email_addr = ?;",
695 -1, SQLITE_PREPARE_PERSISTENT, &PeerUpdateStmt, NULL) != SQLITE_OK)
696 {
697 goto cleanup;
698 }
699 }
700
701 if (sqlite3_bind_int64(PeerUpdateStmt, 1, peer->last_seen) != SQLITE_OK)
702 goto cleanup;
703 if (sqlite3_bind_int64(PeerUpdateStmt, 2, peer->autocrypt_timestamp) != SQLITE_OK)
704 goto cleanup;
705 if (sqlite3_bind_text(PeerUpdateStmt, 3, peer->keyid, -1, SQLITE_STATIC) != SQLITE_OK)
706 goto cleanup;
707 if (sqlite3_bind_text(PeerUpdateStmt, 4, peer->keydata, -1, SQLITE_STATIC) != SQLITE_OK)
708 goto cleanup;
709 if (sqlite3_bind_int(PeerUpdateStmt, 5, peer->prefer_encrypt) != SQLITE_OK)
710 goto cleanup;
711 if (sqlite3_bind_int64(PeerUpdateStmt, 6, peer->gossip_timestamp) != SQLITE_OK)
712 goto cleanup;
713 if (sqlite3_bind_text(PeerUpdateStmt, 7, peer->gossip_keyid, -1, SQLITE_STATIC) != SQLITE_OK)
714 goto cleanup;
715 if (sqlite3_bind_text(PeerUpdateStmt, 8, peer->gossip_keydata, -1, SQLITE_STATIC) != SQLITE_OK)
716 goto cleanup;
717 if (sqlite3_bind_text(PeerUpdateStmt, 9, peer->email_addr, -1, SQLITE_STATIC) != SQLITE_OK)
718 goto cleanup;
719
720 if (sqlite3_step(PeerUpdateStmt) != SQLITE_DONE)
721 goto cleanup;
722
723 rc = 0;
724
725cleanup:
726 sqlite3_reset(PeerUpdateStmt);
727 return rc;
728}
+ Here is the caller graph for this function:

◆ mutt_autocrypt_schema_init()

int mutt_autocrypt_schema_init ( void  )

Set up an Autocrypt database.

Return values
0Success
-1Error

Definition at line 40 of file schema.c.

41{
42 char *errmsg = NULL;
43
44 const char *schema = "BEGIN TRANSACTION; "
45
46 "CREATE TABLE account ("
47 "email_addr text primary key not null, "
48 "keyid text, "
49 "keydata text, "
50 "prefer_encrypt int, "
51 "enabled int);"
52
53 "CREATE TABLE peer ("
54 "email_addr text primary key not null, "
55 "last_seen int, "
56 "autocrypt_timestamp int, "
57 "keyid text, "
58 "keydata text, "
59 "prefer_encrypt int, "
60 "gossip_timestamp int, "
61 "gossip_keyid text, "
62 "gossip_keydata text);"
63
64 "CREATE TABLE peer_history ("
65 "peer_email_addr text not null, "
66 "email_msgid text, "
67 "timestamp int, "
68 "keydata text);"
69
70 "CREATE INDEX peer_history_email "
71 "ON peer_history ("
72 "peer_email_addr);"
73
74 "CREATE TABLE gossip_history ("
75 "peer_email_addr text not null, "
76 "sender_email_addr text, "
77 "email_msgid text, "
78 "timestamp int, "
79 "gossip_keydata text);"
80
81 "CREATE INDEX gossip_history_email "
82 "ON gossip_history ("
83 "peer_email_addr);"
84
85 "CREATE TABLE schema ("
86 "version int);"
87
88 "INSERT into schema (version) values (1);"
89
90 "COMMIT TRANSACTION";
91
92 if (sqlite3_exec(AutocryptDB, schema, NULL, NULL, &errmsg) != SQLITE_OK)
93 {
94 mutt_debug(LL_DEBUG1, "mutt_autocrypt_schema_init() returned %s\n", errmsg);
95 sqlite3_free(errmsg);
96 return -1;
97 }
98 return 0;
99}
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
+ Here is the caller graph for this function:

◆ mutt_autocrypt_schema_update()

int mutt_autocrypt_schema_update ( void  )

Update the version number of the Autocrypt database schema.

Return values
0Success
-1Error

Definition at line 106 of file schema.c.

107{
108 sqlite3_stmt *stmt = NULL;
109 int rc = -1;
110
111 if (sqlite3_prepare_v2(AutocryptDB, "SELECT version FROM schema;", -1, &stmt, NULL) != SQLITE_OK)
112 goto cleanup;
113
114 if (sqlite3_step(stmt) != SQLITE_ROW)
115 goto cleanup;
116
117 int version = sqlite3_column_int(stmt, 0);
118
119 if (version > 1)
120 {
121 /* L10N: The autocrypt database keeps track of schema version numbers.
122 This error occurs if the version number is too high.
123 Presumably because this is an old version of NeoMutt and the
124 database was upgraded by a future version. */
125 mutt_error(_("Autocrypt database version is too new"));
126 goto cleanup;
127 }
128
129 /* TODO: schema version upgrades go here.
130 * Bump one by one, each update inside a transaction. */
131
132 rc = 0;
133
134cleanup:
135 sqlite3_finalize(stmt);
136 return rc;
137}
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_create_key()

int mutt_autocrypt_gpgme_create_key ( struct Address addr,
struct Buffer keyid,
struct Buffer keydata 
)

Create a GPGME key.

Parameters
addrEmail Address
keyidKey id
keydataKey data
Return values
0Success
-1Error

Definition at line 155 of file gpgme.c.

157{
158 int rc = -1;
159 gpgme_ctx_t ctx = NULL;
160 gpgme_genkey_result_t keyresult = NULL;
161 gpgme_key_t primary_key = NULL;
162 char buf[1024] = { 0 };
163
164 /* GPGME says addresses should not be in idna form */
165 struct Address *copy = mutt_addr_copy(addr);
166 mutt_addr_to_local(copy);
167 mutt_addr_write(buf, sizeof(buf), copy, false);
168 mutt_addr_free(&copy);
169
170 if (create_gpgme_context(&ctx))
171 goto cleanup;
172
173 /* L10N: Message displayed just before a GPG key is generated for a created
174 autocrypt account. */
175 mutt_message(_("Generating autocrypt key..."));
176
177 /* Primary key */
178 gpgme_error_t err = gpgme_op_createkey(ctx, buf, "ed25519", 0, 0, NULL,
179 GPGME_CREATE_NOPASSWD | GPGME_CREATE_FORCE |
180 GPGME_CREATE_NOEXPIRE);
181 if (err)
182 {
183 /* L10N: GPGME was unable to generate a key for some reason.
184 %s is the error message returned by GPGME. */
185 mutt_error(_("Error creating autocrypt key: %s"), gpgme_strerror(err));
186 goto cleanup;
187 }
188 keyresult = gpgme_op_genkey_result(ctx);
189 if (!keyresult->fpr)
190 goto cleanup;
191 mutt_buffer_strcpy(keyid, keyresult->fpr);
192 mutt_debug(LL_DEBUG1, "Generated key with id %s\n", mutt_buffer_string(keyid));
193
194 /* Get gpgme_key_t to create the secondary key and export keydata */
195 err = gpgme_get_key(ctx, mutt_buffer_string(keyid), &primary_key, 0);
196 if (err)
197 goto cleanup;
198
199 /* Secondary key */
200 err = gpgme_op_createsubkey(ctx, primary_key, "cv25519", 0, 0,
201 GPGME_CREATE_NOPASSWD | GPGME_CREATE_NOEXPIRE);
202 if (err)
203 {
204 mutt_error(_("Error creating autocrypt key: %s"), gpgme_strerror(err));
205 goto cleanup;
206 }
207
208 /* get keydata */
209 if (export_keydata(ctx, primary_key, keydata))
210 goto cleanup;
211 mutt_debug(LL_DEBUG1, "key has keydata *%s*\n", mutt_buffer_string(keydata));
212
213 rc = 0;
214
215cleanup:
216 gpgme_key_unref(primary_key);
217 gpgme_release(ctx);
218 return rc;
219}
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1025
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
static int create_gpgme_context(gpgme_ctx_t *ctx)
Create a GPGME context.
Definition: gpgme.c:48
static int export_keydata(gpgme_ctx_t ctx, gpgme_key_t key, struct Buffer *keydata)
Export Key data from GPGME into a Buffer.
Definition: gpgme.c:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_import_key()

int mutt_autocrypt_gpgme_import_key ( const char *  keydata,
struct Buffer keyid 
)

Read a key from GPGME.

Parameters
keydataBuffer for key data
keyidBuffer for key id
Return values
0Success
-1Error

Definition at line 316 of file gpgme.c.

317{
318 int rc = -1;
319 gpgme_ctx_t ctx = NULL;
320 gpgme_data_t dh = NULL;
321
322 if (create_gpgme_context(&ctx))
323 goto cleanup;
324
325 struct Buffer *raw_keydata = mutt_buffer_pool_get();
326 if (!mutt_b64_buffer_decode(raw_keydata, keydata))
327 goto cleanup;
328
329 if (gpgme_data_new_from_mem(&dh, mutt_buffer_string(raw_keydata),
330 mutt_buffer_len(raw_keydata), 0))
331 {
332 goto cleanup;
333 }
334
335 if (gpgme_op_import(ctx, dh))
336 goto cleanup;
337
338 gpgme_import_result_t result = gpgme_op_import_result(ctx);
339 if (!result->imports || !result->imports->fpr)
340 goto cleanup;
341 mutt_buffer_strcpy(keyid, result->imports->fpr);
342
343 rc = 0;
344
345cleanup:
346 gpgme_data_release(dh);
347 gpgme_release(ctx);
348 mutt_buffer_pool_release(&raw_keydata);
349 return rc;
350}
int mutt_b64_buffer_decode(struct Buffer *buf, const char *in)
Convert null-terminated base64 string to raw bytes.
Definition: base64.c:217
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:354
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_init()

int mutt_autocrypt_gpgme_init ( void  )

Initialise GPGME.

Return values
0Always

Definition at line 67 of file gpgme.c.

68{
70 return 0;
71}
void pgp_gpgme_init(void)
Implements CryptModuleSpecs::init() -.
Definition: crypt_gpgme.c:4148
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_is_valid_key()

bool mutt_autocrypt_gpgme_is_valid_key ( const char *  keyid)

Is a key id valid?

Parameters
keyidKey id to check
Return values
trueKey id is valid

Definition at line 357 of file gpgme.c.

358{
359 bool rc = false;
360 gpgme_ctx_t ctx = NULL;
361 gpgme_key_t key = NULL;
362
363 if (!keyid)
364 return false;
365
366 if (create_gpgme_context(&ctx))
367 goto cleanup;
368
369 if (gpgme_get_key(ctx, keyid, &key, 0))
370 goto cleanup;
371
372 rc = true;
373 if (key->revoked || key->expired || key->disabled || key->invalid || !key->can_encrypt)
374 rc = false;
375
376cleanup:
377 gpgme_key_unref(key);
378 gpgme_release(ctx);
379 return rc;
380}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_select_key()

int mutt_autocrypt_gpgme_select_key ( struct Buffer keyid,
struct Buffer keydata 
)

Select a Autocrypt key.

Parameters
[in]keyidKey id to select
[out]keydataBuffer for resulting Key data
Return values
0Success
-1Error

Definition at line 228 of file gpgme.c.

229{
230 int rc = -1;
231 gpgme_ctx_t ctx = NULL;
232 gpgme_key_t key = NULL;
233
234 OptAutocryptGpgme = true;
236 goto cleanup;
237
238 if (create_gpgme_context(&ctx))
239 goto cleanup;
240
241 if (gpgme_get_key(ctx, mutt_buffer_string(keyid), &key, 0))
242 goto cleanup;
243
244 if (key->revoked || key->expired || key->disabled || key->invalid ||
245 !key->can_encrypt || !key->can_sign)
246 {
247 /* L10N: After selecting a key for an autocrypt account,
248 this is displayed if the key was revoked/expired/disabled/invalid
249 or can't be used for both signing and encryption.
250 %s is the key fingerprint. */
251 mutt_error(_("The key %s is not usable for autocrypt"), mutt_buffer_string(keyid));
252 goto cleanup;
253 }
254
255 if (export_keydata(ctx, key, keydata))
256 goto cleanup;
257
258 rc = 0;
259
260cleanup:
261 OptAutocryptGpgme = false;
262 gpgme_key_unref(key);
263 gpgme_release(ctx);
264 return rc;
265}
int mutt_gpgme_select_secret_key(struct Buffer *keyid)
Select a private Autocrypt key for a new account.
Definition: crypt_gpgme.c:3967
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_autocrypt_gpgme_select_or_create_key()

int mutt_autocrypt_gpgme_select_or_create_key ( struct Address addr,
struct Buffer keyid,
struct Buffer keydata 
)

Ask the user to select or create an Autocrypt key.

Parameters
addrEmail Address
keyidKey id
keydataKey data
Return values
0Success
-1Error

Definition at line 275 of file gpgme.c.

277{
278 int rc = -1;
279
280 /* L10N: During autocrypt account creation, this prompt asks the
281 user whether they want to create a new GPG key for the account,
282 or select an existing account from the keyring. */
283 const char *prompt = _("(c)reate new, or (s)elect existing GPG key?");
284 /* L10N: The letters corresponding to the
285 "(c)reate new, or (s)elect existing GPG key?" prompt. */
286 const char *letters = _("cs");
287
288 int choice = mutt_multi_choice(prompt, letters);
289 switch (choice)
290 {
291 case 2: /* select existing */
292 rc = mutt_autocrypt_gpgme_select_key(keyid, keydata);
293 if (rc == 0)
294 break;
295
296 /* L10N: During autocrypt account creation, if selecting an existing key fails
297 for some reason, we prompt to see if they want to create a key instead. */
298 if (mutt_yesorno(_("Create a new GPG key for this account, instead?"), MUTT_YES) != MUTT_YES)
299 break;
300 /* fallthrough */
301
302 case 1: /* create new */
303 rc = mutt_autocrypt_gpgme_create_key(addr, keyid, keydata);
304 }
305
306 return rc;
307}
int mutt_autocrypt_gpgme_create_key(struct Address *addr, struct Buffer *keyid, struct Buffer *keydata)
Create a GPGME key.
Definition: gpgme.c:155
int mutt_autocrypt_gpgme_select_key(struct Buffer *keyid, struct Buffer *keydata)
Select a Autocrypt key.
Definition: gpgme.c:228
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: question.c:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ populate_menu()

bool populate_menu ( struct Menu menu)

Add the Autocrypt data to a Menu.

Parameters
menuMenu to populate
Return values
trueSuccess

Definition at line 214 of file dlg_autocrypt.c.

215{
216 // Clear out any existing data
217 autocrypt_menu_free(menu, &menu->mdata);
218 menu->max = 0;
219
220 struct AutocryptAccount **accounts = NULL;
221 int num_accounts = 0;
222
223 if (mutt_autocrypt_db_account_get_all(&accounts, &num_accounts) < 0)
224 return false;
225
226 struct AccountEntry *entries = mutt_mem_calloc(num_accounts, sizeof(struct AccountEntry));
227 menu->mdata = entries;
229 menu->max = num_accounts;
230
231 for (int i = 0; i < num_accounts; i++)
232 {
233 entries[i].num = i + 1;
234 /* note: we are transferring the account pointer to the entries
235 * array, and freeing the accounts array below. the account
236 * will be freed in autocrypt_menu_free(). */
237 entries[i].account = accounts[i];
238
239 entries[i].addr = mutt_addr_new();
240 entries[i].addr->mailbox = mutt_str_dup(accounts[i]->email_addr);
241 mutt_addr_to_local(entries[i].addr);
242 }
243 FREE(&accounts);
244
246 return true;
247}
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
int mutt_autocrypt_db_account_get_all(struct AutocryptAccount ***accounts, int *num_accounts)
Get all accounts from an Autocrypt database.
Definition: db.c:454
static void autocrypt_menu_free(struct Menu *menu, void **ptr)
Free the Autocrypt account Menu - Implements Menu::mdata_free() -.
#define MENU_REDRAW_FULL
Redraw everything.
Definition: lib.h:59
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition: menu.c:178
An entry in the Autocrypt account Menu.
Definition: private.h:44
struct Address * addr
Email address associated with the account.
Definition: private.h:47
struct AutocryptAccount * account
Account details.
Definition: private.h:46
int num
Number in the index.
Definition: private.h:45
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition: lib.h:152
void * mdata
Private data.
Definition: lib.h:137
int max
Number of entries in the menu.
Definition: lib.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AutocryptDB

sqlite3* AutocryptDB
extern

Definition at line 52 of file db.c.