[evolution-mapi] Bug #632450 - Support sending S/MIME messages
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #632450 - Support sending S/MIME messages
- Date: Mon, 14 Mar 2011 18:52:33 +0000 (UTC)
commit 816d2626639ee96af9a81e7d6fc0f64133c8fce0
Author: Milan Crha <mcrha redhat com>
Date: Mon Mar 14 19:51:50 2011 +0100
Bug #632450 - Support sending S/MIME messages
src/libexchangemapi/exchange-mapi-mail-utils.c | 191 +++++++++++++++++++++---
src/libexchangemapi/exchange-mapi-mail-utils.h | 1 +
2 files changed, 174 insertions(+), 18 deletions(-)
---
diff --git a/src/libexchangemapi/exchange-mapi-mail-utils.c b/src/libexchangemapi/exchange-mapi-mail-utils.c
index 7e6da23..586e45e 100644
--- a/src/libexchangemapi/exchange-mapi-mail-utils.c
+++ b/src/libexchangemapi/exchange-mapi-mail-utils.c
@@ -51,6 +51,7 @@ mail_item_free (MailItem *item)
exchange_mapi_util_free_recipient_list (&item->recipients);
g_free (item->msg_class);
+ g_free (item->pid_name_content_type);
g_free (item);
}
@@ -1146,6 +1147,8 @@ mail_item_add_attach (MailItem *item, CamelMimePart *part, CamelStream *content_
item_attach->streams = g_slist_append (item_attach->streams, stream);
item->attachments = g_slist_append(item->attachments, item_attach);
+ g_free (buf);
+
return TRUE;
}
@@ -1224,6 +1227,147 @@ get_content_stream (CamelMimePart *part, GCancellable *cancellable)
return content_stream;
}
+static void
+mapi_do_smime_signed (MailItem *item, CamelMultipart *multipart, GCancellable *cancellable, GError **error)
+{
+ CamelMimePart *content, *signature;
+ ExchangeMAPIAttachment *item_attach;
+ ExchangeMAPIStream *stream;
+ CamelStream *content_stream;
+ CamelContentType *type;
+ CamelDataWrapper *dw;
+ uint32_t ui32;
+ guint8 *buf;
+ guint32 read_size;
+ gchar *content_type_str;
+
+ g_free (item->msg_class);
+ item->msg_class = g_strdup ("IPM.Note.SMIME.MultipartSigned");
+
+ content = camel_multipart_get_part (multipart, CAMEL_MULTIPART_SIGNED_CONTENT);
+ signature = camel_multipart_get_part (multipart, CAMEL_MULTIPART_SIGNED_SIGNATURE);
+
+ g_return_if_fail (content != NULL);
+ g_return_if_fail (signature != NULL);
+
+ content_stream = get_content_stream (content, cancellable);
+ type = camel_mime_part_get_content_type (content);
+
+ if (camel_content_type_is (type, "text", "plain")) {
+ mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
+ } else if (camel_content_type_is (type, "text", "html")) {
+ mail_item_set_body_stream (item, content_stream, PART_TYPE_TEXT_HTML, cancellable);
+ } else {
+ mail_item_add_attach (item, content, content_stream, cancellable);
+ }
+
+ if (content_stream)
+ g_object_unref (content_stream);
+
+ content_stream = camel_stream_mem_new ();
+ dw = CAMEL_DATA_WRAPPER (multipart);
+ type = camel_data_wrapper_get_mime_type_field (dw);
+ content_type_str = camel_content_type_format (type);
+
+ #define wstr(str) camel_stream_write (content_stream, str, strlen (str), cancellable, NULL)
+ wstr("Content-Type: ");
+ wstr(content_type_str);
+ wstr("\n\n");
+ #undef wstr
+
+ g_free (content_type_str);
+
+ camel_data_wrapper_write_to_stream_sync (dw, (CamelStream *) content_stream, cancellable, NULL);
+
+ item_attach = g_new0 (ExchangeMAPIAttachment, 1);
+ item_attach->lpProps = g_new0 (struct SPropValue, 6 + 1);
+ item_attach->cValues = 6;
+
+ ui32 = ATTACH_BY_VALUE;
+ set_SPropValue_proptag (&(item_attach->lpProps[0]), PR_ATTACH_METHOD, &ui32);
+ ui32 = -1;
+ set_SPropValue_proptag (&(item_attach->lpProps[1]), PR_RENDERING_POSITION, &ui32);
+ set_SPropValue_proptag (&(item_attach->lpProps[2]), PR_ATTACH_MIME_TAG, "multipart/signed");
+ set_SPropValue_proptag (&(item_attach->lpProps[3]), PR_ATTACH_FILENAME_UNICODE, "SMIME.txt");
+ set_SPropValue_proptag (&(item_attach->lpProps[4]), PR_ATTACH_LONG_FILENAME_UNICODE, "SMIME.txt");
+ set_SPropValue_proptag (&(item_attach->lpProps[5]), PR_DISPLAY_NAME_UNICODE, "SMIME.txt");
+
+ stream = g_new0 (ExchangeMAPIStream, 1);
+ stream->proptag = PR_ATTACH_DATA_BIN;
+ stream->value = g_byte_array_new ();
+
+ buf = g_new0 (guint8 , STREAM_SIZE);
+
+ g_seekable_seek (G_SEEKABLE (content_stream), 0, G_SEEK_SET, NULL, NULL);
+ while (read_size = camel_stream_read (content_stream, (gchar *) buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
+ stream->value = g_byte_array_append (stream->value, buf, read_size);
+ }
+
+ g_free (buf);
+ g_object_unref (content_stream);
+
+ item_attach->streams = g_slist_append (item_attach->streams, stream);
+ item->attachments = g_slist_append (item->attachments, item_attach);
+}
+
+static void
+mapi_do_smime_encrypted (MailItem *item, CamelMedium *message, GCancellable *cancellable, GError **error)
+{
+ ExchangeMAPIAttachment *item_attach;
+ ExchangeMAPIStream *stream;
+ CamelStream *content_stream;
+ CamelDataWrapper *dw;
+ CamelContentType *type;
+ uint32_t ui32;
+ guint8 *buf;
+ guint32 read_size;
+ gchar *content_type_str;
+
+ g_free (item->msg_class);
+ item->msg_class = g_strdup ("IPM.Note.SMIME");
+
+ type = camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (message));
+ dw = camel_medium_get_content (message);
+
+ content_type_str = camel_content_type_format (type);
+
+ g_free (item->pid_name_content_type);
+ item->pid_name_content_type = content_type_str; /* will be freed with the MailItem structure */
+
+ content_stream = camel_stream_mem_new ();
+ camel_data_wrapper_decode_to_stream_sync (dw, (CamelStream *) content_stream, cancellable, NULL);
+
+ item_attach = g_new0 (ExchangeMAPIAttachment, 1);
+ item_attach->lpProps = g_new0 (struct SPropValue, 6 + 1);
+ item_attach->cValues = 6;
+
+ ui32 = ATTACH_BY_VALUE;
+ set_SPropValue_proptag (&(item_attach->lpProps[0]), PR_ATTACH_METHOD, &ui32);
+ ui32 = -1;
+ set_SPropValue_proptag (&(item_attach->lpProps[1]), PR_RENDERING_POSITION, &ui32);
+ set_SPropValue_proptag (&(item_attach->lpProps[2]), PR_ATTACH_MIME_TAG, content_type_str);
+ set_SPropValue_proptag (&(item_attach->lpProps[3]), PR_ATTACH_FILENAME_UNICODE, "SMIME.txt");
+ set_SPropValue_proptag (&(item_attach->lpProps[4]), PR_ATTACH_LONG_FILENAME_UNICODE, "SMIME.txt");
+ set_SPropValue_proptag (&(item_attach->lpProps[5]), PR_DISPLAY_NAME_UNICODE, "SMIME.txt");
+
+ stream = g_new0 (ExchangeMAPIStream, 1);
+ stream->proptag = PR_ATTACH_DATA_BIN;
+ stream->value = g_byte_array_new ();
+
+ buf = g_new0 (guint8 , STREAM_SIZE);
+
+ g_seekable_seek (G_SEEKABLE (content_stream), 0, G_SEEK_SET, NULL, NULL);
+ while (read_size = camel_stream_read (content_stream, (gchar *) buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
+ stream->value = g_byte_array_append (stream->value, buf, read_size);
+ }
+
+ g_free (buf);
+ g_object_unref (content_stream);
+
+ item_attach->streams = g_slist_append (item_attach->streams, stream);
+ item->attachments = g_slist_append (item->attachments, item_attach);
+}
+
static gboolean
mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first, GCancellable *cancellable)
{
@@ -1232,9 +1376,6 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first, GCanc
CamelContentType *type;
CamelMimePart *part;
gint n_part, i_part;
- const gchar *filename;
- const gchar *description;
- const gchar *content_id;
g_return_val_if_fail (is_first != NULL, FALSE);
@@ -1271,14 +1412,8 @@ mapi_do_multipart (CamelMultipart *mp, MailItem *item, gboolean *is_first, GCanc
}
}
- /* filename */
- filename = camel_mime_part_get_filename(part);
-
content_stream = get_content_stream (part, cancellable);
- description = camel_mime_part_get_description(part);
- content_id = camel_mime_part_get_content_id(part);
-
type = camel_mime_part_get_content_type(part);
if (i_part == 0 && (*is_first) && camel_content_type_is (type, "text", "plain")) {
@@ -1316,6 +1451,7 @@ mapi_mime_message_to_mail_item (CamelMimeMessage *message, gint32 message_camel_
CamelDataWrapper *dw = NULL;
CamelStream *content_stream;
CamelMultipart *multipart;
+ CamelContentType *content_type;
CamelInternetAddress *to, *cc, *bcc;
MailItem *item = g_new0 (MailItem, 1);
const gchar *namep = NULL;
@@ -1396,16 +1532,28 @@ mapi_mime_message_to_mail_item (CamelMimeMessage *message, gint32 message_camel_
item->header.in_reply_to = g_strdup (camel_medium_get_header ((CamelMedium *) message, "In-Reply-To"));
item->header.message_id = g_strdup (camel_medium_get_header ((CamelMedium *) message, "Message-ID"));
- /* contents body */
- multipart = (CamelMultipart *)camel_medium_get_content (CAMEL_MEDIUM (message));
+ item->recipients = recipient_list;
+
+ content_type = camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (message));
+ g_return_val_if_fail (content_type != NULL, item);
- if (CAMEL_IS_MULTIPART(multipart)) {
- gboolean is_first = TRUE;
- if (!mapi_do_multipart (CAMEL_MULTIPART(multipart), item, &is_first, cancellable))
- printf("camel message multi part error\n");
+ if (camel_content_type_is (content_type, "application", "x-pkcs7-mime") || camel_content_type_is (content_type, "application", "pkcs7-mime")) {
+ mapi_do_smime_encrypted (item, CAMEL_MEDIUM (message), cancellable, error);
} else {
+ /* contents body */
dw = camel_medium_get_content (CAMEL_MEDIUM (message));
- if (dw) {
+
+ if (CAMEL_IS_MULTIPART (dw)) {
+ gboolean is_first = TRUE;
+
+ multipart = CAMEL_MULTIPART (dw);
+
+ if (CAMEL_IS_MULTIPART_SIGNED (multipart) && camel_multipart_get_number (multipart) == 2) {
+ mapi_do_smime_signed (item, multipart, cancellable, error);
+ } else {
+ mapi_do_multipart (multipart, item, &is_first, cancellable);
+ }
+ } else if (dw) {
content_stream = get_content_stream ((CamelMimePart *) message, cancellable);
mail_item_set_body_stream (item, content_stream, PART_TYPE_PLAIN_TEXT, cancellable);
@@ -1415,8 +1563,6 @@ mapi_mime_message_to_mail_item (CamelMimeMessage *message, gint32 message_camel_
}
}
- item->recipients = recipient_list;
-
return item;
}
@@ -1434,6 +1580,15 @@ mapi_mail_utils_create_item_build_props (ExchangeMapiConnection *conn, mapi_id_t
return FALSE; \
} G_STMT_END
+ if (item->msg_class) {
+ set_value (PR_MESSAGE_CLASS, item->msg_class);
+ }
+
+ if (item->pid_name_content_type) {
+ if (!exchange_mapi_utils_add_spropvalue_named_id (conn, fid, mem_ctx, values, n_values, PidNameContentType, item->pid_name_content_type))
+ return FALSE;
+ }
+
cpid = 65001; /* UTF8 - also used with PR_HTML */
set_value (PR_INTERNET_CPID, &cpid);
set_value (PR_SUBJECT_UNICODE, item->header.subject);
diff --git a/src/libexchangemapi/exchange-mapi-mail-utils.h b/src/libexchangemapi/exchange-mapi-mail-utils.h
index 67ca9bf..c1f289b 100644
--- a/src/libexchangemapi/exchange-mapi-mail-utils.h
+++ b/src/libexchangemapi/exchange-mapi-mail-utils.h
@@ -67,6 +67,7 @@ typedef struct _MailItem {
mapi_id_t fid;
mapi_id_t mid;
gchar *msg_class;
+ gchar *pid_name_content_type; /* for PidNameContentType */
MailItemHeader header;
MailItemMessage msg;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]