Search in sources :

Example 31 with Multipart

use of com.fsck.k9.mail.Multipart in project k-9 by k9mail.

the class ImapFolder method parseBodyStructure.

private void parseBodyStructure(ImapList bs, Part part, String id) throws MessagingException {
    if (bs.get(0) instanceof ImapList) {
        /*
             * This is a multipart/*
             */
        MimeMultipart mp = MimeMultipart.newInstance();
        for (int i = 0, count = bs.size(); i < count; i++) {
            if (bs.get(i) instanceof ImapList) {
                /*
                     * For each part in the message we're going to add a new BodyPart and parse
                     * into it.
                     */
                MimeBodyPart bp = new MimeBodyPart();
                if (id.equalsIgnoreCase("TEXT")) {
                    parseBodyStructure(bs.getList(i), bp, Integer.toString(i + 1));
                } else {
                    parseBodyStructure(bs.getList(i), bp, id + "." + (i + 1));
                }
                mp.addBodyPart(bp);
            } else {
                /*
                     * We've got to the end of the children of the part, so now we can find out
                     * what type it is and bail out.
                     */
                String subType = bs.getString(i);
                mp.setSubType(subType.toLowerCase(Locale.US));
                break;
            }
        }
        MimeMessageHelper.setBody(part, mp);
    } else {
        /*
             * This is a body. We need to add as much information as we can find out about
             * it to the Part.
             */
        /*
             *  0| 0  body type
             *  1| 1  body subtype
             *  2| 2  body parameter parenthesized list
             *  3| 3  body id (unused)
             *  4| 4  body description (unused)
             *  5| 5  body encoding
             *  6| 6  body size
             *  -| 7  text lines (only for type TEXT, unused)
             * Extensions (optional):
             *  7| 8  body MD5 (unused)
             *  8| 9  body disposition
             *  9|10  body language (unused)
             * 10|11  body location (unused)
             */
        String type = bs.getString(0);
        String subType = bs.getString(1);
        String mimeType = (type + "/" + subType).toLowerCase(Locale.US);
        ImapList bodyParams = null;
        if (bs.get(2) instanceof ImapList) {
            bodyParams = bs.getList(2);
        }
        String encoding = bs.getString(5);
        int size = bs.getNumber(6);
        if (MimeUtility.isMessage(mimeType)) {
            /*
                 * This will be caught by fetch and handled appropriately.
                 */
            throw new MessagingException("BODYSTRUCTURE message/rfc822 not yet supported.");
        }
        /*
             * Set the content type with as much information as we know right now.
             */
        StringBuilder contentType = new StringBuilder();
        contentType.append(mimeType);
        if (bodyParams != null) {
            /*
                 * If there are body params we might be able to get some more information out
                 * of them.
                 */
            for (int i = 0, count = bodyParams.size(); i < count; i += 2) {
                String paramName = bodyParams.getString(i);
                String paramValue = bodyParams.getString(i + 1);
                contentType.append(String.format(";\r\n %s=\"%s\"", paramName, paramValue));
            }
        }
        part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType.toString());
        // Extension items
        ImapList bodyDisposition = null;
        if ("text".equalsIgnoreCase(type) && bs.size() > 9 && bs.get(9) instanceof ImapList) {
            bodyDisposition = bs.getList(9);
        } else if (!("text".equalsIgnoreCase(type)) && bs.size() > 8 && bs.get(8) instanceof ImapList) {
            bodyDisposition = bs.getList(8);
        }
        StringBuilder contentDisposition = new StringBuilder();
        if (bodyDisposition != null && !bodyDisposition.isEmpty()) {
            if (!"NIL".equalsIgnoreCase(bodyDisposition.getString(0))) {
                contentDisposition.append(bodyDisposition.getString(0).toLowerCase(Locale.US));
            }
            if (bodyDisposition.size() > 1 && bodyDisposition.get(1) instanceof ImapList) {
                ImapList bodyDispositionParams = bodyDisposition.getList(1);
                /*
                     * If there is body disposition information we can pull some more information
                     * about the attachment out.
                     */
                for (int i = 0, count = bodyDispositionParams.size(); i < count; i += 2) {
                    String paramName = bodyDispositionParams.getString(i).toLowerCase(Locale.US);
                    String paramValue = bodyDispositionParams.getString(i + 1);
                    contentDisposition.append(String.format(";\r\n %s=\"%s\"", paramName, paramValue));
                }
            }
        }
        if (MimeUtility.getHeaderParameter(contentDisposition.toString(), "size") == null) {
            contentDisposition.append(String.format(Locale.US, ";\r\n size=%d", size));
        }
        /*
             * Set the content disposition containing at least the size. Attachment
             * handling code will use this down the road.
             */
        part.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, contentDisposition.toString());
        /*
             * Set the Content-Transfer-Encoding header. Attachment code will use this
             * to parse the body.
             */
        part.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, encoding);
        if (part instanceof ImapMessage) {
            ((ImapMessage) part).setSize(size);
        }
        part.setServerExtra(id);
    }
}
Also used : MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) MessagingException(com.fsck.k9.mail.MessagingException) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart)

Example 32 with Multipart

use of com.fsck.k9.mail.Multipart in project k-9 by k9mail.

the class PgpMimeMessageTest method testSignedMessage.

@Test
public void testSignedMessage() throws IOException, MessagingException, PGPException {
    String messageSource = "Date: Mon, 08 Dec 2014 17:44:18 +0100\r\n" + "From: cketti <cketti@googlemail.com>\r\n" + "MIME-Version: 1.0\r\n" + "To: test@example.com\r\n" + "Subject: OpenPGP signature test\r\n" + "Content-Type: multipart/signed; micalg=pgp-sha1;\r\n" + " protocol=\"application/pgp-signature\";\r\n" + " boundary=\"24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM\"\r\n" + "\r\n" + "This is an OpenPGP/MIME signed message (RFC 4880 and 3156)\r\n" + "--24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM\r\n" + "Content-Type: multipart/mixed;\r\n" + " boundary=\"------------030308060900040601010501\"\r\n" + "\r\n" + "This is a multi-part message in MIME format.\r\n" + "--------------030308060900040601010501\r\n" + "Content-Type: text/plain; charset=utf-8\r\n" + "Content-Transfer-Encoding: quoted-printable\r\n" + "\r\n" + "Message body\r\n" + "goes here\r\n" + "\r\n" + "\r\n" + "--------------030308060900040601010501\r\n" + "Content-Type: text/plain; charset=UTF-8;\r\n" + " name=\"attachment.txt\"\r\n" + "Content-Transfer-Encoding: base64\r\n" + "Content-Disposition: attachment;\r\n" + " filename=\"attachment.txt\"\r\n" + "\r\n" + "VGV4dCBhdHRhY2htZW50Cg==\r\n" + "--------------030308060900040601010501--\r\n" + "\r\n" + "--24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM\r\n" + "Content-Type: application/pgp-signature; name=\"signature.asc\"\r\n" + "Content-Description: OpenPGP digital signature\r\n" + "Content-Disposition: attachment; filename=\"signature.asc\"\r\n" + "\r\n" + "-----BEGIN PGP SIGNATURE-----\r\n" + "Version: GnuPG v1\r\n" + "\r\n" + "iQIcBAEBAgAGBQJUhdVqAAoJEO4v7zp9qOKJ8DQP/1+JE8UF7UmirnN1ZO+25hFC\r\n" + "jAfFMxRWMWXN0gGB+6ySy6ah0bCwmRwHpRBsW/tNcsmOPKb2XBf9zwF06uk/lLp4\r\n" + "ZmGXxSdQ9XJrlaHk8Sitn9Gi/1L+MNWgrsrLROAZv2jfc9wqN3FOrhN9NC1QXQvO\r\n" + "+D7sMorSr3l94majoIDrzvxEnfJVfrZWNTUaulJofOJ55GBZ3UJNob1WKjrnculL\r\n" + "IwmSERmVUoFBUfe/MBqqZH0WDJq9nt//NZFHLunj6nGsrpush1dQRcbR3zzQfXkk\r\n" + "s7zDLDa8VUv6OxcefjsVN/O7EenoWWgNg6GfW6tY2+oUsLSP2OS3JXvYsylQP4hR\r\n" + "iU1V9vvsu2Ax6bVb0+uTqw3jNiqVFy3o4mBigVUqp1EFIwBYmyNbe5wj4ACs9Avj\r\n" + "9t2reFSfXobWQFUS4s71JeMefNAHHJWZI63wNTxE6LOw01YxdJiDaPWGTOyM75MK\r\n" + "yqn7r5uIfeSv8NypGJaUv4firxKbrcZKk7Wpeh/rZuUSgoPcf3I1IzXfGKKIBHjU\r\n" + "WUMhTF5SoC5kIZyeXvHrhTM8HszcS8EoG2XcmcYArwgCUlOunFwZNqLPsfdMTRL6\r\n" + "9rcioaohEtroqoJiGAToJtIz8kqCaamnP/ASBkp9qqJizRd6fqt+tE8BsmJbuPLS\r\n" + "6lBpS8j0TqmaZMYfB9u4\r\n" + "=QvET\r\n" + "-----END PGP SIGNATURE-----\r\n" + "\r\n" + "--24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM--\r\n";
    BinaryTempFileBody.setTempDirectory(InstrumentationRegistry.getTargetContext().getCacheDir());
    InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
    MimeMessage message;
    try {
        message = MimeMessage.parseMimeMessage(messageInputStream, true);
    } finally {
        messageInputStream.close();
    }
    Multipart multipartSigned = (Multipart) message.getBody();
    BodyPart signedPart = multipartSigned.getBodyPart(0);
    ByteArrayOutputStream signedPartOutputStream = new ByteArrayOutputStream();
    signedPart.writeTo(signedPartOutputStream);
    byte[] signedData = signedPartOutputStream.toByteArray();
    Body signatureBody = multipartSigned.getBodyPart(1).getBody();
    ByteArrayOutputStream signatureBodyOutputStream = new ByteArrayOutputStream();
    signatureBody.writeTo(signatureBodyOutputStream);
    byte[] signatureData = signatureBodyOutputStream.toByteArray();
    assertTrue(verifySignature(signedData, signatureData));
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) BinaryTempFileBody(com.fsck.k9.mail.internet.BinaryTempFileBody) Test(org.junit.Test)

Example 33 with Multipart

use of com.fsck.k9.mail.Multipart in project k-9 by k9mail.

the class ReconstructMessageTest method testMessage.

@Test
public void testMessage() throws IOException, MessagingException {
    String messageSource = "From: from@example.com\r\n" + "To: to@example.com\r\n" + "Subject: Test Message \r\n" + "Date: Thu, 13 Nov 2014 17:09:38 +0100\r\n" + "Content-Type: multipart/mixed;\r\n" + " boundary=\"----Boundary\"\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "MIME-Version: 1.0\r\n" + "\r\n" + "This is a multipart MIME message.\r\n" + "------Boundary\r\n" + "Content-Type: text/plain; charset=utf-8\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "Testing.\r\n" + "This is a text body with some greek characters.\r\n" + "αβγδεζηθ\r\n" + "End of test.\r\n" + "\r\n" + "------Boundary\r\n" + "Content-Type: text/plain\r\n" + "Content-Transfer-Encoding: base64\r\n" + "\r\n" + "VGhpcyBpcyBhIHRl\r\n" + "c3QgbWVzc2FnZQ==\r\n" + "\r\n" + "------Boundary--\r\n" + "Hi, I'm the epilogue";
    BinaryTempFileBody.setTempDirectory(InstrumentationRegistry.getTargetContext().getCacheDir());
    InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
    MimeMessage message;
    try {
        message = MimeMessage.parseMimeMessage(messageInputStream, true);
    } finally {
        messageInputStream.close();
    }
    ByteArrayOutputStream messageOutputStream = new ByteArrayOutputStream();
    try {
        message.writeTo(messageOutputStream);
    } finally {
        messageOutputStream.close();
    }
    String reconstructedMessage = new String(messageOutputStream.toByteArray());
    assertEquals(messageSource, reconstructedMessage);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Example 34 with Multipart

use of com.fsck.k9.mail.Multipart in project k-9 by k9mail.

the class MimeMessageHelper method setBody.

public static void setBody(Part part, Body body) throws MessagingException {
    part.setBody(body);
    if (part instanceof Message) {
        part.setHeader("MIME-Version", "1.0");
    }
    if (body instanceof Multipart) {
        Multipart multipart = ((Multipart) body);
        multipart.setParent(part);
        String mimeType = multipart.getMimeType();
        String contentType = String.format("%s; boundary=\"%s\"", mimeType, multipart.getBoundary());
        part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType);
        // note: if this is ever changed to 8bit, multipart/signed parts must always be 7bit!
        setEncoding(part, MimeUtil.ENC_7BIT);
    } else if (body instanceof TextBody) {
        String contentType;
        if (MimeUtility.mimeTypeMatches(part.getMimeType(), "text/*")) {
            contentType = String.format("%s;\r\n charset=utf-8", part.getMimeType());
            String name = MimeUtility.getHeaderParameter(part.getContentType(), "name");
            if (name != null) {
                contentType += String.format(";\r\n name=\"%s\"", name);
            }
        } else {
            contentType = part.getMimeType();
        }
        part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType);
        setEncoding(part, MimeUtil.ENC_QUOTED_PRINTABLE);
    } else if (body instanceof RawDataBody) {
        String encoding = ((RawDataBody) body).getEncoding();
        part.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, encoding);
    }
}
Also used : Multipart(com.fsck.k9.mail.Multipart) Message(com.fsck.k9.mail.Message)

Example 35 with Multipart

use of com.fsck.k9.mail.Multipart in project k-9 by k9mail.

the class MessageExtractor method findAttachments.

/**
     * Traverse the MIME tree and add everything that's not a known text part to 'attachments'.
     *
     * @param multipart
     *         The {@link Multipart} to start from.
     * @param knownTextParts
     *         A set of known text parts we don't want to end up in 'attachments'.
     * @param attachments
     *         A list that will receive the parts that are considered attachments.
     */
private static void findAttachments(Multipart multipart, Set<Part> knownTextParts, @NonNull List<Part> attachments) {
    for (Part part : multipart.getBodyParts()) {
        Body body = part.getBody();
        if (body instanceof Multipart) {
            Multipart innerMultipart = (Multipart) body;
            findAttachments(innerMultipart, knownTextParts, attachments);
        } else if (!knownTextParts.contains(part)) {
            attachments.add(part);
        }
    }
}
Also used : Multipart(com.fsck.k9.mail.Multipart) Part(com.fsck.k9.mail.Part) BodyPart(com.fsck.k9.mail.BodyPart) Body(com.fsck.k9.mail.Body)

Aggregations

BodyPart (com.fsck.k9.mail.BodyPart)57 Part (com.fsck.k9.mail.Part)51 Test (org.junit.Test)47 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)38 Multipart (com.fsck.k9.mail.Multipart)33 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)29 Message (com.fsck.k9.mail.Message)25 Body (com.fsck.k9.mail.Body)22 MimeMultipart (com.fsck.k9.mail.internet.MimeMultipart)21 ArrayList (java.util.ArrayList)14 MessageCreationHelper.createEmptyPart (com.fsck.k9.message.MessageCreationHelper.createEmptyPart)13 MessageCreationHelper.createPart (com.fsck.k9.message.MessageCreationHelper.createPart)13 MessageCreationHelper.createTextPart (com.fsck.k9.message.MessageCreationHelper.createTextPart)13 ByteArrayOutputStream (java.io.ByteArrayOutputStream)8 TextBody (com.fsck.k9.mail.internet.TextBody)7 MessagingException (com.fsck.k9.mail.MessagingException)6 Stack (java.util.Stack)6 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)5 FetchProfile (com.fsck.k9.mail.FetchProfile)5 BinaryTempFileBody (com.fsck.k9.mail.internet.BinaryTempFileBody)5