use of com.fsck.k9.mail.BodyPart in project k-9 by k9mail.
the class PgpMessageBuilder method launchOpenPgpApiIntent.
private PendingIntent launchOpenPgpApiIntent(@NonNull Intent openPgpIntent, boolean captureOutputPart, boolean capturedOutputPartIs7Bit, boolean writeBodyContentOnly) throws MessagingException {
final MimeBodyPart bodyPart = currentProcessedMimeMessage.toBodyPart();
String[] contentType = currentProcessedMimeMessage.getHeader(MimeHeader.HEADER_CONTENT_TYPE);
if (contentType.length > 0) {
bodyPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType[0]);
}
OpenPgpDataSource dataSource = createOpenPgpDataSourceFromBodyPart(bodyPart, writeBodyContentOnly);
BinaryTempFileBody pgpResultTempBody = null;
OutputStream outputStream = null;
if (captureOutputPart) {
try {
pgpResultTempBody = new BinaryTempFileBody(capturedOutputPartIs7Bit ? MimeUtil.ENC_7BIT : MimeUtil.ENC_8BIT);
outputStream = pgpResultTempBody.getOutputStream();
// OpenKeychain/BouncyCastle at this point use the system newline for formatting, which is LF on android.
// we need this to be CRLF, so we convert the data after receiving.
outputStream = new EOLConvertingOutputStream(outputStream);
} catch (IOException e) {
throw new MessagingException("could not allocate temp file for storage!", e);
}
}
Intent result = openPgpApi.executeApi(openPgpIntent, dataSource, outputStream);
switch(result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
mimeBuildMessage(result, bodyPart, pgpResultTempBody);
return null;
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
PendingIntent returnedPendingIntent = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
if (returnedPendingIntent == null) {
throw new MessagingException("openpgp api needs user interaction, but returned no pendingintent!");
}
return returnedPendingIntent;
case OpenPgpApi.RESULT_CODE_ERROR:
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
if (error == null) {
throw new MessagingException("internal openpgp api error");
}
boolean isOpportunisticError = error.getErrorId() == OpenPgpError.OPPORTUNISTIC_MISSING_KEYS;
if (isOpportunisticError) {
if (!cryptoStatus.isEncryptionOpportunistic()) {
throw new IllegalStateException("Got opportunistic error, but encryption wasn't supposed to be opportunistic!");
}
Timber.d("Skipping encryption due to opportunistic mode");
return null;
}
throw new MessagingException(error.getMessage());
}
throw new IllegalStateException("unreachable code segment reached");
}
use of com.fsck.k9.mail.BodyPart in project k-9 by k9mail.
the class EncryptionDetector method containsPartWithMimeType.
private boolean containsPartWithMimeType(Part part, String... wantedMimeTypes) {
String mimeType = part.getMimeType();
if (isMimeTypeAnyOf(mimeType, wantedMimeTypes)) {
return true;
}
Body body = part.getBody();
if (body instanceof Multipart) {
Multipart multipart = (Multipart) body;
for (BodyPart bodyPart : multipart.getBodyParts()) {
if (containsPartWithMimeType(bodyPart, wantedMimeTypes)) {
return true;
}
}
}
return false;
}
use of com.fsck.k9.mail.BodyPart in project k-9 by k9mail.
the class PgpMessageBuilderTest method buildSign__withDetachedSignatureInResult__shouldSucceed.
@Test
public void buildSign__withDetachedSignatureInResult__shouldSucceed() throws MessagingException {
cryptoStatusBuilder.setCryptoMode(CryptoMode.SIGN_ONLY);
pgpMessageBuilder.setCryptoStatus(cryptoStatusBuilder.build());
ArgumentCaptor<Intent> capturedApiIntent = ArgumentCaptor.forClass(Intent.class);
Intent returnIntent = new Intent();
returnIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
returnIntent.putExtra(OpenPgpApi.RESULT_DETACHED_SIGNATURE, new byte[] { 1, 2, 3 });
when(openPgpApi.executeApi(capturedApiIntent.capture(), any(OpenPgpDataSource.class), any(OutputStream.class))).thenReturn(returnIntent);
Callback mockCallback = mock(Callback.class);
pgpMessageBuilder.buildAsync(mockCallback);
Intent expectedIntent = new Intent(OpenPgpApi.ACTION_DETACHED_SIGN);
expectedIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
expectedIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
assertIntentEqualsActionAndExtras(expectedIntent, capturedApiIntent.getValue());
ArgumentCaptor<MimeMessage> captor = ArgumentCaptor.forClass(MimeMessage.class);
verify(mockCallback).onMessageBuildSuccess(captor.capture(), eq(false));
verifyNoMoreInteractions(mockCallback);
MimeMessage message = captor.getValue();
Assert.assertEquals("message must be multipart/signed", "multipart/signed", message.getMimeType());
MimeMultipart multipart = (MimeMultipart) message.getBody();
Assert.assertEquals("multipart/signed must consist of two parts", 2, multipart.getCount());
BodyPart contentBodyPart = multipart.getBodyPart(0);
Assert.assertEquals("first part must have content type text/plain", "text/plain", MimeUtility.getHeaderParameter(contentBodyPart.getContentType(), null));
Assert.assertTrue("signed message body must be TextBody", contentBodyPart.getBody() instanceof TextBody);
Assert.assertEquals(MimeUtil.ENC_QUOTED_PRINTABLE, ((TextBody) contentBodyPart.getBody()).getEncoding());
assertContentOfBodyPartEquals("content must match the message text", contentBodyPart, TEST_MESSAGE_TEXT);
BodyPart signatureBodyPart = multipart.getBodyPart(1);
String contentType = signatureBodyPart.getContentType();
Assert.assertEquals("second part must be pgp signature", "application/pgp-signature", MimeUtility.getHeaderParameter(contentType, null));
Assert.assertEquals("second part must be called signature.asc", "signature.asc", MimeUtility.getHeaderParameter(contentType, "name"));
assertContentOfBodyPartEquals("content must match the supplied detached signature", signatureBodyPart, new byte[] { 1, 2, 3 });
}
use of com.fsck.k9.mail.BodyPart in project k-9 by k9mail.
the class PgpMessageBuilderTest method buildEncrypt__shouldSucceed.
@Test
public void buildEncrypt__shouldSucceed() throws MessagingException {
ComposeCryptoStatus cryptoStatus = cryptoStatusBuilder.setCryptoMode(CryptoMode.PRIVATE).setRecipients(Collections.singletonList(new Recipient("test", "test@example.org", "labru", -1, "key"))).build();
pgpMessageBuilder.setCryptoStatus(cryptoStatus);
ArgumentCaptor<Intent> capturedApiIntent = ArgumentCaptor.forClass(Intent.class);
Intent returnIntent = new Intent();
returnIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
when(openPgpApi.executeApi(capturedApiIntent.capture(), any(OpenPgpDataSource.class), any(OutputStream.class))).thenReturn(returnIntent);
Callback mockCallback = mock(Callback.class);
pgpMessageBuilder.buildAsync(mockCallback);
Intent expectedApiIntent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, new long[] { TEST_SELF_ENCRYPT_KEY_ID });
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_ENCRYPT_OPPORTUNISTIC, false);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, cryptoStatus.getRecipientAddresses());
assertIntentEqualsActionAndExtras(expectedApiIntent, capturedApiIntent.getValue());
ArgumentCaptor<MimeMessage> captor = ArgumentCaptor.forClass(MimeMessage.class);
verify(mockCallback).onMessageBuildSuccess(captor.capture(), eq(false));
verifyNoMoreInteractions(mockCallback);
MimeMessage message = captor.getValue();
Assert.assertEquals("message must be multipart/encrypted", "multipart/encrypted", message.getMimeType());
MimeMultipart multipart = (MimeMultipart) message.getBody();
Assert.assertEquals("multipart/encrypted must consist of two parts", 2, multipart.getCount());
BodyPart dummyBodyPart = multipart.getBodyPart(0);
Assert.assertEquals("first part must be pgp encrypted dummy part", "application/pgp-encrypted", dummyBodyPart.getContentType());
assertContentOfBodyPartEquals("content must match the supplied detached signature", dummyBodyPart, "Version: 1");
BodyPart encryptedBodyPart = multipart.getBodyPart(1);
Assert.assertEquals("second part must be octet-stream of encrypted data", "application/octet-stream; name=\"encrypted.asc\"", encryptedBodyPart.getContentType());
Assert.assertTrue("message body must be BinaryTempFileBody", encryptedBodyPart.getBody() instanceof BinaryTempFileBody);
Assert.assertEquals(MimeUtil.ENC_7BIT, ((BinaryTempFileBody) encryptedBodyPart.getBody()).getEncoding());
}
use of com.fsck.k9.mail.BodyPart in project k-9 by k9mail.
the class MigrationTest method migrateHtmlWithRelatedMessage.
@Test
public void migrateHtmlWithRelatedMessage() throws Exception {
SQLiteDatabase db = createV50Database();
insertHtmlWithRelatedMessage(db);
db.close();
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
LocalMessage msg = localStore.getFolder("dev").getMessage("10");
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.BODY);
localStore.getFolder("dev").fetch(Collections.singletonList(msg), fp, null);
Assert.assertEquals(9, msg.getId());
Assert.assertEquals(11, msg.getHeaderNames().size());
Assert.assertEquals("multipart/mixed", msg.getMimeType());
Assert.assertEquals(1, msg.getAttachmentCount());
Multipart msgBody = (Multipart) msg.getBody();
Assert.assertEquals("------------050707070308090509030605", msgBody.getBoundary());
Multipart multipartAlternativePart = (Multipart) msgBody.getBodyPart(0).getBody();
BodyPart htmlPart = multipartAlternativePart.getBodyPart(1);
String msgTextContent = MessageExtractor.getTextFromPart(htmlPart);
Assert.assertNotNull(msgTextContent);
Assert.assertTrue(msgTextContent.contains("cid:part1.07090108.09020601@example.org"));
Assert.assertEquals("image/jpeg", msgBody.getBodyPart(1).getMimeType());
}
Aggregations