NeoMutt  2020-06-26-89-g172cd3
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 "private.h"
42 #include "mutt/lib.h"
43 #include "cryptglue.h"
44 #include "crypt_mod.h"
45 #include "ncrypt/lib.h"
46 #ifndef CRYPT_BACKEND_GPGME
47 #include "gui/lib.h"
48 #endif
49 #ifdef USE_AUTOCRYPT
50 #include "email/lib.h"
51 #include "crypt_gpgme.h"
52 #include "options.h"
53 #include "autocrypt/lib.h"
54 #else
55 struct Envelope;
56 #endif
57 
58 struct Address;
59 struct AddressList;
60 struct Mailbox;
61 struct State;
62 
63 #ifdef CRYPT_BACKEND_CLASSIC_PGP
65 #endif
66 
67 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
69 #endif
70 
71 #ifdef CRYPT_BACKEND_GPGME
74 #endif
75 
76 /* If the crypto module identifier by IDENTIFIER has been registered,
77  * call its function FUNC. Do nothing else. This may be used as an
78  * expression. */
79 #define CRYPT_MOD_CALL_CHECK(identifier, func) \
80  (crypto_module_lookup(APPLICATION_##identifier) && \
81  (crypto_module_lookup(APPLICATION_##identifier))->func)
82 
83 /* Call the function FUNC in the crypto module identified by
84  * IDENTIFIER. This may be used as an expression. */
85 #define CRYPT_MOD_CALL(identifier, func) \
86  (*(crypto_module_lookup(APPLICATION_##identifier))->func)
87 
93 void crypt_init(void)
94 {
95 #ifdef CRYPT_BACKEND_CLASSIC_PGP
96  if (
97 #ifdef CRYPT_BACKEND_GPGME
99 #else
100  1
101 #endif
102  )
104 #endif
105 
106 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
107  if (
108 #ifdef CRYPT_BACKEND_GPGME
109  (!C_CryptUseGpgme)
110 #else
111  1
112 #endif
113  )
115 #endif
116 
117 #ifdef CRYPT_BACKEND_GPGME
118  if (C_CryptUseGpgme)
119  {
122  }
123 #endif
124 
125 #if defined(CRYPT_BACKEND_CLASSIC_PGP) || \
126  defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
127  if (CRYPT_MOD_CALL_CHECK(PGP, init))
128  CRYPT_MOD_CALL(PGP, init)();
129 
130  if (CRYPT_MOD_CALL_CHECK(SMIME, init))
131  CRYPT_MOD_CALL(SMIME, init)();
132 #endif
133 }
134 
138 void crypt_cleanup(void)
139 {
140  if (CRYPT_MOD_CALL_CHECK(PGP, cleanup))
141  (CRYPT_MOD_CALL(PGP, cleanup))();
142 
143  if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
144  (CRYPT_MOD_CALL(SMIME, cleanup))();
145 }
146 
154 {
155  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
156  mutt_message(_("Invoking PGP..."));
157  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
158  mutt_message(_("Invoking S/MIME..."));
159 }
160 
168 {
169  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
170  crypto_module_lookup(APPLICATION_PGP))
171  {
172  return true;
173  }
174 
175  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
176  crypto_module_lookup(APPLICATION_SMIME))
177  {
178  return true;
179  }
180 
181  return false;
182 }
183 
188 {
191 }
192 
197 {
199  return CRYPT_MOD_CALL(PGP, valid_passphrase)();
200 
201  return false;
202 }
203 
207 int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
208 {
209 #ifdef USE_AUTOCRYPT
210  if (C_Autocrypt)
211  {
212  OptAutocryptGpgme = true;
213  int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, cur);
214  OptAutocryptGpgme = false;
215  if (result == 0)
216  {
217  b->is_autocrypt = true;
218  return result;
219  }
220  }
221 #endif
222 
224  return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
225 
226  return -1;
227 }
228 
234 int crypt_pgp_application_handler(struct Body *m, struct State *s)
235 {
237  return CRYPT_MOD_CALL(PGP, application_handler)(m, s);
238 
239  return -1;
240 }
241 
247 int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
248 {
249 #ifdef USE_AUTOCRYPT
250  if (C_Autocrypt)
251  {
252  OptAutocryptGpgme = true;
253  int result = pgp_gpgme_encrypted_handler(a, s);
254  OptAutocryptGpgme = false;
255  if (result == 0)
256  {
257  a->is_autocrypt = true;
258  return result;
259  }
260  }
261 #endif
262 
264  return CRYPT_MOD_CALL(PGP, encrypted_handler)(a, s);
265 
266  return -1;
267 }
268 
273 {
276 }
277 
281 int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
282 {
284  return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
285 
286  return 0;
287 }
288 
292 struct Body *crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
293 {
294  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_traditional_encryptsign))
295  return CRYPT_MOD_CALL(PGP, pgp_traditional_encryptsign)(a, flags, keylist);
296 
297  return NULL;
298 }
299 
304 {
305  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
306  return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
307 
308  return NULL;
309 }
310 
314 char *crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
315 {
317  return CRYPT_MOD_CALL(PGP, find_keys)(addrlist, oppenc_mode);
318 
319  return NULL;
320 }
321 
325 struct Body *crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
326 {
328  return CRYPT_MOD_CALL(PGP, sign_message)(a, from);
329 
330  return NULL;
331 }
332 
336 struct Body *crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist,
337  int sign, const struct AddressList *from)
338 {
339 #ifdef USE_AUTOCRYPT
340  if (e->security & SEC_AUTOCRYPT)
341  {
343  return NULL;
344 
345  OptAutocryptGpgme = true;
346  struct Body *result = pgp_gpgme_encrypt_message(a, keylist, sign, from);
347  OptAutocryptGpgme = false;
348 
349  return result;
350  }
351 #endif
352 
353  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_encrypt_message))
354  return CRYPT_MOD_CALL(PGP, pgp_encrypt_message)(a, keylist, sign, from);
355 
356  return NULL;
357 }
358 
362 void crypt_pgp_invoke_import(const char *fname)
363 {
364  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_import))
365  CRYPT_MOD_CALL(PGP, pgp_invoke_import)(fname);
366 }
367 
371 int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
372 {
374  return CRYPT_MOD_CALL(PGP, verify_one)(sigbdy, s, tempf);
375 
376  return -1;
377 }
378 
383 {
384  if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
385  return CRYPT_MOD_CALL(PGP, send_menu)(e);
386 
387  return 0;
388 }
389 
393 void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
394 {
395  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
396  CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, top);
397 }
398 
402 void crypt_pgp_set_sender(const char *sender)
403 {
404  if (CRYPT_MOD_CALL_CHECK(PGP, set_sender))
405  CRYPT_MOD_CALL(PGP, set_sender)(sender);
406 }
407 
412 {
413  if (CRYPT_MOD_CALL_CHECK(SMIME, void_passphrase))
414  CRYPT_MOD_CALL(SMIME, void_passphrase)();
415 }
416 
421 {
422  if (CRYPT_MOD_CALL_CHECK(SMIME, valid_passphrase))
423  return CRYPT_MOD_CALL(SMIME, valid_passphrase)();
424 
425  return false;
426 }
427 
431 int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
432 {
433  if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
434  return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, cur);
435 
436  return -1;
437 }
438 
444 int crypt_smime_application_handler(struct Body *m, struct State *s)
445 {
446  if (CRYPT_MOD_CALL_CHECK(SMIME, application_handler))
447  return CRYPT_MOD_CALL(SMIME, application_handler)(m, s);
448 
449  return -1;
450 }
451 
455 void crypt_smime_getkeys(struct Envelope *env)
456 {
457  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
458  CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
459 }
460 
464 int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e)
465 {
466  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
467  return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(m, e);
468 
469  return 1;
470 }
471 
475 char *crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
476 {
477  if (CRYPT_MOD_CALL_CHECK(SMIME, find_keys))
478  return CRYPT_MOD_CALL(SMIME, find_keys)(addrlist, oppenc_mode);
479 
480  return NULL;
481 }
482 
486 struct 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 
497 struct 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 
508 void 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 
517 int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
518 {
519  if (CRYPT_MOD_CALL_CHECK(SMIME, verify_one))
520  return CRYPT_MOD_CALL(SMIME, verify_one)(sigbdy, s, 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 
539 void 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 }
Convenience wrapper for the gui headers.
#define WithCrypto
Definition: lib.h:118
The envelope/body of an email.
Definition: email.h:37
int(* encrypted_handler)(struct Body *m, struct State *s)
Manage a PGP or S/MIME encrypted MIME part.
Definition: crypt_mod.h:100
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
void crypt_cleanup(void)
Clean up backend.
Definition: cryptglue.c:138
Wrapper for PGP/SMIME calls to GPGME.
Structs that make up an email.
Autocrypt end-to-end encryption.
int crypt_pgp_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:234
#define mutt_message(...)
Definition: logging.h:83
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
Wrapper around crypto functions.
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:187
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:420
int(* application_handler)(struct Body *m, struct State *s)
Manage the MIME type "application/pgp" or "application/smime".
Definition: crypt_mod.h:91
void(* void_passphrase)(void)
Forget the cached passphrase.
Definition: crypt_mod.h:61
int(* pgp_check_traditional)(FILE *fp, struct Body *b, bool just_one)
Look for inline (non-MIME) PGP content.
Definition: crypt_mod.h:174
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:402
#define _(a)
Definition: message.h:28
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:79
An email address.
Definition: address.h:34
WHERE bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:33
#define CRYPT_MOD_CALL(identifier, func)
Definition: cryptglue.c:85
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:89
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:78
bool C_CryptUseGpgme
Config: Use GPGME crypto backend.
Definition: config.c:68
static char * find_keys(struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:5239
int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
void crypto_module_register(struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition: crypt_mod.c:51
Shared constants/structs that are private to libconn.
int crypt_smime_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:444
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:1569
The body of an email.
Definition: body.h:34
struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - Implements CryptModuleSpecs.
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:539
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
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:2381
struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs.
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:528
int pgp_gpgme_encrypted_handler(struct Body *a, struct State *s)
Implements CryptModuleSpecs::encrypted_handler()
Definition: crypt_gpgme.c:3229
int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler()
Definition: cryptglue.c:247
int(* decrypt_mime)(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Decrypt an encrypted MIME part.
Definition: crypt_mod.h:82
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:411
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:393
struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs.
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:661
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:336
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:153
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition: cryptglue.c:79
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:93
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:92
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:362
A mailbox.
Definition: mailbox.h:81
Crypto API.
Definition: crypt_mod.h:44
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
void(* cleanup)(void)
Clean up the crypt module.
Definition: crypt_mod.h:56
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:272
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:382
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:292
API for encryption/signing of emails.
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:431
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:93
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
bool(* valid_passphrase)(void)
Ensure we have a valid passphrase.
Definition: crypt_mod.h:71
struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition: crypt_mod.c:65
static int verify_one(struct Body *sigbdy, struct State *s, const char *tempfile, bool is_smime)
Do the actual verification step.
Definition: crypt_gpgme.c:2075
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:167
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:281
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:303
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:314
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
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:207
static struct Body * sign_message(struct Body *a, const struct AddressList *from, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:1432
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:325
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:517
Keep track when processing files.
Definition: state.h:44
struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs.
Handling of global boolean variables.
Convenience wrapper for the library headers.
void(* pgp_invoke_getkeys)(struct Address *addr)
Run a command to download a PGP key.
Definition: crypt_mod.h:190
void(* init)(void)
Initialise the crypto module.
Definition: crypt_mod.h:51
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:196
Register crypto modules.
The header of an Email.
Definition: envelope.h:54
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:371