[evolution-patches] Mailer bug #127521: Inline PGP support for evolution (sign and signature verification)
- From: Bohumir Jelinek <bj48 ra msstate edu>
- To: Evolution Patches <evolution-patches ximian com>
- Subject: [evolution-patches] Mailer bug #127521: Inline PGP support for evolution (sign and signature verification)
- Date: Tue, 3 Feb 2004 02:28:29 -0600 (CST)
This patch implements:
A) cleartext signing
B) verification of cleartext signed messages
The code is below, or at:
http://bugzilla.gnome.org/showattachment.cgi?attach_id=24012
Note:
There are no ChangeLogs yet. I will add them when I receive comments.
-Bohumir
Index: camel/camel-cipher-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-cipher-context.c,v
retrieving revision 1.17
diff -u -r1.17 camel-cipher-context.c
--- camel/camel-cipher-context.c 10 Dec 2003 05:25:24 -0000 1.17
+++ camel/camel-cipher-context.c 3 Feb 2004 08:02:39 -0000
@@ -650,3 +650,37 @@
return res;
}
+
+/**
+ * camel_cipher_data_wrapper_to_canon_stream
+ * @dw: data wrapper to write.
+ * @flags: flags for the canonicalisation filter (CamelMimeFilterCanon)
+ * @ostream: stream to write canonicalised output to.
+ *
+ * Writes a dw to a stream in a canonicalised format, suitable for signing/encrypting.
+ *
+ * Return value: -1 on error;
+ **/
+int
+camel_cipher_data_wrapper_to_canon_stream (CamelDataWrapper *dw, guint32 flags, CamelStream *ostream)
+{
+ CamelStreamFilter *filter;
+ CamelMimeFilter *canon;
+ int res = -1;
+
+ filter = camel_stream_filter_new_with_stream (ostream);
+
+ canon = camel_mime_filter_canon_new (flags);
+ camel_stream_filter_add (filter, canon);
+ camel_object_unref (canon);
+
+ if (camel_data_wrapper_write_to_stream (dw, (CamelStream *)filter) != -1
+ && camel_stream_flush ((CamelStream *)filter) != -1)
+ res = 0;
+
+ camel_object_unref (filter);
+
+ camel_stream_reset (ostream);
+
+ return res;
+}
Index: camel/camel-cipher-context.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-cipher-context.h,v
retrieving revision 1.15
diff -u -r1.15 camel-cipher-context.h
--- camel/camel-cipher-context.h 10 Dec 2003 05:25:24 -0000 1.15
+++ camel/camel-cipher-context.h 3 Feb 2004 08:02:39 -0000
@@ -183,6 +183,7 @@
/* utility functions */
int camel_cipher_canonical_to_stream(CamelMimePart *part, guint32 flags, CamelStream *ostream);
+int camel_cipher_data_wrapper_to_canon_stream (CamelDataWrapper *dw, guint32 flags, CamelStream *ostream);
#ifdef __cplusplus
}
Index: camel/camel-gpg-context.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-gpg-context.c,v
retrieving revision 1.47
diff -u -r1.47 camel-gpg-context.c
--- camel/camel-gpg-context.c 20 Jan 2004 05:32:54 -0000 1.47
+++ camel/camel-gpg-context.c 3 Feb 2004 08:02:39 -0000
@@ -148,7 +148,9 @@
enum _GpgCtxMode {
GPG_CTX_MODE_SIGN,
+ GPG_CTX_MODE_CLEARSIGN,
GPG_CTX_MODE_VERIFY,
+ GPG_CTX_MODE_CLEARVERIFY,
GPG_CTX_MODE_ENCRYPT,
GPG_CTX_MODE_DECRYPT,
GPG_CTX_MODE_IMPORT,
@@ -296,7 +298,7 @@
gpg_ctx_set_mode (struct _GpgCtx *gpg, enum _GpgCtxMode mode)
{
gpg->mode = mode;
- gpg->need_passwd = ((gpg->mode == GPG_CTX_MODE_SIGN) || (gpg->mode == GPG_CTX_MODE_DECRYPT));
+ gpg->need_passwd = ((gpg->mode == GPG_CTX_MODE_SIGN) || (gpg->mode == GPG_CTX_MODE_DECRYPT) || (gpg->mode == GPG_CTX_MODE_CLEARSIGN));
}
static void
@@ -503,6 +505,18 @@
g_ptr_array_add (argv, "--output");
g_ptr_array_add (argv, "-");
break;
+ case GPG_CTX_MODE_CLEARSIGN:
+ g_ptr_array_add (argv, "--clearsign");
+ hash_str = gpg_hash_str (gpg->hash);
+ if (hash_str)
+ g_ptr_array_add (argv, (char *) hash_str);
+ if (gpg->userid) {
+ g_ptr_array_add (argv, "-u");
+ g_ptr_array_add (argv, (char *) gpg->userid);
+ }
+ g_ptr_array_add (argv, "--output");
+ g_ptr_array_add (argv, "-");
+ break;
case GPG_CTX_MODE_VERIFY:
if (!camel_session_is_online (gpg->session)) {
/* this is a deprecated flag to gpg since 1.0.7 */
@@ -515,6 +529,18 @@
g_ptr_array_add (argv, gpg->sigfile);
g_ptr_array_add (argv, "-");
break;
+ case GPG_CTX_MODE_CLEARVERIFY:
+ if (!camel_session_is_online (gpg->session)) {
+ /* this is a deprecated flag to gpg since 1.0.7 */
+ /*g_ptr_array_add (argv, "--no-auto-key-retrieve");*/
+ g_ptr_array_add (argv, "--keyserver-options");
+ g_ptr_array_add (argv, "no-auto-key-retrieve");
+ }
+ g_ptr_array_add (argv, "--verify");
+ if (gpg->sigfile)
+ g_ptr_array_add (argv, gpg->sigfile);
+ g_ptr_array_add (argv, "-");
+ break;
case GPG_CTX_MODE_ENCRYPT:
g_ptr_array_add (argv, "--encrypt");
if (gpg->armor)
@@ -821,6 +847,11 @@
/* FIXME: save this state? */
}
break;
+ case GPG_CTX_MODE_CLEARSIGN:
+ if (!strncmp (status, "SIG_CREATED ", 12)) {
+ /* FIXME: save this state? */
+ }
+ break;
case GPG_CTX_MODE_VERIFY:
if (!strncmp (status, "TRUST_", 6)) {
status += 6;
@@ -842,6 +873,27 @@
gpg->validsig = FALSE;
}
break;
+ case GPG_CTX_MODE_CLEARVERIFY:
+ if (!strncmp (status, "TRUST_", 6)) {
+ status += 6;
+ if (!strncmp (status, "NEVER", 5)) {
+ gpg->trust = GPG_TRUST_NEVER;
+ } else if (!strncmp (status, "MARGINAL", 8)) {
+ gpg->trust = GPG_TRUST_MARGINAL;
+ } else if (!strncmp (status, "FULLY", 5)) {
+ gpg->trust = GPG_TRUST_FULLY;
+ } else if (!strncmp (status, "ULTIMATE", 8)) {
+ gpg->trust = GPG_TRUST_ULTIMATE;
+ }
+ } else if (!strncmp (status, "VALIDSIG", 8)) {
+ gpg->validsig = TRUE;
+ } else if (!strncmp (status, "BADSIG", 6)) {
+ gpg->validsig = FALSE;
+ } else if (!strncmp (status, "ERRSIG", 6)) {
+ /* Note: NO_PUBKEY often comes after an ERRSIG, but do we really care? */
+ gpg->validsig = FALSE;
+ }
+ break;
case GPG_CTX_MODE_ENCRYPT:
if (!strncmp (status, "BEGIN_ENCRYPTION", 16)) {
/* nothing to do... but we know to expect data on stdout soon */
@@ -1102,9 +1154,15 @@
case GPG_CTX_MODE_SIGN:
mode = "sign";
break;
+ case GPG_CTX_MODE_CLEARSIGN:
+ mode = "clearsign";
+ break;
case GPG_CTX_MODE_VERIFY:
mode = "verify";
break;
+ case GPG_CTX_MODE_CLEARVERIFY:
+ mode = "clearverify";
+ break;
case GPG_CTX_MODE_ENCRYPT:
mode = "encrypt";
break;
@@ -1464,6 +1522,80 @@
return NULL;
}
+CamelCipherValidity *
+camel_gpg_context_clearverify (CamelCipherContext *context, CamelMimePart *ipart, CamelException *ex)
+{
+ CamelCipherValidity *validity;
+ const char *diagnostics = NULL, *tmp;
+ struct _GpgCtx *gpg = NULL;
+ gboolean valid;
+ CamelContentType *ct;
+ CamelStream *istream = NULL;
+
+ if (ipart == NULL) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot verify message signature: Incorrect message format"));
+ goto exception;
+ }
+
+ ct = camel_mime_part_get_content_type(ipart);
+ tmp = camel_content_type_param(ct, "protocol");
+ if (!camel_content_type_is(ct, "application", "x-inline-pgp-signed")) {
+ /* || g_ascii_strcasecmp(tmp, context->sign_protocol) != 0) {*/
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot verify message signature: Incorrect message format"));
+ return NULL;
+ }
+
+ istream = camel_stream_mem_new();
+ camel_cipher_canonical_to_stream(ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream);
+ camel_stream_reset(istream);
+
+ gpg = gpg_ctx_new (context->session);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_CLEARVERIFY);
+ gpg_ctx_set_hash (gpg, camel_cipher_id_to_hash(context, camel_content_type_param(ct, "Hash")));
+ gpg_ctx_set_istream (gpg, istream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg."));
+ gpg_ctx_free (gpg);
+ goto exception;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ goto exception;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ goto exception;
+ }
+ }
+
+ valid = gpg_ctx_op_wait (gpg) == 0;
+ validity = camel_cipher_validity_new ();
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_cipher_validity_set_valid (validity, valid);
+ camel_cipher_validity_set_description (validity, diagnostics);
+ gpg_ctx_free (gpg);
+
+ return validity;
+
+ exception:
+
+ gpg_ctx_free (gpg);
+
+ if (istream)
+ camel_object_unref(istream);
+
+ return NULL;
+}
+
static int
gpg_encrypt (CamelCipherContext *context, const char *userid, GPtrArray *recipients, struct _CamelMimePart *ipart, struct _CamelMimePart *opart, CamelException *ex)
{
@@ -1747,6 +1879,95 @@
/* ********************************************************************** */
+/**
+ * camel_gpg_context_clearsign:
+ * @context: gpg context
+ * @userid: user id
+ * @hash: hash algorithm
+ * @plain: input plain text message
+ * @current: output plain text message with clear text signature added
+ * @ex: exception status
+ *
+ * Sets the @always_trust flag on the gpg context which is used for
+ * encryption.
+ **/
+int
+camel_gpg_context_clearsign (CamelCipherContext *context, const char *userid, CamelCipherHash hash, CamelDataWrapper *plain, CamelDataWrapper *current, CamelException *ex)
+{
+ struct _GpgCtx *gpg = NULL;
+ CamelStream *istream, *ostream;
+ CamelContentType *ct;
+ int res = -1;
+
+ /* Note: see rfc2440, section 7 */
+
+ istream = camel_stream_mem_new ();
+ ostream = camel_stream_mem_new ();
+ if (camel_cipher_data_wrapper_to_canon_stream (plain, CAMEL_MIME_FILTER_CANON_STRIP|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_FROM,
+ istream) == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Could not generate signing data: %s"), g_strerror(errno));
+ goto fail;
+ }
+
+ gpg = gpg_ctx_new (context->session);
+ gpg_ctx_set_mode (gpg, GPG_CTX_MODE_CLEARSIGN);
+ gpg_ctx_set_hash (gpg, hash);
+ gpg_ctx_set_userid (gpg, userid);
+ gpg_ctx_set_istream (gpg, istream);
+ gpg_ctx_set_ostream (gpg, ostream);
+
+ if (gpg_ctx_op_start (gpg) == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to execute gpg: %s"), g_strerror (errno));
+ goto fail;
+ }
+
+ while (!gpg_ctx_op_complete (gpg)) {
+ if (camel_operation_cancel_check (NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+ _("Cancelled."));
+ gpg_ctx_op_cancel (gpg);
+ goto fail;
+ }
+
+ if (gpg_ctx_op_step (gpg, ex) == -1) {
+ gpg_ctx_op_cancel (gpg);
+ goto fail;
+ }
+ }
+
+ if (gpg_ctx_op_wait (gpg) != 0) {
+ const char *diagnostics;
+
+ diagnostics = gpg_ctx_get_diagnostics (gpg);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
+ diagnostics && *diagnostics ? diagnostics :
+ _("Failed to execute gpg."));
+ goto fail;
+ }
+
+ res = 0;
+
+ camel_stream_reset (ostream);
+ camel_data_wrapper_construct_from_stream (current, ostream);
+
+ ct = camel_content_type_new ("text", "plain");
+ camel_content_type_set_param (ct, "x-action", "pgp-signed");
+ camel_content_type_set_param (ct, "format", "text");
+ camel_data_wrapper_set_mime_type_field (current, ct);
+ camel_content_type_unref (ct);
+
+fail:
+ camel_object_unref (ostream);
+ if (gpg)
+ gpg_ctx_free (gpg);
+
+ return res;
+}
+
+/* ********************************************************************** */
+
static void
camel_gpg_context_class_init (CamelGpgContextClass *klass)
{
Index: camel/camel-gpg-context.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-gpg-context.h,v
retrieving revision 1.4
diff -u -r1.4 camel-gpg-context.h
--- camel/camel-gpg-context.h 1 Nov 2002 00:45:05 -0000 1.4
+++ camel/camel-gpg-context.h 3 Feb 2004 08:02:39 -0000
@@ -57,6 +57,11 @@
void camel_gpg_context_set_always_trust (CamelGpgContext *ctx, gboolean trust);
+int camel_gpg_context_clearsign (CamelCipherContext *context, const char *userid, CamelCipherHash hash, CamelDataWrapper *plain, CamelDataWrapper *current, CamelException *ex);
+
+CamelCipherValidity *
+camel_gpg_context_clearverify (CamelCipherContext *context, CamelMimePart *ipart, CamelException *ex);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Index: composer/e-msg-composer.c
===================================================================
RCS file: /cvs/gnome/evolution/composer/e-msg-composer.c,v
retrieving revision 1.435
diff -u -r1.435 e-msg-composer.c
--- composer/e-msg-composer.c 2 Feb 2004 05:05:05 -0000 1.435
+++ composer/e-msg-composer.c 3 Feb 2004 08:02:39 -0000
@@ -371,10 +371,11 @@
CamelMimeMessage *new;
const char *charset = NULL;
CamelStream *stream;
- CamelMimePart *part;
+ CamelMimePart *part = NULL;
CamelException ex;
GByteArray *data;
int i;
+ gboolean clearsign_applied = FALSE;
if (composer->persist_stream_interface == CORBA_OBJECT_NIL)
return NULL;
@@ -579,12 +580,7 @@
const char *pgp_userid;
CamelInternetAddress *from = NULL;
CamelCipherContext *cipher;
-
- part = camel_mime_part_new ();
- camel_medium_set_content_object (CAMEL_MEDIUM (part), current);
- if (current == plain)
- camel_mime_part_set_encoding (part, plain_encoding);
- camel_object_unref (current);
+ gboolean mimesign = FALSE;
if (hdrs->account && hdrs->account->pgp_key && *hdrs->account->pgp_key) {
pgp_userid = hdrs->account->pgp_key;
@@ -593,23 +589,68 @@
camel_internet_address_get(from, 0, NULL, &pgp_userid);
}
- if (composer->pgp_sign) {
- CamelMimePart *npart = camel_mime_part_new();
+ if (composer->pgp_sign && hdrs->account->pgp_clearsign) {
- cipher = mail_crypto_get_pgp_cipher_context(hdrs->account);
- camel_cipher_sign(cipher, pgp_userid, CAMEL_CIPHER_HASH_SHA1, part, npart, &ex);
- camel_object_unref(cipher);
-
- if (camel_exception_is_set(&ex)) {
- camel_object_unref(npart);
+ if ((current == plain) && !composer->pgp_encrypt) {
+ /* do clearsign */
+ current = camel_data_wrapper_new ();
+
+ cipher = mail_crypto_get_pgp_cipher_context (hdrs->account);
+ camel_gpg_context_clearsign (cipher, pgp_userid, CAMEL_CIPHER_HASH_SHA1, plain, current, &ex);
+ clearsign_applied = TRUE;
+ camel_object_unref (cipher);
+
+ if (camel_exception_is_set (&ex)) {
+ camel_object_unref (current);
+ goto exception;
+ }
+ }
+ else {
+ /* offer mimesign */
+ mimesign = em_utils_prompt_user ((GtkWindow *) composer, GTK_RESPONSE_YES, NULL,
+ _("PGP clearsign can only be used for plain text message without encryption.\nUse MIME signature instead?\n"));
+ }
+ }
+
+ mimesign = mimesign || (composer->pgp_sign && !hdrs->account->pgp_clearsign);
+
+ if (mimesign) {
+ /* do mimesign */
+ part = camel_mime_part_new ();
+
+ camel_medium_set_content_object (CAMEL_MEDIUM (part), current);
+ camel_object_unref (current);
+
+ CamelMimePart *npart = camel_mime_part_new ();
+
+ cipher = mail_crypto_get_pgp_cipher_context (hdrs->account);
+ camel_cipher_sign (cipher, pgp_userid, CAMEL_CIPHER_HASH_SHA1, part, npart, &ex);
+ camel_object_unref (cipher);
+
+ if (camel_exception_is_set (&ex)) {
+ camel_object_unref (npart);
goto exception;
}
camel_object_unref(part);
part = npart;
+
+ current = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+ camel_object_ref (current);
+
+ if (!composer->pgp_encrypt)
+ camel_object_unref (part);
}
if (composer->pgp_encrypt) {
+ /* if mimesign was done, we will encrypt "part" created there,
+ * otherwise we need to create a new "part" from "current" */
+ if (!mimesign) {
+ part = camel_mime_part_new ();
+ camel_medium_set_content_object (CAMEL_MEDIUM (part), current);
+ camel_object_unref (current);
+ }
+
CamelMimePart *npart = camel_mime_part_new();
/* check to see if we should encrypt to self, NB gets removed immediately after use */
@@ -630,14 +671,16 @@
camel_object_unref (part);
part = npart;
+
+ current = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+ camel_object_ref (current);
+
+ camel_object_unref (part);
}
if (from)
camel_object_unref (from);
- current = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- camel_object_ref (current);
- camel_object_unref (part);
}
#if defined (HAVE_NSS) && defined (SMIME_SUPPORTED)
@@ -722,7 +765,7 @@
#endif /* HAVE_NSS */
camel_medium_set_content_object (CAMEL_MEDIUM (new), current);
- if (current == plain)
+ if ((current == plain) || clearsign_applied)
camel_mime_part_set_encoding (CAMEL_MIME_PART (new), plain_encoding);
camel_object_unref (current);
@@ -742,7 +785,7 @@
exception:
- if (part != CAMEL_MIME_PART (new))
+ if ((part != CAMEL_MIME_PART (new)) && (part != NULL))
camel_object_unref (part);
camel_object_unref (new);
Index: e-util/e-account.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-account.c,v
retrieving revision 1.6
diff -u -r1.6 e-account.c
--- e-util/e-account.c 14 Jan 2004 17:29:24 -0000 1.6
+++ e-util/e-account.c 3 Feb 2004 08:02:39 -0000
@@ -329,6 +329,7 @@
changed |= xml_set_bool (node, "encrypt-to-self", &account->pgp_encrypt_to_self);
changed |= xml_set_bool (node, "always-trust", &account->pgp_always_trust);
changed |= xml_set_bool (node, "always-sign", &account->pgp_always_sign);
+ changed |= xml_set_bool (node, "clearsign", &account->pgp_clearsign);
changed |= xml_set_bool (node, "no-imip-sign", &account->pgp_no_imip_sign);
if (node->children) {
@@ -418,6 +419,7 @@
dest->pgp_key = g_strdup (src->pgp_key);
dest->pgp_encrypt_to_self = src->pgp_encrypt_to_self;
dest->pgp_always_sign = src->pgp_always_sign;
+ dest->pgp_clearsign = src->pgp_clearsign;
dest->pgp_no_imip_sign = src->pgp_no_imip_sign;
dest->pgp_always_trust = src->pgp_always_trust;
@@ -503,6 +505,7 @@
xmlSetProp (node, "encrypt-to-self", account->pgp_encrypt_to_self ? "true" : "false");
xmlSetProp (node, "always-trust", account->pgp_always_trust ? "true" : "false");
xmlSetProp (node, "always-sign", account->pgp_always_sign ? "true" : "false");
+ xmlSetProp (node, "clearsign", account->pgp_clearsign ? "true" : "false");
xmlSetProp (node, "no-imip-sign", account->pgp_no_imip_sign ? "true" : "false");
if (account->pgp_key)
xmlNewTextChild (node, NULL, "key-id", account->pgp_key);
Index: e-util/e-account.h
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-account.h,v
retrieving revision 1.4
diff -u -r1.4 e-account.h
--- e-util/e-account.h 31 Oct 2003 04:55:41 -0000 1.4
+++ e-util/e-account.h 3 Feb 2004 08:02:39 -0000
@@ -69,6 +69,7 @@
char *pgp_key;
gboolean pgp_encrypt_to_self;
gboolean pgp_always_sign;
+ gboolean pgp_clearsign;
gboolean pgp_no_imip_sign;
gboolean pgp_always_trust;
Index: mail/em-format-html-display.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html-display.c,v
retrieving revision 1.25
diff -u -r1.25 em-format-html-display.c
--- mail/em-format-html-display.c 30 Jan 2004 03:10:14 -0000 1.25
+++ mail/em-format-html-display.c 3 Feb 2004 08:02:40 -0000
@@ -843,8 +843,16 @@
static void
efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
- /* Note: We call EMFormatClass directly, not EMFormatHTML, our parent */
- efhd_format_class->format_secure(emf, stream, part, valid);
+ CamelContentType *type;
+
+ type = camel_mime_part_get_content_type(part);
+ if (!camel_content_type_is (type, "application", "x-inline-pgp-signed")) {
+ /* Note: We call EMFormatClass directly, not EMFormatHTML, our parent */
+ efhd_format_class->format_secure(emf, stream, part, valid);
+ }
+ else {
+ emf->valid = valid;
+ }
if (emf->valid == valid
&& (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
Index: mail/em-format-html.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html.c,v
retrieving revision 1.31
diff -u -r1.31 em-format-html.c
--- mail/em-format-html.c 30 Jan 2004 03:10:14 -0000 1.31
+++ mail/em-format-html.c 3 Feb 2004 08:02:40 -0000
@@ -579,7 +579,27 @@
static void
efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
- efh_parent->format_secure(emf, stream, part, valid);
+ CamelContentType *type;
+ type = camel_mime_part_get_content_type(part);
+ if (camel_content_type_is (type, "application", "x-inline-pgp-signed")) {
+
+ CamelStreamFilter *filtered_stream;
+ CamelMimeFilter *html_filter;
+ guint32 rgb = 0x737373, flags;
+
+ filtered_stream = camel_stream_filter_new_with_stream(stream);
+
+ flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ html_filter = camel_mime_filter_tohtml_new(flags, rgb);
+ camel_stream_filter_add(filtered_stream, html_filter);
+ camel_object_unref(html_filter);
+
+ efh_parent->format_secure(emf, (CamelStream*) filtered_stream, part, valid);
+ }
+ else {
+ efh_parent->format_secure(emf, stream, part, valid);
+ }
/* To explain, if the validity is the same, then we are the
base validity and now have a combined sign/encrypt validity
@@ -701,6 +721,18 @@
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, camel_medium_get_content_object((CamelMedium *)newpart));
camel_stream_flush((CamelStream *)filtered_stream);
camel_stream_write_string(stream, "</tt>\n");
+ }
+ else if (camel_content_type_is (type, "application", "x-inline-pgp-signed")) {
+
+ /* first write as simple text */
+ camel_stream_write_string(stream, "<tt>\n");
+ em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, camel_medium_get_content_object((CamelMedium *)newpart));
+ camel_stream_flush((CamelStream *)filtered_stream);
+ camel_stream_write_string(stream, "</tt>\n");
+
+ /* then investigate validity and notify user */
+ em_format_part((EMFormat *)efh, stream, newpart);
+
} else {
g_string_append_printf(((EMFormat *)efh)->part_id, ".inline.%d", i);
em_format_part((EMFormat *)efh, stream, newpart);
Index: mail/em-format.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format.c,v
retrieving revision 1.23
diff -u -r1.23 em-format.c
--- mail/em-format.c 30 Jan 2004 03:10:14 -0000 1.23
+++ mail/em-format.c 3 Feb 2004 08:02:40 -0000
@@ -586,6 +586,7 @@
{
CamelCipherValidity *save = emf->valid_parent;
int len;
+ CamelContentType *type;
/* Note that this also requires support from higher up in the class chain
- validity needs to be cleared when you start output
@@ -600,10 +601,19 @@
emf->valid_parent = valid;
- len = emf->part_id->len;
- g_string_append_printf(emf->part_id, ".secured");
- em_format_part(emf, stream, part);
- g_string_truncate(emf->part_id, len);
+ type = camel_mime_part_get_content_type(part);
+ if (camel_content_type_is (type, "application", "x-inline-pgp-signed")) {
+ camel_stream_write_string(stream, "<tt>\n");
+ em_format_format_text(emf, stream, camel_medium_get_content_object((CamelMedium *)part));
+ camel_stream_flush((CamelStream *)stream);
+ camel_stream_write_string(stream, "</tt>\n");
+ }
+ else {
+ len = emf->part_id->len;
+ g_string_append_printf(emf->part_id, ".secured");
+ em_format_part(emf, stream, part);
+ g_string_truncate(emf->part_id, len);
+ }
emf->valid_parent = save;
}
@@ -813,6 +823,7 @@
return !(camel_content_type_is (dw->mime_type, "multipart", "*")
|| camel_content_type_is(dw->mime_type, "application", "x-pkcs7-mime")
|| camel_content_type_is(dw->mime_type, "application", "pkcs7-mime")
+ || camel_content_type_is(dw->mime_type, "application", "x-inline-pgp-signed")
|| (camel_content_type_is (dw->mime_type, "text", "*")
&& camel_mime_part_get_filename(part) == NULL));
}
@@ -1052,6 +1063,33 @@
}
#endif
+static void
+emf_inline_pgp_signed (EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
+{
+ CamelCipherContext *cipher = NULL;
+
+ cipher = camel_gpg_context_new(emf->session);
+
+ if (cipher == NULL) {
+ em_format_format_error(emf, stream, _("Unsupported signature format"));
+ em_format_part_as(emf, stream, part, NULL);
+ } else {
+ CamelException *ex = camel_exception_new();
+ CamelCipherValidity *valid;
+
+ valid = camel_gpg_context_clearverify(cipher, part, ex);
+ if (valid == NULL) {
+ em_format_format_error(emf, stream, ex->desc?ex->desc:_("Unknown error verifying signature"));
+ em_format_part_as(emf, stream, part, NULL);
+ } else {
+ em_format_format_secure(emf, stream, part, valid);
+ }
+
+ camel_exception_free(ex);
+ camel_object_unref(cipher);
+ }
+}
+
/* RFC 1740 */
static void
emf_multipart_appledouble(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
@@ -1350,6 +1388,7 @@
#ifdef HAVE_NSS
{ "application/x-pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime },
#endif
+ { "application/x-inline-pgp-signed", (EMFormatFunc)emf_inline_pgp_signed },
{ "multipart/alternative", emf_multipart_alternative },
{ "multipart/appledouble", emf_multipart_appledouble },
{ "multipart/encrypted", emf_multipart_encrypted },
Index: mail/em-inline-filter.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-inline-filter.c,v
retrieving revision 1.4
diff -u -r1.4 em-inline-filter.c
--- mail/em-inline-filter.c 9 Jan 2004 02:06:02 -0000 1.4
+++ mail/em-inline-filter.c 3 Feb 2004 08:02:40 -0000
@@ -110,7 +110,7 @@
{ "application/octet-stream", CAMEL_TRANSFER_ENCODING_UUENCODE, },
{ "application/mac-binhex40", CAMEL_TRANSFER_ENCODING_7BIT, },
{ "application/postscript", CAMEL_TRANSFER_ENCODING_7BIT, },
- { "text/plain", CAMEL_TRANSFER_ENCODING_7BIT, 1, },
+ { "application/x-inline-pgp-signed", CAMEL_TRANSFER_ENCODING_7BIT, },
};
static void
@@ -206,16 +206,11 @@
emif_add_part(emif, data_start, start-data_start);
data_start = start;
emif->state = EMIF_POSTSCRIPT;
-#if 0
-/* This should be hooked in once someone can work out how to handle it.
- Maybe we need a multipart_gpg_inline_signed or some crap, if it
- can't be converted to a real multipart/signed */
} else if (strncmp(start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) {
inptr[-1] = '\n';
emif_add_part(emif, data_start, start-data_start);
data_start = start;
emif->state = EMIF_PGPSIGNED;
-#endif
}
break;
case EMIF_UUENC:
@@ -243,7 +238,6 @@
}
break;
case EMIF_PGPSIGNED:
- /* This is currently a noop - it just turns it into a text part */
if (strcmp(start, "-----END PGP SIGNATURE-----") == 0) {
inptr[-1] = '\n';
emif_add_part(emif, data_start, inptr-data_start);
Index: mail/em-migrate.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-migrate.c,v
retrieving revision 1.32
diff -u -r1.32 em-migrate.c
--- mail/em-migrate.c 27 Jan 2004 22:51:00 -0000 1.32
+++ mail/em-migrate.c 3 Feb 2004 08:02:40 -0000
@@ -718,6 +718,7 @@
{ "account_pgp_encrypt_to_self_%i", "encrypt-to-self", E_BCONF_MAP_BOOL },
{ "account_pgp_always_trust_%i", "always-trust", E_BCONF_MAP_BOOL },
{ "account_pgp_always_sign_%i", "always-sign", E_BCONF_MAP_BOOL },
+ { "account_pgp_clearsign_%i", "clearsign", E_BCONF_MAP_BOOL },
{ "account_pgp_no_imip_sign_%i", "no-imip-sign", E_BCONF_MAP_BOOL },
{ "account_pgp_key_%i", "key-id", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
{ NULL },
Index: mail/mail-account-editor.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-account-editor.c,v
retrieving revision 1.59
diff -u -r1.59 mail-account-editor.c
--- mail/mail-account-editor.c 1 Dec 2003 01:32:24 -0000 1.59
+++ mail/mail-account-editor.c 3 Feb 2004 08:02:40 -0000
@@ -199,6 +199,7 @@
g_signal_connect (editor->gui->pgp_key, "changed", G_CALLBACK (mail_account_editor_changed), editor);
g_signal_connect (editor->gui->pgp_encrypt_to_self, "toggled", G_CALLBACK (mail_account_editor_changed), editor);
g_signal_connect (editor->gui->pgp_always_sign, "toggled", G_CALLBACK (mail_account_editor_changed), editor);
+ g_signal_connect (editor->gui->pgp_clearsign, "toggled", G_CALLBACK (mail_account_editor_changed), editor);
g_signal_connect (editor->gui->pgp_no_imip_sign, "toggled", G_CALLBACK (mail_account_editor_changed), editor);
g_signal_connect (editor->gui->pgp_always_trust, "toggled", G_CALLBACK (mail_account_editor_changed), editor);
Index: mail/mail-account-gui.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-account-gui.c,v
retrieving revision 1.146
diff -u -r1.146 mail-account-gui.c
--- mail/mail-account-gui.c 30 Jan 2004 22:16:48 -0000 1.146
+++ mail/mail-account-gui.c 3 Feb 2004 08:02:40 -0000
@@ -1624,6 +1624,8 @@
gtk_toggle_button_set_active (gui->pgp_encrypt_to_self, account->pgp_encrypt_to_self);
gui->pgp_always_sign = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_always_sign"));
gtk_toggle_button_set_active (gui->pgp_always_sign, account->pgp_always_sign);
+ gui->pgp_clearsign = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_clearsign"));
+ gtk_toggle_button_set_active (gui->pgp_clearsign, account->pgp_clearsign);
gui->pgp_no_imip_sign = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_no_imip_sign"));
gtk_toggle_button_set_active (gui->pgp_no_imip_sign, account->pgp_no_imip_sign);
gui->pgp_always_trust = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_always_trust"));
@@ -2029,6 +2031,7 @@
new->pgp_key = g_strdup (gtk_entry_get_text (gui->pgp_key));
new->pgp_encrypt_to_self = gtk_toggle_button_get_active (gui->pgp_encrypt_to_self);
new->pgp_always_sign = gtk_toggle_button_get_active (gui->pgp_always_sign);
+ new->pgp_clearsign = gtk_toggle_button_get_active (gui->pgp_clearsign);
new->pgp_no_imip_sign = gtk_toggle_button_get_active (gui->pgp_no_imip_sign);
new->pgp_always_trust = gtk_toggle_button_get_active (gui->pgp_always_trust);
Index: mail/mail-account-gui.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-account-gui.h,v
retrieving revision 1.26
diff -u -r1.26 mail-account-gui.h
--- mail/mail-account-gui.h 31 Oct 2003 04:56:46 -0000 1.26
+++ mail/mail-account-gui.h 3 Feb 2004 08:02:40 -0000
@@ -106,6 +106,7 @@
GtkEntry *pgp_key;
GtkToggleButton *pgp_encrypt_to_self;
GtkToggleButton *pgp_always_sign;
+ GtkToggleButton *pgp_clearsign;
GtkToggleButton *pgp_no_imip_sign;
GtkToggleButton *pgp_always_trust;
Index: mail/mail-config.glade
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-config.glade,v
retrieving revision 1.129
diff -u -r1.129 mail-config.glade
--- mail/mail-config.glade 23 Jan 2004 17:21:42 -0000 1.129
+++ mail/mail-config.glade 3 Feb 2004 08:02:41 -0000
@@ -2644,6 +2644,24 @@
</child>
<child>
+ <widget class="GtkCheckButton" id="pgp_clearsign">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">When signing outgoing message, use _cleartext signature if possible</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkCheckButton" id="pgp_no_imip_sign">
<property name="visible">True</property>
<property name="can_focus">True</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]