Esempio n. 1
0
void
org_gnome_prefer_plain_multipart_alternative(void *ep, EMFormatHookTarget *t)
{
	CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)t->part);
	CamelMimePart *part, *display_part = NULL;
	int i, nparts, partidlen, displayid = 0;

	if (epp_mode == EPP_NORMAL) {
		/* Try to find text/html part even when not as last and force to show it.
		   Old handler will show the last part of multipart/alternate, but if we
		   can offer HTML, then offer it, regardless of position in multipart. */
		nparts = camel_multipart_get_number (mp);
		for (i = 0; i < nparts; i++) {
			part = camel_multipart_get_part (mp, i);
			if (part && camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
				displayid = i;
				display_part = part;
				break;
			}
		}

		if (display_part) {
			g_string_append_printf (t->format->part_id, ".alternative.%d", displayid);
			em_format_part_as (t->format, t->stream, display_part, "text/html");
			g_string_truncate (t->format->part_id, partidlen);
		} else {
			t->item->handler.old->handler (t->format, t->stream, t->part, t->item->handler.old);
		}
		return;
	} else if (!CAMEL_IS_MULTIPART(mp)) {
		em_format_format_source(t->format, t->stream, t->part);
		return;
	}

	nparts = camel_multipart_get_number(mp);
	for (i=0; i<nparts; i++) {
		part = camel_multipart_get_part(mp, i);
		if (part && camel_content_type_is(camel_mime_part_get_content_type(part), "text", "plain")) {
			displayid = i;
			display_part = part;
			break;
		}
	}

	/* this part-id stuff is poking private data, needs api */
	partidlen = t->format->part_id->len;

	/* if we found a text part, show it */
	if (display_part) {
		g_string_append_printf(t->format->part_id, ".alternative.%d", displayid);
		em_format_part_as(t->format, t->stream, display_part, "text/plain");
		g_string_truncate(t->format->part_id, partidlen);
	}

	/* all other parts are attachments */
	export_as_attachments (mp, t->format, t->stream, display_part);

	g_string_truncate(t->format->part_id, partidlen);
}
Esempio n. 2
0
/* there is also an identical copy of this in camel-filter-search.c */
gboolean
camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern)
{
	CamelDataWrapper *containee;
	int truth = FALSE;
	int parts, i;

	containee = camel_medium_get_content_object (CAMEL_MEDIUM (object));

	if (containee == NULL)
		return FALSE;

	/* using the object types is more accurate than using the mime/types */
	if (CAMEL_IS_MULTIPART (containee)) {
		parts = camel_multipart_get_number (CAMEL_MULTIPART (containee));
		for (i = 0; i < parts && truth == FALSE; i++) {
			CamelDataWrapper *part = (CamelDataWrapper *)camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
			if (part)
				truth = camel_search_message_body_contains (part, pattern);
		}
	} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
		/* for messages we only look at its contents */
		truth = camel_search_message_body_contains ((CamelDataWrapper *)containee, pattern);
	} else if (camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")) {
		/* for all other text parts, we look inside, otherwise we dont care */
		CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new ();

		camel_data_wrapper_write_to_stream (containee, CAMEL_STREAM (mem));
		camel_stream_write (CAMEL_STREAM (mem), "", 1);
		truth = regexec (pattern, (char *) mem->buffer->data, 0, NULL, 0) == 0;
		camel_object_unref (mem);
	}

	return truth;
}
Esempio n. 3
0
void org_gnome_evolution_import_ics_attachments (EPlugin *ep, EMPopupTargetAttachments *t)
{
	GSList *menus = NULL;
	icalcomponent_kind kind;
	int len = 0;
	int i = 0;
	CamelContentType *type;

	len = g_slist_length(t->attachments);

	if (len != 1)
		return;

	type = camel_data_wrapper_get_mime_type_field (((CamelDataWrapper *) ((EAttachment *) t->attachments->data)->body));
	if (type && camel_content_type_is(type, "text", "calendar")) {

		kind = get_menu_type (t);

		if (kind == ICAL_VTODO_COMPONENT ) {
			for (i = 0; i < sizeof (popup_tasks_items) / sizeof (popup_tasks_items[0]); i++)
				menus = g_slist_prepend (menus, &popup_tasks_items[i]);
		} else if ( kind == ICAL_VEVENT_COMPONENT) {
			for (i = 0; i < sizeof (popup_calendar_items) / sizeof (popup_calendar_items[0]); i++)
				menus = g_slist_prepend (menus, &popup_calendar_items[i]);
		}

		e_popup_add_items (t->target.popup, menus, NULL, popup_free, t);
	}
}
static gssize
data_wrapper_decode_to_stream_sync (CamelDataWrapper *data_wrapper,
                                    CamelStream *stream,
                                    GCancellable *cancellable,
                                    GError **error)
{
	CamelMimeFilter *filter;
	CamelStream *fstream;
	gssize ret;

	fstream = camel_stream_filter_new (stream);

	switch (data_wrapper->encoding) {
	case CAMEL_TRANSFER_ENCODING_BASE64:
		filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
		camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
		g_object_unref (filter);
		break;
	case CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE:
		filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_QP_DEC);
		camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
		g_object_unref (filter);
		break;
	case CAMEL_TRANSFER_ENCODING_UUENCODE:
		filter = camel_mime_filter_basic_new (CAMEL_MIME_FILTER_BASIC_UU_DEC);
		camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
		g_object_unref (filter);
		break;
	default:
		break;
	}

	if (!(camel_content_type_is (data_wrapper->mime_type, "text", "pdf")) && camel_content_type_is (data_wrapper->mime_type, "text", "*")) {
		filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_DECODE,
						     CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
		camel_stream_filter_add (CAMEL_STREAM_FILTER (fstream), filter);
		g_object_unref (filter);
	}

	ret = camel_data_wrapper_write_to_stream_sync (
		data_wrapper, fstream, cancellable, error);

	camel_stream_flush (fstream, NULL, NULL);
	g_object_unref (fstream);

	return ret;
}
Esempio n. 5
0
/**
 *
 * "util_get_msg_body" is based on mail-to-task eplugin's get_description function.
 * which is GPL licensed.
 * */
static gchar *
util_get_msg_body(CamelMimeMessage *message, gchar **text) {
   CamelDataWrapper *content;
   CamelStream *mem;
   CamelContentType *type;
   CamelMimePart *mime_part = CAMEL_MIME_PART(message);

   GSList sl;
   gchar *str, *convert_str = NULL;
   gsize bytes_read, bytes_written;
   gint count = 2;

   content = camel_medium_get_content_object((CamelMedium *) message);

   if (!content)
      return;

   /*
    * Get non-multipart content from multipart message.
    */
   while (CAMEL_IS_MULTIPART(content) && count > 0) {
      mime_part = camel_multipart_get_part(CAMEL_MULTIPART(content), 0);
      content = camel_medium_get_content_object(CAMEL_MEDIUM(mime_part));
      count--;
   }

   if (!mime_part)
      return;

   type = camel_mime_part_get_content_type(mime_part);
   if (!camel_content_type_is(type, "text", "plain"))
      return;

   mem = camel_stream_mem_new();
   camel_data_wrapper_decode_to_stream(content, mem);

   str = g_strndup((const gchar *) ((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len);
   camel_object_unref(mem);

   /* convert to UTF-8 string */
   if (str && content->mime_type->params && content->mime_type->params->value) {
      convert_str = g_convert(str, strlen(str),
            "UTF-8", content->mime_type->params->value,
            &bytes_read, &bytes_written, NULL);
   }

   if (convert_str)
      *text = convert_str;
   else
      *text = str;

   /*g_free (str);
     if (convert_str)
     g_free (convert_str);
     */
}
/* there is also an identical copy of this in camel-filter-search.c */
gboolean
camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern)
{
	CamelDataWrapper *containee;
	gint truth = FALSE;
	gint parts, i;

	containee = camel_medium_get_content (CAMEL_MEDIUM (object));

	if (containee == NULL)
		return FALSE;

	/* using the object types is more accurate than using the mime/types */
	if (CAMEL_IS_MULTIPART (containee)) {
		parts = camel_multipart_get_number (CAMEL_MULTIPART (containee));
		for (i = 0; i < parts && truth == FALSE; i++) {
			CamelDataWrapper *part = (CamelDataWrapper *)camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
			if (part)
				truth = camel_search_message_body_contains (part, pattern);
		}
	} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
		/* for messages we only look at its contents */
		truth = camel_search_message_body_contains ((CamelDataWrapper *)containee, pattern);
	} else if (camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")
		|| camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "x-evolution", "evolution-rss-feed")) {
		/* for all other text parts, we look inside, otherwise we dont care */
		CamelStream *stream;
		GByteArray *byte_array;

		byte_array = g_byte_array_new ();
		stream = camel_stream_mem_new_with_byte_array (byte_array);
		camel_data_wrapper_write_to_stream_sync (
			containee, stream, NULL, NULL);
		camel_stream_write (stream, "", 1, NULL, NULL);
		truth = regexec (pattern, (gchar *) byte_array->data, 0, NULL, 0) == 0;
		g_object_unref (stream);
	}

	return truth;
}
Esempio n. 7
0
static void
export_as_attachments (CamelMultipart *mp, EMFormat *format, CamelStream *stream, CamelMimePart *except)
{
	int i, nparts, partidlen;
	CamelMimePart *part;

	if (!mp || !CAMEL_IS_MULTIPART (mp))
		return;

	partidlen = format->part_id->len;

	nparts = camel_multipart_get_number(mp);
	for (i = 0; i < nparts; i++) {
		part = camel_multipart_get_part (mp, i);

		if (part != except) {
			CamelMultipart *multipart = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);

			if (CAMEL_IS_MULTIPART (multipart)) {
				export_as_attachments (multipart, format, stream, except);
			} else {
				g_string_append_printf (format->part_id, ".alternative.%d", i);

				if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
					/* always show HTML as attachments and not inline */
					camel_mime_part_set_disposition (part, "attachment");

					if (!camel_mime_part_get_filename (part)) {
						char *str = g_strdup_printf ("%s.html", _("attachment"));
						camel_mime_part_set_filename (part, str);
						g_free (str);
					}

					em_format_part_as (format, stream, part, "application/octet-stream");
				} else
					em_format_part (format, stream, part);

				g_string_truncate (format->part_id, partidlen);
			}
		}
	}
}
Esempio n. 8
0
void org_gnome_evolution_import_ics_part (EPlugin*ep, EMPopupTargetPart *t)
{
	GSList *menus = NULL;
	icalcomponent_kind kind;
	int i = 0;

	if (!camel_content_type_is(((CamelDataWrapper *) t->part)->mime_type, "text", "calendar"))
		return;

	kind = get_menu_type (t);

	if (kind == ICAL_VTODO_COMPONENT ) {
		for (i = 0; i < sizeof (popup_tasks_items) / sizeof (popup_tasks_items[0]); i++)
			menus = g_slist_prepend (menus, &popup_tasks_items[i]);
	} else if ( kind == ICAL_VEVENT_COMPONENT) {
		for (i = 0; i < sizeof (popup_calendar_items) / sizeof (popup_calendar_items[0]); i++)
			menus = g_slist_prepend (menus, &popup_calendar_items[i]);
	}

	e_popup_add_items (t->target.popup, menus, NULL, popup_free, t);
}
Esempio n. 9
0
static void
set_description (ECalComponent *comp,
                 CamelMimeMessage *message)
{
	CamelDataWrapper *content;
	CamelStream *stream;
	CamelContentType *type;
	CamelMimePart *mime_part = CAMEL_MIME_PART (message);
	ECalComponentText *text = NULL;
	GByteArray *byte_array;
	GSList *sl = NULL;
	gchar *str, *convert_str = NULL;
	gsize bytes_read, bytes_written;
	gint count = 2;

	content = camel_medium_get_content ((CamelMedium *) message);
	if (!content)
		return;

	/*
	 * Get non-multipart content from multipart message.
	 */
	while (CAMEL_IS_MULTIPART (content) && count > 0) {
		mime_part = camel_multipart_get_part (CAMEL_MULTIPART (content), 0);
		content = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
		count--;
	}

	if (!mime_part)
		return;

	type = camel_mime_part_get_content_type (mime_part);
	if (!camel_content_type_is (type, "text", "plain"))
		return;

	byte_array = g_byte_array_new ();
	stream = camel_stream_mem_new_with_byte_array (byte_array);
	camel_data_wrapper_decode_to_stream_sync (content, stream, NULL, NULL);
	str = g_strndup ((gchar *) byte_array->data, byte_array->len);
	g_object_unref (stream);

	/* convert to UTF-8 string */
	if (str && content->mime_type->params && content->mime_type->params->value) {
		convert_str = g_convert (
			str, strlen (str),
			"UTF-8", content->mime_type->params->value,
			&bytes_read, &bytes_written, NULL);
	}

	text = g_new0 (ECalComponentText, 1);
	if (convert_str)
		text->value = prepend_from (message, &convert_str);
	else
		text->value = prepend_from (message, &str);
	text->altrep = NULL;
	sl = g_slist_append (sl, text);

	e_cal_component_set_description_list (comp, sl);

	g_free (str);
	if (convert_str)
		g_free (convert_str);
	e_cal_component_free_text_list (sl);
}
Esempio n. 10
0
static gboolean
empe_mp_alternative_parse (EMailParserExtension *extension,
                           EMailParser *parser,
                           CamelMimePart *part,
                           GString *part_id,
                           GCancellable *cancellable,
                           GQueue *out_mail_parts)
{
	CamelMultipart *mp;
	gint i, nparts, bestid = 0;
	CamelMimePart *best = NULL;
	EMailExtensionRegistry *reg;

	reg = e_mail_parser_get_extension_registry (parser);

	mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);

	if (!CAMEL_IS_MULTIPART (mp))
		return e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.source",
			cancellable, out_mail_parts);

	/* as per rfc, find the last part we know how to display */
	nparts = camel_multipart_get_number (mp);
	for (i = 0; i < nparts; i++) {
		CamelMimePart *mpart;
		CamelDataWrapper *data_wrapper;
		CamelContentType *type;
		gchar *mime_type;
		gsize content_size;

		if (g_cancellable_is_cancelled (cancellable))
			return TRUE;

		/* is it correct to use the passed in *part here? */
		mpart = camel_multipart_get_part (mp, i);

		if (mpart == NULL)
			continue;

		/* This may block even though the stream does not.
		 * XXX Pretty inefficient way to test if the MIME part
		 *     is empty.  Surely there's a quicker way? */
		data_wrapper = camel_medium_get_content (CAMEL_MEDIUM (mpart));
		content_size = camel_data_wrapper_calculate_decoded_size_sync (data_wrapper, cancellable, NULL);

		if (content_size == 0)
			continue;

		type = camel_mime_part_get_content_type (mpart);
		mime_type = camel_content_type_simple (type);

		camel_strdown (mime_type);

		if (!e_mail_part_is_attachment (mpart) &&
			 ((camel_content_type_is (type, "multipart", "related") == 0) ||
			  !related_display_part_is_attachment (mpart)) &&
		    (e_mail_extension_registry_get_for_mime_type (reg, mime_type) ||
			((best == NULL) &&
			 (e_mail_extension_registry_get_fallback (reg, mime_type)))))
		{
			best = mpart;
			bestid = i;
		}

		g_free (mime_type);
	}

	if (best) {
		gint len = part_id->len;

		g_string_append_printf (part_id, ".alternative.%d", bestid);

		e_mail_parser_parse_part (
			parser, best, part_id,
			cancellable, out_mail_parts);

		g_string_truncate (part_id, len);
	} else {
		e_mail_parser_parse_part_as (
			parser, part, part_id, "multipart/mixed",
			cancellable, out_mail_parts);
	}

	return TRUE;
}
static gboolean
empe_mp_signed_parse (EMailParserExtension *extension,
                      EMailParser *parser,
                      CamelMimePart *part,
                      GString *part_id,
                      GCancellable *cancellable,
                      GQueue *out_mail_parts)
{
	CamelMimePart *cpart = NULL;
	CamelMultipart *multipart;
	CamelCipherContext *cipher = NULL;
	CamelContentType *content_type;
	CamelSession *session;
	guint32 validity_type;
	CamelCipherValidity *valid;
	const gchar *protocol = NULL;
	GError *local_error = NULL;
	gint i, nparts, len;
	gboolean secured;

	/* If the part is application/pgp-signature sub-part then skip it. */
	if (!CAMEL_IS_MULTIPART (part)) {
		content_type = camel_mime_part_get_content_type (part);
		if (camel_content_type_is (
			content_type, "application", "pgp-signature")) {
			return TRUE;
		}
	}

	multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
	if (CAMEL_IS_MULTIPART_SIGNED (multipart)) {
		cpart = camel_multipart_get_part (
			multipart, CAMEL_MULTIPART_SIGNED_CONTENT);
	}

	if (cpart == NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Could not parse MIME message. "
			"Displaying as source."));
		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.source",
			cancellable, out_mail_parts);

		return TRUE;
	}

	content_type = camel_data_wrapper_get_mime_type_field (
		CAMEL_DATA_WRAPPER (multipart));
	if (content_type != NULL)
		protocol = camel_content_type_param (content_type, "protocol");

	session = e_mail_parser_get_session (parser);
	/* FIXME: Should be done via a plugin interface */
	/* FIXME: duplicated in em-format-html-display.c */
	if (protocol != NULL) {
#ifdef ENABLE_SMIME
		if (g_ascii_strcasecmp ("application/x-pkcs7-signature", protocol) == 0
		    || g_ascii_strcasecmp ("application/pkcs7-signature", protocol) == 0) {
			cipher = camel_smime_context_new (session);
			validity_type = E_MAIL_PART_VALIDITY_SMIME;
		} else {
#endif
			if (g_ascii_strcasecmp ("application/pgp-signature", protocol) == 0) {
				cipher = camel_gpg_context_new (session);
				validity_type = E_MAIL_PART_VALIDITY_PGP;
			}
#ifdef ENABLE_SMIME
		}
#endif
	}

	if (cipher == NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Unsupported signature format"));
		e_mail_parser_parse_part_as (
			parser, part, part_id, "multipart/mixed",
			cancellable, out_mail_parts);

		return TRUE;
	}

	valid = camel_cipher_context_verify_sync (
		cipher, part, cancellable, &local_error);

	if (local_error != NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Error verifying signature: %s"),
			local_error->message);
		e_mail_parser_parse_part_as (
			parser, part, part_id, "multipart/mixed",
			cancellable, out_mail_parts);

		g_object_unref (cipher);
		g_error_free (local_error);

		return TRUE;
	}

	nparts = camel_multipart_get_number (multipart);
	secured = FALSE;
	len = part_id->len;
	for (i = 0; i < nparts; i++) {
		GQueue work_queue = G_QUEUE_INIT;
		GList *head, *link;
		CamelMimePart *subpart;

		subpart = camel_multipart_get_part (multipart, i);

		g_string_append_printf (part_id, ".signed.%d", i);

		g_warn_if_fail (e_mail_parser_parse_part (
			parser, subpart, part_id, cancellable, &work_queue));

		g_string_truncate (part_id, len);

		if (!secured)
			secured = e_mail_part_is_secured (subpart);

		head = g_queue_peek_head_link (&work_queue);

		for (link = head; link != NULL; link = g_list_next (link)) {
			EMailPart *mail_part = link->data;

			e_mail_part_update_validity (
				mail_part, valid,
				validity_type | E_MAIL_PART_VALIDITY_SIGNED);
		}

		e_queue_transfer (&work_queue, out_mail_parts);
	}

	/* Add a widget with details about the encryption, but only when
	 * the encrypted isn't itself secured, in that case it has created
	 * the button itself. */
	if (!secured) {
		GQueue work_queue = G_QUEUE_INIT;
		EMailPart *mail_part;

		g_string_append (part_id, ".signed.button");

		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.widget.secure-button",
			cancellable, &work_queue);

		mail_part = g_queue_peek_head (&work_queue);

		if (mail_part != NULL)
			e_mail_part_update_validity (
				mail_part, valid,
				validity_type | E_MAIL_PART_VALIDITY_SIGNED);

		e_queue_transfer (&work_queue, out_mail_parts);

		g_string_truncate (part_id, len);
	}

	camel_cipher_validity_free (valid);

	g_object_unref (cipher);

	return TRUE;
}
Esempio n. 12
0
static void
create_mime_message_cb (ESoapMessage *msg,
                        gpointer user_data)
{
	struct _create_mime_msg_data *create_data = user_data;
	CamelStream *mem, *filtered;
	CamelMimeFilter *filter;
	CamelContentType *content_type;
	GByteArray *bytes;
	gchar *base64;
	gint msgflag;
	guint32 message_camel_flags = 0;

	if (create_data->info)
		message_camel_flags = camel_message_info_flags (create_data->info);
		
	e_soap_message_start_element (msg, "Message", NULL, NULL);
	e_soap_message_start_element (msg, "MimeContent", NULL, NULL);

	/* This is horrid. We really need to extend ESoapMessage to allow us
	 * to stream this directly rather than storing it in RAM. Which right
	 * now we are doing about four times: the GByteArray in the mem stream,
	 * then the base64 version, then the xmlDoc, then the soup request. */
	camel_mime_message_set_best_encoding (
		create_data->message,
		CAMEL_BESTENC_GET_ENCODING,
		CAMEL_BESTENC_8BIT);

	mem = camel_stream_mem_new ();
	filtered = camel_stream_filter_new (mem);

	filter = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_ENCODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
	camel_stream_filter_add (CAMEL_STREAM_FILTER (filtered), filter);
	g_object_unref (filter);

	camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (create_data->message),
		filtered, NULL, NULL);
	camel_stream_flush (filtered, NULL, NULL);
	camel_stream_flush (mem, NULL, NULL);
	bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem));

	base64 = g_base64_encode (bytes->data, bytes->len);
	g_object_unref (mem);
	g_object_unref (filtered);

	e_soap_message_write_string (msg, base64);
	g_free (base64);

	e_soap_message_end_element (msg); /* MimeContent */

	content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (create_data->message));
	if (content_type && camel_content_type_is (content_type, "multipart", "report") &&
	    camel_content_type_param (content_type, "report-type") &&
	    g_ascii_strcasecmp (camel_content_type_param (content_type, "report-type"), "disposition-notification") == 0) {
		/* it's a disposition notification reply, set ItemClass too */
		e_soap_message_start_element (msg, "ItemClass", NULL, NULL);
		e_soap_message_write_string (msg, "REPORT.IPM.NOTE.IPNRN");
		e_soap_message_end_element (msg); /* ItemClass */
	}

	e_ews_message_write_string_parameter_with_attribute (
			msg,
			"Importance",
			NULL,
			(message_camel_flags & CAMEL_MESSAGE_FLAGGED) != 0 ? "High" : "Normal",
			NULL,
			NULL);

	/* more MAPI crap.  You can't just set the IsDraft property
	 * here you have to use the MAPI MSGFLAG_UNSENT extended
	 * property Further crap is that Exchange 2007 assumes when it
	 * sees this property that you're setting the value to 0
	 * ... it never checks */
	msgflag = MAPI_MSGFLAG_READ; /* draft or sent is always read */
	if ((message_camel_flags & CAMEL_MESSAGE_DRAFT) != 0)
		msgflag |= MAPI_MSGFLAG_UNSENT;

	e_ews_message_add_extended_property_tag_int (msg, 0x0e07, msgflag);

	if ((message_camel_flags & (CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_ANSWERED)) != 0) {
		gint icon;

		icon = (message_camel_flags & CAMEL_MESSAGE_ANSWERED) != 0 ? 0x105 : 0x106;

		e_ews_message_add_extended_property_tag_int (msg, 0x1080, icon);
	}

	if (create_data->info) {
		const gchar *followup, *completed, *dueby;
		time_t completed_tt = (time_t) 0 , dueby_tt = (time_t) 0;

		/* follow-up flags */
		followup = camel_message_info_user_tag (create_data->info, "follow-up");
		completed = camel_message_info_user_tag (create_data->info, "completed-on");
		dueby = camel_message_info_user_tag (create_data->info, "due-by");

		if (followup && !*followup)
			followup = NULL;

		if (completed && *completed)
			completed_tt = camel_header_decode_date (completed, NULL);

		if (dueby && *dueby)
			dueby_tt = camel_header_decode_date (dueby, NULL);

		/* PidTagFlagStatus */
		e_ews_message_add_extended_property_tag_int (msg, 0x1090,
			followup ? (completed_tt != (time_t) 0 ? 0x01 /* followupComplete */: 0x02 /* followupFlagged */) : 0x0);

		if (followup) {
			/* PidLidFlagRequest */
			e_ews_message_add_extended_property_distinguished_tag_string (msg, "Common", 0x8530, followup);

			/* PidTagToDoItemFlags */
			e_ews_message_add_extended_property_tag_int (msg, 0x0e2b, 1);
		}

		if (followup && completed_tt != (time_t) 0) {
			/* minute precision */
			completed_tt = completed_tt - (completed_tt % 60);

			/* PidTagFlagCompleteTime */
			e_ews_message_add_extended_property_tag_time (msg, 0x1091, completed_tt);

			/* PidLidTaskDateCompleted */
			e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x810f, completed_tt);

			/* PidLidTaskStatus */
			e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 2);

			/* PidLidPercentComplete */
			e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 1.0);

			/* PidLidTaskComplete */
			e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, TRUE);
		}

		if (followup && dueby_tt != (time_t) 0 && completed_tt == (time_t) 0) {
			/* PidLidTaskStatus */
			e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 0);

			/* PidLidPercentComplete */
			e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 0.0);

			/* PidLidTaskDueDate */
			e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x8105, dueby_tt);

			/* PidLidTaskComplete */
			e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, FALSE);
		}
	}

	if (create_data->recipients) {
		GHashTable *recip_to, *recip_cc, *recip_bcc;

		recip_to = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
		recip_cc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
		recip_bcc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
	
		filter_recipients (create_data->message, create_data->recipients, recip_to, recip_cc, recip_bcc);

		write_recipients (msg, "ToRecipients", recip_to);
		write_recipients (msg, "CcRecipients", recip_cc);
		write_recipients (msg, "BccRecipients", recip_bcc);

		g_hash_table_destroy (recip_to);
		g_hash_table_destroy (recip_cc);
		g_hash_table_destroy (recip_bcc);
	}

	e_ews_message_write_string_parameter_with_attribute (
			msg,
			"IsRead",
			NULL,
			(message_camel_flags & CAMEL_MESSAGE_SEEN) != 0 ? "true" : "false",
			NULL,
			NULL);

	e_soap_message_end_element (msg); /* Message */

	g_free (create_data);
}
static CamelMimeMessage *
mail_attachment_handler_get_selected_message (EAttachmentHandler *handler)
{
	EAttachment *attachment;
	EAttachmentView *view;
	CamelMimePart *mime_part;
	CamelMimeMessage *message = NULL;
	CamelDataWrapper *outer_wrapper;
	CamelContentType *outer_content_type;
	CamelDataWrapper *inner_wrapper;
	CamelContentType *inner_content_type;
	GList *selected;
	gboolean inner_and_outer_content_types_match;

	view = e_attachment_handler_get_view (handler);

	selected = e_attachment_view_get_selected_attachments (view);
	g_return_val_if_fail (g_list_length (selected) == 1, NULL);

	attachment = E_ATTACHMENT (selected->data);
	mime_part = e_attachment_ref_mime_part (attachment);

	outer_wrapper =
		camel_medium_get_content (CAMEL_MEDIUM (mime_part));
	outer_content_type =
		camel_data_wrapper_get_mime_type_field (outer_wrapper);

	if (!camel_content_type_is (outer_content_type, "message", "rfc822"))
		goto exit;

	inner_wrapper =
		camel_medium_get_content (CAMEL_MEDIUM (outer_wrapper));
	inner_content_type =
		camel_data_wrapper_get_mime_type_field (inner_wrapper);

	inner_and_outer_content_types_match =
		camel_content_type_is (
			inner_content_type,
			outer_content_type->type,
			outer_content_type->subtype);

	if (!inner_and_outer_content_types_match) {
		CamelStream *mem;
		gboolean success;

		/* Create a message copy in case the inner content
		 * type doesn't match the mime_part's content type,
		 * which can happen for multipart/digest, where it
		 * confuses the formatter on reply, which skips all
		 * rfc822 subparts. */
		mem = camel_stream_mem_new ();
		camel_data_wrapper_write_to_stream_sync (
			CAMEL_DATA_WRAPPER (outer_wrapper), mem, NULL, NULL);

		g_seekable_seek (
			G_SEEKABLE (mem), 0, G_SEEK_SET, NULL, NULL);
		message = camel_mime_message_new ();
		success = camel_data_wrapper_construct_from_stream_sync (
			CAMEL_DATA_WRAPPER (message), mem, NULL, NULL);
		if (!success)
			g_clear_object (&message);

		g_object_unref (mem);
	}

exit:
	if (message == NULL)
		message = g_object_ref (outer_wrapper);

	g_clear_object (&mime_part);

	g_list_free_full (selected, (GDestroyNotify) g_object_unref);

	return message;
}
Esempio n. 14
0
static CamelCipherValidity *
sm_verify(CamelCipherContext *context, CamelMimePart *ipart, CamelException *ex)
{
	NSSCMSDecoderContext *dec;
	NSSCMSMessage *cmsg;
	CamelStreamMem *mem;
	CamelStream *constream = NULL;
	CamelCipherValidity *valid = NULL;
	CamelContentType *ct;
	const char *tmp;
	CamelMimePart *sigpart;
	CamelDataWrapper *dw;

	dw = camel_medium_get_content_object((CamelMedium *)ipart);
	ct = dw->mime_type;

	/* FIXME: we should stream this to the decoder */
	mem = (CamelStreamMem *)camel_stream_mem_new();

	if (camel_content_type_is(ct, "multipart", "signed")) {
		CamelMultipart *mps = (CamelMultipart *)dw;

		tmp = camel_content_type_param(ct, "protocol");
		if (!CAMEL_IS_MULTIPART_SIGNED(mps)
		    || tmp == NULL
		    || (g_ascii_strcasecmp(tmp, context->sign_protocol) != 0
			&& g_ascii_strcasecmp(tmp, "application/pkcs7-signature") != 0)) {
			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
					     _("Cannot verify message signature: Incorrect message format"));
			goto fail;
		}

		constream = camel_multipart_signed_get_content_stream((CamelMultipartSigned *)mps, ex);
		if (constream == NULL)
			goto fail;

		sigpart = camel_multipart_get_part(mps, CAMEL_MULTIPART_SIGNED_SIGNATURE);
		if (sigpart == NULL) {
			camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
					     _("Cannot verify message signature: Incorrect message format"));
			goto fail;
		}
	} else if (camel_content_type_is(ct, "application", "x-pkcs7-mime")) {
		sigpart = ipart;
	} else {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
				     _("Cannot verify message signature: Incorrect message format"));
		goto fail;
	}

	dec = NSS_CMSDecoder_Start(NULL,
				   NULL, NULL, /* content callback     */
				   NULL, NULL, 	/* password callback    */
				   NULL, NULL); /* decrypt key callback */

	camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)sigpart), (CamelStream *)mem);
	(void)NSS_CMSDecoder_Update(dec, (char *) mem->buffer->data, mem->buffer->len);
	cmsg = NSS_CMSDecoder_Finish(dec);
	if (cmsg == NULL) {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed"));
		goto fail;
	}

	valid = sm_verify_cmsg(context, cmsg, constream, ex);

	NSS_CMSMessage_Destroy(cmsg);
fail:
	camel_object_unref(mem);
	if (constream)
		camel_object_unref(constream);

	return valid;
}
static gboolean
empe_mp_digest_parse (EMailParserExtension *extension,
                      EMailParser *parser,
                      CamelMimePart *part,
                      GString *part_id,
                      GCancellable *cancellable,
                      GQueue *out_mail_parts)
{
	CamelMultipart *mp;
	gint i, nparts, len;

	mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);

	if (!CAMEL_IS_MULTIPART (mp))
		return e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.source",
			cancellable, out_mail_parts);

	len = part_id->len;
	nparts = camel_multipart_get_number (mp);
	for (i = 0; i < nparts; i++) {
		CamelMimePart *subpart;
		CamelContentType *ct;
		gchar *cts;

		subpart = camel_multipart_get_part (mp, i);

		if (!subpart)
			continue;

		g_string_append_printf (part_id, ".digest.%d", i);

		ct = camel_mime_part_get_content_type (subpart);

		/* According to RFC this shouldn't happen, but who knows... */
		if (ct && !camel_content_type_is (ct, "message", "rfc822")) {
			cts = camel_content_type_simple (ct);

			e_mail_parser_parse_part_as (
				parser, subpart, part_id, cts,
				cancellable, out_mail_parts);

			g_free (cts);
		} else {
			GQueue work_queue = G_QUEUE_INIT;
			EMailPart *mail_part;
			gboolean wrap_as_attachment;

			e_mail_parser_parse_part_as (
				parser, subpart, part_id, "message/rfc822",
				cancellable, &work_queue);

			mail_part = g_queue_peek_head (&work_queue);

			wrap_as_attachment =
				(mail_part != NULL) &&
				!e_mail_part_get_is_attachment (mail_part);

			/* Force the message to be collapsable */
			if (wrap_as_attachment)
				e_mail_parser_wrap_as_attachment (
					parser, subpart, part_id, &work_queue);

			mail_part = g_queue_peek_head (&work_queue);

			/* Force the message to be expanded */
			if (mail_part != NULL)
				mail_part->force_inline = TRUE;

			e_queue_transfer (&work_queue, out_mail_parts);
		}

		g_string_truncate (part_id, len);
	}

	return TRUE;
}
Esempio n. 16
0
/* TODO: This is suboptimal, but the only other solution is to pass around NSSCMSMessages */
guint32
camel_smime_context_describe_part(CamelSMIMEContext *context, CamelMimePart *part)
{
	guint32 flags = 0;
	CamelContentType *ct;
	const char *tmp;

	if (!part)
		return flags;

	ct = camel_mime_part_get_content_type(part);

	if (camel_content_type_is(ct, "multipart", "signed")) {
		tmp = camel_content_type_param(ct, "protocol");
		if (tmp &&
		    (g_ascii_strcasecmp(tmp, ((CamelCipherContext *)context)->sign_protocol) == 0
		     || g_ascii_strcasecmp(tmp, "application/pkcs7-signature") == 0))
			flags = CAMEL_SMIME_SIGNED;
	} else if (camel_content_type_is(ct, "application", "x-pkcs7-mime")) {
		CamelStreamMem *istream;
		NSSCMSMessage *cmsg;
		NSSCMSDecoderContext *dec;

		/* FIXME: stream this to the decoder incrementally */
		istream = (CamelStreamMem *)camel_stream_mem_new();
		camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)part), (CamelStream *)istream);
		camel_stream_reset((CamelStream *)istream);

		dec = NSS_CMSDecoder_Start(NULL,
					   NULL, NULL,
					   NULL, NULL,	/* password callback    */
					   NULL, NULL); /* decrypt key callback */

		NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len);
		camel_object_unref(istream);

		cmsg = NSS_CMSDecoder_Finish(dec);
		if (cmsg) {
			if (NSS_CMSMessage_IsSigned(cmsg)) {
				printf("message is signed\n");
				flags |= CAMEL_SMIME_SIGNED;
			}

			if (NSS_CMSMessage_IsEncrypted(cmsg)) {
				printf("message is encrypted\n");
				flags |= CAMEL_SMIME_ENCRYPTED;
			}
#if 0
			if (NSS_CMSMessage_ContainsCertsOrCrls(cmsg)) {
				printf("message contains certs or crls\n");
				flags |= CAMEL_SMIME_CERTS;
			}
#endif
			NSS_CMSMessage_Destroy(cmsg);
		} else {
			printf("Message could not be parsed\n");
		}
	}

	return flags;
}
Esempio n. 17
0
static gboolean
empe_message_parse (EMailParserExtension *extension,
                    EMailParser *parser,
                    CamelMimePart *part,
                    GString *part_id,
                    GCancellable *cancellable,
                    GQueue *out_mail_parts)
{
	GQueue work_queue = G_QUEUE_INIT;
	CamelContentType *ct;
	EMailPart *mail_part;
	gchar *mime_type;

	/* Headers */
	e_mail_parser_parse_part_as (
		parser, part, part_id,
		"application/vnd.evolution.headers",
		cancellable, out_mail_parts);

	ct = camel_mime_part_get_content_type (part);
	mime_type = camel_content_type_simple (ct);

	if (camel_content_type_is (ct, "message", "*")) {
		/* get mime type of the content of the message,
		 * instead of using a generic message/rfc822 */
		CamelDataWrapper *content;

		content = camel_medium_get_content (CAMEL_MEDIUM (part));
		if (content) {
			ct = camel_data_wrapper_get_mime_type_field (content);

			g_free (mime_type);
			mime_type = camel_content_type_simple (ct);
		}
	}

	/* Actual message body */

	e_mail_parser_parse_part_as (
		parser, part, part_id, mime_type,
		cancellable, &work_queue);

	/* If the EMailPart representing the message body is marked as an
	 * attachment, wrap it as such so it gets added to the attachment
	 * bar but also set the "force_inline" flag since it doesn't make
	 * sense to collapse the message body if we can render it. */
	mail_part = g_queue_peek_head (&work_queue);
	if (mail_part != NULL && !E_IS_MAIL_PART_ATTACHMENT (mail_part)) {
		if (e_mail_part_get_is_attachment (mail_part)) {
			e_mail_parser_wrap_as_attachment (
				parser, part, part_id, &work_queue);

			mail_part = g_queue_peek_head (&work_queue);

			if (mail_part != NULL)
				mail_part->force_inline = TRUE;
		}
	}

	e_queue_transfer (&work_queue, out_mail_parts);

	g_free (mime_type);

	return TRUE;
}
static gboolean
emqfe_text_plain_format (EMailFormatterExtension *extension,
                         EMailFormatter *formatter,
                         EMailFormatterContext *context,
                         EMailPart *part,
                         GOutputStream *stream,
                         GCancellable *cancellable)
{
	GOutputStream *filtered_stream;
	GOutputStream *temp_stream;
	CamelMimeFilter *filter;
	CamelMimePart *mime_part;
	CamelContentType *type;
	EMailFormatterQuoteContext *qf_context;
	CamelMimeFilterToHTMLFlags text_flags;
	const gchar *format;
	guint32 rgb = 0x737373;

	mime_part = e_mail_part_ref_mime_part (part);
	if (mime_part == NULL)
		return FALSE;

	qf_context = (EMailFormatterQuoteContext *) context;

	text_flags =
		CAMEL_MIME_FILTER_TOHTML_PRE |
		CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
		CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;

	/* XXX Should we define a separate EMailFormatter property
	 *     for using CAMEL_MIME_FILTER_TOHTML_QUOTE_CITATION? */
	if (e_mail_formatter_get_mark_citations (formatter))
		text_flags |= CAMEL_MIME_FILTER_TOHTML_QUOTE_CITATION;

	/* Check for RFC 2646 flowed text. */
	type = camel_mime_part_get_content_type (mime_part);
	if (camel_content_type_is (type, "text", "plain")
	    && (format = camel_content_type_param (type, "format"))
	    && !g_ascii_strcasecmp (format, "flowed"))
		text_flags |= CAMEL_MIME_FILTER_TOHTML_FORMAT_FLOWED;

	filtered_stream = g_object_ref (stream);

	if ((qf_context->qf_flags & E_MAIL_FORMATTER_QUOTE_FLAG_KEEP_SIG) == 0) {
		filter = e_mail_stripsig_filter_new (TRUE);
		temp_stream = camel_filter_output_stream_new (
			filtered_stream, filter);
		g_filter_output_stream_set_close_base_stream (
			G_FILTER_OUTPUT_STREAM (temp_stream), FALSE);
		g_object_unref (filtered_stream);
		filtered_stream = temp_stream;
		g_object_unref (filter);
	}

	filter = camel_mime_filter_tohtml_new (text_flags, rgb);
	temp_stream = camel_filter_output_stream_new (filtered_stream, filter);
	g_filter_output_stream_set_close_base_stream (
		G_FILTER_OUTPUT_STREAM (temp_stream), FALSE);
	g_object_unref (filtered_stream);
	filtered_stream = temp_stream;
	g_object_unref (filter);

	e_mail_formatter_format_text (
		formatter, part, filtered_stream, cancellable);

	g_output_stream_flush (filtered_stream, cancellable, NULL);
	g_object_unref (filtered_stream);

	g_object_unref (mime_part);

	return TRUE;
}
Esempio n. 19
0
static void
fill_model_rec(CamelMimeMessage *msg, CamelMimePart *part, GtkTreeStore *model, GtkTreeIter *parent, GString *name)
{
	CamelDataWrapper *containee;
	int parts, i;
	char *type;
	GtkTreeIter iter;
	int len = name->len;
	CamelContentType *mime;

	containee = camel_medium_get_content_object((CamelMedium *)part);
	if (containee == NULL)
		return;

	mime = ((CamelDataWrapper *)containee)->mime_type;
	type = camel_content_type_simple(mime);

	if (CAMEL_IS_MULTIPART(containee)) {
		gtk_tree_store_append(model, &iter, parent);
		g_string_append_printf(name, ".multipart");
		gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1);

		parts = camel_multipart_get_number((CamelMultipart *)containee);
		for (i = 0; i < parts; i++) {
			CamelMimePart *mpart = camel_multipart_get_part((CamelMultipart *)containee, i);

			g_string_truncate(name, len);
			g_string_append_printf(name, ".%d", i);
			fill_model_rec(msg, mpart, model, &iter, name);
		}
	} else if (CAMEL_IS_MIME_MESSAGE(containee)) {
		gtk_tree_store_append(model, &iter, parent);
		g_string_append_printf(name, ".msg");
		gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1);
		fill_model_rec(msg, (CamelMimePart *)containee, model, &iter, name);
	} else {
		char *filename = NULL;
		const char *ext = NULL, *tmp;
		int save = FALSE;

		gtk_tree_store_append(model, &iter, parent);
		tmp = camel_mime_part_get_filename(part);
		if (tmp) {
			filename = clean_name(tmp);
			ext = strrchr(filename, '.');
		}
		tmp = camel_mime_part_get_disposition(part);
		if (tmp && !strcmp(tmp, "attachment"))
			save = TRUE;

		if (camel_content_type_is(mime, "text", "*")) {
			if (ext == NULL) {
				if ((ext = mime->subtype) == NULL || !strcmp(ext, "plain"))
					ext = "text";
			}
		} else if (camel_content_type_is(mime, "image", "*")) {
			if (ext == NULL) {
				if ((ext = mime->subtype) == NULL)
					ext = "image";
			}
			save = TRUE;
		}

		g_string_append_printf(name, ".%s", ext);
		gtk_tree_store_set(model, &iter, 0, save, 1, type, 2, filename?filename:name->str, 3, filename?NULL:name->str, 4, part, -1);
		g_free(filename);
	}
	g_free(type);

	g_string_truncate(name, len);
}