NeoMutt  2023-11-03-85-g512e01
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 1851 of file crypt_gpgme.c.

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

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

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

2095{
2096 struct State state = { 0 };
2097 LOFF_T tmpoffset = b->offset;
2098 size_t tmplength = b->length;
2099 int rc = -1;
2100
2102 return -1;
2103
2104 if (b->parts)
2105 return -1;
2106
2107 state.fp_in = fp_in;
2108 if (!mutt_file_seek(state.fp_in, b->offset, SEEK_SET))
2109 {
2110 return -1;
2111 }
2112
2113 FILE *fp_tmp = mutt_file_mkstemp();
2114 if (!fp_tmp)
2115 {
2116 mutt_perror(_("Can't create temporary file"));
2117 return -1;
2118 }
2119
2120 state.fp_out = fp_tmp;
2121 mutt_decode_attachment(b, &state);
2122 fflush(fp_tmp);
2123 b->length = ftello(state.fp_out);
2124 b->offset = 0;
2125 rewind(fp_tmp);
2126 state.fp_in = fp_tmp;
2127 state.fp_out = 0;
2128
2130 if (!*fp_out)
2131 {
2132 mutt_perror(_("Can't create temporary file"));
2133 goto bail;
2134 }
2135
2136 *b_dec = smime_handle_entity(b, &state, *fp_out);
2137 if (!*b_dec)
2138 goto bail;
2139
2140 (*b_dec)->goodsig = b->goodsig;
2141 (*b_dec)->badsig = b->badsig;
2142 rc = 0;
2143
2144bail:
2145 b->length = tmplength;
2146 b->offset = tmpoffset;
2147 mutt_file_fclose(&fp_tmp);
2148 if (*fp_out)
2149 rewind(*fp_out);
2150
2151 return rc;
2152}
static struct Body * smime_handle_entity(struct Body *b, struct State *state, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition: smime.c:1856
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:43
+ Here is the call graph for this function: