NeoMutt  2023-05-17-56-ga67199
Teaching an old dog new tricks
DOXYGEN
cryptglue.c
Go to the documentation of this file.
1
38#include "config.h"
39#include <stdbool.h>
40#include <stdio.h>
41#include "mutt/lib.h"
42#include "core/lib.h"
43#include "cryptglue.h"
44#include "lib.h"
45#include "crypt_mod.h"
46#ifndef CRYPT_BACKEND_GPGME
47#include "gui/lib.h"
48#endif
49#if defined(CRYPT_BACKEND_GPGME) || defined(USE_AUTOCRYPT)
50#include "config/lib.h"
51#endif
52#ifdef USE_AUTOCRYPT
53#include "email/lib.h"
54#include "autocrypt/lib.h"
55#include "crypt_gpgme.h"
56#include "globals.h" // IWYU pragma: keep
57#else
58struct Envelope;
59#endif
60
61struct Address;
62struct AddressList;
63
64#ifdef CRYPT_BACKEND_CLASSIC_PGP
65extern const struct CryptModuleSpecs CryptModPgpClassic;
66#endif
67
68#ifdef CRYPT_BACKEND_CLASSIC_SMIME
69extern const struct CryptModuleSpecs CryptModSmimeClassic;
70#endif
71
72#ifdef CRYPT_BACKEND_GPGME
73extern const struct CryptModuleSpecs CryptModPgpGpgme;
74extern const struct CryptModuleSpecs CryptModSmimeGpgme;
75#endif
76
77/* If the crypto module identifier by IDENTIFIER has been registered,
78 * call its function FUNC. Do nothing else. This may be used as an
79 * expression. */
80#define CRYPT_MOD_CALL_CHECK(identifier, func) \
81 (crypto_module_lookup(APPLICATION_##identifier) && \
82 (crypto_module_lookup(APPLICATION_##identifier))->func)
83
84/* Call the function FUNC in the crypto module identified by
85 * IDENTIFIER. This may be used as an expression. */
86#define CRYPT_MOD_CALL(identifier, func) \
87 (*(crypto_module_lookup(APPLICATION_##identifier))->func)
88
94void crypt_init(void)
95{
96#ifdef CRYPT_BACKEND_GPGME
97 const bool c_crypt_use_gpgme = cs_subset_bool(NeoMutt->sub, "crypt_use_gpgme");
98#endif
99#ifdef CRYPT_BACKEND_CLASSIC_PGP
100 if (
101#ifdef CRYPT_BACKEND_GPGME
102 (!c_crypt_use_gpgme)
103#else
104 1
105#endif
106 )
108#endif
109
110#ifdef CRYPT_BACKEND_CLASSIC_SMIME
111 if (
112#ifdef CRYPT_BACKEND_GPGME
113 (!c_crypt_use_gpgme)
114#else
115 1
116#endif
117 )
119#endif
120
121#ifdef CRYPT_BACKEND_GPGME
122 if (c_crypt_use_gpgme)
123 {
126 }
127#endif
128
129#if defined(CRYPT_BACKEND_CLASSIC_PGP) || \
130 defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
131 if (CRYPT_MOD_CALL_CHECK(PGP, init))
132 CRYPT_MOD_CALL(PGP, init)();
133
134 if (CRYPT_MOD_CALL_CHECK(SMIME, init))
135 CRYPT_MOD_CALL(SMIME, init)();
136#endif
137}
138
143{
145 (CRYPT_MOD_CALL(PGP, cleanup))();
146
147 if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
148 (CRYPT_MOD_CALL(SMIME, cleanup))();
149}
150
158{
159 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
160 mutt_message(_("Invoking PGP..."));
161 else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
162 mutt_message(_("Invoking S/MIME..."));
163}
164
172{
173 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
175 {
176 return true;
177 }
178
179 if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
181 {
182 return true;
183 }
184
185 return false;
186}
187
192{
195}
196
201{
203 return CRYPT_MOD_CALL(PGP, valid_passphrase)();
204
205 return false;
206}
207
211int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
212{
213#ifdef USE_AUTOCRYPT
214 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
215 if (c_autocrypt)
216 {
217 OptAutocryptGpgme = true;
218 int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, cur);
219 OptAutocryptGpgme = false;
220 if (result == 0)
221 {
222 b->is_autocrypt = true;
223 return result;
224 }
225 }
226#endif
227
229 return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
230
231 return -1;
232}
233
237int crypt_pgp_application_handler(struct Body *b, struct State *state)
238{
240 return CRYPT_MOD_CALL(PGP, application_handler)(b, state);
241
242 return -1;
243}
244
248int crypt_pgp_encrypted_handler(struct Body *b, struct State *state)
249{
250#ifdef USE_AUTOCRYPT
251 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
252 if (c_autocrypt)
253 {
254 OptAutocryptGpgme = true;
255 int result = pgp_gpgme_encrypted_handler(b, state);
256 OptAutocryptGpgme = false;
257 if (result == 0)
258 {
259 b->is_autocrypt = true;
260 return result;
261 }
262 }
263#endif
264
266 return CRYPT_MOD_CALL(PGP, encrypted_handler)(b, state);
267
268 return -1;
269}
270
275{
278}
279
283bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
284{
286 return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
287
288 return false;
289}
290
294struct Body *crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
295{
296 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_traditional_encryptsign))
297 return CRYPT_MOD_CALL(PGP, pgp_traditional_encryptsign)(a, flags, keylist);
298
299 return NULL;
300}
301
306{
307 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
308 return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
309
310 return NULL;
311}
312
316char *crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
317{
319 return CRYPT_MOD_CALL(PGP, find_keys)(addrlist, oppenc_mode);
320
321 return NULL;
322}
323
327struct Body *crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
328{
330 return CRYPT_MOD_CALL(PGP, sign_message)(a, from);
331
332 return NULL;
333}
334
338struct Body *crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist,
339 int sign, const struct AddressList *from)
340{
341#ifdef USE_AUTOCRYPT
342 if (e->security & SEC_AUTOCRYPT)
343 {
345 return NULL;
346
347 OptAutocryptGpgme = true;
348 struct Body *result = pgp_gpgme_encrypt_message(a, keylist, sign, from);
349 OptAutocryptGpgme = false;
350
351 return result;
352 }
353#endif
354
355 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_encrypt_message))
356 return CRYPT_MOD_CALL(PGP, pgp_encrypt_message)(a, keylist, sign, from);
357
358 return NULL;
359}
360
364void crypt_pgp_invoke_import(const char *fname)
365{
366 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_import))
367 CRYPT_MOD_CALL(PGP, pgp_invoke_import)(fname);
368}
369
373int crypt_pgp_verify_one(struct Body *sigbdy, struct State *state, const char *tempf)
374{
376 return CRYPT_MOD_CALL(PGP, verify_one)(sigbdy, state, tempf);
377
378 return -1;
379}
380
385{
386 if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
387 return CRYPT_MOD_CALL(PGP, send_menu)(e);
388
389 return 0;
390}
391
396{
397 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
398 CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, top);
399}
400
404void crypt_pgp_set_sender(const char *sender)
405{
406 if (CRYPT_MOD_CALL_CHECK(PGP, set_sender))
407 CRYPT_MOD_CALL(PGP, set_sender)(sender);
408}
409
414{
415 if (CRYPT_MOD_CALL_CHECK(SMIME, void_passphrase))
416 CRYPT_MOD_CALL(SMIME, void_passphrase)();
417}
418
423{
424 if (CRYPT_MOD_CALL_CHECK(SMIME, valid_passphrase))
425 return CRYPT_MOD_CALL(SMIME, valid_passphrase)();
426
427 return false;
428}
429
433int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
434{
435 if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
436 return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, cur);
437
438 return -1;
439}
440
444int crypt_smime_application_handler(struct Body *b, struct State *state)
445{
446 if (CRYPT_MOD_CALL_CHECK(SMIME, application_handler))
447 return CRYPT_MOD_CALL(SMIME, application_handler)(b, state);
448
449 return -1;
450}
451
456{
457 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
458 CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
459}
460
464int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
465{
466 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
467 return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(e, msg);
468
469 return 1;
470}
471
475char *crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
476{
478 return CRYPT_MOD_CALL(SMIME, find_keys)(addrlist, oppenc_mode);
479
480 return NULL;
481}
482
486struct Body *crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
487{
489 return CRYPT_MOD_CALL(SMIME, sign_message)(a, from);
490
491 return NULL;
492}
493
497struct Body *crypt_smime_build_smime_entity(struct Body *a, char *certlist)
498{
499 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_build_smime_entity))
500 return CRYPT_MOD_CALL(SMIME, smime_build_smime_entity)(a, certlist);
501
502 return NULL;
503}
504
508void crypt_smime_invoke_import(const char *infile, const char *mailbox)
509{
510 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_invoke_import))
511 CRYPT_MOD_CALL(SMIME, smime_invoke_import)(infile, mailbox);
512}
513
517int crypt_smime_verify_one(struct Body *sigbdy, struct State *state, const char *tempf)
518{
520 return CRYPT_MOD_CALL(SMIME, verify_one)(sigbdy, state, tempf);
521
522 return -1;
523}
524
529{
530 if (CRYPT_MOD_CALL_CHECK(SMIME, send_menu))
531 return CRYPT_MOD_CALL(SMIME, send_menu)(e);
532
533 return 0;
534}
535
539void crypt_smime_set_sender(const char *sender)
540{
541 if (CRYPT_MOD_CALL_CHECK(SMIME, set_sender))
542 CRYPT_MOD_CALL(SMIME, set_sender)(sender);
543}
Autocrypt end-to-end encryption.
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:703
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
static char * find_keys(const struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:3419
static struct Body * sign_message(struct Body *a, const struct AddressList *from, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:899
static int verify_one(struct Body *sigbdy, struct State *state, const char *tempfile, bool is_smime)
Do the actual verification step.
Definition: crypt_gpgme.c:1540
Wrapper for PGP/SMIME calls to GPGME.
const struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition: crypt_mod.c:66
void crypto_module_register(const struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition: crypt_mod.c:52
Register crypto modules.
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:171
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:157
const struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs.
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:327
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:316
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:433
void crypt_cleanup(void)
Clean up backend.
Definition: cryptglue.c:142
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
const struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - Implements CryptModuleSpecs.
bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:283
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition: cryptglue.c:80
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:305
SecurityFlags crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:528
SecurityFlags crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:384
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:274
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
const struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs.
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:422
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:364
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:413
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *state, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:373
const struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs.
int crypt_smime_verify_one(struct Body *sigbdy, struct State *state, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:517
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:404
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:539
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:211
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:94
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:191
#define CRYPT_MOD_CALL(identifier, func)
Definition: cryptglue.c:86
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:200
struct Body * crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist, int sign, const struct AddressList *from)
Wrapper for CryptModuleSpecs::pgp_encrypt_message()
Definition: cryptglue.c:338
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:294
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:395
Wrapper around crypto functions.
Structs that make up an email.
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: globals.c:68
int pgp_gpgme_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Implements CryptModuleSpecs::decrypt_mime() -.
Definition: crypt_gpgme.c:1853
int pgp_gpgme_encrypted_handler(struct Body *a, struct State *state)
Implements CryptModuleSpecs::encrypted_handler() -.
Definition: crypt_gpgme.c:2661
struct Body * pgp_gpgme_encrypt_message(struct Body *a, char *keylist, bool sign, const struct AddressList *from)
Implements CryptModuleSpecs::pgp_encrypt_message() -.
Definition: crypt_gpgme.c:1036
int crypt_pgp_application_handler(struct Body *b, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:237
int crypt_pgp_encrypted_handler(struct Body *b, struct State *state)
Wrapper for CryptModuleSpecs::encrypted_handler() - Implements handler_t -.
Definition: cryptglue.c:248
int crypt_smime_application_handler(struct Body *b, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:444
#define mutt_message(...)
Definition: logging2.h:89
Convenience wrapper for the gui headers.
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:87
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:76
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define WithCrypto
Definition: lib.h:116
Key value store.
An email address.
Definition: address.h:36
The body of an email.
Definition: body.h:36
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:50
int(* decrypt_mime)(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Definition: crypt_mod.h:99
int(* encrypted_handler)(struct Body *m, struct State *state)
Definition: crypt_mod.h:123
void(* init)(void)
Definition: crypt_mod.h:56
bool(* valid_passphrase)(void)
Definition: crypt_mod.h:85
void(* cleanup)(void)
Definition: crypt_mod.h:64
bool(* pgp_check_traditional)(FILE *fp, struct Body *b, bool just_one)
Definition: crypt_mod.h:221
void(* void_passphrase)(void)
Definition: crypt_mod.h:72
void(* pgp_invoke_getkeys)(struct Address *addr)
Definition: crypt_mod.h:243
int(* application_handler)(struct Body *m, struct State *state)
Definition: crypt_mod.h:111
The envelope/body of an email.
Definition: email.h:37
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
The header of an Email.
Definition: envelope.h:57
A local copy of an email.
Definition: mxapi.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Keep track when processing files.
Definition: state.h:47