1 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
2 /* Balsa E-Mail Client
3  * Copyright (C) 1997-2013 Stuart Parmenter and others,
4  *                         See the file AUTHORS for a list.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21 #if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
22 # include "config.h"
23 #endif                          /* HAVE_CONFIG_H */
24 #include "rfc3156.h"
25 
26 #ifdef HAVE_GPGME
27 
28 #include <string.h>
29 #include <gpgme.h>
30 #include <pwd.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <stdlib.h>
34 
35 #include "libbalsa.h"
36 #include "libbalsa_private.h"
37 
38 #include "gmime-multipart-crypt.h"
39 #include "gmime-gpgme-signature.h"
40 #include "gmime-part-rfc2440.h"
41 
42 #ifdef HAVE_SMIME
43 #  include "gmime-application-pkcs7.h"
44 #endif
45 
46 #ifdef BALSA_USE_THREADS
47 #  include <pthread.h>
48 #  include "misc.h"
49 #endif
50 
51 #if HAVE_MACOSX_DESKTOP
52 #  include "macosx-helpers.h"
53 #endif
54 
55 #include <glib/gi18n.h>
56 
57 
58 /* local prototypes */
59 static gboolean gpg_updates_trustdb(void);
60 static gboolean have_pub_key_for(gpgme_ctx_t gpgme_ctx,
61 				 InternetAddressList * recipients);
62 
63 
64 /* ==== public functions =================================================== */
65 static gboolean
body_is_type(LibBalsaMessageBody * body,const gchar * type,const gchar * sub_type)66 body_is_type(LibBalsaMessageBody * body, const gchar * type,
67 	     const gchar * sub_type)
68 {
69     gboolean retval;
70 
71     if (body->mime_part) {
72 	GMimeContentType *content_type =
73 	    g_mime_object_get_content_type(body->mime_part);
74 	retval = g_mime_content_type_is_type(content_type, type, sub_type);
75     } else {
76 	GMimeContentType *content_type =
77 	    g_mime_content_type_new_from_string(body->content_type);
78 	retval = g_mime_content_type_is_type(content_type, type, sub_type);
79 	g_object_unref(content_type);
80     }
81 
82     return retval;
83 }
84 
85 
86 /* return TRUE if we can encrypt for every recipient in the recipients list
87  * using protocol */
88 gboolean
libbalsa_can_encrypt_for_all(InternetAddressList * recipients,gpgme_protocol_t protocol)89 libbalsa_can_encrypt_for_all(InternetAddressList * recipients,
90 			     gpgme_protocol_t protocol)
91 {
92     gpgme_ctx_t gpgme_ctx;
93     gboolean result;
94 
95     /* silent paranoia checks */
96     if (!recipients)
97 	return TRUE;  /* we can of course encrypt for nobody... */
98 #ifndef HAVE_SMIME
99     if (protocol == GPGME_PROTOCOL_OpenPGP)
100 	return FALSE;
101 #endif
102 
103     /* check if gpg is currently available */
104     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
105 	return FALSE;
106 
107     /* create the gpgme context and set the protocol */
108     if (gpgme_new(&gpgme_ctx) != GPG_ERR_NO_ERROR)
109 	return FALSE;
110     if (gpgme_set_protocol(gpgme_ctx, protocol) != GPG_ERR_NO_ERROR) {
111 	gpgme_release(gpgme_ctx);
112 	return FALSE;
113     }
114 
115     /* loop over all recipients and try to find valid keys */
116     result = have_pub_key_for(gpgme_ctx, recipients);
117     gpgme_release(gpgme_ctx);
118 
119     return result;
120 }
121 
122 
123 /*
124  * Check if body (and eventually its subparts) are RFC 2633 or RFC 3156 signed
125  * or encrypted.
126  */
127 gint
libbalsa_message_body_protection(LibBalsaMessageBody * body)128 libbalsa_message_body_protection(LibBalsaMessageBody * body)
129 {
130     gint result = 0;
131 
132     g_return_val_if_fail(body != NULL, 0);
133     g_return_val_if_fail(body->content_type != NULL, 0);
134 
135     if (body_is_type(body, "multipart", "signed")) {
136 	gchar *protocol =
137 	    libbalsa_message_body_get_parameter(body, "protocol");
138 	gchar *micalg =
139 	    libbalsa_message_body_get_parameter(body, "micalg");
140 
141 	result = LIBBALSA_PROTECT_SIGN;
142 	if (protocol && body->parts && body->parts->next) {
143 	    if ((!g_ascii_strcasecmp("application/pkcs7-signature",
144 				     protocol)
145 		 && body_is_type(body->parts->next, "application",
146 				 "pkcs7-signature")) ||
147 		(!g_ascii_strcasecmp("application/x-pkcs7-signature",
148 				     protocol)
149 		 && body_is_type(body->parts->next, "application",
150 				 "x-pkcs7-signature"))) {
151 		result |= LIBBALSA_PROTECT_SMIMEV3;
152 		if (!micalg)
153 		    result |= LIBBALSA_PROTECT_ERROR;
154 	    } else
155 		if (!g_ascii_strcasecmp
156 		    ("application/pgp-signature", protocol)
157 		    && body_is_type(body->parts->next, "application",
158 				    "pgp-signature")) {
159 		result |= LIBBALSA_PROTECT_RFC3156;
160 		if (!micalg || g_ascii_strncasecmp("pgp-", micalg, 4))
161 		    result |= LIBBALSA_PROTECT_ERROR;
162 	    } else
163 		result |= LIBBALSA_PROTECT_ERROR;
164 	} else
165 	    result |= LIBBALSA_PROTECT_ERROR;
166 	g_free(micalg);
167 	g_free(protocol);
168     } else if (body_is_type(body, "multipart", "encrypted")) {
169 	gchar *protocol =
170 	    libbalsa_message_body_get_parameter(body, "protocol");
171 
172 	result = LIBBALSA_PROTECT_ENCRYPT | LIBBALSA_PROTECT_RFC3156;
173 	if (!protocol ||
174 	    g_ascii_strcasecmp("application/pgp-encrypted", protocol) ||
175 	    !body->parts || !body->parts->next ||
176 	    !body_is_type(body->parts, "application", "pgp-encrypted") ||
177 	    !body_is_type(body->parts->next, "application",
178 			  "octet-stream"))
179 	    result |= LIBBALSA_PROTECT_ERROR;
180 	g_free(protocol);
181     } else if (body_is_type(body, "application", "pkcs7-mime")) {
182 	gchar *smime_type =
183 	    libbalsa_message_body_get_parameter(body, "smime-type");
184 
185 	result = LIBBALSA_PROTECT_SMIMEV3;
186 	if (!g_ascii_strcasecmp("enveloped-data", smime_type) ||
187 	    !g_ascii_strcasecmp("signed-data", smime_type))
188 	    result |= LIBBALSA_PROTECT_ENCRYPT;
189 	else
190 	    result |= LIBBALSA_PROTECT_ERROR;
191 	g_free(smime_type);
192     }
193 
194     return result;
195 }
196 
197 
198 /* === RFC 2633/ RFC 3156 crypto routines === */
199 /*
200  * Signs the MIME object *content with the private key of rfc822_for using
201  * protocol. Return TRUE on success (in which case *content is replaced by the
202  * new MIME object).
203  * Note: In RFC 2633 mode (GPGME_PROTOCOL_CMS), this function creates a
204  * multipart/signed instead of an application/pkcs7-mime, as the latter one
205  * doesn't contain a cleartext also readable for MUA's without S/MIME support.
206  */
207 gboolean
libbalsa_sign_mime_object(GMimeObject ** content,const gchar * rfc822_for,gpgme_protocol_t protocol,GtkWindow * parent,GError ** error)208 libbalsa_sign_mime_object(GMimeObject ** content, const gchar * rfc822_for,
209 			  gpgme_protocol_t protocol, GtkWindow * parent,
210 			  GError ** error)
211 {
212     GMimeMultipartSigned *mps;
213 
214     /* paranoia checks */
215     g_return_val_if_fail(rfc822_for != NULL, FALSE);
216     g_return_val_if_fail(content != NULL, FALSE);
217 #ifndef HAVE_SMIME
218     g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP, FALSE);
219 #endif
220 
221     /* check if gpg is currently available */
222     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
223 	return FALSE;
224 
225     /* call gpgme to create the signature */
226     if (!(mps = g_mime_multipart_signed_new())) {
227 	return FALSE;
228     }
229 
230     if (g_mime_gpgme_mps_sign(mps, *content, rfc822_for, protocol, parent, error) != 0) {
231 	g_object_unref(mps);
232 	return FALSE;
233     }
234 
235     g_object_unref(G_OBJECT(*content));
236     *content = GMIME_OBJECT(mps);
237     return TRUE;
238 }
239 
240 
241 /*
242  * Encrypts MIME object *content for every recipient in the array rfc822_for
243  * using protocol. If successful, return TRUE and replace *content by the new
244  * MIME object.
245  */
246 gboolean
libbalsa_encrypt_mime_object(GMimeObject ** content,GList * rfc822_for,gpgme_protocol_t protocol,gboolean always_trust,GtkWindow * parent,GError ** error)247 libbalsa_encrypt_mime_object(GMimeObject ** content, GList * rfc822_for,
248 			     gpgme_protocol_t protocol, gboolean always_trust,
249 			     GtkWindow * parent, GError ** error)
250 {
251     GMimeObject *encrypted_obj = NULL;
252     GPtrArray *recipients;
253     int result = -1;
254 
255     /* paranoia checks */
256     g_return_val_if_fail(rfc822_for != NULL, FALSE);
257     g_return_val_if_fail(content != NULL, FALSE);
258 #ifndef HAVE_SMIME
259     g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP, FALSE);
260 #endif
261 
262     /* check if gpg is currently available */
263     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
264 	return FALSE;
265 
266     /* convert the key list to a GPtrArray */
267     recipients = g_ptr_array_new();
268     while (rfc822_for) {
269 	g_ptr_array_add(recipients, rfc822_for->data);
270 	rfc822_for = g_list_next(rfc822_for);
271     }
272 
273     /* encrypt: multipart/encrypted for RFC 3156, application/pkcs7-mime for
274        RFC 2633 */
275     if (protocol == GPGME_PROTOCOL_OpenPGP) {
276 	GMimeMultipartEncrypted *mpe = g_mime_multipart_encrypted_new();
277 
278 	encrypted_obj = GMIME_OBJECT(mpe);
279 	result = g_mime_gpgme_mpe_encrypt(mpe, *content, recipients, always_trust, parent, error);
280     }
281 #ifdef HAVE_SMIME
282     else {
283 	GMimePart *pkcs7 =
284 	    g_mime_part_new_with_type("application", "pkcs7-mime");
285 
286 	result = g_mime_application_pkcs7_encrypt(pkcs7, *content, recipients, always_trust, parent, error);
287     }
288 #endif
289     g_ptr_array_free(recipients, FALSE);
290 
291     /* error checking */
292     if (result != 0) {
293 	g_object_unref(encrypted_obj);
294 	return FALSE;
295     } else {
296     g_object_unref(G_OBJECT(*content));
297     *content = GMIME_OBJECT(encrypted_obj);
298     return TRUE;
299     }
300 }
301 
302 
303 /*
304  * Signs the MIME object *content with the private key of rfc822_signer and
305  * then encrypt the result for all recipients in rfc822_for using protocol.
306  * Return TRUE on success (in which case *content is replaced by the new
307  * MIME object).
308  */
309 gboolean
libbalsa_sign_encrypt_mime_object(GMimeObject ** content,const gchar * rfc822_signer,GList * rfc822_for,gpgme_protocol_t protocol,gboolean always_trust,GtkWindow * parent,GError ** error)310 libbalsa_sign_encrypt_mime_object(GMimeObject ** content,
311 				  const gchar * rfc822_signer,
312 				  GList * rfc822_for,
313 				  gpgme_protocol_t protocol,
314 				  gboolean always_trust,
315 				  GtkWindow * parent,
316 				  GError ** error)
317 {
318     GMimeObject *signed_object;
319 
320     /* paranoia checks */
321     g_return_val_if_fail(rfc822_signer != NULL, FALSE);
322     g_return_val_if_fail(rfc822_for != NULL, FALSE);
323     g_return_val_if_fail(content != NULL, FALSE);
324 #ifndef HAVE_SMIME
325     g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP, FALSE);
326 #endif
327 
328     /* check if gpg is currently available */
329     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
330 	return FALSE;
331 
332     /* we want to be able to restore */
333     signed_object = *content;
334     g_object_ref(G_OBJECT(signed_object));
335 
336     if (!libbalsa_sign_mime_object(&signed_object, rfc822_signer, protocol,
337 				   parent, error))
338 	return FALSE;
339 
340     if (!libbalsa_encrypt_mime_object(&signed_object, rfc822_for, protocol,
341 				      always_trust, parent, error)) {
342 	g_object_unref(G_OBJECT(signed_object));
343 	return FALSE;
344     }
345     g_object_unref(G_OBJECT(*content));
346     *content = signed_object;
347 
348     return TRUE;
349 }
350 
351 
352 /*
353  * Check the signature of body (which must be a multipart/signed). On
354  * success, set the sig_info field of the signature part. It succeeds
355  * if all the data needed to verify the signature (gpg database, the
356  * complete signed part itself) were available and the verification
357  * was attempted. Please observe that failure means in this context a
358  * temporary one. Information about failed signature verifications are
359  * passed through LibBalsaBody::sig_info.
360  */
361 gboolean
libbalsa_body_check_signature(LibBalsaMessageBody * body,gpgme_protocol_t protocol)362 libbalsa_body_check_signature(LibBalsaMessageBody * body,
363 			      gpgme_protocol_t protocol)
364 {
365     GError *error = NULL;
366     GMimeGpgmeSigstat *result;
367 
368     /* paranoia checks */
369     g_return_val_if_fail(body, FALSE);
370     g_return_val_if_fail(body->mime_part != NULL, FALSE);
371     g_return_val_if_fail(body->message, FALSE);
372 #ifndef HAVE_SMIME
373     g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP, FALSE);
374 #endif
375 
376     /* check if gpg is currently available */
377     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
378 	return FALSE;
379 
380     /* check if the body is really a multipart/signed */
381     if (!GMIME_IS_MULTIPART_SIGNED(body->mime_part)
382         || (g_mime_multipart_get_count
383             (((GMimeMultipart *) body->mime_part))) < 2)
384         return FALSE;
385     if (body->parts->next->sig_info)
386 	g_object_unref(G_OBJECT(body->parts->next->sig_info));
387 
388     /* verify the signature */
389     libbalsa_mailbox_lock_store(body->message->mailbox);
390     result = g_mime_gpgme_mps_verify(GMIME_MULTIPART_SIGNED(body->mime_part), &error);
391     if (!result || result->status != GPG_ERR_NO_ERROR) {
392 	if (error) {
393 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
394 				 _("signature verification failed"),
395 				 error->message);
396 	    g_error_free(error);
397 	} else
398 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR,
399 				 _("signature verification failed"));
400     }
401 
402     body->parts->next->sig_info = result;
403     libbalsa_mailbox_unlock_store(body->message->mailbox);
404     return TRUE;
405 }
406 
407 
408 /*
409  * Body points to an application/pgp-encrypted body. If decryption is
410  * successful, it is freed, and the routine returns a pointer to the chain of
411  * decrypted bodies. Otherwise, the original body is returned.
412  */
413 LibBalsaMessageBody *
libbalsa_body_decrypt(LibBalsaMessageBody * body,gpgme_protocol_t protocol,GtkWindow * parent)414 libbalsa_body_decrypt(LibBalsaMessageBody *body, gpgme_protocol_t protocol, GtkWindow *parent)
415 {
416     GMimeObject *mime_obj = NULL;
417     GError *error = NULL;
418     LibBalsaMessage *message;
419     GMimeGpgmeSigstat *sig_state = NULL;
420 #ifdef HAVE_SMIME
421     gboolean smime_encrypted = FALSE;
422 #endif
423 
424     /* paranoia checks */
425     g_return_val_if_fail(body != NULL, body);
426     g_return_val_if_fail(body->mime_part != NULL, body);
427     g_return_val_if_fail(body->message != NULL, body);
428 #ifndef HAVE_SMIME
429     g_return_val_if_fail(protocol == GPGME_PROTOCOL_OpenPGP, FALSE);
430 #endif
431 
432     /* check if gpg is currently available */
433     if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
434 	return body;
435 
436     /* sanity checks... */
437     if (protocol == GPGME_PROTOCOL_OpenPGP) {
438 	if (!GMIME_IS_MULTIPART_ENCRYPTED(body->mime_part))
439 	    return body;
440     }
441 #ifdef HAVE_SMIME
442     else {
443 	const char * smime_type =
444 	    g_mime_object_get_content_type_parameter(body->mime_part,
445 						     "smime-type");
446 
447 	if (!smime_type || !GMIME_IS_PART(body->mime_part))
448 	    return body;
449 	if (!g_ascii_strcasecmp(smime_type, "enveloped-data"))
450 	    smime_encrypted = FALSE;
451     }
452 #endif
453 
454     libbalsa_mailbox_lock_store(body->message->mailbox);
455     if (protocol == GPGME_PROTOCOL_OpenPGP)
456 	mime_obj =
457 	    g_mime_gpgme_mpe_decrypt(GMIME_MULTIPART_ENCRYPTED(body->mime_part),
458 				     &sig_state, parent, &error);
459 #ifdef HAVE_SMIME
460     else
461 	mime_obj =
462 	    g_mime_application_pkcs7_decrypt_verify(GMIME_PART(body->mime_part),
463 						    &sig_state, parent, &error);
464 #endif
465     libbalsa_mailbox_unlock_store(body->message->mailbox);
466 
467     /* check the result */
468     if (mime_obj == NULL) {
469 	if (error) {
470 	    if (error->code != GPG_ERR_CANCELED)
471 		libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
472 				     _("decryption failed"),
473 				     error->message);
474 	    g_error_free(error);
475 	} else
476 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR,
477 				 _("decryption failed"));
478 	return body;
479     }
480     message = body->message;
481     libbalsa_message_body_free(body);
482     body = libbalsa_message_body_new(message);
483 
484     /* remember that is was encrypted */
485     if (protocol == GPGME_PROTOCOL_OpenPGP)
486 	body->was_encrypted = TRUE;
487 #ifdef HAVE_SMIME
488     else
489 	body->was_encrypted = smime_encrypted;
490 #endif
491 
492     libbalsa_message_body_set_mime_body(body, mime_obj);
493     if (sig_state) {
494 	if (sig_state->status != GPG_ERR_NOT_SIGNED)
495 	    body->sig_info = sig_state;
496 	else
497 	    g_object_unref(G_OBJECT(sig_state));
498     }
499 
500     return body;
501 }
502 
503 
504 
505 /* routines dealing with RFC2440 */
506 gboolean
libbalsa_rfc2440_sign_encrypt(GMimePart * part,const gchar * sign_for,GList * encrypt_for,gboolean always_trust,GtkWindow * parent,GError ** error)507 libbalsa_rfc2440_sign_encrypt(GMimePart *part, const gchar *sign_for,
508 			      GList *encrypt_for, gboolean always_trust,
509 			      GtkWindow *parent, GError **error)
510 {
511     GPtrArray *recipients;
512     gint result;
513 
514     /* paranoia checks */
515     g_return_val_if_fail(part != NULL, FALSE);
516     g_return_val_if_fail(sign_for != NULL || encrypt_for != NULL, FALSE);
517 
518     /* check if gpg is currently available */
519     if (gpg_updates_trustdb())
520 	return FALSE;
521 
522     /* convert the key list to a GPtrArray */
523     if (encrypt_for) {
524 	recipients = g_ptr_array_new();
525 	while (encrypt_for) {
526 	    g_ptr_array_add(recipients, encrypt_for->data);
527 	    encrypt_for = g_list_next(encrypt_for);
528 	}
529     } else
530 	recipients = NULL;
531 
532     /* sign and/or encrypt */
533     result = g_mime_part_rfc2440_sign_encrypt(part, sign_for, recipients,
534 					      always_trust, parent, error);
535     /* clean up */
536     if (recipients)
537 	g_ptr_array_free(recipients, FALSE);
538     return (result == 0) ? TRUE : FALSE;
539 }
540 
541 
542 /*
543  * Check the signature of part and return the result of the crypto process. If
544  * sig_info is not NULL, return the signature info object there.
545  */
546 gpgme_error_t
libbalsa_rfc2440_verify(GMimePart * part,GMimeGpgmeSigstat ** sig_info)547 libbalsa_rfc2440_verify(GMimePart * part, GMimeGpgmeSigstat ** sig_info)
548 {
549     GMimeGpgmeSigstat *result;
550     GError *error = NULL;
551     gpgme_error_t retval;
552 
553     /* paranoia checks */
554     g_return_val_if_fail(part != NULL, FALSE);
555 
556     /* free any old signature */
557     if (sig_info && *sig_info) {
558 	g_object_unref(*sig_info);
559 	*sig_info = NULL;
560     }
561 
562     /* check if gpg is currently available */
563     if (gpg_updates_trustdb())
564 	return GPG_ERR_TRY_AGAIN;
565 
566     /* verify */
567     result = g_mime_part_rfc2440_verify(part, &error);
568     if (!result || result->status != GPG_ERR_NO_ERROR) {
569 	if (error) {
570 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
571 				 _("signature verification failed"),
572 				 error->message);
573 	    retval = error->code;
574 	    g_error_free(error);
575 	} else {
576 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR,
577 				 _("signature verification failed"));
578 	    retval = GPG_ERR_GENERAL;
579 	}
580     } else
581 	retval = result->status;
582 
583     /* return the signature info if requested */
584     if (result) {
585 	if (sig_info)
586 	    *sig_info = result;
587 	else
588 	    g_object_unref(G_OBJECT(result));
589     }
590     return retval;
591 }
592 
593 
594 /*
595  * Decrypt part, if possible check the signature, and return the result of the
596  * crypto process. If sig_info is not NULL and the part is signed, return the
597  * signature info object there.
598  */
599 gpgme_error_t
libbalsa_rfc2440_decrypt(GMimePart * part,GMimeGpgmeSigstat ** sig_info,GtkWindow * parent)600 libbalsa_rfc2440_decrypt(GMimePart * part, GMimeGpgmeSigstat ** sig_info,
601 			 GtkWindow * parent)
602 {
603     GError *error = NULL;
604     GMimeGpgmeSigstat *result;
605     gpgme_error_t retval;
606 
607     /* paranoia checks */
608     g_return_val_if_fail(part != NULL, FALSE);
609 
610     /* free any old signature */
611     if (sig_info && *sig_info) {
612 	g_object_unref(*sig_info);
613 	*sig_info = NULL;
614     }
615 
616     /* check if gpg is currently available */
617     if (gpg_updates_trustdb())
618 	return GPG_ERR_TRY_AGAIN;
619 
620     /* decrypt */
621     result = g_mime_part_rfc2440_decrypt(part, parent, &error);
622     if (result == NULL) {
623 	if (error) {
624 	    if (error->code != GPG_ERR_CANCELED)
625 		libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
626 				     _("decryption and signature verification failed"),
627 				     error->message);
628 	    retval = error->code;
629 	    g_error_free(error);
630 	} else {
631 	    libbalsa_information(LIBBALSA_INFORMATION_ERROR,
632 				 _
633 				 ("decryption and signature verification failed"));
634 	    retval = GPG_ERR_GENERAL;
635 	}
636     } else {
637 	if (result->status == GPG_ERR_NOT_SIGNED)
638 	    retval = GPG_ERR_NO_ERROR;
639 	else
640 	    retval = result->status;
641 
642 	/* return the signature info if requested */
643 	if (sig_info && result->status != GPG_ERR_NOT_SIGNED)
644 	    *sig_info = result;
645 	else
646 	    g_object_unref(G_OBJECT(result));
647     }
648 
649     return retval;
650 }
651 
652 
653 /* conversion of status values to human-readable messages */
654 const gchar *
libbalsa_gpgme_sig_stat_to_gchar(gpgme_error_t stat)655 libbalsa_gpgme_sig_stat_to_gchar(gpgme_error_t stat)
656 {
657     switch (stat) {
658     case GPG_ERR_NO_ERROR:
659 	return _("The signature is valid.");
660     case GPG_ERR_SIG_EXPIRED:
661 	return _("The signature is valid but expired.");
662     case GPG_ERR_KEY_EXPIRED:
663 	return _
664 	    ("The signature is valid but the key used to verify the signature has expired.");
665     case GPG_ERR_CERT_REVOKED:
666 	return _
667 	    ("The signature is valid but the key used to verify the signature has been revoked.");
668     case GPG_ERR_BAD_SIGNATURE:
669 	return _
670 	    ("The signature is invalid.");
671     case GPG_ERR_NO_PUBKEY:
672 	return
673 	    _("The signature could not be verified due to a missing key.");
674     case GPG_ERR_NO_DATA:
675 	return _("This part is not a real PGP signature.");
676     case GPG_ERR_INV_ENGINE:
677 	return _
678 	    ("The signature could not be verified due to an invalid crypto engine.");
679     case GPG_ERR_TRY_AGAIN:
680 	return _
681 	    ("GnuPG is rebuilding the trust database and is currently unavailable.");
682     default:
683 	g_message("stat %d: %s %s", stat, gpgme_strsource(stat), gpgme_strerror(stat));
684 	return _("An error prevented the signature verification.");
685     }
686 }
687 
688 
689 const gchar *
libbalsa_gpgme_validity_to_gchar(gpgme_validity_t validity)690 libbalsa_gpgme_validity_to_gchar(gpgme_validity_t validity)
691 {
692     switch (validity) {
693     case GPGME_VALIDITY_UNKNOWN:
694 	return _("The user ID is of unknown validity.");
695     case GPGME_VALIDITY_UNDEFINED:
696 	return _("The validity of the user ID is undefined.");
697     case GPGME_VALIDITY_NEVER:
698 	return _("The user ID is never valid.");
699     case GPGME_VALIDITY_MARGINAL:
700 	return _("The user ID is marginally valid.");
701     case GPGME_VALIDITY_FULL:
702 	return _("The user ID is fully valid.");
703     case GPGME_VALIDITY_ULTIMATE:
704 	return _("The user ID is ultimately valid.");
705     default:
706 	return _("bad validity");
707     }
708 }
709 
710 
711 const gchar *
libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t validity)712 libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t validity)
713 {
714     switch (validity) {
715     case GPGME_VALIDITY_UNKNOWN:
716 	return _("unknown");
717     case GPGME_VALIDITY_UNDEFINED:
718 	return _("undefined");
719     case GPGME_VALIDITY_NEVER:
720 	return _("never");
721     case GPGME_VALIDITY_MARGINAL:
722 	return _("marginal");
723     case GPGME_VALIDITY_FULL:
724 	return _("full");
725     case GPGME_VALIDITY_ULTIMATE:
726 	return _("ultimate");
727     default:
728 	return _("bad validity");
729     }
730 }
731 
732 
733 const gchar *
libbalsa_gpgme_sig_protocol_name(gpgme_protocol_t protocol)734 libbalsa_gpgme_sig_protocol_name(gpgme_protocol_t protocol)
735 {
736     switch (protocol) {
737     case GPGME_PROTOCOL_OpenPGP:
738 	return _("PGP signature: ");
739     case GPGME_PROTOCOL_CMS:
740 	return _("S/MIME signature: ");
741     default:
742 	return _("(unknown protocol) ");
743     }
744 }
745 
746 static inline void
append_time_t(GString * str,const gchar * format,time_t * when,const gchar * date_string)747 append_time_t(GString *str, const gchar *format, time_t *when,
748               const gchar * date_string)
749 {
750     if (*when != (time_t) 0) {
751         gchar *tbuf = libbalsa_date_to_utf8(when, date_string);
752         g_string_append_printf(str, format, tbuf);
753         g_free(tbuf);
754     } else {
755         g_string_append_printf(str, format, _("never"));
756     }
757 }
758 
759 gchar *
libbalsa_signature_info_to_gchar(GMimeGpgmeSigstat * info,const gchar * date_string)760 libbalsa_signature_info_to_gchar(GMimeGpgmeSigstat * info,
761 				 const gchar * date_string)
762 {
763     GString *msg;
764     gchar *retval;
765 
766     g_return_val_if_fail(info != NULL, NULL);
767     g_return_val_if_fail(date_string != NULL, NULL);
768     msg = g_string_new(libbalsa_gpgme_sig_protocol_name(info->protocol));
769     msg =
770 	g_string_append(msg,
771 			libbalsa_gpgme_sig_stat_to_gchar(info->status));
772     g_string_append_printf(msg, _("\nSignature validity: %s"),
773 			   libbalsa_gpgme_validity_to_gchar(info->
774 							    validity));
775     append_time_t(msg, _("\nSigned on: %s"), &info->sign_time, date_string);
776     if (info->protocol == GPGME_PROTOCOL_OpenPGP && info->key)
777 	g_string_append_printf(msg, _("\nKey owner trust: %s"),
778 			       libbalsa_gpgme_validity_to_gchar_short
779 			       (info->key->owner_trust));
780     if (info->fingerprint)
781 	g_string_append_printf(msg, _("\nKey fingerprint: %s"),
782 			       info->fingerprint);
783 
784     /* add key information */
785     if (info->key) {
786         gpgme_user_id_t uid;
787         gpgme_subkey_t subkey;
788 
789         /* user ID's */
790         if ((uid = info->key->uids)) {
791             gchar *lead_text;
792 
793             uid = info->key->uids;
794             if (uid->next) {
795         	msg = g_string_append(msg, _("\nUser ID's:"));
796         	lead_text = "\n\342\200\242";
797             } else {
798         	msg = g_string_append(msg, _("\nUser ID:"));
799         	lead_text = "";
800             }
801 
802             /* Note: there is no way to determine which user id has been used
803              * to create the signature.  A broken client may even use an
804              * invalid and/or revoked one.  We therefore add all to the
805              * result. */
806             while (uid) {
807         	msg = g_string_append(msg, lead_text);
808         	if (uid->revoked)
809         	    msg = g_string_append(msg, _(" [Revoked]"));
810         	if (uid->invalid)
811         	    msg = g_string_append(msg, _(" [Invalid]"));
812 
813         	if (uid->uid && *(uid->uid)) {
814         	    gchar *uid_readable =
815         	    	libbalsa_cert_subject_readable(uid->uid);
816         	    g_string_append_printf(msg, " %s", uid_readable);
817         	    g_free(uid_readable);
818         	} else {
819         	    if (uid->name && *(uid->name))
820         		g_string_append_printf(msg, " %s", uid->name);
821         	    if (uid->email && *(uid->email))
822         		g_string_append_printf(msg, " <%s>", uid->email);
823         	    if (uid->comment && *(uid->comment))
824         		g_string_append_printf(msg, " (%s)", uid->comment);
825         	}
826 
827         	uid = uid->next;
828             }
829         }
830 
831         /* subkey */
832         if ((subkey = info->key->subkeys)) {
833             /* find the one which can sign */
834             while (subkey && !subkey->can_sign)
835         	subkey = subkey->next;
836 
837             if (subkey) {
838         	append_time_t(msg, _("\nSubkey created on: %s"),
839         		      &subkey->timestamp, date_string);
840         	append_time_t(msg, _("\nSubkey expires on: %s"),
841         		      &subkey->expires, date_string);
842         	if (subkey->revoked || subkey->expired || subkey->disabled ||
843         	    subkey->invalid) {
844        GString * attrs = g_string_new("");
845        int count = 0;
846 
847         	    if (subkey->revoked) {
848            count++;
849            attrs = g_string_append(attrs, _(" revoked"));
850        }
851         	    if (subkey->expired) {
852            if (count++)
853                attrs = g_string_append_c(attrs, ',');
854            attrs = g_string_append(attrs, _(" expired"));
855        }
856         	    if (subkey->disabled) {
857            if (count)
858                attrs = g_string_append_c(attrs, ',');
859            attrs = g_string_append(attrs, _(" disabled"));
860        }
861         	    if (subkey->invalid) {
862            if (count)
863                attrs = g_string_append_c(attrs, ',');
864            attrs = g_string_append(attrs, _(" invalid"));
865        }
866         	    /* ngettext: string begins with a single space, so no space
867         	     * after the colon is correct punctuation (in English). */
868        g_string_append_printf(msg, ngettext("\nSubkey attribute:%s",
869                                             "\nSubkey attributes:%s",
870                                             count),
871                               attrs->str);
872        g_string_free(attrs, TRUE);
873     }
874             }
875         }
876 
877         if (info->key->issuer_name) {
878             gchar *issuer_name =
879         	libbalsa_cert_subject_readable(info->key->issuer_name);
880             g_string_append_printf(msg, _("\nIssuer name: %s"), issuer_name);
881             g_free(issuer_name);
882     }
883         if (info->key->issuer_serial)
884 	g_string_append_printf(msg, _("\nIssuer serial number: %s"),
885 				   info->key->issuer_serial);
886         if (info->key->chain_id)
887             g_string_append_printf(msg, _("\nChain ID: %s"), info->key->chain_id);
888     }
889 
890     retval = msg->str;
891     g_string_free(msg, FALSE);
892     return retval;
893 }
894 
895 
896 #ifdef HAVE_GPG
897 
898 #include <sys/wait.h>
899 #include <fcntl.h>
900 
901 /* run gpg asynchronously to import or update a key */
902 typedef struct _spawned_gpg_T {
903     gint child_pid;
904     gint standard_error;
905     GString *stderr_buf;
906     GtkWindow *parent;
907 } spawned_gpg_T;
908 
909 static gboolean check_gpg_child(gpointer data);
910 
911 gboolean
gpg_keyserver_op(const gchar * fingerprint,gpg_keyserver_action_t action,GtkWindow * parent)912 gpg_keyserver_op(const gchar * fingerprint, gpg_keyserver_action_t action,
913                  GtkWindow * parent)
914 {
915     gchar **argv;
916     spawned_gpg_T *spawned_gpg;
917     gboolean spawnres;
918 
919     /* launch gpg... */
920     argv = g_new(gchar *, 5);
921     argv[0] = g_strdup(GPG_PATH);
922     argv[1] = g_strdup("--no-greeting");
923     switch (action) {
924     case GPG_KEYSERVER_IMPORT:
925         argv[2] = g_strdup("--recv-keys");
926         break;
927     case GPG_KEYSERVER_UPDATE:
928         argv[2] = g_strdup("--refresh-keys");
929         break;
930     default:
931         g_assert_not_reached();
932     }
933     argv[3] = g_strdup(fingerprint);
934     argv[4] = NULL;
935     spawned_gpg = g_new0(spawned_gpg_T, 1);
936     spawnres =
937 	g_spawn_async_with_pipes(NULL, argv, NULL,
938 				 G_SPAWN_DO_NOT_REAP_CHILD |
939 				 G_SPAWN_STDOUT_TO_DEV_NULL, NULL, NULL,
940 				 &spawned_gpg->child_pid, NULL, NULL,
941 				 &spawned_gpg->standard_error, NULL);
942     g_strfreev(argv);
943     if (spawnres == FALSE) {
944 	libbalsa_information(LIBBALSA_INFORMATION_ERROR,
945 			     _
946 			     ("Could not launch %s to query the public key %s."),
947 			     GPG_PATH, fingerprint);
948 	g_free(spawned_gpg);
949 	return FALSE;
950     }
951 
952     /* install an idle handler to check if the child returnd successfully. */
953     fcntl(spawned_gpg->standard_error, F_SETFL, O_NONBLOCK);
954     spawned_gpg->stderr_buf = g_string_new("");
955     spawned_gpg->parent = parent;
956     g_timeout_add(250, check_gpg_child, spawned_gpg);
957 
958     return TRUE;
959 }
960 
961 
962 static gboolean
check_gpg_child(gpointer data)963 check_gpg_child(gpointer data)
964 {
965     spawned_gpg_T *spawned_gpg = (spawned_gpg_T *) data;
966     int status;
967     ssize_t bytes_read;
968     gchar buffer[1024], *gpg_message;
969     GtkWidget *dialog;
970 
971     /* read input from the child and append it to the buffer */
972     while ((bytes_read =
973 	    read(spawned_gpg->standard_error, buffer, 1023)) > 0) {
974 	buffer[bytes_read] = '\0';
975 	g_string_append(spawned_gpg->stderr_buf, buffer);
976     }
977 
978     /* check if the child exited */
979     if (waitpid(spawned_gpg->child_pid, &status, WNOHANG) !=
980 	spawned_gpg->child_pid)
981 	return TRUE;
982 
983     /* child exited, display some information... */
984     close(spawned_gpg->standard_error);
985 
986     gpg_message =
987 	g_locale_to_utf8(spawned_gpg->stderr_buf->str, -1, NULL,
988 			 NULL, NULL);
989     gdk_threads_enter();
990     if (WEXITSTATUS(status) > 0)
991 	dialog =
992 	    gtk_message_dialog_new(spawned_gpg->parent,
993 				   GTK_DIALOG_DESTROY_WITH_PARENT,
994 				   GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
995 				   _
996 				   ("Running %s failed with return value %d:\n%s"),
997 				   GPG_PATH, WEXITSTATUS(status), gpg_message);
998     else
999 	dialog =
1000 	    gtk_message_dialog_new(spawned_gpg->parent,
1001 				   GTK_DIALOG_DESTROY_WITH_PARENT,
1002 				   GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
1003 				   _("Running %s successful:\n%s"),
1004 				   GPG_PATH, gpg_message);
1005 #if HAVE_MACOSX_DESKTOP
1006     libbalsa_macosx_menu_for_parent(dialog, spawned_gpg->parent);
1007 #endif
1008     g_free(gpg_message);
1009     g_string_free(spawned_gpg->stderr_buf, TRUE);
1010     g_free(spawned_gpg);
1011 
1012     gtk_dialog_run(GTK_DIALOG(dialog));
1013     gtk_widget_destroy(dialog);
1014     gdk_threads_leave();
1015 
1016     return FALSE;
1017 }
1018 
1019 #endif				/* HAVE_GPG */
1020 
1021 
1022 /* ==== local stuff ======================================================== */
1023 
1024 
1025 /*
1026  * return TRUE is gpg is currently updating the trust database (indicated by
1027  * the file ~/.gnupg/trustdb.gpg.lock)
1028  */
1029 static gboolean
gpg_updates_trustdb(void)1030 gpg_updates_trustdb(void)
1031 {
1032     static gchar *lockname = NULL;
1033     struct passwd *pwent;
1034     struct stat stat_buf;
1035 
1036     if (!lockname)
1037 	if ((pwent = getpwuid(getuid())))
1038 	    lockname =
1039 		g_strdup_printf("%s/.gnupg/trustdb.gpg.lock",
1040 				pwent->pw_dir);
1041     if (!stat(lockname, &stat_buf)) {
1042 	libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s%s",
1043 			     _
1044 			     ("GnuPG is rebuilding the trust database and is currently unavailable."),
1045 			     _("Try again later."));
1046 	return TRUE;
1047     } else
1048 	return FALSE;
1049 }
1050 
1051 
1052 /* check if the context contains a public key for the passed recipients */
1053 #define KEY_IS_OK(k)   (!((k)->expired || (k)->revoked || \
1054                           (k)->disabled || (k)->invalid))
1055 static gboolean
have_pub_key_for(gpgme_ctx_t gpgme_ctx,InternetAddressList * recipients)1056 have_pub_key_for(gpgme_ctx_t gpgme_ctx, InternetAddressList * recipients)
1057 {
1058     gpgme_key_t key;
1059     gboolean result = TRUE;
1060     time_t now = time(NULL);
1061     gint i;
1062 
1063     for (i = 0; result && i < internet_address_list_length(recipients);
1064          i++) {
1065         InternetAddress *ia =
1066             internet_address_list_get_address(recipients, i);
1067 
1068 	/* check all entries in the list, handle groups recursively */
1069 	if (INTERNET_ADDRESS_IS_GROUP(ia))
1070 	    result =
1071                 have_pub_key_for(gpgme_ctx,
1072                                  INTERNET_ADDRESS_GROUP(ia)->members);
1073 	else {
1074 	    if (gpgme_op_keylist_start(gpgme_ctx,
1075                                        INTERNET_ADDRESS_MAILBOX(ia)->addr,
1076                                        FALSE) != GPG_ERR_NO_ERROR)
1077 		return FALSE;
1078 
1079 	    result = FALSE;
1080 	    while (!result &&
1081 		   gpgme_op_keylist_next(gpgme_ctx, &key) == GPG_ERR_NO_ERROR) {
1082 		/* check if this key and the relevant subkey are usable */
1083 		if (KEY_IS_OK(key)) {
1084 		    gpgme_subkey_t subkey = key->subkeys;
1085 
1086 		    while (subkey && !subkey->can_encrypt)
1087 			subkey = subkey->next;
1088 
1089 		    if (subkey && KEY_IS_OK(subkey) &&
1090 			(subkey->expires == 0 || subkey->expires > now))
1091 			result = TRUE;
1092 		}
1093 		gpgme_key_unref(key);
1094 	    }
1095 	    gpgme_op_keylist_end(gpgme_ctx);
1096 	}
1097     }
1098 
1099     return result;
1100 }
1101 
1102 #endif				/* HAVE_GPGME */
1103