[balsa] New crypto implementation
- From: Peter Bloomfield <PeterB src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa] New crypto implementation
- Date: Sun, 11 Dec 2011 00:22:07 +0000 (UTC)
commit 3b4d9293a9798399581314c39c54f1e59343459a
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Sat Dec 10 19:21:37 2011 -0500
New crypto implementation
* libbalsa/Makefile.am: new files.
* libbalsa/body.c (libbalsa_message_body_protect_state): use new
implementation.
* libbalsa/gmime-application-pkcs7.c
(g_mime_application_pkcs7_decrypt_verify),
(g_mime_application_pkcs7_encrypt): ditto.
* libbalsa/gmime-application-pkcs7.h: ditto.
* libbalsa/gmime-gpgme-context.c: new file.
* libbalsa/gmime-gpgme-context.h: ditto.
* libbalsa/gmime-gpgme-signature.c
(g_mime_gpgme_sigstat_new_from_gpgme_ctx),
(g_mime_gpgme_sigstat_finalize), (hex_decode),
(libbalsa_cert_subject_readable), (g_mime_gpgme_sigstat_init):
ditto.
* libbalsa/gmime-gpgme-signature.h: ditto.
* libbalsa/gmime-part-rfc2440.c (g_mime_part_check_rfc2440),
(g_mime_part_rfc2440_sign_encrypt), (g_mime_part_rfc2440_verify),
(g_mime_part_rfc2440_decrypt): use new implementation.
* libbalsa/gmime-part-rfc2440.h: ditto.
* libbalsa/rfc3156.c (libbalsa_sign_mime_object),
(libbalsa_encrypt_mime_object), (libbalsa_body_check_signature),
(libbalsa_body_decrypt), (libbalsa_rfc2440_sign_encrypt),
(libbalsa_rfc2440_verify), (libbalsa_rfc2440_decrypt),
(libbalsa_gpgme_validity_to_gchar_short), (append_time_t),
(libbalsa_signature_info_to_gchar): ditto.
* libbalsa/rfc3156.h: ditto.
* src/balsa-message.c (libbalsa_msg_part_2440): ditto.
* src/main.c (main): ditto.
ChangeLog | 33 +
libbalsa/Makefile.am | 16 +-
libbalsa/body.c | 2 +-
libbalsa/gmime-application-pkcs7.c | 353 ++--------
libbalsa/gmime-application-pkcs7.h | 61 +--
libbalsa/gmime-gpgme-context.c | 1415 ------------------------------------
libbalsa/gmime-gpgme-context.h | 125 ----
libbalsa/gmime-gpgme-signature.c | 199 +++---
libbalsa/gmime-gpgme-signature.h | 27 +-
libbalsa/gmime-part-rfc2440.c | 275 ++++----
libbalsa/gmime-part-rfc2440.h | 35 +-
libbalsa/rfc3156.c | 1276 +++++----------------------------
libbalsa/rfc3156.h | 5 +-
src/balsa-message.c | 2 +-
src/main.c | 56 +--
15 files changed, 526 insertions(+), 3354 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d5c62f5..e82dbc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2011-12-10 Albrecht DreÃ
+
+ New crypto implementation
+
+ * libbalsa/Makefile.am: new files.
+ * libbalsa/body.c (libbalsa_message_body_protect_state): use new
+ implementation.
+ * libbalsa/gmime-application-pkcs7.c
+ (g_mime_application_pkcs7_decrypt_verify),
+ (g_mime_application_pkcs7_encrypt): ditto.
+ * libbalsa/gmime-application-pkcs7.h: ditto.
+ * libbalsa/gmime-gpgme-context.c: new file.
+ * libbalsa/gmime-gpgme-context.h: ditto.
+ * libbalsa/gmime-gpgme-signature.c
+ (g_mime_gpgme_sigstat_new_from_gpgme_ctx),
+ (g_mime_gpgme_sigstat_finalize), (hex_decode),
+ (libbalsa_cert_subject_readable), (g_mime_gpgme_sigstat_init):
+ ditto.
+ * libbalsa/gmime-gpgme-signature.h: ditto.
+ * libbalsa/gmime-part-rfc2440.c (g_mime_part_check_rfc2440),
+ (g_mime_part_rfc2440_sign_encrypt), (g_mime_part_rfc2440_verify),
+ (g_mime_part_rfc2440_decrypt): use new implementation.
+ * libbalsa/gmime-part-rfc2440.h: ditto.
+ * libbalsa/rfc3156.c (libbalsa_sign_mime_object),
+ (libbalsa_encrypt_mime_object), (libbalsa_body_check_signature),
+ (libbalsa_body_decrypt), (libbalsa_rfc2440_sign_encrypt),
+ (libbalsa_rfc2440_verify), (libbalsa_rfc2440_decrypt),
+ (libbalsa_gpgme_validity_to_gchar_short), (append_time_t),
+ (libbalsa_signature_info_to_gchar): ditto.
+ * libbalsa/rfc3156.h: ditto.
+ * src/balsa-message.c (libbalsa_msg_part_2440): ditto.
+ * src/main.c (main): ditto.
+
2011-11-27 Peter Bloomfield
Build with GMime 2.6.0
diff --git a/libbalsa/Makefile.am b/libbalsa/Makefile.am
index 525b04a..00bda16 100644
--- a/libbalsa/Makefile.am
+++ b/libbalsa/Makefile.am
@@ -5,8 +5,12 @@ noinst_LIBRARIES = libbalsa.a
if BUILD_WITH_GPGME
libbalsa_gpgme_extra = \
- gmime-gpgme-context.h \
- gmime-gpgme-context.c \
+ libbalsa-gpgme.h \
+ libbalsa-gpgme.c \
+ libbalsa-gpgme-cb.h \
+ libbalsa-gpgme-cb.c \
+ gmime-multipart-crypt.h \
+ gmime-multipart-crypt.c \
gmime-part-rfc2440.h \
gmime-part-rfc2440.c \
gmime-gpgme-signature.h \
@@ -15,8 +19,12 @@ libbalsa_gpgme_extra_dist =
else
libbalsa_gpgme_extra =
libbalsa_gpgme_extra_dist = \
- gmime-gpgme-context.h \
- gmime-gpgme-context.c \
+ libbalsa-gpgme.h \
+ libbalsa-gpgme.c \
+ libbalsa-gpgme-cb.h \
+ libbalsa-gpgme-cb.c \
+ gmime-multipart-crypt.h \
+ gmime-multipart-crypt.c \
gmime-part-rfc2440.h \
gmime-part-rfc2440.c \
gmime-gpgme-signature.h \
diff --git a/libbalsa/body.c b/libbalsa/body.c
index b872a9d..aee94cd 100644
--- a/libbalsa/body.c
+++ b/libbalsa/body.c
@@ -849,7 +849,7 @@ libbalsa_message_body_protect_state(LibBalsaMessageBody *body)
at least marginal */
if (body->sig_info->validity >= GPGME_VALIDITY_MARGINAL &&
(body->sig_info->protocol == GPGME_PROTOCOL_CMS ||
- body->sig_info->trust >= GPGME_VALIDITY_MARGINAL))
+ body->sig_info->key->owner_trust >= GPGME_VALIDITY_MARGINAL))
return LIBBALSA_MSG_PROTECT_SIGN_GOOD;
else
return LIBBALSA_MSG_PROTECT_SIGN_NOTRUST;
diff --git a/libbalsa/gmime-application-pkcs7.c b/libbalsa/gmime-application-pkcs7.c
index 63b8087..cad055c 100644
--- a/libbalsa/gmime-application-pkcs7.c
+++ b/libbalsa/gmime-application-pkcs7.c
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
* S/MIME application/pkcs7-mime support for gmime/balsa
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * Copyright (C) 2004 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +35,7 @@
#include <gmime/gmime-multipart.h>
#include <gmime/gmime-multipart-signed.h>
#include <gmime/gmime-multipart-encrypted.h>
+#include "libbalsa-gpgme.h"
#include "gmime-application-pkcs7.h"
#include <glib/gi18n.h>
@@ -42,137 +43,6 @@
#define GMIME_PKCS7_ERR_QUARK (g_quark_from_static_string ("gmime-app-pkcs7"))
-#ifdef HAS_APPLICATION_PKCS7_MIME_SIGNED_SUPPORT
-
-/*
- * Note: this code has been shamelessly stolen from Jeff's multipart-signed implementation
- */
-static void
-sign_prepare (GMimeObject *mime_part)
-{
- GMimeContentEncoding encoding;
- GMimeObject *subpart;
-
- if (GMIME_IS_MULTIPART (mime_part)) {
- GList *lpart;
-
- if (GMIME_IS_MULTIPART_SIGNED (mime_part) || GMIME_IS_MULTIPART_ENCRYPTED (mime_part)) {
- /* must not modify these parts as they must be treated as opaque */
- return;
- }
-
- lpart = GMIME_MULTIPART (mime_part)->subparts;
- while (lpart) {
- subpart = GMIME_OBJECT (lpart->data);
- sign_prepare (subpart);
- lpart = lpart->next;
- }
- } else if (GMIME_IS_MESSAGE_PART (mime_part)) {
- subpart = GMIME_MESSAGE_PART (mime_part)->message->mime_part;
- sign_prepare (subpart);
- } else {
- encoding = g_mime_part_get_content_encoding (GMIME_PART (mime_part));
-
- if (encoding != GMIME_CONTENT_ENCODING_BASE64)
- g_mime_part_set_content_encoding (GMIME_PART (mime_part),
- GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE);
- }
-}
-
-
-/*
- * Sign content using the context ctx for userid and write the signed
- * application/pkcs7-mime object to pkcs7. Return 0 on success and -1 on error.
- * In the latter case, fill err with more information about the reason.
- */
-int
-g_mime_application_pkcs7_sign (GMimePart *pkcs7, GMimeObject *content,
- GMimeCipherContext *ctx, const char *userid,
- GError **err)
-{
- GMimeDataWrapper *wrapper;
- GMimeStream *filtered_stream;
- GMimeStream *stream, *sig_data_stream;
- GMimeFilter *crlf_filter, *from_filter;
-
- g_return_val_if_fail (GMIME_IS_PART (pkcs7), -1);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail (GMIME_IS_CIPHER_CONTEXT (ctx), -1);
- g_return_val_if_fail (ctx->sign_protocol != NULL, -1);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
- g_return_val_if_fail(g_mime_crypto_context_get_signature_protocol(ctx)
- != NULL, -1);
-#endif /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail (GMIME_IS_OBJECT (content), -1);
-
- /* Prepare all the parts for signing... */
- sign_prepare (content);
-
- /* get the cleartext */
- stream = g_mime_stream_mem_new ();
- filtered_stream = g_mime_stream_filter_new (stream);
-
- /* See RFC 2633, Sect. 3.1- the following op's are "SHOULD", so we do it */
- from_filter = g_mime_filter_from_new (GMIME_FILTER_FROM_MODE_ARMOR);
- g_mime_stream_filter_add (GMIME_STREAM_FILTER (filtered_stream), from_filter);
- g_object_unref (from_filter);
-
- g_mime_object_write_to_stream (content, filtered_stream);
- g_mime_stream_flush (filtered_stream);
- g_object_unref (filtered_stream);
- g_mime_stream_reset (stream);
-
- filtered_stream = g_mime_stream_filter_new (stream);
- crlf_filter = g_mime_filter_crlf_new (TRUE,
- FALSE);
- g_mime_stream_filter_add (GMIME_STREAM_FILTER (filtered_stream), crlf_filter);
- g_object_unref (crlf_filter);
-
- /* construct the signed data stream */
- sig_data_stream = g_mime_stream_mem_new ();
-
- /* get the signed content */
-#ifndef HAVE_GMIME_2_5_7
- if (g_mime_cipher_context_sign (ctx, userid, GMIME_CIPHER_HASH_DEFAULT, filtered_stream, sig_data_stream, err) == -1)
-#else /* HAVE_GMIME_2_5_7 */
- if (g_mime_crypto_context_sign
- (ctx, userid, GMIME_CIPHER_HASH_DEFAULT, filtered_stream,
- sig_data_stream, err) == -1)
-#endif /* HAVE_GMIME_2_5_7 */
- {
- g_object_unref (filtered_stream);
- g_object_unref (sig_data_stream);
- g_object_unref (stream);
- return -1;
- }
-
- g_object_unref (filtered_stream);
- g_object_unref (stream);
- g_mime_stream_reset (sig_data_stream);
-
- /* set the pkcs7 mime part as content of the pkcs7 object */
- wrapper = g_mime_data_wrapper_new();
- g_mime_data_wrapper_set_stream(wrapper, sig_data_stream);
- g_object_unref(sig_data_stream);
- g_mime_part_set_content_object(GMIME_PART(pkcs7), wrapper);
- g_mime_part_set_filename(GMIME_PART(pkcs7), "smime.p7m");
- g_mime_part_set_content_encoding(GMIME_PART(pkcs7),
- GMIME_CONTENT_ENCODING_BASE64);
- g_object_unref(wrapper);
-
- /* set the content-type params for this part */
- g_mime_object_set_content_type_parameter(GMIME_OBJECT(pkcs7),
- "smime-type", "signed-data");
- g_mime_object_set_content_type_parameter(GMIME_OBJECT(pkcs7), "name",
- "smime.p7m");
-
- return 0;
-}
-#endif /* HAS_APPLICATION_PKCS7_MIME_SIGNED_SUPPORT */
-
-
-
/*
* Try to verify pkcs7 using the context ctx, fill validity with the resulting
* validity and return the "readable" decrypted part. If anything fails, the
@@ -181,15 +51,9 @@ g_mime_application_pkcs7_sign (GMimePart *pkcs7, GMimeObject *content,
* decrypting it again. In this case, validity is undefined.
*/
GMimeObject *
-#ifndef HAVE_GMIME_2_5_7
-g_mime_application_pkcs7_verify(GMimePart * pkcs7,
- GMimeSignatureValidity ** validity,
- GMimeCipherContext * ctx, GError ** err)
-#else /* HAVE_GMIME_2_5_7 */
-g_mime_application_pkcs7_verify(GMimePart * pkcs7,
- GMimeSignatureList ** list,
- GMimeCryptoContext * ctx, GError ** err)
-#endif /* HAVE_GMIME_2_5_7 */
+g_mime_application_pkcs7_decrypt_verify(GMimePart * pkcs7,
+ GMimeGpgmeSigstat ** signature,
+ GtkWindow * parent, GError ** err)
{
GMimeObject *decrypted;
GMimeDataWrapper *wrapper;
@@ -200,49 +64,41 @@ g_mime_application_pkcs7_verify(GMimePart * pkcs7,
const char *smime_type;
g_return_val_if_fail(GMIME_IS_PART(pkcs7), NULL);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail(GMIME_IS_CIPHER_CONTEXT(ctx), NULL);
- g_return_val_if_fail(ctx->encrypt_protocol != NULL, NULL);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail(GMIME_IS_CRYPTO_CONTEXT(ctx), NULL);
- g_return_val_if_fail(g_mime_crypto_context_get_encryption_protocol(ctx)
- != NULL, NULL);
-#endif /* HAVE_GMIME_2_5_7 */
- /* some sanity checks */
+ /* get the smime type */
smime_type =
g_mime_object_get_content_type_parameter(GMIME_OBJECT(pkcs7),
"smime-type");
- if (g_ascii_strcasecmp(smime_type, "signed-data")) {
+ if (!smime_type
+ || (g_ascii_strcasecmp(smime_type, "enveloped-data")
+ && g_ascii_strcasecmp(smime_type, "signed-data"))) {
return NULL;
}
/* get the ciphertext stream */
wrapper = g_mime_part_get_content_object(GMIME_PART(pkcs7));
g_return_val_if_fail(wrapper, NULL); /* Incomplete part. */
- ciphertext = g_mime_stream_mem_new ();
- g_mime_data_wrapper_write_to_stream (wrapper, ciphertext);
+ ciphertext = g_mime_stream_mem_new();
+ g_mime_data_wrapper_write_to_stream(wrapper, ciphertext);
g_mime_stream_reset(ciphertext);
stream = g_mime_stream_mem_new();
filtered_stream = g_mime_stream_filter_new(stream);
- crlf_filter = g_mime_filter_crlf_new(FALSE,
- FALSE);
+ crlf_filter = g_mime_filter_crlf_new(FALSE, FALSE);
g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_stream),
crlf_filter);
g_object_unref(crlf_filter);
/* get the cleartext */
-#ifndef HAVE_GMIME_2_5_7
- *validity = g_mime_cipher_context_verify(ctx, GMIME_CIPHER_HASH_DEFAULT,
- ciphertext, filtered_stream, err);
- if (!*validity)
-#else /* HAVE_GMIME_2_5_7 */
- *list = g_mime_crypto_context_verify(ctx, GMIME_CIPHER_ALGO_DEFAULT,
- ciphertext, filtered_stream, err);
- if (!*list)
-#endif /* HAVE_GMIME_2_5_7 */
- {
+ if (g_ascii_strcasecmp(smime_type, "enveloped-data") == 0)
+ *signature =
+ libbalsa_gpgme_decrypt(ciphertext, filtered_stream,
+ GPGME_PROTOCOL_CMS, parent, err);
+ else
+ *signature =
+ libbalsa_gpgme_verify(ciphertext, filtered_stream,
+ GPGME_PROTOCOL_CMS, TRUE, err);
+ if (!*signature) {
g_object_unref(filtered_stream);
g_object_unref(ciphertext);
g_object_unref(stream);
@@ -279,65 +135,47 @@ g_mime_application_pkcs7_verify(GMimePart * pkcs7,
* about the reason.
*/
int
-g_mime_application_pkcs7_encrypt (GMimePart *pkcs7, GMimeObject *content,
-#ifndef HAVE_GMIME_2_5_7
- GMimeCipherContext *ctx, GPtrArray *recipients,
-#else /* HAVE_GMIME_2_5_7 */
- GMimeCryptoContext *ctx,
- GPtrArray *recipients,
-#endif /* HAVE_GMIME_2_5_7 */
- GError **err)
+g_mime_application_pkcs7_encrypt(GMimePart * pkcs7, GMimeObject * content,
+ GPtrArray * recipients,
+ gboolean trust_all, GtkWindow * parent,
+ GError ** err)
{
GMimeDataWrapper *wrapper;
GMimeStream *filtered_stream;
GMimeStream *stream, *ciphertext;
GMimeFilter *crlf_filter;
- g_return_val_if_fail (GMIME_IS_PART (pkcs7), -1);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail (GMIME_IS_CIPHER_CONTEXT (ctx), -1);
- g_return_val_if_fail (ctx->encrypt_protocol != NULL, -1);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
- g_return_val_if_fail(g_mime_crypto_context_get_encryption_protocol(ctx)
- != NULL, -1);
-#endif /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail (GMIME_IS_OBJECT (content), -1);
+ g_return_val_if_fail(GMIME_IS_PART(pkcs7), -1);
+ g_return_val_if_fail(GMIME_IS_OBJECT(content), -1);
/* get the cleartext */
- stream = g_mime_stream_mem_new ();
- filtered_stream = g_mime_stream_filter_new (stream);
+ stream = g_mime_stream_mem_new();
+ filtered_stream = g_mime_stream_filter_new(stream);
- crlf_filter = g_mime_filter_crlf_new (TRUE,
- FALSE);
- g_mime_stream_filter_add (GMIME_STREAM_FILTER (filtered_stream), crlf_filter);
- g_object_unref (crlf_filter);
+ crlf_filter = g_mime_filter_crlf_new(TRUE, FALSE);
+ g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_stream),
+ crlf_filter);
+ g_object_unref(crlf_filter);
- g_mime_object_write_to_stream (content, filtered_stream);
- g_mime_stream_flush (filtered_stream);
- g_object_unref (filtered_stream);
+ g_mime_object_write_to_stream(content, filtered_stream);
+ g_mime_stream_flush(filtered_stream);
+ g_object_unref(filtered_stream);
/* reset the content stream */
- g_mime_stream_reset (stream);
+ g_mime_stream_reset(stream);
/* encrypt the content stream */
- ciphertext = g_mime_stream_mem_new ();
-#ifndef HAVE_GMIME_2_5_7
- if (g_mime_cipher_context_encrypt (ctx, FALSE, NULL, recipients, stream, ciphertext, err) == -1)
-#else /* HAVE_GMIME_2_5_7 */
- if (g_mime_crypto_context_encrypt
- (ctx, FALSE, NULL,
- GMIME_CIPHER_ALGO_DEFAULT,
- recipients, stream, ciphertext, err) == -1)
-#endif /* HAVE_GMIME_2_5_7 */
- {
- g_object_unref (ciphertext);
- g_object_unref (stream);
+ ciphertext = g_mime_stream_mem_new();
+ if (libbalsa_gpgme_encrypt
+ (recipients, NULL, stream, ciphertext, GPGME_PROTOCOL_CMS, TRUE,
+ trust_all, parent, err) == -1) {
+ g_object_unref(ciphertext);
+ g_object_unref(stream);
return -1;
}
- g_object_unref (stream);
- g_mime_stream_reset (ciphertext);
+ g_object_unref(stream);
+ g_mime_stream_reset(ciphertext);
/* set the encrypted mime part as content of the pkcs7 object */
wrapper = g_mime_data_wrapper_new();
@@ -345,109 +183,16 @@ g_mime_application_pkcs7_encrypt (GMimePart *pkcs7, GMimeObject *content,
g_object_unref(ciphertext);
g_mime_part_set_content_object(GMIME_PART(pkcs7), wrapper);
g_mime_part_set_filename(GMIME_PART(pkcs7), "smime.p7m");
- g_mime_part_set_content_encoding(GMIME_PART(pkcs7), GMIME_CONTENT_ENCODING_BASE64);
+ g_mime_part_set_content_encoding(GMIME_PART(pkcs7),
+ GMIME_CONTENT_ENCODING_BASE64);
g_object_unref(wrapper);
/* set the content-type params for this part */
g_mime_object_set_content_type_parameter(GMIME_OBJECT(pkcs7),
- "smime-type", "enveloped-data");
+ "smime-type",
+ "enveloped-data");
g_mime_object_set_content_type_parameter(GMIME_OBJECT(pkcs7), "name",
"smime.p7m");
return 0;
}
-
-
-/*
- * Decrypt the application/pkcs7-mime part pkcs7 unsing the context ctx and
- * return the decrypted gmime object or NULL on error. In the latter case, fill
- * err with more information about the reason.
- */
-GMimeObject *
-#ifndef HAVE_GMIME_2_5_7
-g_mime_application_pkcs7_decrypt (GMimePart *pkcs7, GMimeCipherContext *ctx,
- GError **err)
-#else /* HAVE_GMIME_2_5_7 */
-g_mime_application_pkcs7_decrypt (GMimePart *pkcs7,
- GMimeCryptoContext *ctx,
- GError **err)
-#endif /* HAVE_GMIME_2_5_7 */
-{
- GMimeObject *decrypted;
- GMimeDataWrapper *wrapper;
- GMimeStream *stream, *ciphertext;
- GMimeStream *filtered_stream;
- GMimeFilter *crlf_filter;
- GMimeParser *parser;
- const char *smime_type;
-
- g_return_val_if_fail(GMIME_IS_PART(pkcs7), NULL);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail(GMIME_IS_CIPHER_CONTEXT(ctx), NULL);
- g_return_val_if_fail(ctx->encrypt_protocol != NULL, NULL);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail(GMIME_IS_CRYPTO_CONTEXT(ctx), NULL);
- g_return_val_if_fail(g_mime_crypto_context_get_encryption_protocol(ctx)
- != NULL, NULL);
-#endif /* HAVE_GMIME_2_5_7 */
-
- /* some sanity checks */
- smime_type =
- g_mime_object_get_content_type_parameter(GMIME_OBJECT(pkcs7),
- "smime-type");
- if (!smime_type || (g_ascii_strcasecmp(smime_type, "enveloped-data") &&
- g_ascii_strcasecmp(smime_type, "signed-data"))) {
- return NULL;
- }
-
- /* get the ciphertext stream */
- wrapper = g_mime_part_get_content_object(GMIME_PART(pkcs7));
- g_return_val_if_fail(wrapper, NULL); /* Incomplete part. */
- ciphertext = g_mime_stream_mem_new();
- g_mime_data_wrapper_write_to_stream (wrapper, ciphertext);
- g_mime_stream_reset(ciphertext);
-
- stream = g_mime_stream_mem_new();
- filtered_stream = g_mime_stream_filter_new(stream);
- crlf_filter = g_mime_filter_crlf_new(FALSE,
- FALSE);
- g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_stream),
- crlf_filter);
- g_object_unref(crlf_filter);
-
- /* get the cleartext */
-#ifndef HAVE_GMIME_2_5_7
- if (g_mime_cipher_context_decrypt(ctx, ciphertext, filtered_stream, err) == NULL)
-#else /* HAVE_GMIME_2_5_7 */
- if (g_mime_crypto_context_decrypt
- (ctx, ciphertext, filtered_stream, err) == NULL)
-#endif /* HAVE_GMIME_2_5_7 */
- {
- g_object_unref(filtered_stream);
- g_object_unref(ciphertext);
- g_object_unref(stream);
-
- return NULL;
- }
-
- g_mime_stream_flush(filtered_stream);
- g_object_unref(filtered_stream);
- g_object_unref(ciphertext);
-
- g_mime_stream_reset (stream);
- parser = g_mime_parser_new();
- g_mime_parser_init_with_stream(parser, stream);
- g_object_unref(stream);
-
- decrypted = g_mime_parser_construct_part(parser);
- g_object_unref(parser);
-
- if (decrypted)
- g_object_ref(decrypted);
- else
- g_set_error(err, GMIME_PKCS7_ERR_QUARK, 42,
- _("Failed to decrypt MIME part: parse error"));
-
- return decrypted;
-}
-
diff --git a/libbalsa/gmime-application-pkcs7.h b/libbalsa/gmime-application-pkcs7.h
index 6678ff5..6b9e0e7 100644
--- a/libbalsa/gmime-application-pkcs7.h
+++ b/libbalsa/gmime-application-pkcs7.h
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
* S/MIME application/pkcs7-mime support for gmime/balsa
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * Copyright (C) 2004 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,56 +27,21 @@ extern "C" {
#pragma }
#endif /* __cplusplus */
-#include <gmime/gmime-part.h>
-#ifndef HAVE_GMIME_2_5_7
-#include <gmime/gmime-cipher-context.h>
-#else /* HAVE_GMIME_2_5_7 */
-#include <gmime/gmime-crypto-context.h>
-#endif /* HAVE_GMIME_2_5_7 */
+#include <gmime/gmime.h>
-#undef HAS_APPLICATION_PKCS7_MIME_SIGNED_SUPPORT
-
-#ifdef HAS_APPLICATION_PKCS7_MIME_SIGNED_SUPPORT
-/* Note: application/pkcs7-mime signed parts are not used within balsa, as
- * they can not be viewed by mMUA's without S/MIME support. Therefore,
- * Balsa always encodes S/MIME signed stuff as multipart/signed. */
-int g_mime_application_pkcs7_sign(GMimePart * pkcs7,
+ GMimeObject *g_mime_application_pkcs7_decrypt_verify(GMimePart * pkcs7,
+ GMimeGpgmeSigstat
+ ** signature,
+ GtkWindow *
+ parent,
+ GError ** err);
+ int g_mime_application_pkcs7_encrypt(GMimePart * pkcs7,
GMimeObject * content,
-#ifndef HAVE_GMIME_2_5_7
- GMimeCipherContext * ctx,
-#else /* HAVE_GMIME_2_5_7 */
- GMimeCryptoContext * ctx,
-#endif /* HAVE_GMIME_2_5_7 */
- const char *userid, GError ** err);
-#endif
-
-#ifndef HAVE_GMIME_2_5_7
-GMimeObject *g_mime_application_pkcs7_verify(GMimePart * pkcs7,
- GMimeSignatureValidity ** validity,
- GMimeCipherContext * ctx, GError ** err);
-#else /* HAVE_GMIME_2_5_7 */
-GMimeObject *g_mime_application_pkcs7_verify(GMimePart * pkcs7,
- GMimeSignatureList ** validity,
- GMimeCryptoContext * ctx, GError ** err);
-#endif /* HAVE_GMIME_2_5_7 */
-
-int g_mime_application_pkcs7_encrypt(GMimePart * pkcs7,
- GMimeObject * content,
-#ifndef HAVE_GMIME_2_5_7
- GMimeCipherContext * ctx,
-#else /* HAVE_GMIME_2_5_7 */
- GMimeCryptoContext * ctx,
-#endif /* HAVE_GMIME_2_5_7 */
- GPtrArray * recipients, GError ** err);
-
-#ifndef HAVE_GMIME_2_5_7
-GMimeObject *g_mime_application_pkcs7_decrypt(GMimePart * pkcs7,
- GMimeCipherContext * ctx, GError ** err);
-#else /* HAVE_GMIME_2_5_7 */
-GMimeObject *g_mime_application_pkcs7_decrypt(GMimePart * pkcs7,
- GMimeCryptoContext * ctx, GError ** err);
-#endif /* HAVE_GMIME_2_5_7 */
+ GPtrArray * recipients,
+ gboolean trust_all,
+ GtkWindow * parent,
+ GError ** err);
#ifdef __cplusplus
}
diff --git a/libbalsa/gmime-gpgme-signature.c b/libbalsa/gmime-gpgme-signature.c
index d78441b..b1b67d0 100644
--- a/libbalsa/gmime-gpgme-signature.c
+++ b/libbalsa/gmime-gpgme-signature.c
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
* gmime/gpgme glue layer library
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * Copyright (C) 2004-2011 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,10 +23,11 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <ctype.h>
#include <gpgme.h>
#include <string.h>
#include <glib.h>
-#include "gmime-gpgme-context.h"
+#include "libbalsa-gpgme.h"
#include "gmime-gpgme-signature.h"
@@ -37,7 +38,6 @@ static void g_mime_gpgme_sigstat_class_init(GMimeGpgmeSigstatClass *
klass);
static void g_mime_gpgme_sigstat_finalize(GMimeGpgmeSigstat * self);
static void g_mime_gpgme_sigstat_init(GMimeGpgmeSigstat * self);
-static gchar *fix_EMail_info(gchar * str);
/* GMimeGpgmeSigstat related stuff */
@@ -83,9 +83,6 @@ g_mime_gpgme_sigstat_new_from_gpgme_ctx(gpgme_ctx_t ctx)
{
GMimeGpgmeSigstat *sig_stat;
gpgme_verify_result_t result;
- gpgme_key_t key;
- gpgme_subkey_t subkey;
- gpgme_user_id_t uid;
gpgme_error_t err;
g_return_val_if_fail(ctx, NULL);
@@ -104,53 +101,14 @@ g_mime_gpgme_sigstat_new_from_gpgme_ctx(gpgme_ctx_t ctx)
sig_stat->fingerprint = g_strdup(result->signatures->fpr);
sig_stat->sign_time = result->signatures->timestamp;
sig_stat->status = gpgme_err_code(result->signatures->status);
+ sig_stat->validity = result->signatures->validity;
/* try to get the related key */
- err = gpgme_get_key(ctx, sig_stat->fingerprint, &key, 0);
- if (err != GPG_ERR_NO_ERROR) {
+ err = gpgme_get_key(ctx, sig_stat->fingerprint, &sig_stat->key, 0);
+ if (err != GPG_ERR_NO_ERROR)
g_message("could not retrieve the key with fingerprint %s: %s: %s",
sig_stat->fingerprint, gpgme_strsource(err),
gpgme_strerror(err));
- return sig_stat;
- }
- if (key == NULL)
- return sig_stat;
-
- /* the key is available */
- sig_stat->protocol = key->protocol;
- sig_stat->issuer_serial = g_strdup(key->issuer_serial);
- sig_stat->issuer_name = g_strdup(key->issuer_name);
- sig_stat->chain_id = g_strdup(key->chain_id);
- sig_stat->trust = key->owner_trust;
- uid = key->uids;
-
- /* Note: there is no way to determine which user id has been used to
- * create the signature. We therefore pick the validity of the primary
- * one and scan uid's to get useable name, email and uid strings */
- sig_stat->validity = uid->validity;
- while (uid) {
- if (!sig_stat->sign_name && uid->name && *uid->name)
- sig_stat->sign_name = g_strdup(uid->name);
- if (!sig_stat->sign_email && uid->email && *uid->email)
- sig_stat->sign_email = g_strdup(uid->email);
- if (!sig_stat->sign_uid && uid->uid && *uid->uid)
- sig_stat->sign_uid = fix_EMail_info(g_strdup(uid->uid));
- uid = uid->next;
- }
-
- /* get the subkey which can sign */
- subkey = key->subkeys;
- while (subkey && !subkey->can_sign)
- subkey = subkey->next;
- if (subkey) {
- sig_stat->key_created = subkey->timestamp;
- sig_stat->key_expires = subkey->expires;
- sig_stat->key_revoked = subkey->revoked;
- sig_stat->key_expired = subkey->expired;
- sig_stat->key_disabled = subkey->disabled;
- sig_stat->key_invalid = subkey->invalid;
- }
- gpgme_key_unref(key);
return sig_stat;
}
@@ -166,84 +124,107 @@ g_mime_gpgme_sigstat_class_init(GMimeGpgmeSigstatClass * klass)
(GObjectFinalizeFunc) g_mime_gpgme_sigstat_finalize;
}
-
static void
g_mime_gpgme_sigstat_finalize(GMimeGpgmeSigstat * self)
{
- g_free(self->sign_name);
- self->sign_name = NULL;
- g_free(self->sign_email);
- self->sign_email = NULL;
g_free(self->fingerprint);
self->fingerprint = NULL;
- g_free(self->sign_uid);
- self->sign_uid = NULL;
- g_free(self->issuer_serial);
- self->issuer_serial = NULL;
- g_free(self->issuer_name);
- self->issuer_name = NULL;
- g_free(self->chain_id);
- self->chain_id = NULL;
+ if (self->key)
+ gpgme_key_unref(self->key);
+ self->key = NULL;
g_mime_gpgme_sigstat_parent_class->finalize(G_OBJECT(self));
}
-
-static void
-g_mime_gpgme_sigstat_init(GMimeGpgmeSigstat * self)
+static gchar *
+hex_decode(const gchar *hexstr)
{
- self->status = GPG_ERR_NOT_SIGNED;
- self->sign_name = NULL;
- self->sign_email = NULL;
- self->fingerprint = NULL;
- self->sign_uid = NULL;
- self->issuer_serial = NULL;
- self->issuer_name = NULL;
- self->chain_id = NULL;
+ gchar *result;
+ gchar *outp;
+ int inlen;
+
+ inlen = strlen(hexstr);
+ if ((inlen & 1) == 1)
+ return g_strdup(hexstr);
+
+ result = g_new0(gchar, (inlen >> 1) + 1);
+ for (outp = result; *hexstr; outp++) {
+ if (isdigit(*hexstr))
+ *outp = (*hexstr - '0') << 4;
+ else
+ *outp = (toupper(*hexstr) -'A' + 10) << 4;
+ hexstr++;
+ if (isdigit(*hexstr))
+ *outp |= *hexstr - '0';
+ else
+ *outp |= toupper(*hexstr) -'A' + 10;
+ hexstr++;
+ }
+ return result;
}
-
/*
- * Change an EMail field in a S/MIME certificate to human-readable text.
+ * Change some fields in a S/MIME certificate to human-readable text.
* Note: doesn't do any sophisticated error-checking...
*/
-static gchar *
-fix_EMail_info(gchar * str)
+gchar *
+libbalsa_cert_subject_readable(const gchar *subject)
{
- gchar *p = strstr(str, "1.2.840.113549.1.9.1=#");
+ const struct {
+ gchar *ldap_id;
+ gchar *readable;
+ } ldap_id_list[] = {
+ { .ldap_id = "2.5.4.4", .readable = "sn" },
+ { .ldap_id = "2.5.4.5", .readable = "serialNumber" },
+ { .ldap_id = "2.5.4.42", .readable = "givenName" },
+ { .ldap_id = "1.2.840.113549.1.9.1", .readable = "email" },
+ { .ldap_id = NULL, .readable = NULL }
+ }, *ldap_elem;
+ gchar **elements;
+ gint n;
GString *result;
- if (!p)
- return str;
-
- *p = '\0';
- p += 22;
- result = g_string_new(str);
- result = g_string_append(result, "EMail=");
- while (*p != '\0' && *p != ',') {
- gchar x = 0;
-
- if (*p >= 'A' && *p <= 'F')
- x = (*p - 'A' + 10) << 4;
- else if (*p >= 'a' && *p <= 'f')
- x = (*p - 'a' + 10) << 4;
- else if (*p >= '0' && *p <= '9')
- x = (*p - '0') << 4;
- p++;
- if (*p != '\0' && *p != ',') {
- if (*p >= 'A' && *p <= 'F')
- x += *p - 'A' + 10;
- else if (*p >= 'a' && *p <= 'f')
- x += *p - 'a' + 10;
- else if (*p >= '0' && *p <= '9')
- x += *p - '0';
- p++;
- }
- result = g_string_append_c(result, x);
+ if (!subject)
+ return NULL;
+
+ result = g_string_new(NULL);
+ elements = g_strsplit(subject, ",", -1);
+ for (n = 0; elements[n]; n++) {
+ gchar *equals;
+
+ equals = strchr(elements[n], '=');
+ if (equals) {
+ *equals++ = '\0';
+ for (ldap_elem = ldap_id_list;
+ ldap_elem->ldap_id && strcmp(ldap_elem->ldap_id, elements[n]);
+ ldap_elem++);
+ if (ldap_elem->ldap_id)
+ result = g_string_append(result, ldap_elem->readable);
+ else
+ result = g_string_append(result, elements[n]);
+ result = g_string_append_c(result, '=');
+
+ if (*equals == '#') {
+ gchar *decoded;
+
+ decoded = hex_decode(equals + 1);
+ result = g_string_append(result, decoded);
+ g_free(decoded);
+ } else
+ result = g_string_append(result, equals);
+ } else
+ result = g_string_append(result, elements[n]);
+ if (elements[n + 1])
+ result = g_string_append_c(result, ',');
}
- result = g_string_append(result, p);
- g_free(str);
- p = result->str;
- g_string_free(result, FALSE);
- return p;
+ g_strfreev(elements);
+ return g_string_free(result, FALSE);
+}
+
+static void
+g_mime_gpgme_sigstat_init(GMimeGpgmeSigstat * self)
+{
+ self->status = GPG_ERR_NOT_SIGNED;
+ self->key = NULL;
+ self->fingerprint = NULL;
}
diff --git a/libbalsa/gmime-gpgme-signature.h b/libbalsa/gmime-gpgme-signature.h
index 73a2dfa..f036af9 100644
--- a/libbalsa/gmime-gpgme-signature.h
+++ b/libbalsa/gmime-gpgme-signature.h
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
* gmime/gpgme glue layer library
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * Copyright (C) 2004-2011 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
#define __GMIME_GPGME_SIGNATURE_H__
#include <gpgme.h>
-#include <glib-object.h>
+#include <glib.h>
#ifdef __cplusplus
@@ -43,30 +43,20 @@ extern "C" {
typedef struct _GMimeGpgmeSigstat GMimeGpgmeSigstat;
typedef struct _GMimeGpgmeSigstatClass GMimeGpgmeSigstatClass;
-
+typedef struct _sig_uid_t sig_uid_t;
struct _GMimeGpgmeSigstat {
GObject parent;
- /* various data gathered by gpgme's verify */
+ /* results form gpgme's verify operation */
gpgme_protocol_t protocol;
gpgme_error_t status;
gpgme_validity_t validity;
- gpgme_validity_t trust;
- gchar *sign_name;
- gchar *sign_email;
gchar *fingerprint;
- gchar *sign_uid;
- gchar *issuer_serial;
- gchar *issuer_name;
- gchar *chain_id;
- time_t key_created;
- time_t key_expires;
- gboolean key_revoked;
- gboolean key_expired;
- gboolean key_disabled;
- gboolean key_invalid;
time_t sign_time;
+
+ /* information about the key used to create the signature */
+ gpgme_key_t key;
};
struct _GMimeGpgmeSigstatClass {
@@ -79,6 +69,9 @@ GMimeGpgmeSigstat *g_mime_gpgme_sigstat_new(void);
GMimeGpgmeSigstat *g_mime_gpgme_sigstat_new_from_gpgme_ctx(gpgme_ctx_t
ctx);
+gchar *libbalsa_cert_subject_readable(const gchar *subject);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libbalsa/gmime-part-rfc2440.c b/libbalsa/gmime-part-rfc2440.c
index e79c4cb..4c032c6 100644
--- a/libbalsa/gmime-part-rfc2440.c
+++ b/libbalsa/gmime-part-rfc2440.c
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
- * gmime/gpgme glue layer library
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * gmime/gpgme implementation for RFC2440 parts
+ * Copyright (C) 2004-2011 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,21 +20,35 @@
*/
#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
#endif /* HAVE_CONFIG_H */
-#include "gmime-part-rfc2440.h"
#include <string.h>
+#include <glib.h>
+#include <gtk/gtk.h>
#include <gmime/gmime.h>
+#include "libbalsa-gpgme.h"
+#include "gmime-part-rfc2440.h"
#define RFC2440_BUF_LEN 4096
+
+/** \brief Check for a part's RFC 2440 protection
+ *
+ * \param part GMime part which shall be inspected.
+ * \return The OpenPGP (RFC 2440) protection of the part.
+ *
+ * Check if the passed part is RFC 2440 signed or encrypted by looking for
+ * the "magic" strings defined there. Note that parts which include extra
+ * data before the beginning or after the end of signed or encryped matter
+ * are always classified as GMIME_PART_RFC2440_NONE.
+ */
GMimePartRfc2440Mode
g_mime_part_check_rfc2440(GMimePart * part)
{
- GMimeDataWrapper * wrapper;
- GMimeStream * stream;
+ GMimeDataWrapper *wrapper;
+ GMimeStream *stream;
ssize_t slen;
gchar buf[RFC2440_BUF_LEN];
GMimePartRfc2440Mode retval = GMIME_PART_RFC2440_NONE;
@@ -58,7 +72,7 @@ g_mime_part_check_rfc2440(GMimePart * part)
strstr(buf, "-----END PGP MESSAGE-----"))
retval = GMIME_PART_RFC2440_ENCRYPTED;
else if (!strncmp(buf, "-----BEGIN PGP SIGNED MESSAGE-----", 34)) {
- gchar * p1, * p2;
+ gchar *p1, *p2;
p1 = strstr(buf, "-----BEGIN PGP SIGNATURE-----");
p2 = strstr(buf, "-----END PGP SIGNATURE-----");
@@ -68,14 +82,15 @@ g_mime_part_check_rfc2440(GMimePart * part)
} else {
/* check if the beginning of the stream matches */
g_mime_stream_read(stream, buf, 34);
- g_mime_stream_seek(stream, 1 - RFC2440_BUF_LEN, GMIME_STREAM_SEEK_END);
+ g_mime_stream_seek(stream, 1 - RFC2440_BUF_LEN,
+ GMIME_STREAM_SEEK_END);
if (!strncmp(buf, "-----BEGIN PGP MESSAGE-----", 27)) {
g_mime_stream_read(stream, buf, RFC2440_BUF_LEN - 1);
buf[RFC2440_BUF_LEN - 1] = '\0';
if (strstr(buf, "-----END PGP MESSAGE-----"))
retval = GMIME_PART_RFC2440_ENCRYPTED;
} else if (!strncmp(buf, "-----BEGIN PGP SIGNED MESSAGE-----", 34)) {
- gchar * p1, * p2;
+ gchar *p1, *p2;
g_mime_stream_read(stream, buf, RFC2440_BUF_LEN - 1);
buf[RFC2440_BUF_LEN - 1] = '\0';
@@ -90,20 +105,30 @@ g_mime_part_check_rfc2440(GMimePart * part)
}
-/*
- * RFC2440 sign, encrypt or sign and encrypt a gmime part using the
- * gmime gpgme context ctx. If sign_userid is not NULL, part will be
- * signed. If recipients is not NULL, encrypt part for recipients. If
- * both are not null, part will be first signed and then
+/** \brief RFC 2440 sign and/or encrypt a GMime part
+ *
+ * \param part GMime part which shall be signed and/or encrypted.
+ * \param sign_userid User ID of the signer, or NULL fo no signature.
+ * \param recipients Array of User ID for which the matter shall be
+ * encrypted using their public keys, or NULL for no encryption.
+ * \param trust_all_keys TRUE if all low-truct keys shall be accepted for
+ * encryption.
+ * \param parent Parent window to be passed to the callback functions.
+ * \param error Filled with error information on error.
+ * \return 0 on success, or -1 on error.
+ *
+ * RFC2440 sign, encrypt or sign and encrypt a gmime part. If sign_userid
+ * is not NULL, part will be signed. If recipients is not NULL, encrypt
+ * part for recipients. If both are not null, part will be both signed and
* encrypted. Returns 0 on success or -1 on fail. If any operation
* failed, an exception will be set on err to provide more
* information.
*/
int
-g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
- GMimeGpgmeContext * ctx,
+g_mime_part_rfc2440_sign_encrypt(GMimePart * part, const char *sign_userid,
GPtrArray * recipients,
- const char *sign_userid, GError ** err)
+ gboolean trust_all, GtkWindow * parent,
+ GError ** err)
{
GMimeDataWrapper *wrapper;
GMimeStream *stream, *cipherstream;
@@ -111,14 +136,6 @@ g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
gint result;
g_return_val_if_fail(GMIME_IS_PART(part), -1);
- g_return_val_if_fail(GMIME_IS_GPGME_CONTEXT(ctx), -1);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail(GMIME_CIPHER_CONTEXT(ctx)->sign_protocol != NULL,
- -1);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail(g_mime_crypto_context_get_signature_protocol
- (GMIME_CRYPTO_CONTEXT(ctx)) != NULL, -1);
-#endif /* HAVE_GMIME_2_5_7 */
g_return_val_if_fail(recipients != NULL || sign_userid != NULL, -1);
/* get the raw content */
@@ -133,43 +150,31 @@ g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
g_mime_stream_mem_set_owner(GMIME_STREAM_MEM(cipherstream), TRUE);
/* do the crypto operation */
- ctx->singlepart_mode = TRUE;
- if (recipients == NULL)
- result =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_cipher_context_sign(GMIME_CIPHER_CONTEXT(ctx), sign_userid,
- GMIME_CIPHER_HASH_DEFAULT, stream,
- cipherstream, err);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_crypto_context_sign(GMIME_CRYPTO_CONTEXT(ctx), sign_userid,
- GMIME_CIPHER_ALGO_DEFAULT, stream,
- cipherstream, err);
-#endif /* HAVE_GMIME_2_5_7 */
+ if (recipients == NULL) {
+ if (libbalsa_gpgme_sign
+ (sign_userid, stream, cipherstream, GPGME_PROTOCOL_OpenPGP,
+ TRUE, parent, err) == GPGME_MD_NONE)
+ result = -1;
else
+ result = 0;
+ } else
result =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_cipher_context_encrypt(GMIME_CIPHER_CONTEXT(ctx),
- sign_userid != NULL, sign_userid,
- recipients, stream, cipherstream, err);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_crypto_context_encrypt(GMIME_CRYPTO_CONTEXT(ctx),
- sign_userid != NULL, sign_userid,
- GMIME_CIPHER_ALGO_DEFAULT,
- recipients, stream, cipherstream, err);
-#endif /* HAVE_GMIME_2_5_7 */
+ libbalsa_gpgme_encrypt(recipients, sign_userid, stream,
+ cipherstream, GPGME_PROTOCOL_OpenPGP,
+ TRUE, trust_all, parent, err);
if (result == -1) {
g_object_unref(cipherstream);
return -1;
}
- /* add the headers to encrypted ascii armor output: as there is no "insert"
- * method for the byte array, first remove the leading "BEGIN PGP MESSAGE"
- * (27 chars) and prepend it again... */
+ /* add the headers to encrypted ascii armor output: as there is no
+ * "insert" method for the byte array, first remove the leading "BEGIN
+ * PGP MESSAGE" (27 chars) and prepend it again... */
if (recipients && g_mime_object_get_content_type(GMIME_OBJECT(part))) {
const gchar *charset =
g_mime_object_get_content_type_parameter(GMIME_OBJECT(part),
"charset");
- gchar * rfc2440header;
+ gchar *rfc2440header;
rfc2440header =
g_strdup_printf("-----BEGIN PGP MESSAGE-----\nCharset: %s\n"
@@ -189,16 +194,19 @@ g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
/*
* Paranoia: set the encoding of a signed part to quoted-printable (not
* requested by RFC2440, but it's safer...). If we encrypted use 7-bit
- * and set the charset to us-ascii instead, as gpg added it's own armor.
+ * and set the charset to us-ascii instead, as gpg added it's own
+ * armor.
*/
if (recipients == NULL) {
- if (g_mime_part_get_content_encoding(part) != GMIME_CONTENT_ENCODING_BASE64)
+ if (g_mime_part_get_content_encoding(part) !=
+ GMIME_CONTENT_ENCODING_BASE64)
g_mime_part_set_content_encoding(part,
GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE);
g_mime_data_wrapper_set_encoding(wrapper,
GMIME_CONTENT_ENCODING_DEFAULT);
} else {
- g_mime_part_set_content_encoding(part, GMIME_CONTENT_ENCODING_7BIT);
+ g_mime_part_set_content_encoding(part,
+ GMIME_CONTENT_ENCODING_7BIT);
g_mime_data_wrapper_set_encoding(wrapper,
GMIME_CONTENT_ENCODING_7BIT);
g_mime_object_set_content_type_parameter(GMIME_OBJECT(part),
@@ -213,38 +221,27 @@ g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
}
-/*
- * Verify the signature of the RFC 2440 signed part using the gpgme
- * context ctx and return the validity as determined by the crypto
- * routines or NULL on error. In the latter case, an exception will be
- * set on err to provide more information. Upon success, the content
- * of part is replaced by the verified output of the crypto engine.
+/* \brief Verify a RFC 2440 signed part
+ *
+ * \param part GMime part which shall be verified.
+ * \param error Filled with error information on error.
+ * \return A new signature status object on success, or NULL on error.
+ *
+ * Verify the signature of the RFC 2440 signed part and return the
+ * signature status as determined by the crypto routines or NULL on error.
+ * In the latter case, an exception will be set on err to provide more
+ * information. Upon success, the content of part is replaced by the
+ * verified output of the crypto engine.
*/
-#ifndef HAVE_GMIME_2_5_7
-GMimeSignatureValidity *
-#else /* HAVE_GMIME_2_5_7 */
-GMimeSignatureList *
-#endif /* HAVE_GMIME_2_5_7 */
-g_mime_part_rfc2440_verify(GMimePart * part,
- GMimeGpgmeContext * ctx, GError ** err)
+GMimeGpgmeSigstat *
+g_mime_part_rfc2440_verify(GMimePart * part, GError ** err)
{
- GMimeStream *stream, *plainstream;
- GMimeDataWrapper * wrapper;
-#ifndef HAVE_GMIME_2_5_7
- GMimeSignatureValidity *valid;
-#else /* HAVE_GMIME_2_5_7 */
- GMimeSignatureList *list;
-#endif /* HAVE_GMIME_2_5_7 */
+ GMimeStream *stream;
+ GMimeStream *plainstream;
+ GMimeDataWrapper *wrapper;
+ GMimeGpgmeSigstat *result;
g_return_val_if_fail(GMIME_IS_PART(part), NULL);
- g_return_val_if_fail(GMIME_IS_GPGME_CONTEXT(ctx), NULL);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail(GMIME_CIPHER_CONTEXT(ctx)->sign_protocol != NULL,
- NULL);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail(g_mime_crypto_context_get_signature_protocol
- (GMIME_CRYPTO_CONTEXT(ctx)) != NULL, NULL);
-#endif /* HAVE_GMIME_2_5_7 */
/* get the raw content */
wrapper = g_mime_part_get_content_object(GMIME_PART(part));
@@ -257,26 +254,12 @@ g_mime_part_rfc2440_verify(GMimePart * part,
plainstream = g_mime_stream_mem_new();
/* verify the signature */
- ctx->singlepart_mode = TRUE;
-#ifndef HAVE_GMIME_2_5_7
- valid =
- g_mime_cipher_context_verify(GMIME_CIPHER_CONTEXT(ctx),
- GMIME_CIPHER_HASH_DEFAULT, stream,
- plainstream, err);
-#else /* HAVE_GMIME_2_5_7 */
- list =
- g_mime_crypto_context_verify(GMIME_CRYPTO_CONTEXT(ctx),
- GMIME_CIPHER_ALGO_DEFAULT, stream,
- plainstream, err);
-#endif /* HAVE_GMIME_2_5_7 */
+ result =
+ libbalsa_gpgme_verify(stream, plainstream, GPGME_PROTOCOL_OpenPGP,
+ TRUE, err);
/* upon success, replace the signed content by the checked one */
-#ifndef HAVE_GMIME_2_5_7
- if (valid)
-#else /* HAVE_GMIME_2_5_7 */
- if (list)
-#endif /* HAVE_GMIME_2_5_7 */
- {
+ if (result) {
GMimeDataWrapper *wrapper = g_mime_data_wrapper_new();
g_mime_data_wrapper_set_stream(wrapper, plainstream);
@@ -285,49 +268,36 @@ g_mime_part_rfc2440_verify(GMimePart * part,
}
g_object_unref(plainstream);
-#ifndef HAVE_GMIME_2_5_7
- return valid;
-#else /* HAVE_GMIME_2_5_7 */
- return list;
-#endif /* HAVE_GMIME_2_5_7 */
+ return result;
}
-/*
- * Decrypt the RFC 2440 encrypted part using the gmime gpgme context
- * ctx and return 0 on success or -1 for fail. In the latter case, an
- * exception will be set on err to provide more information. Upon
+/* \brief Decrypt a RFC 2440 encrypted part
+ *
+ * \param part GMime part which shall be verified.
+ * \param parent Parent window to be passed to the passphrase callback
+ * function.
+ * \param error Filled with error information on error.
+ * \return A new signature status object on success, or NULL on error.
+ *
+ * Decrypt the RFC 2440 encrypted part and return the signature status as
+ * determined by the crypto routines or NULL on error. In the latter case,
+ * an exception will be set on err to provide more information. Upon
* success, the content of part is replaced by the decrypted output of
* the crypto engine. If the input was also signed, the signature is
- * verified and the result is placed in ctx by the underlying gpgme
- * context.
+ * verified.
*/
-#ifndef HAVE_GMIME_2_5_7
-GMimeSignatureValidity *
-#else /* HAVE_GMIME_2_5_7 */
-GMimeDecryptResult *
-#endif /* HAVE_GMIME_2_5_7 */
-g_mime_part_rfc2440_decrypt(GMimePart * part,
- GMimeGpgmeContext * ctx, GError ** err)
+GMimeGpgmeSigstat *
+g_mime_part_rfc2440_decrypt(GMimePart * part, GtkWindow * parent,
+ GError ** err)
{
- GMimeStream *stream, *plainstream;
- GMimeDataWrapper * wrapper;
-#ifndef HAVE_GMIME_2_5_7
- GMimeSignatureValidity *result;
-#else /* HAVE_GMIME_2_5_7 */
- GMimeDecryptResult *result;
-#endif /* HAVE_GMIME_2_5_7 */
+ GMimeStream *stream;
+ GMimeStream *plainstream;
+ GMimeDataWrapper *wrapper;
+ GMimeGpgmeSigstat *result;
gchar *headbuf = g_malloc0(1024);
g_return_val_if_fail(GMIME_IS_PART(part), NULL);
- g_return_val_if_fail(GMIME_IS_GPGME_CONTEXT(ctx), NULL);
-#ifndef HAVE_GMIME_2_5_7
- g_return_val_if_fail(GMIME_CIPHER_CONTEXT(ctx)->encrypt_protocol !=
- NULL, NULL);
-#else /* HAVE_GMIME_2_5_7 */
- g_return_val_if_fail(g_mime_crypto_context_get_encryption_protocol
- (GMIME_CRYPTO_CONTEXT(ctx)) != NULL, NULL);
-#endif /* HAVE_GMIME_2_5_7 */
/* get the raw content */
wrapper = g_mime_part_get_content_object(part);
@@ -344,13 +314,8 @@ g_mime_part_rfc2440_decrypt(GMimePart * part,
/* decrypt and (if possible) verify the input */
result =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_cipher_context_decrypt(GMIME_CIPHER_CONTEXT(ctx), stream,
- plainstream, err);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_crypto_context_decrypt(GMIME_CRYPTO_CONTEXT(ctx), stream,
- plainstream, err);
-#endif /* HAVE_GMIME_2_5_7 */
+ libbalsa_gpgme_decrypt(stream, plainstream, GPGME_PROTOCOL_OpenPGP,
+ parent, err);
if (result != NULL) {
GMimeStream *filter_stream;
@@ -361,7 +326,8 @@ g_mime_part_rfc2440_decrypt(GMimePart * part,
/* strip crlf off encrypted stuff coming from Winbloze crap */
filter_stream = g_mime_stream_filter_new(plainstream);
filter = g_mime_filter_crlf_new(FALSE, FALSE);
- g_mime_stream_filter_add(GMIME_STREAM_FILTER(filter_stream), filter);
+ g_mime_stream_filter_add(GMIME_STREAM_FILTER(filter_stream),
+ filter);
g_object_unref(filter);
/* replace the old contents by the decrypted stuff */
@@ -372,14 +338,15 @@ g_mime_part_rfc2440_decrypt(GMimePart * part,
g_mime_stream_write_to_stream(filter_stream, out_stream);
g_object_unref(filter_stream);
- g_mime_part_set_content_encoding(part, GMIME_CONTENT_ENCODING_8BIT);
+ g_mime_part_set_content_encoding(part,
+ GMIME_CONTENT_ENCODING_8BIT);
/*
- * Set the charset of the decrypted content to the RFC 2440 "Charset:"
- * header. If it is not present, RFC 2440 defines that the contents
- * should be utf-8, but real-life applications (e.g. pgp4pine) tend to
- * use "some" charset, so "unknown-8bit" is a safe choice in this case
- * and if no other charset is given.
+ * Set the charset of the decrypted content to the RFC 2440
+ * "Charset:" header. If it is not present, RFC 2440 defines that
+ * the contents should be utf-8, but real-life applications (e.g.
+ * pgp4pine) tend to use "some" charset, so "unknown-8bit" is a
+ * safe choice in this case and if no other charset is given.
*/
if (g_mime_object_get_content_type(GMIME_OBJECT(part))) {
gchar *up_headbuf = g_ascii_strup(headbuf, -1);
@@ -393,13 +360,17 @@ g_mime_part_rfc2440_decrypt(GMimePart * part,
while (*line_end > ' ')
line_end++;
*line_end = '\0';
- g_mime_object_set_content_type_parameter(GMIME_OBJECT(part),
- "charset", p);
+ g_mime_object_set_content_type_parameter(GMIME_OBJECT
+ (part), "charset",
+ p);
} else {
- if (!g_ascii_strcasecmp("us-ascii",
- g_mime_object_get_content_type_parameter(GMIME_OBJECT(part),
+ if (!g_ascii_strcasecmp
+ ("us-ascii",
+ g_mime_object_get_content_type_parameter(GMIME_OBJECT
+ (part),
"charset")))
- g_mime_object_set_content_type_parameter(GMIME_OBJECT(part),
+ g_mime_object_set_content_type_parameter(GMIME_OBJECT
+ (part),
"charset",
"unknown-8bit");
}
diff --git a/libbalsa/gmime-part-rfc2440.h b/libbalsa/gmime-part-rfc2440.h
index cc1901a..a757031 100644
--- a/libbalsa/gmime-part-rfc2440.h
+++ b/libbalsa/gmime-part-rfc2440.h
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/*
- * gmime/gpgme glue layer library
- * Copyright (C) 2004 Albrecht Dreß<albrecht dress arcor de>
+ * gmime/gpgme implementation for RFC2440 parts
+ * Copyright (C) 2004-2011 Albrecht Dreà <albrecht dress arcor de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,19 +23,18 @@
#define __GMIME_PART_RFC2440_H__
+#include <glib.h>
+#include <gtk/gtk.h>
#include <gmime/gmime.h>
-#include "gmime-gpgme-context.h"
#ifdef __cplusplus
extern "C" {
-# ifdef MAKE_EMACS_HAPPY
+#ifdef MAKE_EMACS_HAPPY
}
-# endif
+#endif
#endif /* __cplusplus */
-
-
typedef enum _GMimePartRfc2440Mode GMimePartRfc2440Mode;
enum _GMimePartRfc2440Mode {
GMIME_PART_RFC2440_NONE,
@@ -49,25 +48,15 @@ GMimePartRfc2440Mode g_mime_part_check_rfc2440(GMimePart * part);
/* crypto routines */
int g_mime_part_rfc2440_sign_encrypt(GMimePart * part,
- GMimeGpgmeContext * ctx,
- GPtrArray * recipients,
const char *sign_userid,
+ GPtrArray * recipients,
+ gboolean trust_all,
+ GtkWindow * parent, GError ** err);
+GMimeGpgmeSigstat *g_mime_part_rfc2440_verify(GMimePart * part,
GError ** err);
-#ifndef HAVE_GMIME_2_5_7
-GMimeSignatureValidity *g_mime_part_rfc2440_verify(GMimePart * part,
- GMimeGpgmeContext * ctx,
- GError ** err);
-GMimeSignatureValidity *g_mime_part_rfc2440_decrypt(GMimePart * part,
- GMimeGpgmeContext *
- ctx, GError ** err);
-#else /* HAVE_GMIME_2_5_7 */
-GMimeSignatureList *g_mime_part_rfc2440_verify(GMimePart * part,
- GMimeGpgmeContext * ctx,
- GError ** err);
-GMimeDecryptResult *g_mime_part_rfc2440_decrypt(GMimePart * part,
- GMimeGpgmeContext * ctx,
+GMimeGpgmeSigstat *g_mime_part_rfc2440_decrypt(GMimePart * part,
+ GtkWindow * parent,
GError ** err);
-#endif /* HAVE_GMIME_2_5_7 */
#ifdef __cplusplus
}
diff --git a/libbalsa/rfc3156.c b/libbalsa/rfc3156.c
index df4a2e1..c11f64e 100644
--- a/libbalsa/rfc3156.c
+++ b/libbalsa/rfc3156.c
@@ -35,7 +35,7 @@
#include "libbalsa.h"
#include "libbalsa_private.h"
-#include "gmime-gpgme-context.h"
+#include "gmime-multipart-crypt.h"
#include "gmime-gpgme-signature.h"
#include "gmime-part-rfc2440.h"
@@ -52,88 +52,16 @@
# include "macosx-helpers.h"
#endif
-#include "padlock-keyhole.xpm"
#include <glib/gi18n.h>
/* local prototypes */
-static const gchar *libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t
- validity);
-static gpgme_error_t get_passphrase_cb(void *opaque, const char *uid_hint,
- const char *passph_info,
- int prev_wasbad, int fd);
-static gpgme_key_t select_key_from_list(const gchar * name,
- gboolean is_secret,
- GMimeGpgmeContext * ctx,
- GList * keys);
-static gboolean accept_low_trust_key(const gchar * name,
- gpgme_user_id_t uid,
- GMimeGpgmeContext * ctx);
static gboolean gpg_updates_trustdb(void);
-static gchar *fix_EMail_info(gchar * str);
static gboolean have_pub_key_for(gpgme_ctx_t gpgme_ctx,
InternetAddressList * recipients);
/* ==== public functions =================================================== */
-gboolean
-libbalsa_check_crypto_engine(gpgme_protocol_t protocol)
-{
- gpgme_error_t err;
-
- err = gpgme_engine_check_version(protocol);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
- gpgme_engine_info_t info;
- GString *message = g_string_new("");
- err = gpgme_get_engine_info(&info);
- if (err == GPG_ERR_NO_ERROR) {
- while (info && info->protocol != protocol)
- info = info->next;
- if (!info)
- g_string_append_printf(message,
- _
- ("Gpgme has been compiled without support for protocol %s."),
- gpgme_get_protocol_name(protocol));
- else if (info->file_name && !info->version) {
- g_string_append_printf(message,
- _
- ("Crypto engine %s is not installed properly."),
- info->file_name);
- if (protocol == GPGME_PROTOCOL_OpenPGP)
- g_string_append_printf(message,
- _(" Hint: check the `gnupg2' (preferred) or `gnupg' package."));
- else if (protocol == GPGME_PROTOCOL_CMS)
- g_string_append_printf(message,
- _(" Hint: check the `gpgsm' package."));
- } else if (info->file_name && info->version && info->req_version)
- g_string_append_printf(message,
- _
- ("Crypto engine %s version %s is installed, but at least version %s is required."),
- info->file_name, info->version,
- info->req_version);
-
- else
- g_string_append_printf(message,
- _
- ("Unknown problem with engine for protocol %s."),
- gpgme_get_protocol_name(protocol));
- } else
- g_string_append_printf(message,
- _
- ("%s: could not retrieve crypto engine information: %s."),
- gpgme_strsource(err),
- gpgme_strerror(err));
- g_string_append_printf(message,
- _("\nDisable support for protocol %s."),
- gpgme_get_protocol_name(protocol));
- libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s", message->str);
- g_string_free(message, TRUE);
- return FALSE;
- } else
- return TRUE;
-}
-
-
static gboolean
body_is_type(LibBalsaMessageBody * body, const gchar * type,
const gchar * sub_type)
@@ -266,42 +194,6 @@ libbalsa_message_body_protection(LibBalsaMessageBody * body)
return result;
}
-#if defined(HAVE_GMIME_2_6)
-static gboolean
-#ifndef HAVE_GMIME_2_5_7
-password_request_func(GMimeCipherContext * ctx, const char *user_id,
- const char *prompt_ctx, gboolean reprompt,
- GMimeStream * response, GError ** err)
-#else /* HAVE_GMIME_2_5_7 */
-password_request_func(GMimeCryptoContext * ctx, const char *user_id,
- const char *prompt_ctx, gboolean reprompt,
- GMimeStream * response, GError ** err)
-#endif /* HAVE_GMIME_2_5_7 */
-{
- gint fd;
- gchar *name_used;
- gboolean rc;
-
- fd = g_file_open_tmp(NULL, &name_used, NULL);
- if (fd < 0)
- return FALSE;
-
- rc = get_passphrase_cb(ctx, user_id, prompt_ctx, reprompt, fd)
- == GPG_ERR_NO_ERROR;
- if (rc) {
- GMimeStream *stream = g_mime_stream_fs_new(fd);
- g_mime_stream_reset(stream);
- g_mime_stream_write_to_stream(response, stream);
-
- g_object_unref(stream);
- }
-
- unlink(name_used);
- g_free(name_used);
-
- return rc;
-}
-#endif /* HAVE_GMIME_2_6 */
/* === RFC 2633/ RFC 3156 crypto routines === */
/*
@@ -317,10 +209,6 @@ libbalsa_sign_mime_object(GMimeObject ** content, const gchar * rfc822_for,
gpgme_protocol_t protocol, GtkWindow * parent,
GError ** error)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
GMimeMultipartSigned *mps;
/* paranoia checks */
@@ -334,70 +222,18 @@ libbalsa_sign_mime_object(GMimeObject ** content, const gchar * rfc822_for,
if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
return FALSE;
-#if defined(HAVE_GMIME_2_6)
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, protocol, error));
- if (ctx == NULL)
- return FALSE;
-#else /* HAVE_GMIME_2_6 */
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new(session, protocol,
- error));
- if (ctx == NULL) {
- g_object_unref(session);
- return FALSE;
- }
-#endif /* HAVE_GMIME_2_6 */
-
- /* set the callbacks for the passphrase entry and the key selection */
- if (g_getenv("GPG_AGENT_INFO"))
- ctx->passphrase_cb = NULL; /* use gpg-agent */
- else {
- ctx->passphrase_cb = get_passphrase_cb;
- g_object_set_data(G_OBJECT(ctx), "passphrase-info",
- _
- ("Enter passphrase to unlock the secret key for signing"));
- }
- ctx->key_select_cb = select_key_from_list;
- g_object_set_data(G_OBJECT(ctx), "parent-window", parent);
-
/* call gpgme to create the signature */
if (!(mps = g_mime_multipart_signed_new())) {
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return FALSE;
}
-#ifndef HAVE_GMIME_2_5_7
- if (g_mime_multipart_signed_sign
- (mps, *content, GMIME_CIPHER_CONTEXT(ctx), rfc822_for,
- GMIME_CIPHER_HASH_DEFAULT, error) != 0)
-#else /* HAVE_GMIME_2_5_7 */
- if (g_mime_multipart_signed_sign
- (mps, *content, GMIME_CRYPTO_CONTEXT(ctx), rfc822_for,
- GMIME_DIGEST_ALGO_DEFAULT, error) != 0)
-#endif /* HAVE_GMIME_2_5_7 */
- {
+ if (g_mime_gpgme_mps_sign(mps, *content, rfc822_for, protocol, parent, error) != 0) {
g_object_unref(mps);
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return FALSE;
}
- g_mime_object_set_content_type_parameter(GMIME_OBJECT(mps),
- "micalg", ctx->micalg);
g_object_unref(G_OBJECT(*content));
*content = GMIME_OBJECT(mps);
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return TRUE;
}
@@ -412,10 +248,6 @@ libbalsa_encrypt_mime_object(GMimeObject ** content, GList * rfc822_for,
gpgme_protocol_t protocol, gboolean always_trust,
GtkWindow * parent, GError ** error)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
GMimeObject *encrypted_obj = NULL;
GPtrArray *recipients;
int result = -1;
@@ -431,32 +263,6 @@ libbalsa_encrypt_mime_object(GMimeObject ** content, GList * rfc822_for,
if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
return FALSE;
-#if !defined(HAVE_GMIME_2_6)
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new(session, protocol,
- error));
- if (ctx == NULL) {
- g_object_unref(session);
- return FALSE;
-#else /* HAVE_GMIME_2_6 */
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, protocol, error));
- if (ctx == NULL)
- return FALSE;
-#endif /* HAVE_GMIME_2_6 */
-#if !defined(HAVE_GMIME_2_6)
- }
-#endif /* HAVE_GMIME_2_6 */
-
- /* set the callback for the key selection (no secret needed here) */
- ctx->key_select_cb = select_key_from_list;
- if (!always_trust)
- ctx->key_trust_cb = accept_low_trust_key;
- ctx->always_trust_uid = always_trust;
- g_object_set_data(G_OBJECT(ctx), "parent-window", parent);
-
/* convert the key list to a GPtrArray */
recipients = g_ptr_array_new();
while (rfc822_for) {
@@ -470,60 +276,27 @@ libbalsa_encrypt_mime_object(GMimeObject ** content, GList * rfc822_for,
GMimeMultipartEncrypted *mpe = g_mime_multipart_encrypted_new();
encrypted_obj = GMIME_OBJECT(mpe);
- result =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_multipart_encrypted_encrypt(mpe, *content,
- GMIME_CIPHER_CONTEXT(ctx),
- FALSE, NULL,
- recipients, error);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_multipart_encrypted_encrypt(mpe, *content,
- GMIME_CRYPTO_CONTEXT(ctx),
- FALSE, NULL,
- GMIME_DIGEST_ALGO_DEFAULT,
- recipients, error);
-#endif /* HAVE_GMIME_2_5_7 */
+ result = g_mime_gpgme_mpe_encrypt(mpe, *content, recipients, always_trust, parent, error);
}
#ifdef HAVE_SMIME
else {
GMimePart *pkcs7 =
g_mime_part_new_with_type("application", "pkcs7-mime");
- encrypted_obj = GMIME_OBJECT(pkcs7);
- ctx->singlepart_mode = TRUE;
- result =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_application_pkcs7_encrypt(pkcs7, *content,
- GMIME_CIPHER_CONTEXT(ctx),
- recipients, error);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_application_pkcs7_encrypt(pkcs7, *content,
- GMIME_CRYPTO_CONTEXT(ctx),
- recipients, error);
-#endif /* HAVE_GMIME_2_5_7 */
+ result = g_mime_application_pkcs7_encrypt(pkcs7, *content, recipients, always_trust, parent, error);
}
#endif
+ g_ptr_array_free(recipients, FALSE);
/* error checking */
if (result != 0) {
- g_ptr_array_free(recipients, FALSE);
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
g_object_unref(encrypted_obj);
return FALSE;
- }
-
- g_ptr_array_free(recipients, FALSE);
+ } else {
g_object_unref(G_OBJECT(*content));
*content = GMIME_OBJECT(encrypted_obj);
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
-
return TRUE;
+ }
}
@@ -589,18 +362,8 @@ gboolean
libbalsa_body_check_signature(LibBalsaMessageBody * body,
gpgme_protocol_t protocol)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
-#ifndef HAVE_GMIME_2_5_7
- GMimeCipherContext *g_mime_ctx;
- GMimeSignatureValidity *valid;
-#else /* HAVE_GMIME_2_5_7 */
- GMimeCryptoContext *g_mime_ctx;
- GMimeSignatureList *valid;
-#endif /* HAVE_GMIME_2_5_7 */
- GMimeGpgmeContext *ctx;
GError *error = NULL;
+ GMimeGpgmeSigstat *result;
/* paranoia checks */
g_return_val_if_fail(body, FALSE);
@@ -622,56 +385,10 @@ libbalsa_body_check_signature(LibBalsaMessageBody * body,
if (body->parts->next->sig_info)
g_object_unref(G_OBJECT(body->parts->next->sig_info));
- /* try to create GMimeGpgMEContext */
-#if !defined(HAVE_GMIME_2_6)
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- g_mime_ctx = g_mime_gpgme_context_new(session, protocol, &error);
-#else /* HAVE_GMIME_2_6 */
- g_mime_ctx =
- g_mime_gpgme_context_new(password_request_func, protocol, &error);
-#endif /* HAVE_GMIME_2_6 */
- if (g_mime_ctx == NULL) {
- if (error) {
- libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
- _("creating a gpgme context failed"),
- error->message);
- g_error_free(error);
- } else
- libbalsa_information(LIBBALSA_INFORMATION_ERROR,
- _("creating a gpgme context failed"));
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
- body->parts->next->sig_info = g_mime_gpgme_sigstat_new();
- body->parts->next->sig_info->status = GPGME_SIG_STAT_ERROR;
- return FALSE;
- }
- ctx = GMIME_GPGME_CONTEXT(g_mime_ctx);
-
- /* S/MIME uses the protocol application/pkcs7-signature, but some ancient
- mailers, not yet knowing RFC 2633, use application/x-pkcs7-signature,
- so tweak the context if necessary... */
- if (protocol == GPGME_PROTOCOL_CMS) {
- const char * cms_protocol =
- g_mime_object_get_content_type_parameter(GMIME_OBJECT (body->mime_part),
- "protocol");
- if (!g_ascii_strcasecmp(cms_protocol, "application/x-pkcs7-signature"))
-#ifndef HAVE_GMIME_2_5_7
- g_mime_ctx->sign_protocol = cms_protocol;
-#else /* HAVE_GMIME_2_5_7 */
- ctx->sign_protocol = cms_protocol;
-#endif /* HAVE_GMIME_2_5_7 */
- }
-
/* verify the signature */
-
libbalsa_mailbox_lock_store(body->message->mailbox);
- valid = g_mime_multipart_signed_verify(GMIME_MULTIPART_SIGNED
- (body->mime_part), g_mime_ctx,
- &error);
- libbalsa_mailbox_unlock_store(body->message->mailbox);
-
- if (valid == NULL) {
+ result = g_mime_gpgme_mps_verify(GMIME_MULTIPART_SIGNED(body->mime_part), &error);
+ if (!result || result->status != GPG_ERR_NO_ERROR) {
if (error) {
libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
_("signature verification failed"),
@@ -681,19 +398,9 @@ libbalsa_body_check_signature(LibBalsaMessageBody * body,
libbalsa_information(LIBBALSA_INFORMATION_ERROR,
_("signature verification failed"));
}
- if (ctx->sig_state) {
- body->parts->next->sig_info = ctx->sig_state;
- g_object_ref(G_OBJECT(body->parts->next->sig_info));
- }
-#ifndef HAVE_GMIME_2_5_7
- g_mime_signature_validity_free(valid);
-#else /* HAVE_GMIME_2_5_7 */
- g_object_unref(valid);
-#endif /* HAVE_GMIME_2_5_7 */
- g_object_unref(g_mime_ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
+
+ body->parts->next->sig_info = result;
+ libbalsa_mailbox_unlock_store(body->message->mailbox);
return TRUE;
}
@@ -704,18 +411,14 @@ libbalsa_body_check_signature(LibBalsaMessageBody * body,
* decrypted bodies. Otherwise, the original body is returned.
*/
LibBalsaMessageBody *
-libbalsa_body_decrypt(LibBalsaMessageBody * body,
- gpgme_protocol_t protocol, GtkWindow * parent)
+libbalsa_body_decrypt(LibBalsaMessageBody *body, gpgme_protocol_t protocol, GtkWindow *parent)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
GMimeObject *mime_obj = NULL;
GError *error = NULL;
LibBalsaMessage *message;
+ GMimeGpgmeSigstat *sig_state = NULL;
#ifdef HAVE_SMIME
- gboolean smime_signed = FALSE;
+ gboolean smime_encrypted = FALSE;
#endif
/* paranoia checks */
@@ -743,97 +446,17 @@ libbalsa_body_decrypt(LibBalsaMessageBody * body,
if (!smime_type || !GMIME_IS_PART(body->mime_part))
return body;
- if (!g_ascii_strcasecmp(smime_type, "signed-data"))
- smime_signed = TRUE;
- else if (!g_ascii_strcasecmp(smime_type, "enveloped-data"))
- smime_signed = FALSE;
- else
- return body;
+ if (!g_ascii_strcasecmp(smime_type, "enveloped-data"))
+ smime_encrypted = FALSE;
}
#endif
-#if !defined(HAVE_GMIME_2_6)
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new(session, protocol,
- &error));
-#else /* HAVE_GMIME_2_6 */
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, protocol, &error));
-#endif /* HAVE_GMIME_2_6 */
- if (ctx == NULL) {
- if (error) {
- libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
- _("creating a gpgme context failed"),
- error->message);
- g_error_free(error);
- } else
- libbalsa_information(LIBBALSA_INFORMATION_ERROR,
- _("creating a gpgme context failed"));
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
- return body;
- }
-
- /* set the callback for the passphrase entry */
- if (g_getenv("GPG_AGENT_INFO"))
- ctx->passphrase_cb = NULL; /* use gpg-agent */
- else {
- ctx->passphrase_cb = get_passphrase_cb;
- g_object_set_data(G_OBJECT(ctx), "parent-window", parent);
- g_object_set_data(G_OBJECT(ctx), "passphrase-info",
- _("Enter passphrase to decrypt message"));
- }
-
libbalsa_mailbox_lock_store(body->message->mailbox);
if (protocol == GPGME_PROTOCOL_OpenPGP)
- mime_obj =
-#ifndef HAVE_GMIME_2_5_7
- g_mime_multipart_encrypted_decrypt(GMIME_MULTIPART_ENCRYPTED(body->mime_part),
- GMIME_CIPHER_CONTEXT(ctx),
- &error);
-#else /* HAVE_GMIME_2_5_7 */
- g_mime_multipart_encrypted_decrypt(GMIME_MULTIPART_ENCRYPTED(body->mime_part),
- GMIME_CRYPTO_CONTEXT(ctx),
- NULL,
- &error);
-#endif /* HAVE_GMIME_2_5_7 */
+ mime_obj = g_mime_gpgme_mpe_decrypt(GMIME_MULTIPART_ENCRYPTED(body->mime_part), &sig_state, parent, &error);
#ifdef HAVE_SMIME
- else if (smime_signed) {
-#ifndef HAVE_GMIME_2_5_7
- GMimeSignatureValidity *valid;
-#else /* HAVE_GMIME_2_5_7 */
- GMimeSignatureList *valid;
-#endif /* HAVE_GMIME_2_5_7 */
-
- ctx->singlepart_mode = TRUE;
-#ifndef HAVE_GMIME_2_5_7
- mime_obj =
- g_mime_application_pkcs7_verify(GMIME_PART(body->mime_part),
- &valid,
- GMIME_CIPHER_CONTEXT(ctx),
- &error);
- g_mime_signature_validity_free(valid);
- } else
- mime_obj =
- g_mime_application_pkcs7_decrypt(GMIME_PART(body->mime_part),
- GMIME_CIPHER_CONTEXT(ctx),
- &error);
-#else /* HAVE_GMIME_2_5_7 */
- mime_obj =
- g_mime_application_pkcs7_verify(GMIME_PART(body->mime_part),
- &valid,
- GMIME_CRYPTO_CONTEXT(ctx),
- &error);
- g_object_unref(valid);
- } else
- mime_obj =
- g_mime_application_pkcs7_decrypt(GMIME_PART(body->mime_part),
- GMIME_CRYPTO_CONTEXT(ctx),
- &error);
-#endif /* HAVE_GMIME_2_5_7 */
+ else
+ mime_obj = g_mime_application_pkcs7_decrypt_verify(GMIME_PART(body->mime_part), &sig_state, parent, &error);
#endif
libbalsa_mailbox_unlock_store(body->message->mailbox);
@@ -848,10 +471,6 @@ libbalsa_body_decrypt(LibBalsaMessageBody * body,
} else
libbalsa_information(LIBBALSA_INFORMATION_ERROR,
_("decryption failed"));
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return body;
}
message = body->message;
@@ -863,18 +482,14 @@ libbalsa_body_decrypt(LibBalsaMessageBody * body,
body->was_encrypted = TRUE;
#ifdef HAVE_SMIME
else
- body->was_encrypted = !smime_signed;
+ body->was_encrypted = smime_encrypted;
#endif
libbalsa_message_body_set_mime_body(body, mime_obj);
- if (ctx->sig_state && ctx->sig_state->status != GPG_ERR_NOT_SIGNED) {
- g_object_ref(ctx->sig_state);
- body->sig_info = ctx->sig_state;
- }
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
+ if (sig_state && sig_state->status != GPG_ERR_NOT_SIGNED)
+ body->sig_info = sig_state;
+ else
+ g_object_unref(G_OBJECT(sig_state));
return body;
}
@@ -883,14 +498,9 @@ libbalsa_body_decrypt(LibBalsaMessageBody * body,
/* routines dealing with RFC2440 */
gboolean
-libbalsa_rfc2440_sign_encrypt(GMimePart * part, const gchar * sign_for,
- GList * encrypt_for, gboolean always_trust,
- GtkWindow * parent, GError ** error)
+libbalsa_rfc2440_sign_encrypt(GMimePart *part, const gchar *sign_for, GList *encrypt_for, gboolean always_trust,
+ GtkWindow *parent, GError **error)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
GPtrArray *recipients;
gint result;
@@ -902,42 +512,6 @@ libbalsa_rfc2440_sign_encrypt(GMimePart * part, const gchar * sign_for,
if (gpg_updates_trustdb())
return FALSE;
-#if !defined(HAVE_GMIME_2_6)
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new(session,
- GPGME_PROTOCOL_OpenPGP,
- error));
- if (ctx == NULL) {
- g_object_unref(session);
-#else /* HAVE_GMIME_2_6 */
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, GPGME_PROTOCOL_OpenPGP, error));
- if (ctx == NULL)
-#endif /* HAVE_GMIME_2_6 */
- return FALSE;
-#if !defined(HAVE_GMIME_2_6)
- }
-#endif /* HAVE_GMIME_2_6 */
-
- /* set the callback for the key selection and the passphrase */
- if (sign_for) {
- if (g_getenv("GPG_AGENT_INFO"))
- ctx->passphrase_cb = NULL; /* use gpg-agent */
- else {
- ctx->passphrase_cb = get_passphrase_cb;
- g_object_set_data(G_OBJECT(ctx), "passphrase-info",
- _
- ("Enter passphrase to unlock the secret key for signing"));
- }
- }
- ctx->key_select_cb = select_key_from_list;
- if (!always_trust)
- ctx->key_trust_cb = accept_low_trust_key;
- ctx->always_trust_uid = always_trust;
- g_object_set_data(G_OBJECT(ctx), "parent-window", parent);
-
/* convert the key list to a GPtrArray */
if (encrypt_for) {
recipients = g_ptr_array_new();
@@ -949,16 +523,10 @@ libbalsa_rfc2440_sign_encrypt(GMimePart * part, const gchar * sign_for,
recipients = NULL;
/* sign and/or encrypt */
- result =
- g_mime_part_rfc2440_sign_encrypt(part, ctx, recipients, sign_for,
- error);
+ result = g_mime_part_rfc2440_sign_encrypt(part, sign_for, recipients, always_trust, parent, error);
/* clean up */
if (recipients)
g_ptr_array_free(recipients, FALSE);
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return (result == 0) ? TRUE : FALSE;
}
@@ -970,15 +538,7 @@ libbalsa_rfc2440_sign_encrypt(GMimePart * part, const gchar * sign_for,
gpgme_error_t
libbalsa_rfc2440_verify(GMimePart * part, GMimeGpgmeSigstat ** sig_info)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
-#ifndef HAVE_GMIME_2_5_7
- GMimeSignatureValidity *valid;
-#else /* HAVE_GMIME_2_5_7 */
- GMimeSignatureList *valid;
-#endif /* HAVE_GMIME_2_5_7 */
+ GMimeGpgmeSigstat *result;
GError *error = NULL;
gpgme_error_t retval;
@@ -995,36 +555,9 @@ libbalsa_rfc2440_verify(GMimePart * part, GMimeGpgmeSigstat ** sig_info)
if (gpg_updates_trustdb())
return GPG_ERR_TRY_AGAIN;
-#if !defined(HAVE_GMIME_2_6)
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new(session,
- GPGME_PROTOCOL_OpenPGP,
- &error));
-#else /* HAVE_GMIME_2_6 */
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, GPGME_PROTOCOL_OpenPGP, &error));
-#endif /* HAVE_GMIME_2_6 */
- if (ctx == NULL) {
- if (error) {
- libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
- _("creating a gpgme context failed"),
- error->message);
- g_error_free(error);
- } else
- libbalsa_information(LIBBALSA_INFORMATION_ERROR,
- _("creating a gpgme context failed"));
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
- return FALSE;
- }
-
/* verify */
- valid = g_mime_part_rfc2440_verify(part, ctx, &error);
-
- if (valid == NULL) {
+ result = g_mime_part_rfc2440_verify(part, &error);
+ if (!result || result->status != GPG_ERR_NO_ERROR) {
if (error) {
libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
_("signature verification failed"),
@@ -1036,30 +569,16 @@ libbalsa_rfc2440_verify(GMimePart * part, GMimeGpgmeSigstat ** sig_info)
_("signature verification failed"));
retval = GPG_ERR_GENERAL;
}
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
- return retval;
- }
+ } else
+ retval = result->status;
/* return the signature info if requested */
- if (sig_info) {
- g_object_ref(ctx->sig_state);
- *sig_info = ctx->sig_state;
+ if (result) {
+ if (sig_info)
+ *sig_info = result;
+ else
+ g_object_unref(G_OBJECT(result));
}
-
- /* clean up */
-#ifndef HAVE_GMIME_2_5_7
- g_mime_signature_validity_free(valid);
-#else /* HAVE_GMIME_2_5_7 */
- g_object_unref(valid);
-#endif /* HAVE_GMIME_2_5_7 */
- retval = ctx->sig_state->status;
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return retval;
}
@@ -1073,11 +592,8 @@ gpgme_error_t
libbalsa_rfc2440_decrypt(GMimePart * part, GMimeGpgmeSigstat ** sig_info,
GtkWindow * parent)
{
-#if !defined(HAVE_GMIME_2_6)
- GMimeSession *session;
-#endif /* HAVE_GMIME_2_6 */
- GMimeGpgmeContext *ctx;
GError *error = NULL;
+ GMimeGpgmeSigstat *result;
gpgme_error_t retval;
/* paranoia checks */
@@ -1093,44 +609,11 @@ libbalsa_rfc2440_decrypt(GMimePart * part, GMimeGpgmeSigstat ** sig_info,
if (gpg_updates_trustdb())
return GPG_ERR_TRY_AGAIN;
-#if !defined(HAVE_GMIME_2_6)
- /* create a session and a GMimeGpgmeContext */
- session = g_object_new(g_mime_session_get_type(), NULL, NULL);
- ctx =
- GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (session, GPGME_PROTOCOL_OpenPGP, &error));
-#else /* HAVE_GMIME_2_6 */
- /* create a GMimeGpgmeContext */
- ctx = GMIME_GPGME_CONTEXT(g_mime_gpgme_context_new
- (password_request_func, GPGME_PROTOCOL_OpenPGP, &error));
-#endif /* HAVE_GMIME_2_6 */
- if (ctx == NULL) {
- if (error) {
- libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
- _("creating a gpgme context failed"),
- error->message);
- g_error_free(error);
- } else
- libbalsa_information(LIBBALSA_INFORMATION_ERROR,
- _("creating a gpgme context failed"));
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
- return GPG_ERR_GENERAL;
- }
-
- /* set the callback for the passphrase */
- if (g_getenv("GPG_AGENT_INFO"))
- ctx->passphrase_cb = NULL; /* use gpg-agent */
- else {
- ctx->passphrase_cb = get_passphrase_cb;
- g_object_set_data(G_OBJECT(ctx), "passphrase-info",
- _("Enter passphrase to decrypt message"));
- g_object_set_data(G_OBJECT(ctx), "parent-window", parent);
- }
+ // g_object_set_data(G_OBJECT(ctx), "parent-window", parent); FIXME - pass downstream
/* decrypt */
- if (g_mime_part_rfc2440_decrypt(part, ctx, &error) == NULL) {
+ result = g_mime_part_rfc2440_decrypt(part, parent, &error);
+ if (result == NULL) {
if (error) {
if (error->code != GPG_ERR_CANCELED)
libbalsa_information(LIBBALSA_INFORMATION_ERROR, "%s: %s",
@@ -1144,28 +627,18 @@ libbalsa_rfc2440_decrypt(GMimePart * part, GMimeGpgmeSigstat ** sig_info,
("decryption and signature verification failed"));
retval = GPG_ERR_GENERAL;
}
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return retval;
- }
+ } else
+ retval = result->status;
- retval = GPG_ERR_NO_ERROR;
- if (ctx->sig_state) {
- retval = ctx->sig_state->status;
- /* return the signature info if requested & available */
- if (sig_info && ctx->sig_state->status != GPG_ERR_NOT_SIGNED) {
- g_object_ref(ctx->sig_state);
- *sig_info = ctx->sig_state;
- }
+ /* return the signature info if requested */
+ if (result) {
+ if (sig_info && result->status != GPG_ERR_NOT_SIGNED)
+ *sig_info = result;
+ else
+ g_object_unref(G_OBJECT(result));
}
- /* clean up */
- g_object_unref(ctx);
-#if !defined(HAVE_GMIME_2_6)
- g_object_unref(session);
-#endif /* HAVE_GMIME_2_6 */
return retval;
}
@@ -1204,6 +677,8 @@ libbalsa_gpgme_sig_stat_to_gchar(gpgme_error_t stat)
return _("An error prevented the signature verification.");
}
}
+
+
const gchar *
libbalsa_gpgme_validity_to_gchar(gpgme_validity_t validity)
{
@@ -1224,6 +699,30 @@ libbalsa_gpgme_validity_to_gchar(gpgme_validity_t validity)
return _("bad validity");
}
}
+
+
+const gchar *
+libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t validity)
+{
+ switch (validity) {
+ case GPGME_VALIDITY_UNKNOWN:
+ return _("unknown");
+ case GPGME_VALIDITY_UNDEFINED:
+ return _("undefined");
+ case GPGME_VALIDITY_NEVER:
+ return _("never");
+ case GPGME_VALIDITY_MARGINAL:
+ return _("marginal");
+ case GPGME_VALIDITY_FULL:
+ return _("full");
+ case GPGME_VALIDITY_ULTIMATE:
+ return _("ultimate");
+ default:
+ return _("bad validity");
+ }
+}
+
+
const gchar *
libbalsa_gpgme_sig_protocol_name(gpgme_protocol_t protocol)
{
@@ -1237,14 +736,18 @@ libbalsa_gpgme_sig_protocol_name(gpgme_protocol_t protocol)
}
}
-#define APPEND_TIMET(str,fmt,t) \
- do { \
- if (t) { \
- gchar * _tbuf = libbalsa_date_to_utf8(&t, date_string); \
- g_string_append_printf(str, fmt, _tbuf); \
- g_free(_tbuf); \
- } \
- } while (0)
+static inline void
+append_time_t(GString *str, const gchar *format, time_t *when,
+ const gchar * date_string)
+{
+ if (*when != (time_t) 0) {
+ gchar *tbuf = libbalsa_date_to_utf8(when, date_string);
+ g_string_append_printf(str, format, tbuf);
+ g_free(tbuf);
+ } else {
+ g_string_append_printf(str, format, _("never"));
+ }
+}
gchar *
libbalsa_signature_info_to_gchar(GMimeGpgmeSigstat * info,
@@ -1259,74 +762,124 @@ libbalsa_signature_info_to_gchar(GMimeGpgmeSigstat * info,
msg =
g_string_append(msg,
libbalsa_gpgme_sig_stat_to_gchar(info->status));
- if (info->sign_uid && strlen(info->sign_uid))
- g_string_append_printf(msg, _("\nUser ID: %s"), info->sign_uid);
-
- else if (info->sign_name && strlen(info->sign_name)) {
- g_string_append_printf(msg, _("\nSigned by: %s"), info->sign_name);
- if (info->sign_email && strlen(info->sign_email))
- g_string_append_printf(msg, " <%s>", info->sign_email);
- } else if (info->sign_email && strlen(info->sign_email))
- g_string_append_printf(msg, _("\nMail address: %s"),
- info->sign_email);
- APPEND_TIMET(msg, _("\nSigned on: %s"), info->sign_time);
- g_string_append_printf(msg, _("\nUser ID validity: %s"),
+ g_string_append_printf(msg, _("\nSignature validity: %s"),
libbalsa_gpgme_validity_to_gchar(info->
validity));
- if (info->protocol == GPGME_PROTOCOL_OpenPGP)
+ append_time_t(msg, _("\nSigned on: %s"), &info->sign_time, date_string);
+ if (info->protocol == GPGME_PROTOCOL_OpenPGP && info->key)
g_string_append_printf(msg, _("\nKey owner trust: %s"),
libbalsa_gpgme_validity_to_gchar_short
- (info->trust));
+ (info->key->owner_trust));
if (info->fingerprint)
g_string_append_printf(msg, _("\nKey fingerprint: %s"),
info->fingerprint);
- /* Subkey creation date */
- APPEND_TIMET(msg, _("\nSubkey created on: %s"), info->key_created);
- /* Subkey expiration date */
- APPEND_TIMET(msg, _("\nSubkey expires on: %s"), info->key_expires);
- if (info->key_revoked || info->key_expired || info->key_disabled ||
- info->key_invalid) {
+
+ /* add key information */
+ if (info->key) {
+ gpgme_user_id_t uid;
+ gpgme_subkey_t subkey;
+
+ /* user ID's */
+ if ((uid = info->key->uids)) {
+ gchar *lead_text;
+
+ uid = info->key->uids;
+ if (uid->next) {
+ msg = g_string_append(msg, _("\nUser ID's:"));
+ lead_text = "\n\342\200\242";
+ } else {
+ msg = g_string_append(msg, _("\nUser ID:"));
+ lead_text = "";
+ }
+
+ /* Note: there is no way to determine which user id has been used
+ * to create the signature. A broken client may even use an
+ * invalid and/or revoked one. We therefore add all to the
+ * result. */
+ while (uid) {
+ msg = g_string_append(msg, lead_text);
+ if (uid->revoked)
+ msg = g_string_append(msg, _(" [Revoked]"));
+ if (uid->invalid)
+ msg = g_string_append(msg, _(" [Invalid]"));
+
+ if (uid->uid && *(uid->uid)) {
+ gchar *uid_readable =
+ libbalsa_cert_subject_readable(uid->uid);
+ g_string_append_printf(msg, " %s", uid_readable);
+ g_free(uid_readable);
+ } else {
+ if (uid->name && *(uid->name))
+ g_string_append_printf(msg, " %s", uid->name);
+ if (uid->email && *(uid->email))
+ g_string_append_printf(msg, " <%s>", uid->email);
+ if (uid->comment && *(uid->comment))
+ g_string_append_printf(msg, " (%s)", uid->comment);
+ }
+
+ uid = uid->next;
+ }
+ }
+
+ /* subkey */
+ if ((subkey = info->key->subkeys)) {
+ /* find the one which can sign */
+ while (subkey && !subkey->can_sign)
+ subkey = subkey->next;
+
+ if (subkey) {
+ append_time_t(msg, _("\nSubkey created on: %s"),
+ &subkey->timestamp, date_string);
+ append_time_t(msg, _("\nSubkey expires on: %s"),
+ &subkey->expires, date_string);
+ if (subkey->revoked || subkey->expired || subkey->disabled ||
+ subkey->invalid) {
GString * attrs = g_string_new("");
int count = 0;
- if (info->key_revoked) {
+ if (subkey->revoked) {
count++;
attrs = g_string_append(attrs, _(" revoked"));
}
- if (info->key_expired) {
+ if (subkey->expired) {
if (count++)
attrs = g_string_append_c(attrs, ',');
attrs = g_string_append(attrs, _(" expired"));
}
- if (info->key_disabled) {
+ if (subkey->disabled) {
if (count)
attrs = g_string_append_c(attrs, ',');
attrs = g_string_append(attrs, _(" disabled"));
}
- if (info->key_invalid) {
+ if (subkey->invalid) {
if (count)
attrs = g_string_append_c(attrs, ',');
attrs = g_string_append(attrs, _(" invalid"));
}
- /* ngettext: string begins with a single space, so no space after
- * the colon is correct punctuation (in English). */
+ /* ngettext: string begins with a single space, so no space
+ * after the colon is correct punctuation (in English). */
g_string_append_printf(msg, ngettext("\nSubkey attribute:%s",
"\nSubkey attributes:%s",
count),
attrs->str);
g_string_free(attrs, TRUE);
}
- if (info->issuer_name) {
- gchar * issuer = fix_EMail_info(g_strdup(info->issuer_name));
-
- g_string_append_printf(msg, _("\nIssuer name: %s"), issuer);
- g_free(issuer);
+ }
+ }
+
+ if (info->key->issuer_name) {
+ gchar *issuer_name =
+ libbalsa_cert_subject_readable(info->key->issuer_name);
+ g_string_append_printf(msg, _("\nIssuer name: %s"), issuer_name);
+ g_free(issuer_name);
}
- if (info->issuer_serial)
+ if (info->key->issuer_serial)
g_string_append_printf(msg, _("\nIssuer serial number: %s"),
- info->issuer_serial);
- if (info->chain_id)
- g_string_append_printf(msg, _("\nChain ID: %s"), info->chain_id);
+ info->key->issuer_serial);
+ if (info->key->chain_id)
+ g_string_append_printf(msg, _("\nChain ID: %s"), info->key->chain_id);
+ }
+
retval = msg->str;
g_string_free(msg, FALSE);
return retval;
@@ -1462,489 +1015,6 @@ check_gpg_child(gpointer data)
/* ==== local stuff ======================================================== */
-static const gchar *
-libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t validity)
-{
- switch (validity) {
- case GPGME_VALIDITY_UNKNOWN:
- return _("unknown");
- case GPGME_VALIDITY_UNDEFINED:
- return _("undefined");
- case GPGME_VALIDITY_NEVER:
- return _("never");
- case GPGME_VALIDITY_MARGINAL:
- return _("marginal");
- case GPGME_VALIDITY_FULL:
- return _("full");
- case GPGME_VALIDITY_ULTIMATE:
- return _("ultimate");
- default:
- return _("bad validity");
- }
-}
-
-
-#define OID_EMAIL "1.2.840.113549.1.9.1=#"
-#define OID_EMAIL_LEN 22
-static gchar *
-fix_EMail_info(gchar * str)
-{
- gchar *p;
- GString *result;
-
- /* check for any EMail info */
- p = strstr(str, OID_EMAIL);
- if (!p)
- return str;
-
- *p = '\0';
- p += OID_EMAIL_LEN;
- result = g_string_new(str);
- while (p) {
- gchar *next;
-
- result = g_string_append(result, "EMail=");
- /* convert the info from hex until we reach some other char */
- while (g_ascii_isxdigit(*p)) {
- gchar c = g_ascii_xdigit_value(*p++) << 4;
-
- if (g_ascii_isxdigit(*p))
- result =
- g_string_append_c(result, c + g_ascii_xdigit_value(*p++));
- }
-
- /* find more */
- next = strstr(p, OID_EMAIL);
- if (next) {
- *next = '\0';
- next += OID_EMAIL_LEN;
- }
- result = g_string_append(result, p);
- p = next;
- }
- g_free(str);
- p = result->str;
- g_string_free(result, FALSE);
- return p;
-}
-
-
-/* stuff to get a key fingerprint from a selection list */
-enum {
- GPG_KEY_USER_ID_COLUMN = 0,
- GPG_KEY_ID_COLUMN,
- GPG_KEY_LENGTH_COLUMN,
- GPG_KEY_VALIDITY_COLUMN,
- GPG_KEY_PTR_COLUMN,
- GPG_KEY_NUM_COLUMNS
-};
-
-static gchar *col_titles[] =
- { N_("User ID"), N_("Key ID"), N_("Length"), N_("Validity") };
-
-/* callback function if a new row is selected in the list */
-static void
-key_selection_changed_cb(GtkTreeSelection * selection, gpgme_key_t * key)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
-
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, GPG_KEY_PTR_COLUMN, key, -1);
-}
-
-
-/*
- * Select a key for the mail address for_address from the gpgme_key_t's in keys
- * and return either the selected key or NULL if the dialog was cancelled.
- * secret_only controls the dialog message.
- */
-static gpgme_key_t
-select_key_from_list(const gchar * name, gboolean is_secret,
- GMimeGpgmeContext * ctx, GList * keys)
-{
- GtkWidget *dialog;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *scrolled_window;
- GtkWidget *tree_view;
- GtkTreeStore *model;
- GtkTreeSelection *selection;
- GtkTreeIter iter;
- gint i, last_col;
- gchar *prompt;
- gchar *upcase_name;
- gpgme_protocol_t protocol;
- GtkWindow *parent;
- gpgme_key_t use_key = NULL;
-
- g_return_val_if_fail(ctx != NULL, NULL);
- g_return_val_if_fail(keys != NULL, NULL);
- protocol = gpgme_get_protocol(ctx->gpgme_ctx);
- parent = GTK_WINDOW(g_object_get_data(G_OBJECT(ctx), "parent-window"));
-
- /* FIXME: create dialog according to the Gnome HIG */
- dialog = gtk_dialog_new_with_buttons(_("Select key"),
- parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL, NULL);
-#if HAVE_MACOSX_DESKTOP
- libbalsa_macosx_menu_for_parent(dialog, parent);
-#endif
- vbox = gtk_vbox_new(FALSE, 12);
- gtk_container_add(GTK_CONTAINER
- (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
- vbox);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
- if (is_secret)
- prompt =
- g_strdup_printf(_("Select the private key for the signer %s"),
- name);
- else
- prompt = g_strdup_printf(_
- ("Select the public key for the recipient %s"),
- name);
- label = gtk_label_new(prompt);
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
- g_free(prompt);
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
-
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
- (scrolled_window),
- GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
-
- model =
- gtk_tree_store_new(GPG_KEY_NUM_COLUMNS,
- G_TYPE_STRING, /* user ID */
- G_TYPE_STRING, /* key ID */
- G_TYPE_INT, /* length */
- G_TYPE_STRING, /* validity (gpg encrypt only) */
- G_TYPE_POINTER); /* key */
-
- tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
- gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
- g_signal_connect(G_OBJECT(selection), "changed",
- G_CALLBACK(key_selection_changed_cb), &use_key);
-
- /* add the keys */
- upcase_name = g_ascii_strup(name, -1);
- while (keys) {
- gpgme_key_t key = (gpgme_key_t) keys->data;
- gpgme_subkey_t subkey = key->subkeys;
- gpgme_user_id_t uid = key->uids;
- gchar *uid_info = NULL;
- gboolean uid_found;
-
- /* find the relevant subkey */
- while (subkey && ((is_secret && !subkey->can_sign) ||
- (!is_secret && !subkey->can_encrypt)))
- subkey = subkey->next;
-
- /* find the relevant uid */
- uid_found = FALSE;
- while (uid && !uid_found) {
- g_free(uid_info);
- uid_info = fix_EMail_info(g_strdup(uid->uid));
-
- /* check the email field which may or may not be present */
- if (uid->email && !g_ascii_strcasecmp(uid->email, name))
- uid_found = TRUE;
- else {
- /* no email or no match, check the uid */
- gchar * upcase_uid = g_ascii_strup(uid_info, -1);
-
- if (strstr(upcase_uid, upcase_name))
- uid_found = TRUE;
- else
- uid = uid->next;
- g_free(upcase_uid);
- }
- }
-
- /* append the element */
- if (subkey && uid) {
- gtk_tree_store_append(GTK_TREE_STORE(model), &iter, NULL);
- gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
- GPG_KEY_USER_ID_COLUMN, uid_info,
- GPG_KEY_ID_COLUMN, subkey->keyid,
- GPG_KEY_LENGTH_COLUMN, subkey->length,
- GPG_KEY_VALIDITY_COLUMN,
- libbalsa_gpgme_validity_to_gchar_short
- (uid->validity),
- GPG_KEY_PTR_COLUMN, key,
- -1);
- }
- g_free(uid_info);
- keys = g_list_next(keys);
- }
- g_free(upcase_name);
-
- g_object_unref(G_OBJECT(model));
- /* show the validity only if we are asking for a gpg public key */
- last_col = (protocol == GPGME_PROTOCOL_CMS || is_secret) ?
- GPG_KEY_LENGTH_COLUMN : GPG_KEY_VALIDITY_COLUMN;
- for (i = 0; i <= last_col; i++) {
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
-
- renderer = gtk_cell_renderer_text_new();
- column =
- gtk_tree_view_column_new_with_attributes(_(col_titles[i]),
- renderer, "text", i,
- NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
- gtk_tree_view_column_set_resizable(column, TRUE);
- }
-
- gtk_container_add(GTK_CONTAINER(scrolled_window), tree_view);
- gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
- gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
-
- if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
- use_key = NULL;
- gtk_widget_destroy(dialog);
-
- return use_key;
-}
-
-
-/*
- * Display a dialog to select whether a key with a low trust level shall be accepted
- */
-static gboolean
-accept_low_trust_key(const gchar * name, gpgme_user_id_t uid,
- GMimeGpgmeContext * ctx)
-{
- GtkWidget *dialog;
- GtkWindow *parent;
- gint result;
- gchar *message1;
- gchar *message2;
-
- /* paranoia checks */
- g_return_val_if_fail(ctx != NULL, FALSE);
- g_return_val_if_fail(uid != NULL, FALSE);
- parent = GTK_WINDOW(g_object_get_data(G_OBJECT(ctx), "parent-window"));
-
- /* build the message */
- message1 =
- g_strdup_printf(_("Insufficient trust for recipient %s"), name);
- message2 =
- g_strdup_printf(_("The validity of the key with user ID \"%s\" is \"%s\"."),
- uid->uid,
- libbalsa_gpgme_validity_to_gchar_short(uid->validity));
- dialog =
- gtk_message_dialog_new_with_markup(parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_YES_NO,
- "<b>%s</b>\n\n%s\n%s",
- message1,
- message2,
- _("Use this key anyway?"));
-#if HAVE_MACOSX_DESKTOP
- libbalsa_macosx_menu_for_parent(dialog, parent);
-#endif
-
- /* ask the user */
- result = gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
-
- return result == GTK_RESPONSE_YES;
-}
-
-
-/*
- * display a dialog to read the passphrase
- */
-static gchar *
-get_passphrase_real(GMimeGpgmeContext * ctx, const gchar * uid_hint,
- int prev_was_bad)
-{
- static GdkPixbuf *padlock_keyhole = NULL;
- GtkWidget *dialog, *entry, *vbox, *hbox;
- gchar *prompt, *passwd;
- const gchar *title =
- g_object_get_data(G_OBJECT(ctx), "passphrase-title");
- GtkWindow *parent = g_object_get_data(G_OBJECT(ctx), "parent-window");
-
- /* FIXME: create dialog according to the Gnome HIG */
- dialog = gtk_dialog_new_with_buttons(title, parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL, NULL);
-#if HAVE_MACOSX_DESKTOP
- libbalsa_macosx_menu_for_parent(dialog, parent);
-#endif
- hbox = gtk_hbox_new(FALSE, 12);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 12);
- gtk_container_add(GTK_CONTAINER
- (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
- hbox);
-
- vbox = gtk_vbox_new(FALSE, 12);
- gtk_container_add(GTK_CONTAINER(hbox), vbox);
- if (!padlock_keyhole)
- padlock_keyhole =
- gdk_pixbuf_new_from_xpm_data(padlock_keyhole_xpm);
- gtk_box_pack_start(GTK_BOX(vbox),
- gtk_image_new_from_pixbuf(padlock_keyhole), FALSE,
- FALSE, 0);
- vbox = gtk_vbox_new(FALSE, 12);
- gtk_container_add(GTK_CONTAINER(hbox), vbox);
- if (prev_was_bad)
- prompt =
- g_strdup_printf(_
- ("The passphrase for this key was bad, please try again!\n\nKey: %s"),
- uid_hint);
- else
- prompt =
- g_strdup_printf(_
- ("Please enter the passphrase for the secret key!\n\nKey: %s"),
- uid_hint);
- gtk_container_add(GTK_CONTAINER(vbox), gtk_label_new(prompt));
- g_free(prompt);
- entry = gtk_entry_new();
- gtk_container_add(GTK_CONTAINER(vbox), entry);
-
- gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
- gtk_entry_set_width_chars(GTK_ENTRY(entry), 40);
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
-
- gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- gtk_widget_grab_focus(entry);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
- passwd = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
- else
- passwd = NULL;
-
- gtk_widget_destroy(dialog);
-
- return passwd;
-}
-
-
-#ifdef BALSA_USE_THREADS
-/* FIXME: is this really necessary? */
-typedef struct {
- pthread_cond_t cond;
- GMimeGpgmeContext *ctx;
- const gchar *desc;
- gint was_bad;
- gchar *res;
-} AskPassphraseData;
-
-/* get_passphrase_idle:
- called in MT mode by the main thread.
- */
-static gboolean
-get_passphrase_idle(gpointer data)
-{
- AskPassphraseData *apd = (AskPassphraseData *) data;
- gdk_threads_enter();
- apd->res = get_passphrase_real(apd->ctx, apd->desc, apd->was_bad);
- gdk_threads_leave();
- pthread_cond_signal(&apd->cond);
- return FALSE;
-}
-#endif
-
-
-/*
- * Helper function: overwrite a sting in memory with random data
- */
-static inline void
-wipe_string(gchar * password)
-{
- while (*password)
- *password++ = random();
-}
-
-
-/*
- * Called by gpgme to get the passphrase for a key.
- */
-static gpgme_error_t
-get_passphrase_cb(void *opaque, const char *uid_hint,
- const char *passph_info, int prev_was_bad, int fd)
-{
- GMimeGpgmeContext *context;
- gchar *passwd = NULL;
- int foo, bar;
-
- if (!opaque || !GMIME_IS_GPGME_CONTEXT(opaque)) {
- foo = write(fd, "\n", 1);
- return foo > 0 ? GPG_ERR_USER_1 : GPG_ERR_EIO;
- }
- context = GMIME_GPGME_CONTEXT(opaque);
-
-#ifdef ENABLE_PCACHE
- if (!pcache)
- pcache = init_pcache();
-
- /* check if we have the passphrase already cached... */
- if ((passwd = check_cache(pcache, uid_hint, prev_was_bad))) {
- foo = write(fd, passwd, strlen(passwd));
- bar = write(fd, "\n", 1);
- wipe_string(passwd);
- g_free(passwd);
- return foo > 0 && bar > 0 ? GPG_ERR_NO_ERROR : GPG_ERR_EIO;
- }
-#endif
-
-#ifdef BALSA_USE_THREADS
- if (!libbalsa_am_i_subthread())
-#ifdef ENABLE_PCACHE
- passwd =
- get_passphrase_real(context, uid_hint, prev_was_bad, pcache);
-
-#else
- passwd = get_passphrase_real(context, uid_hint, prev_was_bad);
-#endif
- else {
- static pthread_mutex_t get_passphrase_lock =
- PTHREAD_MUTEX_INITIALIZER;
- AskPassphraseData apd;
-
- pthread_mutex_lock(&get_passphrase_lock);
- pthread_cond_init(&apd.cond, NULL);
- apd.ctx = context;
- apd.desc = uid_hint;
- apd.was_bad = prev_was_bad;
- g_idle_add(get_passphrase_idle, &apd);
- pthread_cond_wait(&apd.cond, &get_passphrase_lock);
-
- pthread_cond_destroy(&apd.cond);
- pthread_mutex_unlock(&get_passphrase_lock);
- passwd = apd.res;
- }
-#else
- passwd = get_passphrase_real(context, uid_hint, prev_was_bad);
-#endif /* BALSA_USE_THREADS */
-
- if (!passwd) {
- foo = write(fd, "\n", 1);
- return foo > 0 ? GPG_ERR_CANCELED : GPG_ERR_EIO;
- }
-
- /* send the passphrase and erase the string */
- foo = write(fd, passwd, strlen(passwd));
- wipe_string(passwd);
- g_free(passwd);
- bar = write(fd, "\n", 1);
- return foo > 0 && bar > 0 ? GPG_ERR_NO_ERROR : GPG_ERR_EIO;
-}
-
-
/*
* return TRUE is gpg is currently updating the trust database (indicated by
* the file ~/.gnupg/trustdb.gpg.lock)
diff --git a/libbalsa/rfc3156.h b/libbalsa/rfc3156.h
index 4f4be8c..1331b33 100644
--- a/libbalsa/rfc3156.h
+++ b/libbalsa/rfc3156.h
@@ -37,7 +37,7 @@
#include <gpgme.h>
#include "libbalsa.h"
#include "misc.h"
-#include "gmime-gpgme-context.h"
+#include "gmime-gpgme-signature.h"
/* bits to define the protection mode: signed or encrypted */
@@ -60,8 +60,6 @@
#define GPG_ERR_NOT_SIGNED GPG_ERR_USER_16
-gboolean libbalsa_check_crypto_engine(gpgme_protocol_t protocol);
-
gint libbalsa_message_body_protection(LibBalsaMessageBody * body);
gboolean libbalsa_can_encrypt_for_all(InternetAddressList * recipients,
gpgme_protocol_t protocol);
@@ -108,6 +106,7 @@ gpgme_error_t libbalsa_rfc2440_decrypt(GMimePart * part,
const gchar *libbalsa_gpgme_sig_protocol_name(gpgme_protocol_t protocol);
const gchar *libbalsa_gpgme_sig_stat_to_gchar(gpgme_error_t stat);
const gchar *libbalsa_gpgme_validity_to_gchar(gpgme_validity_t validity);
+const gchar *libbalsa_gpgme_validity_to_gchar_short(gpgme_validity_t validity);
gchar *libbalsa_signature_info_to_gchar(GMimeGpgmeSigstat * info,
const gchar * date_string);
diff --git a/src/balsa-message.c b/src/balsa-message.c
index f5eb7ae..fff4677 100644
--- a/src/balsa-message.c
+++ b/src/balsa-message.c
@@ -3090,7 +3090,7 @@ libbalsa_msg_part_2440(LibBalsaMessage * message, LibBalsaMessageBody * body,
if (sig_res == GPG_ERR_NO_ERROR) {
if (body->sig_info->validity >= GPGME_VALIDITY_MARGINAL &&
- body->sig_info->trust >= GPGME_VALIDITY_MARGINAL)
+ body->sig_info->key->owner_trust >= GPGME_VALIDITY_MARGINAL)
libbalsa_information(LIBBALSA_INFORMATION_DEBUG,
_("Detected a good signature"));
else
diff --git a/src/main.c b/src/main.c
index 7536c7c..95a3418 100644
--- a/src/main.c
+++ b/src/main.c
@@ -78,8 +78,8 @@
#endif /* HAVE_UNIQUE */
#ifdef HAVE_GPGME
-#include <string.h>
-#include <gpgme.h>
+#include "libbalsa-gpgme.h"
+#include "libbalsa-gpgme-cb.h"
#endif
#ifdef BALSA_USE_THREADS
@@ -943,26 +943,6 @@ balsa_progress_set_activity(gboolean set, const gchar * text)
gdk_threads_leave();
}
-#if defined(ENABLE_NLS) && defined(HAVE_GPGME)
-static const gchar *
-get_utf8_locale(int category)
-{
- gchar * locale;
- static gchar localebuf[64]; /* should be large enough */
- gchar * dot;
-
- if (!(locale = setlocale(category, NULL)))
- return NULL;
- strncpy(localebuf, locale, 57);
- localebuf[57] = '\0';
- dot = strchr(localebuf, '.');
- if (!dot)
- dot = localebuf + strlen(localebuf);
- strcpy(dot, ".UTF-8");
- return localebuf;
-}
-#endif
-
/* -------------------------- main --------------------------------- */
int
main(int argc, char *argv[])
@@ -1035,27 +1015,9 @@ main(int argc, char *argv[])
#endif /* HAVE_UNIQUE */
#ifdef HAVE_GPGME
- /* initialise the gpgme library */
- g_message("init gpgme version %s", gpgme_check_version(NULL));
-#ifdef HAVE_GPG
- /* configure the GnuPG engine if a specific gpg path has been detected*/
- gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, GPG_PATH, NULL);
-#endif
-#ifdef ENABLE_NLS
- gpgme_set_locale(NULL, LC_CTYPE, get_utf8_locale(LC_CTYPE));
- gpgme_set_locale(NULL, LC_MESSAGES, get_utf8_locale(LC_MESSAGES));
-#endif /* ENABLE_NLS */
- { /* scope */
- gpgme_engine_info_t e;
-
- if (gpgme_get_engine_info(&e) == GPG_ERR_NO_ERROR)
- while (e) {
- g_message("protocol %s: engine %s (home %s, version %s)",
- gpgme_get_protocol_name(e->protocol),
- e->file_name, e->home_dir, e->version);
- e = e->next;
- }
- }
+ /* initialise the gpgme library and set the callback funcs */
+ libbalsa_gpgme_init(lb_gpgme_passphrase, lb_gpgme_select_key,
+ lb_gpgme_accept_low_trust_key);
#endif
#ifdef GTKHTML_HAVE_GCONF
@@ -1137,13 +1099,9 @@ main(int argc, char *argv[])
#ifdef HAVE_GPGME
balsa_app.has_openpgp =
- libbalsa_check_crypto_engine(GPGME_PROTOCOL_OpenPGP);
-#ifdef HAVE_SMIME
+ libbalsa_gpgme_check_crypto_engine(GPGME_PROTOCOL_OpenPGP);
balsa_app.has_smime =
- libbalsa_check_crypto_engine(GPGME_PROTOCOL_CMS);
-#else
- balsa_app.has_smime = FALSE;
-#endif /* HAVE_SMIME */
+ libbalsa_gpgme_check_crypto_engine(GPGME_PROTOCOL_CMS);
#endif /* HAVE_GPGME */
if (opt_compose_email || opt_attach_list) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]