From 7b67d054a4eabe3aaeef135a48c5c0531f60b680 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 29 Jan 2015 15:16:59 +0100 Subject: [PATCH 1/3] Don't save reference to multipart/encrypted "root" in decrypted parts --- .../k9/mailstore/DecryptStreamParser.java | 28 ++++++------------- .../ui/messageview/MessageViewFragment.java | 4 +-- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java index d95ab2df0..e38da1ce9 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java @@ -27,8 +27,8 @@ import org.apache.james.mime4j.stream.MimeConfig; public class DecryptStreamParser { - public static DecryptedBodyPart parse(Part multipartEncrypted, InputStream inputStream) throws MessagingException, IOException { - DecryptedBodyPart decryptedRootPart = new DecryptedBodyPart(multipartEncrypted); + public static DecryptedBodyPart parse(InputStream inputStream) throws MessagingException, IOException { + DecryptedBodyPart decryptedRootPart = new DecryptedBodyPart(); MimeConfig parserConfig = new MimeConfig(); parserConfig.setMaxHeaderLen(-1); @@ -36,7 +36,7 @@ public class DecryptStreamParser { parserConfig.setMaxHeaderCount(-1); MimeStreamParser parser = new MimeStreamParser(parserConfig); - parser.setContentHandler(new PartBuilder(multipartEncrypted, decryptedRootPart)); + parser.setContentHandler(new PartBuilder(decryptedRootPart)); parser.setRecurse(); try { @@ -64,12 +64,10 @@ public class DecryptStreamParser { private static class PartBuilder implements ContentHandler { - private final Part multipartEncrypted; private final DecryptedBodyPart decryptedRootPart; private final Stack stack = new Stack(); - public PartBuilder(Part multipartEncrypted, DecryptedBodyPart decryptedRootPart) throws MessagingException { - this.multipartEncrypted = multipartEncrypted; + public PartBuilder(DecryptedBodyPart decryptedRootPart) throws MessagingException { this.decryptedRootPart = decryptedRootPart; } @@ -80,7 +78,7 @@ public class DecryptStreamParser { } else { Part part = (Part) stack.peek(); - Message innerMessage = new DecryptedMimeMessage(multipartEncrypted); + Message innerMessage = new MimeMessage(); part.setBody(innerMessage); stack.push(innerMessage); @@ -97,7 +95,7 @@ public class DecryptStreamParser { try { Multipart multipart = (Multipart) stack.peek(); - BodyPart bodyPart = new DecryptedBodyPart(multipartEncrypted); + BodyPart bodyPart = new MimeBodyPart(); multipart.addBodyPart(bodyPart); stack.push(bodyPart); @@ -183,18 +181,8 @@ public class DecryptStreamParser { } public static class DecryptedBodyPart extends MimeBodyPart { - private final Part multipartEncrypted; - - public DecryptedBodyPart(Part multipartEncrypted) throws MessagingException { - this.multipartEncrypted = multipartEncrypted; - } - } - - public static class DecryptedMimeMessage extends MimeMessage { - private final Part multipartEncrypted; - - public DecryptedMimeMessage(Part multipartEncrypted) { - this.multipartEncrypted = multipartEncrypted; + public DecryptedBodyPart() throws MessagingException { + // Do nothing } } } diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java index 8eaab42d3..735eda80f 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java @@ -71,8 +71,6 @@ import com.fsck.k9.ui.message.DecodeMessageLoader; import com.fsck.k9.ui.message.LocalMessageLoader; import com.fsck.k9.view.MessageHeader; import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback; import org.openintents.openpgp.util.OpenPgpServiceConnection; @@ -381,7 +379,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF protected DecryptedBodyPart doInBackground(Void... params) { DecryptedBodyPart decryptedPart = null; try { - decryptedPart = DecryptStreamParser.parse(currentlyDecryptingPart, decryptedInputStream); + decryptedPart = DecryptStreamParser.parse(decryptedInputStream); latch.await(); } catch (InterruptedException e) { From 9e4768627722f6a985ef828fb199efb1e472527d Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 29 Jan 2015 15:23:48 +0100 Subject: [PATCH 2/3] Code style fixes --- .../ui/messageview/MessageViewFragment.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java index 735eda80f..9228e5845 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java @@ -92,6 +92,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF private static final int LOCAL_MESSAGE_LOADER_ID = 1; private static final int DECODE_MESSAGE_LOADER_ID = 2; + private static final int INVALID_OPENPGP_RESULT_CODE = -1; + public static MessageViewFragment newInstance(MessageReference reference) { MessageViewFragment fragment = new MessageViewFragment(); @@ -400,50 +402,52 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } private void onDecryptionConverge (DecryptedBodyPart decryptedPart) { - try { - if (currentDecryptingResult == null) { - Log.e(K9.LOG_TAG, "internal error, we should have a result here!"); + Log.e(K9.LOG_TAG, "Internal error: we should have a result here!"); return; } - int resultCode = currentDecryptingResult.getIntExtra(OpenPgpApi.RESULT_CODE, -1); - Log.d(K9.LOG_TAG, "result: " + resultCode); + int resultCode = currentDecryptingResult.getIntExtra(OpenPgpApi.RESULT_CODE, INVALID_OPENPGP_RESULT_CODE); + if (K9.DEBUG) { + Log.d(K9.LOG_TAG, "OpenPGP API decryptVerify result code: " + resultCode); + } switch (resultCode) { - case -1: - Log.e(K9.LOG_TAG, "internal error: no result code!"); - return; - + case INVALID_OPENPGP_RESULT_CODE: { + Log.e(K9.LOG_TAG, "Internal error: no result code!"); + break; + } case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { PendingIntent pendingIntent = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_INTENT); if (pendingIntent == null) { throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!"); } + try { getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(), MessageList.REQUEST_CODE_CRYPTO, null, 0, 0, 0); } catch (SendIntentException e) { - Log.e(K9.LOG_TAG, "internal error on starting pendingintent!", e); + Log.e(K9.LOG_TAG, "Internal error on starting pendingintent!", e); } - return; + break; } - case OpenPgpApi.RESULT_CODE_ERROR: { - Log.e(K9.LOG_TAG, "error msg: " + currentDecryptingResult.getStringExtra(OpenPgpApi.RESULT_ERROR)); + if (K9.DEBUG) { + String errorMessage = currentDecryptingResult.getStringExtra(OpenPgpApi.RESULT_ERROR); + Log.w(K9.LOG_TAG, "OpenPGP API error: " + errorMessage); + } onDecryptionFailed(); - return; + break; } - case OpenPgpApi.RESULT_CODE_SUCCESS: { onDecryptionSuccess(decryptedPart); + break; } } } finally { currentDecryptingResult = null; } - } public void handleCryptoResult(int resultCode, Intent data) { From fbfa6d146f501d473c2096810508a6e3d710908a Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 29 Jan 2015 16:16:29 +0100 Subject: [PATCH 3/3] Pass OpenPgpSignatureResult to LocalMessageExtractor --- .../k9/mailstore/DecryptStreamParser.java | 21 ++++++++++++ .../k9/mailstore/LocalMessageExtractor.java | 33 +++++++++++++++++-- .../ui/messageview/MessageViewFragment.java | 27 +++++++++++---- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java index e38da1ce9..13cd6c87d 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/DecryptStreamParser.java @@ -24,6 +24,8 @@ import org.apache.james.mime4j.parser.MimeStreamParser; import org.apache.james.mime4j.stream.BodyDescriptor; import org.apache.james.mime4j.stream.Field; import org.apache.james.mime4j.stream.MimeConfig; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; public class DecryptStreamParser { @@ -181,8 +183,27 @@ public class DecryptStreamParser { } public static class DecryptedBodyPart extends MimeBodyPart { + private OpenPgpSignatureResult signatureResult; + private OpenPgpError error; + public DecryptedBodyPart() throws MessagingException { // Do nothing } + + public OpenPgpSignatureResult getSignatureResult() { + return signatureResult; + } + + public void setSignatureResult(OpenPgpSignatureResult signatureResult) { + this.signatureResult = signatureResult; + } + + public OpenPgpError getError() { + return error; + } + + public void setError(OpenPgpError error) { + this.error = error; + } } } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java index a021bcede..95aaf3794 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java @@ -4,15 +4,20 @@ import android.content.Context; import android.net.Uri; import com.fsck.k9.R; +import com.fsck.k9.crypto.MessageDecryptor; import com.fsck.k9.mail.Address; +import com.fsck.k9.mail.Body; +import com.fsck.k9.mail.BodyPart; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mail.Multipart; import com.fsck.k9.mail.Part; import com.fsck.k9.helper.HtmlConverter; import com.fsck.k9.mail.internet.MessageExtractor; import com.fsck.k9.mail.internet.MimeHeader; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mail.internet.Viewable; +import com.fsck.k9.mailstore.DecryptStreamParser.DecryptedBodyPart; import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer; import com.fsck.k9.provider.AttachmentProvider; import org.openintents.openpgp.OpenPgpSignatureResult; @@ -36,6 +41,7 @@ public class LocalMessageExtractor { private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length(); private static final String FILENAME_SUFFIX = " "; private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length(); + private static final OpenPgpSignatureResult NO_SIGNATURE_RESULT = null; private LocalMessageExtractor() {} /** @@ -433,8 +439,7 @@ public class LocalMessageExtractor { attachments); List attachmentInfos = extractAttachmentInfos(attachments); - // TODO correctly extract OpenPgpSignatureResult and add to MessageViewContainer - OpenPgpSignatureResult result = null; + OpenPgpSignatureResult result = getSignatureResultForPart(part); containers.add(new MessageViewContainer(viewable.html, attachmentInfos, result, false, null)); } @@ -442,6 +447,30 @@ public class LocalMessageExtractor { return new MessageViewInfo(containers, message); } + private static OpenPgpSignatureResult getSignatureResultForPart(Part part) { + if (!MessageDecryptor.isPgpMimeEncryptedPart(part)) { + return NO_SIGNATURE_RESULT; + } + + Body body = part.getBody(); + if (!(body instanceof Multipart)) { + return NO_SIGNATURE_RESULT; + } + + Multipart multipart = (Multipart) body; + if (multipart.getCount() < 3) { + return NO_SIGNATURE_RESULT; + } + + BodyPart bodyPart = multipart.getBodyPart(2); + if (!(bodyPart instanceof DecryptedBodyPart)) { + return NO_SIGNATURE_RESULT; + } + + DecryptedBodyPart decryptedBodyPart = (DecryptedBodyPart) bodyPart; + return decryptedBodyPart.getSignatureResult(); + } + private static List extractAttachmentInfos(List attachmentParts) throws MessagingException { diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java index 9228e5845..3deb3ca4a 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java @@ -71,6 +71,8 @@ import com.fsck.k9.ui.message.DecodeMessageLoader; import com.fsck.k9.ui.message.LocalMessageLoader; import com.fsck.k9.view.MessageHeader; import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback; import org.openintents.openpgp.util.OpenPgpServiceConnection; @@ -433,14 +435,20 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF break; } case OpenPgpApi.RESULT_CODE_ERROR: { + OpenPgpError error = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + if (K9.DEBUG) { - String errorMessage = currentDecryptingResult.getStringExtra(OpenPgpApi.RESULT_ERROR); - Log.w(K9.LOG_TAG, "OpenPGP API error: " + errorMessage); + Log.w(K9.LOG_TAG, "OpenPGP API error: " + error.getMessage()); } - onDecryptionFailed(); + + onDecryptionFailed(error); break; } case OpenPgpApi.RESULT_CODE_SUCCESS: { + OpenPgpSignatureResult signatureResult = + currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE); + decryptedPart.setSignatureResult(signatureResult); + onDecryptionSuccess(decryptedPart); break; } @@ -454,7 +462,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF if (resultCode == Activity.RESULT_OK) { decryptNextPartOrStartExtractingTextAndAttachments(); } else { - onDecryptionFailed(); + //FIXME: don't pass null + onDecryptionFailed(null); } } @@ -468,8 +477,14 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF multipart.addBodyPart(decryptedPart); } - private void onDecryptionFailed() { - // TODO: display error to user? + private void onDecryptionFailed(OpenPgpError error) { + try { + DecryptedBodyPart errorPart = new DecryptedBodyPart(); + errorPart.setError(error); + addDecryptedPartToMessage(errorPart); + } catch (MessagingException e) { + Log.e(K9.LOG_TAG, "This shouldn't happen", e); + } onDecryptionFinished(); }