NeoMutt  2025-05-10-9-gb9f27b
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 1894 of file crypt_gpgme.c.

1895{
1896 struct State state = { 0 };
1897 struct Body *first_part = b;
1898 int is_signed = 0;
1899 bool need_decode = false;
1900 LOFF_T saved_offset = 0;
1901 size_t saved_length = 0;
1902 FILE *fp_decoded = NULL;
1903 int rc = 0;
1904
1905 first_part->goodsig = false;
1906 first_part->warnsig = false;
1907
1909 {
1910 b = b->parts->next;
1911 /* Some clients improperly encode the octetstream part. */
1912 if (b->encoding != ENC_7BIT)
1913 need_decode = true;
1914 }
1916 {
1917 b = b->parts->next->next;
1918 need_decode = true;
1919 }
1920 else
1921 {
1922 return -1;
1923 }
1924
1925 state.fp_in = fp_in;
1926
1927 if (need_decode)
1928 {
1929 saved_offset = b->offset;
1930 saved_length = b->length;
1931
1932 fp_decoded = mutt_file_mkstemp();
1933 if (!fp_decoded)
1934 {
1935 mutt_perror(_("Can't create temporary file"));
1936 return -1;
1937 }
1938
1939 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1940 {
1941 rc = -1;
1942 goto bail;
1943 }
1944 state.fp_out = fp_decoded;
1945
1946 mutt_decode_attachment(b, &state);
1947
1948 fflush(fp_decoded);
1949 b->length = ftello(fp_decoded);
1950 b->offset = 0;
1951 rewind(fp_decoded);
1952 state.fp_in = fp_decoded;
1953 state.fp_out = 0;
1954 }
1955
1956 *fp_out = mutt_file_mkstemp();
1957 if (!*fp_out)
1958 {
1959 mutt_perror(_("Can't create temporary file"));
1960 rc = -1;
1961 goto bail;
1962 }
1963
1964 *b_dec = decrypt_part(b, &state, *fp_out, false, &is_signed);
1965 if (*b_dec)
1966 {
1967 rewind(*fp_out);
1968 if (is_signed > 0)
1969 first_part->goodsig = true;
1970 }
1971 else
1972 {
1973 rc = -1;
1974 mutt_file_fclose(fp_out);
1975 }
1976
1977bail:
1978 if (need_decode)
1979 {
1980 b->length = saved_length;
1981 b->offset = saved_offset;
1982 mutt_file_fclose(&fp_decoded);
1983 }
1984
1985 return rc;
1986}
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.
Definition: crypt_gpgme.c:1732
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:655
#define mutt_file_fclose(FP)
Definition: file.h:139
#define mutt_perror(...)
Definition: logging2.h:94
void mutt_decode_attachment(const struct Body *b, struct State *state)
Decode an email's attachment.
Definition: handler.c:1907
@ ENC_7BIT
7-bit text
Definition: mime.h:49
#define _(a)
Definition: message.h:28
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:48
FILE * fp_out
File to write to.
Definition: state.h:50
FILE * fp_in
File to read from.
Definition: state.h:49
#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 1991 of file crypt_gpgme.c.

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

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

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