示例#1
0
/**
 * sign_prepare:
 * @mime_part: MIME part
 *
 * Prepare a part (and all subparts) to be signed. To do this we need
 * to set the encoding of all parts (that are not already encoded to
 * either QP or Base64 or 7-bit) to QP.
 *
 * Ref: RFC 3156, sect. 3.
 **/
static void
sign_prepare(GMimeObject * mime_part)
{
    GMimeContentEncoding encoding;
    GMimeObject *subpart;

    if (GMIME_IS_MULTIPART(mime_part)) {
        GMimeMultipart *multipart;
        int i, n;

	multipart = (GMimeMultipart *) mime_part;

	if (GMIME_IS_MULTIPART_SIGNED(multipart) ||
	    GMIME_IS_MULTIPART_ENCRYPTED(multipart)) {
	    /* must not modify these parts as they must be treated as opaque */
	    return;
	}

	n = g_mime_multipart_get_count(multipart);
	for (i = 0; i < n; i++) {
	    subpart = g_mime_multipart_get_part(multipart, i);
	    sign_prepare(subpart);
	}
    } else if (GMIME_IS_MESSAGE_PART(mime_part)) {
	subpart = GMIME_MESSAGE_PART(mime_part)->message->mime_part;
	sign_prepare(subpart);
    } else {
	encoding = g_mime_part_get_content_encoding(GMIME_PART(mime_part));
	if ((encoding != GMIME_CONTENT_ENCODING_BASE64) && (encoding != GMIME_CONTENT_ENCODING_7BIT))
	    g_mime_part_set_content_encoding(GMIME_PART(mime_part),
					     GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE);
    }
}
示例#2
0
文件: mu-msg-part.c 项目: otfrom/mu
gboolean
mu_msg_part_save (MuMsg *msg, MuMsgOptions opts,
		  const char *fullpath, guint partidx, GError **err)
{
	GMimeObject *part;

	g_return_val_if_fail (msg, FALSE);
	g_return_val_if_fail (fullpath, FALSE);
	g_return_val_if_fail (!((opts & MU_MSG_OPTION_OVERWRITE) &&
			        (opts & MU_MSG_OPTION_USE_EXISTING)), FALSE);

	if (!mu_msg_load_msg_file (msg, err))
		return FALSE;

	part = get_mime_object_at_index (msg, opts, partidx);
	if (!GMIME_IS_PART(part) || GMIME_IS_MESSAGE_PART(part)) {
		g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME,
			     "unexpected type %s for part %u",
			     G_OBJECT_TYPE_NAME((GObject*)part),
			     partidx);
		return FALSE;
	}

	return save_object (part, opts, fullpath, err);
}
示例#3
0
static void process_message_callback(GMimeObject *part, gpointer user_data)
{
	struct mime_cbinfo *cbinfo = user_data;

	cbinfo->count++;

	/* We strip off the headers before we get here, so should only see GMIME_IS_PART */
	if (GMIME_IS_MESSAGE_PART(part)) {
		ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MESSAGE_PART\n");
		return;
	} else if (GMIME_IS_MESSAGE_PARTIAL(part)) {
		ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MESSAGE_PARTIAL\n");
		return;
	} else if (GMIME_IS_MULTIPART(part)) {
		GList *l;
		
		ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MULTIPART, trying to process subparts\n");
		l = GMIME_MULTIPART(part)->subparts;
		while (l) {
			process_message_callback(l->data, cbinfo);
			l = l->next;
		}
	} else if (GMIME_IS_PART(part)) {
		const char *filename;

		if (ast_strlen_zero(filename = g_mime_part_get_filename(GMIME_PART(part)))) {
			ast_debug(1, "Skipping part with no filename\n");
			return;
		}

		post_raw(GMIME_PART(part), cbinfo->post_dir, filename);
	} else {
		ast_log(LOG_ERROR, "Encountered unknown MIME part. This should never happen!\n");
	}
}
示例#4
0
文件: mu-msg-part.c 项目: otfrom/mu
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;
}
示例#5
0
文件: gmimex.c 项目: swerter/gmimex
static void part_extractor_foreach_callback(GMimeObject *parent, GMimeObject *part, gpointer user_data) {
  PartExtractorData *a_data = (PartExtractorData *) user_data;

  if (GMIME_IS_MESSAGE_PART(part)) {

    if (a_data->recursion_depth < RECURSION_LIMIT) {
      GMimeMessage *message = g_mime_message_part_get_message((GMimeMessagePart *) part); // transfer none
      if (message)
        g_mime_message_foreach(message, part_extractor_foreach_callback, a_data);

    } else {
      g_printerr("endless recursion detected: %d\r\n", a_data->recursion_depth);
      return;
    }

  } else if (GMIME_IS_MESSAGE_PARTIAL (part)) {
    // Save into an array ? Todo: Look into the specs
  } else if (GMIME_IS_MULTIPART (part)) {
    // Nothing special needed on multipart, let descend further
  } else if (GMIME_IS_PART (part)) {

    // We are interested only in the part 0 (counting down by same logic)
    if (a_data->part_id == 0)
      extract_part(part, a_data);

    a_data->part_id--;

  } else {
    g_assert_not_reached();
  }
}
示例#6
0
文件: gmimex.c 项目: swerter/gmimex
static void collector_foreach_callback(GMimeObject *parent, GMimeObject *part, gpointer user_data) {
  g_return_if_fail(user_data != NULL);

  PartCollectorData *fdata = (PartCollectorData *) user_data;

  if (GMIME_IS_MESSAGE_PART(part)) {

    if (fdata->recursion_depth++ < RECURSION_LIMIT) {
      GMimeMessage *message = g_mime_message_part_get_message((GMimeMessagePart *) part); // transfer none
      if (message)
        g_mime_message_foreach(message, collector_foreach_callback, user_data);

    } else {
      g_printerr("endless recursion detected: %d\r\n", fdata->recursion_depth);
      return;
    }

  } else if (GMIME_IS_MESSAGE_PARTIAL(part)) {
    // Save into an array ? Todo: Look into the specs
  } else if (GMIME_IS_MULTIPART(part)) {
    // Nothing special needed on multipart, let descend further
  } else if (GMIME_IS_PART(part)) {
    collect_part(part, fdata, GMIME_IS_MULTIPART(parent));
    fdata->part_id++;
  } else {
    g_assert_not_reached();
  }
}
示例#7
0
static gboolean
handle_mime_object (MuMsg *msg, GMimeObject *mobj, GMimeObject *parent,
		    MuMsgOptions opts, unsigned *index, gboolean decrypted,
		    MuMsgPartForeachFunc func, gpointer user_data)
{
	if (GMIME_IS_PART (mobj))
		return handle_part
			(msg, GMIME_PART(mobj), parent,
			 opts, index, decrypted, func, user_data);
	else if (GMIME_IS_MESSAGE_PART (mobj))
		return handle_message_part
			(msg, GMIME_MESSAGE_PART(mobj),
			 parent, opts, index, decrypted, func, user_data);
	else if ((opts & MU_MSG_OPTION_VERIFY) &&
	         GMIME_IS_MULTIPART_SIGNED (mobj)) {
		check_signature
			(msg, GMIME_MULTIPART_SIGNED (mobj), opts);
		return handle_multipart
			(msg, GMIME_MULTIPART (mobj), mobj, opts,
			 index, decrypted, func, user_data);
	} else if ((opts & MU_MSG_OPTION_DECRYPT) &&
	           GMIME_IS_MULTIPART_ENCRYPTED (mobj))
		return handle_encrypted_part
			(msg, GMIME_MULTIPART_ENCRYPTED (mobj),
			 opts, index, func, user_data);
	else if (GMIME_IS_MULTIPART (mobj))
		return handle_multipart
			(msg, GMIME_MULTIPART (mobj), parent, opts,
			 index, decrypted, func, user_data);
	return TRUE;
}
示例#8
0
/**
 * g_mime_message_part_get_message:
 * @part: message part
 *
 * Gets the message object on the message part object @part.
 *
 * Returns: (transfer none): the message part contained within @part.
 **/
GMimeMessage *
g_mime_message_part_get_message (GMimeMessagePart *part)
{
	g_return_val_if_fail (GMIME_IS_MESSAGE_PART (part), NULL);
	
	return part->message;
}
示例#9
0
/**
 * g_mime_message_part_set_message:
 * @part: message part
 * @message: message
 *
 * Sets the @message object on the message part object @part.
 **/
void
g_mime_message_part_set_message (GMimeMessagePart *part, GMimeMessage *message)
{
	g_return_if_fail (GMIME_IS_MESSAGE_PART (part));
	
	if (message)
		g_object_ref (message);
	
	if (part->message)
		g_object_unref (part->message);
	
	part->message = message;
}
示例#10
0
文件: mu-msg-part.c 项目: otfrom/mu
char*
mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts)
{
	GMimeObject  *mobj;
	GMimeMessage *mime_msg;
	gboolean err;

	g_return_val_if_fail (msg, NULL);
	g_return_val_if_fail (self && self->data, NULL);

	mobj = (GMimeObject*)self->data;

	err = FALSE;
	if (GMIME_IS_PART (mobj)) {
		if (self->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN)
			return mu_msg_mime_part_to_string ((GMimePart*)mobj, &err);
		else
			return NULL; /* non-text MimePart */
	}

	mime_msg = NULL;
	if (GMIME_IS_MESSAGE_PART (mobj))
		mime_msg = g_mime_message_part_get_message
			((GMimeMessagePart*)mobj);
	else if (GMIME_IS_MESSAGE (mobj))
		mime_msg = (GMimeMessage*)mobj;

	if (mime_msg) {
		GString *gstr;
		gstr = g_string_sized_new (4096);
		handle_children (msg, mime_msg, opts, self->index,
 				 (MuMsgPartForeachFunc)accumulate_text,
				 &gstr);
		return g_string_free (gstr, FALSE);
	} else {
		g_warning ("%s: cannot get text for %s",
			   __FUNCTION__, G_OBJECT_TYPE_NAME (mobj));
		return NULL;
	}
}
示例#11
0
int remove_part(GMimeObject *parent, GMimeObject *part) {
  int attachment = is_attachment(part);

  if (attachment && GMIME_IS_MULTIPART(parent)) {
    g_mime_multipart_remove((GMimeMultipart*)parent, part);
    return 1;
  }
  else if (attachment && GMIME_IS_MESSAGE(parent)) { // I'm not sure if this could ever occur or even makes sense.
    GMimePart *new_part;
    new_part = g_mime_part_new_with_type("text", "plain");
    g_mime_part_set_content_object(new_part,
				   g_mime_data_wrapper_new_with_stream(g_mime_stream_mem_new_with_buffer("Attachment Removed.", 19),
								       GMIME_CONTENT_ENCODING_DEFAULT));
    g_mime_message_set_mime_part((GMimeMessage*)parent, (GMimeObject*)new_part);
    g_object_unref(part);
  }
  else if (GMIME_IS_MESSAGE_PART(part)) {
    remove_message(g_mime_message_part_get_message((GMimeMessagePart*)part));
  }

  return 0;
}
示例#12
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));
	}
}
示例#13
0
文件: test-mbox.c 项目: GNOME/gmime
static void
print_mime_struct (GMimeStream *stream, GMimeObject *part, int depth)
{
	GMimeMultipart *multipart;
	GMimeMessagePart *mpart;
	GMimeContentType *type;
	GMimeObject *subpart;
	GMimeObject *body;
	GMimeMessage *msg;
	int i, n;
	
	print_depth (stream, depth);
	
	type = g_mime_object_get_content_type (part);
	
	g_mime_stream_printf (stream, "Content-Type: %s/%s\n",
			      g_mime_content_type_get_media_type (type),
			      g_mime_content_type_get_media_subtype (type));
	
	if (GMIME_IS_MULTIPART (part)) {
		multipart = (GMimeMultipart *) part;
		
		n = g_mime_multipart_get_count (multipart);
		for (i = 0; i < n; i++) {
			subpart = g_mime_multipart_get_part (multipart, i);
			print_mime_struct (stream, subpart, depth + 1);
		}
	} else if (GMIME_IS_MESSAGE_PART (part)) {
		mpart = (GMimeMessagePart *) part;
		msg = g_mime_message_part_get_message (mpart);
		
		if (msg != NULL) {
			body = g_mime_message_get_mime_part (msg);
			
			print_mime_struct (stream, body, depth + 1);
		}
	}
}
示例#14
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);
	}
}
示例#15
0
文件: mu-msg-part.c 项目: otfrom/mu
static gboolean
handle_mime_object (MuMsg *msg,
		    GMimeObject *mobj, GMimeObject *parent, MuMsgOptions opts,
		    unsigned index, MuMsgPartForeachFunc func, gpointer user_data)
{
	if (GMIME_IS_PART (mobj))
		return handle_part
			(msg, GMIME_PART(mobj), parent,
			 opts, index, func, user_data);
	else if (GMIME_IS_MESSAGE_PART (mobj))
		return handle_message_part
			(msg, GMIME_MESSAGE_PART(mobj),
			 parent, opts, index, func, user_data);
	else if (GMIME_IS_MULTIPART_SIGNED (mobj))
		return handle_signed_part
				(msg, GMIME_MULTIPART_SIGNED (mobj),
				 parent, opts, index, func, user_data);
	else if (GMIME_IS_MULTIPART_ENCRYPTED (mobj))
		return handle_encrypted_part
			(msg, GMIME_MULTIPART_ENCRYPTED (mobj),
			 parent, opts, index, func, user_data);

	return TRUE;
}
示例#16
0
char*
mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts)
{
	GMimeObject  *mobj;
	GMimeMessage *mime_msg;
	gboolean err;

	g_return_val_if_fail (msg, NULL);
	g_return_val_if_fail (self && GMIME_IS_OBJECT(self->data),
			      NULL);

	mobj = (GMimeObject*)self->data;

	err = FALSE;
	if (GMIME_IS_PART (mobj)) {
		if (self->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN)
			return mu_msg_mime_part_to_string ((GMimePart*)mobj,
							   &err);
		else
			return NULL; /* non-text MimePart */
	}

	mime_msg = NULL;

	if (GMIME_IS_MESSAGE_PART (mobj))
		mime_msg = g_mime_message_part_get_message
			((GMimeMessagePart*)mobj);
	else if (GMIME_IS_MESSAGE (mobj))
		mime_msg = (GMimeMessage*)mobj;

	/* apparently, g_mime_message_part_get_message may still
	 * return NULL */
 	if (mime_msg)
		return get_text_from_mime_msg (msg, mime_msg, opts);
	return NULL;
}
示例#17
0
static void
count_foreach_callback (GMimeObject *parent, GMimeObject *part, gpointer user_data)
{
    int *count = user_data;
    (*count)++;

    /* 'part' points to the current part node that
     * g_mime_message_foreach() is iterating over */

    /* find out what class 'part' is... */
    if (GMIME_IS_MESSAGE_PART (part))
    {
        /* message/rfc822 or message/news */
        GMimeMessage *message;

        /* g_mime_message_foreach() 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() again here. */
        printf("\n===============descend into subparts=================\n");
        message = g_mime_message_part_get_message ((GMimeMessagePart *) part);
        g_mime_message_foreach (message, count_foreach_callback, count);
    }
    else if (GMIME_IS_MESSAGE_PARTIAL (part))
    {
        /* message/partial */

        /* this is an incomplete message part, probably a
                   large message that the sender has broken into
                   smaller parts and is sending us bit by bit. we
                   could save some info about it so that we could
                   piece this back together again once we get all the
                   parts? */
        printf("\n===============partial=================\n");
    }
    else if (GMIME_IS_MULTIPART (part))
    {
        /* multipart/mixed, multipart/alternative,
         * multipart/related, multipart/signed,
         * multipart/encrypted, etc... */

        /* we'll get to finding out if this is a
         * signed/encrypted multipart later... */
        printf("\n===============multipart=================\n");
    }
    else if (GMIME_IS_PART (part))
    {
        /* a normal leaf part, could be text/plain or
         * image/jpeg etc */
        printf("\n===============normal leaf part=================\n");
        printf("====>>>>====>>>>====>>>>Decode start here<<<<====<<<<====<<<<====\n");
        {
#if 0
            printf("\ndecode this normal leaf part================\n" );
            //GMimeStream *stream = g_mime_stream_file_new (stdout);
            //GMimeDataWrapper * content=g_mime_part_get_content_object(part);
            //g_mime_data_wrapper_write_to_stream(content,stream);
#endif
        }
        AnalyseMessageParse((GMimePart*)part);
    }
    else
    {
        printf("\n===============descend not reached=================\n");
        g_assert_not_reached ();
    }
}
示例#18
0
文件: crypto.c 项目: notmuch/notmuch
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;
}