evolution-3.6.4/em-format/e-mail-formatter-secure-button.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-formatter-secure-button.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-formatter-secure-button.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * evolution-secure-button.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 #include "e-mail-format-extensions.h"
 23 
 24 #include <glib/gi18n-lib.h>
 25 
 26 #include <em-format/e-mail-formatter-extension.h>
 27 #include <em-format/e-mail-formatter.h>
 28 #include <e-util/e-util.h>
 29 
 30 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
 31 #include "certificate-viewer.h"
 32 #include "e-cert-db.h"
 33 #endif
 34 
 35 #include <camel/camel.h>
 36 
 37 typedef struct _EMailFormatterSecureButton {
 38 	GObject parent;
 39 } EMailFormatterSecureButton;
 40 
 41 typedef struct _EMailFormatterSecureButtonClass {
 42 	GObjectClass parent_class;
 43 } EMailFormatterSecureButtonClass;
 44 
 45 static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
 46 static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
 47 
 48 G_DEFINE_TYPE_EXTENDED (
 49 	EMailFormatterSecureButton,
 50 	e_mail_formatter_secure_button,
 51 	G_TYPE_OBJECT,
 52 	0,
 53 	G_IMPLEMENT_INTERFACE (
 54 		E_TYPE_MAIL_EXTENSION,
 55 		e_mail_formatter_mail_extension_interface_init)
 56 	G_IMPLEMENT_INTERFACE (
 57 		E_TYPE_MAIL_FORMATTER_EXTENSION,
 58 		e_mail_formatter_formatter_extension_interface_init));
 59 
 60 static const gchar *formatter_mime_types[] = { "application/vnd.evolution.widget.secure-button", NULL };
 61 
 62 static const struct {
 63 	const gchar *icon, *shortdesc, *description;
 64 } smime_sign_table[5] = {
 65 	{ "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that this message is authentic.") },
 66 	{ "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that it is very likely that this message is authentic.") },
 67 	{ "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be verified, it may have been altered in transit.") },
 68 	{ "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with a valid signature, but the sender of the message cannot be verified.") },
 69 	{ "stock_signature-bad", N_("Signature exists, but need public key"), N_("This message is signed with a signature, but there is no corresponding public key.") },
 70 
 71 };
 72 
 73 static const struct {
 74 	const gchar *icon, *shortdesc, *description;
 75 } smime_encrypt_table[4] = {
 76 	{ "stock_lock-broken", N_("Unencrypted"), N_("This message is not encrypted. Its content may be viewed in transit across the Internet.") },
 77 	{ "stock_lock-ok", N_("Encrypted, weak"), N_("This message is encrypted, but with a weak encryption algorithm. It would be difficult, but not impossible for an outsider to view the content of this message in a practical amount of time.") },
 78 	{ "stock_lock-ok", N_("Encrypted"), N_("This message is encrypted.  It would be difficult for an outsider to view the content of this message.") },
 79 	{ "stock_lock-ok", N_("Encrypted, strong"), N_("This message is encrypted, with a strong encryption algorithm. It would be very difficult for an outsider to view the content of this message in a practical amount of time.") },
 80 };
 81 
 82 static const GdkRGBA smime_sign_colour[5] = {
 83 	{ 0 }, { 0.53, 0.73, 0.53, 1 }, { 0.73, 0.53, 0.53, 1 }, { 0.91, 0.82, 0.13, 1 }, { 0 },
 84 };
 85 
 86 static gboolean
 87 emfe_secure_button_format (EMailFormatterExtension *extension,
 88                            EMailFormatter *formatter,
 89                            EMailFormatterContext *context,
 90                            EMailPart *part,
 91                            CamelStream *stream,
 92                            GCancellable *cancellable)
 93 {
 94 	gchar *str;
 95 
 96 	if ((context->mode != E_MAIL_FORMATTER_MODE_NORMAL) &&
 97 	    (context->mode != E_MAIL_FORMATTER_MODE_RAW) &&
 98 	    (context->mode != E_MAIL_FORMATTER_MODE_ALL_HEADERS))
 99 		return FALSE;
100 
101 	str = g_strdup_printf (
102 		"<object type=\"application/vnd.evolution.widget.secure-button\" "
103 		"height=\"20\" width=\"100%%\" data=\"%s\" id=\"%s\"></object>",
104 		part->id, part->id);
105 
106 	camel_stream_write_string (stream, str, cancellable, NULL);
107 
108 	g_free (str);
109 	return TRUE;
110 }
111 
112 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
113 static void
114 viewcert_clicked (GtkWidget *button,
115                   GtkWidget *parent)
116 {
117 	CamelCipherCertInfo *info = g_object_get_data ((GObject *) button, "e-cert-info");
118 	ECert *ec = NULL;
119 
120 	if (info->cert_data)
121 		ec = e_cert_new (CERT_DupCertificate (info->cert_data));
122 
123 	if (ec != NULL) {
124 		GtkWidget *w = certificate_viewer_show (ec);
125 
126 		/* oddly enough certificate_viewer_show doesn't ... */
127 		gtk_widget_show (w);
128 		g_signal_connect (
129 			w, "response",
130 			G_CALLBACK (gtk_widget_destroy), NULL);
131 
132 		if (w && parent)
133 			gtk_window_set_transient_for (
134 				(GtkWindow *) w, (GtkWindow *) parent);
135 
136 		g_object_unref (ec);
137 	} else {
138 		g_warning (
139 			"can't find certificate for %s <%s>",
140 			info->name ? info->name : "",
141 			info->email ? info->email : "");
142 	}
143 }
144 #endif
145 
146 static void
147 info_response (GtkWidget *widget,
148                guint button,
149                gpointer user_data)
150 {
151 	gtk_widget_destroy (widget);
152 }
153 
154 static void
155 add_cert_table (GtkWidget *grid,
156                 GQueue *certlist,
157                 gpointer user_data)
158 {
159 	GList *head, *link;
160 	GtkTable *table;
161 	gint n = 0;
162 
163 	table = (GtkTable *) gtk_table_new (certlist->length, 2, FALSE);
164 
165 	head = g_queue_peek_head_link (certlist);
166 
167 	for (link = head; link != NULL; link = g_list_next (link)) {
168 		CamelCipherCertInfo *info = link->data;
169 		gchar *la = NULL;
170 		const gchar *l = NULL;
171 
172 		if (info->name) {
173 			if (info->email && strcmp (info->name, info->email) != 0)
174 				l = la = g_strdup_printf ("%s <%s>", info->name, info->email);
175 			else
176 				l = info->name;
177 		} else {
178 			if (info->email)
179 				l = info->email;
180 		}
181 
182 		if (l) {
183 			GtkWidget *w;
184 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
185 			ECert *ec = NULL;
186 #endif
187 			w = gtk_label_new (l);
188 			gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
189 			g_free (la);
190 			gtk_table_attach (table, w, 0, 1, n, n + 1, GTK_FILL, GTK_FILL, 3, 3);
191 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
192 			w = gtk_button_new_with_mnemonic (_("_View Certificate"));
193 			gtk_table_attach (table, w, 1, 2, n, n + 1, 0, 0, 3, 3);
194 			g_object_set_data ((GObject *) w, "e-cert-info", info);
195 			g_signal_connect (
196 				w, "clicked",
197 				G_CALLBACK (viewcert_clicked), grid);
198 
199 			if (info->cert_data)
200 				ec = e_cert_new (CERT_DupCertificate (info->cert_data));
201 
202 			if (ec == NULL)
203 				gtk_widget_set_sensitive (w, FALSE);
204 			else
205 				g_object_unref (ec);
206 #else
207 			w = gtk_label_new (_("This certificate is not viewable"));
208 			gtk_table_attach (table, w, 1, 2, n, n + 1, 0, 0, 3, 3);
209 #endif
210 			n++;
211 		}
212 	}
213 
214 	gtk_container_add (GTK_CONTAINER (grid), GTK_WIDGET (table));
215 }
216 
217 static void
218 format_cert_infos (GQueue *cert_infos,
219                    GString *output_buffer)
220 {
221 	GQueue valid = G_QUEUE_INIT;
222 	GList *head, *link;
223 
224 	head = g_queue_peek_head_link (cert_infos);
225 
226 	/* Make sure we have a valid CamelCipherCertInfo before
227 	 * appending anything to the output buffer, so we don't
228 	 * end up with "()". */
229 	for (link = head; link != NULL; link = g_list_next (link)) {
230 		CamelCipherCertInfo *cinfo = link->data;
231 
232 		if ((cinfo->name != NULL && *cinfo->name != '\0') ||
233 		    (cinfo->email != NULL && *cinfo->email != '\0')) {
234 			g_queue_push_tail (&valid, cinfo);
235 		}
236 	}
237 
238 	if (g_queue_is_empty (&valid))
239 		return;
240 
241 	g_string_append (output_buffer, " (");
242 
243 	while (!g_queue_is_empty (&valid)) {
244 		CamelCipherCertInfo *cinfo;
245 
246 		cinfo = g_queue_pop_head (&valid);
247 
248 		if (cinfo->name != NULL && *cinfo->name != '\0') {
249 			g_string_append (output_buffer, cinfo->name);
250 
251 			if (cinfo->email != NULL && *cinfo->email != '\0') {
252 				g_string_append (output_buffer, " <");
253 				g_string_append (output_buffer, cinfo->email);
254 				g_string_append (output_buffer, ">");
255 			}
256 
257 		} else if (cinfo->email != NULL && *cinfo->email != '\0') {
258 			g_string_append (output_buffer, cinfo->email);
259 		}
260 
261 		if (!g_queue_is_empty (&valid))
262 			g_string_append (output_buffer, ", ");
263 	}
264 
265 	g_string_append_c (output_buffer, ')');
266 }
267 
268 static void
269 secure_button_clicked_cb (GtkWidget *widget,
270                           EMailPart *part)
271 {
272 	GtkBuilder *builder;
273 	GtkWidget *grid, *w;
274 	GtkWidget *dialog;
275 
276 	builder = gtk_builder_new ();
277 	e_load_ui_builder_definition (builder, "mail-dialogs.ui");
278 
279 	dialog = e_builder_get_widget (builder, "message_security_dialog");
280 
281 	grid = e_builder_get_widget (builder, "signature_grid");
282 	w = gtk_label_new (_(smime_sign_table[part->validity->sign.status].description));
283 	gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
284 	gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
285 	gtk_container_add (GTK_CONTAINER (grid), w);
286 	if (part->validity->sign.description) {
287 		GtkTextBuffer *buffer;
288 
289 		buffer = gtk_text_buffer_new (NULL);
290 		gtk_text_buffer_set_text (
291 			buffer, part->validity->sign.description,
292 			strlen (part->validity->sign.description));
293 		w = g_object_new (
294 			gtk_scrolled_window_get_type (),
295 			"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
296 			"vscrollbar_policy", GTK_POLICY_AUTOMATIC,
297 			"shadow_type", GTK_SHADOW_IN,
298 			"expand", TRUE,
299 			"child", g_object_new (gtk_text_view_get_type (),
300 			"buffer", buffer,
301 			"cursor_visible", FALSE,
302 			"editable", FALSE,
303 			"width_request", 500,
304 			"height_request", 160,
305 			NULL),
306 			NULL);
307 		g_object_unref (buffer);
308 
309 		gtk_container_add (GTK_CONTAINER (grid), w);
310 	}
311 
312 	if (!g_queue_is_empty (&part->validity->sign.signers))
313 		add_cert_table (
314 			grid, &part->validity->sign.signers, NULL);
315 
316 	gtk_widget_show_all (grid);
317 
318 	grid = e_builder_get_widget (builder, "encryption_grid");
319 	w = gtk_label_new (_(smime_encrypt_table[part->validity->encrypt.status].description));
320 	gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
321 	gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
322 	gtk_container_add (GTK_CONTAINER (grid), w);
323 	if (part->validity->encrypt.description) {
324 		GtkTextBuffer *buffer;
325 
326 		buffer = gtk_text_buffer_new (NULL);
327 		gtk_text_buffer_set_text (
328 			buffer, part->validity->encrypt.description,
329 			strlen (part->validity->encrypt.description));
330 		w = g_object_new (
331 			gtk_scrolled_window_get_type (),
332 			"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
333 			"vscrollbar_policy", GTK_POLICY_AUTOMATIC,
334 			"shadow_type", GTK_SHADOW_IN,
335 			"expand", TRUE,
336 			"child", g_object_new (gtk_text_view_get_type (),
337 			"buffer", buffer,
338 			"cursor_visible", FALSE,
339 			"editable", FALSE,
340 			"width_request", 500,
341 			"height_request", 160,
342 			NULL),
343 			NULL);
344 		g_object_unref (buffer);
345 
346 		gtk_container_add (GTK_CONTAINER (grid), w);
347 	}
348 
349 	if (!g_queue_is_empty (&part->validity->encrypt.encrypters))
350 		add_cert_table (grid, &part->validity->encrypt.encrypters, NULL);
351 
352 	gtk_widget_show_all (grid);
353 
354 	g_object_unref (builder);
355 
356 	g_signal_connect (
357 		dialog, "response",
358 		G_CALLBACK (info_response), NULL);
359 
360 	gtk_widget_show (dialog);
361 }
362 
363 static GtkWidget *
364 emfe_secure_button_get_widget (EMailFormatterExtension *extension,
365                                EMailPartList *context,
366                                EMailPart *part,
367                                GHashTable *params)
368 {
369 	GtkWidget *box, *button, *layout, *widget;
370 	const gchar *icon_name;
371 	gchar *description;
372 	GString *buffer;
373 	buffer = g_string_new ("");
374 
375 	if (part->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
376 		const gchar *desc;
377 		gint status;
378 
379 		status = part->validity->sign.status;
380 		desc = smime_sign_table[status].shortdesc;
381 
382 		g_string_append (buffer, gettext (desc));
383 
384 		format_cert_infos (&part->validity->sign.signers, buffer);
385 	}
386 
387 	if (part->validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
388 		const gchar *desc;
389 		gint status;
390 
391 		if (part->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)
392 			g_string_append (buffer, "\n");
393 
394 		status = part->validity->encrypt.status;
395 		desc = smime_encrypt_table[status].shortdesc;
396 		g_string_append (buffer, gettext (desc));
397 	}
398 
399 	description = g_string_free (buffer, FALSE);
400 
401 	/* FIXME: need to have it based on encryption and signing too */
402 	if (part->validity->sign.status != 0)
403 		icon_name = smime_sign_table[part->validity->sign.status].icon;
404 	else
405 		icon_name = smime_encrypt_table[part->validity->encrypt.status].icon;
406 
407 	box = gtk_event_box_new ();
408 	if (part->validity->sign.status != 0)
409 		gtk_widget_override_background_color (
410 			box, GTK_STATE_FLAG_NORMAL,
411 			&smime_sign_colour[part->validity->sign.status]);
412 
413 	layout = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
414 	gtk_container_add (GTK_CONTAINER (box), layout);
415 
416 	button = gtk_button_new ();
417 	gtk_box_pack_start (GTK_BOX (layout), button, FALSE, FALSE, 0);
418 	g_signal_connect (
419 		button, "clicked",
420 		G_CALLBACK (secure_button_clicked_cb), part);
421 
422 	widget = gtk_image_new_from_icon_name (
423 			icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
424 	gtk_button_set_image (GTK_BUTTON (button), widget);
425 
426 	widget = gtk_label_new (description);
427 	gtk_box_pack_start (GTK_BOX (layout), widget, FALSE, FALSE, 0);
428 
429 	gtk_widget_show_all (box);
430 
431 	g_free (description);
432 	return box;
433 }
434 
435 static const gchar *
436 emfe_secure_button_get_display_name (EMailFormatterExtension *extension)
437 {
438 	return NULL;
439 }
440 
441 static const gchar *
442 emfe_secure_button_get_description (EMailFormatterExtension *extension)
443 {
444 	return NULL;
445 }
446 
447 static const gchar **
448 emfe_secure_button_mime_types (EMailExtension *extension)
449 {
450 	return formatter_mime_types;
451 }
452 
453 static void
454 e_mail_formatter_secure_button_class_init (EMailFormatterSecureButtonClass *class)
455 {
456 }
457 
458 static void
459 e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
460 {
461 	iface->format = emfe_secure_button_format;
462 	iface->get_widget = emfe_secure_button_get_widget;
463 	iface->get_display_name = emfe_secure_button_get_display_name;
464 	iface->get_description = emfe_secure_button_get_description;
465 }
466 
467 static void
468 e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
469 {
470 	iface->mime_types = emfe_secure_button_mime_types;
471 }
472 
473 static void
474 e_mail_formatter_secure_button_init (EMailFormatterSecureButton *extension)
475 {
476 
477 }