Esempio n. 1
0
static void
format_headers_message_part_json (GMimeMessage *message)
{
    void *ctx = talloc_new (NULL);
    void *ctx_quote = talloc_new (ctx);
    InternetAddressList *recipients;
    const char *recipients_string;

    printf ("%s: %s",
	    json_quote_str (ctx_quote, "From"),
	    json_quote_str (ctx_quote, 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 (ctx_quote, "To"),
		json_quote_str (ctx_quote, 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 (ctx_quote, "Cc"),
		json_quote_str (ctx_quote, recipients_string));
    printf (", %s: %s",
	    json_quote_str (ctx_quote, "Subject"),
	    json_quote_str (ctx_quote, g_mime_message_get_subject (message)));
    printf (", %s: %s",
	    json_quote_str (ctx_quote, "Date"),
	    json_quote_str (ctx_quote, g_mime_message_get_date_as_string (message)));

    talloc_free (ctx_quote);
    talloc_free (ctx);
}
Esempio n. 2
0
static char*
mime_part_get_filename (GMimeObject *mobj, unsigned index,
			gboolean construct_if_needed)
{
	gchar *fname;

	fname = NULL;

	if (GMIME_IS_PART (mobj)) {
		/* the easy case: the part has a filename */
		fname = (gchar*)g_mime_part_get_filename (GMIME_PART(mobj));
		if (fname) /* don't include directory components */
			fname = g_path_get_basename (fname);
	}

	if (!fname && !construct_if_needed)
		return NULL;

	if (GMIME_IS_MESSAGE_PART(mobj)) {
		GMimeMessage *msg;
		const char *subj;
		msg  = g_mime_message_part_get_message
			(GMIME_MESSAGE_PART(mobj));
		subj = g_mime_message_get_subject (msg);
		fname = g_strdup_printf ("%s.eml", subj ? subj : "message");
	}

	if (!fname)
		fname =	g_strdup_printf ("%u.part", index);

	/* remove slashes, spaces, colons... */
	cleanup_filename (fname);
	return fname;
}
Esempio n. 3
0
int main (int argc, char* argv[]) {
  if (argc < 2) {
    fprintf(stderr, "Usage: %s MSG_FILE\n", argv[0]);
    return 1;
  }

  g_mime_init(0);

  FILE* fp = fopen(argv[1], "r");
  if (fp == NULL) {
    fprintf(stderr, "Cannot open the file %s\n", argv[1]);
    return 1;
  }

  GMimeStream* stream = g_mime_stream_file_new(fp);
  GMimeParser* parser = g_mime_parser_new_with_stream(stream);
  GMimeMessage* message = g_mime_parser_construct_message(parser);

  if (message == NULL) {
    fprintf(stderr, "Cannot construct message\n");
    return 1;
  }

  printf("Date    : %s\n", g_mime_message_get_date_as_string(message));
  printf("Subject : %s\n", g_mime_message_get_subject(message));
  printf("From    : %s\n", g_mime_message_get_sender(message));
  printf("To      : %s\n", internet_address_list_to_string(
        g_mime_message_get_all_recipients(message), FALSE));

  fclose(fp);
  return 0;
}
Esempio n. 4
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);
}
Esempio n. 5
0
static void
format_part_reply (mime_node_t *node)
{
    int i;

    if (node->envelope_file) {
	printf ("On %s, %s wrote:\n",
		notmuch_message_get_header (node->envelope_file, "date"),
		notmuch_message_get_header (node->envelope_file, "from"));
    } else if (GMIME_IS_MESSAGE (node->part)) {
	GMimeMessage *message = GMIME_MESSAGE (node->part);
	InternetAddressList *recipients;
	const char *recipients_string;

	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 ("> Subject: %s\n", g_mime_message_get_subject (message));
	printf ("> Date: %s\n", g_mime_message_get_date_as_string (message));
	printf (">\n");
    } else if (GMIME_IS_PART (node->part)) {
	GMimeContentType *content_type = g_mime_object_get_content_type (node->part);
	GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (node->part);

	if (g_mime_content_type_is_type (content_type, "application", "pgp-encrypted") ||
	    g_mime_content_type_is_type (content_type, "application", "pgp-signature")) {
	    /* Ignore PGP/MIME cruft parts */
	} else 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, NOTMUCH_SHOW_TEXT_PART_REPLY);
	    g_object_unref(stream_stdout);
	} else if (disposition &&
		   strcasecmp (g_mime_content_disposition_get_disposition (disposition),
			       GMIME_DISPOSITION_ATTACHMENT) == 0) {
	    const char *filename = g_mime_part_get_filename (GMIME_PART (node->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));
	}
    }

    for (i = 0; i < node->nchildren; i++)
	format_part_reply (mime_node_child (node, i));
}
Esempio n. 6
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;
}
Esempio n. 7
0
void extract_headers (GMimeMessage *message, GMimeStream *out_stream) {
  const char *subject;
  char *escaped_subject;
  const char *sender;
  char *escaped_sender;
  const char *reply_to;
  char *escaped_reply_to;
  time_t t;
  int tz;
  char buf[64];
  struct tm *t_m;
  subject = g_mime_message_get_subject(message);
  escaped_subject = str_replace((char *) subject, "\"", "");
  g_mime_stream_printf (out_stream, "subject: \"%s\", ", escaped_subject);
  g_mime_stream_printf (out_stream, "message_id: \"%s\", ", g_mime_message_get_message_id(message));
  sender = g_mime_message_get_sender(message);
  escaped_sender = str_replace((char *) sender, "\"", "");
  g_mime_stream_printf (out_stream, "sender: \"%s\", ", escaped_sender);
  reply_to = g_mime_message_get_reply_to(message);
  escaped_reply_to = str_replace((char *) reply_to, "\"", "");
  g_mime_stream_printf (out_stream, "reply_to: \"%s\", ", escaped_reply_to);
  g_mime_message_get_date (message, &t, &tz);
  t_m = localtime (&t);
  strftime(buf, sizeof(buf) - 1, "%c", t_m);
  g_mime_stream_printf (out_stream, "date: \"%s\", ", buf);
  strftime(buf, sizeof(buf) - 1, "%Y%m%d%H%M%S", t_m);
  g_mime_stream_printf (out_stream, "sort_date: \"%s\", ", buf);

  InternetAddressList *recipients;
  recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_TO);
  g_mime_stream_printf (out_stream, "recipients_to: [");
  extract_addresses(recipients, out_stream);
  g_mime_stream_printf (out_stream, "], ");

  recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_CC);
  g_mime_stream_printf (out_stream, "recipients_cc: [");
  extract_addresses(recipients, out_stream);
  g_mime_stream_printf (out_stream, "], ");

  recipients = g_mime_message_get_recipients(message, GMIME_RECIPIENT_TYPE_BCC);
  g_mime_stream_printf (out_stream, "recipients_bcc: [");
  extract_addresses(recipients, out_stream);
  g_mime_stream_printf (out_stream, "] ");
}
Esempio n. 8
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);
}
Esempio n. 9
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. 10
0
static void
reply_headers_message_part (GMimeMessage *message)
{
    InternetAddressList *recipients;
    const char *recipients_string;

    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 ("> Subject: %s\n", g_mime_message_get_subject (message));
    printf ("> Date: %s\n", g_mime_message_get_date_as_string (message));
}
Esempio n. 11
0
static gboolean
test_message (GMimeMessage *msg)
{
    gchar *val;
    const gchar *str;

    g_print ("From   : %s\n", g_mime_message_get_sender (msg));

    val = get_recip (msg, GMIME_RECIPIENT_TYPE_TO);
    g_print ("To     : %s\n", val ? val : "<none>" );
    g_free (val);

    val = get_recip (msg, GMIME_RECIPIENT_TYPE_CC);
    g_print ("Cc     : %s\n", val ? val : "<none>" );
    g_free (val);

    val = get_recip (msg, GMIME_RECIPIENT_TYPE_BCC);
    g_print ("Bcc    : %s\n", val ? val : "<none>" );
    g_free (val);

    str = g_mime_message_get_subject (msg);
    g_print ("Subject: %s\n", str ? str : "<none>");

    print_date (msg);


    str = g_mime_message_get_message_id (msg);
    g_print ("Msg-id : %s\n", str ? str : "<none>");

    {
        gchar *refsstr;
        refsstr = get_refs_str (msg);
        g_print ("Refs   : %s\n", refsstr ? refsstr : "<none>");
        g_free (refsstr);
    }


    return TRUE;
}
Esempio n. 12
0
static void
accumulate_text_message (MuMsg *msg, MuMsgPart *part, GString **gstrp)
{
	const gchar *str;
	char *adrs;
	GMimeMessage *mimemsg;
	InternetAddressList *addresses;

	/* put sender, recipients and subject in the string, so they
	 * can be indexed as well */
	mimemsg = GMIME_MESSAGE (part->data);
	str = g_mime_message_get_sender (mimemsg);
	g_string_append_printf
		(*gstrp, "%s%s", str ? str : "", str ? "\n" : "");
	str = g_mime_message_get_subject (mimemsg);
	g_string_append_printf
		(*gstrp, "%s%s", str ? str : "", str ? "\n" : "");
		addresses = g_mime_message_get_all_recipients (mimemsg);
		adrs = internet_address_list_to_string (addresses, FALSE);
		g_object_unref (addresses);
		g_string_append_printf
			(*gstrp, "%s%s", adrs ? adrs : "", adrs ? "\n" : "");
		g_free (adrs);
}
Esempio n. 13
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. 14
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_message_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;
}
Esempio n. 15
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;
}
Esempio n. 16
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. 17
0
static void
test_parser (GMimeParser *parser, GMimeStream *mbox, GMimeStream *summary)
{
	gint64 message_begin, message_end, headers_begin, headers_end;
	GMimeFormatOptions *format = g_mime_format_options_get_default ();
	InternetAddressList *list;
	GMimeMessage *message;
	char *marker, *buf;
	const char *subject;
	GMimeObject *body;
	GDateTime *date;
	int nmsg = 0;
	
	while (!g_mime_parser_eos (parser)) {
		message_begin = g_mime_parser_tell (parser);
		if (!(message = g_mime_parser_construct_message (parser, NULL)))
			throw (exception_new ("failed to parse message #%d", nmsg));
		
		message_end = g_mime_parser_tell (parser);
		
		headers_begin = g_mime_parser_get_headers_begin (parser);
		headers_end = g_mime_parser_get_headers_end (parser);
		
		g_mime_stream_printf (summary, "message offsets: %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "\n",
				      message_begin, message_end);
		g_mime_stream_printf (summary, "header offsets: %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "\n",
				      headers_begin, headers_end);
		
		marker = g_mime_parser_get_mbox_marker (parser);
		g_mime_stream_printf (summary, "%s\n", marker);
		
		if ((list = g_mime_message_get_from (message)) != NULL &&
		    internet_address_list_length (list) > 0) {
			buf = internet_address_list_to_string (list, format, FALSE);
			g_mime_stream_printf (summary, "From: %s\n", buf);
			g_free (buf);
		}
		
		if ((list = g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO)) != NULL &&
		    internet_address_list_length (list) > 0) {
			buf = internet_address_list_to_string (list, format, FALSE);
			g_mime_stream_printf (summary, "To: %s\n", buf);
			g_free (buf);
		}
		
		if (!(subject = g_mime_message_get_subject (message)))
			subject = "";
		g_mime_stream_printf (summary, "Subject: %s\n", subject);
		
		if (!(date = g_mime_message_get_date (message))) {
			date = g_date_time_new_from_unix_utc (0);
		} else {
			g_date_time_ref (date);
		}
		buf = g_mime_utils_header_format_date (date);
		g_mime_stream_printf (summary, "Date: %s\n", buf);
		g_date_time_unref (date);
		g_free (buf);
		
		body = g_mime_message_get_mime_part (message);
		print_mime_struct (summary, body, 0);
		g_mime_stream_write (summary, "\n", 1);
		
		if (mbox) {
			if (nmsg > 0)
				g_mime_stream_write (mbox, "\n", 1);
			
			g_mime_stream_printf (mbox, "%s\n", marker);
			g_mime_object_write_to_stream ((GMimeObject *) message, format, mbox);
		}
		
		g_object_unref (message);
		g_free (marker);
		nmsg++;
	}
}
Esempio n. 18
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;
}