NeoMutt  2023-05-17-16-g61469c
Teaching an old dog new tricks
DOXYGEN
pgp_encrypt_message()

PGP encrypt an email. More...

+ Collaboration diagram for pgp_encrypt_message():

Functions

struct Bodypgp_gpgme_encrypt_message (struct Body *a, char *keylist, bool sign, const struct AddressList *from)
 Implements CryptModuleSpecs::pgp_encrypt_message() -. More...
 
struct Bodypgp_class_encrypt_message (struct Body *a, char *keylist, bool sign, const struct AddressList *from)
 Implements CryptModuleSpecs::pgp_encrypt_message() -. More...
 

Detailed Description

PGP encrypt an email.

Parameters
aBody of email to encrypt
keylistList of keys, or fingerprints (space separated)
signIf true, sign the message too
fromFrom line, to choose the key to sign
Return values
ptrEncrypted Body
NULLError

Encrypt the mail body to all the given keys.

Function Documentation

◆ pgp_gpgme_encrypt_message()

struct Body * pgp_gpgme_encrypt_message ( struct Body a,
char *  keylist,
bool  sign,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::pgp_encrypt_message() -.

Definition at line 1037 of file crypt_gpgme.c.

1039{
1040 if (sign)
1042 gpgme_data_t plaintext = body_to_data_object(a, false);
1043 if (!plaintext)
1044 return NULL;
1045
1046 char *outfile = encrypt_gpgme_object(plaintext, keylist, false, sign, from);
1047 gpgme_data_release(plaintext);
1048 if (!outfile)
1049 return NULL;
1050
1051 struct Body *t = mutt_body_new();
1052 t->type = TYPE_MULTIPART;
1053 t->subtype = mutt_str_dup("encrypted");
1054 t->encoding = ENC_7BIT;
1055 t->use_disp = false;
1057
1059 mutt_param_set(&t->parameter, "protocol", "application/pgp-encrypted");
1060
1061 t->parts = mutt_body_new();
1063 t->parts->subtype = mutt_str_dup("pgp-encrypted");
1064 t->parts->encoding = ENC_7BIT;
1065
1066 t->parts->next = mutt_body_new();
1068 t->parts->next->subtype = mutt_str_dup("octet-stream");
1069 t->parts->next->encoding = ENC_7BIT;
1070 t->parts->next->filename = outfile;
1071 t->parts->next->use_disp = true;
1073 t->parts->next->unlink = true; /* delete after sending the message */
1074 t->parts->next->d_filename = mutt_str_dup("msg.asc"); /* non pgp/mime
1075 can save */
1076
1077 return t;
1078}
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:799
static gpgme_data_t body_to_data_object(struct Body *a, bool convert)
Create GPGME object from the mail body.
Definition: crypt_gpgme.c:418
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.
Definition: crypt_gpgme.c:775
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
@ ENC_7BIT
7-bit text
Definition: mime.h:49
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
@ TYPE_APPLICATION
Type: 'application/*'.
Definition: mime.h:33
@ DISP_ATTACH
Content is attached.
Definition: mime.h:63
@ DISP_INLINE
Content is inline.
Definition: mime.h:62
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: multipart.c:86
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
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:72
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:67
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:62
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:71
char * subtype
content-type subtype
Definition: body.h:60
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:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_class_encrypt_message()

struct Body * pgp_class_encrypt_message ( struct Body a,
char *  keylist,
bool  sign,
const struct AddressList *  from 
)

Implements CryptModuleSpecs::pgp_encrypt_message() -.

Warning
"a" is no longer freed in this routine, you need to free it later. This is necessary for $fcc_attach.

Definition at line 1591 of file pgp.c.

1593{
1594 char buf[1024] = { 0 };
1595 FILE *fp_pgp_in = NULL, *fp_tmp = NULL;
1596 struct Body *t = NULL;
1597 int err = 0;
1598 bool empty = false;
1599 pid_t pid;
1600 struct Buffer *tempfile = buf_pool_get();
1601 struct Buffer *pgpinfile = buf_pool_get();
1602
1603 buf_mktemp(tempfile);
1604 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w+");
1605 if (!fp_out)
1606 {
1607 mutt_perror(buf_string(tempfile));
1608 goto cleanup;
1609 }
1610
1611 FILE *fp_pgp_err = mutt_file_mkstemp();
1612 if (!fp_pgp_err)
1613 {
1614 mutt_perror(_("Can't create temporary file"));
1615 unlink(buf_string(tempfile));
1616 mutt_file_fclose(&fp_out);
1617 goto cleanup;
1618 }
1619
1620 buf_mktemp(pgpinfile);
1621 fp_tmp = mutt_file_fopen(buf_string(pgpinfile), "w");
1622 if (!fp_tmp)
1623 {
1624 mutt_perror(buf_string(pgpinfile));
1625 unlink(buf_string(tempfile));
1626 mutt_file_fclose(&fp_out);
1627 mutt_file_fclose(&fp_pgp_err);
1628 goto cleanup;
1629 }
1630
1631 if (sign)
1633
1634 mutt_write_mime_header(a, fp_tmp, NeoMutt->sub);
1635 fputc('\n', fp_tmp);
1636 mutt_write_mime_body(a, fp_tmp, NeoMutt->sub);
1637 mutt_file_fclose(&fp_tmp);
1638
1639 pid = pgp_invoke_encrypt(&fp_pgp_in, NULL, NULL, -1, fileno(fp_out),
1640 fileno(fp_pgp_err), buf_string(pgpinfile), keylist, sign);
1641 if (pid == -1)
1642 {
1643 mutt_file_fclose(&fp_out);
1644 mutt_file_fclose(&fp_pgp_err);
1645 unlink(buf_string(pgpinfile));
1646 goto cleanup;
1647 }
1648
1649 if (sign)
1650 {
1651 if (!pgp_use_gpg_agent())
1652 fputs(PgpPass, fp_pgp_in);
1653 fputc('\n', fp_pgp_in);
1654 }
1655 mutt_file_fclose(&fp_pgp_in);
1656
1657 const bool c_pgp_check_exit = cs_subset_bool(NeoMutt->sub, "pgp_check_exit");
1658 if (filter_wait(pid) && c_pgp_check_exit)
1659 empty = true;
1660
1661 unlink(buf_string(pgpinfile));
1662
1663 fflush(fp_out);
1664 rewind(fp_out);
1665 if (!empty)
1666 empty = (fgetc(fp_out) == EOF);
1667 mutt_file_fclose(&fp_out);
1668
1669 fflush(fp_pgp_err);
1670 rewind(fp_pgp_err);
1671 while (fgets(buf, sizeof(buf) - 1, fp_pgp_err))
1672 {
1673 err = 1;
1674 fputs(buf, stdout);
1675 }
1676 mutt_file_fclose(&fp_pgp_err);
1677
1678 /* pause if there is any error output from PGP */
1679 if (err)
1681
1682 if (empty)
1683 {
1684 /* fatal error while trying to encrypt message */
1685 if (sign)
1686 pgp_class_void_passphrase(); /* just in case */
1687 unlink(buf_string(tempfile));
1688 goto cleanup;
1689 }
1690
1691 t = mutt_body_new();
1692 t->type = TYPE_MULTIPART;
1693 t->subtype = mutt_str_dup("encrypted");
1694 t->encoding = ENC_7BIT;
1695 t->use_disp = false;
1697
1699 mutt_param_set(&t->parameter, "protocol", "application/pgp-encrypted");
1700
1701 t->parts = mutt_body_new();
1703 t->parts->subtype = mutt_str_dup("pgp-encrypted");
1704 t->parts->encoding = ENC_7BIT;
1705
1706 t->parts->next = mutt_body_new();
1708 t->parts->next->subtype = mutt_str_dup("octet-stream");
1709 t->parts->next->encoding = ENC_7BIT;
1710 t->parts->next->filename = buf_strdup(tempfile);
1711 t->parts->next->use_disp = true;
1713 t->parts->next->unlink = true; /* delete after sending the message */
1714 t->parts->next->d_filename = mutt_str_dup("msg.asc"); /* non pgp/mime can save */
1715
1716cleanup:
1717 buf_pool_release(&tempfile);
1718 buf_pool_release(&pgpinfile);
1719 return t;
1720}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:490
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:388
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
void pgp_class_void_passphrase(void)
Implements CryptModuleSpecs::void_passphrase() -.
Definition: pgp.c:76
#define mutt_perror(...)
Definition: logging2.h:88
int mutt_write_mime_header(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition: header.c:758
#define _(a)
Definition: message.h:28
static char PgpPass[1024]
Cached PGP Passphrase.
Definition: pgp.c:69
bool pgp_use_gpg_agent(void)
Does the user want to use the gpg agent?
Definition: pgp.c:128
pid_t pgp_invoke_encrypt(FILE **fp_pgp_in, FILE **fp_pgp_out, FILE **fp_pgp_err, int fd_pgp_in, int fd_pgp_out, int fd_pgp_err, const char *fname, const char *uids, bool sign)
Use PGP to encrypt a file.
Definition: pgpinvoke.c:360
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:106
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:119
int mutt_write_mime_body(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Definition: body.c:318
String manipulation buffer.
Definition: buffer.h:34
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define buf_mktemp(buf)
Definition: tmp.h:37
#define mutt_file_mkstemp()
Definition: tmp.h:40
+ Here is the call graph for this function: