Beispiel #1
0
CamelMimePart *
mail_tool_make_message_attachment (CamelMimeMessage *message)
{
	CamelMimePart *part;
	const char *subject;
	struct _camel_header_raw *xev;
	char *desc;

	subject = camel_mime_message_get_subject (message);
	if (subject)
		desc = g_strdup_printf (_("Forwarded message - %s"), subject);
	else
		desc = g_strdup (_("Forwarded message"));

	/* rip off the X-Evolution headers */
	xev = mail_tool_remove_xevolution_headers (message);
	camel_header_raw_clear(&xev);

	/* remove Bcc headers */
	camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");

	part = camel_mime_part_new ();
	camel_mime_part_set_disposition (part, "inline");
	camel_mime_part_set_description (part, desc);
	camel_medium_set_content_object (CAMEL_MEDIUM (part),
					 CAMEL_DATA_WRAPPER (message));
	camel_mime_part_set_content_type (part, "message/rfc822");
	g_free (desc);

	return part;
}
static gint
multipart_construct_from_parser (CamelMultipart *multipart,
                                 CamelMimeParser *mp)
{
	gint err;
	CamelContentType *content_type;
	CamelMimePart *bodypart;
	gchar *buf;
	gsize len;

	g_assert (camel_mime_parser_state (mp) == CAMEL_MIME_PARSER_STATE_MULTIPART);

	/* FIXME: we should use a came-mime-mutlipart, not jsut a camel-multipart, but who cares */
	d(printf("Creating multi-part\n"));

	content_type = camel_mime_parser_content_type (mp);
	camel_multipart_set_boundary (multipart,
				     camel_content_type_param(content_type, "boundary"));

	while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
		camel_mime_parser_unstep (mp);
		bodypart = camel_mime_part_new ();
		camel_mime_part_construct_from_parser_sync (
			bodypart, mp, NULL, NULL);
		camel_multipart_add_part (multipart, bodypart);
		g_object_unref (bodypart);
	}

	/* these are only return valid data in the MULTIPART_END state */
	camel_multipart_set_preface (multipart, camel_mime_parser_preface (mp));
	camel_multipart_set_postface (multipart, camel_mime_parser_postface (mp));

	err = camel_mime_parser_errno (mp);
	if (err != 0) {
		errno = err;
		return -1;
	} else
		return 0;
}
CamelMimeMessage *
scalix_appointment_to_mime_message (ScalixObject * object)
{
    CamelMimeMessage *message;
    CamelMultipart *multipart;
    CamelMimePart *part;
    CamelMedium *medium;
    CamelStream *stream;
    CamelDataWrapper *wrapper;
    ECalComponentDateTime dtstart, dtend;
    ECalComponent *comp;
    ECalComponentText text;
    icalcomponent_kind kind;
    icalcomponent *icalcomp, *toplevel_comp;
    icaltimezone *zone = NULL;
    GSList *attachment_list = NULL;
    GSList *attachment_list_new = NULL;
    GSList *siter = NULL;
    GList *part_list = NULL;
    GList *iter = NULL;
    char *msgid;
    char *str, *meeting_status;
    const char *ouid = NULL;
    char *file_contents = NULL;
    char *full_path, *filename, *mime_filename;
    char *cid;
    int size;

    g_object_get (SCALIX_APPOINTMENT (object), "timezone", &zone, NULL);

    comp = E_CAL_COMPONENT (scalix_object_clone (object));
    message = camel_mime_message_new ();
    medium = CAMEL_MEDIUM (message);

    camel_medium_add_header (medium, "X-Scalix-Class", "IPM.Appointment");

    /* Preserve msg id if there is already one */
    if (scalix_appointment_get (SCALIX_APPOINTMENT (comp),
                                X_SCALIX_MSG_ID, &msgid)) {

        scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_MSG_ID);

    } else {
        msgid = camel_header_msgid_generate ();
    }

    camel_mime_message_set_message_id (message, msgid);

    /* subject */
    e_cal_component_get_summary (comp, &text);

    if (text.value != NULL) {
        camel_mime_message_set_subject (message, text.value);
    }

    /* start day */
    e_cal_component_get_dtstart (comp, &dtstart);

    if (!icaltime_get_timezone (*dtstart.value))
        icaltime_set_timezone (dtstart.value,
                               icaltimezone_get_builtin_timezone_from_tzid
                               (dtstart.tzid));

    /* end day */
    e_cal_component_get_dtend (comp, &dtend);

    if (!icaltime_get_timezone (*dtend.value))
        icaltime_set_timezone (dtend.value,
                               icaltimezone_get_builtin_timezone_from_tzid
                               (dtend.tzid));

    /* set From: and Sender: */
    if (e_cal_component_has_organizer (comp)) {
        ECalComponentOrganizer organizer;

        e_cal_component_get_organizer (comp, &organizer);
        if (!strncasecmp (organizer.value, "MAILTO:", 7)) {
            camel_medium_add_header (medium, "Sender", organizer.value + 7);
            camel_medium_add_header (medium, "From", organizer.value + 7);
        }
    }

    /* set the appropriate recipient headers from the recipient table */
    if (e_cal_component_has_attendees (comp)
        && e_cal_component_has_organizer (comp)) {
        GSList *iter, *attendees = NULL;
        CamelInternetAddress *recipients_to = NULL;
        CamelInternetAddress *recipients_cc = NULL;

        meeting_status = "1";

        e_cal_component_get_attendee_list (comp, &attendees);

        for (iter = attendees; iter; iter = iter->next) {
            ECalComponentAttendee *attendee = iter->data;
            const char *mail = NULL;

            /* attendee entries must start with MAILTO: */
            if (strncasecmp (attendee->value, "MAILTO:", 7)) {
                continue;
            }

            mail = attendee->value + 7;

            if (attendee->role == ICAL_ROLE_REQPARTICIPANT) {
                if (recipients_to == NULL) {
                    recipients_to = camel_internet_address_new ();
                }
                camel_internet_address_add (recipients_to, attendee->cn, mail);
            } else if (attendee->role == ICAL_ROLE_OPTPARTICIPANT) {
                if (recipients_cc == NULL) {
                    recipients_cc = camel_internet_address_new ();
                }
                camel_internet_address_add (recipients_cc, attendee->cn, mail);
            } else {
                continue;
            }
        }

        if (recipients_to != NULL) {
            camel_mime_message_set_recipients (message, "To", recipients_to);
            camel_object_unref (recipients_to);
        }

        if (recipients_cc != NULL) {
            camel_mime_message_set_recipients (message, "Cc", recipients_cc);
            camel_object_unref (recipients_cc);
        }
    } else {
        meeting_status = "0";
    }

    /* Clear properties */
    scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_IMAP_UID);
    /* Render the text/calendar  */
    e_cal_component_commit_sequence (comp);
    icalcomp = e_cal_component_get_icalcomponent (comp);

    kind = icalcomponent_isa (icalcomp);
    if (kind != ICAL_VCALENDAR_COMPONENT) {
        /* If its not a VCALENDAR, make it one to simplify below */
        toplevel_comp = e_cal_util_new_top_level ();
        icalcomponent_add_component (toplevel_comp, icalcomp);
        icalcomp = toplevel_comp;
    }

    /* set METHOD to PUSBLISH */
    icalcomponent_set_method (icalcomp, ICAL_METHOD_PUBLISH);

    /* Add the VTIMEZONE components for start- and/or end-times */
    if (zone) {
        icalcomponent_add_component (icalcomp,
                                     icaltimezone_get_component (zone));
    } else if (dtstart.tzid) {
        icalcomponent_add_component (icalcomp,
                                     icaltimezone_get_component
                                     (icaltimezone_get_builtin_timezone_from_tzid
                                      (dtstart.tzid)));
    }

    if (dtstart.tzid && dtend.tzid && strcmp (dtstart.tzid, dtend.tzid) != 0) {
        icalcomponent_add_component (icalcomp,
                                     icaltimezone_get_component
                                     (icaltimezone_get_builtin_timezone_from_tzid
                                      (dtend.tzid)));
    }

    /* FIXME: do we leek icalcomponents here? */

    if (e_cal_component_has_attachments (comp)) {

        multipart = camel_multipart_new ();
        camel_multipart_set_boundary (multipart, NULL);

        e_cal_component_get_uid (comp, &ouid);
        e_cal_component_get_attachment_list (comp, &attachment_list);

        for (siter = attachment_list; siter; siter = siter->next) {

            if (siter->data == NULL)
                continue;

            if (strstr (siter->data, "file://") != siter->data)
                continue;

            full_path = ((char *) siter->data) + strlen ("file://");
            filename = g_strrstr (full_path, "/") + 1;
            mime_filename = filename + strlen (ouid) + 1;

            size = 0;
            file_contents = get_file_contents (full_path, &size);

            if (file_contents == NULL)
                continue;

            stream = camel_stream_mem_new_with_buffer (file_contents, size);
            wrapper = camel_data_wrapper_new ();
            camel_data_wrapper_construct_from_stream (wrapper, stream);
            camel_object_unref (stream);

            part = camel_mime_part_new ();
            camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper);
            camel_mime_part_set_filename (part, mime_filename);
            camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64);

            cid = camel_header_msgid_generate ();
            camel_mime_part_set_content_id (part, cid);
            camel_mime_part_set_description (part, mime_filename);
            camel_mime_part_set_disposition (part, "attachment");
            part_list = g_list_append (part_list, part);

            attachment_list_new = g_slist_append (attachment_list_new,
                                                  g_strdup_printf ("CID:%s",
                                                                   cid));
            g_free (cid);
        }

        e_cal_component_set_attachment_list (comp, attachment_list_new);
        str = icalcomponent_as_ical_string (icalcomp);

        part = camel_mime_part_new ();

        camel_mime_part_set_content (part,
                                     str,
                                     strlen (str),
                                     "text/calendar; method=PUBLISH; charset=UTF-8");

        part_list = g_list_prepend (part_list, part);

        for (iter = part_list; iter; iter = iter->next) {
            part = (CamelMimePart *) iter->data;
            camel_multipart_add_part (multipart, part);
            camel_object_unref (part);
        }

        camel_medium_set_content_object (CAMEL_MEDIUM (message),
                                         CAMEL_DATA_WRAPPER (multipart));
        camel_object_unref (multipart);

        g_slist_free (attachment_list);
        g_slist_free (attachment_list_new);
        g_list_free (part_list);

    } else {
        str = icalcomponent_as_ical_string (icalcomp);

        camel_mime_part_set_content (CAMEL_MIME_PART (message),
                                     str,
                                     strlen (str),
                                     "text/calendar; method=PUBLISH; charset=UTF-8");
    }

    scalix_appointment_set (SCALIX_APPOINTMENT (object),
                            X_SCALIX_MSG_ID, msgid);

    return message;
}
Beispiel #4
0
static void
eab_composer_created_cb (GObject *source_object,
			 GAsyncResult *result,
			 gpointer user_data)
{
	CreateComposerData *ccd = user_data;
	EComposerHeaderTable *table;
	EMsgComposer *composer;
	GError *error = NULL;

	g_return_if_fail (ccd != NULL);

	composer = e_msg_composer_new_finish (result, &error);
	if (error) {
		g_warning ("%s: Failed to create msg composer: %s", G_STRFUNC, error->message);
		g_clear_error (&error);
	} else {
		table = e_msg_composer_get_header_table (composer);

		if (ccd->to_destinations)
			e_composer_header_table_set_destinations_to (table, ccd->to_destinations);

		if (ccd->bcc_destinations)
			e_composer_header_table_set_destinations_bcc (table, ccd->bcc_destinations);

		if (ccd->attachment_destinations) {
			CamelMimePart *attachment;
			GSList *contacts, *iter;
			gchar *data;

			attachment = camel_mime_part_new ();

			contacts = g_slist_copy (ccd->attachment_destinations);
			for (iter = contacts; iter != NULL; iter = iter->next)
				iter->data = e_destination_get_contact (iter->data);
			data = eab_contact_list_to_string (contacts);
			g_slist_free (contacts);

			camel_mime_part_set_content (attachment, data, strlen (data), "text/x-vcard");

			if (ccd->attachment_destinations->next != NULL) {
				camel_mime_part_set_description (attachment, _("Multiple vCards"));
			} else {
				EContact *contact;
				const gchar *file_as;
				gchar *description;

				contact = e_destination_get_contact (ccd->attachment_destinations->data);
				file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
				description = g_strdup_printf (_("vCard for %s"), file_as);
				camel_mime_part_set_description (attachment, description);
				g_free (description);
			}

			camel_mime_part_set_disposition (attachment, "attachment");

			e_msg_composer_attach (composer, attachment);
			g_object_unref (attachment);

			if (ccd->attachment_destinations->next != NULL) {
				e_composer_header_table_set_subject (table, _("Contact information"));
			} else {
				EContact *contact;
				gchar *tempstr;
				const gchar *tempstr2;
				gchar *tempfree = NULL;

				contact = e_destination_get_contact (ccd->attachment_destinations->data);
				tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
				if (!tempstr2 || !*tempstr2)
					tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
				if (!tempstr2 || !*tempstr2)
					tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
				if (!tempstr2 || !*tempstr2) {
					g_free (tempfree);
					tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
				}
				if (!tempstr2 || !*tempstr2) {
					g_free (tempfree);
					tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
				}
				if (!tempstr2 || !*tempstr2) {
					g_free (tempfree);
					tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
				}

				if (!tempstr2 || !*tempstr2)
					tempstr = g_strdup_printf (_("Contact information"));
				else
					tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);

				e_composer_header_table_set_subject (table, tempstr);

				g_free (tempstr);
				g_free (tempfree);
			}
		}

		gtk_widget_show (GTK_WIDGET (composer));
	}

	if (ccd->to_destinations)
		e_destination_freev (ccd->to_destinations);
	if (ccd->bcc_destinations)
		e_destination_freev (ccd->bcc_destinations);
	g_slist_free_full (ccd->attachment_destinations, g_object_unref);

	g_free (ccd);
}
static gboolean
empe_inlinepgp_encrypted_parse (EMailParserExtension *extension,
                                EMailParser *parser,
                                CamelMimePart *part,
                                GString *part_id,
                                GCancellable *cancellable,
                                GQueue *out_mail_parts)
{
	CamelCipherContext *cipher;
	CamelCipherValidity *valid;
	CamelMimePart *opart;
	CamelDataWrapper *dw;
	gchar *mime_type;
	gint len;
	GQueue work_queue = G_QUEUE_INIT;
	GList *head, *link;
	GError *local_error = NULL;

	if (g_cancellable_is_cancelled (cancellable))
		return FALSE;

	cipher = camel_gpg_context_new (e_mail_parser_get_session (parser));

	opart = camel_mime_part_new ();

	/* Decrypt the message */
	valid = camel_cipher_context_decrypt_sync (
		cipher, part, opart, cancellable, &local_error);

	if (local_error != NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Could not parse PGP message: %s"),
			local_error->message);
		g_error_free (local_error);

		e_mail_parser_parse_part_as (
			parser,
			part, part_id,
			"application/vnd.evolution.source",
			cancellable, out_mail_parts);

		g_object_unref (cipher);
		g_object_unref (opart);

		return TRUE;
	}

	dw = camel_medium_get_content ((CamelMedium *) opart);
	mime_type = camel_data_wrapper_get_mime_type (dw);

	/* this ensures to show the 'opart' as inlined, if possible */
	if (mime_type && g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0) {
		const gchar *snoop;

		snoop = e_mail_part_snoop_type (opart);

		if (snoop != NULL) {
			camel_data_wrapper_set_mime_type (dw, snoop);

			/* Set the MIME type on the 'opart' itself as well.
			 * If it's "text/plain", then we want the TextPlain
			 * parser extension to treat it as "text/plain" and
			 * NOT wrap it as an attachment. */
			camel_data_wrapper_set_mime_type (
				CAMEL_DATA_WRAPPER (opart), snoop);
		}
	}

	e_mail_part_preserve_charset_in_content_type (part, opart);
	g_free (mime_type);

	/* Pass it off to the real formatter */
	len = part_id->len;
	g_string_append (part_id, ".inlinepgp_encrypted");

	g_warn_if_fail (e_mail_parser_parse_part_as (
		parser, opart, part_id,
		camel_data_wrapper_get_mime_type (dw),
		cancellable, &work_queue));

	g_string_truncate (part_id, len);

	head = g_queue_peek_head_link (&work_queue);

	for (link = head; link != NULL; link = g_list_next (link)) {
		EMailPart *mail_part = link->data;

		e_mail_part_update_validity (
			mail_part, valid,
			E_MAIL_PART_VALIDITY_ENCRYPTED |
			E_MAIL_PART_VALIDITY_PGP);
	}

	e_queue_transfer (&work_queue, out_mail_parts);

	/* Add a widget with details about the encryption, but only when
	 * the encrypted isn't itself secured, in that case it has created
	 * the button itself */
	if (!e_mail_part_is_secured (opart)) {
		EMailPart *mail_part;

		g_string_append (part_id, ".inlinepgp_encrypted.button");

		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.widget.secure-button",
			cancellable, &work_queue);

		mail_part = g_queue_peek_head (&work_queue);
		if (mail_part != NULL)
			e_mail_part_update_validity (
				mail_part, valid,
				E_MAIL_PART_VALIDITY_ENCRYPTED |
				E_MAIL_PART_VALIDITY_PGP);

		e_queue_transfer (&work_queue, out_mail_parts);

		g_string_truncate (part_id, len);
	}

	/* Clean Up */
	camel_cipher_validity_free (valid);
	g_object_unref (opart);
	g_object_unref (cipher);

	return TRUE;
}
static int
sm_sign(CamelCipherContext *context, const char *userid, CamelCipherHash hash, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex)
{
	int res = -1;
	NSSCMSMessage *cmsg;
	CamelStream *ostream, *istream;
	SECOidTag sechash;
	NSSCMSEncoderContext *enc;
	CamelDataWrapper *dw;
	CamelContentType *ct;

	switch (hash) {
	case CAMEL_CIPHER_HASH_SHA1:
	case CAMEL_CIPHER_HASH_DEFAULT:
	default:
		sechash = SEC_OID_SHA1;
		break;
	case CAMEL_CIPHER_HASH_MD5:
		sechash = SEC_OID_MD5;
		break;
	}

	cmsg = sm_signing_cmsmessage((CamelSMIMEContext *)context, userid, sechash,
				     ((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN, ex);
	if (cmsg == NULL)
		return -1;

	ostream = camel_stream_mem_new();

	/* FIXME: stream this, we stream output at least */
	istream = camel_stream_mem_new();
	if (camel_cipher_canonical_to_stream(ipart,
					     CAMEL_MIME_FILTER_CANON_STRIP
					     |CAMEL_MIME_FILTER_CANON_CRLF
					     |CAMEL_MIME_FILTER_CANON_FROM, istream) == -1) {
		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
				     _("Could not generate signing data: %s"), g_strerror(errno));
		goto fail;
	}

	enc = NSS_CMSEncoder_Start(cmsg,
				   sm_write_stream, ostream, /* DER output callback  */
				   NULL, NULL,     /* destination storage  */
				   NULL, NULL,	   /* password callback    */
				   NULL, NULL,     /* decrypt key callback */
				   NULL, NULL );   /* detached digests    */
	if (!enc) {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create encoder context"));
		goto fail;
	}

	if (NSS_CMSEncoder_Update(enc, (char *) ((CamelStreamMem *)istream)->buffer->data, ((CamelStreamMem *)istream)->buffer->len) != SECSuccess) {
		NSS_CMSEncoder_Cancel(enc);
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to add data to CMS encoder"));
		goto fail;
	}

	if (NSS_CMSEncoder_Finish(enc) != SECSuccess) {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to encode data"));
		goto fail;
	}

	res = 0;

	dw = camel_data_wrapper_new();
	camel_stream_reset(ostream);
	camel_data_wrapper_construct_from_stream(dw, ostream);
	dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;

	if (((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
		CamelMultipartSigned *mps;
		CamelMimePart *sigpart;

		sigpart = camel_mime_part_new();
		ct = camel_content_type_new("application", "x-pkcs7-signature");
		camel_content_type_set_param(ct, "name", "smime.p7s");
		camel_data_wrapper_set_mime_type_field(dw, ct);
		camel_content_type_unref(ct);

		camel_medium_set_content_object((CamelMedium *)sigpart, dw);

		camel_mime_part_set_filename(sigpart, "smime.p7s");
		camel_mime_part_set_disposition(sigpart, "attachment");
		camel_mime_part_set_encoding(sigpart, CAMEL_TRANSFER_ENCODING_BASE64);

		mps = camel_multipart_signed_new();
		ct = camel_content_type_new("multipart", "signed");
		camel_content_type_set_param(ct, "micalg", camel_cipher_hash_to_id(context, hash));
		camel_content_type_set_param(ct, "protocol", context->sign_protocol);
		camel_data_wrapper_set_mime_type_field((CamelDataWrapper *)mps, ct);
		camel_content_type_unref(ct);
		camel_multipart_set_boundary((CamelMultipart *)mps, NULL);

		mps->signature = sigpart;
		mps->contentraw = istream;
		camel_stream_reset(istream);
		camel_object_ref(istream);

		camel_medium_set_content_object((CamelMedium *)opart, (CamelDataWrapper *)mps);
	} else {
		ct = camel_content_type_new("application", "x-pkcs7-mime");
		camel_content_type_set_param(ct, "name", "smime.p7m");
		camel_content_type_set_param(ct, "smime-type", "signed-data");
		camel_data_wrapper_set_mime_type_field(dw, ct);
		camel_content_type_unref(ct);

		camel_medium_set_content_object((CamelMedium *)opart, dw);

		camel_mime_part_set_filename(opart, "smime.p7m");
		camel_mime_part_set_description(opart, "S/MIME Signed Message");
		camel_mime_part_set_disposition(opart, "attachment");
		camel_mime_part_set_encoding(opart, CAMEL_TRANSFER_ENCODING_BASE64);
	}

	camel_object_unref(dw);
fail:
	camel_object_unref(ostream);
	camel_object_unref(istream);

	return res;
}
Beispiel #7
0
gint main (gint argc, gchar **argv)
{
	CamelSession *session;
	CamelCipherContext *ctx;
	GError **error;
	CamelCipherValidity *valid;
	CamelMimePart *mime_part;
	CamelMultipartSigned *mps;
	CamelMultipartEncrypted *mpe;
	GPtrArray *recipients;
	gint ret;

	camel_test_init (argc, argv);

	/* clear out any camel-test data */
	system ("/bin/rm -rf /tmp/camel-test");
	system ("/bin/mkdir /tmp/camel-test");
	setenv ("GNUPGHOME", "/tmp/camel-test/.gnupg", 1);

	/* import the gpg keys */
	if ((ret = system ("gpg < /dev/null > /dev/null 2>&1")) == -1)
		return 77;
	else if (WEXITSTATUS (ret) == 127)
		return 77;

	system ("gpg --import ../data/camel-test.gpg.pub > /dev/null 2>&1");
	system ("gpg --import ../data/camel-test.gpg.sec > /dev/null 2>&1");

	session = camel_pgp_session_new ("/tmp/camel-test");

	ex = camel_exception_new ();

	ctx = camel_gpg_context_new (session);
	camel_gpg_context_set_always_trust (CAMEL_GPG_CONTEXT (ctx), TRUE);

	camel_test_start ("Test of PGP/MIME functions");

	mime_part = camel_mime_part_new ();
	camel_mime_part_set_content (mime_part, test_msg, strlen (test_msg), "text/plain");
	camel_mime_part_set_description (mime_part, "Test of PGP/MIME multipart/signed stuff");

	camel_test_push ("PGP/MIME signing");
	mps = camel_multipart_signed_new ();
	camel_multipart_signed_sign (mps, ctx, mime_part, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	camel_test_pull ();

	g_object_unref (mime_part);
	camel_exception_clear (ex);

	camel_test_push ("PGP/MIME verify");
	valid = camel_multipart_signed_verify (mps, ctx, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid));
	camel_cipher_validity_free (valid);
	camel_test_pull ();

	g_object_unref (mps);
	camel_exception_clear (ex);

	mime_part = camel_mime_part_new ();
	camel_mime_part_set_content (mime_part, test_msg, strlen (test_msg), "text/plain");
	camel_mime_part_set_description (mime_part, "Test of PGP/MIME multipart/encrypted stuff");

	camel_test_push ("PGP/MIME encrypt");
	recipients = g_ptr_array_new ();
	g_ptr_array_add (recipients, "*****@*****.**");

	mpe = camel_multipart_encrypted_new ();
	camel_multipart_encrypted_encrypt (mpe, mime_part, ctx, "*****@*****.**", recipients, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	g_ptr_array_free (recipients, TRUE);
	camel_test_pull ();

	camel_exception_clear (ex);
	g_object_unref (mime_part);

	camel_test_push ("PGP/MIME decrypt");
	mime_part = camel_multipart_encrypted_decrypt (mpe, ctx, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	g_object_unref (mime_part);
	g_object_unref (mpe);
	camel_test_pull ();

	g_object_unref (ctx);
	g_object_unref (session);

	camel_test_end ();

	return 0;
}
static void
mail_attachment_handler_x_uid_list (EAttachmentView *view,
                                    GdkDragContext *drag_context,
                                    gint x,
                                    gint y,
                                    GtkSelectionData *selection_data,
                                    guint info,
                                    guint time,
                                    EAttachmentHandler *handler)
{
	static GdkAtom atom = GDK_NONE;
	EMailAttachmentHandlerPrivate *priv;
	CamelDataWrapper *wrapper;
	CamelMimeMessage *message;
	CamelMultipart *multipart;
	CamelMimePart *mime_part;
	CamelFolder *folder = NULL;
	EAttachment *attachment;
	EAttachmentStore *store;
	EMailSession *session;
	GPtrArray *uids;
	const gchar *data;
	const gchar *cp, *end;
	gchar *description;
	gpointer parent;
	gint length;
	guint ii;
	GError *local_error = NULL;

	if (G_UNLIKELY (atom == GDK_NONE))
		atom = gdk_atom_intern_static_string ("x-uid-list");

	if (gtk_selection_data_get_target (selection_data) != atom)
		return;

	store = e_attachment_view_get_store (view);
	priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);

	parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;

	uids = g_ptr_array_new ();

	data = (const gchar *) gtk_selection_data_get_data (selection_data);
	length = gtk_selection_data_get_length (selection_data);

	/* The UID list is delimited by NUL characters.
	 * Brilliant.  So we can't use g_strsplit(). */

	cp = data;
	end = data + length;

	while (cp < end) {
		const gchar *start = cp;

		while (cp < end && *cp != '\0')
			cp++;

		/* Skip the first string. */
		if (start > data)
			g_ptr_array_add (uids, g_strndup (start, cp - start));

		cp++;
	}

	if (uids->len == 0)
		goto exit;

	session = e_mail_backend_get_session (priv->backend);

	/* The first string is the folder URI. */
	/* FIXME Not passing a GCancellable here. */
	folder = e_mail_session_uri_to_folder_sync (
		session, data, 0, NULL, &local_error);
	if (folder == NULL)
		goto exit;

	/* Handle one message. */
	if (uids->len == 1) {
		const gchar *message_uid;

		message_uid = g_ptr_array_index (uids, 0);

		/* FIXME Not passing a GCancellable here. */
		message = camel_folder_get_message_sync (
			folder, message_uid, NULL, &local_error);
		if (message == NULL)
			goto exit;

		attachment = e_attachment_new_for_message (message);
		e_attachment_store_add_attachment (store, attachment);
		e_attachment_load_async (
			attachment, (GAsyncReadyCallback)
			call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);

		g_object_unref (attachment);

		g_object_unref (message);
		goto exit;
	}

	/* Build a multipart/digest message out of the UIDs. */

	multipart = camel_multipart_new ();
	wrapper = CAMEL_DATA_WRAPPER (multipart);
	camel_data_wrapper_set_mime_type (wrapper, "multipart/digest");
	camel_multipart_set_boundary (multipart, NULL);

	for (ii = 0; ii < uids->len; ii++) {
		/* FIXME Not passing a GCancellable here. */
		message = camel_folder_get_message_sync (
			folder, uids->pdata[ii], NULL, &local_error);
		if (message == NULL) {
			g_object_unref (multipart);
			goto exit;
		}

		mime_part = camel_mime_part_new ();
		wrapper = CAMEL_DATA_WRAPPER (message);
		camel_mime_part_set_disposition (mime_part, "inline");
		camel_medium_set_content (
			CAMEL_MEDIUM (mime_part), wrapper);
		camel_mime_part_set_content_type (mime_part, "message/rfc822");
		camel_multipart_add_part (multipart, mime_part);
		g_object_unref (mime_part);

		g_object_unref (message);
	}

	mime_part = camel_mime_part_new ();
	wrapper = CAMEL_DATA_WRAPPER (multipart);
	camel_medium_set_content (CAMEL_MEDIUM (mime_part), wrapper);

	description = g_strdup_printf (
		ngettext (
			"%d attached message",
			"%d attached messages",
			uids->len),
		uids->len);
	camel_mime_part_set_description (mime_part, description);
	g_free (description);

	attachment = e_attachment_new ();
	e_attachment_set_mime_part (attachment, mime_part);
	e_attachment_store_add_attachment (store, attachment);
	e_attachment_load_async (
		attachment, (GAsyncReadyCallback)
		call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
	g_object_unref (attachment);

	g_object_unref (mime_part);
	g_object_unref (multipart);

exit:
	if (local_error != NULL) {
		const gchar *folder_name = data;

		if (folder != NULL)
			folder_name = camel_folder_get_display_name (folder);

		e_alert_run_dialog_for_args (
			parent, "mail-composer:attach-nomessages",
			folder_name, local_error->message, NULL);

		g_clear_error (&local_error);
	}

	if (folder != NULL)
		g_object_unref (folder);

	g_ptr_array_free (uids, TRUE);

	g_signal_stop_emission_by_name (view, "drag-data-received");
}
static CamelMimePart *
multipart_signed_get_part (CamelMultipart *multipart,
                           guint index)
{
	CamelMultipartSigned *mps = (CamelMultipartSigned *) multipart;
	CamelDataWrapper *data_wrapper;
	CamelStream *stream;
	GByteArray *byte_array;

	data_wrapper = CAMEL_DATA_WRAPPER (multipart);
	byte_array = camel_data_wrapper_get_byte_array (data_wrapper);

	switch (index) {
	case CAMEL_MULTIPART_SIGNED_CONTENT:
		if (mps->content)
			return mps->content;
		if (mps->contentraw) {
			g_return_val_if_fail (
				G_IS_SEEKABLE (mps->contentraw), NULL);
			stream = g_object_ref (mps->contentraw);
		} else if (mps->start1 == -1
			   && multipart_signed_parse_content (mps) == -1
			   && byte_array->len == 0) {
			g_warning ("Trying to get content on an invalid multipart/signed");
			return NULL;
		} else if (byte_array->len == 0) {
			return NULL;
		} else if (mps->start1 == -1) {
			stream = camel_stream_mem_new ();
			camel_stream_mem_set_byte_array (
				CAMEL_STREAM_MEM (stream), byte_array);
		} else {
			stream = multipart_signed_clip_stream (
				mps, mps->start1, mps->end1);
		}
		g_seekable_seek (
			G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
		mps->content = camel_mime_part_new ();
		camel_data_wrapper_construct_from_stream_sync (
			CAMEL_DATA_WRAPPER (mps->content), stream, NULL, NULL);
		g_object_unref (stream);
		return mps->content;
	case CAMEL_MULTIPART_SIGNED_SIGNATURE:
		if (mps->signature)
			return mps->signature;
		if (mps->start1 == -1
		    && multipart_signed_parse_content (mps) == -1) {
			g_warning ("Trying to get signature on invalid multipart/signed");
			return NULL;
		} else if (byte_array->len == 0) {
			return NULL;
		}
		stream = multipart_signed_clip_stream (
			mps, mps->start2, mps->end2);
		g_seekable_seek (
			G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
		mps->signature = camel_mime_part_new ();
		camel_data_wrapper_construct_from_stream_sync (
			CAMEL_DATA_WRAPPER (mps->signature),
			stream, NULL, NULL);
		g_object_unref (stream);
		return mps->signature;
	default:
		g_warning ("trying to get object out of bounds for multipart");
	}

	return NULL;
}
void
eab_send_as_attachment (EShell *shell,
                        GSList *destinations)
{
	EMsgComposer *composer;
	EComposerHeaderTable *table;
	CamelMimePart *attachment;
	GSList *contacts, *iter;
	gchar *data;

	g_return_if_fail (E_IS_SHELL (shell));

	if (destinations == NULL)
		return;

	composer = e_msg_composer_new (shell);
	table = e_msg_composer_get_header_table (composer);

	attachment = camel_mime_part_new ();

	contacts = g_slist_copy (destinations);
	for (iter = contacts; iter != NULL; iter = iter->next)
		iter->data = e_destination_get_contact (iter->data);
	data = eab_contact_list_to_string (contacts);
	g_slist_free (contacts);

	camel_mime_part_set_content (
		attachment, data, strlen (data), "text/x-vcard");

	if (destinations->next != NULL)
		camel_mime_part_set_description (
			attachment, _("Multiple vCards"));
	else {
		EContact *contact;
		const gchar *file_as;
		gchar *description;

		contact = e_destination_get_contact (destinations->data);
		file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
		description = g_strdup_printf (_("vCard for %s"), file_as);
		camel_mime_part_set_description (attachment, description);
		g_free (description);
	}

	camel_mime_part_set_disposition (attachment, "attachment");

	e_msg_composer_attach (composer, attachment);
	g_object_unref (attachment);

	if (destinations->next != NULL)
		e_composer_header_table_set_subject (
			table, _("Contact information"));
	else {
		EContact *contact;
		gchar *tempstr;
		const gchar *tempstr2;
		gchar *tempfree = NULL;

		contact = e_destination_get_contact (destinations->data);
		tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
		if (!tempstr2 || !*tempstr2)
			tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
		if (!tempstr2 || !*tempstr2)
			tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
		}
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
		}
		if (!tempstr2 || !*tempstr2) {
			g_free (tempfree);
			tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
		}

		if (!tempstr2 || !*tempstr2)
			tempstr = g_strdup_printf (_("Contact information"));
		else
			tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);

		e_composer_header_table_set_subject (table, tempstr);

		g_free (tempstr);
		g_free (tempfree);
	}

	gtk_widget_show (GTK_WIDGET (composer));
}
static gboolean
empe_mp_encrypted_parse (EMailParserExtension *extension,
                         EMailParser *parser,
                         CamelMimePart *part,
                         GString *part_id,
                         GCancellable *cancellable,
                         GQueue *out_mail_parts)
{
	CamelCipherContext *context;
	const gchar *protocol;
	CamelMimePart *opart;
	CamelCipherValidity *valid;
	CamelMultipartEncrypted *mpe;
	GQueue work_queue = G_QUEUE_INIT;
	GList *head, *link;
	GError *local_error = NULL;
	gint len;

	mpe = (CamelMultipartEncrypted *) camel_medium_get_content ((CamelMedium *) part);
	if (!CAMEL_IS_MULTIPART_ENCRYPTED (mpe)) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Could not parse MIME message. "
			"Displaying as source."));
		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution/source",
			cancellable, out_mail_parts);

		return TRUE;
	}

	/* Currently we only handle RFC2015-style PGP encryption. */
	protocol = camel_content_type_param (
		((CamelDataWrapper *) mpe)->mime_type, "protocol");
	if (!protocol || g_ascii_strcasecmp (protocol, "application/pgp-encrypted") != 0) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Unsupported encryption type for multipart/encrypted"));
		e_mail_parser_parse_part_as (
			parser, part, part_id, "multipart/mixed",
			cancellable, out_mail_parts);

		return TRUE;
	}

	context = camel_gpg_context_new (e_mail_parser_get_session (parser));

	opart = camel_mime_part_new ();
	valid = camel_cipher_context_decrypt_sync (
		context, part, opart, cancellable, &local_error);

	e_mail_part_preserve_charset_in_content_type (part, opart);

	if (local_error != NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Could not parse PGP/MIME message: %s"),
			local_error->message);
		e_mail_parser_parse_part_as (
			parser, part, part_id, "multipart/mixed",
			cancellable, out_mail_parts);

		g_object_unref (opart);
		g_object_unref (context);
		g_error_free (local_error);

		return TRUE;
	}

	len = part_id->len;
	g_string_append (part_id, ".encrypted");

	g_warn_if_fail (e_mail_parser_parse_part (
		parser, opart, part_id, cancellable, &work_queue));

	g_string_truncate (part_id, len);

	head = g_queue_peek_head_link (&work_queue);

	/* Update validity of all encrypted sub-parts */
	for (link = head; link != NULL; link = g_list_next (link)) {
		EMailPart *mail_part = link->data;

		e_mail_part_update_validity (
			mail_part, valid,
			E_MAIL_PART_VALIDITY_ENCRYPTED |
			E_MAIL_PART_VALIDITY_PGP);
	}

	e_queue_transfer (&work_queue, out_mail_parts);

	/* Add a widget with details about the encryption, but only when
	 * the decrypted part isn't itself secured, in that case it has
	 * created the button itself. */
	if (!e_mail_part_is_secured (opart)) {
		EMailPart *mail_part;

		g_string_append (part_id, ".encrypted.button");

		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.widget.secure-button",
			cancellable, &work_queue);

		mail_part = g_queue_peek_head (&work_queue);

		if (mail_part != NULL)
			e_mail_part_update_validity (
				mail_part, valid,
				E_MAIL_PART_VALIDITY_ENCRYPTED |
				E_MAIL_PART_VALIDITY_PGP);

		e_queue_transfer (&work_queue, out_mail_parts);

		g_string_truncate (part_id, len);
	}

	camel_cipher_validity_free (valid);

	/* TODO: Make sure when we finalize this part, it is zero'd out */
	g_object_unref (opart);
	g_object_unref (context);

	return TRUE;
}
Beispiel #12
0
void
camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                                    EEwsConnection *cnc,
                                    GSList *items_created,
				    CamelFolderChangeInfo *change_info,
                                    GCancellable *cancellable)
{
	CamelFolder *folder;
	CamelFolderSummary *folder_summary;
	GSList *l;

	if (!items_created)
		return;

	folder = CAMEL_FOLDER (ews_folder);
	folder_summary = camel_folder_get_folder_summary (folder);

	for (l = items_created; l != NULL; l = g_slist_next (l)) {
		EEwsItem *item = (EEwsItem *) l->data;
		CamelMessageInfo *mi;
		const EwsId *id;
		const EwsMailbox *from;
		gchar *tmp;
		EEwsItemType item_type;
		const gchar *msg_headers;
		gboolean has_attachments, found_property, message_requests_read_receipt = FALSE;
		guint32 server_flags;

		if (!item)
			continue;

		if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
			g_object_unref (item);
			continue;
		}

		id = e_ews_item_get_id (item);
		if (!id) {
			g_warning ("%s: Missing ItemId for item type %d (subject:%s)", G_STRFUNC, e_ews_item_get_item_type (item),
				e_ews_item_get_subject (item) ? e_ews_item_get_subject (item) : "???");
			g_object_unref (item);
			continue;
		}

		mi = camel_folder_summary_get (folder_summary, id->id);
		if (mi) {
			g_clear_object (&mi);
			g_object_unref (item);
			continue;
		}


		/* PidTagTransportMessageHeaders */
		found_property = FALSE;
		msg_headers = e_ews_item_get_extended_property_as_string (item, NULL, 0x007D, &found_property);
		if (!found_property)
			msg_headers = NULL;

		if (msg_headers && *msg_headers) {
			CamelMimePart *part = camel_mime_part_new ();
			CamelStream *stream;
			CamelMimeParser *parser;

			stream = camel_stream_mem_new_with_buffer (msg_headers, strlen (msg_headers));
			parser = camel_mime_parser_new ();
			camel_mime_parser_init_with_stream (parser, stream, NULL);
			camel_mime_parser_scan_from (parser, FALSE);
			g_object_unref (stream);

			if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
				mi = camel_folder_summary_info_new_from_headers (folder_summary, camel_medium_get_headers (CAMEL_MEDIUM (part)));
				if (camel_medium_get_header (CAMEL_MEDIUM (part), "Disposition-Notification-To"))
					message_requests_read_receipt = TRUE;
			}

			g_object_unref (parser);
			g_object_unref (part);
		}

		if (!mi)
			mi = camel_message_info_new (folder_summary);

		camel_message_info_set_abort_notifications (mi, TRUE);

		item_type = e_ews_item_get_item_type (item);
		if (item_type == E_EWS_ITEM_TYPE_EVENT ||
			 item_type == E_EWS_ITEM_TYPE_MEETING_MESSAGE ||
			 item_type == E_EWS_ITEM_TYPE_MEETING_REQUEST ||
			 item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE ||
			 item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE)
			camel_message_info_set_user_flag (mi, "$has_cal", TRUE);

		camel_message_info_set_uid (mi, id->id);
		camel_message_info_set_size (mi, e_ews_item_get_size (item));
		camel_message_info_set_subject (mi, e_ews_item_get_subject (item));
		camel_ews_message_info_set_item_type (CAMEL_EWS_MESSAGE_INFO (mi), item_type);
		camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key);

		camel_message_info_set_date_sent (mi, e_ews_item_get_date_sent (item));
		camel_message_info_set_date_received (mi, e_ews_item_get_date_received (item));

		from = e_ews_item_get_from (item);
		if (!from)
			from = e_ews_item_get_sender (item);
		tmp = form_email_string_from_mb (cnc, from, cancellable);
		camel_message_info_set_from (mi, tmp);
		g_free (tmp);

		tmp = form_recipient_list (cnc, e_ews_item_get_to_recipients (item), cancellable);
		camel_message_info_set_to (mi, tmp);
		g_free (tmp);

		tmp = form_recipient_list (cnc, e_ews_item_get_cc_recipients (item), cancellable);
		camel_message_info_set_cc (mi, tmp);
		g_free (tmp);

		e_ews_item_has_attachments (item, &has_attachments);
		if (has_attachments)
			camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);

		ews_set_threading_data (mi, item);
		server_flags = ews_utils_get_server_flags (item);
		ews_utils_merge_server_user_flags (item, mi);

		camel_message_info_set_flags (mi, server_flags, server_flags);
		camel_ews_message_info_set_server_flags (CAMEL_EWS_MESSAGE_INFO (mi), server_flags);

		camel_ews_utils_update_follow_up_flags (item, mi);
		camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, message_requests_read_receipt);

		camel_message_info_set_abort_notifications (mi, FALSE);

		camel_folder_summary_add (folder_summary, mi, FALSE);

		/* camel_folder_summary_add() sets folder_flagged flag
		 * on the message info, but this is a fresh item downloaded
		 * from the server, thus unset it, to avoid resync up to the server
		 * on folder leave/store
		 */
		camel_message_info_set_folder_flagged (mi, FALSE);

		camel_folder_change_info_add_uid (change_info, id->id);
		camel_folder_change_info_recent_uid (change_info, id->id);

		g_object_unref (mi);
		g_object_unref (item);
	}

	g_slist_free (items_created);
}
static gboolean
empe_inlinepgp_signed_parse (EMailParserExtension *extension,
                             EMailParser *parser,
                             CamelMimePart *part,
                             GString *part_id,
                             GCancellable *cancellable,
                             GQueue *out_mail_parts)
{
	CamelStream *filtered_stream;
	CamelMimeFilterPgp *pgp_filter;
	CamelContentType *content_type;
	CamelCipherContext *cipher;
	CamelCipherValidity *valid;
	CamelDataWrapper *dw;
	CamelMimePart *opart;
	CamelStream *ostream;
	GQueue work_queue = G_QUEUE_INIT;
	GList *head, *link;
	gchar *type;
	gint len;
	GError *local_error = NULL;
	GByteArray *ba;

	if (g_cancellable_is_cancelled (cancellable) ||
	    /* avoid recursion */
	    (part_id->str && part_id->len > 17 && g_str_has_suffix (part_id->str, ".inlinepgp_signed")))
		return FALSE;

	cipher = camel_gpg_context_new (e_mail_parser_get_session (parser));

	/* Verify the signature of the message */
	valid = camel_cipher_context_verify_sync (
		cipher, part, cancellable, &local_error);

	if (local_error != NULL) {
		e_mail_parser_error (
			parser, out_mail_parts,
			_("Error verifying signature: %s"),
			local_error->message);

		g_error_free (local_error);

		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.source",
			cancellable, out_mail_parts);

		g_object_unref (cipher);

		return TRUE;
	}

	/* Setup output stream */
	ostream = camel_stream_mem_new ();
	filtered_stream = camel_stream_filter_new (ostream);

	/* Add PGP header / footer filter */
	pgp_filter = (CamelMimeFilterPgp *) camel_mime_filter_pgp_new ();
	camel_stream_filter_add (
		CAMEL_STREAM_FILTER (filtered_stream),
		CAMEL_MIME_FILTER (pgp_filter));
	g_object_unref (pgp_filter);

	/* Pass through the filters that have been setup */
	dw = camel_medium_get_content ((CamelMedium *) part);
	camel_data_wrapper_decode_to_stream_sync (
		dw, (CamelStream *) filtered_stream, cancellable, NULL);
	camel_stream_flush ((CamelStream *) filtered_stream, cancellable, NULL);
	g_object_unref (filtered_stream);

	/* Create a new text/plain MIME part containing the signed
	 * content preserving the original part's Content-Type params. */
	content_type = camel_mime_part_get_content_type (part);
	type = camel_content_type_format (content_type);
	content_type = camel_content_type_decode (type);
	g_free (type);

	g_free (content_type->type);
	content_type->type = g_strdup ("text");
	g_free (content_type->subtype);
	content_type->subtype = g_strdup ("plain");
	type = camel_content_type_format (content_type);
	camel_content_type_unref (content_type);

	ba = camel_stream_mem_get_byte_array ((CamelStreamMem *) ostream);
	opart = camel_mime_part_new ();
	camel_mime_part_set_content (opart, (gchar *) ba->data, ba->len, type);
	g_free (type);

	len = part_id->len;
	g_string_append (part_id, ".inlinepgp_signed");

	e_mail_parser_parse_part (
		parser, opart, part_id, cancellable, &work_queue);

	head = g_queue_peek_head_link (&work_queue);

	for (link = head; link != NULL; link = g_list_next (link)) {
		EMailPart *mail_part = link->data;

		e_mail_part_update_validity (
			mail_part, valid,
			E_MAIL_PART_VALIDITY_SIGNED |
			E_MAIL_PART_VALIDITY_PGP);
	}

	e_queue_transfer (&work_queue, out_mail_parts);

	g_string_truncate (part_id, len);

	/* Add a widget with details about the encryption, but only when
	 * the encrypted isn't itself secured, in that case it has created
	 * the button itself */
	if (!e_mail_part_is_secured (opart)) {
		EMailPart *mail_part;

		g_string_append (part_id, ".inlinepgp_signed.button");

		e_mail_parser_parse_part_as (
			parser, part, part_id,
			"application/vnd.evolution.widget.secure-button",
			cancellable, &work_queue);

		mail_part = g_queue_peek_head (&work_queue);
		if (mail_part != NULL)
			e_mail_part_update_validity (
				mail_part, valid,
				E_MAIL_PART_VALIDITY_SIGNED |
				E_MAIL_PART_VALIDITY_PGP);

		e_queue_transfer (&work_queue, out_mail_parts);

		g_string_truncate (part_id, len);
	}

	/* Clean Up */
	camel_cipher_validity_free (valid);
	g_object_unref (opart);
	g_object_unref (ostream);
	g_object_unref (cipher);

	return TRUE;
}
Beispiel #14
0
void
org_gnome_format_tnef(void *ep, EMFormatHookTarget *t)
{
	char *tmpdir = NULL, *name = NULL;
	CamelStream *out;
	struct dirent *d;
	DIR *dir;
	CamelMultipart *mp;
	CamelMimePart *mainpart;
	CamelDataWrapper *content;
	int len;
	TNEFStruct *tnef;
	tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct));

	tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
	if (tmpdir == NULL)
		return;

	filepath = tmpdir;

	name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL);

	out = camel_stream_fs_new_with_name(name, O_RDWR|O_CREAT, 0666);
	if (out == NULL)
	    goto fail;
	content = camel_medium_get_content_object((CamelMedium *)t->part);
	if (content == NULL)
		goto fail;
	if (camel_data_wrapper_decode_to_stream(content, out) == -1
	    || camel_stream_close(out) == -1) {
		camel_object_unref(out);
 		goto fail;
	}
	camel_object_unref(out);

	/* Extracting the winmail.dat */
        TNEFInitialize(tnef);
	tnef->Debug = verbose;
        if (TNEFParseFile(name, tnef) == -1) {
            printf("ERROR processing file\n");
        }
	processTnef(tnef);

        TNEFFree(tnef);
	/* Extraction done */

	dir = opendir(tmpdir);
	if (dir == NULL)
	    goto fail;

	mainpart = camel_mime_part_new();

	mp = camel_multipart_new();
	camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed");
	camel_multipart_set_boundary(mp, NULL);

	camel_medium_set_content_object((CamelMedium *)mainpart, (CamelDataWrapper *)mp);

	while ((d = readdir(dir))) {
		CamelMimePart *part;
		CamelDataWrapper *content;
		CamelStream *stream;
		char *path;
		const char *type;

		if (!strcmp(d->d_name, ".")
		    || !strcmp(d->d_name, "..")
		    || !strcmp(d->d_name, ".evo-attachment.tnef"))
		    continue;

		path = g_build_filename(tmpdir, d->d_name, NULL);

		stream = camel_stream_fs_new_with_name(path, O_RDONLY, 0);
		content = camel_data_wrapper_new();
		camel_data_wrapper_construct_from_stream(content, stream);
		camel_object_unref(stream);

		part = camel_mime_part_new();
		camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_BINARY);

		camel_medium_set_content_object((CamelMedium *)part, content);
		camel_object_unref(content);

		type = em_utils_snoop_type(part);
		if (type)
		    camel_data_wrapper_set_mime_type((CamelDataWrapper *)part, type);

		camel_mime_part_set_filename(part, d->d_name);

		g_free(path);

		camel_multipart_add_part(mp, part);
	}

	closedir(dir);

	len = t->format->part_id->len;
	g_string_append_printf(t->format->part_id, ".tnef");

	if (camel_multipart_get_number(mp) > 0)
		em_format_part_as(t->format, t->stream, mainpart, "multipart/mixed");
	else if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);

	g_string_truncate(t->format->part_id, len);

	camel_object_unref(mainpart);

	goto ok;
 fail:
	if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);
 ok:
	g_free(name);
	g_free(tmpdir);
}
int main (int argc, char **argv)
{
	CamelSession *session;
	CamelCipherContext *ctx;
	CamelException *ex;
	CamelCipherValidity *valid;
	CamelStream *stream1, *stream2;
	struct _CamelMimePart *sigpart, *conpart, *encpart, *outpart;
	CamelDataWrapper *dw;
	GPtrArray *recipients;
	GByteArray *buf;
	char *before, *after;
	int ret;

	if (getenv("CAMEL_TEST_GPG") == NULL)
		return 77;

	camel_test_init (argc, argv);

	/* clear out any camel-test data */
	system ("/bin/rm -rf /tmp/camel-test");
	system ("/bin/mkdir /tmp/camel-test");
	setenv ("GNUPGHOME", "/tmp/camel-test/.gnupg", 1);

	/* import the gpg keys */
	if ((ret = system ("gpg < /dev/null > /dev/null 2>&1")) == -1)
		return 77;
	else if (WEXITSTATUS (ret) == 127)
		return 77;

	g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1");
	system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1");
	g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1");
	system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1");

	session = camel_pgp_session_new ("/tmp/camel-test");

	ex = camel_exception_new ();

	ctx = camel_gpg_context_new (session);
	camel_gpg_context_set_always_trust (CAMEL_GPG_CONTEXT (ctx), TRUE);

	camel_test_start ("Test of PGP functions");

	stream1 = camel_stream_mem_new ();
	camel_stream_write (stream1, "Hello, I am a test stream.\n", 27);
	camel_stream_reset (stream1);

	conpart = camel_mime_part_new();
	dw = camel_data_wrapper_new();
	camel_data_wrapper_construct_from_stream(dw, stream1);
	camel_medium_set_content_object((CamelMedium *)conpart, dw);
	camel_object_unref(stream1);
	camel_object_unref(dw);

	sigpart = camel_mime_part_new();

	camel_test_push ("PGP signing");
	camel_cipher_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, conpart, sigpart, ex);
	if (camel_exception_is_set(ex)) {
		printf("PGP signing failed assuming non-functional environment\n%s", camel_exception_get_description (ex));
		camel_test_pull();
		return 77;
	}
	camel_test_pull ();

	camel_exception_clear (ex);

	camel_test_push ("PGP verify");
	valid = camel_cipher_verify (ctx, sigpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid));
	camel_cipher_validity_free (valid);
	camel_test_pull ();

	camel_object_unref(conpart);
	camel_object_unref(sigpart);

	stream1 = camel_stream_mem_new ();
	camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44);
	camel_stream_reset (stream1);

	conpart = camel_mime_part_new();
	dw = camel_data_wrapper_new();
	camel_stream_reset(stream1);
	camel_data_wrapper_construct_from_stream(dw, stream1);
	camel_medium_set_content_object((CamelMedium *)conpart, dw);
	camel_object_unref(stream1);
	camel_object_unref(dw);

	encpart = camel_mime_part_new();

	camel_exception_clear (ex);

	camel_test_push ("PGP encrypt");
	recipients = g_ptr_array_new ();
	g_ptr_array_add (recipients, "*****@*****.**");
	camel_cipher_encrypt (ctx, "*****@*****.**", recipients, conpart, encpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	g_ptr_array_free (recipients, TRUE);
	camel_test_pull ();

	camel_exception_clear (ex);

	camel_test_push ("PGP decrypt");
	outpart = camel_mime_part_new();
	valid = camel_cipher_decrypt (ctx, encpart, outpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (valid->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED, "%s", valid->encrypt.description);

	stream1 = camel_stream_mem_new();
	stream2 = camel_stream_mem_new();

	camel_data_wrapper_write_to_stream((CamelDataWrapper *)conpart, stream1);
	camel_data_wrapper_write_to_stream((CamelDataWrapper *)outpart, stream2);

	buf = CAMEL_STREAM_MEM (stream1)->buffer;
	before = g_strndup (buf->data, buf->len);
	buf = CAMEL_STREAM_MEM (stream2)->buffer;
	after = g_strndup (buf->data, buf->len);
	check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after);
	g_free (before);
	g_free (after);

	camel_object_unref(stream1);
	camel_object_unref(stream2);
	camel_object_unref(conpart);
	camel_object_unref(encpart);
	camel_object_unref(outpart);

	camel_test_pull ();

	camel_object_unref (CAMEL_OBJECT (ctx));
	camel_object_unref (CAMEL_OBJECT (session));

	camel_test_end ();

	return 0;
}