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); }
/* 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; }
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; }
/** * * "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; }
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); } } } }
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); }
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); }
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; }
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; }
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; }
/* 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; }
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; }
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); }