void sipe_mime_parts_foreach(const gchar *type, const gchar *body, sipe_mime_parts_cb callback, gpointer user_data) { gchar *doc = g_strdup_printf("Content-Type: %s\r\n\r\n%s", type, body); GMimeStream *stream = g_mime_stream_mem_new_with_buffer(doc, strlen(doc)); if (stream) { GMimeParser *parser = g_mime_parser_new_with_stream(stream); GMimeMultipart *multipart = (GMimeMultipart *)g_mime_parser_construct_part(parser); if (multipart) { struct gmime_callback_data cd = {callback, user_data}; SIPE_DEBUG_INFO("sipe_mime_parts_foreach: %d parts", g_mime_multipart_get_count(multipart)); g_mime_multipart_foreach(multipart, gmime_callback, &cd); g_object_unref(multipart); } g_object_unref(parser); g_object_unref(stream); } g_free(doc); }
/** * 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); } }
void remove_multipart(GMimeMultipart *multipart) { int i=0; while (i < g_mime_multipart_get_count(multipart)) { int removed = remove_part((GMimeObject*)multipart, g_mime_multipart_get_part(multipart, i)); if (!removed) i++; } }
static void multipart_encode (GMimeObject *object, GMimeEncodingConstraint constraint) { GMimeMultipart *multipart = (GMimeMultipart *) object; GMimeObject *subpart; int i; for (i = 0; i < g_mime_multipart_get_count (multipart); i++) { subpart = g_mime_multipart_get_part (multipart, i); g_mime_object_encode (subpart, constraint); } }
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); } } }
GMimeGpgmeSigstat * g_mime_gpgme_mps_verify(GMimeMultipartSigned * mps, GError ** error) { const gchar *protocol; gpgme_protocol_t crypto_prot; gchar *content_type; GMimeObject *content; GMimeObject *signature; GMimeStream *stream; GMimeStream *filtered_stream; GMimeFilter *crlf_filter; GMimeDataWrapper *wrapper; GMimeStream *sigstream; GMimeGpgmeSigstat *result; g_return_val_if_fail(GMIME_IS_MULTIPART_SIGNED(mps), NULL); if (g_mime_multipart_get_count(GMIME_MULTIPART(mps)) < 2) { g_set_error(error, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR, "%s", _ ("Cannot verify multipart/signed part due to missing subparts.")); return NULL; } /* grab the protocol so we can configure the GpgME context */ protocol = g_mime_object_get_content_type_parameter(GMIME_OBJECT(mps), "protocol"); if (protocol) { if (g_ascii_strcasecmp("application/pgp-signature", protocol) == 0) crypto_prot = GPGME_PROTOCOL_OpenPGP; else if (g_ascii_strcasecmp ("application/pkcs7-signature", protocol) == 0 || g_ascii_strcasecmp("application/x-pkcs7-signature", protocol) == 0) crypto_prot = GPGME_PROTOCOL_CMS; else crypto_prot = GPGME_PROTOCOL_UNKNOWN; } else crypto_prot = GPGME_PROTOCOL_UNKNOWN; /* eject on unknown protocols */ if (crypto_prot == GPGME_PROTOCOL_UNKNOWN) { g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_INV_VALUE, _("unsupported protocol “%s”"), protocol); return NULL; } signature = g_mime_multipart_get_part(GMIME_MULTIPART(mps), GMIME_MULTIPART_SIGNED_SIGNATURE); /* make sure the protocol matches the signature content-type */ content_type = g_mime_content_type_to_string(signature->content_type); if (g_ascii_strcasecmp(content_type, protocol) != 0) { g_set_error(error, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR, "%s", _ ("Cannot verify multipart/signed part: signature content-type does not match protocol.")); g_free(content_type); return NULL; } g_free(content_type); content = g_mime_multipart_get_part(GMIME_MULTIPART(mps), GMIME_MULTIPART_SIGNED_CONTENT); /* get the content stream */ stream = g_mime_stream_mem_new(); filtered_stream = g_mime_stream_filter_new(stream); /* Note: see rfc2015 or rfc3156, section 5.1 */ 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); g_mime_stream_reset(stream); /* get the signature stream */ wrapper = g_mime_part_get_content_object(GMIME_PART(signature)); /* a s/mime signature is always encoded, a pgp signature shouldn't, * but there exist implementations which encode it... */ sigstream = g_mime_stream_mem_new(); g_mime_data_wrapper_write_to_stream(wrapper, sigstream); g_mime_stream_reset(sigstream); /* verify the signature */ result = libbalsa_gpgme_verify(stream, sigstream, crypto_prot, FALSE, error); g_object_unref(stream); g_object_unref(sigstream); return result; }