public static List<Part> findPgpInlineParts(Part startPart) { List<Part> inlineParts = new ArrayList<>(); Stack<Part> partsToCheck = new Stack<>(); partsToCheck.push(startPart); while (!partsToCheck.isEmpty()) { Part part = partsToCheck.pop(); Body body = part.getBody(); if (isPartPgpInlineEncryptedOrSigned(part)) { inlineParts.add(part); continue; } if (body instanceof Multipart) { Multipart multipart = (Multipart) body; for (int i = multipart.getCount() - 1; i >= 0; i--) { BodyPart bodyPart = multipart.getBodyPart(i); partsToCheck.push(bodyPart); } } } return inlineParts; }
public static List<Part> findMultipartEncryptedParts(Part startPart) { List<Part> encryptedParts = new ArrayList<>(); Stack<Part> partsToCheck = new Stack<>(); partsToCheck.push(startPart); while (!partsToCheck.isEmpty()) { Part part = partsToCheck.pop(); Body body = part.getBody(); if (isPartMultipartEncrypted(part)) { encryptedParts.add(part); continue; } if (body instanceof Multipart) { Multipart multipart = (Multipart) body; for (int i = multipart.getCount() - 1; i >= 0; i--) { BodyPart bodyPart = multipart.getBodyPart(i); partsToCheck.push(bodyPart); } } } return encryptedParts; }
private void addChildrenToStack(Stack<PartContainer> stack, Part part, long parentMessageId) { Body body = part.getBody(); if (body instanceof Multipart) { Multipart multipart = (Multipart) body; for (int i = multipart.getCount() - 1; i >= 0; i--) { BodyPart childPart = multipart.getBodyPart(i); stack.push(new PartContainer(parentMessageId, childPart)); } } else if (body instanceof Message) { Message innerMessage = (Message) body; stack.push(new PartContainer(parentMessageId, innerMessage)); } }
@Override public void endMultipart() { expect(Multipart.class); Multipart multipart = (Multipart) stack.removeFirst(); boolean hasNoBodyParts = multipart.getCount() == 0; boolean hasNoEpilogue = multipart.getEpilogue() == null; if (hasNoBodyParts && hasNoEpilogue) { /* * The parser is calling startMultipart(), preamble(), and endMultipart() when all we have is * headers of a "multipart/*" part. But there's really no point in keeping a Multipart body if all * of the content is missing. */ expect(Part.class); Part part = (Part) stack.peek(); part.setBody(null); } }
@Nullable private static Part findPrimaryPartInMixed(Part part, List<Part> outputExtraParts) { Body body = part.getBody(); boolean isMultipartMixed = part.isMimeType("multipart/mixed") && body instanceof Multipart; if (!isMultipartMixed) { return null; } Multipart multipart = (Multipart) body; if (multipart.getCount() == 0) { return null; } BodyPart firstBodyPart = multipart.getBodyPart(0); Part foundPart; if (isPartEncryptedOrSigned(firstBodyPart)) { foundPart = firstBodyPart; } else { foundPart = findPrimaryPartInAlternative(firstBodyPart); } if (foundPart != null && outputExtraParts != null) { for (int i = 1; i < multipart.getCount(); i++) { outputExtraParts.add(multipart.getBodyPart(i)); } } return foundPart; }
public static List<Part> findMultipartSignedParts(Part startPart, MessageCryptoAnnotations messageCryptoAnnotations) { List<Part> signedParts = new ArrayList<>(); Stack<Part> partsToCheck = new Stack<>(); partsToCheck.push(startPart); while (!partsToCheck.isEmpty()) { Part part = partsToCheck.pop(); if (messageCryptoAnnotations.has(part)) { CryptoResultAnnotation resultAnnotation = messageCryptoAnnotations.get(part); MimeBodyPart replacementData = resultAnnotation.getReplacementData(); if (replacementData != null) { part = replacementData; } } Body body = part.getBody(); if (isPartMultipartSigned(part)) { signedParts.add(part); continue; } if (body instanceof Multipart) { Multipart multipart = (Multipart) body; for (int i = multipart.getCount() - 1; i >= 0; i--) { BodyPart bodyPart = multipart.getBodyPart(i); partsToCheck.push(bodyPart); } } } return signedParts; }
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; }
if (multipart.getCount() > 0) { BodyPart bodyPart = multipart.getBodyPart(0); findViewablesAndAttachments(bodyPart, outputViewableParts, outputNonViewableParts);
@Test public void migratePgpMimeSignedMessage() throws Exception { SQLiteDatabase db = createV50Database(); insertPgpMimeSignedMessage(db); db.close(); LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account); LocalMessage msg = localStore.getFolder("dev").getMessage("5"); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); localStore.getFolder("dev").fetch(Collections.singletonList(msg), fp, null); Assert.assertEquals(4, msg.getDatabaseId()); Assert.assertEquals(8, msg.getHeaderNames().size()); Assert.assertEquals("multipart/mixed", msg.getMimeType()); Assert.assertEquals(2, msg.getAttachmentCount()); Multipart body = (Multipart) msg.getBody(); Assert.assertEquals(3, body.getCount()); Assert.assertEquals("multipart/alternative", body.getBodyPart(0).getMimeType()); Assert.assertEquals("image/png", body.getBodyPart(1).getMimeType()); Assert.assertEquals("application/pgp-signature", body.getBodyPart(2).getMimeType()); }
@Test public void migratePgpMimeEncryptedMessage() throws Exception { SQLiteDatabase db = createV50Database(); insertPgpMimeEncryptedMessage(db); db.close(); LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account); LocalMessage msg = localStore.getFolder("dev").getMessage("6"); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); localStore.getFolder("dev").fetch(Collections.singletonList(msg), fp, null); Assert.assertEquals(5, msg.getDatabaseId()); Assert.assertEquals(13, msg.getHeaderNames().size()); Assert.assertEquals("multipart/encrypted", msg.getMimeType()); Assert.assertEquals(2, msg.getAttachmentCount()); Multipart body = (Multipart) msg.getBody(); Assert.assertEquals(1, msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE).length); Assert.assertEquals("application/pgp-encrypted", MimeUtility.getHeaderParameter(msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0], "protocol")); Assert.assertEquals("UoPmpPX/dBe4BELn", MimeUtility.getHeaderParameter(msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0], "boundary")); Assert.assertEquals("UoPmpPX/dBe4BELn", body.getBoundary()); Assert.assertEquals(2, body.getCount()); Assert.assertEquals("application/pgp-encrypted", body.getBodyPart(0).getMimeType()); Assert.assertEquals("application/octet-stream", body.getBodyPart(1).getMimeType()); }
Assert.assertEquals(3, body.getCount());