mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-23 18:02:15 -05:00
Merge branch 'store_decryption_result' into pgp_mime_preparations
Conflicts: k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java
This commit is contained in:
commit
fed15a01e5
@ -24,11 +24,13 @@ import org.apache.james.mime4j.parser.MimeStreamParser;
|
|||||||
import org.apache.james.mime4j.stream.BodyDescriptor;
|
import org.apache.james.mime4j.stream.BodyDescriptor;
|
||||||
import org.apache.james.mime4j.stream.Field;
|
import org.apache.james.mime4j.stream.Field;
|
||||||
import org.apache.james.mime4j.stream.MimeConfig;
|
import org.apache.james.mime4j.stream.MimeConfig;
|
||||||
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
|
|
||||||
|
|
||||||
public class DecryptStreamParser {
|
public class DecryptStreamParser {
|
||||||
public static DecryptedBodyPart parse(Part multipartEncrypted, InputStream inputStream) throws MessagingException, IOException {
|
public static DecryptedBodyPart parse(InputStream inputStream) throws MessagingException, IOException {
|
||||||
DecryptedBodyPart decryptedRootPart = new DecryptedBodyPart(multipartEncrypted);
|
DecryptedBodyPart decryptedRootPart = new DecryptedBodyPart();
|
||||||
|
|
||||||
MimeConfig parserConfig = new MimeConfig();
|
MimeConfig parserConfig = new MimeConfig();
|
||||||
parserConfig.setMaxHeaderLen(-1);
|
parserConfig.setMaxHeaderLen(-1);
|
||||||
@ -36,7 +38,7 @@ public class DecryptStreamParser {
|
|||||||
parserConfig.setMaxHeaderCount(-1);
|
parserConfig.setMaxHeaderCount(-1);
|
||||||
|
|
||||||
MimeStreamParser parser = new MimeStreamParser(parserConfig);
|
MimeStreamParser parser = new MimeStreamParser(parserConfig);
|
||||||
parser.setContentHandler(new PartBuilder(multipartEncrypted, decryptedRootPart));
|
parser.setContentHandler(new PartBuilder(decryptedRootPart));
|
||||||
parser.setRecurse();
|
parser.setRecurse();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -64,12 +66,10 @@ public class DecryptStreamParser {
|
|||||||
|
|
||||||
|
|
||||||
private static class PartBuilder implements ContentHandler {
|
private static class PartBuilder implements ContentHandler {
|
||||||
private final Part multipartEncrypted;
|
|
||||||
private final DecryptedBodyPart decryptedRootPart;
|
private final DecryptedBodyPart decryptedRootPart;
|
||||||
private final Stack<Object> stack = new Stack<Object>();
|
private final Stack<Object> stack = new Stack<Object>();
|
||||||
|
|
||||||
public PartBuilder(Part multipartEncrypted, DecryptedBodyPart decryptedRootPart) throws MessagingException {
|
public PartBuilder(DecryptedBodyPart decryptedRootPart) throws MessagingException {
|
||||||
this.multipartEncrypted = multipartEncrypted;
|
|
||||||
this.decryptedRootPart = decryptedRootPart;
|
this.decryptedRootPart = decryptedRootPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ public class DecryptStreamParser {
|
|||||||
} else {
|
} else {
|
||||||
Part part = (Part) stack.peek();
|
Part part = (Part) stack.peek();
|
||||||
|
|
||||||
Message innerMessage = new DecryptedMimeMessage(multipartEncrypted);
|
Message innerMessage = new MimeMessage();
|
||||||
part.setBody(innerMessage);
|
part.setBody(innerMessage);
|
||||||
|
|
||||||
stack.push(innerMessage);
|
stack.push(innerMessage);
|
||||||
@ -97,7 +97,7 @@ public class DecryptStreamParser {
|
|||||||
try {
|
try {
|
||||||
Multipart multipart = (Multipart) stack.peek();
|
Multipart multipart = (Multipart) stack.peek();
|
||||||
|
|
||||||
BodyPart bodyPart = new DecryptedBodyPart(multipartEncrypted);
|
BodyPart bodyPart = new MimeBodyPart();
|
||||||
multipart.addBodyPart(bodyPart);
|
multipart.addBodyPart(bodyPart);
|
||||||
|
|
||||||
stack.push(bodyPart);
|
stack.push(bodyPart);
|
||||||
@ -183,18 +183,27 @@ public class DecryptStreamParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class DecryptedBodyPart extends MimeBodyPart {
|
public static class DecryptedBodyPart extends MimeBodyPart {
|
||||||
private final Part multipartEncrypted;
|
private OpenPgpSignatureResult signatureResult;
|
||||||
|
private OpenPgpError error;
|
||||||
|
|
||||||
public DecryptedBodyPart(Part multipartEncrypted) throws MessagingException {
|
public DecryptedBodyPart() throws MessagingException {
|
||||||
this.multipartEncrypted = multipartEncrypted;
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class DecryptedMimeMessage extends MimeMessage {
|
public OpenPgpSignatureResult getSignatureResult() {
|
||||||
private final Part multipartEncrypted;
|
return signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
public DecryptedMimeMessage(Part multipartEncrypted) {
|
public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
|
||||||
this.multipartEncrypted = multipartEncrypted;
|
this.signatureResult = signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpError getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(OpenPgpError error) {
|
||||||
|
this.error = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import com.fsck.k9.mail.internet.MessageExtractor;
|
|||||||
import com.fsck.k9.mail.internet.MimeHeader;
|
import com.fsck.k9.mail.internet.MimeHeader;
|
||||||
import com.fsck.k9.mail.internet.MimeUtility;
|
import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
import com.fsck.k9.mail.internet.Viewable;
|
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.mailstore.MessageViewInfo.MessageViewContainer;
|
||||||
import com.fsck.k9.provider.AttachmentProvider;
|
import com.fsck.k9.provider.AttachmentProvider;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
@ -44,6 +45,7 @@ public class LocalMessageExtractor {
|
|||||||
private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length();
|
private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length();
|
||||||
private static final String FILENAME_SUFFIX = " ";
|
private static final String FILENAME_SUFFIX = " ";
|
||||||
private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
|
private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
|
||||||
|
private static final OpenPgpSignatureResult NO_SIGNATURE_RESULT = null;
|
||||||
|
|
||||||
private LocalMessageExtractor() {}
|
private LocalMessageExtractor() {}
|
||||||
/**
|
/**
|
||||||
@ -439,7 +441,7 @@ public class LocalMessageExtractor {
|
|||||||
List<AttachmentViewInfo> attachmentInfos = extractAttachmentInfos(attachments);
|
List<AttachmentViewInfo> attachmentInfos = extractAttachmentInfos(attachments);
|
||||||
|
|
||||||
// TODO fill from part
|
// TODO fill from part
|
||||||
OpenPgpSignatureResult pgpResult = null;
|
OpenPgpSignatureResult pgpResult = getSignatureResultForPart(part);
|
||||||
OpenPgpError pgpError = null;
|
OpenPgpError pgpError = null;
|
||||||
boolean wasEncrypted = false;
|
boolean wasEncrypted = false;
|
||||||
PendingIntent pendingIntent = null;
|
PendingIntent pendingIntent = null;
|
||||||
@ -490,6 +492,15 @@ public class LocalMessageExtractor {
|
|||||||
&& ((Multipart) part.getBody()).getBodyParts().size() == 3;
|
&& ((Multipart) part.getBody()).getBodyParts().size() == 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static OpenPgpSignatureResult getSignatureResultForPart(Part part) {
|
||||||
|
if (part instanceof DecryptedBodyPart) {
|
||||||
|
DecryptedBodyPart decryptedBodyPart = (DecryptedBodyPart) part;
|
||||||
|
return decryptedBodyPart.getSignatureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_SIGNATURE_RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<AttachmentViewInfo> extractAttachmentInfos(List<Part> attachmentParts)
|
private static List<AttachmentViewInfo> extractAttachmentInfos(List<Part> attachmentParts)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
|
|
||||||
|
@ -94,6 +94,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
|||||||
private static final int LOCAL_MESSAGE_LOADER_ID = 1;
|
private static final int LOCAL_MESSAGE_LOADER_ID = 1;
|
||||||
private static final int DECODE_MESSAGE_LOADER_ID = 2;
|
private static final int DECODE_MESSAGE_LOADER_ID = 2;
|
||||||
|
|
||||||
|
private static final int INVALID_OPENPGP_RESULT_CODE = -1;
|
||||||
|
|
||||||
|
|
||||||
public static MessageViewFragment newInstance(MessageReference reference) {
|
public static MessageViewFragment newInstance(MessageReference reference) {
|
||||||
MessageViewFragment fragment = new MessageViewFragment();
|
MessageViewFragment fragment = new MessageViewFragment();
|
||||||
@ -381,7 +383,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
|||||||
protected DecryptedBodyPart doInBackground(Void... params) {
|
protected DecryptedBodyPart doInBackground(Void... params) {
|
||||||
DecryptedBodyPart decryptedPart = null;
|
DecryptedBodyPart decryptedPart = null;
|
||||||
try {
|
try {
|
||||||
decryptedPart = DecryptStreamParser.parse(currentlyDecryptingPart, decryptedInputStream);
|
decryptedPart = DecryptStreamParser.parse(decryptedInputStream);
|
||||||
|
|
||||||
latch.await();
|
latch.await();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -402,57 +404,66 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onDecryptionConverge (DecryptedBodyPart decryptedPart) {
|
private void onDecryptionConverge (DecryptedBodyPart decryptedPart) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (currentDecryptingResult == null) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resultCode = currentDecryptingResult.getIntExtra(OpenPgpApi.RESULT_CODE, -1);
|
int resultCode = currentDecryptingResult.getIntExtra(OpenPgpApi.RESULT_CODE, INVALID_OPENPGP_RESULT_CODE);
|
||||||
Log.d(K9.LOG_TAG, "result: " + resultCode);
|
if (K9.DEBUG) {
|
||||||
|
Log.d(K9.LOG_TAG, "OpenPGP API decryptVerify result code: " + resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
switch (resultCode) {
|
switch (resultCode) {
|
||||||
case -1:
|
case INVALID_OPENPGP_RESULT_CODE: {
|
||||||
Log.e(K9.LOG_TAG, "internal error: no result code!");
|
Log.e(K9.LOG_TAG, "Internal error: no result code!");
|
||||||
return;
|
break;
|
||||||
|
}
|
||||||
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
|
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
|
||||||
PendingIntent pendingIntent = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
|
PendingIntent pendingIntent = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
|
||||||
if (pendingIntent == null) {
|
if (pendingIntent == null) {
|
||||||
throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!");
|
throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(),
|
getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(),
|
||||||
MessageList.REQUEST_CODE_CRYPTO, null, 0, 0, 0);
|
MessageList.REQUEST_CODE_CRYPTO, null, 0, 0, 0);
|
||||||
} catch (SendIntentException e) {
|
} 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: {
|
case OpenPgpApi.RESULT_CODE_ERROR: {
|
||||||
Log.e(K9.LOG_TAG, "error msg: " + currentDecryptingResult.getStringExtra(OpenPgpApi.RESULT_ERROR));
|
OpenPgpError error = currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
|
||||||
onDecryptionFailed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (K9.DEBUG) {
|
||||||
|
Log.w(K9.LOG_TAG, "OpenPGP API error: " + error.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
onDecryptionFailed(error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OpenPgpApi.RESULT_CODE_SUCCESS: {
|
case OpenPgpApi.RESULT_CODE_SUCCESS: {
|
||||||
|
OpenPgpSignatureResult signatureResult =
|
||||||
|
currentDecryptingResult.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE);
|
||||||
|
decryptedPart.setSignatureResult(signatureResult);
|
||||||
|
|
||||||
onDecryptionSuccess(decryptedPart);
|
onDecryptionSuccess(decryptedPart);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
currentDecryptingResult = null;
|
currentDecryptingResult = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleCryptoResult(int resultCode, Intent data) {
|
public void handleCryptoResult(int resultCode, Intent data) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
decryptNextPartOrStartExtractingTextAndAttachments();
|
decryptNextPartOrStartExtractingTextAndAttachments();
|
||||||
} else {
|
} else {
|
||||||
onDecryptionFailed();
|
//FIXME: don't pass null
|
||||||
|
onDecryptionFailed(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,8 +477,14 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
|||||||
multipart.addBodyPart(decryptedPart);
|
multipart.addBodyPart(decryptedPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDecryptionFailed() {
|
private void onDecryptionFailed(OpenPgpError error) {
|
||||||
// TODO: display error to user?
|
try {
|
||||||
|
DecryptedBodyPart errorPart = new DecryptedBodyPart();
|
||||||
|
errorPart.setError(error);
|
||||||
|
addDecryptedPartToMessage(errorPart);
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
Log.e(K9.LOG_TAG, "This shouldn't happen", e);
|
||||||
|
}
|
||||||
onDecryptionFinished();
|
onDecryptionFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user