When signing mail Evolution forces base64 or quoted-printable for the
purpose of reducing the likelyhood of mail gateways modifying the body
and making the signature unverifiable.
However, this causes serious problems when the mail has to be read by
programs that do not understand these encodings (such as Linus Torvalds'
patch scripts).
Furthermore, if mail is sent directly rather than through an ISP
smarthost (and the MTA on localhost isn't broken), mail can only
corrupted by the recipient (that presumably is capable of correctly
configuring a mail server).
This patch adds a couple of options to allow non-base64/quoted-printable
encodings in GnuPG signed mail and in S/MIME signed mail.
If you consider my implementation unacceptable, please still consider
the feature request and provide an alternate implementation.
The S/MIME part is untested.
diff -urdp /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-gpg-context.c evolution/camel/camel-gpg-context.c
--- /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-gpg-context.c 2002-10-28 15:43:06.000000000 +0100
+++ evolution/camel/camel-gpg-context.c 2002-11-18 23:39:45.000000000 +0100
@@ -109,6 +109,7 @@ camel_gpg_context_init (CamelGpgContext
CamelCipherContext *cipher = (CamelCipherContext *) context;
context->always_trust = FALSE;
+ context->allow_non_base64qp = FALSE;
cipher->sign_protocol = "application/pgp-signature";
cipher->encrypt_protocol = "application/pgp-encrypted";
@@ -163,6 +164,14 @@ camel_gpg_context_set_always_trust (Came
ctx->always_trust = always_trust;
}
+void
+camel_gpg_context_set_allow_non_base64qp (CamelGpgContext *ctx, gboolean allow_non_base64qp)
+{
+ g_return_if_fail (CAMEL_IS_GPG_CONTEXT (ctx));
+
+ ctx->allow_non_base64qp = allow_non_base64qp;
+}
+
static const char *
gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
diff -urdp /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-gpg-context.h evolution/camel/camel-gpg-context.h
--- /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-gpg-context.h 2002-10-21 17:14:42.000000000 +0200
+++ evolution/camel/camel-gpg-context.h 2002-11-19 01:14:38.000000000 +0100
@@ -43,6 +43,7 @@ struct _CamelGpgContext {
CamelCipherContext parent_object;
gboolean always_trust;
+ gboolean allow_non_base64qp;
};
struct _CamelGpgContextClass {
@@ -56,6 +57,7 @@ CamelType camel_gpg_context_get_type (vo
CamelCipherContext *camel_gpg_context_new (CamelSession *session);
void camel_gpg_context_set_always_trust (CamelGpgContext *ctx, gboolean trust);
+void camel_gpg_context_set_allow_non_base64qp (CamelGpgContext *ctx, gboolean allow_non_base64qp);
#ifdef __cplusplus
}
diff -urdp /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-multipart-signed.c evolution/camel/camel-multipart-signed.c
--- /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-multipart-signed.c 2002-06-18 20:34:52.000000000 +0200
+++ evolution/camel/camel-multipart-signed.c 2002-11-19 00:40:30.000000000 +0100
@@ -47,6 +47,8 @@
#include "camel-mime-filter-crlf.h"
#include "camel-mime-filter-canon.h"
+#include "camel-gpg-context.h"
+
#define d(x)
static void signed_add_part(CamelMultipart *multipart, CamelMimePart *part);
@@ -521,7 +523,7 @@ write_to_stream (CamelDataWrapper *data_
This is so that we can safely translate any occurance of "From "
into the quoted-printable escaped version safely. */
static void
-prepare_sign(CamelMimePart *mime_part)
+prepare_sign(CamelMimePart *mime_part, gboolean allow_non_base64qp)
{
CamelDataWrapper *wrapper;
CamelMimePartEncodingType encoding;
@@ -534,13 +536,14 @@ prepare_sign(CamelMimePart *mime_part)
if (CAMEL_IS_MULTIPART (wrapper)) {
parts = camel_multipart_get_number((CamelMultipart *)wrapper);
for (i = 0; i < parts; i++)
- prepare_sign(camel_multipart_get_part((CamelMultipart *)wrapper, i));
+ prepare_sign(camel_multipart_get_part((CamelMultipart *)wrapper, i), allow_non_base64qp);
} else if (CAMEL_IS_MIME_MESSAGE (wrapper)) {
- prepare_sign((CamelMimePart *)wrapper);
+ prepare_sign((CamelMimePart *)wrapper, allow_non_base64qp);
} else {
encoding = camel_mime_part_get_encoding(mime_part);
- if (encoding != CAMEL_MIME_PART_ENCODING_BASE64
+ if (!allow_non_base64qp
+ && encoding != CAMEL_MIME_PART_ENCODING_BASE64
&& encoding != CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE) {
camel_mime_part_set_encoding(mime_part, CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE);
}
@@ -582,7 +585,7 @@ camel_multipart_signed_sign(CamelMultipa
/* this needs to be set */
g_return_val_if_fail(context->sign_protocol != NULL, -1);
- prepare_sign(content);
+ prepare_sign(content, CAMEL_IS_GPG_CONTEXT(context) ? CAMEL_GPG_CONTEXT(context)->allow_non_base64qp : FALSE);
mem = camel_stream_mem_new();
filter = camel_stream_filter_new_with_stream(mem);
diff -urdp /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-smime-context.c evolution/camel/camel-smime-context.c
--- /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-smime-context.c 2002-05-31 23:02:44.000000000 +0200
+++ evolution/camel/camel-smime-context.c 2002-11-19 00:42:33.000000000 +0100
@@ -133,7 +133,7 @@ camel_smime_context_get_type (void)
* Return value: the new CamelSMimeContext
**/
CamelSMimeContext *
-camel_smime_context_new (CamelSession *session, const char *encryption_key)
+camel_smime_context_new (CamelSession *session, const char *encryption_key, gboolean allow_non_base64qp)
{
CamelSMimeContext *context;
CERTCertDBHandle *certdb;
@@ -151,6 +151,7 @@ camel_smime_context_new (CamelSession *s
context->encryption_key = g_strdup (encryption_key);
context->priv->certdb = certdb;
+ context->allow_non_base64qp = allow_non_base64qp;
return context;
}
@@ -305,7 +306,7 @@ smime_sign_restore (CamelMimePart *mime_
}
static void
-smime_sign_prepare (CamelMimePart *mime_part, GSList **encodings)
+smime_sign_prepare (CamelMimePart *mime_part, GSList **encodings, gboolean allow_non_base64qp)
{
CamelDataWrapper *wrapper;
int parts, i;
@@ -319,20 +320,21 @@ smime_sign_prepare (CamelMimePart *mime_
for (i = 0; i < parts; i++) {
CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (wrapper), i);
- smime_sign_prepare (part, encodings);
+ smime_sign_prepare (part, encodings, allow_non_base64qp);
}
} else {
CamelMimePartEncodingType encoding;
if (CAMEL_IS_MIME_MESSAGE (wrapper)) {
/* prepare the message parts' subparts */
- smime_sign_prepare (CAMEL_MIME_PART (wrapper), encodings);
+ smime_sign_prepare (CAMEL_MIME_PART (wrapper), encodings, allow_non_base64qp);
} else {
encoding = camel_mime_part_get_encoding (mime_part);
/* FIXME: find the best encoding for this part and use that instead?? */
/* the encoding should really be QP or Base64 */
- if (encoding != CAMEL_MIME_PART_ENCODING_BASE64)
+
+ if (!allow_non_base64qp && (encoding != CAMEL_MIME_PART_ENCODING_BASE64))
camel_mime_part_set_encoding (mime_part, CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE);
*encodings = g_slist_append (*encodings, GINT_TO_POINTER (encoding));
@@ -371,7 +373,7 @@ smime_sign (CamelCMSContext *ctx, CamelM
stream = camel_stream_mem_new ();
- smime_sign_prepare (CAMEL_MIME_PART (message), &encodings);
+ smime_sign_prepare (CAMEL_MIME_PART (message), &encodings, CAMEL_SMIME_CONTEXT (ctx)->allow_non_base64qp);
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream);
list = encodings;
smime_sign_restore (CAMEL_MIME_PART (message), &list);
diff -urdp /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-smime-context.h evolution/camel/camel-smime-context.h
--- /usr/src/evolution-1.2.0/build-tree/evolution/camel/camel-smime-context.h 2001-11-03 01:26:20.000000000 +0100
+++ evolution/camel/camel-smime-context.h 2002-11-19 00:42:07.000000000 +0100
@@ -43,6 +43,8 @@ typedef struct _CamelSMimeContext {
struct _CamelSMimeContextPrivate *priv;
char *encryption_key;
+
+ gboolean allow_non_base64qp;
} CamelSMimeContext;
typedef struct _CamelSMimeContextClass {
@@ -53,7 +55,7 @@ typedef struct _CamelSMimeContextClass {
CamelType camel_smime_context_get_type (void);