NeoMutt  2022-04-29-249-gaae397
Teaching an old dog new tricks
DOXYGEN
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 **cur)
 Implements CryptModuleSpecs::decrypt_mime() -. More...
 
int smime_gpgme_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() -. More...
 
int pgp_class_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() -. More...
 
int smime_class_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
 Implements CryptModuleSpecs::decrypt_mime() -. More...
 

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]curBody 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 **  cur 
)

Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1846 of file crypt_gpgme.c.

1847{
1848 struct State s = { 0 };
1849 struct Body *first_part = b;
1850 int is_signed = 0;
1851 bool need_decode = false;
1852 LOFF_T saved_offset = 0;
1853 size_t saved_length = 0;
1854 FILE *fp_decoded = NULL;
1855 int rc = 0;
1856
1857 first_part->goodsig = false;
1858 first_part->warnsig = false;
1859
1861 {
1862 b = b->parts->next;
1863 /* Some clients improperly encode the octetstream part. */
1864 if (b->encoding != ENC_7BIT)
1865 need_decode = true;
1866 }
1868 {
1869 b = b->parts->next->next;
1870 need_decode = true;
1871 }
1872 else
1873 return -1;
1874
1875 s.fp_in = fp_in;
1876
1877 if (need_decode)
1878 {
1879 saved_offset = b->offset;
1880 saved_length = b->length;
1881
1882 fp_decoded = mutt_file_mkstemp();
1883 if (!fp_decoded)
1884 {
1885 mutt_perror(_("Can't create temporary file"));
1886 return -1;
1887 }
1888
1889 if (!mutt_file_seek(s.fp_in, b->offset, SEEK_SET))
1890 {
1891 rc = -1;
1892 goto bail;
1893 }
1894 s.fp_out = fp_decoded;
1895
1897
1898 fflush(fp_decoded);
1899 b->length = ftello(fp_decoded);
1900 b->offset = 0;
1901 rewind(fp_decoded);
1902 s.fp_in = fp_decoded;
1903 s.fp_out = 0;
1904 }
1905
1906 *fp_out = mutt_file_mkstemp();
1907 if (!*fp_out)
1908 {
1909 mutt_perror(_("Can't create temporary file"));
1910 rc = -1;
1911 goto bail;
1912 }
1913
1914 *cur = decrypt_part(b, &s, *fp_out, false, &is_signed);
1915 if (*cur)
1916 {
1917 rewind(*fp_out);
1918 if (is_signed > 0)
1919 first_part->goodsig = true;
1920 }
1921 else
1922 {
1923 rc = -1;
1924 mutt_file_fclose(fp_out);
1925 }
1926
1927bail:
1928 if (need_decode)
1929 {
1930 b->length = saved_length;
1931 b->offset = saved_offset;
1932 mutt_file_fclose(&fp_decoded);
1933 }
1934
1935 return rc;
1936}
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:463
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:500
static struct Body * decrypt_part(struct Body *a, struct State *s, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
Definition: crypt_gpgme.c:1688
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:690
#define mutt_file_mkstemp()
Definition: file.h:112
#define mutt_perror(...)
Definition: logging.h:88
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email's attachment.
Definition: handler.c:1867
@ 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:46
FILE * fp_out
File to write to.
Definition: state.h:48
FILE * fp_in
File to read from.
Definition: state.h:47
+ 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 **  cur 
)

Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1941 of file crypt_gpgme.c.

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

Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 1144 of file pgp.c.

1145{
1146 struct State s = { 0 };
1147 struct Body *p = b;
1148 bool need_decode = false;
1149 LOFF_T saved_offset = 0;
1150 size_t saved_length = 0;
1151 FILE *fp_decoded = NULL;
1152 int rc = 0;
1153
1155 {
1156 b = b->parts->next;
1157 /* Some clients improperly encode the octetstream part. */
1158 if (b->encoding != ENC_7BIT)
1159 need_decode = true;
1160 }
1162 {
1163 b = b->parts->next->next;
1164 need_decode = true;
1165 }
1166 else
1167 return -1;
1168
1169 s.fp_in = fp_in;
1170
1171 if (need_decode)
1172 {
1173 saved_offset = b->offset;
1174 saved_length = b->length;
1175
1176 fp_decoded = mutt_file_mkstemp();
1177 if (!fp_decoded)
1178 {
1179 mutt_perror(_("Can't create temporary file"));
1180 return -1;
1181 }
1182
1183 if (!mutt_file_seek(s.fp_in, b->offset, SEEK_SET))
1184 {
1185 rc = -1;
1186 goto bail;
1187 }
1188 s.fp_out = fp_decoded;
1189
1191
1192 fflush(fp_decoded);
1193 b->length = ftello(fp_decoded);
1194 b->offset = 0;
1195 rewind(fp_decoded);
1196 s.fp_in = fp_decoded;
1197 s.fp_out = 0;
1198 }
1199
1200 *fp_out = mutt_file_mkstemp();
1201 if (!*fp_out)
1202 {
1203 mutt_perror(_("Can't create temporary file"));
1204 rc = -1;
1205 goto bail;
1206 }
1207
1208 *cur = pgp_decrypt_part(b, &s, *fp_out, p);
1209 if (!*cur)
1210 rc = -1;
1211 rewind(*fp_out);
1212
1213bail:
1214 if (need_decode)
1215 {
1216 b->length = saved_length;
1217 b->offset = saved_offset;
1218 mutt_file_fclose(&fp_decoded);
1219 }
1220
1221 return rc;
1222}
static struct Body * pgp_decrypt_part(struct Body *a, struct State *s, FILE *fp_out, struct Body *p)
Decrypt part of a PGP message.
Definition: pgp.c:1008
+ 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 **  cur 
)

Implements CryptModuleSpecs::decrypt_mime() -.

Definition at line 2075 of file smime.c.

2076{
2077 struct State s = { 0 };
2078 LOFF_T tmpoffset = b->offset;
2079 size_t tmplength = b->length;
2080 int rc = -1;
2081
2083 return -1;
2084
2085 if (b->parts)
2086 return -1;
2087
2088 s.fp_in = fp_in;
2089 if (!mutt_file_seek(s.fp_in, b->offset, SEEK_SET))
2090 {
2091 return -1;
2092 }
2093
2094 FILE *fp_tmp = mutt_file_mkstemp();
2095 if (!fp_tmp)
2096 {
2097 mutt_perror(_("Can't create temporary file"));
2098 return -1;
2099 }
2100
2101 s.fp_out = fp_tmp;
2103 fflush(fp_tmp);
2104 b->length = ftello(s.fp_out);
2105 b->offset = 0;
2106 rewind(fp_tmp);
2107 s.fp_in = fp_tmp;
2108 s.fp_out = 0;
2109
2111 if (!*fp_out)
2112 {
2113 mutt_perror(_("Can't create temporary file"));
2114 goto bail;
2115 }
2116
2117 *cur = smime_handle_entity(b, &s, *fp_out);
2118 if (!*cur)
2119 goto bail;
2120
2121 (*cur)->goodsig = b->goodsig;
2122 (*cur)->badsig = b->badsig;
2123 rc = 0;
2124
2125bail:
2126 b->length = tmplength;
2127 b->offset = tmpoffset;
2128 mutt_file_fclose(&fp_tmp);
2129 if (*fp_out)
2130 rewind(*fp_out);
2131
2132 return rc;
2133}
static struct Body * smime_handle_entity(struct Body *m, struct State *s, FILE *fp_out_file)
Handle type application/pkcs7-mime.
Definition: smime.c:1840
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:43
+ Here is the call graph for this function: