NeoMutt  2024-03-23-23-gec7045
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 1852 of file crypt_gpgme.c.

1853{
1854 struct State state = { 0 };
1855 struct Body *first_part = b;
1856 int is_signed = 0;
1857 bool need_decode = false;
1858 LOFF_T saved_offset = 0;
1859 size_t saved_length = 0;
1860 FILE *fp_decoded = NULL;
1861 int rc = 0;
1862
1863 first_part->goodsig = false;
1864 first_part->warnsig = false;
1865
1867 {
1868 b = b->parts->next;
1869 /* Some clients improperly encode the octetstream part. */
1870 if (b->encoding != ENC_7BIT)
1871 need_decode = true;
1872 }
1874 {
1875 b = b->parts->next->next;
1876 need_decode = true;
1877 }
1878 else
1879 {
1880 return -1;
1881 }
1882
1883 state.fp_in = fp_in;
1884
1885 if (need_decode)
1886 {
1887 saved_offset = b->offset;
1888 saved_length = b->length;
1889
1890 fp_decoded = mutt_file_mkstemp();
1891 if (!fp_decoded)
1892 {
1893 mutt_perror(_("Can't create temporary file"));
1894 return -1;
1895 }
1896
1897 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1898 {
1899 rc = -1;
1900 goto bail;
1901 }
1902 state.fp_out = fp_decoded;
1903
1904 mutt_decode_attachment(b, &state);
1905
1906 fflush(fp_decoded);
1907 b->length = ftello(fp_decoded);
1908 b->offset = 0;
1909 rewind(fp_decoded);
1910 state.fp_in = fp_decoded;
1911 state.fp_out = 0;
1912 }
1913
1914 *fp_out = mutt_file_mkstemp();
1915 if (!*fp_out)
1916 {
1917 mutt_perror(_("Can't create temporary file"));
1918 rc = -1;
1919 goto bail;
1920 }
1921
1922 *b_dec = decrypt_part(b, &state, *fp_out, false, &is_signed);
1923 if (*b_dec)
1924 {
1925 rewind(*fp_out);
1926 if (is_signed > 0)
1927 first_part->goodsig = true;
1928 }
1929 else
1930 {
1931 rc = -1;
1932 mutt_file_fclose(fp_out);
1933 }
1934
1935bail:
1936 if (need_decode)
1937 {
1938 b->length = saved_length;
1939 b->offset = saved_offset;
1940 mutt_file_fclose(&fp_decoded);
1941 }
1942
1943 return rc;
1944}
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:453
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:490
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:1693
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:771
#define mutt_file_fclose(FP)
Definition: file.h:148
#define mutt_perror(...)
Definition: logging2.h:93
void mutt_decode_attachment(struct Body *b, struct State *state)
Decode an email's attachment.
Definition: handler.c:1905
@ 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:72
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:71
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 1949 of file crypt_gpgme.c.

1950{
1951 struct State state = { 0 };
1952 int is_signed;
1953 LOFF_T saved_b_offset;
1954 size_t saved_b_length;
1955
1957 return -1;
1958
1959 if (b->parts)
1960 return -1;
1961
1962 /* Decode the body - we need to pass binary CMS to the
1963 * backend. The backend allows for Base64 encoded data but it does
1964 * not allow for QP which I have seen in some messages. So better
1965 * do it here. */
1966 saved_b_offset = b->offset;
1967 saved_b_length = b->length;
1968 state.fp_in = fp_in;
1969 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
1970 {
1971 return -1;
1972 }
1973 FILE *fp_tmp = mutt_file_mkstemp();
1974 if (!fp_tmp)
1975 {
1976 mutt_perror(_("Can't create temporary file"));
1977 return -1;
1978 }
1979
1980 state.fp_out = fp_tmp;
1981 mutt_decode_attachment(b, &state);
1982 fflush(fp_tmp);
1983 b->length = ftello(state.fp_out);
1984 b->offset = 0;
1985 rewind(fp_tmp);
1986
1987 memset(&state, 0, sizeof(state));
1988 state.fp_in = fp_tmp;
1989 state.fp_out = 0;
1991 if (!*fp_out)
1992 {
1993 mutt_perror(_("Can't create temporary file"));
1994 return -1;
1995 }
1996
1997 *b_dec = decrypt_part(b, &state, *fp_out, true, &is_signed);
1998 if (*b_dec)
1999 (*b_dec)->goodsig = is_signed > 0;
2000 b->length = saved_b_length;
2001 b->offset = saved_b_offset;
2002 mutt_file_fclose(&fp_tmp);
2003 rewind(*fp_out);
2004 if (*b_dec && !is_signed && !(*b_dec)->parts && mutt_is_application_smime(*b_dec))
2005 {
2006 /* Assume that this is a opaque signed s/mime message. This is an ugly way
2007 * of doing it but we have anyway a problem with arbitrary encoded S/MIME
2008 * messages: Only the outer part may be encrypted. The entire mime parsing
2009 * should be revamped, probably by keeping the temporary files so that we
2010 * don't need to decrypt them all the time. Inner parts of an encrypted
2011 * part can then point into this file and there won't ever be a need to
2012 * decrypt again. This needs a partial rewrite of the MIME engine. */
2013 struct Body *bb = *b_dec;
2014
2015 saved_b_offset = bb->offset;
2016 saved_b_length = bb->length;
2017 memset(&state, 0, sizeof(state));
2018 state.fp_in = *fp_out;
2019 if (!mutt_file_seek(state.fp_in, bb->offset, SEEK_SET))
2020 {
2021 return -1;
2022 }
2023 FILE *fp_tmp2 = mutt_file_mkstemp();
2024 if (!fp_tmp2)
2025 {
2026 mutt_perror(_("Can't create temporary file"));
2027 return -1;
2028 }
2029
2030 state.fp_out = fp_tmp2;
2031 mutt_decode_attachment(bb, &state);
2032 fflush(fp_tmp2);
2033 bb->length = ftello(state.fp_out);
2034 bb->offset = 0;
2035 rewind(fp_tmp2);
2036 mutt_file_fclose(fp_out);
2037
2038 memset(&state, 0, sizeof(state));
2039 state.fp_in = fp_tmp2;
2040 state.fp_out = 0;
2041 *fp_out = mutt_file_mkstemp();
2042 if (!*fp_out)
2043 {
2044 mutt_perror(_("Can't create temporary file"));
2045 return -1;
2046 }
2047
2048 struct Body *b_tmp = decrypt_part(bb, &state, *fp_out, true, &is_signed);
2049 if (b_tmp)
2050 b_tmp->goodsig = is_signed > 0;
2051 bb->length = saved_b_length;
2052 bb->offset = saved_b_offset;
2053 mutt_file_fclose(&fp_tmp2);
2054 rewind(*fp_out);
2055 mutt_body_free(b_dec);
2056 *b_dec = b_tmp;
2057 }
2058 return *b_dec ? 0 : -1;
2059}
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:595
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:77
+ 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 1163 of file pgp.c.

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

2057{
2058 struct State state = { 0 };
2059 LOFF_T tmpoffset = b->offset;
2060 size_t tmplength = b->length;
2061 int rc = -1;
2062
2064 return -1;
2065
2066 if (b->parts)
2067 return -1;
2068
2069 state.fp_in = fp_in;
2070 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
2071 {
2072 return -1;
2073 }
2074
2075 FILE *fp_tmp = mutt_file_mkstemp();
2076 if (!fp_tmp)
2077 {
2078 mutt_perror(_("Can't create temporary file"));
2079 return -1;
2080 }
2081
2082 state.fp_out = fp_tmp;
2083 mutt_decode_attachment(b, &state);
2084 fflush(fp_tmp);
2085 b->length = ftello(state.fp_out);
2086 b->offset = 0;
2087 rewind(fp_tmp);
2088 state.fp_in = fp_tmp;
2089 state.fp_out = 0;
2090
2092 if (!*fp_out)
2093 {
2094 mutt_perror(_("Can't create temporary file"));
2095 goto bail;
2096 }
2097
2098 *b_dec = smime_handle_entity(b, &state, *fp_out);
2099 if (!*b_dec)
2100 goto bail;
2101
2102 (*b_dec)->goodsig = b->goodsig;
2103 (*b_dec)->badsig = b->badsig;
2104 rc = 0;
2105
2106bail:
2107 b->length = tmplength;
2108 b->offset = tmpoffset;
2109 mutt_file_fclose(&fp_tmp);
2110 if (*fp_out)
2111 rewind(*fp_out);
2112
2113 return rc;
2114}
static struct Body * smime_handle_entity(struct Body *b, struct State *state, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition: smime.c:1818
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:43
+ Here is the call graph for this function: