NeoMutt  2020-09-25
Teaching an old dog new tricks
DOXYGEN
smime.h File Reference

SMIME helper routines. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "lib.h"
+ Include dependency graph for smime.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SmimeKey
 An SIME key. More...
 

Functions

void smime_init (void)
 Initialise smime globals. More...
 
void smime_cleanup (void)
 Clean up smime globals. More...
 
int smime_class_application_handler (struct Body *m, struct State *s)
 Implements CryptModuleSpecs::application_handler() More...
 
struct Bodysmime_class_build_smime_entity (struct Body *a, char *certlist)
 Implements CryptModuleSpecs::smime_build_smime_entity() More...
 
int smime_class_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() More...
 
char * smime_class_find_keys (struct AddressList *addrlist, bool oppenc_mode)
 Implements CryptModuleSpecs::find_keys() More...
 
void smime_class_getkeys (struct Envelope *env)
 Implements CryptModuleSpecs::smime_getkeys() More...
 
void smime_class_invoke_import (const char *infile, const char *mailbox)
 Implements CryptModuleSpecs::smime_invoke_import() More...
 
int smime_class_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() More...
 
struct Bodysmime_class_sign_message (struct Body *a, const struct AddressList *from)
 Implements CryptModuleSpecs::sign_message() More...
 
bool smime_class_valid_passphrase (void)
 Implements CryptModuleSpecs::valid_passphrase() More...
 
int smime_class_verify_one (struct Body *sigbdy, struct State *s, const char *tempfile)
 Implements CryptModuleSpecs::verify_one() More...
 
int smime_class_verify_sender (struct Mailbox *m, struct Email *e)
 Implements CryptModuleSpecs::smime_verify_sender() More...
 
void smime_class_void_passphrase (void)
 Implements CryptModuleSpecs::void_passphrase() More...
 

Detailed Description

SMIME helper routines.

Authors
  • Oliver Ehli
  • g10 Code 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 smime.h.

Function Documentation

◆ smime_init()

void smime_init ( void  )

Initialise smime globals.

Definition at line 87 of file smime.c.

88 {
92 }
static struct Buffer SmimeKeyToUse
Definition: smime.c:80
static struct Buffer SmimeIntermediateToUse
Definition: smime.c:82
static struct Buffer SmimeCertToUse
Definition: smime.c:81
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smime_cleanup()

void smime_cleanup ( void  )

Clean up smime globals.

Definition at line 97 of file smime.c.

98 {
102 }
static struct Buffer SmimeKeyToUse
Definition: smime.c:80
static struct Buffer SmimeIntermediateToUse
Definition: smime.c:82
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
static struct Buffer SmimeCertToUse
Definition: smime.c:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smime_class_application_handler()

int smime_class_application_handler ( struct Body m,
struct State s 
)

Implements CryptModuleSpecs::application_handler()

Definition at line 2081 of file smime.c.

2082 {
2083  int rc = -1;
2084 
2085  /* clear out any mime headers before the handler, so they can't be spoofed. */
2087 
2088  struct Body *tattach = smime_handle_entity(m, s, NULL);
2089  if (tattach)
2090  {
2091  rc = 0;
2092  mutt_body_free(&tattach);
2093  }
2094  return rc;
2095 }
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
static struct Body * smime_handle_entity(struct Body *m, struct State *s, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition: smime.c:1788
The body of an email.
Definition: body.h:34
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
+ Here is the call graph for this function:

◆ smime_class_build_smime_entity()

struct Body* smime_class_build_smime_entity ( struct Body a,
char *  certlist 
)

Implements CryptModuleSpecs::smime_build_smime_entity()

Definition at line 1311 of file smime.c.

1312 {
1313  char buf[1024], certfile[PATH_MAX];
1314  char *cert_end = NULL;
1315  FILE *fp_smime_in = NULL, *fp_smime_err = NULL, *fp_out = NULL, *fp_tmp = NULL;
1316  struct Body *t = NULL;
1317  int err = 0, empty, off;
1318  pid_t pid;
1319 
1320  struct Buffer *tempfile = mutt_buffer_pool_get();
1321  struct Buffer *smime_infile = mutt_buffer_pool_get();
1322 
1323  mutt_buffer_mktemp(tempfile);
1324  fp_out = mutt_file_fopen(mutt_b2s(tempfile), "w+");
1325  if (!fp_out)
1326  {
1327  mutt_perror(mutt_b2s(tempfile));
1328  goto cleanup;
1329  }
1330 
1331  fp_smime_err = mutt_file_mkstemp();
1332  if (!fp_smime_err)
1333  {
1334  mutt_perror(_("Can't create temporary file"));
1335  goto cleanup;
1336  }
1337 
1338  mutt_buffer_mktemp(smime_infile);
1339  fp_tmp = mutt_file_fopen(mutt_b2s(smime_infile), "w+");
1340  if (!fp_tmp)
1341  {
1342  mutt_perror(mutt_b2s(smime_infile));
1343  goto cleanup;
1344  }
1345 
1346  *certfile = '\0';
1347  for (char *cert_start = certlist; cert_start; cert_start = cert_end)
1348  {
1349  cert_end = strchr(cert_start, ' ');
1350  if (cert_end)
1351  *cert_end = '\0';
1352  if (*cert_start)
1353  {
1354  off = mutt_str_len(certfile);
1355  snprintf(certfile + off, sizeof(certfile) - off, "%s%s/%s",
1356  (off != 0) ? " " : "", NONULL(C_SmimeCertificates), cert_start);
1357  }
1358  if (cert_end)
1359  *cert_end++ = ' ';
1360  }
1361 
1362  /* write a MIME entity */
1363  mutt_write_mime_header(a, fp_tmp, NeoMutt->sub);
1364  fputc('\n', fp_tmp);
1365  mutt_write_mime_body(a, fp_tmp, NeoMutt->sub);
1366  mutt_file_fclose(&fp_tmp);
1367 
1368  pid = smime_invoke_encrypt(&fp_smime_in, NULL, NULL, -1, fileno(fp_out),
1369  fileno(fp_smime_err), mutt_b2s(smime_infile), certfile);
1370  if (pid == -1)
1371  {
1372  mutt_file_unlink(mutt_b2s(smime_infile));
1373  goto cleanup;
1374  }
1375 
1376  mutt_file_fclose(&fp_smime_in);
1377 
1378  filter_wait(pid);
1379  mutt_file_unlink(mutt_b2s(smime_infile));
1380 
1381  fflush(fp_out);
1382  rewind(fp_out);
1383  empty = (fgetc(fp_out) == EOF);
1384  mutt_file_fclose(&fp_out);
1385 
1386  fflush(fp_smime_err);
1387  rewind(fp_smime_err);
1388  while (fgets(buf, sizeof(buf) - 1, fp_smime_err))
1389  {
1390  err = 1;
1391  fputs(buf, stdout);
1392  }
1393  mutt_file_fclose(&fp_smime_err);
1394 
1395  /* pause if there is any error output from SMIME */
1396  if (err)
1398 
1399  if (empty)
1400  {
1401  /* fatal error while trying to encrypt message */
1402  if (err == 0)
1403  mutt_any_key_to_continue(_("No output from OpenSSL..."));
1404  mutt_file_unlink(mutt_b2s(tempfile));
1405  goto cleanup;
1406  }
1407 
1408  t = mutt_body_new();
1409  t->type = TYPE_APPLICATION;
1410  t->subtype = mutt_str_dup("x-pkcs7-mime");
1411  mutt_param_set(&t->parameter, "name", "smime.p7m");
1412  mutt_param_set(&t->parameter, "smime-type", "enveloped-data");
1413  t->encoding = ENC_BASE64; /* The output of OpenSSL SHOULD be binary */
1414  t->use_disp = true;
1415  t->disposition = DISP_ATTACH;
1416  t->d_filename = mutt_str_dup("smime.p7m");
1417  t->filename = mutt_buffer_strdup(tempfile);
1418  t->unlink = true; /* delete after sending the message */
1419  t->parts = NULL;
1420  t->next = NULL;
1421 
1422 cleanup:
1423  if (fp_out)
1424  {
1425  mutt_file_fclose(&fp_out);
1426  mutt_file_unlink(mutt_b2s(tempfile));
1427  }
1428  mutt_file_fclose(&fp_smime_err);
1429  if (fp_tmp)
1430  {
1431  mutt_file_fclose(&fp_tmp);
1432  mutt_file_unlink(mutt_b2s(smime_infile));
1433  }
1434  mutt_buffer_pool_release(&tempfile);
1435  mutt_buffer_pool_release(&smime_infile);
1436 
1437  return t;
1438 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
int mutt_write_mime_body(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition: body.c:314
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
Container for Accounts, Notifications.
Definition: neomutt.h:36
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:67
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
Content is attached.
Definition: mime.h:63
int mutt_write_mime_header(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition: header.c:760
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
static pid_t smime_invoke_encrypt(FILE **fp_smime_in, FILE **fp_smime_out, FILE **fp_smime_err, int fp_smime_infd, int fp_smime_outfd, int fp_smime_errfd, const char *fname, const char *uids)
Use SMIME to encrypt a file.
Definition: smime.c:1273
#define PATH_MAX
Definition: mutt.h:44
char * C_SmimeCertificates
Config: File containing user&#39;s public certificates.
Definition: config.c:107
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:106
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
+ Here is the call graph for this function:

◆ smime_class_decrypt_mime()

int smime_class_decrypt_mime ( FILE *  fp_in,
FILE **  fp_out,
struct Body b,
struct Body **  cur 
)

Implements CryptModuleSpecs::decrypt_mime()

Definition at line 2019 of file smime.c.

2020 {
2021  struct State s = { 0 };
2022  LOFF_T tmpoffset = b->offset;
2023  size_t tmplength = b->length;
2024  int orig_type = b->type;
2025  int rc = -1;
2026 
2027  if (!mutt_is_application_smime(b))
2028  return -1;
2029 
2030  if (b->parts)
2031  return -1;
2032 
2033  s.fp_in = fp_in;
2034  fseeko(s.fp_in, b->offset, SEEK_SET);
2035 
2036  FILE *fp_tmp = mutt_file_mkstemp();
2037  if (!fp_tmp)
2038  {
2039  mutt_perror(_("Can't create temporary file"));
2040  return -1;
2041  }
2042 
2043  s.fp_out = fp_tmp;
2044  mutt_decode_attachment(b, &s);
2045  fflush(fp_tmp);
2046  b->length = ftello(s.fp_out);
2047  b->offset = 0;
2048  rewind(fp_tmp);
2049  s.fp_in = fp_tmp;
2050  s.fp_out = 0;
2051 
2053  if (!*fp_out)
2054  {
2055  mutt_perror(_("Can't create temporary file"));
2056  goto bail;
2057  }
2058 
2059  *cur = smime_handle_entity(b, &s, *fp_out);
2060  if (!*cur)
2061  goto bail;
2062 
2063  (*cur)->goodsig = b->goodsig;
2064  (*cur)->badsig = b->badsig;
2065  rc = 0;
2066 
2067 bail:
2068  b->type = orig_type;
2069  b->length = tmplength;
2070  b->offset = tmpoffset;
2071  mutt_file_fclose(&fp_tmp);
2072  if (*fp_out)
2073  rewind(*fp_out);
2074 
2075  return rc;
2076 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1843
#define mutt_perror(...)
Definition: logging.h:85
static struct Body * smime_handle_entity(struct Body *m, struct State *s, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition: smime.c:1788
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
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:153
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:77
bool goodsig
Good cryptographic signature.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_file_mkstemp()
Definition: file.h:106
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:610
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Keep track when processing files.
Definition: state.h:44
+ Here is the call graph for this function:

◆ smime_class_find_keys()

char* smime_class_find_keys ( struct AddressList *  addrlist,
bool  oppenc_mode 
)

Implements CryptModuleSpecs::find_keys()

Definition at line 800 of file smime.c.

801 {
802  struct SmimeKey *key = NULL;
803  char *keyid = NULL, *keylist = NULL;
804  size_t keylist_size = 0;
805  size_t keylist_used = 0;
806 
807  struct Address *a = NULL;
808  TAILQ_FOREACH(a, al, entries)
809  {
810  key = smime_get_key_by_addr(a->mailbox, KEYFLAG_CANENCRYPT, true, oppenc_mode);
811  if (!key && !oppenc_mode)
812  {
813  char buf[1024];
814  snprintf(buf, sizeof(buf), _("Enter keyID for %s: "), a->mailbox);
815  key = smime_ask_for_key(buf, KEYFLAG_CANENCRYPT, true);
816  }
817  if (!key)
818  {
819  if (!oppenc_mode)
820  mutt_message(_("No (valid) certificate found for %s"), a->mailbox);
821  FREE(&keylist);
822  return NULL;
823  }
824 
825  keyid = key->hash;
826  keylist_size += mutt_str_len(keyid) + 2;
827  mutt_mem_realloc(&keylist, keylist_size);
828  sprintf(keylist + keylist_used, "%s%s", keylist_used ? " " : "", keyid);
829  keylist_used = mutt_str_len(keylist);
830 
831  smime_key_free(&key);
832  }
833  return keylist;
834 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
An SIME key.
Definition: smime.h:43
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
Definition: lib.h:135
static void smime_key_free(struct SmimeKey **keylist)
Free a list of SMIME keys.
Definition: smime.c:108
static struct SmimeKey * smime_ask_for_key(char *prompt, KeyFlags abilities, bool only_public_key)
Ask the user to select a key.
Definition: smime.c:701
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
char * hash
Definition: smime.h:46
#define FREE(x)
Definition: memory.h:40
static struct SmimeKey * smime_get_key_by_addr(char *mailbox, KeyFlags abilities, bool only_public_key, bool oppenc_mode)
Find an SIME key by address.
Definition: smime.c:576
+ Here is the call graph for this function:

◆ smime_class_getkeys()

void smime_class_getkeys ( struct Envelope env)

Implements CryptModuleSpecs::smime_getkeys()

Definition at line 764 of file smime.c.

765 {
767  {
770  return;
771  }
772 
773  struct Address *a = NULL;
774  TAILQ_FOREACH(a, &env->to, entries)
775  {
776  if (mutt_addr_is_user(a))
777  {
778  getkeys(a->mailbox);
779  return;
780  }
781  }
782 
783  TAILQ_FOREACH(a, &env->cc, entries)
784  {
785  if (mutt_addr_is_user(a))
786  {
787  getkeys(a->mailbox);
788  return;
789  }
790  }
791 
792  struct Address *f = mutt_default_from(NeoMutt->sub);
793  getkeys(f->mailbox);
794  mutt_addr_free(&f);
795 }
static struct Buffer SmimeKeyToUse
Definition: smime.c:80
#define NONULL(x)
Definition: string2.h:37
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * C_SmimeKeys
Config: File containing user&#39;s private certificates.
Definition: config.c:115
static void getkeys(char *mailbox)
Get the keys for a mailbox.
Definition: smime.c:732
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
static struct Buffer SmimeCertToUse
Definition: smime.c:81
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default &#39;from&#39; Address.
Definition: send.c:1323
char * C_SmimeCertificates
Config: File containing user&#39;s public certificates.
Definition: config.c:107
char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: config.c:69
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:544
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool C_SmimeDecryptUseDefaultKey
Config: Use the default key for decryption.
Definition: config.c:109
+ Here is the call graph for this function:

◆ smime_class_invoke_import()

void smime_class_invoke_import ( const char *  infile,
const char *  mailbox 
)

Implements CryptModuleSpecs::smime_invoke_import()

Definition at line 1120 of file smime.c.

1121 {
1122  char *certfile = NULL;
1123  char buf[256];
1124  FILE *fp_smime_in = NULL;
1125 
1126  FILE *fp_err = mutt_file_mkstemp();
1127  if (!fp_err)
1128  {
1129  mutt_perror(_("Can't create temporary file"));
1130  return;
1131  }
1132 
1133  FILE *fp_out = mutt_file_mkstemp();
1134  if (!fp_out)
1135  {
1136  mutt_file_fclose(&fp_err);
1137  mutt_perror(_("Can't create temporary file"));
1138  return;
1139  }
1140 
1141  buf[0] = '\0';
1142  if (C_SmimeAskCertLabel)
1143  {
1144  if ((mutt_get_field(_("Label for certificate: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0) ||
1145  (buf[0] == '\0'))
1146  {
1147  mutt_file_fclose(&fp_out);
1148  mutt_file_fclose(&fp_err);
1149  return;
1150  }
1151  }
1152 
1153  mutt_endwin();
1154  certfile = smime_extract_certificate(infile);
1155  if (certfile)
1156  {
1157  mutt_endwin();
1158 
1159  pid_t pid = smime_invoke(&fp_smime_in, NULL, NULL, -1, fileno(fp_out),
1160  fileno(fp_err), certfile, NULL, NULL, NULL, NULL,
1161  NULL, NULL, C_SmimeImportCertCommand);
1162  if (pid == -1)
1163  {
1164  mutt_message(_("Error: unable to create OpenSSL subprocess"));
1165  return;
1166  }
1167  fputs(buf, fp_smime_in);
1168  fputc('\n', fp_smime_in);
1169  mutt_file_fclose(&fp_smime_in);
1170 
1171  filter_wait(pid);
1172 
1173  mutt_file_unlink(certfile);
1174  FREE(&certfile);
1175  }
1176 
1177  fflush(fp_out);
1178  rewind(fp_out);
1179  fflush(fp_err);
1180  rewind(fp_err);
1181 
1182  mutt_file_copy_stream(fp_out, stdout);
1183  mutt_file_copy_stream(fp_err, stdout);
1184 
1185  mutt_file_fclose(&fp_out);
1186  mutt_file_fclose(&fp_err);
1187 }
#define mutt_perror(...)
Definition: logging.h:85
#define mutt_message(...)
Definition: logging.h:83
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:571
bool C_SmimeAskCertLabel
Config: Prompt the user for a label for SMIME certificates.
Definition: config.c:105
char * C_SmimeImportCertCommand
Config: (smime) External command to import a certificate.
Definition: config.c:114
#define mutt_file_mkstemp()
Definition: file.h:106
static pid_t smime_invoke(FILE **fp_smime_in, FILE **fp_smime_out, FILE **fp_smime_err, int fp_smime_infd, int fp_smime_outfd, int fp_smime_errfd, const char *fname, const char *sig_fname, const char *cryptalg, const char *digestalg, const char *key, const char *certificates, const char *intermediates, const char *format)
Run an SMIME command.
Definition: smime.c:389
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
#define FREE(x)
Definition: memory.h:40
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
static char * smime_extract_certificate(const char *infile)
Extract an SMIME certificate from a file.
Definition: smime.c:941
+ Here is the call graph for this function:

◆ smime_class_send_menu()

int smime_class_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu()

Definition at line 2100 of file smime.c.

2101 {
2102  struct SmimeKey *key = NULL;
2103  const char *prompt = NULL;
2104  const char *letters = NULL;
2105  const char *choices = NULL;
2106  int choice;
2107 
2108  if (!(WithCrypto & APPLICATION_SMIME))
2109  return e->security;
2110 
2112 
2113  /* Opportunistic encrypt is controlling encryption.
2114  * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
2115  * letter choices for those. */
2117  {
2118  /* L10N: S/MIME options (opportunistic encryption is on) */
2119  prompt = _("S/MIME (s)ign, encrypt (w)ith, sign (a)s, (c)lear, or (o)ppenc "
2120  "mode off?");
2121  /* L10N: S/MIME options (opportunistic encryption is on) */
2122  letters = _("swaco");
2123  choices = "SwaCo";
2124  }
2125  /* Opportunistic encryption option is set, but is toggled off
2126  * for this message. */
2127  else if (C_CryptOpportunisticEncrypt)
2128  {
2129  /* L10N: S/MIME options (opportunistic encryption is off) */
2130  prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, "
2131  "(c)lear, or (o)ppenc mode?");
2132  /* L10N: S/MIME options (opportunistic encryption is off) */
2133  letters = _("eswabco");
2134  choices = "eswabcO";
2135  }
2136  /* Opportunistic encryption is unset */
2137  else
2138  {
2139  /* L10N: S/MIME options */
2140  prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, "
2141  "or (c)lear?");
2142  /* L10N: S/MIME options */
2143  letters = _("eswabc");
2144  choices = "eswabc";
2145  }
2146 
2147  choice = mutt_multi_choice(prompt, letters);
2148  if (choice > 0)
2149  {
2150  switch (choices[choice - 1])
2151  {
2152  case 'a': /* sign (a)s */
2153  key = smime_ask_for_key(_("Sign as: "), KEYFLAG_CANSIGN, false);
2154  if (key)
2155  {
2157  smime_key_free(&key);
2158 
2159  e->security |= SEC_SIGN;
2160 
2161  /* probably need a different passphrase */
2163  }
2164 
2165  break;
2166 
2167  case 'b': /* (b)oth */
2168  e->security |= (SEC_ENCRYPT | SEC_SIGN);
2169  break;
2170 
2171  case 'c': /* (c)lear */
2172  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2173  break;
2174 
2175  case 'C':
2176  e->security &= ~SEC_SIGN;
2177  break;
2178 
2179  case 'e': /* (e)ncrypt */
2180  e->security |= SEC_ENCRYPT;
2181  e->security &= ~SEC_SIGN;
2182  break;
2183 
2184  case 'O': /* oppenc mode on */
2185  e->security |= SEC_OPPENCRYPT;
2187  break;
2188 
2189  case 'o': /* oppenc mode off */
2190  e->security &= ~SEC_OPPENCRYPT;
2191  break;
2192 
2193  case 'S': /* (s)ign in oppenc mode */
2194  e->security |= SEC_SIGN;
2195  break;
2196 
2197  case 's': /* (s)ign */
2198  e->security &= ~SEC_ENCRYPT;
2199  e->security |= SEC_SIGN;
2200  break;
2201 
2202  case 'w': /* encrypt (w)ith */
2203  {
2204  e->security |= SEC_ENCRYPT;
2205  do
2206  {
2207  struct Buffer errmsg = mutt_buffer_make(0);
2208  int rc = CSR_SUCCESS;
2209  switch (mutt_multi_choice(_("Choose algorithm family: (1) DES, (2) "
2210  "RC2, (3) AES, or (c)lear?"),
2211  // L10N: Options for: Choose algorithm family: (1) DES, (2) RC2, (3) AES, or (c)lear?
2212  _("123c")))
2213  {
2214  case 1:
2215  switch (choice = mutt_multi_choice(_("(1) DES, (2) Triple-DES?"),
2216  // L10N: Options for: (1) DES, (2) Triple-DES
2217  _("12")))
2218  {
2219  case 1:
2220  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2221  "des", &errmsg);
2222  break;
2223  case 2:
2224  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2225  "des3", &errmsg);
2226  break;
2227  }
2228  break;
2229 
2230  case 2:
2231  switch (choice = mutt_multi_choice(
2232  _("(1) RC2-40, (2) RC2-64, (3) RC2-128?"),
2233  // L10N: Options for: (1) RC2-40, (2) RC2-64, (3) RC2-128
2234  _("123")))
2235  {
2236  case 1:
2237  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2238  "rc2-40", &errmsg);
2239  break;
2240  case 2:
2241  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2242  "rc2-64", &errmsg);
2243  break;
2244  case 3:
2245  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2246  "rc2-128", &errmsg);
2247  break;
2248  }
2249  break;
2250 
2251  case 3:
2252  switch (choice = mutt_multi_choice(
2253  _("(1) AES128, (2) AES192, (3) AES256?"),
2254  // L10N: Options for: (1) AES128, (2) AES192, (3) AES256
2255  _("123")))
2256  {
2257  case 1:
2258  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2259  "aes128", &errmsg);
2260  break;
2261  case 2:
2262  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2263  "aes192", &errmsg);
2264  break;
2265  case 3:
2266  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2267  "aes256", &errmsg);
2268  break;
2269  }
2270  break;
2271 
2272  case 4:
2273  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2274  NULL, &errmsg);
2275  /* (c)lear */
2276  /* fallthrough */
2277  case -1: /* Ctrl-G or Enter */
2278  choice = 0;
2279  break;
2280  }
2281 
2282  if ((CSR_RESULT(rc) != CSR_SUCCESS) && !mutt_buffer_is_empty(&errmsg))
2283  mutt_error("%s", mutt_b2s(&errmsg));
2284 
2285  mutt_buffer_dealloc(&errmsg);
2286  } while (choice == -1);
2287  break;
2288  }
2289  }
2290  }
2291 
2292  return e->security;
2293 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define WithCrypto
Definition: lib.h:123
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
An SIME key.
Definition: smime.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CSR_RESULT(x)
Definition: set.h:52
static void smime_key_free(struct SmimeKey **keylist)
Free a list of SMIME keys.
Definition: smime.c:108
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:395
bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: config.c:56
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:411
static struct SmimeKey * smime_ask_for_key(char *prompt, KeyFlags abilities, bool only_public_key)
Ask the user to select a key.
Definition: smime.c:701
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:933
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:134
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:93
char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: config.c:70
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1021
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
#define mutt_error(...)
Definition: logging.h:84
char * hash
Definition: smime.h:46
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
+ Here is the call graph for this function:

◆ smime_class_sign_message()

struct Body* smime_class_sign_message ( struct Body a,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::sign_message()

Definition at line 1475 of file smime.c.

1476 {
1477  struct Body *t = NULL;
1478  struct Body *retval = NULL;
1479  char buf[1024];
1480  struct Buffer *filetosign = NULL, *signedfile = NULL;
1481  FILE *fp_smime_in = NULL, *fp_smime_out = NULL, *fp_smime_err = NULL, *fp_sign = NULL;
1482  int err = 0;
1483  int empty = 0;
1484  pid_t pid;
1485  char *intermediates = NULL;
1486 
1487  char *signas = C_SmimeSignAs ? C_SmimeSignAs : C_SmimeDefaultKey;
1488  if (!signas || (*signas == '\0'))
1489  {
1490  mutt_error(_("Can't sign: No key specified. Use Sign As."));
1491  return NULL;
1492  }
1493 
1494  crypt_convert_to_7bit(a); /* Signed data _must_ be in 7-bit format. */
1495 
1496  filetosign = mutt_buffer_pool_get();
1497  signedfile = mutt_buffer_pool_get();
1498 
1499  mutt_buffer_mktemp(filetosign);
1500  fp_sign = mutt_file_fopen(mutt_b2s(filetosign), "w+");
1501  if (!fp_sign)
1502  {
1503  mutt_perror(mutt_b2s(filetosign));
1504  goto cleanup;
1505  }
1506 
1507  mutt_buffer_mktemp(signedfile);
1508  fp_smime_out = mutt_file_fopen(mutt_b2s(signedfile), "w+");
1509  if (!fp_smime_out)
1510  {
1511  mutt_perror(mutt_b2s(signedfile));
1512  goto cleanup;
1513  }
1514 
1515  mutt_write_mime_header(a, fp_sign, NeoMutt->sub);
1516  fputc('\n', fp_sign);
1517  mutt_write_mime_body(a, fp_sign, NeoMutt->sub);
1518  mutt_file_fclose(&fp_sign);
1519 
1520  mutt_buffer_printf(&SmimeKeyToUse, "%s/%s", NONULL(C_SmimeKeys), signas);
1522 
1523  struct SmimeKey *signas_key = smime_get_key_by_hash(signas, 1);
1524  if (!signas_key || mutt_str_equal("?", signas_key->issuer))
1525  intermediates = signas; /* so openssl won't complain in any case */
1526  else
1527  intermediates = signas_key->issuer;
1528 
1530  NONULL(C_SmimeCertificates), intermediates);
1531 
1532  smime_key_free(&signas_key);
1533 
1534  pid = smime_invoke_sign(&fp_smime_in, NULL, &fp_smime_err, -1,
1535  fileno(fp_smime_out), -1, mutt_b2s(filetosign));
1536  if (pid == -1)
1537  {
1538  mutt_perror(_("Can't open OpenSSL subprocess"));
1539  mutt_file_unlink(mutt_b2s(filetosign));
1540  goto cleanup;
1541  }
1542  fputs(SmimePass, fp_smime_in);
1543  fputc('\n', fp_smime_in);
1544  mutt_file_fclose(&fp_smime_in);
1545 
1546  filter_wait(pid);
1547 
1548  /* check for errors from OpenSSL */
1549  err = 0;
1550  fflush(fp_smime_err);
1551  rewind(fp_smime_err);
1552  while (fgets(buf, sizeof(buf) - 1, fp_smime_err))
1553  {
1554  err = 1;
1555  fputs(buf, stdout);
1556  }
1557  mutt_file_fclose(&fp_smime_err);
1558 
1559  fflush(fp_smime_out);
1560  rewind(fp_smime_out);
1561  empty = (fgetc(fp_smime_out) == EOF);
1562  mutt_file_fclose(&fp_smime_out);
1563 
1564  mutt_file_unlink(mutt_b2s(filetosign));
1565 
1566  if (err)
1568 
1569  if (empty)
1570  {
1571  mutt_any_key_to_continue(_("No output from OpenSSL..."));
1572  mutt_file_unlink(mutt_b2s(signedfile));
1573  goto cleanup; /* fatal error while signing */
1574  }
1575 
1576  t = mutt_body_new();
1577  t->type = TYPE_MULTIPART;
1578  t->subtype = mutt_str_dup("signed");
1579  t->encoding = ENC_7BIT;
1580  t->use_disp = false;
1581  t->disposition = DISP_INLINE;
1582 
1584 
1586  mutt_param_set(&t->parameter, "micalg", micalg);
1587  FREE(&micalg);
1588 
1589  mutt_param_set(&t->parameter, "protocol", "application/x-pkcs7-signature");
1590 
1591  t->parts = a;
1592  retval = t;
1593 
1594  t->parts->next = mutt_body_new();
1595  t = t->parts->next;
1596  t->type = TYPE_APPLICATION;
1597  t->subtype = mutt_str_dup("x-pkcs7-signature");
1598  t->filename = mutt_buffer_strdup(signedfile);
1599  t->d_filename = mutt_str_dup("smime.p7s");
1600  t->use_disp = true;
1601  t->disposition = DISP_ATTACH;
1602  t->encoding = ENC_BASE64;
1603  t->unlink = true; /* ok to remove this file after sending. */
1604 
1605 cleanup:
1606  if (fp_sign)
1607  {
1608  mutt_file_fclose(&fp_sign);
1609  mutt_file_unlink(mutt_b2s(filetosign));
1610  }
1611  if (fp_smime_out)
1612  {
1613  mutt_file_fclose(&fp_smime_out);
1614  mutt_file_unlink(mutt_b2s(signedfile));
1615  }
1616  mutt_buffer_pool_release(&filetosign);
1617  mutt_buffer_pool_release(&signedfile);
1618  return retval;
1619 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
static struct Buffer SmimeKeyToUse
Definition: smime.c:80
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
7-bit text
Definition: mime.h:49
int mutt_write_mime_body(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition: body.c:314
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:801
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
static char * openssl_md_to_smime_micalg(char *md)
Change the algorithm names.
Definition: smime.c:1452
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
static pid_t smime_invoke_sign(FILE **fp_smime_in, FILE **fp_smime_out, FILE **fp_smime_err, int fp_smime_infd, int fp_smime_outfd, int fp_smime_errfd, const char *fname)
Use SMIME to sign a file.
Definition: smime.c:1298
static struct Buffer SmimeIntermediateToUse
Definition: smime.c:82
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
An SIME key.
Definition: smime.h:43
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:67
static void smime_key_free(struct SmimeKey **keylist)
Free a list of SMIME keys.
Definition: smime.c:108
char * C_SmimeKeys
Config: File containing user&#39;s private certificates.
Definition: config.c:115
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: multipart.c:86
char SmimePass[256]
Definition: smime.c:77
Content is attached.
Definition: mime.h:63
int mutt_write_mime_header(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition: header.c:760
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
static struct Buffer SmimeCertToUse
Definition: smime.c:81
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
char * C_SmimeCertificates
Config: File containing user&#39;s public certificates.
Definition: config.c:107
static struct SmimeKey * smime_get_key_by_hash(char *hash, bool only_public_key)
Find a key by its hash.
Definition: smime.c:550
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: config.c:69
char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: config.c:70
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * C_SmimeSignDigestAlg
Config: Digest algorithm.
Definition: config.c:118
#define FREE(x)
Definition: memory.h:40
char * issuer
Definition: smime.h:48
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
+ Here is the call graph for this function:

◆ smime_class_valid_passphrase()

bool smime_class_valid_passphrase ( void  )

Implements CryptModuleSpecs::valid_passphrase()

Definition at line 167 of file smime.c.

168 {
169  const time_t now = mutt_date_epoch();
170  if (now < SmimeExpTime)
171  {
172  /* Use cached copy. */
173  return true;
174  }
175 
177 
178  if (mutt_get_password(_("Enter S/MIME passphrase:"), SmimePass, sizeof(SmimePass)) == 0)
179  {
181  return true;
182  }
183  else
184  SmimeExpTime = 0;
185 
186  return false;
187 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
#define mutt_get_password(msg, buf, buflen)
Definition: curs_lib.h:92
#define _(a)
Definition: message.h:28
long C_SmimeTimeout
Config: Time in seconds to cache a passphrase.
Definition: config.c:119
time_t mutt_date_add_timeout(time_t now, time_t timeout)
Safely add a timeout to a given time_t value.
Definition: date.c:625
char SmimePass[256]
Definition: smime.c:77
void smime_class_void_passphrase(void)
Implements CryptModuleSpecs::void_passphrase()
Definition: smime.c:158
time_t SmimeExpTime
Definition: smime.c:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smime_class_verify_one()

int smime_class_verify_one ( struct Body sigbdy,
struct State s,
const char *  tempfile 
)

Implements CryptModuleSpecs::verify_one()

Definition at line 1676 of file smime.c.

1677 {
1678  FILE *fp = NULL, *fp_smime_out = NULL, *fp_smime_err = NULL;
1679  pid_t pid;
1680  int badsig = -1;
1681 
1682  LOFF_T tmpoffset = 0;
1683  size_t tmplength = 0;
1684  int orig_type = sigbdy->type;
1685 
1686  struct Buffer *signedfile = mutt_buffer_pool_get();
1687 
1688  mutt_buffer_printf(signedfile, "%s.sig", tempfile);
1689 
1690  /* decode to a tempfile, saving the original destination */
1691  fp = s->fp_out;
1692  s->fp_out = mutt_file_fopen(mutt_b2s(signedfile), "w");
1693  if (!s->fp_out)
1694  {
1695  mutt_perror(mutt_b2s(signedfile));
1696  goto cleanup;
1697  }
1698  /* decoding the attachment changes the size and offset, so save a copy
1699  * of the "real" values now, and restore them after processing */
1700  tmplength = sigbdy->length;
1701  tmpoffset = sigbdy->offset;
1702 
1703  /* if we are decoding binary bodies, we don't want to prefix each
1704  * line with the prefix or else the data will get corrupted. */
1705  char *save_prefix = s->prefix;
1706  s->prefix = NULL;
1707 
1708  mutt_decode_attachment(sigbdy, s);
1709 
1710  sigbdy->length = ftello(s->fp_out);
1711  sigbdy->offset = 0;
1712  mutt_file_fclose(&s->fp_out);
1713 
1714  /* restore final destination and substitute the tempfile for input */
1715  s->fp_out = fp;
1716  fp = s->fp_in;
1717  s->fp_in = fopen(mutt_b2s(signedfile), "r");
1718 
1719  /* restore the prefix */
1720  s->prefix = save_prefix;
1721 
1722  sigbdy->type = orig_type;
1723 
1724  fp_smime_err = mutt_file_mkstemp();
1725  if (!fp_smime_err)
1726  {
1727  mutt_perror(_("Can't create temporary file"));
1728  goto cleanup;
1729  }
1730 
1731  crypt_current_time(s, "OpenSSL");
1732 
1733  pid = smime_invoke_verify(NULL, &fp_smime_out, NULL, -1, -1, fileno(fp_smime_err),
1734  tempfile, mutt_b2s(signedfile), 0);
1735  if (pid != -1)
1736  {
1737  fflush(fp_smime_out);
1738  mutt_file_fclose(&fp_smime_out);
1739 
1740  if (filter_wait(pid))
1741  badsig = -1;
1742  else
1743  {
1744  char *line = NULL;
1745  size_t linelen;
1746 
1747  fflush(fp_smime_err);
1748  rewind(fp_smime_err);
1749 
1750  line = mutt_file_read_line(line, &linelen, fp_smime_err, NULL, 0);
1751  if (linelen && mutt_istr_equal(line, "verification successful"))
1752  badsig = 0;
1753 
1754  FREE(&line);
1755  }
1756  }
1757 
1758  fflush(fp_smime_err);
1759  rewind(fp_smime_err);
1760  mutt_file_copy_stream(fp_smime_err, s->fp_out);
1761  mutt_file_fclose(&fp_smime_err);
1762 
1763  state_attach_puts(s, _("[-- End of OpenSSL output --]\n\n"));
1764 
1765  mutt_file_unlink(mutt_b2s(signedfile));
1766 
1767  sigbdy->length = tmplength;
1768  sigbdy->offset = tmpoffset;
1769 
1770  /* restore the original source stream */
1771  mutt_file_fclose(&s->fp_in);
1772  s->fp_in = fp;
1773 
1774 cleanup:
1775  mutt_buffer_pool_release(&signedfile);
1776  return badsig;
1777 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1843
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:667
FILE * fp_out
File to write to.
Definition: state.h:47
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
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:153
void crypt_current_time(struct State *s, const char *app_name)
Print the current time.
Definition: crypt.c:71
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
#define mutt_b2s(buf)
Definition: buffer.h:41
static pid_t smime_invoke_verify(FILE **fp_smime_in, FILE **fp_smime_out, FILE **fp_smime_err, int fp_smime_infd, int fp_smime_outfd, int fp_smime_errfd, const char *fname, const char *sig_fname, int opaque)
Use SMIME to verify a file.
Definition: smime.c:1638
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define mutt_file_mkstemp()
Definition: file.h:106
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
#define FREE(x)
Definition: memory.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
+ Here is the call graph for this function:

◆ smime_class_verify_sender()

int smime_class_verify_sender ( struct Mailbox m,
struct Email e 
)

Implements CryptModuleSpecs::smime_verify_sender()

Definition at line 1192 of file smime.c.

1193 {
1194  char *mbox = NULL, *certfile = NULL;
1195  int rc = 1;
1196 
1197  struct Buffer *tempfname = mutt_buffer_pool_get();
1198  mutt_buffer_mktemp(tempfname);
1199  FILE *fp_out = mutt_file_fopen(mutt_b2s(tempfname), "w");
1200  if (!fp_out)
1201  {
1202  mutt_perror(mutt_b2s(tempfname));
1203  goto cleanup;
1204  }
1205 
1206  if (e->security & SEC_ENCRYPT)
1207  {
1209  CH_MIME | CH_WEED | CH_NONEWLINE, 0);
1210  }
1211  else
1212  mutt_copy_message(fp_out, m, e, MUTT_CM_NO_FLAGS, CH_NO_FLAGS, 0);
1213 
1214  fflush(fp_out);
1215  mutt_file_fclose(&fp_out);
1216 
1217  if (!TAILQ_EMPTY(&e->env->from))
1218  {
1220  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
1221  }
1222  else if (!TAILQ_EMPTY(&e->env->sender))
1223  {
1225  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
1226  }
1227 
1228  if (mbox)
1229  {
1230  certfile = smime_extract_signer_certificate(mutt_b2s(tempfname));
1231  if (certfile)
1232  {
1233  mutt_file_unlink(mutt_b2s(tempfname));
1234  if (smime_handle_cert_email(certfile, mbox, false, NULL, NULL))
1235  {
1236  if (isendwin())
1238  }
1239  else
1240  rc = 0;
1241  mutt_file_unlink(certfile);
1242  FREE(&certfile);
1243  }
1244  else
1245  mutt_any_key_to_continue(_("no certfile"));
1246  }
1247  else
1248  mutt_any_key_to_continue(_("no mbox"));
1249 
1250  mutt_file_unlink(mutt_b2s(tempfname));
1251 
1252 cleanup:
1253  mutt_buffer_pool_release(&tempfname);
1254  return rc;
1255 }
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define mutt_perror(...)
Definition: logging.h:85
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
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:828
#define _(a)
Definition: message.h:28
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
#define CH_WEED
Weed the headers?
Definition: copy.h:52
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:90
static int smime_handle_cert_email(char *certificate, char *mailbox, bool copy, char ***buffer, int *num)
Process an email containing certificates.
Definition: smime.c:847
#define mutt_b2s(buf)
Definition: buffer.h:41
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#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:604
static char * smime_extract_signer_certificate(const char *infile)
Extract the signer&#39;s certificate.
Definition: smime.c:1054
#define FREE(x)
Definition: memory.h:40
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
#define TAILQ_EMPTY(head)
Definition: queue.h:714
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
+ Here is the call graph for this function:

◆ smime_class_void_passphrase()

void smime_class_void_passphrase ( void  )

Implements CryptModuleSpecs::void_passphrase()

Definition at line 158 of file smime.c.

159 {
160  memset(SmimePass, 0, sizeof(SmimePass));
161  SmimeExpTime = 0;
162 }
char SmimePass[256]
Definition: smime.c:77
time_t SmimeExpTime
Definition: smime.c:78
+ Here is the caller graph for this function: