NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
crypt.c File Reference
#include "config.h"
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "crypt.h"
#include "ncrypt/lib.h"
#include "send/lib.h"
#include "context.h"
#include "copy.h"
#include "cryptglue.h"
#include "handler.h"
#include "mutt_globals.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "options.h"
#include "state.h"
#include "autocrypt/lib.h"
+ Include dependency graph for crypt.c:

Go to the source code of this file.

Functions

void crypt_current_time (struct State *s, const char *app_name)
 Print the current time. More...
 
void crypt_forget_passphrase (void)
 Forget a passphrase and display a message. More...
 
bool crypt_valid_passphrase (SecurityFlags flags)
 Check that we have a usable passphrase, ask if not. More...
 
int mutt_protect (struct Email *e, char *keylist, bool postpone)
 Encrypt and/or sign a message. More...
 
SecurityFlags mutt_is_multipart_signed (struct Body *b)
 Is a message signed? More...
 
SecurityFlags mutt_is_multipart_encrypted (struct Body *b)
 Does the message have encrypted parts? More...
 
int mutt_is_valid_multipart_pgp_encrypted (struct Body *b)
 Is this a valid multi-part encrypted message? More...
 
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted (struct Body *b)
 Check for malformed layout. More...
 
SecurityFlags mutt_is_application_pgp (struct Body *m)
 Does the message use PGP? More...
 
SecurityFlags mutt_is_application_smime (struct Body *m)
 Does the message use S/MIME? More...
 
SecurityFlags crypt_query (struct Body *m)
 Check out the type of encryption used. More...
 
int crypt_write_signed (struct Body *a, struct State *s, const char *tempfile)
 Write the message body/part. More...
 
void crypt_convert_to_7bit (struct Body *a)
 Convert an email to 7bit encoding. More...
 
void crypt_extract_keys_from_messages (struct Mailbox *m, struct EmailList *el)
 Extract keys from a message. More...
 
int crypt_get_keys (struct Email *e, char **keylist, bool oppenc_mode)
 Check we have all the keys we need. More...
 
void crypt_opportunistic_encrypt (struct Email *e)
 Can all recipients be determined. More...
 
static void crypt_fetch_signatures (struct Body ***signatures, struct Body *a, int *n)
 Create an array of an emails parts. More...
 
bool mutt_should_hide_protected_subject (struct Email *e)
 Should NeoMutt hide the protected subject? More...
 
int mutt_protected_headers_handler (struct Body *a, struct State *s)
 Process a protected header - Implements handler_t. More...
 
int mutt_signed_handler (struct Body *a, struct State *s)
 Verify a "multipart/signed" body - Implements handler_t. More...
 
const char * crypt_get_fingerprint_or_id (const char *p, const char **pphint, const char **ppl, const char **pps)
 Get the fingerprint or long key ID. More...
 
bool crypt_is_numerical_keyid (const char *s)
 Is this a numerical keyid. More...
 

Detailed Description

Signing/encryption multiplexor

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • Thomas Roessler
  • Oliver Ehli
  • Werner Koch
  • g10code GmbH
  • Pietro Cerutti

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 crypt.c.

Function Documentation

◆ crypt_current_time()

void crypt_current_time ( struct State s,
const char *  app_name 
)

Print the current time.

Parameters
sState to use
app_nameApp name, e.g. "PGP"

print the current time to avoid spoofing of the signature output

Definition at line 72 of file crypt.c.

73 {
74  char p[256], tmp[256];
75 
76  if (!WithCrypto)
77  return;
78 
79  if (C_CryptTimestamp)
80  {
81  mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), MUTT_DATE_NOW);
82  }
83  else
84  *p = '\0';
85 
86  snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
87  state_attach_puts(s, tmp);
88 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_forget_passphrase()

void crypt_forget_passphrase ( void  )

Forget a passphrase and display a message.

Definition at line 93 of file crypt.c.

94 {
97 
100 
101  if (WithCrypto)
102  {
103  /* L10N: Due to the implementation details (e.g. some passwords are managed
104  by gpg-agent) we can't know whether we forgot zero, 1, 12, ...
105  passwords. So in English we use "Passphrases". Your language might
106  have other means to express this. */
107  mutt_message(_("Passphrases forgotten"));
108  }
109 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_valid_passphrase()

bool crypt_valid_passphrase ( SecurityFlags  flags)

Check that we have a usable passphrase, ask if not.

Parameters
flagsFlags, see SecurityFlags
Return values
trueSuccess
falseFailed

Definition at line 135 of file crypt.c.

136 {
137  bool rc = false;
138 
139 #ifndef DEBUG
140  disable_coredumps();
141 #endif
142 
143  if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & APPLICATION_PGP))
145 
146  if (((WithCrypto & APPLICATION_SMIME) != 0) && (flags & APPLICATION_SMIME))
148 
149  return rc;
150 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_protect()

int mutt_protect ( struct Email e,
char *  keylist,
bool  postpone 
)

Encrypt and/or sign a message.

Parameters
eEmail
keylistList of keys to encrypt to (space-separated)
postponeWhen true, signing is automatically disabled
Return values
0Success
-1Error

Definition at line 160 of file crypt.c.

161 {
162  struct Body *pbody = NULL, *tmp_pbody = NULL;
163  struct Body *tmp_smime_pbody = NULL;
164  struct Body *tmp_pgp_pbody = NULL;
165  bool has_retainable_sig = false;
166 
167  if (!WithCrypto)
168  return -1;
169 
170  SecurityFlags security = e->security;
171  int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
172  if (postpone)
173  {
174  sign = SEC_NO_FLAGS;
175  security &= ~SEC_SIGN;
176  }
177 
178  if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
179  return 0;
180 
181  if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
182  return -1;
183 
184  if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
185  ((security & PGP_INLINE) == PGP_INLINE))
186  {
187  if ((e->body->type != TYPE_TEXT) ||
188  !mutt_istr_equal(e->body->subtype, "plain"))
189  {
191  _("Inline PGP can't be used with attachments. "
192  "Revert to PGP/MIME?")) != MUTT_YES)
193  {
194  mutt_error(
195  _("Mail not sent: inline PGP can't be used with attachments"));
196  return -1;
197  }
198  }
199  else if (mutt_istr_equal("flowed",
200  mutt_param_get(&e->body->parameter, "format")))
201  {
203  _("Inline PGP can't be used with format=flowed. "
204  "Revert to PGP/MIME?"))) != MUTT_YES)
205  {
206  mutt_error(
207  _("Mail not sent: inline PGP can't be used with format=flowed"));
208  return -1;
209  }
210  }
211  else
212  {
213  /* they really want to send it inline... go for it */
214  if (!isendwin())
215  {
216  mutt_endwin();
217  puts(_("Invoking PGP..."));
218  }
219  pbody = crypt_pgp_traditional_encryptsign(e->body, security, keylist);
220  if (pbody)
221  {
222  e->body = pbody;
223  return 0;
224  }
225 
226  /* otherwise inline won't work...ask for revert */
227  if (query_quadoption(
229  _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
230  {
231  mutt_error(_("Mail not sent"));
232  return -1;
233  }
234  }
235 
236  /* go ahead with PGP/MIME */
237  }
238 
239  if (!isendwin())
240  mutt_endwin();
241 
243  tmp_smime_pbody = e->body;
245  tmp_pgp_pbody = e->body;
246 
247 #ifdef CRYPT_BACKEND_GPGME
248  if (sign && C_CryptUsePka)
249 #else
250  if (sign)
251 #endif
252  {
253  /* Set sender (necessary for e.g. PKA). */
254  const char *mailbox = NULL;
255  struct Address *from = TAILQ_FIRST(&e->env->from);
256  bool free_from = false;
257 
258  if (!from)
259  {
260  free_from = true;
261  from = mutt_default_from(NeoMutt->sub);
262  }
263 
264  mailbox = from->mailbox;
267 
268  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
270  else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
272 
273  if (free_from)
274  mutt_addr_free(&from);
275  }
276 
278  {
279  struct Envelope *protected_headers = mutt_env_new();
280  mutt_str_replace(&protected_headers->subject, e->env->subject);
281  /* Note: if other headers get added, such as to, cc, then a call to
282  * mutt_env_to_intl() will need to be added here too. */
283  mutt_prepare_envelope(protected_headers, 0, NeoMutt->sub);
284 
286  e->body->mime_headers = protected_headers;
287  /* Optional part of the draft RFC, but required by Enigmail */
288  mutt_param_set(&e->body->parameter, "protected-headers", "v1");
289  }
290  else
291  {
292  mutt_param_delete(&e->body->parameter, "protected-headers");
293  }
294 
295 #ifdef USE_AUTOCRYPT
296  /* A note about e->body->mime_headers. If postpone or send
297  * fails, the mime_headers is cleared out before returning to the
298  * compose menu. So despite the "robustness" code above and in the
299  * gen_gossip_list function below, mime_headers will not be set when
300  * entering mutt_protect().
301  *
302  * This is important to note because the user could toggle
303  * $crypt_protected_headers_write or $autocrypt off back in the
304  * compose menu. We don't want mutt_write_rfc822_header() to write
305  * stale data from one option if the other is set.
306  */
307  if (C_Autocrypt && !postpone && (security & SEC_AUTOCRYPT))
308  {
309  struct Mailbox *m = ctx_mailbox(Context);
311  }
312 #endif
313 
314  if (sign)
315  {
316  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
317  {
318  tmp_pbody = crypt_smime_sign_message(e->body, &e->env->from);
319  if (!tmp_pbody)
320  goto bail;
321  pbody = tmp_pbody;
322  tmp_smime_pbody = tmp_pbody;
323  }
324 
325  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
326  (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || C_PgpRetainableSigs))
327  {
328  tmp_pbody = crypt_pgp_sign_message(e->body, &e->env->from);
329  if (!tmp_pbody)
330  goto bail;
331 
332  has_retainable_sig = true;
333  sign = SEC_NO_FLAGS;
334  pbody = tmp_pbody;
335  tmp_pgp_pbody = tmp_pbody;
336  }
337 
338  if ((WithCrypto != 0) && (security & APPLICATION_SMIME) && (security & APPLICATION_PGP))
339  {
340  /* here comes the draft ;-) */
341  }
342  }
343 
344  if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
345  {
346  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
347  {
348  tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
349  if (!tmp_pbody)
350  {
351  /* signed ? free it! */
352  goto bail;
353  }
354  /* free tmp_body if messages was signed AND encrypted ... */
355  if ((tmp_smime_pbody != e->body) && (tmp_smime_pbody != tmp_pbody))
356  {
357  /* detach and don't delete e->body,
358  * which tmp_smime_pbody->parts after signing. */
359  tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
360  e->body->next = NULL;
361  mutt_body_free(&tmp_smime_pbody);
362  }
363  pbody = tmp_pbody;
364  }
365 
366  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
367  {
368  pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
369  if (!pbody)
370  {
371  /* did we perform a retainable signature? */
372  if (has_retainable_sig)
373  {
374  /* remove the outer multipart layer */
375  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
376  /* get rid of the signature */
377  mutt_body_free(&tmp_pgp_pbody->next);
378  }
379 
380  goto bail;
381  }
382 
383  // destroy temporary signature envelope when doing retainable signatures.
384  if (has_retainable_sig)
385  {
386  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
387  mutt_body_free(&tmp_pgp_pbody->next);
388  }
389  }
390  }
391 
392  if (pbody)
393  {
394  e->body = pbody;
395  return 0;
396  }
397 
398 bail:
400  return -1;
401 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_multipart_signed()

SecurityFlags mutt_is_multipart_signed ( struct Body b)

Is a message signed?

Parameters
bBody of email
Return values
numMessage is signed, see SecurityFlags
0Message is not signed (SEC_NO_FLAGS)

Definition at line 409 of file crypt.c.

410 {
411  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "signed"))
412  {
413  return SEC_NO_FLAGS;
414  }
415 
416  char *p = mutt_param_get(&b->parameter, "protocol");
417  if (!p)
418  return SEC_NO_FLAGS;
419 
420  if (mutt_istr_equal(p, "multipart/mixed"))
421  return SEC_SIGN;
422 
423  if (((WithCrypto & APPLICATION_PGP) != 0) &&
424  mutt_istr_equal(p, "application/pgp-signature"))
425  {
426  return PGP_SIGN;
427  }
428 
429  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
430  mutt_istr_equal(p, "application/x-pkcs7-signature"))
431  {
432  return SMIME_SIGN;
433  }
434  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
435  mutt_istr_equal(p, "application/pkcs7-signature"))
436  {
437  return SMIME_SIGN;
438  }
439 
440  return SEC_NO_FLAGS;
441 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_multipart_encrypted()

SecurityFlags mutt_is_multipart_encrypted ( struct Body b)

Does the message have encrypted parts?

Parameters
bBody of email
Return values
numMessage has got encrypted parts, see SecurityFlags
0Message hasn't got encrypted parts (SEC_NO_FLAGS)

Definition at line 449 of file crypt.c.

450 {
451  if ((WithCrypto & APPLICATION_PGP) == 0)
452  return SEC_NO_FLAGS;
453 
454  char *p = NULL;
455 
456  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
457  !mutt_istr_equal(b->subtype, "encrypted") ||
458  !(p = mutt_param_get(&b->parameter, "protocol")) ||
459  !mutt_istr_equal(p, "application/pgp-encrypted"))
460  {
461  return SEC_NO_FLAGS;
462  }
463 
464  return PGP_ENCRYPT;
465 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_valid_multipart_pgp_encrypted()

int mutt_is_valid_multipart_pgp_encrypted ( struct Body b)

Is this a valid multi-part encrypted message?

Parameters
bBody of email
Return values
>0Message is valid, with encrypted parts, e.g. PGP_ENCRYPT
0Message hasn't got encrypted parts

Definition at line 473 of file crypt.c.

474 {
476  return 0;
477 
478  b = b->parts;
479  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
480  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
481  {
482  return 0;
483  }
484 
485  b = b->next;
486  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
487  !mutt_istr_equal(b->subtype, "octet-stream"))
488  {
489  return 0;
490  }
491 
492  return PGP_ENCRYPT;
493 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_malformed_multipart_pgp_encrypted()

SecurityFlags mutt_is_malformed_multipart_pgp_encrypted ( struct Body b)

Check for malformed layout.

Parameters
bBody of email
Return values
numSuccess, see SecurityFlags
0Error, (SEC_NO_FLAGS)

This checks for the malformed layout caused by MS Exchange in some cases:

<multipart/mixed>
<text/plain>
<application/pgp-encrypted> [BASE64-encoded]
<application/octet-stream> [BASE64-encoded]

Definition at line 510 of file crypt.c.

511 {
512  if (!(WithCrypto & APPLICATION_PGP))
513  return SEC_NO_FLAGS;
514 
515  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "mixed"))
516  {
517  return SEC_NO_FLAGS;
518  }
519 
520  b = b->parts;
521  if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
522  !mutt_istr_equal(b->subtype, "plain") || (b->length != 0))
523  {
524  return SEC_NO_FLAGS;
525  }
526 
527  b = b->next;
528  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
529  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
530  {
531  return SEC_NO_FLAGS;
532  }
533 
534  b = b->next;
535  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
536  !mutt_istr_equal(b->subtype, "octet-stream"))
537  {
538  return SEC_NO_FLAGS;
539  }
540 
541  b = b->next;
542  if (b)
543  return SEC_NO_FLAGS;
544 
545  return PGP_ENCRYPT;
546 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_application_pgp()

SecurityFlags mutt_is_application_pgp ( struct Body m)

Does the message use PGP?

Parameters
mBody of email
Return values
>0Message uses PGP, e.g. PGP_ENCRYPT
0Message doesn't use PGP, (SEC_NO_FLAGS)

Definition at line 554 of file crypt.c.

555 {
557  char *p = NULL;
558 
559  if (m->type == TYPE_APPLICATION)
560  {
561  if (mutt_istr_equal(m->subtype, "pgp") ||
562  mutt_istr_equal(m->subtype, "x-pgp-message"))
563  {
564  p = mutt_param_get(&m->parameter, "x-action");
565  if (p && (mutt_istr_equal(p, "sign") || mutt_istr_equal(p, "signclear")))
566  {
567  t |= PGP_SIGN;
568  }
569 
570  p = mutt_param_get(&m->parameter, "format");
571  if (p && mutt_istr_equal(p, "keys-only"))
572  {
573  t |= PGP_KEY;
574  }
575 
576  if (t == SEC_NO_FLAGS)
577  t |= PGP_ENCRYPT; /* not necessarily correct, but... */
578  }
579 
580  if (mutt_istr_equal(m->subtype, "pgp-signed"))
581  t |= PGP_SIGN;
582 
583  if (mutt_istr_equal(m->subtype, "pgp-keys"))
584  t |= PGP_KEY;
585  }
586  else if ((m->type == TYPE_TEXT) && mutt_istr_equal("plain", m->subtype))
587  {
588  if (((p = mutt_param_get(&m->parameter, "x-mutt-action")) ||
589  (p = mutt_param_get(&m->parameter, "x-action")) ||
590  (p = mutt_param_get(&m->parameter, "action"))) &&
591  mutt_istr_startswith(p, "pgp-sign"))
592  {
593  t |= PGP_SIGN;
594  }
595  else if (p && mutt_istr_startswith(p, "pgp-encrypt"))
596  t |= PGP_ENCRYPT;
597  else if (p && mutt_istr_startswith(p, "pgp-keys"))
598  t |= PGP_KEY;
599  }
600  if (t)
601  t |= PGP_INLINE;
602 
603  return t;
604 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_application_smime()

SecurityFlags mutt_is_application_smime ( struct Body m)

Does the message use S/MIME?

Parameters
mBody of email
Return values
>0Message uses S/MIME, e.g. SMIME_ENCRYPT
0Message doesn't use S/MIME, (SEC_NO_FLAGS)

Definition at line 612 of file crypt.c.

613 {
614  if (!m)
615  return SEC_NO_FLAGS;
616 
617  if (((m->type & TYPE_APPLICATION) == 0) || !m->subtype)
618  return SEC_NO_FLAGS;
619 
620  char *t = NULL;
621  bool complain = false;
622  /* S/MIME MIME types don't need x- anymore, see RFC2311 */
623  if (mutt_istr_equal(m->subtype, "x-pkcs7-mime") || mutt_istr_equal(m->subtype, "pkcs7-mime"))
624  {
625  t = mutt_param_get(&m->parameter, "smime-type");
626  if (t)
627  {
628  if (mutt_istr_equal(t, "enveloped-data"))
629  return SMIME_ENCRYPT;
630  if (mutt_istr_equal(t, "signed-data"))
631  return SMIME_SIGN | SMIME_OPAQUE;
632  return SEC_NO_FLAGS;
633  }
634  /* Netscape 4.7 uses
635  * Content-Description: S/MIME Encrypted Message
636  * instead of Content-Type parameter */
637  if (mutt_istr_equal(m->description, "S/MIME Encrypted Message"))
638  return SMIME_ENCRYPT;
639  complain = true;
640  }
641  else if (!mutt_istr_equal(m->subtype, "octet-stream"))
642  return SEC_NO_FLAGS;
643 
644  t = mutt_param_get(&m->parameter, "name");
645 
646  if (!t)
647  t = m->d_filename;
648  if (!t)
649  t = m->filename;
650  if (!t)
651  {
652  if (complain)
653  {
654  mutt_message(
655  _("S/MIME messages with no hints on content are unsupported"));
656  }
657  return SEC_NO_FLAGS;
658  }
659 
660  /* no .p7c, .p10 support yet. */
661 
662  int len = mutt_str_len(t) - 4;
663  if ((len > 0) && (*(t + len) == '.'))
664  {
665  len++;
666  if (mutt_istr_equal((t + len), "p7m"))
667  {
668  /* Not sure if this is the correct thing to do, but
669  * it's required for compatibility with Outlook */
670  return SMIME_SIGN | SMIME_OPAQUE;
671  }
672  else if (mutt_istr_equal((t + len), "p7s"))
673  return SMIME_SIGN | SMIME_OPAQUE;
674  }
675 
676  return SEC_NO_FLAGS;
677 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_query()

SecurityFlags crypt_query ( struct Body m)

Check out the type of encryption used.

Parameters
mBody of email
Return values
numFlags, see SecurityFlags
0Error (SEC_NO_FLAGS)

Set the cached status values if there are any.

Definition at line 687 of file crypt.c.

688 {
689  if (!WithCrypto || !m)
690  return SEC_NO_FLAGS;
691 
693 
694  if (m->type == TYPE_APPLICATION)
695  {
697  rc |= mutt_is_application_pgp(m);
698 
700  {
701  rc |= mutt_is_application_smime(m);
702  if (rc && m->goodsig)
703  rc |= SEC_GOODSIGN;
704  if (rc && m->badsig)
705  rc |= SEC_BADSIGN;
706  }
707  }
708  else if (((WithCrypto & APPLICATION_PGP) != 0) && (m->type == TYPE_TEXT))
709  {
710  rc |= mutt_is_application_pgp(m);
711  if (rc && m->goodsig)
712  rc |= SEC_GOODSIGN;
713  }
714 
715  if (m->type == TYPE_MULTIPART)
716  {
718  rc |= mutt_is_multipart_signed(m);
720 
721  if (rc && m->goodsig)
722  rc |= SEC_GOODSIGN;
723 #ifdef USE_AUTOCRYPT
724  if (rc && m->is_autocrypt)
725  rc |= SEC_AUTOCRYPT;
726 #endif
727  }
728 
729  if ((m->type == TYPE_MULTIPART) || (m->type == TYPE_MESSAGE))
730  {
731  SecurityFlags u = m->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
732  SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
733 
734  for (struct Body *b = m->parts; b; b = b->next)
735  {
736  const SecurityFlags v = crypt_query(b);
737  u &= v;
738  w |= v;
739  }
740  rc |= u | (w & ~SEC_GOODSIGN);
741 
742  if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
743  rc |= SEC_PARTSIGN;
744  }
745 
746  return rc;
747 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_write_signed()

int crypt_write_signed ( struct Body a,
struct State s,
const char *  tempfile 
)

Write the message body/part.

Parameters
aBody to write
sState to use
tempfileFile to write to
Return values
0Success
-1Error

Body/part A described by state S to the given TEMPFILE.

Definition at line 759 of file crypt.c.

760 {
761  if (!WithCrypto)
762  return -1;
763 
764  FILE *fp = mutt_file_fopen(tempfile, "w");
765  if (!fp)
766  {
767  mutt_perror(tempfile);
768  return -1;
769  }
770 
771  fseeko(s->fp_in, a->hdr_offset, SEEK_SET);
772  size_t bytes = a->length + a->offset - a->hdr_offset;
773  bool hadcr = false;
774  while (bytes > 0)
775  {
776  const int c = fgetc(s->fp_in);
777  if (c == EOF)
778  break;
779 
780  bytes--;
781 
782  if (c == '\r')
783  hadcr = true;
784  else
785  {
786  if ((c == '\n') && !hadcr)
787  fputc('\r', fp);
788 
789  hadcr = false;
790  }
791 
792  fputc(c, fp);
793  }
794  mutt_file_fclose(&fp);
795 
796  return 0;
797 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_convert_to_7bit()

void crypt_convert_to_7bit ( struct Body a)

Convert an email to 7bit encoding.

Parameters
aBody of email to convert

Definition at line 803 of file crypt.c.

804 {
805  if (!WithCrypto)
806  return;
807 
808  while (a)
809  {
810  if (a->type == TYPE_MULTIPART)
811  {
812  if (a->encoding != ENC_7BIT)
813  {
814  a->encoding = ENC_7BIT;
816  }
817  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_PgpStrictEnc)
819  }
820  else if ((a->type == TYPE_MESSAGE) &&
821  !mutt_istr_equal(a->subtype, "delivery-status"))
822  {
823  if (a->encoding != ENC_7BIT)
824  mutt_message_to_7bit(a, NULL, NeoMutt->sub);
825  }
826  else if (a->encoding == ENC_8BIT)
828  else if (a->encoding == ENC_BINARY)
829  a->encoding = ENC_BASE64;
830  else if (a->content && (a->encoding != ENC_BASE64) &&
831  (a->content->from || (a->content->space && C_PgpStrictEnc)))
832  {
834  }
835  a = a->next;
836  }
837 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_extract_keys_from_messages()

void crypt_extract_keys_from_messages ( struct Mailbox m,
struct EmailList *  el 
)

Extract keys from a message.

Parameters
mMailbox
elList of Emails to process

The extracted keys will be added to the user's keyring.

Definition at line 846 of file crypt.c.

847 {
848  if (!WithCrypto)
849  return;
850 
851  struct Buffer *tempfname = mutt_buffer_pool_get();
852  mutt_buffer_mktemp(tempfname);
853  FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfname), "w");
854  if (!fp_out)
855  {
856  mutt_perror(mutt_buffer_string(tempfname));
857  goto cleanup;
858  }
859 
861  OptDontHandlePgpKeys = true;
862 
863  struct EmailNode *en = NULL;
864  STAILQ_FOREACH(en, el, entries)
865  {
866  struct Email *e = en->email;
867 
870  {
871  mutt_file_fclose(&fp_out);
872  break;
873  }
874 
875  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
876  {
878  fflush(fp_out);
879 
880  mutt_endwin();
881  puts(_("Trying to extract PGP keys...\n"));
883  }
884 
885  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
886  {
887  if (e->security & SEC_ENCRYPT)
888  {
890  CH_NO_FLAGS, 0);
891  }
892  else
894  fflush(fp_out);
895 
896  char *mbox = NULL;
897  if (!TAILQ_EMPTY(&e->env->from))
898  {
900  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
901  }
902  else if (!TAILQ_EMPTY(&e->env->sender))
903  {
905  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
906  }
907  if (mbox)
908  {
909  mutt_endwin();
910  puts(_("Trying to extract S/MIME certificates..."));
912  }
913  }
914 
915  rewind(fp_out);
916  }
917 
918  mutt_file_fclose(&fp_out);
919  if (isendwin())
921 
923 
925  OptDontHandlePgpKeys = false;
926 
927 cleanup:
928  mutt_buffer_pool_release(&tempfname);
929 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_get_keys()

int crypt_get_keys ( struct Email e,
char **  keylist,
bool  oppenc_mode 
)

Check we have all the keys we need.

Parameters
[in]eEmail with addresses to match
[out]keylistKeys needed
[in]oppenc_modeIf true, use opportunistic encryption
Return values
0Success
-1Error

Do a quick check to make sure that we can find all of the encryption keys if the user has requested this service. Return the list of keys in KEYLIST. If oppenc_mode is true, only keys that can be determined without prompting will be used.

Definition at line 945 of file crypt.c.

946 {
947  if (!WithCrypto)
948  return 0;
949 
950  struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
951  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
952  char *self_encrypt = NULL;
953 
954  /* Do a quick check to make sure that we can find all of the encryption
955  * keys if the user has requested this service. */
956 
957  *keylist = NULL;
958 
959 #ifdef USE_AUTOCRYPT
960  if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
961  {
962  struct Mailbox *m = ctx_mailbox(Context);
964  return -1;
965  return 0;
966  }
967 #endif
968 
970  OptPgpCheckTrust = true;
971 
972  mutt_addrlist_copy(&addrlist, &e->env->to, false);
973  mutt_addrlist_copy(&addrlist, &e->env->cc, false);
974  mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
975  mutt_addrlist_qualify(&addrlist, fqdn);
976  mutt_addrlist_dedupe(&addrlist);
977 
978  if (oppenc_mode || (e->security & SEC_ENCRYPT))
979  {
980  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
981  {
982  *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
983  if (!*keylist)
984  {
985  mutt_addrlist_clear(&addrlist);
986  return -1;
987  }
988  OptPgpCheckTrust = false;
990  self_encrypt = C_PgpDefaultKey;
991  }
992  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
993  {
994  *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
995  if (!*keylist)
996  {
997  mutt_addrlist_clear(&addrlist);
998  return -1;
999  }
1001  self_encrypt = C_SmimeDefaultKey;
1002  }
1003  }
1004 
1005  if (!oppenc_mode && self_encrypt)
1006  {
1007  const size_t keylist_size = mutt_str_len(*keylist);
1008  mutt_mem_realloc(keylist, keylist_size + mutt_str_len(self_encrypt) + 2);
1009  sprintf(*keylist + keylist_size, " %s", self_encrypt);
1010  }
1011 
1012  mutt_addrlist_clear(&addrlist);
1013 
1014  return 0;
1015 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_opportunistic_encrypt()

void crypt_opportunistic_encrypt ( struct Email e)

Can all recipients be determined.

Parameters
eEmail

Check if all recipients keys can be automatically determined. Enable encryption if they can, otherwise disable encryption.

Definition at line 1024 of file crypt.c.

1025 {
1026  if (!WithCrypto)
1027  return;
1028 
1030  return;
1031 
1032  char *pgpkeylist = NULL;
1033 
1034  crypt_get_keys(e, &pgpkeylist, 1);
1035  if (pgpkeylist)
1036  {
1037  e->security |= SEC_ENCRYPT;
1038  FREE(&pgpkeylist);
1039  }
1040  else
1041  {
1042  e->security &= ~SEC_ENCRYPT;
1043  }
1044 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_fetch_signatures()

static void crypt_fetch_signatures ( struct Body ***  signatures,
struct Body a,
int *  n 
)
static

Create an array of an emails parts.

Parameters
[out]signaturesArray of Body parts
[in]aBody part to examine
[out]nCumulative count of parts

Definition at line 1052 of file crypt.c.

1053 {
1054  if (!WithCrypto)
1055  return;
1056 
1057  for (; a; a = a->next)
1058  {
1059  if (a->type == TYPE_MULTIPART)
1060  crypt_fetch_signatures(signatures, a->parts, n);
1061  else
1062  {
1063  if ((*n % 5) == 0)
1064  mutt_mem_realloc(signatures, (*n + 6) * sizeof(struct Body **));
1065 
1066  (*signatures)[(*n)++] = a;
1067  }
1068  }
1069 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_should_hide_protected_subject()

bool mutt_should_hide_protected_subject ( struct Email e)

Should NeoMutt hide the protected subject?

Parameters
eEmail to test
Return values
boolTrue if the subject should be protected

Definition at line 1076 of file crypt.c.

1077 {
1080  {
1081  return true;
1082  }
1083 
1084  return false;
1085 }
+ Here is the caller graph for this function:

◆ mutt_protected_headers_handler()

int mutt_protected_headers_handler ( struct Body a,
struct State s 
)

Process a protected header - Implements handler_t.

Definition at line 1090 of file crypt.c.

1091 {
1093  {
1094  if (a->mime_headers->subject)
1095  {
1096  const bool display = (s->flags & MUTT_DISPLAY);
1097 
1098  if (display && C_Weed && mutt_matches_ignore("subject"))
1099  return 0;
1100 
1102  int wraplen = display ? mutt_window_wrap_cols(s->wraplen, C_Wrap) : 0;
1103 
1104  mutt_write_one_header(s->fp_out, "Subject", a->mime_headers->subject, s->prefix,
1105  wraplen, display ? CH_DISPLAY : CH_NO_FLAGS, NeoMutt->sub);
1106  state_puts(s, "\n");
1107  }
1108  }
1109 
1110  return 0;
1111 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_signed_handler()

int mutt_signed_handler ( struct Body a,
struct State s 
)

Verify a "multipart/signed" body - Implements handler_t.

Definition at line 1116 of file crypt.c.

1117 {
1118  if (!WithCrypto)
1119  return -1;
1120 
1121  bool inconsistent = false;
1122  struct Body *b = a;
1123  struct Body **signatures = NULL;
1124  int sigcnt = 0;
1125  int rc = 0;
1126  struct Buffer *tempfile = NULL;
1127 
1128  a = a->parts;
1129  SecurityFlags signed_type = mutt_is_multipart_signed(b);
1130  if (signed_type == SEC_NO_FLAGS)
1131  {
1132  /* A null protocol value is already checked for in mutt_body_handler() */
1133  state_printf(s,
1134  _("[-- Error: "
1135  "Unknown multipart/signed protocol %s --]\n\n"),
1136  mutt_param_get(&b->parameter, "protocol"));
1137  return mutt_body_handler(a, s);
1138  }
1139 
1140  if (!(a && a->next))
1141  inconsistent = true;
1142  else
1143  {
1144  switch (signed_type)
1145  {
1146  case SEC_SIGN:
1147  if ((a->next->type != TYPE_MULTIPART) || !mutt_istr_equal(a->next->subtype, "mixed"))
1148  {
1149  inconsistent = true;
1150  }
1151  break;
1152  case PGP_SIGN:
1153  if ((a->next->type != TYPE_APPLICATION) ||
1154  !mutt_istr_equal(a->next->subtype, "pgp-signature"))
1155  {
1156  inconsistent = true;
1157  }
1158  break;
1159  case SMIME_SIGN:
1160  if ((a->next->type != TYPE_APPLICATION) ||
1161  (!mutt_istr_equal(a->next->subtype, "x-pkcs7-signature") &&
1162  !mutt_istr_equal(a->next->subtype, "pkcs7-signature")))
1163  {
1164  inconsistent = true;
1165  }
1166  break;
1167  default:
1168  inconsistent = true;
1169  }
1170  }
1171  if (inconsistent)
1172  {
1173  state_attach_puts(s, _("[-- Error: Missing or bad-format multipart/signed "
1174  "signature --]\n\n"));
1175  return mutt_body_handler(a, s);
1176  }
1177 
1178  if (s->flags & MUTT_DISPLAY)
1179  {
1180  crypt_fetch_signatures(&signatures, a->next, &sigcnt);
1181 
1182  if (sigcnt != 0)
1183  {
1184  tempfile = mutt_buffer_pool_get();
1185  mutt_buffer_mktemp(tempfile);
1186  bool goodsig = true;
1187  if (crypt_write_signed(a, s, mutt_buffer_string(tempfile)) == 0)
1188  {
1189  for (int i = 0; i < sigcnt; i++)
1190  {
1191  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1192  (signatures[i]->type == TYPE_APPLICATION) &&
1193  mutt_istr_equal(signatures[i]->subtype, "pgp-signature"))
1194  {
1195  if (crypt_pgp_verify_one(signatures[i], s, mutt_buffer_string(tempfile)) != 0)
1196  goodsig = false;
1197 
1198  continue;
1199  }
1200 
1201  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
1202  (signatures[i]->type == TYPE_APPLICATION) &&
1203  (mutt_istr_equal(signatures[i]->subtype, "x-pkcs7-signature") ||
1204  mutt_istr_equal(signatures[i]->subtype, "pkcs7-signature")))
1205  {
1206  if (crypt_smime_verify_one(signatures[i], s, mutt_buffer_string(tempfile)) != 0)
1207  goodsig = false;
1208 
1209  continue;
1210  }
1211 
1212  state_printf(s,
1213  _("[-- Warning: "
1214  "We can't verify %s/%s signatures. --]\n\n"),
1215  TYPE(signatures[i]), signatures[i]->subtype);
1216  }
1217  }
1218 
1220  mutt_buffer_pool_release(&tempfile);
1221 
1222  b->goodsig = goodsig;
1223  b->badsig = !goodsig;
1224 
1225  /* Now display the signed body */
1226  state_attach_puts(s, _("[-- The following data is signed --]\n\n"));
1227 
1229 
1230  FREE(&signatures);
1231  }
1232  else
1233  {
1235  _("[-- Warning: Can't find any signatures. --]\n\n"));
1236  }
1237  }
1238 
1239  rc = mutt_body_handler(a, s);
1240 
1241  if ((s->flags & MUTT_DISPLAY) && (sigcnt != 0))
1242  state_attach_puts(s, _("\n[-- End of signed data --]\n"));
1243 
1244  return rc;
1245 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_get_fingerprint_or_id()

const char* crypt_get_fingerprint_or_id ( const char *  p,
const char **  pphint,
const char **  ppl,
const char **  pps 
)

Get the fingerprint or long key ID.

Parameters
[in]pString to examine
[out]pphintStart of string to be passed to pgp_add_string_to_hints() or crypt_add_string_to_hints()
[out]pplStart of long key ID if detected, else NULL
[out]ppsStart of short key ID if detected, else NULL
Return values
ptrCopy of fingerprint, if any, stripped of all spaces. Must be FREE'd by caller
NULLOtherwise

Obtain pointers to fingerprint or short or long key ID, if any.

Upon return, at most one of return, *ppl and *pps pointers is non-NULL, indicating the longest fingerprint or ID found, if any.

Definition at line 1261 of file crypt.c.

1263 {
1264  const char *ps = NULL, *pl = NULL, *phint = NULL;
1265  char *pfcopy = NULL, *s1 = NULL, *s2 = NULL;
1266  char c;
1267  int isid;
1268  size_t hexdigits;
1269 
1270  /* User input may be partial name, fingerprint or short or long key ID,
1271  * independent of `$pgp_long_ids`.
1272  * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1273  * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1274  * if an ID was found and to simplify logic in the key loop's inner
1275  * condition of the caller. */
1276 
1277  char *pf = mutt_str_skip_whitespace(p);
1278  if (mutt_istr_startswith(pf, "0x"))
1279  pf += 2;
1280 
1281  /* Check if a fingerprint is given, must be hex digits only, blanks
1282  * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1283  isid = 2; /* unknown */
1284  hexdigits = 0;
1285  s1 = pf;
1286  do
1287  {
1288  c = *(s1++);
1289  if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1290  (('a' <= c) && (c <= 'f')))
1291  {
1292  hexdigits++;
1293  if (isid == 2)
1294  isid = 1; /* it is an ID so far */
1295  }
1296  else if (c)
1297  {
1298  isid = 0; /* not an ID */
1299  if ((c == ' ') && ((hexdigits % 4) == 0))
1300  ; /* skip blank before or after 4 hex digits */
1301  else
1302  break; /* any other character or position */
1303  }
1304  } while (c);
1305 
1306  /* If at end of input, check for correct fingerprint length and copy if. */
1307  pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_dup(pf) : NULL);
1308 
1309  if (pfcopy)
1310  {
1311  /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1312  s1 = pfcopy;
1313  s2 = pfcopy;
1314  do
1315  {
1316  *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1317  } while (*(s2++));
1318 
1319  phint = pfcopy;
1320  ps = NULL;
1321  pl = NULL;
1322  }
1323  else
1324  {
1325  phint = p;
1326  ps = NULL;
1327  pl = NULL;
1328  if (isid == 1)
1329  {
1330  if (mutt_str_len(pf) == 16)
1331  pl = pf; /* long key ID */
1332  else if (mutt_str_len(pf) == 8)
1333  ps = pf; /* short key ID */
1334  }
1335  }
1336 
1337  *pphint = phint;
1338  *ppl = pl;
1339  *pps = ps;
1340  return pfcopy;
1341 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_is_numerical_keyid()

bool crypt_is_numerical_keyid ( const char *  s)

Is this a numerical keyid.

Parameters
sKey to test
Return values
trueIf keyid is numeric

Check if a crypt-hook value is a key id.

Definition at line 1350 of file crypt.c.

1351 {
1352  /* or should we require the "0x"? */
1353  if (mutt_strn_equal(s, "0x", 2))
1354  s += 2;
1355  if (strlen(s) % 8)
1356  return false;
1357  while (*s)
1358  if (!strchr("0123456789ABCDEFabcdef", *s++))
1359  return false;
1360 
1361  return true;
1362 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:
Body::hdr_offset
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
Envelope
The header of an Email.
Definition: envelope.h:54
C_CryptProtectedHeadersSubject
char * C_CryptProtectedHeadersSubject
Config: Use this as the subject for encrypted emails.
Definition: config.c:70
SMIME_SIGN
#define SMIME_SIGN
Definition: lib.h:110
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
Envelope::subject
char * subject
Email's subject.
Definition: envelope.h:66
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
ENC_BINARY
@ ENC_BINARY
Binary.
Definition: mime.h:53
ENC_QUOTED_PRINTABLE
@ ENC_QUOTED_PRINTABLE
Quoted-printable text.
Definition: mime.h:51
C_EnvelopeFromAddress
struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: config.c:71
PGP_SIGN
#define PGP_SIGN
Definition: lib.h:104
State::fp_in
FILE * fp_in
File to read from.
Definition: state.h:46
AUTOCRYPT_REC_NO
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition: lib.h:158
MUTT_CM_CHARCONV
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
Mailbox
A mailbox.
Definition: mailbox.h:81
APPLICATION_SMIME
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
Body::content
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
mutt_addrlist_dedupe
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1405
crypt_fetch_signatures
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1052
mutt_addrlist_qualify
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
MUTT_DISPLAY
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
Buffer
String manipulation buffer.
Definition: buffer.h:33
Body::offset
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
ctx_mailbox
struct Mailbox * ctx_mailbox(struct Context *ctx)
wrapper to get the mailbox in a Context, or NULL
Definition: context.c:429
SEC_OPPENCRYPT
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:93
crypt_smime_void_passphrase
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:414
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_is_malformed_multipart_pgp_encrypted
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:510
Body::next
struct Body * next
next attachment in the list
Definition: body.h:53
MUTT_CM_DECODE_CRYPT
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
Body
The body of an email.
Definition: body.h:34
SMIME_ENCRYPT
#define SMIME_ENCRYPT
Definition: lib.h:109
SEC_ENCRYPT
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
Body::is_autocrypt
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:79
crypt_pgp_encrypt_message
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
MUTT_CM_NOHEADER
#define MUTT_CM_NOHEADER
Don't copy the message header.
Definition: copy.h:35
mutt_remove_multipart
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: multipart.c:126
mutt_window_wrap_cols
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:477
SEC_SIGN
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
C_PgpStrictEnc
bool C_PgpStrictEnc
Config: Encode PGP signed messages with quoted-printable (don't unset)
Definition: config.c:77
SMIME_OPAQUE
#define SMIME_OPAQUE
Definition: lib.h:113
PGP_INLINE
#define PGP_INLINE
Definition: lib.h:107
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
mutt_autocrypt_generate_gossip_list
int mutt_autocrypt_generate_gossip_list(struct Mailbox *m, struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:823
Content::from
bool from
Has a line beginning with "From "?
Definition: content.h:43
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
EmailNode::email
struct Email * email
Email in the list.
Definition: email.h:127
mutt_prepare_envelope
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:1238
crypt_pgp_find_keys
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:316
crypt_pgp_invoke_import
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:365
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
crypt_smime_build_smime_entity
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:500
mutt_expand_aliases
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
crypt_smime_invoke_import
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:511
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
mutt_file_unlink
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
crypt_convert_to_7bit
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:803
FREE
#define FREE(x)
Definition: memory.h:40
C_Autocrypt
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
EmailNode
List of Emails.
Definition: email.h:125
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
Body::encoding
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
SecurityFlags
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:83
State::wraplen
int wraplen
Width to wrap lines to (when flags & MUTT_DISPLAY)
Definition: state.h:50
state_mark_protected_header
void state_mark_protected_header(struct State *s)
Write a unique marker around protected headers.
Definition: state.c:56
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Content::space
bool space
Whitespace at the end of lines?
Definition: content.h:41
mutt_body_free
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
crypt_smime_verify_one
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:520
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
State::fp_out
FILE * fp_out
File to write to.
Definition: state.h:47
state_attach_puts
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
C_CryptProtectedHeadersRead
bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: config.c:56
crypt_get_keys
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:945
State::prefix
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
mutt_parse_mime_message
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
MUTT_CM_DECODE_SMIME
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
Body::badsig
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:77
C_CryptUsePka
bool C_CryptUsePka
Config: Use GPGME to use PKA (lookup PGP keys using DNS)
Definition: config.c:51
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
C_PgpRetainableSigs
bool C_PgpRetainableSigs
Config: Create nested multipart/signed or encrypted messages.
Definition: config.c:75
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
mutt_write_one_header
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
Write one header line to a file.
Definition: header.c:420
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
mutt_date_localtime_format
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:680
mutt_env_free
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_is_application_pgp
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:554
SEC_ALL_FLAGS
#define SEC_ALL_FLAGS
Definition: lib.h:101
crypt_query
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:687
crypt_pgp_valid_passphrase
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:198
Body::goodsig
bool goodsig
Good cryptographic signature.
Definition: body.h:75
C_Wrap
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: mutt_globals.h:116
TYPE
#define TYPE(body)
Definition: mime.h:89
mutt_is_multipart_encrypted
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:449
Body::length
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
crypt_pgp_traditional_encryptsign
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:294
crypt_pgp_sign_message
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:327
ENC_8BIT
@ ENC_8BIT
8-bit text
Definition: mime.h:50
APPLICATION_PGP
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
MUTT_CM_NO_FLAGS
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
C_CryptOpportunisticEncrypt
bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient's key is available.
Definition: config.c:54
CH_NO_FLAGS
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
OptDontHandlePgpKeys
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:36
C_PgpSelfEncrypt
bool C_PgpSelfEncrypt
Config: Encrypted messages will also be encrypted to $pgp_default_key too.
Definition: config.c:76
C_PgpEncryptSelf
unsigned char C_PgpEncryptSelf
Definition: config.c:73
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
Body::description
char * description
content-description
Definition: body.h:40
mutt_matches_ignore
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:315
mutt_param_set
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
CH_DISPLAY
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
C_PgpDefaultKey
char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: config.c:64
Body::parts
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
TYPE_MESSAGE
@ TYPE_MESSAGE
Type: 'message/*'.
Definition: mime.h:35
C_PgpMimeAuto
unsigned char C_PgpMimeAuto
Config: Prompt the user to use MIME if inline PGP fails.
Definition: config.c:74
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
crypt_write_signed
int crypt_write_signed(struct Body *a, struct State *s, const char *tempfile)
Write the message body/part.
Definition: crypt.c:759
state_printf
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:153
mutt_addr_free
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
Email::security
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:39
MUTT_DATE_NOW
#define MUTT_DATE_NOW
Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()
Definition: date.h:39
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
crypt_smime_valid_passphrase
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:423
WithCrypto
#define WithCrypto
Definition: lib.h:123
SEC_BADSIGN
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:88
crypt_smime_set_sender
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:542
mutt_param_delete
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
mutt_param_get
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
PGP_ENCRYPT
#define PGP_ENCRYPT
Definition: lib.h:103
crypt_smime_sign_message
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:489
mutt_str_skip_whitespace
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition: string.c:686
C_Weed
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: globals.c:40
OptPgpCheckTrust
WHERE bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: options.h:49
crypt_pgp_verify_one
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:374
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
TYPE_APPLICATION
@ TYPE_APPLICATION
Type: 'application/*'.
Definition: mime.h:33
Body::d_filename
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
ENC_BASE64
@ ENC_BASE64
Base-64 encoded text.
Definition: mime.h:52
C_SmimeSelfEncrypt
bool C_SmimeSelfEncrypt
Config: Encrypted messages will also be encrypt to $smime_default_key too.
Definition: config.c:79
TYPE_TEXT
@ TYPE_TEXT
Type: 'text/*'.
Definition: mime.h:38
mutt_protected_headers_handler
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1090
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
SEC_INLINE
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:92
crypt_smime_find_keys
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:478
PGP_KEY
#define PGP_KEY
Definition: lib.h:106
mutt_istr_startswith
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
C_SmimeDefaultKey
char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: config.c:67
mutt_body_handler
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1595
mutt_default_from
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default 'from' Address.
Definition: send.c:1338
MUTT_CM_DECODE
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
crypt_pgp_void_passphrase
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:189
Body::parameter
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
mutt_autocrypt_ui_recommendation
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Mailbox *m, struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:561
mutt_fqdn
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1182
State::flags
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
TYPE_MULTIPART
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
Email
The envelope/body of an email.
Definition: email.h:37
C_CryptProtectedHeadersWrite
bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: config.c:58
mutt_message
#define mutt_message(...)
Definition: logging.h:83
crypt_pgp_set_sender
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:405
C_CryptTimestamp
bool C_CryptTimestamp
Config: Add a timestamp to PGP or SMIME output to prevent spoofing.
Definition: config.c:72
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
mutt_copy_message
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:835
crypt_valid_passphrase
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
SEC_NO_FLAGS
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:84
mutt_is_multipart_signed
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:409
Envelope::sender
struct AddressList sender
Email's sender.
Definition: envelope.h:61
SEC_GOODSIGN
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:87
mutt_is_application_smime
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:612
ENC_7BIT
@ ENC_7BIT
7-bit text
Definition: mime.h:49
mutt_message_to_7bit
void mutt_message_to_7bit(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Convert an email's MIME parts to 7-bit.
Definition: sendlib.c:748
SEC_AUTOCRYPT
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:94
Address
An email address.
Definition: address.h:34
state_puts
#define state_puts(STATE, STR)
Definition: state.h:55
SEC_PARTSIGN
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:89
Body::mime_headers
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
C_SmimeEncryptSelf
unsigned char C_SmimeEncryptSelf
Definition: config.c:78
Body::filename
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
mutt_error
#define mutt_error(...)
Definition: logging.h:84