Search in sources :

Example 71 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class FilterUtil method reject.

public static void reject(OperationContext octxt, Mailbox mailbox, ParsedMessage parsedMessage, String reason, LmtpEnvelope envelope) throws MessagingException, ServiceException {
    MimeMessage mimeMessage = parsedMessage.getMimeMessage();
    if (isMailLoop(mailbox, mimeMessage, new String[] { HEADER_FORWARDED })) {
        // Detected a mail loop.  Do not send MDN, but just discard the message
        String error = String.format("Detected a mail loop for message %s. No MDN sent.", Mime.getMessageID(mimeMessage));
        ZimbraLog.filter.info(error);
        throw ServiceException.FAILURE(error, null);
    }
    String reportTo = null;
    if (envelope != null && envelope.hasSender()) {
        reportTo = envelope.getSender().getEmailAddress();
    }
    if (reportTo == null || reportTo.isEmpty()) {
        String[] returnPath = mimeMessage.getHeader(HEADER_RETURN_PATH);
        if (returnPath == null || returnPath.length == 0) {
            // >> NOT be generated if the MAIL FROM (or Return-Path) is empty.
            throw new MessagingException("Neither 'envelope from' nor 'Return-Path' specified. Can't locate the address to reject to (No MDN sent)");
        } else {
            // At least one 'return-path' should exist.
            reportTo = returnPath[0];
        }
    }
    Account owner = mailbox.getAccount();
    Locale locale = owner.getLocale();
    String charset = owner.getPrefMailDefaultCharset();
    if (charset == null) {
        charset = MimeConstants.P_CHARSET_UTF8;
    }
    SMTPMessage report = new SMTPMessage(JMSession.getSmtpSession());
    // add the forwarded header account names to detect the mail loop between accounts
    for (String headerFwdAccountName : Mime.getHeaders(mimeMessage, HEADER_FORWARDED)) {
        report.addHeader(HEADER_FORWARDED, headerFwdAccountName);
    }
    report.addHeader(HEADER_FORWARDED, owner.getName());
    // MDN header
    report.setEnvelopeFrom("<>");
    report.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(reportTo));
    String subject = L10nUtil.getMessage(MsgKey.seiveRejectMDNSubject, locale);
    report.setSubject(subject);
    report.setSentDate(new Date());
    InternetAddress address = new JavaMailInternetAddress(owner.getName());
    report.setFrom(address);
    MimeMultipart multi = new ZMimeMultipart("report");
    // part 1: human-readable notification
    String text = L10nUtil.getMessage(MsgKey.seiveRejectMDNErrorMsg, locale) + "\n" + reason;
    MimeBodyPart mpText = new ZMimeBodyPart();
    mpText.setText(text, CharsetUtil.checkCharset(text, charset));
    multi.addBodyPart(mpText);
    // part 2: disposition notification
    StringBuilder mdn = new StringBuilder();
    mdn.append("Final-Recipient: rfc822;").append(owner.getName()).append("\r\n");
    mdn.append("Disposition: automatic-action/MDN-sent-automatically");
    mdn.append("; deleted\r\n");
    MimeBodyPart mpMDN = new ZMimeBodyPart();
    mpMDN.setText(mdn.toString(), MimeConstants.P_CHARSET_UTF8);
    mpMDN.setHeader("Content-Type", "message/disposition-notification; charset=utf-8");
    multi.addBodyPart(mpMDN);
    // Assemble the MDN
    report.setContent(multi);
    report.setHeader("Content-Type", multi.getContentType() + "; report-type=disposition-notification");
    report.saveChanges();
    MailSender mailSender = mailbox.getMailSender().setSaveToSent(false);
    mailSender.setRecipients(reportTo);
    mailSender.setEnvelopeFrom("<>");
    mailSender.sendMimeMessage(octxt, mailbox, report);
}
Also used : Locale(java.util.Locale) Account(com.zimbra.cs.account.Account) SMTPMessage(com.sun.mail.smtp.SMTPMessage) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) MessagingException(javax.mail.MessagingException) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MailSender(com.zimbra.cs.mailbox.MailSender) Date(java.util.Date) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 72 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class CalendarItem method createBlob.

/**
     * The Blob for the appointment/task is currently single Mime multipart/digest which has
     * each invite's MimeMessage stored as a part.
     *
     * @param invPm
     * @param firstInvite
     * @throws ServiceException
     */
private MailboxBlob createBlob(ParsedMessage invPm, Invite firstInvite) throws ServiceException {
    // Create blob only if there's an attachment or DESCRIPTION is too big to be stored in metadata.
    if (!firstInvite.hasAttachment() && (invPm == null || firstInvite.descInMeta())) {
        // If we're not going to create a blob after all, we must at least save the metadata to db.
        // It's weird that the db update is implicitly required of this method, but that's the way
        // it is, unfortunately.  If we're creating a blob, the implicit db update is done by
        // storeUpdatedBlob() call.  (see below)
        saveMetadata();
        return null;
    }
    try {
        // create the toplevel multipart/digest...
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
        MimeMultipart mmp = new ZMimeMultipart("digest");
        mm.setContent(mmp);
        // add the invite
        MimeBodyPart mbp = new ZMimeBodyPart();
        mbp.setDataHandler(new DataHandler(new PMDataSource(invPm)));
        mbp.addHeader("invId", Integer.toString(firstInvite.getMailItemId()));
        mmp.addBodyPart(mbp);
        mm.saveChanges();
        return storeUpdatedBlob(mm);
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("MessagingException " + e, e);
    } catch (IOException e) {
        throw ServiceException.FAILURE("IOException " + e, e);
    }
}
Also used : MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 73 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class ParsedContact method generateMimeMessage.

private static MimeMessage generateMimeMessage(List<Attachment> attachments) throws MessagingException {
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
    MimeMultipart multi = new ZMimeMultipart("mixed");
    int part = 1;
    for (Attachment attach : attachments) {
        ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT);
        cdisp.setParameter("filename", attach.getFilename()).setParameter("field", attach.getName());
        MimeBodyPart bp = new ZMimeBodyPart();
        // it gets called before setting Content-Type and CTE headers.
        try {
            bp.setDataHandler(new DataHandler(new ByteArrayDataSource(attach.getContent(), attach.getContentType())));
        } catch (IOException e) {
            throw new MessagingException("could not generate mime part content", e);
        }
        bp.addHeader("Content-Disposition", cdisp.toString());
        bp.addHeader("Content-Type", attach.getContentType());
        bp.addHeader("Content-Transfer-Encoding", MimeConstants.ET_8BIT);
        multi.addBodyPart(bp);
        attach.setPartName(Integer.toString(part++));
    }
    mm.setContent(multi);
    mm.saveChanges();
    return mm;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attachment(com.zimbra.cs.mailbox.Contact.Attachment) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ContentDisposition(com.zimbra.common.mime.ContentDisposition) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Example 74 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class MimeVisitor method accept.

private final synchronized boolean accept(MimePart mp, int depth) throws MessagingException {
    // do not recurse beyond a fixed depth
    if (depth >= MAX_VISITOR_DEPTH)
        return false;
    boolean modified = false;
    if (mp instanceof MimeMessage)
        modified |= visitMessage((MimeMessage) mp, VisitPhase.VISIT_BEGIN);
    String ctype = Mime.getContentType(mp);
    boolean isMultipart = ctype.startsWith(MimeConstants.CT_MULTIPART_PREFIX);
    boolean isMessage = !isMultipart && ctype.equals(MimeConstants.CT_MESSAGE_RFC822);
    if (isMultipart) {
        Object content = null;
        try {
            content = Mime.getMultipartContent(mp, ctype);
        } catch (Exception e) {
            ZimbraLog.extensions.warn("could not fetch multipart content; skipping", e);
        }
        if (content instanceof MimeMultipart) {
            MimeMultipart multi = (MimeMultipart) content;
            boolean multiModified = false;
            if (visitMultipart(multi, VisitPhase.VISIT_BEGIN))
                modified = multiModified = true;
            try {
                for (int i = 0; i < multi.getCount(); i++) {
                    BodyPart bp = multi.getBodyPart(i);
                    if (bp instanceof MimeBodyPart) {
                        if (accept((MimeBodyPart) bp, depth + 1))
                            modified = multiModified = true;
                    } else {
                        ZimbraLog.extensions.info("unexpected BodyPart subclass: " + bp.getClass().getName());
                    }
                }
            } catch (MessagingException e) {
                ZimbraLog.extensions.warn("could not fetch body subpart; skipping remainder", e);
            }
            if (visitMultipart(multi, VisitPhase.VISIT_END))
                modified = multiModified = true;
            if (multiModified)
                mp.setContent(multi);
        }
    } else if (isMessage) {
        MimeMessage content = null;
        try {
            content = Mime.getMessageContent(mp);
        } catch (Exception e) {
            ZimbraLog.extensions.warn("could not fetch attached message content; skipping", e);
        }
        if (content != null)
            modified |= accept(content, depth + 1);
    } else if (mp instanceof MimeBodyPart) {
        modified |= visitBodyPart((MimeBodyPart) mp);
    } else if (!(mp instanceof MimeMessage)) {
        ZimbraLog.extensions.info("unexpected MimePart subclass: " + mp.getClass().getName() + " (ctype='" + ctype + "')");
    }
    if (mp instanceof MimeMessage) {
        MimeMessage mm = (MimeMessage) mp;
        modified |= visitMessage(mm, VisitPhase.VISIT_END);
        // commit changes to the message
        if (modified)
            mm.saveChanges();
    }
    return modified;
}
Also used : MimeBodyPart(javax.mail.internet.MimeBodyPart) BodyPart(javax.mail.BodyPart) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) MessagingException(javax.mail.MessagingException) MimeBodyPart(javax.mail.internet.MimeBodyPart) MessagingException(javax.mail.MessagingException)

Example 75 with MimeMultipart

use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.

the class Mime method listParts.

private static List<MPartInfo> listParts(MimePart root, String defaultCharset) throws MessagingException, IOException {
    List<MPartInfo> parts = new ArrayList<MPartInfo>();
    LinkedList<MPartInfo> queue = new LinkedList<MPartInfo>();
    queue.add(generateMPartInfo(root, null, "", 0));
    MimeMultipart emptyMultipart = null;
    while (!queue.isEmpty()) {
        MPartInfo mpart = queue.removeFirst();
        MimePart mp = mpart.getMimePart();
        parts.add(mpart);
        String cts = mpart.mContentType;
        boolean isMultipart = cts.startsWith(MimeConstants.CT_MULTIPART_PREFIX);
        boolean isMessage = !isMultipart && cts.equals(MimeConstants.CT_MESSAGE_RFC822);
        if (isMultipart) {
            // IMAP part numbering is screwy: top-level multipart doesn't get a number
            String prefix = mpart.mPartName.length() > 0 ? (mpart.mPartName + '.') : "";
            if (mp instanceof MimeMessage) {
                mpart.mPartName = prefix + "TEXT";
            }
            MimeMultipart multi = getMultipartContent(mp, cts);
            if (multi != null) {
                if (multi.getCount() == 0 && LC.mime_promote_empty_multipart.booleanValue()) {
                    if (emptyMultipart == null) {
                        emptyMultipart = multi;
                    }
                    if (MimeConstants.CT_MULTIPART_APPLEDOUBLE.equalsIgnoreCase(getContentType(mp))) {
                        ZimbraLog.misc.debug("appledouble with no children; assuming it is malformed and really applefile");
                        mpart.mContentType = mpart.mContentType.replace(MimeConstants.CT_MULTIPART_APPLEDOUBLE, MimeConstants.CT_APPLEFILE);
                    }
                }
                mpart.mChildren = new ArrayList<MPartInfo>(multi.getCount());
                for (int i = 1; i <= multi.getCount(); i++) {
                    mpart.mChildren.add(generateMPartInfo((MimePart) multi.getBodyPart(i - 1), mpart, prefix + i, i));
                }
                queue.addAll(0, mpart.mChildren);
            }
        } else if (isMessage) {
            MimeMessage mm = getMessageContent(mp);
            if (mm != null) {
                MPartInfo child = generateMPartInfo(mm, mpart, mpart.mPartName, 0);
                queue.addFirst(child);
                mpart.mChildren = Arrays.asList(child);
            }
        } else {
        // nothing to do at this stage
        }
    }
    if (emptyMultipart != null && parts.size() == 1) {
        String text = emptyMultipart.getPreamble();
        if (!StringUtil.isNullOrEmpty(text)) {
            ZimbraLog.misc.debug("single multipart with no children. promoting the preamble into a single text part");
            parts.remove(0);
            MPartInfo mpart = new MPartInfo();
            ZMimeBodyPart mp = new ZMimeBodyPart();
            mp.setText(text, defaultCharset);
            mpart.mPart = mp;
            mpart.mContentType = mp.getContentType();
            mpart.mDisposition = "";
            mpart.mPartName = "1";
            parts.add(mpart);
        }
    }
    return parts;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) MimePart(javax.mail.internet.MimePart) ZMimePart(com.zimbra.common.zmime.ZMimePart)

Aggregations

MimeMultipart (javax.mail.internet.MimeMultipart)213 MimeBodyPart (javax.mail.internet.MimeBodyPart)134 MimeMessage (javax.mail.internet.MimeMessage)85 MessagingException (javax.mail.MessagingException)69 ByteArrayOutputStream (java.io.ByteArrayOutputStream)55 BodyPart (javax.mail.BodyPart)55 IOException (java.io.IOException)47 ByteString (com.linkedin.data.ByteString)37 DataHandler (javax.activation.DataHandler)33 InternetAddress (javax.mail.internet.InternetAddress)33 Test (org.testng.annotations.Test)31 ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)27 HashMap (java.util.HashMap)27 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)26 Multipart (javax.mail.Multipart)26 Properties (java.util.Properties)25 Session (javax.mail.Session)24 ByteArrayDataSource (javax.mail.util.ByteArrayDataSource)24 InputStream (java.io.InputStream)23 Date (java.util.Date)21