Esempio n. 1
0
static void
show_reply_headers (GMimeMessage *message)
{
    GMimeStream *stream_stdout = NULL;

    stream_stdout = g_mime_stream_file_new (stdout);
    if (stream_stdout) {
	g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
	/* Output RFC 2822 formatted (and RFC 2047 encoded) headers. */
	g_mime_object_write_to_stream (GMIME_OBJECT(message), stream_stdout);
	g_object_unref(stream_stdout);
    }
}
Esempio n. 2
0
static void
mime_foreach_callback (GMimeObject * parent,
	GMimeObject * part,
	gpointer user_data)
{
	GMimeContentType *type;

	if (GMIME_IS_MESSAGE_PART (part)) {
		/* message/rfc822 or message/news */
		GMimeMessage *message;

		/* g_mime_message_foreach_part() won't descend into
			   child message parts, so if we want to count any
			   subparts of this child message, we'll have to call
			   g_mime_message_foreach_part() again here. */
		rspamd_printf ("got message part %p: parent: %p\n",
						part, parent);
		message = g_mime_message_part_get_message ((GMimeMessagePart *) part);
		g_mime_message_foreach (message, mime_foreach_callback, part);
	}
	else if (GMIME_IS_MULTIPART (part)) {
		type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (
						part));
		rspamd_printf ("got multipart part %p, boundary: %s: parent: %p, type: %s/%s\n",
					part, g_mime_multipart_get_boundary (GMIME_MULTIPART(part)),
					parent,
					g_mime_content_type_get_media_type (type),
					g_mime_content_type_get_media_subtype (type));
	}
	else {
		type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (
				part));
		rspamd_printf ("got normal part %p, parent: %p, type: %s/%s\n",
				part,
				parent,
				g_mime_content_type_get_media_type (type),
				g_mime_content_type_get_media_subtype (type));
	}
}
Esempio n. 3
0
static void fold_to(GSList** stack, guint level)
{
    guint min_level = level ? level : 1;
    while ( g_slist_length(*stack) > min_level ) {
        /* pop and add to top */
        GSList*      top = *stack;
        GMimeObject* part = GMIME_OBJECT(top->data);
        

        if ( GMIME_IS_MESSAGE(part) ) {
            GMimeMessagePart* mgp = g_mime_message_part_new_with_message(
                "rfc822",
                GMIME_MESSAGE(part));
            part = GMIME_OBJECT(mgp);
        }

        *stack = g_slist_remove_link(*stack, top);

        add_part(stack, part);
        g_slist_free(top);
    }
}
Esempio n. 4
0
static void
show_message_part (mime_node_t *node,
                   show_message_state_t *state,
                   const notmuch_show_format_t *format,
                   int first)
{
    /* Formatters expect the envelope for embedded message parts */
    GMimeObject *part = node->envelope_part ?
                        GMIME_OBJECT (node->envelope_part) : node->part;
    int i;

    if (!first)
        fputs (format->part_sep, stdout);

    /* Format this part */
    if (format->part_start)
        format->part_start (part, &(state->part_count));

    if (node->decrypt_attempted && format->part_encstatus)
        format->part_encstatus (node->decrypt_success);

    if (node->verify_attempted && format->part_sigstatus)
#ifdef GMIME_ATLEAST_26
        format->part_sigstatus (node->sig_list);
#else
        format->part_sigstatus (node->sig_validity);
#endif

    format->part_content (part);

    if (node->envelope_part) {
        fputs (format->header_start, stdout);
        if (format->header_message_part)
            format->header_message_part (GMIME_MESSAGE (node->part));
        fputs (format->header_end, stdout);

        fputs (format->body_start, stdout);
    }

    /* Recurse over the children */
    state->part_count += 1;
    for (i = 0; i < node->nchildren; i++)
        show_message_part (mime_node_child (node, i), state, format, i == 0);

    /* Finish this part */
    if (node->envelope_part)
        fputs (format->body_end, stdout);

    if (format->part_end)
        format->part_end (part);
}
Esempio n. 5
0
/* Write a MIME text part out to the given stream.
 *
 * If (flags & NOTMUCH_SHOW_TEXT_PART_REPLY), this prepends "> " to
 * each output line.
 *
 * Both line-ending conversion (CRLF->LF) and charset conversion ( ->
 * UTF-8) will be performed, so it is inappropriate to call this
 * function with a non-text part. Doing so will trigger an internal
 * error.
 */
void
show_text_part_content (GMimeObject *part, GMimeStream *stream_out,
                        notmuch_show_text_part_flags flags)
{
    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
    GMimeStream *stream_filter = NULL;
    GMimeDataWrapper *wrapper;
    const char *charset;

    if (! g_mime_content_type_is_type (content_type, "text", "*"))
        INTERNAL_ERROR ("Illegal request to format non-text part (%s) as text.",
                        g_mime_content_type_to_string (content_type));

    if (stream_out == NULL)
        return;

    stream_filter = g_mime_stream_filter_new (stream_out);
    g_mime_stream_filter_add(GMIME_STREAM_FILTER (stream_filter),
                             g_mime_filter_crlf_new (FALSE, FALSE));

    charset = g_mime_object_get_content_type_parameter (part, "charset");
    if (charset) {
        GMimeFilter *charset_filter;
        charset_filter = g_mime_filter_charset_new (charset, "UTF-8");
        /* This result can be NULL for things like "unknown-8bit".
         * Don't set a NULL filter as that makes GMime print
         * annoying assertion-failure messages on stderr. */
        if (charset_filter) {
            g_mime_stream_filter_add (GMIME_STREAM_FILTER (stream_filter),
                                      charset_filter);
            g_object_unref (charset_filter);
        }

    }

    if (flags & NOTMUCH_SHOW_TEXT_PART_REPLY) {
        GMimeFilter *reply_filter;
        reply_filter = g_mime_filter_reply_new (TRUE);
        if (reply_filter) {
            g_mime_stream_filter_add (GMIME_STREAM_FILTER (stream_filter),
                                      reply_filter);
            g_object_unref (reply_filter);
        }
    }

    wrapper = g_mime_part_get_content_object (GMIME_PART (part));
    if (wrapper && stream_filter)
        g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
    if (stream_filter)
        g_object_unref(stream_filter);
}
Esempio n. 6
0
/**
 * g_mime_part_new:
 *
 * Creates a new MIME Part object with a default content-type of
 * text/plain.
 *
 * Returns: an empty MIME Part object with a default content-type of
 * text/plain.
 **/
GMimePart *
g_mime_part_new (void)
{
	GMimeContentType *content_type;
	GMimePart *mime_part;
	
	mime_part = g_object_newv (GMIME_TYPE_PART, 0, NULL);
	
	content_type = g_mime_content_type_new ("text", "plain");
	g_mime_object_set_content_type (GMIME_OBJECT (mime_part), content_type);
	g_object_unref (content_type);
	
	return mime_part;
}
Esempio n. 7
0
/**
 * g_mime_multipart_new_with_subtype:
 * @subtype: content-type subtype
 *
 * Creates a new MIME multipart object with a content-type of
 * multipart/@subtype.
 *
 * Returns: an empty MIME multipart object with a content-type of
 * multipart/@subtype.
 **/
GMimeMultipart *
g_mime_multipart_new_with_subtype (const char *subtype)
{
	GMimeContentType *content_type;
	GMimeMultipart *multipart;
	
	multipart = g_object_newv (GMIME_TYPE_MULTIPART, 0, NULL);
	
	content_type = g_mime_content_type_new ("multipart", subtype ? subtype : "mixed");
	g_mime_object_set_content_type (GMIME_OBJECT (multipart), content_type);
	g_object_unref (content_type);
	
	return multipart;
}
Esempio n. 8
0
/**
 * g_mime_part_new_with_type:
 * @type: content-type string
 * @subtype: content-subtype string
 *
 * Creates a new MIME Part with a sepcified type.
 *
 * Returns: an empty MIME Part object with the specified content-type.
 **/
GMimePart *
g_mime_part_new_with_type (const char *type, const char *subtype)
{
	GMimeContentType *content_type;
	GMimePart *mime_part;
	
	mime_part = g_object_newv (GMIME_TYPE_PART, 0, NULL);
	
	content_type = g_mime_content_type_new (type, subtype);
	g_mime_object_set_content_type (GMIME_OBJECT (mime_part), content_type);
	g_object_unref (content_type);
	
	return mime_part;
}
Esempio n. 9
0
static void
reply_part_content (GMimeObject *part)
{
    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
    GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);

    if (g_mime_content_type_is_type (content_type, "text", "*") &&
	!g_mime_content_type_is_type (content_type, "text", "html"))
    {
	GMimeStream *stream_stdout = NULL, *stream_filter = NULL;
	GMimeDataWrapper *wrapper;
	const char *charset;

	charset = g_mime_object_get_content_type_parameter (part, "charset");
	stream_stdout = g_mime_stream_file_new (stdout);
	if (stream_stdout) {
	    g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
	    stream_filter = g_mime_stream_filter_new(stream_stdout);
	    if (charset) {
		g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),
					 g_mime_filter_charset_new(charset, "UTF-8"));
	    }
	}
	g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),
				 g_mime_filter_reply_new(TRUE));
	wrapper = g_mime_part_get_content_object (GMIME_PART (part));
	if (wrapper && stream_filter)
	    g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
	if (stream_filter)
	    g_object_unref(stream_filter);
	if (stream_stdout)
	    g_object_unref(stream_stdout);
    }
    else
    {
	if (disposition &&
	    strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
	{
	    const char *filename = g_mime_part_get_filename (GMIME_PART (part));
	    printf ("Attachment: %s (%s)\n", filename,
		    g_mime_content_type_to_string (content_type));
	}
	else
	{
	    printf ("Non-text part: %s\n",
		    g_mime_content_type_to_string (content_type));
	}
    }
}
Esempio n. 10
0
static void add_part(GSList** stack, GMimeObject* p)
{
    GMimeObject* top_part = GMIME_OBJECT((*stack)->data);

    if ( GMIME_IS_MESSAGE(top_part) ) {
        GMimeMessage* m = GMIME_MESSAGE(top_part);
        GMimeObject*  msg_part = g_mime_message_get_mime_part(m);
        GMimeObject*  add_part = p;
        if ( msg_part ) {
            add_part = add_part_to_existing(msg_part, p);
        }
        
        g_mime_message_set_mime_part(m, add_part);
    } else {
        (*stack)->data = add_part_to_existing(top_part, p);
    }    
}
Esempio n. 11
0
static GMimeObject* add_part_to_existing(GMimeObject* mp, GMimeObject* p)
{
    GMimeObject* rv = mp;
    /* there was a previous part, switch to multipart or just add if we already switched */
    /* g_debug("mp=%p (%s), p=%p (%s)", mp, G_OBJECT_TYPE_NAME(mp), p, G_OBJECT_TYPE_NAME(p)); */
    if ( GMIME_IS_MULTIPART(mp) ) {
        g_mime_multipart_add(GMIME_MULTIPART(mp), p);
    } else {
        GMimeMultipart* mlp = g_mime_multipart_new();

        g_mime_multipart_add(mlp, mp);
        g_mime_multipart_add(mlp, p);
        rv = GMIME_OBJECT(mlp);
    }

    return rv;
}
Esempio n. 12
0
static void
show_reply_headers (GMimeMessage *message)
{
    GMimeStream *stream_stdout = NULL, *stream_filter = NULL;

    stream_stdout = g_mime_stream_file_new (stdout);
    if (stream_stdout) {
	g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
	stream_filter = g_mime_stream_filter_new(stream_stdout);
	if (stream_filter) {
		g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),
					 g_mime_filter_headers_new());
		g_mime_object_write_to_stream(GMIME_OBJECT(message), stream_filter);
		g_object_unref(stream_filter);
	}
	g_object_unref(stream_stdout);
    }
}
Esempio n. 13
0
static void
format_part_content_json (GMimeObject *part)
{
    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
    GMimeStream *stream_memory = g_mime_stream_mem_new ();
    const char *cid = g_mime_object_get_content_id (part);
    void *ctx = talloc_new (NULL);
    GByteArray *part_content;

    printf (", \"content-type\": %s",
	    json_quote_str (ctx, g_mime_content_type_to_string (content_type)));

    if (cid != NULL)
	    printf(", \"content-id\": %s", json_quote_str (ctx, cid));

    if (GMIME_IS_PART (part))
    {
	const char *filename = g_mime_part_get_filename (GMIME_PART (part));
	if (filename)
	    printf (", \"filename\": %s", json_quote_str (ctx, filename));
    }

    if (g_mime_content_type_is_type (content_type, "text", "*") &&
	!g_mime_content_type_is_type (content_type, "text", "html"))
    {
	show_text_part_content (part, stream_memory);
	part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (stream_memory));

	printf (", \"content\": %s", json_quote_chararray (ctx, (char *) part_content->data, part_content->len));
    }
    else if (g_mime_content_type_is_type (content_type, "multipart", "*"))
    {
	printf (", \"content\": [");
    }
    else if (g_mime_content_type_is_type (content_type, "message", "rfc822"))
    {
	printf (", \"content\": [{");
    }

    talloc_free (ctx);
    if (stream_memory)
	g_object_unref (stream_memory);
}
Esempio n. 14
0
parsed_article *parse_file(const char *file_name) {
  static parsed_article pa;
  GMimeStream *stream;
  GMimeMessage *msg = NULL;
  int offset;
  int file;

  printf("%s\n", file_name);

  if ((file = open(file_name, O_RDONLY|O_STREAMING)) == -1) {
    fprintf(stderr, "Can't open %s\n", file_name);
    return NULL;
  }

  stream = g_mime_stream_fs_new(file);
  msg = g_mime_parser_construct_message(stream);
  g_mime_stream_unref(stream);

  if (msg != 0) {
    hstrcpy(pa.from, g_mime_message_get_header(msg, "From"));
    hstrcpy(pa.subject, g_mime_message_get_subject(msg));
    hstrcpy(pa.message_id, g_mime_message_get_message_id(msg));
    hstrcpy(pa.references, g_mime_message_get_header(msg, "references"));
    hstrcpy(pa.xref, g_mime_message_get_header(msg, "xref"));
    hstrcpy(pa.original_message_id,
	    g_mime_message_get_header(msg, "original-message-id"));
    g_mime_message_get_date(msg, &pa.date, &offset);

    if (pa.xref != NULL &&
	strstr(pa.xref, "gmane.spam.detected") != NULL)
      pa.spamp = 1;
    else
      pa.spamp = 0;

    g_mime_message_foreach_part(msg, count_part, (gpointer) &pa);

    g_mime_object_unref(GMIME_OBJECT(msg));
  
  }
  close(file);
  return &pa;
}
Esempio n. 15
0
static void
format_part_content_text (GMimeObject *part)
{
    const char *cid = g_mime_object_get_content_id (part);
    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));

    if (GMIME_IS_PART (part))
    {
	const char *filename = g_mime_part_get_filename (GMIME_PART (part));
	if (filename)
	    printf (", Filename: %s", filename);
    }

    if (cid)
	printf (", Content-id: %s", cid);

    printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));

    if (g_mime_content_type_is_type (content_type, "text", "*") &&
	!g_mime_content_type_is_type (content_type, "text", "html"))
    {
	GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);
	g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
	show_text_part_content (part, stream_stdout);
	g_object_unref(stream_stdout);
    }
    else if (g_mime_content_type_is_type (content_type, "multipart", "*") ||
	     g_mime_content_type_is_type (content_type, "message", "rfc822"))
    {
	/* Do nothing for multipart since its content will be printed
	 * when recursing. */
    }
    else
    {
	printf ("Non-text part: %s\n",
		g_mime_content_type_to_string (content_type));
    }
}
Esempio n. 16
0
static void
multipart_set_boundary (GMimeMultipart *multipart, const char *boundary)
{
	char bbuf[35];
	
	if (!boundary) {
		/* Generate a fairly random boundary string. */
		unsigned char digest[16], *p;
		guint32 save = 0;
		int state = 0;
		
		read_random_pool (digest, 16);
		
		strcpy (bbuf, "=-");
		p = (unsigned char *) bbuf + 2;
		p += g_mime_encoding_base64_encode_step (digest, 16, p, &state, &save);
		*p = '\0';
		
		boundary = bbuf;
	}
	
	g_mime_object_set_content_type_parameter (GMIME_OBJECT (multipart), "boundary", boundary);
}
Esempio n. 17
0
static void
write_part(GMimeObject *part)
{
	GList *l;
	const GMimeContentType *ct;
	ct = g_mime_object_get_content_type(GMIME_OBJECT(part));
	
	if (GMIME_IS_MULTIPART(part)) {
		if (g_mime_content_type_is_type(ct, "multipart", "alternative")) {
			choose_alternative(part);
			level += g_list_length(GMIME_MULTIPART(part)->subparts);
		} else {
			l = GMIME_MULTIPART(part)->subparts;
			while (l != NULL) {
				write_part(l->data);
				l = l->next;
				level++;
			}
		}
	} else if (GMIME_IS_MESSAGE_PART(part)) {
	} else if (GMIME_IS_PART(part)) {
		display_part(part, ct);
	}
}
Esempio n. 18
0
static GMimeMessage *
create_reply_message(void *ctx,
		     notmuch_config_t *config,
		     notmuch_message_t *message,
		     notmuch_bool_t reply_all)
{
    const char *subject, *from_addr = NULL;
    const char *in_reply_to, *orig_references, *references;

    /* The 1 means we want headers in a "pretty" order. */
    GMimeMessage *reply = g_mime_message_new (1);
    if (reply == NULL) {
	fprintf (stderr, "Out of memory\n");
	return NULL;
    }

    subject = notmuch_message_get_header (message, "subject");
    if (subject) {
	if (strncasecmp (subject, "Re:", 3))
	    subject = talloc_asprintf (ctx, "Re: %s", subject);
	g_mime_message_set_subject (reply, subject);
    }

    from_addr = add_recipients_from_message (reply, config,
					     message, reply_all);

    /*
     * Sadly, there is no standard way to find out to which email
     * address a mail was delivered - what is in the headers depends
     * on the MTAs used along the way.
     *
     * If none of the user's email addresses are in the To: or Cc:
     * headers, we try a number of heuristics which hopefully will
     * answer this question.
     *
     * First, check for Envelope-To:, X-Original-To:, and
     * Delivered-To: headers.
     */
    if (from_addr == NULL)
	from_addr = get_from_in_to_headers (config, message);

    /*
     * Check for a (for <*****@*****.**>) clause in Received: headers,
     * and the domain part of known email addresses in the 'by' part
     * of Received: headers
     */
    if (from_addr == NULL)
	from_addr = guess_from_in_received_headers (config, message);

    /* Default to user's primary address. */
    if (from_addr == NULL)
	from_addr = notmuch_config_get_user_primary_email (config);

    from_addr = talloc_asprintf (ctx, "%s <%s>",
				 notmuch_config_get_user_name (config),
				 from_addr);
    g_mime_object_set_header (GMIME_OBJECT (reply),
			      "From", from_addr);

    in_reply_to = talloc_asprintf (ctx, "<%s>",
				   notmuch_message_get_message_id (message));

    g_mime_object_set_header (GMIME_OBJECT (reply),
			      "In-Reply-To", in_reply_to);

    orig_references = notmuch_message_get_header (message, "references");
    if (!orig_references)
	/* Treat errors like missing References headers. */
	orig_references = "";
    references = talloc_asprintf (ctx, "%s%s%s",
				  *orig_references ? orig_references : "",
				  *orig_references ? " " : "",
				  in_reply_to);
    g_mime_object_set_header (GMIME_OBJECT (reply),
			      "References", references);

    return reply;
}
Esempio n. 19
0
gboolean
write_smtp_reply (struct smtp_session *session)
{
	gchar logbuf[1024], *new_subject;
	const gchar *old_subject;
	struct smtp_metric_callback_data cd;
	GMimeStream *stream;
	gint old_fd, sublen;

	/* Check metrics */
	cd.session = session;
	cd.action = METRIC_ACTION_NOACTION;
	cd.res = NULL;
	cd.log_buf = logbuf;
	cd.log_offset = rspamd_snprintf (logbuf,
			sizeof (logbuf),
			"id: <%s>, qid: <%s>, ",
			session->task->message_id,
			session->task->queue_id);
	cd.log_size = sizeof (logbuf);
	if (session->task->user) {
		cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset,
				sizeof (logbuf) - cd.log_offset,
				"user: %s, ",
				session->task->user);
	}

	g_hash_table_foreach (session->task->results, smtp_metric_callback, &cd);

	msg_info ("%s", logbuf);

	if (cd.action <= METRIC_ACTION_REJECT) {
		if (!rspamd_dispatcher_write (session->dispatcher,
			session->ctx->reject_message, 0, FALSE, TRUE)) {
			return FALSE;
		}
		if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
			1, FALSE, TRUE)) {
			return FALSE;
		}
		destroy_session (session->s);
		return FALSE;
	}
	else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <=
		METRIC_ACTION_REWRITE_SUBJECT) {
		old_fd = session->temp_fd;
		if (!make_smtp_tempfile (session)) {
			session->error = SMTP_ERROR_FILE;
			session->state = SMTP_STATE_CRITICAL_ERROR;
			rspamd_dispatcher_restore (session->dispatcher);
			if (!rspamd_dispatcher_write (session->dispatcher, session->error,
				0, FALSE, TRUE)) {
				goto err;
			}
			destroy_session (session->s);
			return FALSE;
		}

		if (cd.action <= METRIC_ACTION_REWRITE_SUBJECT) {
			/* XXX: add this action */
			old_subject = g_mime_message_get_subject (session->task->message);
			if (old_subject != NULL) {
				sublen = strlen (old_subject) + sizeof (SPAM_SUBJECT);
				new_subject = rspamd_mempool_alloc (session->pool, sublen);
				rspamd_snprintf (new_subject,
					sublen,
					"%s%s",
					SPAM_SUBJECT,
					old_subject);
			}
			else {
				new_subject = SPAM_SUBJECT;
			}
			g_mime_message_set_subject (session->task->message, new_subject);
		}
		else if (cd.action <= METRIC_ACTION_ADD_HEADER) {
#ifndef GMIME24
			g_mime_message_add_header (session->task->message, "X-Spam",
				"true");
#else
			g_mime_object_append_header (GMIME_OBJECT (
					session->task->message), "X-Spam", "true");
#endif
		}
		stream = g_mime_stream_fs_new (session->temp_fd);
		g_mime_stream_fs_set_owner (GMIME_STREAM_FS (stream), FALSE);
		close (old_fd);

		if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message),
			stream) == -1) {
			msg_err ("cannot write MIME object to stream: %s",
				strerror (errno));
			session->error = SMTP_ERROR_FILE;
			session->state = SMTP_STATE_CRITICAL_ERROR;
			rspamd_dispatcher_restore (session->dispatcher);
			if (!rspamd_dispatcher_write (session->dispatcher, session->error,
				0, FALSE, TRUE)) {
				goto err;
			}
			destroy_session (session->s);
			return FALSE;
		}
		g_object_unref (stream);
	}
	/* XXX: Add other actions */
	return smtp_send_upstream_message (session);
err:
	session->error = SMTP_ERROR_FILE;
	session->state = SMTP_STATE_CRITICAL_ERROR;
	if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
		TRUE)) {
		return FALSE;
	}
	destroy_session (session->s);
	return FALSE;
}
Esempio n. 20
0
/* This format is currently tuned for a git send-email --notmuch hook */
static int
notmuch_reply_format_headers_only(void *ctx,
				  notmuch_config_t *config,
				  notmuch_query_t *query,
				  unused (notmuch_show_params_t *params),
				  notmuch_bool_t reply_all,
				  unused (sprinter_t *sp))
{
    GMimeMessage *reply;
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    const char *in_reply_to, *orig_references, *references;
    char *reply_headers;
    notmuch_status_t status;

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch reply", query, status))
	return 1;

    for (;
	 notmuch_messages_valid (messages);
	 notmuch_messages_move_to_next (messages))
    {
	message = notmuch_messages_get (messages);

	/* The 0 means we do not want headers in a "pretty" order. */
	reply = g_mime_message_new (0);
	if (reply == NULL) {
	    fprintf (stderr, "Out of memory\n");
	    return 1;
	}

	in_reply_to = talloc_asprintf (ctx, "<%s>",
			     notmuch_message_get_message_id (message));

        g_mime_object_set_header (GMIME_OBJECT (reply),
				  "In-Reply-To", in_reply_to);


	orig_references = notmuch_message_get_header (message, "references");

	/* We print In-Reply-To followed by References because git format-patch treats them
         * specially.  Git does not interpret the other headers specially
	 */
	references = talloc_asprintf (ctx, "%s%s%s",
				      orig_references ? orig_references : "",
				      orig_references ? " " : "",
				      in_reply_to);
	g_mime_object_set_header (GMIME_OBJECT (reply),
				  "References", references);

	(void)add_recipients_from_message (reply, config, message, reply_all);

	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
	printf ("%s", reply_headers);
	free (reply_headers);

	g_object_unref (G_OBJECT (reply));
	reply = NULL;

	notmuch_message_destroy (message);
    }
    return 0;
}
Esempio n. 21
0
gboolean
g_mime_gpgme_mpe_encrypt(GMimeMultipartEncrypted * mpe,
			 GMimeObject * content, GPtrArray * recipients,
			 gboolean trust_all, GtkWindow * parent,
			 GError ** err)
{
    GMimeStream *filtered_stream;
    GMimeStream *ciphertext;
    GMimeStream *stream;
    GMimePart *version_part;
    GMimePart *encrypted_part;
    GMimeDataWrapper *wrapper;
    GMimeFilter *crlf_filter;

    g_return_val_if_fail(GMIME_IS_MULTIPART_ENCRYPTED(mpe), FALSE);
    g_return_val_if_fail(GMIME_IS_OBJECT(content), FALSE);

    /* get the cleartext */
    stream = g_mime_stream_mem_new();
    filtered_stream = g_mime_stream_filter_new(stream);

    crlf_filter = g_mime_filter_crlf_new(TRUE, FALSE);
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_stream),
			     crlf_filter);
    g_object_unref(crlf_filter);

    g_mime_object_write_to_stream(content, filtered_stream);
    g_mime_stream_flush(filtered_stream);
    g_object_unref(filtered_stream);

    /* reset the content stream */
    g_mime_stream_reset(stream);

    /* encrypt the content stream */
    ciphertext = g_mime_stream_mem_new();
    if (!libbalsa_gpgme_encrypt
	(recipients, NULL, stream, ciphertext, GPGME_PROTOCOL_OpenPGP,
	 FALSE, trust_all, parent, err)) {
	g_object_unref(ciphertext);
	g_object_unref(stream);
	return FALSE;
    }

    g_object_unref(stream);
    g_mime_stream_reset(ciphertext);

    /* construct the version part */
    version_part =
	g_mime_part_new_with_type("application", "pgp-encrypted");
    g_mime_part_set_content_encoding(version_part,
				     GMIME_CONTENT_ENCODING_7BIT);
    stream =
	g_mime_stream_mem_new_with_buffer("Version: 1\n",
					  strlen("Version: 1\n"));
    wrapper =
	g_mime_data_wrapper_new_with_stream(stream,
					    GMIME_CONTENT_ENCODING_7BIT);
    g_mime_part_set_content_object(version_part, wrapper);
    g_object_unref(wrapper);
    g_object_unref(stream);

    /* construct the encrypted mime part */
    encrypted_part =
	g_mime_part_new_with_type("application", "octet-stream");
    g_mime_part_set_content_encoding(encrypted_part,
				     GMIME_CONTENT_ENCODING_7BIT);
    wrapper =
	g_mime_data_wrapper_new_with_stream(ciphertext,
					    GMIME_CONTENT_ENCODING_7BIT);
    g_mime_part_set_content_object(encrypted_part, wrapper);
    g_object_unref(ciphertext);
    g_object_unref(wrapper);

    /* save the version and encrypted parts */
    /* FIXME: make sure there aren't any other parts?? */
    g_mime_multipart_add(GMIME_MULTIPART(mpe), GMIME_OBJECT(version_part));
    g_mime_multipart_add(GMIME_MULTIPART(mpe),
			 GMIME_OBJECT(encrypted_part));
    g_object_unref(encrypted_part);
    g_object_unref(version_part);

    /* set the content-type params for this multipart/encrypted part */
    g_mime_object_set_content_type_parameter(GMIME_OBJECT(mpe), "protocol",
					     "application/pgp-encrypted");
    g_mime_multipart_set_boundary(GMIME_MULTIPART(mpe), NULL);

    return TRUE;
}
Esempio n. 22
0
static notmuch_status_t
format_part_text (const void *ctx, mime_node_t *node,
                  int indent, const notmuch_show_params_t *params)
{
    /* The disposition and content-type metadata are associated with
     * the envelope for message parts */
    GMimeObject *meta = node->envelope_part ?
                        GMIME_OBJECT (node->envelope_part) : node->part;
    GMimeContentType *content_type = g_mime_object_get_content_type (meta);
    const notmuch_bool_t leaf = GMIME_IS_PART (node->part);
    const char *part_type;
    int i;

    if (node->envelope_file) {
        notmuch_message_t *message = node->envelope_file;

        part_type = "message";
        printf ("\f%s{ id:%s depth:%d match:%d excluded:%d filename:%s\n",
                part_type,
                notmuch_message_get_message_id (message),
                indent,
                notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0,
                notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
                notmuch_message_get_filename (message));
    } else {
        GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (meta);
        const char *cid = g_mime_object_get_content_id (meta);
        const char *filename = leaf ?
                               g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;

        if (disposition &&
                strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
            part_type = "attachment";
        else
            part_type = "part";

        printf ("\f%s{ ID: %d", part_type, node->part_num);
        if (filename)
            printf (", Filename: %s", filename);
        if (cid)
            printf (", Content-id: %s", cid);
        printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
    }

    if (GMIME_IS_MESSAGE (node->part)) {
        GMimeMessage *message = GMIME_MESSAGE (node->part);
        InternetAddressList *recipients;
        const char *recipients_string;

        printf ("\fheader{\n");
        if (node->envelope_file)
            printf ("%s\n", _get_one_line_summary (ctx, node->envelope_file));
        printf ("Subject: %s\n", g_mime_message_get_subject (message));
        printf ("From: %s\n", 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 ("To: %s\n", 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 ("Cc: %s\n", recipients_string);
        printf ("Date: %s\n", g_mime_message_get_date_as_string (message));
        printf ("\fheader}\n");

        printf ("\fbody{\n");
    }

    if (leaf) {
        if (g_mime_content_type_is_type (content_type, "text", "*") &&
                !g_mime_content_type_is_type (content_type, "text", "html"))
        {
            GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);
            g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
            show_text_part_content (node->part, stream_stdout, 0);
            g_object_unref(stream_stdout);
        } else {
            printf ("Non-text part: %s\n",
                    g_mime_content_type_to_string (content_type));
        }
    }

    for (i = 0; i < node->nchildren; i++)
        format_part_text (ctx, mime_node_child (node, i), indent, params);

    if (GMIME_IS_MESSAGE (node->part))
        printf ("\fbody}\n");

    printf ("\f%s}\n", part_type);

    return NOTMUCH_STATUS_SUCCESS;
}
Esempio n. 23
0
void
format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first)
{
    /* Any changes to the JSON format should be reflected in the file
     * devel/schemata. */

    if (node->envelope_file) {
        printf ("{");
        format_message_json (ctx, node->envelope_file);

        printf ("\"headers\": ");
        format_headers_json (ctx, GMIME_MESSAGE (node->part), FALSE);

        printf (", \"body\": [");
        format_part_json (ctx, mime_node_child (node, 0), first);

        printf ("]}");
        return;
    }

    void *local = talloc_new (ctx);
    /* The disposition and content-type metadata are associated with
     * the envelope for message parts */
    GMimeObject *meta = node->envelope_part ?
                        GMIME_OBJECT (node->envelope_part) : node->part;
    GMimeContentType *content_type = g_mime_object_get_content_type (meta);
    const char *cid = g_mime_object_get_content_id (meta);
    const char *filename = GMIME_IS_PART (node->part) ?
                           g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;
    const char *terminator = "";
    int i;

    if (!first)
        printf (", ");

    printf ("{\"id\": %d", node->part_num);

    if (node->decrypt_attempted)
        printf (", \"encstatus\": [{\"status\": \"%s\"}]",
                node->decrypt_success ? "good" : "bad");

    if (node->verify_attempted) {
        printf (", \"sigstatus\": ");
        format_part_sigstatus_json (node);
    }

    printf (", \"content-type\": %s",
            json_quote_str (local, g_mime_content_type_to_string (content_type)));

    if (cid)
        printf (", \"content-id\": %s", json_quote_str (local, cid));

    if (filename)
        printf (", \"filename\": %s", json_quote_str (local, filename));

    if (GMIME_IS_PART (node->part)) {
        /* For non-HTML text parts, we include the content in the
         * JSON. Since JSON must be Unicode, we handle charset
         * decoding here and do not report a charset to the caller.
         * For text/html parts, we do not include the content. If a
         * caller is interested in text/html parts, it should retrieve
         * them separately and they will not be decoded. Since this
         * makes charset decoding the responsibility on the caller, we
         * report the charset for text/html parts.
         */
        if (g_mime_content_type_is_type (content_type, "text", "html")) {
            const char *content_charset = g_mime_object_get_content_type_parameter (meta, "charset");

            if (content_charset != NULL)
                printf (", \"content-charset\": %s", json_quote_str (local, content_charset));
        } else if (g_mime_content_type_is_type (content_type, "text", "*")) {
            GMimeStream *stream_memory = g_mime_stream_mem_new ();
            GByteArray *part_content;
            show_text_part_content (node->part, stream_memory, 0);
            part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (stream_memory));

            printf (", \"content\": %s", json_quote_chararray (local, (char *) part_content->data, part_content->len));
            g_object_unref (stream_memory);
        }
    } else if (GMIME_IS_MULTIPART (node->part)) {
        printf (", \"content\": [");
        terminator = "]";
    } else if (GMIME_IS_MESSAGE (node->part)) {
        printf (", \"content\": [{");
        printf ("\"headers\": ");
        format_headers_json (local, GMIME_MESSAGE (node->part), FALSE);

        printf (", \"body\": [");
        terminator = "]}]";
    }

    talloc_free (local);

    for (i = 0; i < node->nchildren; i++)
        format_part_json (ctx, mime_node_child (node, i), i == 0);

    printf ("%s}", terminator);
}
Esempio n. 24
0
gboolean
g_mime_gpgme_mps_sign(GMimeMultipartSigned * mps, GMimeObject * content,
		      const gchar * userid, gpgme_protocol_t protocol,
		      GtkWindow * parent, GError ** err)
{
    GMimeStream *stream;
    GMimeStream *filtered;
    GMimeStream *sigstream;
    GMimeFilter *filter;
    GMimeContentType *content_type;
    GMimeDataWrapper *wrapper;
    GMimeParser *parser;
    GMimePart *signature;
    gchar *micalg;
    const gchar *proto_type;
    const gchar *sig_subtype;
    gpgme_hash_algo_t hash_algo;

    g_return_val_if_fail(GMIME_IS_MULTIPART_SIGNED(mps), FALSE);
    g_return_val_if_fail(GMIME_IS_OBJECT(content), FALSE);

    /* Prepare all the parts for signing... */
    sign_prepare(content);

    /* get the cleartext */
    stream = g_mime_stream_mem_new();
    filtered = g_mime_stream_filter_new(stream);

    /* Note: see rfc3156, section 3 - second note */
    filter = g_mime_filter_from_new(GMIME_FILTER_FROM_MODE_ARMOR);
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered), filter);
    g_object_unref(filter);

    /* Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) */
    filter = g_mime_filter_strip_new();
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered), filter);
    g_object_unref(filter);

    g_mime_object_write_to_stream(content, filtered);
    g_mime_stream_flush(filtered);
    g_object_unref(filtered);
    g_mime_stream_reset(stream);

    /* Note: see rfc2015 or rfc3156, section 5.1 */
    filtered = g_mime_stream_filter_new(stream);
    filter = g_mime_filter_crlf_new(TRUE, FALSE);
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered), filter);
    g_object_unref(filter);

    /* construct the signature stream */
    sigstream = g_mime_stream_mem_new();

    /* sign the content stream */
    hash_algo =
	libbalsa_gpgme_sign(userid, filtered, sigstream, protocol, FALSE,
			    parent, err);
    g_object_unref(filtered);
    if (hash_algo == GPGME_MD_NONE) {
	g_object_unref(sigstream);
	g_object_unref(stream);
	return FALSE;
    }

    g_mime_stream_reset(sigstream);
    g_mime_stream_reset(stream);

    /* set the multipart/signed protocol and micalg */
    content_type = g_mime_object_get_content_type(GMIME_OBJECT(mps));
    if (protocol == GPGME_PROTOCOL_OpenPGP) {
	micalg =
	    g_strdup_printf("PGP-%s", gpgme_hash_algo_name(hash_algo));
	proto_type = "application/pgp-signature";
	sig_subtype = "pgp-signature";
    } else {
	micalg = g_strdup(gpgme_hash_algo_name(hash_algo));
	proto_type = "application/pkcs7-signature";
	sig_subtype = "pkcs7-signature";
    }
    g_mime_content_type_set_parameter(content_type, "micalg", micalg);
    g_free(micalg);
    g_mime_content_type_set_parameter(content_type, "protocol", proto_type);
    g_mime_multipart_set_boundary(GMIME_MULTIPART(mps), NULL);

    /* construct the content part */
    parser = g_mime_parser_new_with_stream(stream);
    content = g_mime_parser_construct_part(parser);
    g_object_unref(stream);
    g_object_unref(parser);

    /* construct the signature part */
    signature = g_mime_part_new_with_type("application", sig_subtype);

    wrapper = g_mime_data_wrapper_new();
    g_mime_data_wrapper_set_stream(wrapper, sigstream);
    g_mime_part_set_content_object(signature, wrapper);
    g_object_unref(sigstream);
    g_object_unref(wrapper);

    /* FIXME: temporary hack, this info should probably be set in
     * the CipherContext class - maybe ::sign can take/output a
     * GMimePart instead. */
    if (protocol == GPGME_PROTOCOL_CMS) {
	g_mime_part_set_content_encoding(signature,
					 GMIME_CONTENT_ENCODING_BASE64);
	g_mime_part_set_filename(signature, "smime.p7m");
    }

    /* save the content and signature parts */
    /* FIXME: make sure there aren't any other parts?? */
    g_mime_multipart_add(GMIME_MULTIPART(mps), content);
    g_mime_multipart_add(GMIME_MULTIPART(mps), (GMimeObject *) signature);
    g_object_unref(signature);
    g_object_unref(content);

    return TRUE;
}
Esempio n. 25
0
GMimeObject *
g_mime_gpgme_mpe_decrypt(GMimeMultipartEncrypted * mpe,
			 GMimeGpgmeSigstat ** signature,
			 GtkWindow * parent, GError ** err)
{
    GMimeObject *decrypted, *version, *encrypted;
    GMimeStream *stream, *ciphertext;
    GMimeStream *filtered_stream;
    GMimeContentType *mime_type;
    GMimeGpgmeSigstat *sigstat;
    GMimeDataWrapper *wrapper;
    GMimeFilter *crlf_filter;
    GMimeParser *parser;
    const char *protocol;
    char *content_type;

    g_return_val_if_fail(GMIME_IS_MULTIPART_ENCRYPTED(mpe), NULL);

    if (signature && *signature) {
	g_object_unref(G_OBJECT(*signature));
	*signature = NULL;
    }

    protocol =
	g_mime_object_get_content_type_parameter(GMIME_OBJECT(mpe),
						 "protocol");

    /* make sure the protocol is present and matches the cipher encrypt protocol */
    if (!protocol
	|| g_ascii_strcasecmp("application/pgp-encrypted",
			      protocol) != 0) {
	g_set_error(err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR,
		    _
		    ("Cannot decrypt multipart/encrypted part: unsupported encryption protocol “%s”."),
		    protocol ? protocol : _("(none)"));
	return NULL;
    }

    version =
	g_mime_multipart_get_part(GMIME_MULTIPART(mpe),
				  GMIME_MULTIPART_ENCRYPTED_VERSION);

    /* make sure the protocol matches the version part's content-type */
    content_type = g_mime_content_type_to_string(version->content_type);
    if (g_ascii_strcasecmp(content_type, protocol) != 0) {
	g_set_error(err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR, "%s",
		    _
		    ("Cannot decrypt multipart/encrypted part: content-type does not match protocol."));
	g_free(content_type);
	return NULL;
    }
    g_free(content_type);

    /* get the encrypted part and check that it is of type application/octet-stream */
    encrypted =
	g_mime_multipart_get_part(GMIME_MULTIPART(mpe),
				  GMIME_MULTIPART_ENCRYPTED_CONTENT);
    mime_type = g_mime_object_get_content_type(encrypted);
    if (!g_mime_content_type_is_type
	(mime_type, "application", "octet-stream")) {
	g_set_error(err, GMIME_ERROR, GMIME_ERROR_PROTOCOL_ERROR, "%s",
		    _
		    ("Cannot decrypt multipart/encrypted part: unexpected content type"));
	return NULL;
    }

    /* get the ciphertext stream */
    wrapper = g_mime_part_get_content_object(GMIME_PART(encrypted));
    ciphertext = g_mime_data_wrapper_get_decoded_stream(wrapper);
    g_mime_stream_reset(ciphertext);

    stream = g_mime_stream_mem_new();
    filtered_stream = g_mime_stream_filter_new(stream);
    crlf_filter = g_mime_filter_crlf_new(FALSE, FALSE);
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_stream),
			     crlf_filter);
    g_object_unref(crlf_filter);

    /* get the cleartext */
    sigstat =
	libbalsa_gpgme_decrypt(ciphertext, filtered_stream,
			       GPGME_PROTOCOL_OpenPGP, parent, err);
    if (!sigstat) {
	g_object_unref(filtered_stream);
	g_object_unref(ciphertext);
	g_object_unref(stream);
	return NULL;
    }

    g_mime_stream_flush(filtered_stream);
    g_object_unref(filtered_stream);
    g_object_unref(ciphertext);

    g_mime_stream_reset(stream);
    parser = g_mime_parser_new();
    g_mime_parser_init_with_stream(parser, stream);
    g_object_unref(stream);

    decrypted = g_mime_parser_construct_part(parser);
    g_object_unref(parser);

    if (!decrypted) {
	g_set_error(err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR, "%s",
		    _
		    ("Cannot decrypt multipart/encrypted part: failed to parse decrypted content"));
	g_object_unref(G_OBJECT(sigstat));
	return NULL;
    }


    /* cache the decrypted part */
    if (signature) {
	if (sigstat->status != GPG_ERR_NOT_SIGNED)
	    *signature = sigstat;
	else
	    g_object_unref(G_OBJECT(sigstat));
    }

    return decrypted;
}
Esempio n. 26
0
END_TEST


START_TEST(test_imap_get_partspec)
{
	DbmailMessage *message;
	GMimeObject *object;
	char *result, *expect;
	
	/* text/plain */
	message = dbmail_message_new();
	message = dbmail_message_init_with_string(message, g_string_new(rfc822));

	object = imap_get_partspec(GMIME_OBJECT(message->content),"HEADER");
	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("From nobody Wed Sep 14 16:47:48 2005\r\n"
			"Content-Type: text/plain; charset=\"us-ascii\"\r\n"
			"MIME-Version: 1.0\r\n"
			"Content-Transfer-Encoding: 7bit\r\n"
			"Message-Id: <1199706209l.3020l.1l@(none)>\r\n"
			"To: [email protected]\r\n"
			"From: [email protected]\r\n"
			"Subject: dbmail test message\r\n"
			"");

	fail_unless(MATCH(expect,result),"imap_get_partsec failed \n[%s] !=\n[%s]\n", expect, result);
	g_free(expect);
	g_free(result);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"TEXT");
	result = imap_get_logical_part(object,"TEXT");
	expect = g_strdup("\r\n"
			"    this is a test message\r\n"
			"\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partsec failed \n[%s] !=\n[%s]\n", expect, result);
	g_free(expect);
	g_free(result);

	dbmail_message_free(message);

	/* multipart */
	
	message = dbmail_message_new();
	message = dbmail_message_init_with_string(message, g_string_new(multipart_message));

	object = imap_get_partspec(GMIME_OBJECT(message->content),"1");
	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("Content-type: text/html\r\n"
	        "Content-disposition: inline\r\n\r\n"
	        "Test message one\r\n"
		" and more.\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"1.TEXT");
	result = imap_get_logical_part(object,"TEXT");
	expect = g_strdup("Test message one\r\n"
			" and more.\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"1.HEADER");
	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("Content-type: text/html\r\n"
			"Content-disposition: inline\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);
	
	object = imap_get_partspec(GMIME_OBJECT(message->content),"2.MIME");
	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup("Content-type: text/plain; charset=us-ascii; name=testfile\r\n"
			"Content-transfer-encoding: base64\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	dbmail_message_free(message);
	
	/* multipart mixed */
	message = dbmail_message_new();
	message = dbmail_message_init_with_string(message, g_string_new(multipart_mixed));

	object = imap_get_partspec(GMIME_OBJECT(message->content),"2.HEADER");
	result = imap_get_logical_part(object,"HEADER");
	fail_unless(strncmp(result,"From: \"try\" <*****@*****.**>",29)==0,"imap_get_partspec failed");
	g_free(result);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"2.1.1");
	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("Content-Type: text/plain;\r\n"
			"	charset=\"us-ascii\"\r\n"
			"Content-Transfer-Encoding: 7bit\r\n\r\n"
			"Body of doc2\r\n\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	dbmail_message_free(message);
}
Esempio n. 27
0
static int
notmuch_reply_format_default(void *ctx,
			     notmuch_config_t *config,
			     notmuch_query_t *query,
			     notmuch_show_params_t *params)
{
    GMimeMessage *reply;
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    const char *subject, *from_addr = NULL;
    const char *in_reply_to, *orig_references, *references;
    const notmuch_show_format_t *format = &format_reply;

    for (messages = notmuch_query_search_messages (query);
	 notmuch_messages_valid (messages);
	 notmuch_messages_move_to_next (messages))
    {
	message = notmuch_messages_get (messages);

	/* The 1 means we want headers in a "pretty" order. */
	reply = g_mime_message_new (1);
	if (reply == NULL) {
	    fprintf (stderr, "Out of memory\n");
	    return 1;
	}

	subject = notmuch_message_get_header (message, "subject");
	if (subject) {
	    if (strncasecmp (subject, "Re:", 3))
		subject = talloc_asprintf (ctx, "Re: %s", subject);
	    g_mime_message_set_subject (reply, subject);
	}

	from_addr = add_recipients_from_message (reply, config, message);

	if (from_addr == NULL)
	    from_addr = guess_from_received_header (config, message);

	if (from_addr == NULL)
	    from_addr = notmuch_config_get_user_primary_email (config);

	from_addr = talloc_asprintf (ctx, "%s <%s>",
				     notmuch_config_get_user_name (config),
				     from_addr);
	g_mime_object_set_header (GMIME_OBJECT (reply),
				  "From", from_addr);

	in_reply_to = talloc_asprintf (ctx, "<%s>",
			     notmuch_message_get_message_id (message));

	g_mime_object_set_header (GMIME_OBJECT (reply),
				  "In-Reply-To", in_reply_to);

	orig_references = notmuch_message_get_header (message, "references");
	references = talloc_asprintf (ctx, "%s%s%s",
				      orig_references ? orig_references : "",
				      orig_references ? " " : "",
				      in_reply_to);
	g_mime_object_set_header (GMIME_OBJECT (reply),
				  "References", references);

	show_reply_headers (reply);

	g_object_unref (G_OBJECT (reply));
	reply = NULL;

	printf ("On %s, %s wrote:\n",
		notmuch_message_get_header (message, "date"),
		notmuch_message_get_header (message, "from"));

	show_message_body (notmuch_message_get_filename (message),
			   format, params);

	notmuch_message_destroy (message);
    }
    return 0;
}
Esempio n. 28
0
document* parse_file(const char *file_name) {
  int tallied_length = 0;
  GMimeStream *stream;
  GMimeMessage *msg = 0;
  // struct stat stat_buf;
  const char *author, *subject, *xref, *xref_end;
  time_t date;
  int offset;
  int num_words = 0;
  int file;
  InternetAddress *iaddr;
  InternetAddressList *iaddr_list;
  char *address;

#if DEBUG
  printf("%s\n", file_name);
#endif

  /*
  if ((file = stat(file_name, &stat_buf)) == -1) {
    perror("tokenizer");
    return NULL;
  }
  */

  // |O_STREAMING
  if ((file = open(file_name, O_RDONLY|O_STREAMING)) == -1) {
    perror("tokenizer");
    return NULL;
  }

#ifdef POSIX_FADV_NOREUSE
  no_reuse(file);
#endif

  stream = g_mime_stream_fs_new(file);
  msg = g_mime_parser_construct_message(stream);
  g_mime_stream_unref(stream);

  if (msg != 0) {
    table = g_hash_table_new(g_str_hash, g_str_equal);
    bufp = buffer;
    dword_table[0].word = NULL;
    bzero(saved_body, MAX_SAVED_BODY_LENGTH);
    saved_body_length = 0;
    author = g_mime_message_get_sender(msg);
    subject = g_mime_message_get_subject(msg);
    xref = g_mime_message_get_header(msg, "Xref");
    g_mime_message_get_date(msg, &date, &offset);
    if (author != NULL && subject != NULL && xref != NULL) {
      tallied_length = tally_string(author, tallied_length);
      strncpy(doc.author, author, MAX_HEADER_LENGTH-1);

      /* Get the address from the From header. */
      if ((iaddr_list = internet_address_parse_string(author)) != NULL) {
	iaddr = iaddr_list->address;
	internet_address_set_name(iaddr, NULL);
	address = internet_address_to_string(iaddr, FALSE);
	strncpy(doc.address, address, MAX_HEADER_LENGTH-1);
	downcase_string(doc.address);
	free(address);
	internet_address_list_destroy(iaddr_list);
      } else {
	*doc.address = 0;
      }

      tallied_length = tally_string(subject, tallied_length);
      strncpy(doc.subject, subject, MAX_HEADER_LENGTH-1);

      doc.time = date;

      if ((xref = strchr(xref, ' ')) != NULL) {
	xref++;
	xref_end = strchr(xref, ':');
	*doc.group = 0;
	strncat(doc.group, xref, min(xref_end-xref, MAX_HEADER_LENGTH-1));
	xref_end++;
	sscanf(xref_end, "%d", &doc.article);
      }

      g_mime_message_foreach_part(msg, partFound, (gpointer) &tallied_length);

      strncpy(doc.body, saved_body, MAX_SAVED_BODY_LENGTH);

      g_hash_table_foreach(table, add_word_to_table, (gpointer) &num_words);
      dword_table[num_words].word = NULL;
      g_hash_table_destroy(table);
      g_mime_object_unref(GMIME_OBJECT(msg));
    } else {
      close(file);
      return NULL;
    }
  }
  close(file);
  doc.words = dword_table;
  doc.num_words = num_words;

  return &doc;
}
Esempio n. 29
0
END_TEST


START_TEST(test_imap_get_partspec)
{
	DbmailMessage *message;
	GMimeObject *object;
	char *result, *expect;

	/* text/plain */
	message = dbmail_message_new(NULL);
	message = dbmail_message_init_with_string(message, rfc822);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"HEADER");
	result = g_mime_object_to_string(object);
	fail_unless(MATCH(rfc822,result),
			"imap_get_partsec failed \n[%s] !=\n[%s]\n",
		       	rfc822, result);
	g_free(result);

	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("From nobody Wed Sep 14 16:47:48 2005\r\n"
			"Content-Type: text/plain; charset=\"us-ascii\"\r\n"
			"MIME-Version: 1.0\r\n"
			"Content-Transfer-Encoding: 7bit\r\n"
			"Message-Id: <1199706209l.3020l.1l@(none)>\r\n"
			"To: [email protected]\r\n"
			"From: [email protected]\r\n"
			"Subject: dbmail test message\r\n"
			"\r\n");

	fail_unless(MATCH(expect,result),"imap_get_partsec failed \n[%s] !=\n[%s]\n", expect, result);
	g_free(expect);
	g_free(result);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"TEXT");
	result = imap_get_logical_part(object,"TEXT");
	expect = g_strdup("\r\n"
			"    this is a test message\r\n"
			"\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partsec failed \n[%s] !=\n[%s]\n", expect, result);
	g_free(expect);
	g_free(result);

	dbmail_message_free(message);

	/* multipart */
	
	message = dbmail_message_new(NULL);
	message = dbmail_message_init_with_string(message, multipart_message);

	/* test a simple mime part */
	object = imap_get_partspec(GMIME_OBJECT(message->content),"1");
	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup("Content-type: text/html\r\n"
	        "Content-disposition: inline\r\n\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("Test message one\r\n and more.\r\n");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	/* object isn't a message/rfc822 so these are 
	 * acually invalid. Let's try anyway */
	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("Content-type: text/html\r\n"
			"Content-disposition: inline\r\n\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	result = imap_get_logical_part(object,"TEXT");
	expect = g_strdup("Test message one\r\n and more.\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	/* moving on */
	object = imap_get_partspec(GMIME_OBJECT(message->content),"2");
	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup(
			"Content-type: text/plain; charset=us-ascii; name=testfile\r\n"
			"Content-transfer-encoding: base64\r\n"
			"\r\n"
			);
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	dbmail_message_free(message);
	
	/* multipart mixed */
	message = dbmail_message_new(NULL);
	message = dbmail_message_init_with_string(message, multipart_mixed);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"2");
	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("From: \"try\" <*****@*****.**>");
	fail_unless((strncmp(expect,result,29)==0),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(expect);
	g_free(result);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"2.1.1");
	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("Body of doc2\r\n\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
			expect, result);
	g_free(result);
	g_free(expect);
	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup("Content-Type: text/plain;\r\n"
			"	charset=\"us-ascii\"\r\n"
			"Content-Transfer-Encoding: 7bit\r\n\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
			expect, result);
	g_free(result);
	g_free(expect);

	dbmail_message_free(message);

	/* multipart signed */
	message = dbmail_message_new(NULL);
	message = dbmail_message_init_with_string(message, multipart_signed);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"1.1");
	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("quo-pri text");
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	object = imap_get_partspec(GMIME_OBJECT(message->content),"1.3");
	result = g_mime_object_to_string(object);
	expect = g_strdup("Content-Type: message/rfc822;\n"
			"Content-Transfer-Encoding: 7bit\n"
			"Content-Disposition: attachment;\n"
			" filename=\"msg1.eml\"\n"
			"\n"
			"Date: Mon, 19 Aug 2013 14:54:05 +0200\n"
			"To: a@b\n"
			"From: d@b\n"
			"Reply-To: e@b\n"
			"Subject: msg1\n"
			"MIME-Version: 1.0\n"
			"Content-Type: multipart/alternative;\n"
			"	boundary=b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\n"
			"\n"
			"\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\n"
			"Content-Type: text/plain; charset=\"ISO-8859-1\"\n"
			"Content-Transfer-Encoding: quoted-printable\n"
			"\n"
			"quo-pri text\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\n"
			"Content-Type: text/html; charset=\"ISO-8859-1\"\n"
			"Content-Transfer-Encoding: quoted-printable\n"
			"\n"
			"html text\n"
			"\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845--\n"
			"\n"
			"\n"
			"\n");

	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup("Content-Type: message/rfc822;\r\n"
			"Content-Transfer-Encoding: 7bit\r\n"
			"Content-Disposition: attachment;\r\n"
			" filename=\"msg1.eml\"\r\n"
			"\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	
	result = imap_get_logical_part(object,NULL);
	expect = g_strdup("Date: Mon, 19 Aug 2013 14:54:05 +0200\r\n"
			"To: a@b\r\n"
			"From: d@b\r\n"
			"Reply-To: e@b\r\n"
			"Subject: msg1\r\n"
			"MIME-Version: 1.0\r\n"
			"Content-Type: multipart/alternative;\r\n"
			"	boundary=b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\r\n"
			"\r\n"
			"\r\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\r\n"
			"Content-Type: text/plain; charset=\"ISO-8859-1\"\r\n"
			"Content-Transfer-Encoding: quoted-printable\r\n"
			"\r\n"
			"quo-pri text\r\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\r\n"
			"Content-Type: text/html; charset=\"ISO-8859-1\"\r\n"
			"Content-Transfer-Encoding: quoted-printable\r\n"
			"\r\n"
			"html text\r\n"
			"\r\n"
			"--b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845--\r\n"
			"\r\n"
			"\r\n"
			"\r\n");

	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);



	result = imap_get_logical_part(object,"MIME");
	expect = g_strdup("Content-Type: message/rfc822;\r\n"
			"Content-Transfer-Encoding: 7bit\r\n"
			"Content-Disposition: attachment;\r\n"
			" filename=\"msg1.eml\"\r\n"
			"\r\n");
	fail_unless(MATCH(expect,result),
			"imap_get_partspec failed:\n[%s] != \n[%s]\n",
		       	expect, result);
	g_free(result);
	g_free(expect);

	result = imap_get_logical_part(object,"HEADER");
	expect = g_strdup("Date: Mon, 19 Aug 2013 14:54:05 +0200\r\n"
			"To: a@b\r\n"
			"From: d@b\r\n"
			"Reply-To: e@b\r\n"
			"Subject: msg1\r\n"
			"MIME-Version: 1.0\r\n"
			"Content-Type: multipart/alternative;\r\n"
			"\tboundary=b1_7ad0d7cccab59d27194f9ad69c14606001f05f531376916845\r\n"
			"\r\n");
				
	fail_unless(MATCH(expect,result),"imap_get_partspec failed:\n[%s] != \n[%s]\n", expect, result);
	g_free(result);
	g_free(expect);

	dbmail_message_free(message);

}
Esempio n. 30
0
void
format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node,
		      notmuch_bool_t first, notmuch_bool_t output_body,
		      notmuch_bool_t include_html)
{
    /* Any changes to the JSON or S-Expression format should be
     * reflected in the file devel/schemata. */

    if (node->envelope_file) {
	sp->begin_map (sp);
	format_message_sprinter (sp, node->envelope_file);

	sp->map_key (sp, "headers");
	format_headers_sprinter (sp, GMIME_MESSAGE (node->part), FALSE);

	if (output_body) {
	    sp->map_key (sp, "body");
	    sp->begin_list (sp);
	    format_part_sprinter (ctx, sp, mime_node_child (node, 0), first, TRUE, include_html);
	    sp->end (sp);
	}
	sp->end (sp);
	return;
    }

    /* The disposition and content-type metadata are associated with
     * the envelope for message parts */
    GMimeObject *meta = node->envelope_part ?
	GMIME_OBJECT (node->envelope_part) : node->part;
    GMimeContentType *content_type = g_mime_object_get_content_type (meta);
    const char *cid = g_mime_object_get_content_id (meta);
    const char *filename = GMIME_IS_PART (node->part) ?
	g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;
    int nclose = 0;
    int i;

    sp->begin_map (sp);

    sp->map_key (sp, "id");
    sp->integer (sp, node->part_num);

    if (node->decrypt_attempted) {
	sp->map_key (sp, "encstatus");
	sp->begin_list (sp);
	sp->begin_map (sp);
	sp->map_key (sp, "status");
	sp->string (sp, node->decrypt_success ? "good" : "bad");
	sp->end (sp);
	sp->end (sp);
    }

    if (node->verify_attempted) {
	sp->map_key (sp, "sigstatus");
	format_part_sigstatus_sprinter (sp, node);
    }

    sp->map_key (sp, "content-type");
    sp->string (sp, g_mime_content_type_to_string (content_type));

    if (cid) {
	sp->map_key (sp, "content-id");
	sp->string (sp, cid);
    }

    if (filename) {
	sp->map_key (sp, "filename");
	sp->string (sp, filename);
    }

    if (GMIME_IS_PART (node->part)) {
	/* For non-HTML text parts, we include the content in the
	 * JSON. Since JSON must be Unicode, we handle charset
	 * decoding here and do not report a charset to the caller.
	 * For text/html parts, we do not include the content unless
	 * the --include-html option has been passed. If a html part
	 * is not included, it can be requested directly. This makes
	 * charset decoding the responsibility on the caller so we
	 * report the charset for text/html parts.
	 */
	if (g_mime_content_type_is_type (content_type, "text", "*") &&
	    (include_html ||
	     ! g_mime_content_type_is_type (content_type, "text", "html")))
	{
	    GMimeStream *stream_memory = g_mime_stream_mem_new ();
	    GByteArray *part_content;
	    show_text_part_content (node->part, stream_memory, 0);
	    part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (stream_memory));
	    sp->map_key (sp, "content");
	    sp->string_len (sp, (char *) part_content->data, part_content->len);
	    g_object_unref (stream_memory);
	} else {
	    format_omitted_part_meta_sprinter (sp, meta, GMIME_PART (node->part));
	}
    } else if (GMIME_IS_MULTIPART (node->part)) {
	sp->map_key (sp, "content");
	sp->begin_list (sp);
	nclose = 1;
    } else if (GMIME_IS_MESSAGE (node->part)) {
	sp->map_key (sp, "content");
	sp->begin_list (sp);
	sp->begin_map (sp);

	sp->map_key (sp, "headers");
	format_headers_sprinter (sp, GMIME_MESSAGE (node->part), FALSE);

	sp->map_key (sp, "body");
	sp->begin_list (sp);
	nclose = 3;
    }

    for (i = 0; i < node->nchildren; i++)
	format_part_sprinter (ctx, sp, mime_node_child (node, i), i == 0, TRUE, include_html);

    /* Close content structures */
    for (i = 0; i < nclose; i++)
	sp->end (sp);
    /* Close part map */
    sp->end (sp);
}