NeoMutt  2025-12-11-1009-ga75d9e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
decrypt_mime()

Decrypt an encrypted MIME part. More...

Collaboration diagram for decrypt_mime():

Functions

int pgp_gpgme_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
int smime_gpgme_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
int pgp_class_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
int smime_class_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.

Detailed Description

Decrypt an encrypted MIME part.

Parameters
[in]fp_inFile containing the encrypted part
[out]fp_outFile containing the decrypted part
[in]bBody of the email
[out]b_decBody containing the decrypted part
Return values
0Success
-1Failure

Function Documentation

◆ pgp_gpgme_decrypt_mime()

int pgp_gpgme_decrypt_mime ( FILE * fp_in,
FILE ** fp_out,
struct Body * b,
struct Body ** b_dec )

Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1908 of file crypt_gpgme.c.

1909{
1910 struct State state = { 0 };
1911 struct Body *first_part = b;
1912 int is_signed = 0;
1913 bool need_decode = false;
1914 LOFF_T saved_offset = 0;
1915 size_t saved_length = 0;
1916 FILE *fp_decoded = NULL;
1917 int rc = 0;
1918
1919 first_part->goodsig = false;
1920 first_part->warnsig = false;
1921
1923 {
1924 b = b->parts->next;
1925 /* Some clients improperly encode the octetstream part. */
1926 if (b->encoding != ENC_7BIT)
1927 need_decode = true;
1928 }
1930 {
1931 b = b->parts->next->next;
1932 need_decode = true;
1933 }
1934 else
1935 {
1936 return -1;
1937 }
1938
1939 state.fp_in = fp_in;
1940
1941 if (need_decode)
1942 {
1943 saved_offset = b->offset;
1944 saved_length = b->length;
1945
1946 fp_decoded = mutt_file_mkstemp();
1947 if (!fp_decoded)
1948 {
1949 mutt_perror(_("Can't create temporary file"));
1950 return -1;
1951 }
1952
1953 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1954 {
1955 rc = -1;
1956 goto bail;
1957 }
1958 state.fp_out = fp_decoded;
1959
1960 mutt_decode_attachment(b, &state);
1961
1962 fflush(fp_decoded);
1963 b->length = ftello(fp_decoded);
1964 b->offset = 0;
1965 rewind(fp_decoded);
1966 state.fp_in = fp_decoded;
1967 state.fp_out = 0;
1968 }
1969
1970 *fp_out = mutt_file_mkstemp();
1971 if (!*fp_out)
1972 {
1973 mutt_perror(_("Can't create temporary file"));
1974 rc = -1;
1975 goto bail;
1976 }
1977
1978 *b_dec = decrypt_part(b, &state, *fp_out, false, &is_signed);
1979 if (*b_dec)
1980 {
1981 rewind(*fp_out);
1982 if (is_signed > 0)
1983 first_part->goodsig = true;
1984 }
1985 else
1986 {
1987 rc = -1;
1988 mutt_file_fclose(fp_out);
1989 }
1990
1991bail:
1992 if (need_decode)
1993 {
1994 b->length = saved_length;
1995 b->offset = saved_offset;
1996 mutt_file_fclose(&fp_decoded);
1997 }
1998
1999 return rc;
2000}
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition crypt.c:468
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition crypt.c:505
static struct Body * decrypt_part(struct Body *b, struct State *state, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_perror(...)
Definition logging2.h:95
void mutt_decode_attachment(const struct Body *b, struct State *state)
Decode an email's attachment.
Definition handler.c:1943
@ ENC_7BIT
7-bit text
Definition mime.h:49
#define _(a)
Definition message.h:28
#define PGP_ENCRYPT
Email is PGP encrypted.
Definition lib.h:112
The body of an email.
Definition body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
LOFF_T offset
offset where the actual data begins
Definition body.h:52
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
struct Body * next
next attachment in the list
Definition body.h:72
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
bool goodsig
Good cryptographic signature.
Definition body.h:45
bool warnsig
Maybe good signature.
Definition body.h:48
Keep track when processing files.
Definition state.h:54
FILE * fp_out
File to write to.
Definition state.h:56
FILE * fp_in
File to read from.
Definition state.h:55
#define mutt_file_mkstemp()
Definition tmp.h:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ smime_gpgme_decrypt_mime()

int smime_gpgme_decrypt_mime ( FILE * fp_in,
FILE ** fp_out,
struct Body * b,
struct Body ** b_dec )

Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 2005 of file crypt_gpgme.c.

2006{
2007 struct State state = { 0 };
2008 int is_signed = 0;
2009 LOFF_T saved_b_offset;
2010 size_t saved_b_length;
2011
2013 return -1;
2014
2015 if (b->parts)
2016 return -1;
2017
2018 /* Decode the body - we need to pass binary CMS to the
2019 * backend. The backend allows for Base64 encoded data but it does
2020 * not allow for QP which I have seen in some messages. So better
2021 * do it here. */
2022 saved_b_offset = b->offset;
2023 saved_b_length = b->length;
2024 state.fp_in = fp_in;
2025 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
2026 {
2027 return -1;
2028 }
2029 FILE *fp_tmp = mutt_file_mkstemp();
2030 if (!fp_tmp)
2031 {
2032 mutt_perror(_("Can't create temporary file"));
2033 return -1;
2034 }
2035
2036 state.fp_out = fp_tmp;
2037 mutt_decode_attachment(b, &state);
2038 fflush(fp_tmp);
2039 b->length = ftello(state.fp_out);
2040 b->offset = 0;
2041 rewind(fp_tmp);
2042
2043 memset(&state, 0, sizeof(state));
2044 state.fp_in = fp_tmp;
2045 state.fp_out = 0;
2047 if (!*fp_out)
2048 {
2049 mutt_perror(_("Can't create temporary file"));
2050 mutt_file_fclose(&fp_tmp);
2051 return -1;
2052 }
2053
2054 *b_dec = decrypt_part(b, &state, *fp_out, true, &is_signed);
2055 if (*b_dec)
2056 (*b_dec)->goodsig = is_signed > 0;
2057 b->length = saved_b_length;
2058 b->offset = saved_b_offset;
2059 mutt_file_fclose(&fp_tmp);
2060 rewind(*fp_out);
2061 if (*b_dec && !is_signed && !(*b_dec)->parts && mutt_is_application_smime(*b_dec))
2062 {
2063 /* Assume that this is a opaque signed s/mime message. This is an ugly way
2064 * of doing it but we have anyway a problem with arbitrary encoded S/MIME
2065 * messages: Only the outer part may be encrypted. The entire mime parsing
2066 * should be revamped, probably by keeping the temporary files so that we
2067 * don't need to decrypt them all the time. Inner parts of an encrypted
2068 * part can then point into this file and there won't ever be a need to
2069 * decrypt again. This needs a partial rewrite of the MIME engine. */
2070 struct Body *bb = *b_dec;
2071
2072 saved_b_offset = bb->offset;
2073 saved_b_length = bb->length;
2074 memset(&state, 0, sizeof(state));
2075 state.fp_in = *fp_out;
2076 if (!mutt_file_seek(state.fp_in, bb->offset, SEEK_SET))
2077 {
2078 return -1;
2079 }
2080 FILE *fp_tmp2 = mutt_file_mkstemp();
2081 if (!fp_tmp2)
2082 {
2083 mutt_perror(_("Can't create temporary file"));
2084 return -1;
2085 }
2086
2087 state.fp_out = fp_tmp2;
2088 mutt_decode_attachment(bb, &state);
2089 fflush(fp_tmp2);
2090 bb->length = ftello(state.fp_out);
2091 bb->offset = 0;
2092 rewind(fp_tmp2);
2093 mutt_file_fclose(fp_out);
2094
2095 memset(&state, 0, sizeof(state));
2096 state.fp_in = fp_tmp2;
2097 state.fp_out = 0;
2098 *fp_out = mutt_file_mkstemp();
2099 if (!*fp_out)
2100 {
2101 mutt_perror(_("Can't create temporary file"));
2102 mutt_file_fclose(&fp_tmp2);
2103 return -1;
2104 }
2105
2106 struct Body *b_tmp = decrypt_part(bb, &state, *fp_out, true, &is_signed);
2107 if (b_tmp)
2108 b_tmp->goodsig = is_signed > 0;
2109 bb->length = saved_b_length;
2110 bb->offset = saved_b_offset;
2111 mutt_file_fclose(&fp_tmp2);
2112 rewind(*fp_out);
2113 mutt_body_free(b_dec);
2114 *b_dec = b_tmp;
2115 }
2116 return *b_dec ? 0 : -1;
2117}
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition crypt.c:610
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
@ SEC_NONE
No flags are set.
Definition lib.h:91
Here is the call graph for this function:

◆ pgp_class_decrypt_mime()

int pgp_class_decrypt_mime ( FILE * fp_in,
FILE ** fp_out,
struct Body * b,
struct Body ** b_dec )

Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1166 of file pgp.c.

1167{
1168 struct State state = { 0 };
1169 struct Body *p = b;
1170 bool need_decode = false;
1171 LOFF_T saved_offset = 0;
1172 size_t saved_length = 0;
1173 FILE *fp_decoded = NULL;
1174 int rc = 0;
1175
1177 {
1178 b = b->parts->next;
1179 /* Some clients improperly encode the octetstream part. */
1180 if (b->encoding != ENC_7BIT)
1181 need_decode = true;
1182 }
1184 {
1185 b = b->parts->next->next;
1186 need_decode = true;
1187 }
1188 else
1189 {
1190 return -1;
1191 }
1192
1193 state.fp_in = fp_in;
1194
1195 if (need_decode)
1196 {
1197 saved_offset = b->offset;
1198 saved_length = b->length;
1199
1200 fp_decoded = mutt_file_mkstemp();
1201 if (!fp_decoded)
1202 {
1203 mutt_perror(_("Can't create temporary file"));
1204 return -1;
1205 }
1206
1207 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1208 {
1209 rc = -1;
1210 goto bail;
1211 }
1212 state.fp_out = fp_decoded;
1213
1214 mutt_decode_attachment(b, &state);
1215
1216 fflush(fp_decoded);
1217 b->length = ftello(fp_decoded);
1218 b->offset = 0;
1219 rewind(fp_decoded);
1220 state.fp_in = fp_decoded;
1221 state.fp_out = 0;
1222 }
1223
1224 *fp_out = mutt_file_mkstemp();
1225 if (!*fp_out)
1226 {
1227 mutt_perror(_("Can't create temporary file"));
1228 rc = -1;
1229 goto bail;
1230 }
1231
1232 *b_dec = pgp_decrypt_part(b, &state, *fp_out, p);
1233 if (!*b_dec)
1234 rc = -1;
1235 rewind(*fp_out);
1236
1237bail:
1238 if (need_decode)
1239 {
1240 b->length = saved_length;
1241 b->offset = saved_offset;
1242 mutt_file_fclose(&fp_decoded);
1243 }
1244
1245 return rc;
1246}
static struct Body * pgp_decrypt_part(struct Body *a, struct State *state, FILE *fp_out, struct Body *p)
Decrypt part of a PGP message.
Definition pgp.c:1027
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 ** b_dec )

Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1943 of file smime.c.

1944{
1945 struct State state = { 0 };
1946 LOFF_T tmpoffset = b->offset;
1947 size_t tmplength = b->length;
1948 int rc = -1;
1949
1951 return -1;
1952
1953 if (b->parts)
1954 return -1;
1955
1956 state.fp_in = fp_in;
1957 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1958 {
1959 return -1;
1960 }
1961
1962 FILE *fp_tmp = mutt_file_mkstemp();
1963 if (!fp_tmp)
1964 {
1965 mutt_perror(_("Can't create temporary file"));
1966 return -1;
1967 }
1968
1969 state.fp_out = fp_tmp;
1970 mutt_decode_attachment(b, &state);
1971 fflush(fp_tmp);
1972 b->length = ftello(state.fp_out);
1973 b->offset = 0;
1974 rewind(fp_tmp);
1975 state.fp_in = fp_tmp;
1976 state.fp_out = 0;
1977
1979 if (!*fp_out)
1980 {
1981 mutt_perror(_("Can't create temporary file"));
1982 goto bail;
1983 }
1984
1985 *b_dec = smime_handle_entity(b, &state, *fp_out);
1986 if (!*b_dec)
1987 goto bail;
1988
1989 (*b_dec)->goodsig = b->goodsig;
1990 (*b_dec)->badsig = b->badsig;
1991 rc = 0;
1992
1993bail:
1994 b->length = tmplength;
1995 b->offset = tmpoffset;
1996 mutt_file_fclose(&fp_tmp);
1997 if (*fp_out)
1998 rewind(*fp_out);
1999
2000 return rc;
2001}
static struct Body * smime_handle_entity(struct Body *b, struct State *state, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition smime.c:1701
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures).
Definition body.h:43
Here is the call graph for this function: