No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-parser-multipart-signed.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-parser-multipart-signed.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-parser-multipart-signed.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include "e-mail-format-extensions.h"
24
25 #include <em-format/e-mail-parser-extension.h>
26 #include <em-format/e-mail-parser.h>
27 #include <em-format/e-mail-part-utils.h>
28
29 #include <glib/gi18n-lib.h>
30 #include <camel/camel.h>
31
32 typedef struct _EMailParserMultipartSigned {
33 GObject parent;
34 } EMailParserMultipartSigned;
35
36 typedef struct _EMailParserMultipartSignedClass {
37 GObjectClass parent_class;
38 } EMailParserMultipartSignedClass;
39
40 static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
41 static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
42
43 G_DEFINE_TYPE_EXTENDED (
44 EMailParserMultipartSigned,
45 e_mail_parser_multipart_signed,
46 G_TYPE_OBJECT,
47 0,
48 G_IMPLEMENT_INTERFACE (
49 E_TYPE_MAIL_EXTENSION,
50 e_mail_parser_mail_extension_interface_init)
51 G_IMPLEMENT_INTERFACE (
52 E_TYPE_MAIL_PARSER_EXTENSION,
53 e_mail_parser_parser_extension_interface_init));
54
55 static const gchar * parser_mime_types[] = { "multipart/signed",
56 "application/pgp-signature",
57 NULL };
58
59 static GSList *
60 empe_mp_signed_parse (EMailParserExtension *extension,
61 EMailParser *parser,
62 CamelMimePart *part,
63 GString *part_id,
64 GCancellable *cancellable)
65 {
66 CamelMimePart *cpart;
67 CamelMultipartSigned *mps;
68 CamelCipherContext *cipher = NULL;
69 CamelSession *session;
70 guint32 validity_type;
71 GSList *parts;
72 CamelCipherValidity *valid;
73 GError *local_error = NULL;
74 gint i, nparts, len;
75 gboolean secured;
76
77 if (g_cancellable_is_cancelled (cancellable))
78 return NULL;
79
80 /* If the part is application/pgp-signature sub-part then skip it. */
81 if (!CAMEL_IS_MULTIPART (part)) {
82 CamelContentType *ct;
83 ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (part));
84 if (camel_content_type_is (ct, "application", "pgp-signature")) {
85 return g_slist_alloc ();
86 }
87 }
88
89 mps = (CamelMultipartSigned *) camel_medium_get_content ((CamelMedium *) part);
90 if (!CAMEL_IS_MULTIPART_SIGNED (mps)
91 || (
92 cpart = camel_multipart_get_part (
93 (CamelMultipart *) mps,
94 CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
95 parts = e_mail_parser_error (
96 parser, cancellable,
97 _("Could not parse MIME message. "
98 "Displaying as source."));
99
100 parts = g_slist_concat (
101 parts,
102 e_mail_parser_parse_part_as (
103 parser, part, part_id,
104 "application/vnd.evolution.source",
105 cancellable));
106 return parts;
107 }
108
109 session = e_mail_parser_get_session (parser);
110 /* FIXME: Should be done via a plugin interface */
111 /* FIXME: duplicated in em-format-html-display.c */
112 if (mps->protocol) {
113 #ifdef ENABLE_SMIME
114 if (g_ascii_strcasecmp ("application/x-pkcs7-signature", mps->protocol) == 0
115 || g_ascii_strcasecmp ("application/pkcs7-signature", mps->protocol) == 0) {
116 cipher = camel_smime_context_new (session);
117 validity_type = E_MAIL_PART_VALIDITY_SMIME;
118 } else {
119 #endif
120 if (g_ascii_strcasecmp ("application/pgp-signature", mps->protocol) == 0) {
121 cipher = camel_gpg_context_new (session);
122 validity_type = E_MAIL_PART_VALIDITY_PGP;
123 }
124 #ifdef ENABLE_SMIME
125 }
126 #endif
127 }
128
129 if (cipher == NULL) {
130 parts = e_mail_parser_error (
131 parser, cancellable,
132 _("Unsupported signature format"));
133
134 parts = g_slist_concat (
135 parts,
136 e_mail_parser_parse_part_as (
137 parser, part, part_id,
138 "multipart/mixed", cancellable));
139
140 return parts;
141 }
142
143 valid = camel_cipher_context_verify_sync (
144 cipher, part, cancellable, &local_error);
145
146 if (local_error != NULL) {
147 parts = e_mail_parser_error (
148 parser, cancellable,
149 _("Error verifying signature: %s"),
150 local_error->message);
151
152 g_error_free (local_error);
153
154 parts = g_slist_concat (
155 parts,
156 e_mail_parser_parse_part_as (
157 parser, part, part_id,
158 "multipart/mixed", cancellable));
159
160 g_object_unref (cipher);
161 return parts;
162 }
163
164 nparts = camel_multipart_get_number (CAMEL_MULTIPART (mps));
165 secured = FALSE;
166 len = part_id->len;
167 parts = NULL;
168 for (i = 0; i < nparts; i++) {
169 CamelMimePart *subpart;
170 GSList *mail_parts, *iter;
171 subpart = camel_multipart_get_part (CAMEL_MULTIPART (mps), i);
172
173 g_string_append_printf (part_id, ".signed.%d", i);
174
175 mail_parts = e_mail_parser_parse_part (
176 parser, subpart, part_id, cancellable);
177
178 g_string_truncate (part_id, len);
179
180 if (!secured)
181 secured = e_mail_part_is_secured (subpart);
182
183 for (iter = mail_parts; iter; iter = iter->next) {
184 EMailPart *mail_part;
185
186 mail_part = iter->data;
187 if (!mail_part)
188 continue;
189
190 e_mail_part_update_validity (
191 mail_part, valid,
192 validity_type | E_MAIL_PART_VALIDITY_SIGNED);
193 }
194
195 parts = g_slist_concat (parts, mail_parts);
196 }
197
198 /* Add a widget with details about the encryption, but only when
199 * the encrypted isn't itself secured, in that case it has created
200 * the button itself */
201 if (!secured) {
202 GSList *button;
203 EMailPart *mail_part;
204 g_string_append (part_id, ".signed.button");
205
206 button = e_mail_parser_parse_part_as (
207 parser, part, part_id,
208 "application/vnd.evolution.widget.secure-button",
209 cancellable);
210 if (button && button->data) {
211 mail_part = button->data;
212
213 e_mail_part_update_validity (
214 mail_part, valid,
215 validity_type | E_MAIL_PART_VALIDITY_SIGNED);
216 }
217
218 parts = g_slist_concat (parts, button);
219
220 g_string_truncate (part_id, len);
221 }
222
223 camel_cipher_validity_free (valid);
224
225 g_object_unref (cipher);
226
227 return parts;
228 }
229
230 static const gchar **
231 empe_mp_signed_mime_types (EMailExtension *extension)
232 {
233 return parser_mime_types;
234 }
235
236 static void
237 e_mail_parser_multipart_signed_class_init (EMailParserMultipartSignedClass *class)
238 {
239 }
240
241 static void
242 e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
243 {
244 iface->parse = empe_mp_signed_parse;
245 }
246
247 static void
248 e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
249 {
250 iface->mime_types = empe_mp_signed_mime_types;
251 }
252
253 static void
254 e_mail_parser_multipart_signed_init (EMailParserMultipartSigned *parser)
255 {
256 }