NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
crypt.c File Reference

Signing/encryption multiplexor. More...

#include "config.h"
#include <limits.h>
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "mutt.h"
#include "alias.h"
#include "copy.h"
#include "cryptglue.h"
#include "curs_lib.h"
#include "globals.h"
#include "handler.h"
#include "mutt_curses.h"
#include "mutt_parse.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "ncrypt.h"
#include "options.h"
#include "send.h"
#include "sendlib.h"
#include "state.h"
#include "autocrypt/autocrypt.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...
 

Variables

bool C_CryptTimestamp
 Config: Add a timestamp to PGP or SMIME output to prevent spoofing. More...
 
unsigned char C_PgpEncryptSelf
 Deprecated, see C_PgpSelfEncrypt. More...
 
unsigned char C_PgpMimeAuto
 Config: Prompt the user to use MIME if inline PGP fails. More...
 
bool C_PgpRetainableSigs
 Config: Create nested multipart/signed or encrypted messages. More...
 
bool C_PgpSelfEncrypt
 Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too. More...
 
bool C_PgpStrictEnc
 Config: Encode PGP signed messages with quoted-printable (don't unset) More...
 
unsigned char C_SmimeEncryptSelf
 Deprecated, see C_SmimeSelfEncrypt. More...
 
bool C_SmimeSelfEncrypt
 Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too. 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 84 of file crypt.c.

85 {
86  char p[256], tmp[256];
87 
88  if (!WithCrypto)
89  return;
90 
91  if (C_CryptTimestamp)
92  {
93  mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), MUTT_DATE_NOW);
94  }
95  else
96  *p = '\0';
97 
98  snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
99  state_attach_puts(tmp, s);
100 }
#define NONULL(x)
Definition: string2.h:37
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:773
#define _(a)
Definition: message.h:28
#define MUTT_DATE_NOW
Constant representing the &#39;current time&#39;, see: mutt_date_gmtime(), mutt_date_localtime() ...
Definition: date.h:36
void state_attach_puts(const char *t, struct State *s)
Write a string to the state.
Definition: state.c:64
bool C_CryptTimestamp
Config: Add a timestamp to PGP or SMIME output to prevent spoofing.
Definition: crypt.c:65
#define WithCrypto
Definition: ncrypt.h:160
+ 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 105 of file crypt.c.

106 {
109 
112 
113  if (WithCrypto)
114  {
115  /* L10N: Due to the implementation details (e.g. some passwords are managed
116  by gpg-agent) we can't know whether we forgot zero, 1, 12, ...
117  passwords. So in English we use "Passphrases". Your language might
118  have other means to express this. */
119  mutt_message(_("Passphrases forgotten"));
120  }
121 }
#define mutt_message(...)
Definition: logging.h:83
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:179
#define _(a)
Definition: message.h:28
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:402
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 147 of file crypt.c.

148 {
149  bool rc = false;
150 
151 #ifndef DEBUG
152  disable_coredumps();
153 #endif
154 
155  if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & APPLICATION_PGP))
157 
158  if (((WithCrypto & APPLICATION_SMIME) != 0) && (flags & APPLICATION_SMIME))
160 
161  return rc;
162 }
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:411
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define WithCrypto
Definition: ncrypt.h:160
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:188
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 172 of file crypt.c.

173 {
174  struct Body *pbody = NULL, *tmp_pbody = NULL;
175  struct Body *tmp_smime_pbody = NULL;
176  struct Body *tmp_pgp_pbody = NULL;
177  bool has_retainable_sig = false;
178 
179  if (!WithCrypto)
180  return -1;
181 
182  int security = e->security;
183  int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
184  if (postpone)
185  {
186  sign = SEC_NO_FLAGS;
187  security &= ~SEC_SIGN;
188  }
189 
190  if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
191  return 0;
192 
193  if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
194  return -1;
195 
196  if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
197  ((security & PGP_INLINE) == PGP_INLINE))
198  {
199  if ((e->content->type != TYPE_TEXT) ||
200  (mutt_str_strcasecmp(e->content->subtype, "plain") != 0))
201  {
203  _("Inline PGP can't be used with attachments. "
204  "Revert to PGP/MIME?")) != MUTT_YES)
205  {
206  mutt_error(
207  _("Mail not sent: inline PGP can't be used with attachments"));
208  return -1;
209  }
210  }
211  else if (mutt_str_strcasecmp("flowed", mutt_param_get(&e->content->parameter, "format")) == 0)
212  {
214  _("Inline PGP can't be used with format=flowed. "
215  "Revert to PGP/MIME?"))) != MUTT_YES)
216  {
217  mutt_error(
218  _("Mail not sent: inline PGP can't be used with format=flowed"));
219  return -1;
220  }
221  }
222  else
223  {
224  /* they really want to send it inline... go for it */
225  if (!isendwin())
226  {
227  mutt_endwin();
228  puts(_("Invoking PGP..."));
229  }
230  pbody = crypt_pgp_traditional_encryptsign(e->content, security, keylist);
231  if (pbody)
232  {
233  e->content = pbody;
234  return 0;
235  }
236 
237  /* otherwise inline won't work...ask for revert */
238  if (query_quadoption(
240  _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
241  {
242  mutt_error(_("Mail not sent"));
243  return -1;
244  }
245  }
246 
247  /* go ahead with PGP/MIME */
248  }
249 
250  if (!isendwin())
251  mutt_endwin();
252 
254  tmp_smime_pbody = e->content;
255  if (WithCrypto & APPLICATION_PGP)
256  tmp_pgp_pbody = e->content;
257 
258  if (C_CryptUsePka && sign)
259  {
260  /* Set sender (necessary for e.g. PKA). */
261  const char *mailbox = NULL;
262  struct Address *from = TAILQ_FIRST(&e->env->from);
263  bool free_from = false;
264 
265  if (!from)
266  {
267  free_from = true;
268  from = mutt_default_from();
269  }
270 
271  mailbox = from->mailbox;
272  if (!mailbox && C_EnvelopeFromAddress)
273  mailbox = C_EnvelopeFromAddress->mailbox;
274 
275  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
276  crypt_smime_set_sender(mailbox);
277  else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
278  crypt_pgp_set_sender(mailbox);
279 
280  if (free_from)
281  mutt_addr_free(&from);
282  }
283 
285  {
286  struct Envelope *protected_headers = mutt_env_new();
287  mutt_str_replace(&protected_headers->subject, e->env->subject);
288  /* Note: if other headers get added, such as to, cc, then a call to
289  * mutt_env_to_intl() will need to be added here too. */
290  mutt_prepare_envelope(protected_headers, 0);
291 
293  e->content->mime_headers = protected_headers;
294  }
295 
296  /* A note about e->content->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 #ifdef USE_AUTOCRYPT
308  if (C_Autocrypt && !postpone && (security & SEC_AUTOCRYPT))
309  {
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->content);
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->content);
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->content) && (tmp_smime_pbody != tmp_pbody))
356  {
357  /* detach and don't delete e->content,
358  * which tmp_smime_pbody->parts after signing. */
359  tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
360  e->content->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);
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
384  * signatures.
385 
386  */
387  if (has_retainable_sig)
388  {
389  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
390  mutt_body_free(&tmp_pgp_pbody->next);
391  }
392  }
393  }
394 
395  if (pbody)
396  {
397  e->content = pbody;
398  return 0;
399  }
400 
401 bail:
403  return -1;
404 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:205
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1742
#define PGP_INLINE
Definition: ncrypt.h:144
#define TAILQ_FIRST(head)
Definition: queue.h:717
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3331
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * content
List of MIME parts.
Definition: email.h:92
WHERE bool C_CryptUsePka
Config: Use GPGME to use PKA (lookup PGP keys using DNS)
Definition: globals.h:275
WHERE bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: globals.h:283
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:393
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:439
The body of an email.
Definition: body.h:34
void mutt_prepare_envelope(struct Envelope *env, bool final)
Prepare an email header.
Definition: sendlib.c:2997
struct Body * crypt_smime_sign_message(struct Body *a)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:539
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:147
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool C_PgpRetainableSigs
Config: Create nested multipart/signed or encrypted messages.
Definition: crypt.c:71
struct Envelope * env
Envelope information.
Definition: email.h:91
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
char * subtype
content-type subtype
Definition: body.h:37
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1307
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
Type: &#39;text/*&#39;.
Definition: mime.h:38
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:284
struct Body * crypt_pgp_sign_message(struct Body *a)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:317
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
unsigned char C_PgpMimeAuto
Config: Prompt the user to use MIME if inline PGP fails.
Definition: crypt.c:70
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
char * subject
Email&#39;s subject.
Definition: envelope.h:66
int mutt_autocrypt_generate_gossip_list(struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:798
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: globals.h:98
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
struct Body * crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist, int sign)
Wrapper for CryptModuleSpecs::pgp_encrypt_message()
Definition: cryptglue.c:328
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
The header of an Email.
Definition: envelope.h:54
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 412 of file crypt.c.

413 {
414  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
415  (mutt_str_strcasecmp(b->subtype, "signed") != 0))
416  {
417  return SEC_NO_FLAGS;
418  }
419 
420  char *p = mutt_param_get(&b->parameter, "protocol");
421  if (!p)
422  return SEC_NO_FLAGS;
423 
424  if (!(mutt_str_strcasecmp(p, "multipart/mixed") != 0))
425  return SEC_SIGN;
426 
427  if (((WithCrypto & APPLICATION_PGP) != 0) &&
428  !(mutt_str_strcasecmp(p, "application/pgp-signature") != 0))
429  {
430  return PGP_SIGN;
431  }
432 
433  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
434  !(mutt_str_strcasecmp(p, "application/x-pkcs7-signature") != 0))
435  {
436  return SMIME_SIGN;
437  }
438  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
439  !(mutt_str_strcasecmp(p, "application/pkcs7-signature") != 0))
440  {
441  return SMIME_SIGN;
442  }
443 
444  return SEC_NO_FLAGS;
445 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define SMIME_SIGN
Definition: ncrypt.h:147
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 453 of file crypt.c.

454 {
455  if ((WithCrypto & APPLICATION_PGP) == 0)
456  return SEC_NO_FLAGS;
457 
458  char *p = NULL;
459 
460  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
461  (mutt_str_strcasecmp(b->subtype, "encrypted") != 0) ||
462  !(p = mutt_param_get(&b->parameter, "protocol")) ||
463  (mutt_str_strcasecmp(p, "application/pgp-encrypted") != 0))
464  {
465  return SEC_NO_FLAGS;
466  }
467 
468  return PGP_ENCRYPT;
469 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 477 of file crypt.c.

478 {
480  return 0;
481 
482  b = b->parts;
483  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
484  (mutt_str_strcasecmp(b->subtype, "pgp-encrypted") != 0))
485  {
486  return 0;
487  }
488 
489  b = b->next;
490  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
491  (mutt_str_strcasecmp(b->subtype, "octet-stream") != 0))
492  {
493  return 0;
494  }
495 
496  return PGP_ENCRYPT;
497 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * next
next attachment in the list
Definition: body.h:53
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
char * subtype
content-type subtype
Definition: body.h:37
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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]

See ticket #3742

Definition at line 515 of file crypt.c.

516 {
517  if (!(WithCrypto & APPLICATION_PGP))
518  return SEC_NO_FLAGS;
519 
520  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
521  (mutt_str_strcasecmp(b->subtype, "mixed") != 0))
522  {
523  return SEC_NO_FLAGS;
524  }
525 
526  b = b->parts;
527  if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
528  (mutt_str_strcasecmp(b->subtype, "plain") != 0) || (b->length != 0))
529  {
530  return SEC_NO_FLAGS;
531  }
532 
533  b = b->next;
534  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
535  (mutt_str_strcasecmp(b->subtype, "pgp-encrypted") != 0))
536  {
537  return SEC_NO_FLAGS;
538  }
539 
540  b = b->next;
541  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
542  (mutt_str_strcasecmp(b->subtype, "octet-stream") != 0))
543  {
544  return SEC_NO_FLAGS;
545  }
546 
547  b = b->next;
548  if (b)
549  return SEC_NO_FLAGS;
550 
551  return PGP_ENCRYPT;
552 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * next
next attachment in the list
Definition: body.h:53
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Type: &#39;text/*&#39;.
Definition: mime.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define WithCrypto
Definition: ncrypt.h:160
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 560 of file crypt.c.

561 {
563  char *p = NULL;
564 
565  if (m->type == TYPE_APPLICATION)
566  {
567  if ((mutt_str_strcasecmp(m->subtype, "pgp") == 0) ||
568  (mutt_str_strcasecmp(m->subtype, "x-pgp-message") == 0))
569  {
570  p = mutt_param_get(&m->parameter, "x-action");
571  if (p && ((mutt_str_strcasecmp(p, "sign") == 0) ||
572  (mutt_str_strcasecmp(p, "signclear") == 0)))
573  {
574  t |= PGP_SIGN;
575  }
576 
577  p = mutt_param_get(&m->parameter, "format");
578  if (p && (mutt_str_strcasecmp(p, "keys-only") == 0))
579  {
580  t |= PGP_KEY;
581  }
582 
583  if (t == SEC_NO_FLAGS)
584  t |= PGP_ENCRYPT; /* not necessarily correct, but... */
585  }
586 
587  if (mutt_str_strcasecmp(m->subtype, "pgp-signed") == 0)
588  t |= PGP_SIGN;
589 
590  if (mutt_str_strcasecmp(m->subtype, "pgp-keys") == 0)
591  t |= PGP_KEY;
592  }
593  else if ((m->type == TYPE_TEXT) && (mutt_str_strcasecmp("plain", m->subtype) == 0))
594  {
595  if (((p = mutt_param_get(&m->parameter, "x-mutt-action")) ||
596  (p = mutt_param_get(&m->parameter, "x-action")) ||
597  (p = mutt_param_get(&m->parameter, "action"))) &&
598  mutt_str_startswith(p, "pgp-sign", CASE_IGNORE))
599  {
600  t |= PGP_SIGN;
601  }
602  else if (p && mutt_str_startswith(p, "pgp-encrypt", CASE_IGNORE))
603  t |= PGP_ENCRYPT;
604  else if (p && mutt_str_startswith(p, "pgp-keys", CASE_IGNORE))
605  t |= PGP_KEY;
606  }
607  if (t)
608  t |= PGP_INLINE;
609 
610  return t;
611 }
#define PGP_INLINE
Definition: ncrypt.h:144
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
#define PGP_KEY
Definition: ncrypt.h:143
Type: &#39;text/*&#39;.
Definition: mime.h:38
Ignore case when comparing strings.
Definition: string2.h:68
unsigned int type
content-type primary type
Definition: body.h:65
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 619 of file crypt.c.

620 {
621  if (!m)
622  return SEC_NO_FLAGS;
623 
624  if (((m->type & TYPE_APPLICATION) == 0) || !m->subtype)
625  return SEC_NO_FLAGS;
626 
627  char *t = NULL;
628  bool complain = false;
629  /* S/MIME MIME types don't need x- anymore, see RFC2311 */
630  if ((mutt_str_strcasecmp(m->subtype, "x-pkcs7-mime") == 0) ||
631  (mutt_str_strcasecmp(m->subtype, "pkcs7-mime") == 0))
632  {
633  t = mutt_param_get(&m->parameter, "smime-type");
634  if (t)
635  {
636  if (mutt_str_strcasecmp(t, "enveloped-data") == 0)
637  return SMIME_ENCRYPT;
638  else if (mutt_str_strcasecmp(t, "signed-data") == 0)
639  return SMIME_SIGN | SMIME_OPAQUE;
640  else
641  return SEC_NO_FLAGS;
642  }
643  /* Netscape 4.7 uses
644  * Content-Description: S/MIME Encrypted Message
645  * instead of Content-Type parameter */
646  if (mutt_str_strcasecmp(m->description, "S/MIME Encrypted Message") == 0)
647  return SMIME_ENCRYPT;
648  complain = true;
649  }
650  else if (mutt_str_strcasecmp(m->subtype, "octet-stream") != 0)
651  return SEC_NO_FLAGS;
652 
653  t = mutt_param_get(&m->parameter, "name");
654 
655  if (!t)
656  t = m->d_filename;
657  if (!t)
658  t = m->filename;
659  if (!t)
660  {
661  if (complain)
662  {
663  mutt_message(
664  _("S/MIME messages with no hints on content are unsupported"));
665  }
666  return SEC_NO_FLAGS;
667  }
668 
669  /* no .p7c, .p10 support yet. */
670 
671  int len = mutt_str_strlen(t) - 4;
672  if ((len > 0) && (*(t + len) == '.'))
673  {
674  len++;
675  if (mutt_str_strcasecmp((t + len), "p7m") == 0)
676  {
677  /* Not sure if this is the correct thing to do, but
678  * it's required for compatibility with Outlook */
679  return SMIME_SIGN | SMIME_OPAQUE;
680  }
681  else if (mutt_str_strcasecmp((t + len), "p7s") == 0)
682  return SMIME_SIGN | SMIME_OPAQUE;
683  }
684 
685  return SEC_NO_FLAGS;
686 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define mutt_message(...)
Definition: logging.h:83
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define _(a)
Definition: message.h:28
#define SMIME_SIGN
Definition: ncrypt.h:147
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#define SMIME_OPAQUE
Definition: ncrypt.h:150
char * subtype
content-type subtype
Definition: body.h:37
char * description
content-description
Definition: body.h:40
unsigned int type
content-type primary type
Definition: body.h:65
#define SMIME_ENCRYPT
Definition: ncrypt.h:146
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ 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 696 of file crypt.c.

697 {
698  if (!WithCrypto || !m)
699  return SEC_NO_FLAGS;
700 
702 
703  if (m->type == TYPE_APPLICATION)
704  {
706  rc |= mutt_is_application_pgp(m);
707 
709  {
710  rc |= mutt_is_application_smime(m);
711  if (rc && m->goodsig)
712  rc |= SEC_GOODSIGN;
713  if (rc && m->badsig)
714  rc |= SEC_BADSIGN;
715  }
716  }
717  else if (((WithCrypto & APPLICATION_PGP) != 0) && (m->type == TYPE_TEXT))
718  {
719  rc |= mutt_is_application_pgp(m);
720  if (rc && m->goodsig)
721  rc |= SEC_GOODSIGN;
722  }
723 
724  if (m->type == TYPE_MULTIPART)
725  {
727  rc |= mutt_is_multipart_signed(m);
729 
730  if (rc && m->goodsig)
731  rc |= SEC_GOODSIGN;
732 #ifdef USE_AUTOCRYPT
733  if (rc && m->is_autocrypt)
734  rc |= SEC_AUTOCRYPT;
735 #endif
736  }
737 
738  if ((m->type == TYPE_MULTIPART) || (m->type == TYPE_MESSAGE))
739  {
740  SecurityFlags u = m->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
741  SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
742 
743  for (struct Body *b = m->parts; b; b = b->next)
744  {
745  const SecurityFlags v = crypt_query(b);
746  u &= v;
747  w |= v;
748  }
749  rc |= u | (w & ~SEC_GOODSIGN);
750 
751  if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
752  rc |= SEC_PARTSIGN;
753  }
754 
755  return rc;
756 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:85
struct Body * next
next attachment in the list
Definition: body.h:53
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:126
The body of an email.
Definition: body.h:34
#define SEC_BADSIGN
Email has a bad signature.
Definition: ncrypt.h:125
#define SEC_ALL_FLAGS
Definition: ncrypt.h:138
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:124
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:83
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:412
bool goodsig
Good cryptographic signature.
Definition: body.h:81
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:560
Type: &#39;text/*&#39;.
Definition: mime.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:515
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:619
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
#define WithCrypto
Definition: ncrypt.h:160
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:696
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 768 of file crypt.c.

769 {
770  if (!WithCrypto)
771  return -1;
772 
773  FILE *fp = mutt_file_fopen(tempfile, "w");
774  if (!fp)
775  {
776  mutt_perror(tempfile);
777  return -1;
778  }
779 
780  fseeko(s->fp_in, a->hdr_offset, SEEK_SET);
781  size_t bytes = a->length + a->offset - a->hdr_offset;
782  bool hadcr = false;
783  while (bytes > 0)
784  {
785  const int c = fgetc(s->fp_in);
786  if (c == EOF)
787  break;
788 
789  bytes--;
790 
791  if (c == '\r')
792  hadcr = true;
793  else
794  {
795  if ((c == '\n') && !hadcr)
796  fputc('\r', fp);
797 
798  hadcr = false;
799  }
800 
801  fputc(c, fp);
802  }
803  mutt_file_fclose(&fp);
804 
805  return 0;
806 }
#define mutt_perror(...)
Definition: logging.h:85
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
FILE * fp_in
File to read from.
Definition: state.h:46
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
#define WithCrypto
Definition: ncrypt.h:160
+ 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 812 of file crypt.c.

813 {
814  if (!WithCrypto)
815  return;
816 
817  while (a)
818  {
819  if (a->type == TYPE_MULTIPART)
820  {
821  if (a->encoding != ENC_7BIT)
822  {
823  a->encoding = ENC_7BIT;
825  }
826  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_PgpStrictEnc)
828  }
829  else if ((a->type == TYPE_MESSAGE) &&
830  (mutt_str_strcasecmp(a->subtype, "delivery-status") != 0))
831  {
832  if (a->encoding != ENC_7BIT)
833  mutt_message_to_7bit(a, NULL);
834  }
835  else if (a->encoding == ENC_8BIT)
837  else if (a->encoding == ENC_BINARY)
838  a->encoding = ENC_BASE64;
839  else if (a->content && (a->encoding != ENC_BASE64) &&
840  (a->content->from || (a->content->space && C_PgpStrictEnc)))
841  {
843  }
844  a = a->next;
845  }
846 }
void mutt_message_to_7bit(struct Body *a, FILE *fp)
Convert an email&#39;s MIME parts to 7-bit.
Definition: sendlib.c:1280
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
7-bit text
Definition: mime.h:49
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:812
struct Body * next
next attachment in the list
Definition: body.h:53
8-bit text
Definition: mime.h:50
bool C_PgpStrictEnc
Config: Encode PGP signed messages with quoted-printable (don&#39;t unset)
Definition: crypt.c:73
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
bool from
Has a line beginning with "From "?
Definition: content.h:43
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Binary.
Definition: mime.h:53
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
Quoted-printable text.
Definition: mime.h:51
bool space
Whitespace at the end of lines?
Definition: content.h:41
#define WithCrypto
Definition: ncrypt.h:160
+ 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 855 of file crypt.c.

856 {
857  if (!WithCrypto)
858  return;
859 
860  char tempfname[PATH_MAX];
861 
862  mutt_mktemp(tempfname, sizeof(tempfname));
863  FILE *fp_out = mutt_file_fopen(tempfname, "w");
864  if (!fp_out)
865  {
866  mutt_perror(tempfname);
867  return;
868  }
869 
871  OptDontHandlePgpKeys = true;
872 
873  struct EmailNode *en = NULL;
874  STAILQ_FOREACH(en, el, entries)
875  {
876  struct Email *e = en->email;
877 
880  {
881  mutt_file_fclose(&fp_out);
882  break;
883  }
884 
885  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
886  {
888  fflush(fp_out);
889 
890  mutt_endwin();
891  puts(_("Trying to extract PGP keys...\n"));
892  crypt_pgp_invoke_import(tempfname);
893  }
894 
895  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
896  {
897  if (e->security & SEC_ENCRYPT)
898  {
900  CH_NO_FLAGS);
901  }
902  else
904  fflush(fp_out);
905 
906  char *mbox = NULL;
907  if (!TAILQ_EMPTY(&e->env->from))
908  {
910  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
911  }
912  else if (!TAILQ_EMPTY(&e->env->sender))
913  {
915  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
916  }
917  if (mbox)
918  {
919  mutt_endwin();
920  puts(_("Trying to extract S/MIME certificates..."));
921  crypt_smime_invoke_import(tempfname, mbox);
922  }
923  }
924 
925  rewind(fp_out);
926  }
927 
928  mutt_file_fclose(&fp_out);
929  if (isendwin())
931 
932  mutt_file_unlink(tempfname);
933 
934  if (WithCrypto & APPLICATION_PGP)
935  OptDontHandlePgpKeys = false;
936 }
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:304
The envelope/body of an email.
Definition: email.h:39
#define TAILQ_FIRST(head)
Definition: queue.h:717
#define mutt_perror(...)
Definition: logging.h:85
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:192
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:48
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Copy a message from a Mailbox.
Definition: copy.c:806
#define _(a)
Definition: message.h:28
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:147
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
struct Envelope * env
Envelope information.
Definition: email.h:91
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:34
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:353
#define PATH_MAX
Definition: mutt.h:52
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:532
struct Email * email
Email in the list.
Definition: email.h:122
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
List of Emails.
Definition: email.h:120
void crypt_smime_invoke_import(char *infile, char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
#define TAILQ_EMPTY(head)
Definition: queue.h:715
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 952 of file crypt.c.

953 {
954  if (!WithCrypto)
955  return 0;
956 
957  struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
958  const char *fqdn = mutt_fqdn(true);
959  char *self_encrypt = NULL;
960 
961  /* Do a quick check to make sure that we can find all of the encryption
962  * keys if the user has requested this service. */
963 
964  *keylist = NULL;
965 
966 #ifdef USE_AUTOCRYPT
967  if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
968  {
970  return -1;
971  return 0;
972  }
973 #endif
974 
976  OptPgpCheckTrust = true;
977 
978  mutt_addrlist_copy(&addrlist, &e->env->to, false);
979  mutt_addrlist_copy(&addrlist, &e->env->cc, false);
980  mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
981  mutt_addrlist_qualify(&addrlist, fqdn);
982  mutt_addrlist_dedupe(&addrlist);
983 
984  if (oppenc_mode || (e->security & SEC_ENCRYPT))
985  {
986  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
987  {
988  *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
989  if (!*keylist)
990  {
991  mutt_addrlist_clear(&addrlist);
992  return -1;
993  }
994  OptPgpCheckTrust = false;
996  self_encrypt = C_PgpDefaultKey;
997  }
998  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
999  {
1000  *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
1001  if (!*keylist)
1002  {
1003  mutt_addrlist_clear(&addrlist);
1004  return -1;
1005  }
1007  self_encrypt = C_SmimeDefaultKey;
1008  }
1009  }
1010 
1011  if (!oppenc_mode && self_encrypt)
1012  {
1013  const size_t keylist_size = mutt_str_strlen(*keylist);
1014  mutt_mem_realloc(keylist, keylist_size + mutt_str_strlen(self_encrypt) + 2);
1015  sprintf(*keylist + keylist_size, " %s", self_encrypt);
1016  }
1017 
1018  mutt_addrlist_clear(&addrlist);
1019 
1020  return 0;
1021 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
WHERE char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: globals.h:171
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1381
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:727
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
bool C_PgpSelfEncrypt
Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too.
Definition: crypt.c:72
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1318
unsigned char C_PgpEncryptSelf
Deprecated, see C_PgpSelfEncrypt.
Definition: crypt.c:69
struct Envelope * env
Envelope information.
Definition: email.h:91
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
bool C_SmimeSelfEncrypt
Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too.
Definition: crypt.c:75
Do no use Autocrypt.
Definition: autocrypt.h:104
unsigned char C_SmimeEncryptSelf
Deprecated, see C_SmimeSelfEncrypt.
Definition: crypt.c:74
WHERE bool OptPgpCheckTrust
(pseudo) used by pgp_select_key ()
Definition: options.h:47
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2527
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:640
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:306
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:562
WHERE char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: globals.h:167
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:631
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 1030 of file crypt.c.

1031 {
1032  if (!WithCrypto)
1033  return;
1034 
1036  return;
1037 
1038  char *pgpkeylist = NULL;
1039 
1040  crypt_get_keys(e, &pgpkeylist, 1);
1041  if (pgpkeylist)
1042  {
1043  e->security |= SEC_ENCRYPT;
1044  FREE(&pgpkeylist);
1045  }
1046  else
1047  {
1048  e->security &= ~SEC_ENCRYPT;
1049  }
1050 }
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:952
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:280
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define FREE(x)
Definition: memory.h:40
#define WithCrypto
Definition: ncrypt.h:160
+ 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 1058 of file crypt.c.

1059 {
1060  if (!WithCrypto)
1061  return;
1062 
1063  for (; a; a = a->next)
1064  {
1065  if (a->type == TYPE_MULTIPART)
1066  crypt_fetch_signatures(signatures, a->parts, n);
1067  else
1068  {
1069  if ((*n % 5) == 0)
1070  mutt_mem_realloc(signatures, (*n + 6) * sizeof(struct Body **));
1071 
1072  (*signatures)[(*n)++] = a;
1073  }
1074  }
1075 }
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1058
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define WithCrypto
Definition: ncrypt.h:160
+ 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 1082 of file crypt.c.

1083 {
1086  {
1087  return true;
1088  }
1089 
1090  return false;
1091 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE char * C_CryptProtectedHeadersSubject
Config: Use this as the subject for encrypted emails.
Definition: globals.h:110
WHERE bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: globals.h:283
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
+ 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 1096 of file crypt.c.

1097 {
1099  {
1100  if (a->mime_headers->subject)
1101  {
1102  if ((s->flags & MUTT_DISPLAY) && C_Weed && mutt_matches_ignore("subject"))
1103  return 0;
1104 
1106  mutt_write_one_header(s->fp_out, "Subject", a->mime_headers->subject, s->prefix,
1109  state_puts("\n", s);
1110  }
1111  }
1112 
1113  return 0;
1114 }
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:307
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: globals.h:157
FILE * fp_out
File to write to.
Definition: state.h:47
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:337
void state_mark_protected_header(struct State *s)
Write a unique marker around protected headers.
Definition: state.c:53
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:281
#define state_puts(str, state)
Definition: state.h:54
char * subject
Email&#39;s subject.
Definition: envelope.h:66
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags)
Write one header line to a file.
Definition: sendlib.c:2133
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
+ 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 1119 of file crypt.c.

1120 {
1121  if (!WithCrypto)
1122  return -1;
1123 
1124  bool inconsistent = false;
1125  struct Body *b = a;
1126  struct Body **signatures = NULL;
1127  int sigcnt = 0;
1128  int rc = 0;
1129 
1130  a = a->parts;
1131  SecurityFlags signed_type = mutt_is_multipart_signed(b);
1132  if (signed_type == SEC_NO_FLAGS)
1133  {
1134  /* A null protocol value is already checked for in mutt_body_handler() */
1135  state_printf(s,
1136  _("[-- Error: "
1137  "Unknown multipart/signed protocol %s --]\n\n"),
1138  mutt_param_get(&b->parameter, "protocol"));
1139  return mutt_body_handler(a, s);
1140  }
1141 
1142  if (!(a && a->next))
1143  inconsistent = true;
1144  else
1145  {
1146  switch (signed_type)
1147  {
1148  case SEC_SIGN:
1149  if ((a->next->type != TYPE_MULTIPART) ||
1150  (mutt_str_strcasecmp(a->next->subtype, "mixed") != 0))
1151  {
1152  inconsistent = true;
1153  }
1154  break;
1155  case PGP_SIGN:
1156  if ((a->next->type != TYPE_APPLICATION) ||
1157  (mutt_str_strcasecmp(a->next->subtype, "pgp-signature") != 0))
1158  {
1159  inconsistent = true;
1160  }
1161  break;
1162  case SMIME_SIGN:
1163  if ((a->next->type != TYPE_APPLICATION) ||
1164  ((mutt_str_strcasecmp(a->next->subtype, "x-pkcs7-signature") != 0) &&
1165  (mutt_str_strcasecmp(a->next->subtype, "pkcs7-signature") != 0)))
1166  {
1167  inconsistent = true;
1168  }
1169  break;
1170  default:
1171  inconsistent = true;
1172  }
1173  }
1174  if (inconsistent)
1175  {
1176  state_attach_puts(_("[-- Error: "
1177  "Missing or bad-format multipart/signed signature"
1178  " --]\n\n"),
1179  s);
1180  return mutt_body_handler(a, s);
1181  }
1182 
1183  if (s->flags & MUTT_DISPLAY)
1184  {
1185  crypt_fetch_signatures(&signatures, a->next, &sigcnt);
1186 
1187  if (sigcnt != 0)
1188  {
1189  char tempfile[PATH_MAX];
1190  mutt_mktemp(tempfile, sizeof(tempfile));
1191  bool goodsig = true;
1192  if (crypt_write_signed(a, s, tempfile) == 0)
1193  {
1194  for (int i = 0; i < sigcnt; i++)
1195  {
1196  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1197  (signatures[i]->type == TYPE_APPLICATION) &&
1198  (mutt_str_strcasecmp(signatures[i]->subtype, "pgp-signature") == 0))
1199  {
1200  if (crypt_pgp_verify_one(signatures[i], s, tempfile) != 0)
1201  goodsig = false;
1202 
1203  continue;
1204  }
1205 
1206  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
1207  (signatures[i]->type == TYPE_APPLICATION) &&
1208  ((mutt_str_strcasecmp(signatures[i]->subtype,
1209  "x-pkcs7-signature") == 0) ||
1210  (mutt_str_strcasecmp(signatures[i]->subtype,
1211  "pkcs7-signature") == 0)))
1212  {
1213  if (crypt_smime_verify_one(signatures[i], s, tempfile) != 0)
1214  goodsig = false;
1215 
1216  continue;
1217  }
1218 
1219  state_printf(s,
1220  _("[-- Warning: "
1221  "We can't verify %s/%s signatures. --]\n\n"),
1222  TYPE(signatures[i]), signatures[i]->subtype);
1223  }
1224  }
1225 
1226  mutt_file_unlink(tempfile);
1227 
1228  b->goodsig = goodsig;
1229  b->badsig = !goodsig;
1230 
1231  /* Now display the signed body */
1232  state_attach_puts(_("[-- The following data is signed --]\n\n"), s);
1233 
1235 
1236  FREE(&signatures);
1237  }
1238  else
1239  state_attach_puts(_("[-- Warning: Can't find any signatures. --]\n\n"), s);
1240  }
1241 
1242  rc = mutt_body_handler(a, s);
1243 
1244  if ((s->flags & MUTT_DISPLAY) && (sigcnt != 0))
1245  state_attach_puts(_("\n[-- End of signed data --]\n"), s);
1246 
1247  return rc;
1248 }
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1096
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:192
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
#define SMIME_SIGN
Definition: ncrypt.h:147
int crypt_write_signed(struct Body *a, struct State *s, const char *tempfile)
Write the message body/part.
Definition: crypt.c:768
void state_attach_puts(const char *t, struct State *s)
Write a string to the state.
Definition: state.c:64
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:83
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:412
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
bool goodsig
Good cryptographic signature.
Definition: body.h:81
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
#define PATH_MAX
Definition: mutt.h:52
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1058
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define TYPE(body)
Definition: mime.h:83
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:517
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1545
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:362
+ 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 1264 of file crypt.c.

1266 {
1267  const char *ps = NULL, *pl = NULL, *phint = NULL;
1268  char *pfcopy = NULL, *s1 = NULL, *s2 = NULL;
1269  char c;
1270  int isid;
1271  size_t hexdigits;
1272 
1273  /* User input may be partial name, fingerprint or short or long key ID,
1274  * independent of C_PgpLongIds.
1275  * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1276  * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1277  * if an ID was found and to simplify logic in the key loop's inner
1278  * condition of the caller. */
1279 
1280  char *pf = mutt_str_skip_whitespace(p);
1281  if (mutt_str_startswith(pf, "0x", CASE_IGNORE))
1282  pf += 2;
1283 
1284  /* Check if a fingerprint is given, must be hex digits only, blanks
1285  * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1286  isid = 2; /* unknown */
1287  hexdigits = 0;
1288  s1 = pf;
1289  do
1290  {
1291  c = *(s1++);
1292  if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1293  (('a' <= c) && (c <= 'f')))
1294  {
1295  hexdigits++;
1296  if (isid == 2)
1297  isid = 1; /* it is an ID so far */
1298  }
1299  else if (c)
1300  {
1301  isid = 0; /* not an ID */
1302  if ((c == ' ') && ((hexdigits % 4) == 0))
1303  ; /* skip blank before or after 4 hex digits */
1304  else
1305  break; /* any other character or position */
1306  }
1307  } while (c);
1308 
1309  /* If at end of input, check for correct fingerprint length and copy if. */
1310  pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_strdup(pf) : NULL);
1311 
1312  if (pfcopy)
1313  {
1314  /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1315  s1 = pfcopy;
1316  s2 = pfcopy;
1317  do
1318  {
1319  *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1320  } while (*(s2++));
1321 
1322  phint = pfcopy;
1323  ps = NULL;
1324  pl = NULL;
1325  }
1326  else
1327  {
1328  phint = p;
1329  ps = NULL;
1330  pl = NULL;
1331  if (isid == 1)
1332  {
1333  if (mutt_str_strlen(pf) == 16)
1334  pl = pf; /* long key ID */
1335  else if (mutt_str_strlen(pf) == 8)
1336  ps = pf; /* short key ID */
1337  }
1338  }
1339 
1340  *pphint = phint;
1341  *ppl = pl;
1342  *pps = ps;
1343  return pfcopy;
1344 }
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition: string.c:720
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
Ignore case when comparing strings.
Definition: string2.h:68
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ 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 1353 of file crypt.c.

1354 {
1355  /* or should we require the "0x"? */
1356  if (strncmp(s, "0x", 2) == 0)
1357  s += 2;
1358  if (strlen(s) % 8)
1359  return false;
1360  while (*s)
1361  if (!strchr("0123456789ABCDEFabcdef", *s++))
1362  return false;
1363 
1364  return true;
1365 }
+ Here is the caller graph for this function:

Variable Documentation

◆ C_CryptTimestamp

bool C_CryptTimestamp

Config: Add a timestamp to PGP or SMIME output to prevent spoofing.

Definition at line 65 of file crypt.c.

◆ C_PgpEncryptSelf

unsigned char C_PgpEncryptSelf

Deprecated, see C_PgpSelfEncrypt.

Definition at line 69 of file crypt.c.

◆ C_PgpMimeAuto

unsigned char C_PgpMimeAuto

Config: Prompt the user to use MIME if inline PGP fails.

Definition at line 70 of file crypt.c.

◆ C_PgpRetainableSigs

bool C_PgpRetainableSigs

Config: Create nested multipart/signed or encrypted messages.

Definition at line 71 of file crypt.c.

◆ C_PgpSelfEncrypt

bool C_PgpSelfEncrypt

Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too.

Definition at line 72 of file crypt.c.

◆ C_PgpStrictEnc

bool C_PgpStrictEnc

Config: Encode PGP signed messages with quoted-printable (don't unset)

Definition at line 73 of file crypt.c.

◆ C_SmimeEncryptSelf

unsigned char C_SmimeEncryptSelf

Deprecated, see C_SmimeSelfEncrypt.

Definition at line 74 of file crypt.c.

◆ C_SmimeSelfEncrypt

bool C_SmimeSelfEncrypt

Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too.

Definition at line 75 of file crypt.c.