NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
smime_build_smime_entity()

Encrypt the email body to all recipients. More...

Collaboration diagram for smime_build_smime_entity():

Functions

struct Bodysmime_gpgme_build_smime_entity (struct Body *b, char *keylist)
 Encrypt the email body to all recipients - Implements CryptModuleSpecs::smime_build_smime_entity() -.
struct Bodysmime_class_build_smime_entity (struct Body *b, char *certlist)
 Encrypt the email body to all recipients - Implements CryptModuleSpecs::smime_build_smime_entity() -.

Detailed Description

Encrypt the email body to all recipients.

Parameters
bBody of email
certlistList of key fingerprints (space separated)
Return values
ptrNew S/MIME encrypted Body
NULLError

Function Documentation

◆ smime_gpgme_build_smime_entity()

struct Body * smime_gpgme_build_smime_entity ( struct Body * b,
char * keylist )

Encrypt the email body to all recipients - Implements CryptModuleSpecs::smime_build_smime_entity() -.

Definition at line 1100 of file crypt_gpgme.c.

1101{
1102 /* OpenSSL converts line endings to crlf when encrypting. Some clients
1103 * depend on this for signed+encrypted messages: they do not convert line
1104 * endings between decrypting and checking the signature. */
1105 gpgme_data_t plaintext = body_to_data_object(b, true);
1106 if (!plaintext)
1107 return NULL;
1108
1109 char *outfile = encrypt_gpgme_object(plaintext, keylist, true, false, NULL);
1110 gpgme_data_release(plaintext);
1111 if (!outfile)
1112 return NULL;
1113
1114 struct Body *b_enc = mutt_body_new();
1115 b_enc->type = TYPE_APPLICATION;
1116 b_enc->subtype = mutt_str_dup("pkcs7-mime");
1117 mutt_param_set(&b_enc->parameter, "name", "smime.p7m");
1118 mutt_param_set(&b_enc->parameter, "smime-type", "enveloped-data");
1119 b_enc->encoding = ENC_BASE64; /* The output of OpenSSL SHOULD be binary */
1120 b_enc->use_disp = true;
1121 b_enc->disposition = DISP_ATTACH;
1122 b_enc->d_filename = mutt_str_dup("smime.p7m");
1123 b_enc->filename = outfile;
1124 b_enc->unlink = true; /* delete after sending the message */
1125 b_enc->parts = 0;
1126 b_enc->next = 0;
1127
1128 return b_enc;
1129}
static gpgme_data_t body_to_data_object(struct Body *b, bool convert)
Create GPGME object from the mail body.
static char * encrypt_gpgme_object(gpgme_data_t plaintext, char *keylist, bool use_smime, bool combined_signed, const struct AddressList *from)
Encrypt the GPGPME data object.
struct Body * mutt_body_new(void)
Create a new Body.
Definition body.c:44
@ ENC_BASE64
Base-64 encoded text.
Definition mime.h:52
@ TYPE_APPLICATION
Type: 'application/*'.
Definition mime.h:33
@ DISP_ATTACH
Content is attached.
Definition mime.h:63
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition parameter.c:111
The body of an email.
Definition body.h:36
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition body.h:56
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition body.h:68
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
bool use_disp
Content-Disposition uses filename= ?
Definition body.h:47
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
struct Body * next
next attachment in the list
Definition body.h:72
char * subtype
content-type subtype
Definition body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
unsigned int type
content-type primary type, ContentType
Definition body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
Here is the call graph for this function:

◆ smime_class_build_smime_entity()

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

Encrypt the email body to all recipients - Implements CryptModuleSpecs::smime_build_smime_entity() -.

Definition at line 1213 of file smime.c.

1214{
1215 char buf[1024] = { 0 };
1216 char certfile[PATH_MAX] = { 0 };
1217 char *cert_end = NULL;
1218 FILE *fp_smime_in = NULL;
1219 FILE *fp_smime_err = NULL;
1220 FILE *fp_out = NULL;
1221 FILE *fp_tmp = NULL;
1222 struct Body *b_enc = NULL;
1223 bool err = false;
1224 int empty;
1225 int off;
1226 pid_t pid;
1227
1228 struct Buffer *tempfile = buf_pool_get();
1229 struct Buffer *smime_infile = buf_pool_get();
1230
1231 buf_mktemp(tempfile);
1232 fp_out = mutt_file_fopen(buf_string(tempfile), "w+");
1233 if (!fp_out)
1234 {
1235 mutt_perror("%s", buf_string(tempfile));
1236 goto cleanup;
1237 }
1238
1239 fp_smime_err = mutt_file_mkstemp();
1240 if (!fp_smime_err)
1241 {
1242 mutt_perror(_("Can't create temporary file"));
1243 goto cleanup;
1244 }
1245
1246 buf_mktemp(smime_infile);
1247 fp_tmp = mutt_file_fopen(buf_string(smime_infile), "w+");
1248 if (!fp_tmp)
1249 {
1250 mutt_perror("%s", buf_string(smime_infile));
1251 goto cleanup;
1252 }
1253
1254 *certfile = '\0';
1255 for (char *cert_start = certlist; cert_start; cert_start = cert_end)
1256 {
1257 cert_end = strchr(cert_start, ' ');
1258 if (cert_end)
1259 *cert_end = '\0';
1260 if (*cert_start)
1261 {
1262 off = mutt_str_len(certfile);
1263 const char *const c_smime_certificates = cs_subset_path(NeoMutt->sub, "smime_certificates");
1264 snprintf(certfile + off, sizeof(certfile) - off, "%s%s/%s",
1265 (off != 0) ? " " : "", NONULL(c_smime_certificates), cert_start);
1266 }
1267 if (cert_end)
1268 *cert_end++ = ' ';
1269 }
1270
1271 /* write a MIME entity */
1272 mutt_write_mime_header(b, fp_tmp, NeoMutt->sub);
1273 fputc('\n', fp_tmp);
1274 mutt_write_mime_body(b, fp_tmp, NeoMutt->sub);
1275 mutt_file_fclose(&fp_tmp);
1276
1277 pid = smime_invoke_encrypt(&fp_smime_in, NULL, NULL, -1, fileno(fp_out),
1278 fileno(fp_smime_err), buf_string(smime_infile), certfile);
1279 if (pid == -1)
1280 {
1281 mutt_file_unlink(buf_string(smime_infile));
1282 goto cleanup;
1283 }
1284
1285 mutt_file_fclose(&fp_smime_in);
1286
1287 filter_wait(pid);
1288 mutt_file_unlink(buf_string(smime_infile));
1289
1290 fflush(fp_out);
1291 fseek(fp_out, 0, SEEK_SET);
1292 clearerr(fp_out);
1293 empty = (fgetc(fp_out) == EOF);
1294 mutt_file_fclose(&fp_out);
1295
1296 fflush(fp_smime_err);
1297 fseek(fp_smime_err, 0, SEEK_SET);
1298 clearerr(fp_smime_err);
1299 while (fgets(buf, sizeof(buf) - 1, fp_smime_err))
1300 {
1301 err = true;
1302 fputs(buf, stdout);
1303 }
1304 mutt_file_fclose(&fp_smime_err);
1305
1306 /* pause if there is any error output from SMIME */
1307 if (err)
1309
1310 if (empty)
1311 {
1312 /* fatal error while trying to encrypt message */
1313 if (!err)
1314 mutt_any_key_to_continue(_("No output from OpenSSL..."));
1315 mutt_file_unlink(buf_string(tempfile));
1316 goto cleanup;
1317 }
1318
1319 b_enc = mutt_body_new();
1320 b_enc->type = TYPE_APPLICATION;
1321 b_enc->subtype = mutt_str_dup("pkcs7-mime");
1322 mutt_param_set(&b_enc->parameter, "name", "smime.p7m");
1323 mutt_param_set(&b_enc->parameter, "smime-type", "enveloped-data");
1324 b_enc->encoding = ENC_BASE64; /* The output of OpenSSL SHOULD be binary */
1325 b_enc->use_disp = true;
1326 b_enc->disposition = DISP_ATTACH;
1327 b_enc->d_filename = mutt_str_dup("smime.p7m");
1328 b_enc->filename = buf_strdup(tempfile);
1329 b_enc->unlink = true; /* delete after sending the message */
1330 b_enc->parts = NULL;
1331 b_enc->next = NULL;
1332
1333cleanup:
1334 if (fp_out)
1335 {
1336 mutt_file_fclose(&fp_out);
1337 mutt_file_unlink(buf_string(tempfile));
1338 }
1339 mutt_file_fclose(&fp_smime_err);
1340 if (fp_tmp)
1341 {
1342 mutt_file_fclose(&fp_tmp);
1343 mutt_file_unlink(buf_string(smime_infile));
1344 }
1345 buf_pool_release(&tempfile);
1346 buf_pool_release(&smime_infile);
1347
1348 return b_enc;
1349}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition helpers.c:168
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition curs_lib.c:174
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition file.c:156
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
#define mutt_perror(...)
Definition logging2.h:95
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition filter.c:231
#define _(a)
Definition message.h:28
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
#define PATH_MAX
Definition mutt.h:49
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
int mutt_write_mime_body(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition body.c:304
int mutt_write_mime_header(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition header.c:763
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:1169
#define NONULL(x)
Definition string2.h:44
String manipulation buffer.
Definition buffer.h:36
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
#define buf_mktemp(buf)
Definition tmp.h:33
#define mutt_file_mkstemp()
Definition tmp.h:36
Here is the call graph for this function: