/** * Verify the email is signed by the given certificate. * * @param signedData * @param mailMsg * @return * @throws CMSException * @throws OperatorCreationException * @throws CertificateException */ @SuppressWarnings({"rawtypes"}) protected boolean isValid(CMSSignedData signedData, MailMessage mailMsg) throws OperatorCreationException, CMSException, CertificateException { boolean verify = false; SignerInformationStore signerStore = signedData.getSignerInfos(); Iterator<SignerInformation> it = signerStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = it.next(); org.bouncycastle.util.Store store = signedData.getCertificates(); @SuppressWarnings("unchecked") Collection certCollection = store.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); X509Certificate certificate = new JcaX509CertificateConverter().setProvider(PROVIDER_NAME).getCertificate(certHolder); verify = signer.verify( new JcaSimpleSignerInfoVerifierBuilder() .setProvider(PROVIDER_NAME) .build(certificate)); mailMsg.setHasSignature(true); mailMsg.setSignaturePassed(verify); mailMsg.setNameOfPrincipal(certificate.getSubjectDN().getName()); } return verify; }
/** * Get message header for MailMessage. * * @param msg * @param mailMsg * @throws MessagingException */ protected void processHeader(Message msg, MailMessage mailMsg) throws MessagingException { String xAutoResponseSuppressHeaderName = "X-Auto-Response-Suppress"; String xAutoReplyHeaderName = "X-Autoreply"; String xAutoRespondHeaderName = "X-Autorespond"; String xAutoSubmittedHeaderName = "auto-submitted"; String xAutoResponseSuppressVal = Arrays.toString(msg.getHeader(xAutoResponseSuppressHeaderName)); String xAutoReplyVal = Arrays.toString(msg.getHeader(xAutoReplyHeaderName)); String xAutoRespondVal = Arrays.toString(msg.getHeader(xAutoRespondHeaderName)); String xAutoSubmittedVal = Arrays.toString(msg.getHeader(xAutoSubmittedHeaderName)); String contentType = msg.getContentType(); // If any of those are present in an email, then that email is an auto-reply. String[] autoReplyArray = { xAutoResponseSuppressVal, xAutoReplyVal, xAutoRespondVal, xAutoSubmittedVal }; mailMsg.setAutoReply(autoReplyArray); mailMsg.setContentType(contentType); }
/** * Set some email's basic information to MailMessage . * * @param mime * @param mailMsg * @throws MessagingException * @throws ParseException */ private void setMailBasicInfoForMailMsg(MimeMessage mime, MailMessage mailMsg) throws MessagingException, ParseException { SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); String msgId = mime.getMessageID(); Address[] from = mime.getFrom(); Address[] to = mime.getRecipients(RecipientType.TO); Address[] cc = mime.getRecipients(RecipientType.CC); Address[] bcc = mime.getRecipients(RecipientType.BCC); String subject = mime.getSubject(); Date sendDate = mime.getSentDate(); String receivedUTCDate = sdf.format(this.resolveReceivedDate(mime)); mailMsg.setMsgId(msgId); mailMsg.setFrom(this.convertToMailAddress(from)); mailMsg.setTo(this.convertToMailAddress(to)); mailMsg.setCc(this.convertToMailAddress(cc)); mailMsg.setBcc(this.convertToMailAddress(bcc)); mailMsg.setSubject(subject); if (sendDate != null) { mailMsg.setSendDate(sdf.format(sendDate)); } mailMsg.setReceivedDate(receivedUTCDate); }
/** * Process the MimeMessage for signed mail with/without attachment. * * @param mime * @param mailMsg * @return * @throws MessagingException * @throws IOException * @throws ParseException */ private String processSignedMail(MimeMessage mime, MailMessage mailMsg) throws IOException, MessagingException, ParseException { this.setMailBasicInfoForMailMsg(mime, mailMsg); String txtBody = null; String htmlBody = null; // Get the content of the messsage, it's an Multipart object like a package including all the // email text and attachment. Multipart multi1 = (Multipart) mime.getContent(); // process each part in order. for (int i = 0, n = multi1.getCount(); i < n; i++) { // unpack, get each part of Multipart, part 0 may email text and part 1 may attachment. Or it // is another embedded Multipart. Part part2 = multi1.getBodyPart(i); // determine Part is email text or Multipart. if (part2.getContent() instanceof Multipart) { Multipart multi2 = (Multipart) part2.getContent(); // First, verify the quantity and size of attachments. boolean isValidMailMsg = this.isValidMailMsg(multi2); if (isValidMailMsg) { // process the content in multi2. for (int j = 0; j < multi2.getCount(); j++) { Part part3 = multi2.getBodyPart(j); if (part3.isMimeType("text/plain") && !Part.ATTACHMENT.equalsIgnoreCase(part3.getDisposition())) { txtBody = part3.getContent().toString(); } else if (part3.isMimeType("text/html") && !Part.ATTACHMENT.equalsIgnoreCase(part3.getDisposition())) { htmlBody = part3.getContent().toString(); } else if (part3.isMimeType("multipart/alternative")) { // generally if the content type multipart/alternative, it is email text. if (part3.getContent() instanceof Multipart) { Multipart multi3 = (Multipart) part3.getContent(); for (int k = 0; k < multi3.getCount(); k++) { Part part4 = multi3.getBodyPart(k); if (part4.isMimeType("text/plain") && !Part.ATTACHMENT.equalsIgnoreCase(part4.getDisposition())) { txtBody = part4.getContent().toString(); } else if (part4.isMimeType("text/html") && !Part.ATTACHMENT.equalsIgnoreCase(part4.getDisposition())) { htmlBody = part4.getContent().toString(); } } } } else if (part3.isMimeType("multipart/related")) { if (part3.getContent() instanceof Multipart) { Multipart multi3 = (Multipart) part3.getContent(); for (int m = 0; m < multi3.getCount(); m++) { Part part4 = multi3.getBodyPart(m); if (part4.isMimeType("multipart/alternative")) { if (part4.getContent() instanceof Multipart) { Multipart multi4 = (Multipart) part4.getContent(); for (int p = 0; p < multi4.getCount(); p++) { Part part5 = multi4.getBodyPart(p); if (part5.isMimeType("text/plain") && !Part.ATTACHMENT.equalsIgnoreCase(part5.getDisposition())) { txtBody = part5.getContent().toString(); } else if (part5.isMimeType("text/html") && !Part.ATTACHMENT.equalsIgnoreCase(part5.getDisposition())) { htmlBody = part5.getContent().toString(); } } } } else { // This is an embedded picture, set it as an attachment. mailMsg.setHasAttachments(true); } } } } else { String disposition = part3.getDisposition(); if (disposition != null && Part.ATTACHMENT.equalsIgnoreCase(disposition)) { mailMsg.setHasAttachments(true); } } } } } else { // This is a certificate file, set it as an attachment String disposition = part2.getDisposition(); if (disposition != null && Part.ATTACHMENT.equalsIgnoreCase(disposition)) { mailMsg.setHasAttachments(true); } } } if (!isNull(txtBody)) { mailMsg.setBody(txtBody); } else { mailMsg.setBody(htmlBody); } return JSONObject.fromObject(mailMsg).toString(); }