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