NeoMutt  2025-12-11-949-g4870ee
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 1903 of file crypt_gpgme.c.

1904{
1905 struct State state = { 0 };
1906 struct Body *first_part = b;
1907 int is_signed = 0;
1908 bool need_decode = false;
1909 LOFF_T saved_offset = 0;
1910 size_t saved_length = 0;
1911 FILE *fp_decoded = NULL;
1912 int rc = 0;
1913
1914 first_part->goodsig = false;
1915 first_part->warnsig = false;
1916
1918 {
1919 b = b->parts->next;
1920 /* Some clients improperly encode the octetstream part. */
1921 if (b->encoding != ENC_7BIT)
1922 need_decode = true;
1923 }
1925 {
1926 b = b->parts->next->next;
1927 need_decode = true;
1928 }
1929 else
1930 {
1931 return -1;
1932 }
1933
1934 state.fp_in = fp_in;
1935
1936 if (need_decode)
1937 {
1938 saved_offset = b->offset;
1939 saved_length = b->length;
1940
1941 fp_decoded = mutt_file_mkstemp();
1942 if (!fp_decoded)
1943 {
1944 mutt_perror(_("Can't create temporary file"));
1945 return -1;
1946 }
1947
1948 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1949 {
1950 rc = -1;
1951 goto bail;
1952 }
1953 state.fp_out = fp_decoded;
1954
1955 mutt_decode_attachment(b, &state);
1956
1957 fflush(fp_decoded);
1958 b->length = ftello(fp_decoded);
1959 b->offset = 0;
1960 rewind(fp_decoded);
1961 state.fp_in = fp_decoded;
1962 state.fp_out = 0;
1963 }
1964
1965 *fp_out = mutt_file_mkstemp();
1966 if (!*fp_out)
1967 {
1968 mutt_perror(_("Can't create temporary file"));
1969 rc = -1;
1970 goto bail;
1971 }
1972
1973 *b_dec = decrypt_part(b, &state, *fp_out, false, &is_signed);
1974 if (*b_dec)
1975 {
1976 rewind(*fp_out);
1977 if (is_signed > 0)
1978 first_part->goodsig = true;
1979 }
1980 else
1981 {
1982 rc = -1;
1983 mutt_file_fclose(fp_out);
1984 }
1985
1986bail:
1987 if (need_decode)
1988 {
1989 b->length = saved_length;
1990 b->offset = saved_offset;
1991 mutt_file_fclose(&fp_decoded);
1992 }
1993
1994 return rc;
1995}
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition crypt.c:467
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition crypt.c:504
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:1939
@ 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 2000 of file crypt_gpgme.c.

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

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

1921{
1922 struct State state = { 0 };
1923 LOFF_T tmpoffset = b->offset;
1924 size_t tmplength = b->length;
1925 int rc = -1;
1926
1928 return -1;
1929
1930 if (b->parts)
1931 return -1;
1932
1933 state.fp_in = fp_in;
1934 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1935 {
1936 return -1;
1937 }
1938
1939 FILE *fp_tmp = mutt_file_mkstemp();
1940 if (!fp_tmp)
1941 {
1942 mutt_perror(_("Can't create temporary file"));
1943 return -1;
1944 }
1945
1946 state.fp_out = fp_tmp;
1947 mutt_decode_attachment(b, &state);
1948 fflush(fp_tmp);
1949 b->length = ftello(state.fp_out);
1950 b->offset = 0;
1951 rewind(fp_tmp);
1952 state.fp_in = fp_tmp;
1953 state.fp_out = 0;
1954
1956 if (!*fp_out)
1957 {
1958 mutt_perror(_("Can't create temporary file"));
1959 goto bail;
1960 }
1961
1962 *b_dec = smime_handle_entity(b, &state, *fp_out);
1963 if (!*b_dec)
1964 goto bail;
1965
1966 (*b_dec)->goodsig = b->goodsig;
1967 (*b_dec)->badsig = b->badsig;
1968 rc = 0;
1969
1970bail:
1971 b->length = tmplength;
1972 b->offset = tmpoffset;
1973 mutt_file_fclose(&fp_tmp);
1974 if (*fp_out)
1975 rewind(*fp_out);
1976
1977 return rc;
1978}
static struct Body * smime_handle_entity(struct Body *b, struct State *state, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition smime.c:1681
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition body.h:43
+ Here is the call graph for this function: