Exemplo n.º 1
0
static void
pump_data_through_filter (GMimeFilter *filter, const char *path, GMimeStream *ostream, gboolean is_text, gboolean inc)
{
	GMimeStream *onebyte, *filtered, *stream;
	GMimeFilter *dos2unix;
	
	filtered = g_mime_stream_filter_new (ostream);
	
	if (is_text) {
		/* canonicalize text input */
		dos2unix = g_mime_filter_dos2unix_new (FALSE);
		g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, dos2unix);
		g_object_unref (dos2unix);
	}
	
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
	
	if (inc) {
		onebyte = test_stream_onebyte_new (filtered);
		g_object_unref (filtered);
	} else {
		onebyte = filtered;
	}
	
	stream = g_mime_stream_fs_open (path, O_RDONLY, 0644, NULL);
	g_mime_stream_write_to_stream (stream, onebyte);
	g_mime_stream_flush (onebyte);
	g_object_unref (onebyte);
	g_object_unref (stream);
}
Exemplo n.º 2
0
static GMimeStream* create_stream(GMimeContentEncoding en, const gchar* fn)
{
    GMimeStream* rv = NULL;
    FILE*        f = fopen(fn, "r");
    GMimeStream* fst = NULL;

    if ( f ) {
        fst = g_mime_stream_file_new(f);
    }

    if ( fst ) {
        switch (en) {
            case GMIME_CONTENT_ENCODING_DEFAULT:
            {
                rv = fst;
            }
            break;
            
            default:
            {
                GMimeFilter* flt = g_mime_filter_basic_new(en, TRUE);
                
                rv = g_mime_stream_filter_new(fst);
                g_mime_stream_filter_add(GMIME_STREAM_FILTER(rv), flt);
                g_object_unref(flt);
                g_object_unref(fst);
            }
            break;
        }
    } else {
        g_warning("failed to open '%s'", fn);
    }

    return rv;
}
Exemplo n.º 3
0
/**
 * g_mime_part_get_best_content_encoding:
 * @mime_part: a #GMimePart object
 * @constraint: a #GMimeEncodingConstraint
 *
 * Calculates the most efficient content encoding for the @mime_part
 * given the @constraint.
 *
 * Returns: the best content encoding for the specified mime part.
 **/
GMimeContentEncoding
g_mime_part_get_best_content_encoding (GMimePart *mime_part, GMimeEncodingConstraint constraint)
{
	GMimeStream *filtered, *stream;
	GMimeContentEncoding encoding;
	GMimeFilterBest *best;
	GMimeFilter *filter;
	
	g_return_val_if_fail (GMIME_IS_PART (mime_part), GMIME_CONTENT_ENCODING_DEFAULT);
	
	stream = g_mime_stream_null_new ();
	filtered = g_mime_stream_filter_new (stream);
	g_object_unref (stream);
	
	filter = g_mime_filter_best_new (GMIME_FILTER_BEST_ENCODING);
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
	best = (GMimeFilterBest *) filter;
	
	g_mime_data_wrapper_write_to_stream (mime_part->content, filtered);
	g_mime_stream_flush (filtered);
	g_object_unref (filtered);
	
	encoding = g_mime_filter_best_encoding (best, constraint);
	g_object_unref (best);
	
	return encoding;
}
Exemplo n.º 4
0
static GByteArray *
read_all_bytes (const char *path, gboolean is_text)
{
	GMimeStream *filtered, *stream, *mem;
	GMimeFilter *filter;
	GByteArray *buffer;
	
	buffer = g_byte_array_new ();
	stream = g_mime_stream_fs_open (path, O_RDONLY, 0644, NULL);
	mem = g_mime_stream_mem_new_with_byte_array (buffer);
	g_mime_stream_mem_set_owner ((GMimeStreamMem *) mem, FALSE);
	
	if (is_text) {
		filtered = g_mime_stream_filter_new (mem);
		filter = g_mime_filter_dos2unix_new (FALSE);
		g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
		g_object_unref (filter);
		g_object_unref (mem);
	} else {
		filtered = mem;
	}
	
	g_mime_stream_write_to_stream (stream, filtered);
	g_mime_stream_flush (filtered);
	g_object_unref (filtered);
	g_object_unref (stream);
	
	return buffer;
}
Exemplo n.º 5
0
static void
pump_data_through_filter (GMimeFilter *filter, const char *path, GMimeStream *ostream)
{
	GMimeStream *onebyte, *filtered, *stream;
	GMimeFilter *unix2dos, *dos2unix;
	
	filtered = g_mime_stream_filter_new (ostream);
	
	/* convert to DOS format before piping through the OpenPGP filter to maximize testing area */
	unix2dos = g_mime_filter_unix2dos_new (FALSE);
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, unix2dos);
	g_object_unref (unix2dos);
	
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
	
	/* convert back to UNIX format after filtering */
	dos2unix = g_mime_filter_dos2unix_new (FALSE);
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, dos2unix);
	g_object_unref (dos2unix);
	
	onebyte = test_stream_onebyte_new (filtered);
	g_object_unref (filtered);
	
	stream = g_mime_stream_fs_open (path, O_RDONLY, 0644, NULL);
	g_mime_stream_write_to_stream (stream, onebyte);
	g_mime_stream_flush (onebyte);
	g_object_unref (onebyte);
	g_object_unref (stream);
}
Exemplo n.º 6
0
static void
format_part_content_raw (GMimeObject *part)
{
    if (! GMIME_IS_PART (part))
	return;

    GMimeStream *stream_stdout;
    GMimeStream *stream_filter = NULL;
    GMimeDataWrapper *wrapper;

    stream_stdout = g_mime_stream_file_new (stdout);
    g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);

    stream_filter = g_mime_stream_filter_new (stream_stdout);

    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);
}
Exemplo n.º 7
0
static GMimeStream *
g_mime_data_wrapper_get_decoded_stream(GMimeDataWrapper * wrapper)
{
    GMimeStream *decoded_stream;
    GMimeFilter *decoder;

    g_mime_stream_reset(wrapper->stream);

    switch (wrapper->encoding) {
    case GMIME_CONTENT_ENCODING_BASE64:
    case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE:
    case GMIME_CONTENT_ENCODING_UUENCODE:
	decoder = g_mime_filter_basic_new(wrapper->encoding, FALSE);
	decoded_stream = g_mime_stream_filter_new(wrapper->stream);
	g_mime_stream_filter_add(GMIME_STREAM_FILTER(decoded_stream),
				 decoder);
	g_object_unref(decoder);
	break;
    default:
	decoded_stream = wrapper->stream;
	g_object_ref(wrapper->stream);
	break;
    }

    return decoded_stream;
}
Exemplo n.º 8
0
static void write_result(GMimeMessage* m, const char* fn)
{
    FILE* of = stdout;

    if ( fn ) {
        of = fopen(fn, "w");
    }

    GMimeStream* fst = g_mime_stream_file_new(of);
    GMimeFilter* flt = g_mime_filter_crlf_new(TRUE, FALSE);
    GMimeStream* st = g_mime_stream_filter_new(fst);
    time_t       dt;
    int          tz_off = 0;
    
    if ( !g_mime_message_get_message_id(m) ) {
        char* mid = g_mime_utils_generate_message_id("MG");
        g_mime_message_set_message_id(m, mid);
        g_free(mid);
    }
    g_mime_message_get_date(m, &dt, &tz_off);
    if ( !dt ) {
        g_mime_message_set_date(m, time(NULL), 0);
    }
    g_mime_stream_filter_add(GMIME_STREAM_FILTER(st), flt);
    g_mime_object_write_to_stream(GMIME_OBJECT(m), st);

    g_object_unref(st);
    g_object_unref(flt);
    g_object_unref(fst);
}
Exemplo 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, "multipart", "*") ||
	g_mime_content_type_is_type (content_type, "message", "rfc822"))
    {
	/* Output nothing, since multipart subparts will be handled individually. */
    }
    else 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 = 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));
	}
    }
}
Exemplo n.º 10
0
/**
 * g_mime_part_set_content_md5:
 * @mime_part: a #GMimePart object
 * @content_md5: content md5 or %NULL to generate the md5 digest.
 *
 * Set the content md5 for the specified mime part.
 **/
void
g_mime_part_set_content_md5 (GMimePart *mime_part, const char *content_md5)
{
	unsigned char digest[16], b64digest[32];
	GMimeStreamFilter *filtered_stream;
	GMimeContentType *content_type;
	GMimeFilter *md5_filter;
	GMimeStream *stream;
	guint32 save = 0;
	int state = 0;
	size_t len;
	
	g_return_if_fail (GMIME_IS_PART (mime_part));
	
	g_free (mime_part->content_md5);
	
	if (!content_md5) {
		/* compute a md5sum */
		stream = g_mime_stream_null_new ();
		filtered_stream = (GMimeStreamFilter *) g_mime_stream_filter_new (stream);
		g_object_unref (stream);
		
		content_type = g_mime_object_get_content_type ((GMimeObject *) mime_part);
		if (g_mime_content_type_is_type (content_type, "text", "*")) {
			GMimeFilter *crlf_filter;
			
			crlf_filter = g_mime_filter_crlf_new (TRUE, FALSE);
			g_mime_stream_filter_add (filtered_stream, crlf_filter);
			g_object_unref (crlf_filter);
		}
		
		md5_filter = g_mime_filter_md5_new ();
		g_mime_stream_filter_add (filtered_stream, md5_filter);
		
		stream = (GMimeStream *) filtered_stream;
		g_mime_data_wrapper_write_to_stream (mime_part->content, stream);
		g_object_unref (stream);
		
		memset (digest, 0, 16);
		g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) md5_filter, digest);
		g_object_unref (md5_filter);
		
		len = g_mime_encoding_base64_encode_close (digest, 16, b64digest, &state, &save);
		b64digest[len] = '\0';
		g_strstrip ((char *) b64digest);
		
		content_md5 = (const char *) b64digest;
	}
	
	mime_part->content_md5 = g_strdup (content_md5);
	g_mime_header_list_set (GMIME_OBJECT (mime_part)->headers, "Content-Md5", content_md5);
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
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));
	}
    }
}
Exemplo n.º 13
0
/**
 * g_mime_part_verify_content_md5:
 * @mime_part: a #GMimePart object
 *
 * Verify the content md5 for the specified mime part.
 *
 * Returns: %TRUE if the md5 is valid or %FALSE otherwise. Note: will
 * return %FALSE if the mime part does not contain a Content-MD5.
 **/
gboolean
g_mime_part_verify_content_md5 (GMimePart *mime_part)
{
	unsigned char digest[16], b64digest[32];
	GMimeStreamFilter *filtered_stream;
	GMimeContentType *content_type;
	GMimeFilter *md5_filter;
	GMimeStream *stream;
	guint32 save = 0;
	int state = 0;
	size_t len;
	
	g_return_val_if_fail (GMIME_IS_PART (mime_part), FALSE);
	g_return_val_if_fail (mime_part->content != NULL, FALSE);
	
	if (!mime_part->content_md5)
		return FALSE;
	
	stream = g_mime_stream_null_new ();
	filtered_stream = (GMimeStreamFilter *) g_mime_stream_filter_new (stream);
	g_object_unref (stream);
	
	content_type = g_mime_object_get_content_type ((GMimeObject *) mime_part);
	if (g_mime_content_type_is_type (content_type, "text", "*")) {
		GMimeFilter *crlf_filter;
		
		crlf_filter = g_mime_filter_crlf_new (TRUE, FALSE);
		g_mime_stream_filter_add (filtered_stream, crlf_filter);
		g_object_unref (crlf_filter);
	}
	
	md5_filter = g_mime_filter_md5_new ();
	g_mime_stream_filter_add (filtered_stream, md5_filter);
	
	stream = (GMimeStream *) filtered_stream;
	g_mime_data_wrapper_write_to_stream (mime_part->content, stream);
	g_object_unref (stream);
	
	memset (digest, 0, 16);
	g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) md5_filter, digest);
	g_object_unref (md5_filter);
	
	len = g_mime_encoding_base64_encode_close (digest, 16, b64digest, &state, &save);
	b64digest[len] = '\0';
	g_strstrip ((char *) b64digest);
	
	return !strcmp ((char *) b64digest, mime_part->content_md5);
}
Exemplo n.º 14
0
static void
mime_part_encode (GMimeObject *object, GMimeEncodingConstraint constraint)
{
	GMimePart *part = (GMimePart *) object;
	GMimeContentEncoding encoding;
	GMimeStream *stream, *null;
	GMimeFilter *filter;
	
	switch (part->encoding) {
	case GMIME_CONTENT_ENCODING_DEFAULT:
		/* Unspecified encoding, we need to figure out the
		 * best encoding no matter what */
		break;
	case GMIME_CONTENT_ENCODING_7BIT:
		/* This encoding is always safe. */
		return;
	case GMIME_CONTENT_ENCODING_8BIT:
		/* This encoding is safe unless the constraint is 7bit. */
		if (constraint != GMIME_ENCODING_CONSTRAINT_7BIT)
			return;
		break;
	case GMIME_CONTENT_ENCODING_BINARY:
		/* This encoding is only safe if the constraint is binary. */
		if (constraint == GMIME_ENCODING_CONSTRAINT_BINARY)
			return;
		break;
	case GMIME_CONTENT_ENCODING_BASE64:
	case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE:
	case GMIME_CONTENT_ENCODING_UUENCODE:
		/* These encodings are always safe. */
		return;
	}
	
	filter = g_mime_filter_best_new (GMIME_FILTER_BEST_ENCODING);
	
	null = g_mime_stream_null_new ();
	stream = g_mime_stream_filter_new (null);
	g_mime_stream_filter_add ((GMimeStreamFilter *) stream, filter);
	g_object_unref (null);
	
	g_mime_object_write_to_stream (object, stream);
	g_object_unref (stream);
	
	encoding = g_mime_filter_best_encoding ((GMimeFilterBest *) filter, constraint);
	g_mime_part_set_content_encoding (part, encoding);
	g_object_unref (filter);
}
Exemplo n.º 15
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);
    }
}
Exemplo n.º 16
0
static notmuch_status_t
format_part_raw (unused (const void *ctx), mime_node_t *node,
                 unused (int indent),
                 unused (const notmuch_show_params_t *params))
{
    if (node->envelope_file) {
        /* Special case the entire message to avoid MIME parsing. */
        const char *filename;
        FILE *file;
        size_t size;
        char buf[4096];

        filename = notmuch_message_get_filename (node->envelope_file);
        if (filename == NULL) {
            fprintf (stderr, "Error: Cannot get message filename.\n");
            return NOTMUCH_STATUS_FILE_ERROR;
        }

        file = fopen (filename, "r");
        if (file == NULL) {
            fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
            return NOTMUCH_STATUS_FILE_ERROR;
        }

        while (!feof (file)) {
            size = fread (buf, 1, sizeof (buf), file);
            if (ferror (file)) {
                fprintf (stderr, "Error: Read failed from %s\n", filename);
                fclose (file);
                return NOTMUCH_STATUS_FILE_ERROR;
            }

            if (fwrite (buf, size, 1, stdout) != 1) {
                fprintf (stderr, "Error: Write failed\n");
                fclose (file);
                return NOTMUCH_STATUS_FILE_ERROR;
            }
        }

        fclose (file);
        return NOTMUCH_STATUS_SUCCESS;
    }

    GMimeStream *stream_stdout;
    GMimeStream *stream_filter = NULL;

    stream_stdout = g_mime_stream_file_new (stdout);
    g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);

    stream_filter = g_mime_stream_filter_new (stream_stdout);

    if (GMIME_IS_PART (node->part)) {
        /* For leaf parts, we emit only the transfer-decoded
         * body. */
        GMimeDataWrapper *wrapper;
        wrapper = g_mime_part_get_content_object (GMIME_PART (node->part));

        if (wrapper && stream_filter)
            g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
    } else {
        /* Write out the whole part.  For message parts (the root
         * part and embedded message parts), this will be the
         * message including its headers (but not the
         * encapsulating part's headers).  For multipart parts,
         * this will include the headers. */
        if (stream_filter)
            g_mime_object_write_to_stream (node->part, stream_filter);
    }

    if (stream_filter)
        g_object_unref (stream_filter);

    if (stream_stdout)
        g_object_unref(stream_stdout);

    return NOTMUCH_STATUS_SUCCESS;
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
static int
uuencode (const char *progname, int argc, char **argv)
{
	GMimeStream *istream, *ostream, *fstream;
	GMimeContentEncoding encoding;
	const char *filename, *name;
	GMimeFilter *filter;
	gboolean base64;
	struct stat st;
	int fd, opt;
	
	base64 = FALSE;
	encoding = GMIME_CONTENT_ENCODING_UUENCODE;
	while ((opt = getopt_long (argc, argv, "hvm", longopts, NULL)) != -1) {
		switch (opt) {
		case 'h':
			usage (progname);
			return 0;
		case 'v':
			version (progname);
			return 0;
		case 'm':
			base64 = TRUE;
			encoding = GMIME_CONTENT_ENCODING_BASE64;
			break;
		default:
			printf ("Try `%s --help' for more information.\n", progname);
			return -1;
		}
	}
	
	if (optind >= argc) {
		printf ("Try `%s --help' for more information.\n", progname);
		return -1;
	}
	
	if (optind + 1 < argc)
		filename = argv[optind++];
	else
		filename = NULL;
	
	name = argv[optind];
	
	/* open our input file... */
	if ((fd = filename ? open (filename, O_RDONLY, 0) : dup (0)) == -1) {
		fprintf (stderr, "%s: %s: %s\n", progname,
			 filename ? filename : "stdin",
			 g_strerror (errno));
		return -1;
	}
	
	/* stat() our input file for file mode permissions */
	if (fstat (fd, &st) == -1) {
		fprintf (stderr, "%s: %s: %s\n", progname,
			 filename ? filename : "stdin",
			 g_strerror (errno));
		close (fd);
		return -1;
	}
	
	printf ("begin%s %.3o %s\n", base64 ? "-base64" : "", st.st_mode & 0777, name);
	fflush (stdout);
	
	istream = g_mime_stream_fs_new (fd);
	
	/* open our output stream */
	ostream = g_mime_stream_fs_new (1);
	g_mime_stream_fs_set_owner ((GMimeStreamFs *) ostream, FALSE);
	
	fstream = g_mime_stream_filter_new (ostream);
	
	/* attach an encode filter */
	filter = g_mime_filter_basic_new (encoding, TRUE);
	g_mime_stream_filter_add ((GMimeStreamFilter *) fstream, filter);
	g_object_unref (filter);
	
	if (g_mime_stream_write_to_stream (istream, fstream) == -1) {
		fprintf (stderr, "%s: %s\n", progname, g_strerror (errno));
		g_object_unref (fstream);
		g_object_unref (istream);
		g_object_unref (ostream);
		return -1;
	}
	
	g_mime_stream_flush (fstream);
	g_object_unref (fstream);
	g_object_unref (istream);
	
	if (g_mime_stream_write_string (ostream, base64 ? "====\n" : "end\n") == -1) {
		fprintf (stderr, "%s: %s\n", progname, g_strerror (errno));
		g_object_unref (ostream);
		return -1;
	}
	
	g_object_unref (ostream);
	
	return 0;
}
Exemplo n.º 20
0
void AnalyseMessageParse(GMimePart * mime_part)
{
    int ichar=0,iencode =0;

    if( NULL==mime_part )
    {
        printf("empty part\n");
        return ;
    }

    GMimeContentEncoding ReEncoding = g_mime_part_get_content_encoding(mime_part);

    char* szCharset = (char*)g_mime_object_get_content_type_parameter((GMimeObject*)mime_part,"charset");
    printf("charset %s\n",szCharset);

    {
        char* szCharset = (char*)g_mime_object_get_content_type_parameter((GMimeObject*)mime_part,"name");
        printf("name %s\n",szCharset);
        GMimeContentType* pContentType = g_mime_object_get_content_type((GMimeObject*)mime_part) ;
        printf("The content type is: (%s/%s)\n",pContentType->type,pContentType->subtype);
        const char *  ppp= g_mime_object_get_disposition((GMimeObject*)mime_part);
        if(!ppp)
        {
            goto exits;
        }
        const char * qqq=g_mime_object_get_content_disposition_parameter((GMimeObject*)mime_part,"filename");
        printf("get disposition\t%s\n%s\n",ppp,qqq);
        if(qqq)
        {
            FILE * ps=fopen(qqq,"w+b");
            printf("\n=======write to file================\n" );
            GMimeStream *stream = g_mime_stream_file_new (ps);
            GMimeDataWrapper * content=g_mime_part_get_content_object(mime_part);
            g_mime_data_wrapper_write_to_stream(content,stream);
            fclose(ps);
            printf("finish writing\n");
            getchar();
            return ;
        }
    }

exits:{}
    /*decode for text/plain or html*/
    GMimeDataWrapper *dataWrap = g_mime_part_get_content_object(mime_part);
    if(!dataWrap)
        printf("error in dataWrap\n" );

    GMimeStream * gmime_stream= g_mime_data_wrapper_get_stream(dataWrap);
    //encoding转码
    GMimeFilter * pAttFilter =  g_mime_filter_basic_new(ReEncoding,FALSE);
    GMimeStream* pFilterStream =  g_mime_stream_filter_new(gmime_stream);

    iencode = g_mime_stream_filter_add (GMIME_STREAM_FILTER (pFilterStream), pAttFilter);

    /*create a filter convert the charset into local type*/
    GMimeFilter * secondPtr =  g_mime_filter_charset_new(szCharset,g_mime_charset_locale_name());
    ichar = g_mime_stream_filter_add (GMIME_STREAM_FILTER (pFilterStream), secondPtr);

    /*convert stream into stdout*/
    GMimeStream *stream = g_mime_stream_file_new (stdout);
    g_mime_stream_write_to_stream(pFilterStream,stream);
#if 0
    /*get data from stream load into char* */
    char pp[10000]= {0};
    int tt=g_mime_stream_read(pFilterStream,pp,10000);

    printf("%d\t%s\n",tt,pp);
#endif

    g_object_unref ( pAttFilter );
    g_object_unref ( secondPtr );


    g_mime_stream_filter_remove((GMimeStreamFilter*)pFilterStream,ichar);
    g_mime_stream_filter_remove((GMimeStreamFilter*)pFilterStream,iencode);
    g_object_unref (pFilterStream);
    //g_object_unref (gmime_stream);
    //g_object_unref (stream);

    //if(NULL==szCharset)
    {
        printf("\n====>>>>====>>>>====>>>>Finish decoding this part<<<<====<<<<====<<<<====\n");
        getchar();
        //return ;
    }
    return ;
}
Exemplo n.º 21
0
static void collect_part(GMimeObject *part, PartCollectorData *fdata, gboolean multipart_parent) {
  GMimeContentType        *content_type = g_mime_object_get_content_type(part);
  GMimeContentDisposition *disposition  = g_mime_object_get_content_disposition(part);

  if (!content_type)
    return;

  GMimeDataWrapper *wrapper = g_mime_part_get_content_object(GMIME_PART(part));
  if (!wrapper)
    return;

  // All the information will be collected in the CollectedPart
  CollectedPart *c_part = new_collected_part(fdata->part_id);

  gboolean is_attachment = FALSE;
  if (disposition) {
    c_part->disposition = g_ascii_strdown(disposition->disposition, -1);
    is_attachment = !g_ascii_strcasecmp(disposition->disposition, GMIME_DISPOSITION_ATTACHMENT);
  }

  // If a filename is given, collect it always
  const gchar *filename = g_mime_part_get_filename(GMIME_PART(part));
  if (filename)
    c_part->filename = g_strdup(filename);

  // If a contentID is given, collect it always
  const char* content_id = g_mime_part_get_content_id (GMIME_PART(part));
  if (content_id)
    c_part->content_id = g_strdup(content_id);

  // Get the contentType in lowercase
  gchar *content_type_str = g_mime_content_type_to_string(content_type);
  c_part->content_type = g_ascii_strdown(content_type_str, -1);
  g_free(content_type_str);

  // To qualify as a message body, a MIME entity MUST NOT have a Content-Disposition header with the value "attachment".
  if (!is_attachment && g_mime_content_type_is_type(content_type, "text", "*")) {
    gboolean is_text_plain    = g_mime_content_type_is_type(content_type, "text", "plain");
    gboolean is_text_html     = g_mime_content_type_is_type(content_type, "text", "html");
    gboolean is_text_rtf      = g_mime_content_type_is_type(content_type, "text", "rtf");
    gboolean is_text_enriched = g_mime_content_type_is_type(content_type, "text", "enriched");

    gboolean is_new_text = !fdata->text_part && is_text_plain;
    gboolean is_new_html = !fdata->html_part && (is_text_html || is_text_enriched || is_text_rtf);

    GMimeStream *mem_stream = g_mime_stream_mem_new();
    g_mime_stream_mem_set_owner(GMIME_STREAM_MEM(mem_stream), FALSE);
    GMimeStream *filtered_mem_stream = g_mime_stream_filter_new(mem_stream);

    const gchar *charset = g_mime_object_get_content_type_parameter(part, "charset");
    if (charset && g_ascii_strcasecmp(charset, UTF8_CHARSET)) {
      GMimeFilter *utf8_charset_filter = g_mime_filter_charset_new(charset, UTF8_CHARSET);
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), utf8_charset_filter);
      g_object_unref(utf8_charset_filter);
    }

    if (!fdata->raw && is_new_text) {
      GMimeFilter *strip_filter = g_mime_filter_strip_new();
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), strip_filter);
      g_object_unref(strip_filter);

      GMimeFilter *crlf_filter = g_mime_filter_crlf_new(FALSE, FALSE);
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), crlf_filter);
      g_object_unref(crlf_filter);

      GMimeFilter *html_filter = g_mime_filter_html_new(
         GMIME_FILTER_HTML_CONVERT_NL        |
         GMIME_FILTER_HTML_CONVERT_SPACES    |
         GMIME_FILTER_HTML_CONVERT_URLS      |
         GMIME_FILTER_HTML_MARK_CITATION     |
         GMIME_FILTER_HTML_CONVERT_ADDRESSES |
         GMIME_FILTER_HTML_CITE, CITATION_COLOUR);
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), html_filter);
      g_object_unref(html_filter);
    }

    if (!fdata->raw && (is_new_text || is_new_html)) {
      GMimeFilter *from_filter = g_mime_filter_from_new(GMIME_FILTER_FROM_MODE_ESCAPE);
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), from_filter);
      g_object_unref(from_filter);
    }

    // Add Enriched/RTF filter for this content
    if (!fdata->raw && (is_new_html && (is_text_enriched || is_text_rtf))) {
      guint flags = 0;
      if (is_text_rtf)
        flags = GMIME_FILTER_ENRICHED_IS_RICHTEXT;

      GMimeFilter *enriched_filter = g_mime_filter_enriched_new(flags);
      g_mime_stream_filter_add(GMIME_STREAM_FILTER(filtered_mem_stream), enriched_filter);
      g_object_unref(enriched_filter);
    }
    g_mime_data_wrapper_write_to_stream(wrapper, filtered_mem_stream);

    // Very important! Flush the the stream and get all content through.
    g_mime_stream_flush(filtered_mem_stream);

    // Freed by the mem_stream on its own (owner) [transfer none]
    c_part->content = g_mime_stream_mem_get_byte_array(GMIME_STREAM_MEM(mem_stream));

    // After we unref the mem_stream, part_content is NOT available anymore
    g_object_unref(filtered_mem_stream);
    g_object_unref(mem_stream);

    // Without content, the collected body part is of no use, so we ignore it.
    if (c_part->content->len == 0) {
      free_collected_part(c_part);
      return;
    }

    // We accept only the first text and first html content, everything
    // else is considered an alternative body
    if (is_new_text) {
      fdata->text_part = c_part;
    } else if (is_new_html) {
      fdata->html_part = c_part;
    } else {
      g_ptr_array_add(fdata->alternative_bodies, c_part);
    }

  } else {
    GMimeStream *attachment_mem_stream = g_mime_stream_mem_new();
    g_mime_stream_mem_set_owner (GMIME_STREAM_MEM(attachment_mem_stream), FALSE);
    g_mime_data_wrapper_write_to_stream(wrapper, attachment_mem_stream);
    g_mime_stream_flush(attachment_mem_stream);

    c_part->content = g_mime_stream_mem_get_byte_array(GMIME_STREAM_MEM(attachment_mem_stream));
    g_object_unref(attachment_mem_stream);

    // Some content may not have disposition defined so we need to determine better what it is
    if ((disposition && !g_ascii_strcasecmp(disposition->disposition, GMIME_DISPOSITION_INLINE)) ||
        g_mime_part_get_content_id(GMIME_PART(part))) {
      g_ptr_array_add(fdata->inlines, c_part);
    } else {
      // All other disposition should be kept within attachments
      g_ptr_array_add(fdata->attachments, c_part);
    }

  }
}
Exemplo n.º 22
0
static void
test_openpgp_filter (GMimeFilterOpenPGP *filter, const char *path, GMimeOpenPGPData data_type, gint64 begin, gint64 end)
{
	GMimeStream *filtered, *stream, *expected, *ostream;
	GMimeFilter *dos2unix;
	GMimeOpenPGPData type;
	Exception *ex = NULL;
	GByteArray *buf[2];
	char *filename;
	struct stat st;
	gint64 offset;
	
	ostream = g_mime_stream_mem_new ();
	
	pump_data_through_filter ((GMimeFilter *) filter, path, ostream);
	
	if ((type = g_mime_filter_openpgp_get_data_type (filter)) != data_type) {
		g_object_unref (ostream);
		throw (exception_new ("Incorrect OpenPGP data type detected: %s", openpgp_data_types[type]));
	}
	
	if ((offset = g_mime_filter_openpgp_get_begin_offset (filter)) != begin) {
		g_object_unref (ostream);
		throw (exception_new ("Incorrect begin offset: %ld", (long) offset));
	}
	
	if ((offset = g_mime_filter_openpgp_get_end_offset (filter)) != end) {
		g_object_unref (ostream);
		throw (exception_new ("Incorrect end offset: %ld", (long) offset));
	}
	
	filename = g_strdup_printf ("%s.openpgp-block", path);
	if (stat (filename, &st) == -1) {
		stream = g_mime_stream_fs_open (filename, O_RDWR | O_CREAT, 0644, NULL);
		g_mime_stream_reset (ostream);
		g_mime_stream_write_to_stream (ostream, stream);
		g_mime_stream_flush (stream);
		g_mime_stream_reset (stream);
	} else {
		stream = g_mime_stream_fs_open (filename, O_RDONLY, 0644, NULL);
	}
	g_free (filename);
	
	/* make sure the data is in UNIX format before comparing (might be running tests on Windows) */
	expected = g_mime_stream_mem_new ();
	filtered = g_mime_stream_filter_new (expected);
	dos2unix = g_mime_filter_dos2unix_new (FALSE);
	g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, dos2unix);
	g_object_unref (dos2unix);
	
	g_mime_stream_write_to_stream (stream, filtered);
	g_mime_stream_flush (filtered);
	g_object_unref (filtered);
	g_object_unref (stream);
	
	buf[0] = GMIME_STREAM_MEM (expected)->buffer;
	buf[1] = GMIME_STREAM_MEM (ostream)->buffer;
	
	if (buf[0]->len != buf[1]->len || memcmp (buf[0]->data, buf[1]->data, buf[0]->len) != 0)
		ex = exception_new ("filtered data does not match the expected result");
	
	g_object_unref (expected);
	g_object_unref (ostream);
	
	if (ex != NULL)
		throw (ex);
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
static ssize_t
write_content (GMimePart *part, GMimeStream *stream)
{
	ssize_t nwritten, total = 0;
	
	if (!part->content)
		return 0;
	
	/* Evil Genius's "slight" optimization: Since GMimeDataWrapper::write_to_stream()
	 * decodes its content stream to the raw format, we can cheat by requesting its
	 * content stream and not doing any encoding on the data if the source and
	 * destination encodings are identical.
	 */
	
	if (part->encoding != g_mime_data_wrapper_get_encoding (part->content)) {
		GMimeStream *filtered_stream;
		const char *filename;
		GMimeFilter *filter;
		
		switch (part->encoding) {
		case GMIME_CONTENT_ENCODING_UUENCODE:
			filename = g_mime_part_get_filename (part);
			nwritten = g_mime_stream_printf (stream, "begin 0644 %s\n",
							 filename ? filename : "unknown");
			if (nwritten == -1)
				return -1;
			
			total += nwritten;
			
			/* fall thru... */
		case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE:
		case GMIME_CONTENT_ENCODING_BASE64:
			filtered_stream = g_mime_stream_filter_new (stream);
			filter = g_mime_filter_basic_new (part->encoding, TRUE);
			g_mime_stream_filter_add (GMIME_STREAM_FILTER (filtered_stream), filter);
			g_object_unref (filter);
			break;
		default:
			filtered_stream = stream;
			g_object_ref (stream);
			break;
		}
		
		nwritten = g_mime_data_wrapper_write_to_stream (part->content, filtered_stream);
		g_mime_stream_flush (filtered_stream);
		g_object_unref (filtered_stream);
		
		if (nwritten == -1)
			return -1;
		
		total += nwritten;
		
		if (part->encoding == GMIME_CONTENT_ENCODING_UUENCODE) {
			/* FIXME: get rid of this special-case x-uuencode crap */
			nwritten = g_mime_stream_write (stream, "end\n", 4);
			if (nwritten == -1)
				return -1;
			
			total += nwritten;
		}
	} else {
		GMimeStream *content_stream;
		
		content_stream = g_mime_data_wrapper_get_stream (part->content);
		g_mime_stream_reset (content_stream);
		nwritten = g_mime_stream_write_to_stream (content_stream, stream);
		g_mime_stream_reset (content_stream);
		
		if (nwritten == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Exemplo n.º 25
0
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;
}