Search in sources :

Example 6 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class AttachmentInfoExtractorTest method extractInfoForDb__withDispositionAttach__shouldReturnNamedAttachment.

@Test
public void extractInfoForDb__withDispositionAttach__shouldReturnNamedAttachment() throws Exception {
    MimeBodyPart part = new MimeBodyPart();
    part.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, "attachment" + "; filename=\"filename.ext\"; meaningless=\"dummy\"");
    AttachmentViewInfo attachmentViewInfo = attachmentInfoExtractor.extractAttachmentInfoForDatabase(part);
    assertEquals(Uri.EMPTY, attachmentViewInfo.internalUri);
    assertEquals("filename.ext", attachmentViewInfo.displayName);
    assertFalse(attachmentViewInfo.inlineAttachment);
}
Also used : MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart) AttachmentViewInfo(com.fsck.k9.mailstore.AttachmentViewInfo) Test(org.junit.Test)

Example 7 with Attachment

use of com.fsck.k9.activity.misc.Attachment 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 8 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class AttachmentProvider method query.

@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    String[] columnNames = (projection == null) ? DEFAULT_PROJECTION : projection;
    List<String> segments = uri.getPathSegments();
    String accountUuid = segments.get(0);
    String id = segments.get(1);
    final AttachmentInfo attachmentInfo;
    try {
        final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
        attachmentInfo = LocalStore.getInstance(account, getContext()).getAttachmentInfo(id);
    } catch (MessagingException e) {
        Timber.e(e, "Unable to retrieve attachment info from local store for ID: %s", id);
        return null;
    }
    if (attachmentInfo == null) {
        Timber.d("No attachment info for ID: %s", id);
        return null;
    }
    MatrixCursor ret = new MatrixCursor(columnNames);
    Object[] values = new Object[columnNames.length];
    for (int i = 0, count = columnNames.length; i < count; i++) {
        String column = columnNames[i];
        if (AttachmentProviderColumns._ID.equals(column)) {
            values[i] = id;
        } else if (AttachmentProviderColumns.DATA.equals(column)) {
            values[i] = uri.toString();
        } else if (AttachmentProviderColumns.DISPLAY_NAME.equals(column)) {
            values[i] = attachmentInfo.name;
        } else if (AttachmentProviderColumns.SIZE.equals(column)) {
            values[i] = attachmentInfo.size;
        }
    }
    ret.addRow(values);
    return ret;
}
Also used : Account(com.fsck.k9.Account) MessagingException(com.fsck.k9.mail.MessagingException) AttachmentInfo(com.fsck.k9.mailstore.LocalStore.AttachmentInfo) MatrixCursor(android.database.MatrixCursor)

Example 9 with Attachment

use of com.fsck.k9.activity.misc.Attachment 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 10 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class MessageExtractor method collectAttachments.

/**
     * Collect attachment parts of a message.
     * @return A list of parts regarded as attachments.
     * @throws MessagingException In case of an error.
     */
public static List<Part> collectAttachments(Message message) throws MessagingException {
    try {
        List<Part> attachments = new ArrayList<>();
        findViewablesAndAttachments(message, new ArrayList<Viewable>(), attachments);
        return attachments;
    } catch (Exception e) {
        throw new MessagingException("Couldn't collect attachment parts", e);
    }
}
Also used : MessagingException(com.fsck.k9.mail.MessagingException) Part(com.fsck.k9.mail.Part) BodyPart(com.fsck.k9.mail.BodyPart) ArrayList(java.util.ArrayList) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException)

Aggregations

Attachment (com.fsck.k9.activity.misc.Attachment)8 Test (org.junit.Test)8 MessagingException (com.fsck.k9.mail.MessagingException)7 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)7 Part (com.fsck.k9.mail.Part)6 Body (com.fsck.k9.mail.Body)5 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)5 BodyPart (com.fsck.k9.mail.BodyPart)4 Multipart (com.fsck.k9.mail.Multipart)4 AttachmentViewInfo (com.fsck.k9.mailstore.AttachmentViewInfo)4 File (java.io.File)4 ArrayList (java.util.ArrayList)4 MimeMultipart (com.fsck.k9.mail.internet.MimeMultipart)3 SQLiteException (android.database.sqlite.SQLiteException)2 Uri (android.net.Uri)2 Address (com.fsck.k9.mail.Address)2 TextBody (com.fsck.k9.mail.internet.TextBody)2 Html (com.fsck.k9.mail.internet.Viewable.Html)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2