Пример #1
0
void
format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
			 notmuch_bool_t reply)
{
    /* Any changes to the JSON or S-Expression format should be
     * reflected in the file devel/schemata. */

    InternetAddressList *recipients;
    const char *recipients_string;
    const char *reply_to_string;

    sp->begin_map (sp);

    sp->map_key (sp, "Subject");
    sp->string (sp, g_mime_message_get_subject (message));

    sp->map_key (sp, "From");
    sp->string (sp, g_mime_message_get_sender (message));

    recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
    recipients_string = internet_address_list_to_string (recipients, 0);
    if (recipients_string) {
	sp->map_key (sp, "To");
	sp->string (sp, recipients_string);
    }

    recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
    recipients_string = internet_address_list_to_string (recipients, 0);
    if (recipients_string) {
	sp->map_key (sp, "Cc");
	sp->string (sp, recipients_string);
    }

    recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_BCC);
    recipients_string = internet_address_list_to_string (recipients, 0);
    if (recipients_string) {
	sp->map_key (sp, "Bcc");
	sp->string (sp, recipients_string);
    }

    reply_to_string = g_mime_message_get_reply_to (message);
    if (reply_to_string) {
	sp->map_key (sp, "Reply-To");
	sp->string (sp, reply_to_string);
    }

    if (reply) {
	sp->map_key (sp, "In-reply-to");
	sp->string (sp, g_mime_object_get_header (GMIME_OBJECT (message), "In-reply-to"));

	sp->map_key (sp, "References");
	sp->string (sp, g_mime_object_get_header (GMIME_OBJECT (message), "References"));
    } else {
	sp->map_key (sp, "Date");
	sp->string (sp, g_mime_message_get_date_as_string (message));
    }

    sp->end (sp);
}
Пример #2
0
static MessageData *convert_message(GMimeMessage *message, guint content_option) {
  if (!message)
    return NULL;

  MessageData *md = new_message_data();

  const gchar *message_id = g_mime_message_get_message_id(message);
  if (message_id)
    md->message_id = g_strdup(message_id);

  md->from     = get_from_addresses(message);
  md->reply_to = get_reply_to_addresses(message);
  md->to       = get_to_addresses(message);
  md->cc       = get_cc_addresses(message);
  md->bcc      = get_bcc_addresses(message);

  const gchar *subject = g_mime_message_get_subject(message);
  if (subject)
    md->subject = g_strdup(subject);

  md->date = g_mime_message_get_date_as_string(message);

  const gchar *in_reply_to = g_mime_object_get_header(GMIME_OBJECT (message), "In-Reply-To");
  if (in_reply_to) {
    gchar *in_reply_to_str = g_mime_utils_header_decode_text(in_reply_to);
    md->in_reply_to = g_mime_references_decode(in_reply_to_str);
    g_free(in_reply_to_str);
  }

  const gchar *references = g_mime_object_get_header(GMIME_OBJECT (message), "References");
  if (references) {
    gchar *references_str = g_mime_utils_header_decode_text(references);
    md->references = g_mime_references_decode(references_str);
    g_free(references_str);
  }

  if (content_option) {
    PartCollectorData *pc = collect_parts(message, content_option);

    if (pc->text_part)
      md->text = get_body(pc->text_part, (content_option != COLLECT_RAW_CONTENT), NULL);

    if (pc->html_part)
      md->html = get_body(pc->html_part, (content_option != COLLECT_RAW_CONTENT), pc->inlines);

    md->attachments = get_attachments(pc);

    free_part_collector_data(pc);
  }

  return md;
}
Пример #3
0
static gchar*
get_refs_str (GMimeMessage *msg)
{
    const gchar *str;
    const GMimeReferences *cur;
    GMimeReferences *mime_refs;
    gchar *rv;

    str = g_mime_object_get_header (GMIME_OBJECT(msg), "References");
    if (!str)
        return NULL;

    mime_refs = g_mime_references_decode (str);
    for (rv = NULL, cur = mime_refs; cur;
            cur = g_mime_references_get_next(cur)) {

        const char* msgid;
        msgid = g_mime_references_get_message_id (cur);
        rv = g_strdup_printf ("%s%s%s",
                              rv ? rv : "",
                              rv ? "," : "",
                              msgid);
    }
    g_mime_references_free (mime_refs);

    return rv;
}
Пример #4
0
void
format_headers_json (const void *ctx, GMimeMessage *message, notmuch_bool_t reply)
{
    void *local = talloc_new (ctx);
    InternetAddressList *recipients;
    const char *recipients_string;

    printf ("{%s: %s",
            json_quote_str (local, "Subject"),
            json_quote_str (local, g_mime_message_get_subject (message)));
    printf (", %s: %s",
            json_quote_str (local, "From"),
            json_quote_str (local, g_mime_message_get_sender (message)));
    recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
    recipients_string = internet_address_list_to_string (recipients, 0);
    if (recipients_string)
        printf (", %s: %s",
                json_quote_str (local, "To"),
                json_quote_str (local, recipients_string));
    recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
    recipients_string = internet_address_list_to_string (recipients, 0);
    if (recipients_string)
        printf (", %s: %s",
                json_quote_str (local, "Cc"),
                json_quote_str (local, recipients_string));

    if (reply) {
        printf (", %s: %s",
                json_quote_str (local, "In-reply-to"),
                json_quote_str (local, g_mime_object_get_header (GMIME_OBJECT (message), "In-reply-to")));

        printf (", %s: %s",
                json_quote_str (local, "References"),
                json_quote_str (local, g_mime_object_get_header (GMIME_OBJECT (message), "References")));
    } else {
        printf (", %s: %s",
                json_quote_str (local, "Date"),
                json_quote_str (local, g_mime_message_get_date_as_string (message)));
    }

    printf ("}");

    talloc_free (local);
}
static gboolean
is_spam (GMimeMessage *mime_message)
{
  const char *spam;

  g_return_val_if_fail(GMIME_IS_MESSAGE(mime_message), FALSE);

  /* SpamAssassin */
  spam = g_mime_object_get_header(mime_message, "X-Spam-Status");
  if (spam && mn_ascii_str_case_has_prefix(spam, "yes"))
    return TRUE;

  /* bogofilter */
  spam = g_mime_object_get_header(mime_message, "X-Bogosity");
  if (spam && mn_ascii_str_case_has_prefix(spam, "yes"))
    return TRUE;

  return FALSE;
}
Пример #6
0
static void
format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart *part)
{
    const char *content_charset = g_mime_object_get_content_type_parameter (meta, "charset");
    const char *cte = g_mime_object_get_header (meta, "content-transfer-encoding");
    GMimeDataWrapper *wrapper = g_mime_part_get_content_object (part);
    GMimeStream *stream = g_mime_data_wrapper_get_stream (wrapper);
    ssize_t content_length = g_mime_stream_length (stream);

    if (content_charset != NULL) {
	sp->map_key (sp, "content-charset");
	sp->string (sp, content_charset);
    }
    if (cte != NULL) {
	sp->map_key (sp, "content-transfer-encoding");
	sp->string (sp, cte);
    }
    if (content_length >= 0) {
	sp->map_key (sp, "content-length");
	sp->integer (sp, content_length);
    }
}
Пример #7
0
static void
test_address_sync (void)
{
	const char *raw_value, *value;
	InternetAddress *addr, *ia;
	InternetAddressList *list;
	GMimeHeaderList *headers;
	GMimeMessage *message;
	GMimeObject *object;
	GMimeHeader *header;
	
	message = g_mime_message_new (TRUE);
	list = g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO);
	object = (GMimeObject *) message;
	headers = object->headers;
	
	testsuite_check ("address header synchronization");
	try {
		/* first, check that the To recipients are empty */
		if (list == NULL || internet_address_list_length (list) != 0)
			throw (exception_new ("unexpected initial internet address list"));
		
		/* now check that the initial header value is null */
		if ((value = g_mime_object_get_header (object, "To")) != NULL)
			throw (exception_new ("unexpected initial value"));
		
		header = g_mime_header_list_get_header (headers, "To");
		if ((raw_value = g_mime_header_get_raw_value (header)) != NULL)
			throw (exception_new ("unexpected initial raw_value"));
		
		/* now try adding an address */
		addr = internet_address_mailbox_new ("Tester", "*****@*****.**");
		internet_address_list_add (list, addr);
		
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after adding recipient"));
		if (strcmp ("Tester <*****@*****.**>", value) != 0)
			throw (exception_new ("unexpected address list header after adding recipient"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after adding recipient"));
		if (strcmp (" Tester <*****@*****.**>\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after adding recipient: %s", raw_value));
		
		/* now let's try changing the address name to make sure signals properly chain up */
		internet_address_set_name (addr, "Eva Lucy-Ann Tester");
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after changing name"));
		if (strcmp ("Eva Lucy-Ann Tester <*****@*****.**>", value) != 0)
			throw (exception_new ("unexpected address list header after changing name: %s", value));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after changing name"));
		if (strcmp (" Eva Lucy-Ann Tester <*****@*****.**>\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after changing name"));
		
		/* now let's try changing the address mailbox... */
		internet_address_mailbox_set_addr ((InternetAddressMailbox *) addr, "*****@*****.**");
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after changing mailbox"));
		if (strcmp ("Eva Lucy-Ann Tester <*****@*****.**>", value) != 0)
			throw (exception_new ("unexpected address list header after changing mailbox"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after changing mailbox"));
		if (strcmp (" Eva Lucy-Ann Tester <*****@*****.**>\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after changing mailbox"));
		
		/* now let's try inserting a group address */
		g_object_unref (addr);
		addr = internet_address_group_new ("Group");
		internet_address_list_insert (list, 0, addr);
		
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after inserting group"));
		if (strcmp ("Group: ;, Eva Lucy-Ann Tester <*****@*****.**>", value) != 0)
			throw (exception_new ("unexpected address list header after inserting group"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after inserting group"));
		if (strcmp (" Group: ;, Eva Lucy-Ann Tester <*****@*****.**>\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after inserting group"));
		
		/* now let's try removing the original recipient */
		internet_address_list_remove_at (list, 1);
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after removing recipient"));
		if (strcmp ("Group: ;", value) != 0)
			throw (exception_new ("unexpected address list header after removing recipient"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after removing recipient"));
		if (strcmp (" Group: ;\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after removing recipient"));
		
		/* now let's try adding an address to the group... */
		ia = internet_address_mailbox_new ("Tester", "*****@*****.**");
		internet_address_list_add (((InternetAddressGroup *) addr)->members, ia);
		if (!(value = g_mime_object_get_header (object, "To")))
			throw (exception_new ("address list header unexpectedly null after adding addr to group"));
		if (strcmp ("Group: Tester <*****@*****.**>;", value) != 0)
			throw (exception_new ("unexpected address list header after adding addr to group"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after adding addr to group"));
		if (strcmp (" Group: Tester <*****@*****.**>;\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after adding addr to group"));
		
		/* let's try this in reverse... set the header value and make sure InternetAddressList gets updated */
		g_mime_object_set_header (object, "To", "[email protected] (=?iso-8859-1?q?Fran=E7ois?= Pons)", NULL);
		if (internet_address_list_length (list) != 1)
			throw (exception_new ("unexpected number of addresses in addrlist after setting header value"));
		ia = internet_address_list_get_address (list, 0);
		value = internet_address_get_name (ia);
		if (strcmp ("Fran\xc3\xa7ois Pons", value) != 0)
			throw (exception_new ("unexpected name after setting header value"));
		value = internet_address_mailbox_get_addr ((InternetAddressMailbox *) ia);
		if (strcmp ("*****@*****.**", value) != 0)
			throw (exception_new ("unexpected addr after setting header value"));
		header = g_mime_header_list_get_header (headers, "To");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("raw_value is null after setting header value"));
		if (strcmp (" =?iso-8859-1?q?Fran=E7ois?= Pons <*****@*****.**>\n", raw_value) != 0)
			throw (exception_new ("unexpected raw_value after setting header value: %s", raw_value));
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("address header not synchronized: %s", ex->message);
	} finally;
	
	g_object_unref (message);
}
Пример #8
0
static void
test_disposition_sync (void)
{
	GMimeContentDisposition *disposition;
	const char *raw_value, *value;
	GMimeHeaderList *headers;
	GMimeParamList *params;
	GMimeObject *object;
	GMimeHeader *header;
	GMimePart *part;
	
	object = (GMimeObject *) (part = g_mime_part_new ());
	headers = g_mime_object_get_header_list (object);
	
	testsuite_check ("content-disposition synchronization");
	try {
		g_mime_object_set_disposition (object, "attachment");
		
		/* first, check that the current Content-Disposition header
		 * value is "application/octet-stream" as expected */
		if (!(value = g_mime_object_get_header (object, "Content-Disposition")))
			throw (exception_new ("initial content-disposition header was unexpectedly null"));
		if (strcmp ("attachment", value) != 0)
			throw (exception_new ("initial content-disposition header had unexpected value: %s", value));
		header = g_mime_header_list_get_header (headers, "Content-Disposition");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("initial content-disposition raw_value was unexpectedly null"));
		if (strcmp (" attachment\n", raw_value) != 0)
			throw (exception_new ("initial content-disposition raw_value had unexpected value: %s", raw_value));
		
		/* now change the content-disposition's disposition */
		disposition = g_mime_object_get_content_disposition (object);
		g_mime_content_disposition_set_disposition (disposition, "inline");
		if (!(value = g_mime_object_get_header (object, "Content-Disposition")))
			throw (exception_new ("content-disposition header was unexpectedly null after changing type"));
		if (strcmp ("inline", value) != 0)
			throw (exception_new ("content-disposition header had unexpected value after changing type"));
		header = g_mime_header_list_get_header (headers, "Content-Disposition");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-disposition raw_value was unexpectedly null after changing type"));
		if (strcmp (" inline\n", raw_value) != 0)
			throw (exception_new ("content-disposition raw_value had unexpected value after changing type: %s", raw_value));
		
		/* now change the content-disposition's parameters by setting a param */
		g_mime_content_disposition_set_parameter (disposition, "filename", "hello.txt");
		if (!(value = g_mime_object_get_header (object, "Content-Disposition")))
			throw (exception_new ("content-disposition header was unexpectedly null after setting a param"));
		if (strcmp ("inline; filename=hello.txt", value) != 0)
			throw (exception_new ("content-disposition header had unexpected value after setting a param"));
		header = g_mime_header_list_get_header (headers, "Content-Disposition");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-disposition raw_value was unexpectedly null after setting a param"));
		if (strcmp (" inline; filename=hello.txt\n", raw_value) != 0)
			throw (exception_new ("content-disposition raw_value had unexpected value after setting a param: %s", raw_value));
		
		/* now change the content-disposition's parameters by clearing the params */
		params = g_mime_content_disposition_get_parameters (disposition);
		g_mime_param_list_clear (params);
		if (!(value = g_mime_object_get_header (object, "Content-Disposition")))
			throw (exception_new ("content-disposition header was unexpectedly null after clearing params"));
		if (strcmp ("inline", value) != 0)
			throw (exception_new ("content-disposition header had unexpected value after clearing params"));
		header = g_mime_header_list_get_header (headers, "Content-Disposition");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-disposition raw_value was unexpectedly null after clearing params"));
		if (strcmp (" inline\n", raw_value) != 0)
			throw (exception_new ("content-disposition raw_value had unexpected value after clearing params: %s", raw_value));
		
		/* let's try this in reverse... set the header value and make sure GMimeContentDisposition gets updated */
		header = g_mime_header_list_get_header_at (headers, 1);
		g_mime_header_set_value (header, NULL, "attachment; filename=xyz", NULL);
		disposition = g_mime_object_get_content_disposition (object);
		if (!g_mime_content_disposition_is_attachment (disposition))
			throw (exception_new ("GMimeContentDisposition object was not updated"));
		header = g_mime_header_list_get_header (headers, "Content-Disposition");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-disposition raw_value was unexpectedly null after setting value"));
		if (strcmp (" attachment; filename=xyz\n", raw_value) != 0)
			throw (exception_new ("content-disposition raw_value had unexpected value after setting value: %s", raw_value));
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("content-disposition header not synchronized: %s", ex->message);
	} finally;
	
	g_object_unref (part);
}
Пример #9
0
static void
test_content_type_sync (void)
{
	const char *raw_value, *value;
	GMimeHeaderList *headers;
	GMimeContentType *type;
	GMimeParamList *params;
	GMimeObject *object;
	GMimeHeader *header;
	GMimePart *part;
	
	object = (GMimeObject *) (part = g_mime_part_new ());
	headers = g_mime_object_get_header_list (object);
	
	testsuite_check ("content-type synchronization");
	try {
		/* first, check that the current Content-Type header
		 * value is "application/octet-stream" as expected */
		if (!(value = g_mime_object_get_header (object, "Content-Type")))
			throw (exception_new ("initial content-type header was unexpectedly null"));
		
		if (strcmp ("application/octet-stream", value) != 0)
			throw (exception_new ("initial content-type header had unexpected value: %s", value));
		
		/* now change the content-type's media type... */
		type = g_mime_object_get_content_type (object);
		g_mime_content_type_set_media_type (type, "text");
		if (!(value = g_mime_object_get_header (object, "Content-Type")))
			throw (exception_new ("content-type header was unexpectedly null after changing type"));
		if (strcmp ("text/octet-stream", value) != 0)
			throw (exception_new ("content-type header had unexpected value after changing type"));
		header = g_mime_header_list_get_header (headers, "Content-Type");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-type raw_value was unexpectedly null after changing type"));
		if (strcmp (" text/octet-stream\n", raw_value) != 0)
			throw (exception_new ("content-type raw_value had unexpected value after changing type"));
		
		/* now change the content-type's media subtype... */
		g_mime_content_type_set_media_subtype (type, "plain");
		if (!(value = g_mime_object_get_header (object, "Content-Type")))
			throw (exception_new ("content-type header was unexpectedly null after changing subtype"));
		if (strcmp ("text/plain", value) != 0)
			throw (exception_new ("content-type header had unexpected value after changing subtype"));
		header = g_mime_header_list_get_header (headers, "Content-Type");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-type raw_value was unexpectedly null after changing subtype"));
		if (strcmp (" text/plain\n", raw_value) != 0)
			throw (exception_new ("content-type raw_value had unexpected value after changing subtype"));
		
		/* now change the content-type's parameters by setting a param */
		g_mime_content_type_set_parameter (type, "format", "flowed");
		if (!(value = g_mime_object_get_header (object, "Content-Type")))
			throw (exception_new ("content-type header was unexpectedly null after setting a param"));
		if (strcmp ("text/plain; format=flowed", value) != 0)
			throw (exception_new ("content-type header had unexpected value after setting a param"));
		header = g_mime_header_list_get_header (headers, "Content-Type");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-type raw_value was unexpectedly null after setting a param"));
		if (strcmp (" text/plain; format=flowed\n", raw_value) != 0)
			throw (exception_new ("content-type raw_value had unexpected value after setting a param"));
		
		/* now change the content-type's parameters by clearing the params */
		params = g_mime_content_type_get_parameters (type);
		g_mime_param_list_clear (params);
		if (!(value = g_mime_object_get_header (object, "Content-Type")))
			throw (exception_new ("content-type header was unexpectedly null after clearing params"));
		if (strcmp ("text/plain", value) != 0)
			throw (exception_new ("content-type header had unexpected value after clearing params"));
		header = g_mime_header_list_get_header (headers, "Content-Type");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-type raw_value was unexpectedly null after clearing params"));
		if (strcmp (" text/plain\n", raw_value) != 0)
			throw (exception_new ("content-type raw_value had unexpected value after clearing params"));
		
		/* let's try this in reverse... set the header value and make sure GMimeContentType gets updated */
		header = g_mime_header_list_get_header_at (headers, 0);
		g_mime_header_set_value (header, NULL, "text/html; charset=utf-8", NULL);
		type = g_mime_object_get_content_type (object);
		if (!g_mime_content_type_is_type (type, "text", "html"))
			throw (exception_new ("GMimeContentType object was not updated"));
		header = g_mime_header_list_get_header (headers, "Content-Type");
		if (!(raw_value = g_mime_header_get_raw_value (header)))
			throw (exception_new ("content-type raw_value was unexpectedly null after setting value"));
		if (strcmp (" text/html; charset=utf-8\n", raw_value) != 0)
			throw (exception_new ("content-type raw_value had unexpected value after setting value"));
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("content-type header not synchronized: %s", ex->message);
	} finally;
	
	g_object_unref (part);
}
Пример #10
0
notmuch_status_t
_notmuch_message_crypto_potential_payload (_notmuch_message_crypto_t *msg_crypto, GMimeObject *payload, GMimeObject *parent, int childnum)
{
    const char *protected_headers = NULL;
    const char *forwarded = NULL;
    const char *subject = NULL;

    if (!msg_crypto || !payload)
	return NOTMUCH_STATUS_NULL_POINTER;

    /* only fire on the first payload part encountered */
    if (msg_crypto->payload_encountered)
	return NOTMUCH_STATUS_SUCCESS;

    /* the first child of multipart/encrypted that matches the
     * encryption protocol should be "control information" metadata,
     * not payload.  So we skip it. (see
     * https://tools.ietf.org/html/rfc1847#page-8) */
    if (parent && GMIME_IS_MULTIPART_ENCRYPTED (parent) && childnum == GMIME_MULTIPART_ENCRYPTED_VERSION) {
	const char *enc_type = g_mime_object_get_content_type_parameter (parent, "protocol");
	GMimeContentType *ct = g_mime_object_get_content_type (payload);
	if (ct && enc_type) {
	    const char *part_type = g_mime_content_type_get_mime_type (ct);
	    if (part_type && strcmp (part_type, enc_type) == 0)
		return NOTMUCH_STATUS_SUCCESS;
	}
    }

    msg_crypto->payload_encountered = true;

    /* don't bother recording anything if there is no cryptographic
     * envelope: */
    if ((msg_crypto->decryption_status != NOTMUCH_MESSAGE_DECRYPTED_FULL) &&
	(msg_crypto->sig_list == NULL))
	return NOTMUCH_STATUS_SUCCESS;

    /* Verify that this payload has headers that are intended to be
     * exported to the larger message: */

    /* Consider a payload that uses Alexei Melinkov's forwarded="no" for
     * message/global or message/rfc822:
     * https://tools.ietf.org/html/draft-melnikov-smime-header-signing-05#section-4 */
    forwarded = g_mime_object_get_content_type_parameter (payload, "forwarded");
    if (GMIME_IS_MESSAGE_PART (payload) && forwarded && strcmp (forwarded, "no") == 0) {
	GMimeMessage *message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (payload));
	subject = g_mime_message_get_subject (message);
	/* FIXME: handle more than just Subject: at some point */
    } else {
	/* Consider "memoryhole"-style protected headers as practiced by Enigmail and K-9 */
	protected_headers = g_mime_object_get_content_type_parameter (payload, "protected-headers");
	if (protected_headers && strcasecmp("v1", protected_headers) == 0)
	    subject = g_mime_object_get_header (payload, "Subject");
	/* FIXME: handle more than just Subject: at some point */
    }

    if (subject) {
	if (msg_crypto->payload_subject)
	    talloc_free (msg_crypto->payload_subject);
	msg_crypto->payload_subject = talloc_strdup (msg_crypto, subject);
    }

    return NOTMUCH_STATUS_SUCCESS;
}
Пример #11
0
MNMessage *
mn_message_new_from_mime_message_full (GType type,
				       MNMailbox *mailbox,
				       GMimeMessage *mime_message,
				       const char *mid,
				       const char *uri,
				       MNMessageFlags flags,
				       gboolean handle_status)
{
  MNMessage *message;
  const char *id;
  time_t sent_time;
  const char *from;
  const char *subject;
  char *decoded_from;
  char *decoded_subject;

  g_return_val_if_fail(type != 0, NULL);
  g_return_val_if_fail(MN_IS_MAILBOX(mailbox), NULL);
  g_return_val_if_fail(GMIME_IS_MESSAGE(mime_message), NULL);

  if (is_spam(mime_message))
    return NULL;

  if (handle_status)
    {
      const char *status;

      status = g_mime_object_get_header(mime_message, "Status");
      if (status && strchr(status, 'R'))
	return NULL;		/* the message was read */
      else if (status && strchr(status, 'O'))
	flags &= ~MN_MESSAGE_NEW;
      else
	flags |= MN_MESSAGE_NEW;
    }

  id = g_mime_message_get_message_id(mime_message);
  g_mime_message_get_date(mime_message, &sent_time, NULL);
  from = g_mime_message_get_sender(mime_message);
  subject = g_mime_message_get_subject(mime_message);

  decoded_from = from ? g_mime_utils_header_decode_text(from) : NULL;
  decoded_subject = subject ? g_mime_utils_header_decode_text(subject) : NULL;

  message = g_object_new(type,
			 MN_MESSAGE_PROP_MAILBOX(mailbox),
			 MN_MESSAGE_PROP_SENT_TIME(sent_time),
			 MN_MESSAGE_PROP_ID((char *) id),
			 MN_MESSAGE_PROP_MID((char *) mid),
			 MN_MESSAGE_PROP_FROM(decoded_from),
			 MN_MESSAGE_PROP_SUBJECT(decoded_subject),
			 MN_MESSAGE_PROP_URI((char *) uri),
			 MN_MESSAGE_PROP_FLAGS(flags),
			 NULL);

  g_free(decoded_from);
  g_free(decoded_subject);

  return message;
}