use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class MessageDecryptVerifier method findPrimaryPartInAlternative.
private static Part findPrimaryPartInAlternative(Part part) {
Body body = part.getBody();
if (part.isMimeType("multipart/alternative") && body instanceof Multipart) {
Multipart multipart = (Multipart) body;
if (multipart.getCount() == 0) {
return null;
}
BodyPart firstBodyPart = multipart.getBodyPart(0);
if (isPartPgpInlineEncryptedOrSigned(firstBodyPart)) {
return firstBodyPart;
}
}
return null;
}
use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class ImapFolder method fetchPart.
@Override
public void fetchPart(Message message, Part part, MessageRetrievalListener<Message> listener) throws MessagingException {
checkOpen();
String partId = part.getServerExtra();
String fetch;
if ("TEXT".equalsIgnoreCase(partId)) {
int maximumAutoDownloadMessageSize = store.getStoreConfig().getMaximumAutoDownloadMessageSize();
fetch = String.format(Locale.US, "BODY.PEEK[TEXT]<0.%d>", maximumAutoDownloadMessageSize);
} else {
fetch = String.format("BODY.PEEK[%s]", partId);
}
try {
String command = String.format("UID FETCH %s (UID %s)", message.getUid(), fetch);
connection.sendCommand(command, false);
ImapResponse response;
int messageNumber = 0;
ImapResponseCallback callback = new FetchPartCallback(part);
do {
response = connection.readResponse(callback);
if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(1), "FETCH")) {
ImapList fetchList = (ImapList) response.getKeyedValue("FETCH");
String uid = fetchList.getKeyedString("UID");
if (!message.getUid().equals(uid)) {
if (K9MailLib.isDebug()) {
Log.d(LOG_TAG, "Did not ask for UID " + uid + " for " + getLogId());
}
handleUntaggedResponse(response);
continue;
}
if (listener != null) {
listener.messageStarted(uid, messageNumber++, 1);
}
ImapMessage imapMessage = (ImapMessage) message;
Object literal = handleFetchResponse(imapMessage, fetchList);
if (literal != null) {
if (literal instanceof Body) {
// Most of the work was done in FetchAttchmentCallback.foundLiteral()
MimeMessageHelper.setBody(part, (Body) literal);
} else if (literal instanceof String) {
String bodyString = (String) literal;
InputStream bodyStream = new ByteArrayInputStream(bodyString.getBytes());
String contentTransferEncoding = part.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0];
String contentType = part.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0];
MimeMessageHelper.setBody(part, MimeUtility.createBody(bodyStream, contentTransferEncoding, contentType));
} else {
// This shouldn't happen
throw new MessagingException("Got FETCH response with bogus parameters");
}
}
if (listener != null) {
listener.messageFinished(message, messageNumber, 1);
}
} else {
handleUntaggedResponse(response);
}
} while (response.getTag() == null);
} catch (IOException ioe) {
throw ioExceptionHandler(connection, ioe);
}
}
use of com.fsck.k9.mail.Body 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);
}
}
use of com.fsck.k9.mail.Body 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));
}
use of com.fsck.k9.mail.Body 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);
}
Aggregations