Search in sources :

Example 6 with ZSharedFileInputStream

use of com.zimbra.common.zmime.ZSharedFileInputStream in project zm-mailbox by Zimbra.

the class CalendarRequest method sendCalendarMessageInternal.

/**
     * Send an iCalendar email message and optionally create/update/cancel
     * corresponding appointment/invite in sender's calendar.
     * @param zsc
     * @param apptFolderId
     * @param acct
     * @param mbox
     * @param csd
     * @param response
     * @param updateOwnAppointment if true, corresponding change is made to
     *                             sender's calendar
     * @return
     * @throws ServiceException
     */
private static Element sendCalendarMessageInternal(ZimbraSoapContext zsc, OperationContext octxt, int apptFolderId, Account acct, Mailbox mbox, CalSendData csd, Element response, boolean updateOwnAppointment, boolean forceSend, MailSendQueue sendQueue) throws ServiceException {
    boolean onBehalfOf = isOnBehalfOfRequest(zsc);
    boolean notifyOwner = onBehalfOf && acct.getBooleanAttr(Provisioning.A_zimbraPrefCalendarNotifyDelegatedChanges, false);
    if (notifyOwner) {
        try {
            InternetAddress addr = AccountUtil.getFriendlyEmailAddress(acct);
            csd.mMm.addRecipient(javax.mail.Message.RecipientType.TO, addr);
        } catch (MessagingException e) {
            throw ServiceException.FAILURE("count not add calendar owner to recipient list", e);
        }
    }
    // in a non-delegated request.
    if (!onBehalfOf) {
        String[] aliases = acct.getMailAlias();
        String[] addrs;
        if (aliases != null && aliases.length > 0) {
            addrs = new String[aliases.length + 1];
            addrs[0] = acct.getAttr(Provisioning.A_mail);
            for (int i = 0; i < aliases.length; i++) {
                addrs[i + 1] = aliases[i];
            }
        } else {
            addrs = new String[1];
            addrs[0] = acct.getAttr(Provisioning.A_mail);
        }
        try {
            Mime.removeRecipients(csd.mMm, addrs);
        } catch (MessagingException e) {
        }
    }
    ParsedMessage pm = new ParsedMessage(csd.mMm, false);
    if (csd.mInvite.getFragment() == null || csd.mInvite.getFragment().equals("")) {
        csd.mInvite.setFragment(pm.getFragment(acct.getLocale()));
    }
    boolean willNotify = false;
    if (!csd.mDontNotifyAttendees) {
        try {
            Address[] rcpts = csd.mMm.getAllRecipients();
            willNotify = rcpts != null && rcpts.length > 0;
        } catch (MessagingException e) {
            throw ServiceException.FAILURE("Checking recipients of outgoing msg ", e);
        }
    }
    // Validate the addresses first.
    if (!csd.mInvite.isCancel() && !forceSend && willNotify) {
        try {
            MailUtil.validateRcptAddresses(JMSession.getSmtpSession(mbox.getAccount()), csd.mMm.getAllRecipients());
        } catch (MessagingException mex) {
            if (mex instanceof SendFailedException) {
                SendFailedException sfex = (SendFailedException) mex;
                throw MailServiceException.SEND_ABORTED_ADDRESS_FAILURE("invalid addresses", sfex, sfex.getInvalidAddresses(), sfex.getValidUnsentAddresses());
            }
        }
    }
    AddInviteData aid = null;
    File tempMmFile = null;
    boolean queued = false;
    try {
        if (willNotify) {
            // Write out the MimeMessage to a temp file and create a new MimeMessage from the file.
            // If we don't do this, we get into trouble during modify appointment call.  If the blob
            // is bigger than the streaming threshold (e.g. appointment has a big attachment), the
            // MimeMessage object is attached to the current blob file.  But the Mailbox.addInvite()
            // call below updates the blob to a new mod_content (hence new path).  The attached blob
            // thus having been deleted, the MainSender.sendMimeMessage() call that follows will attempt
            // to read from a non-existent file and fail.  We can avoid this situation by writing the
            // to-be-emailed mime message to a temp file, thus detaching it from the appointment's
            // current blob file.  This is inefficient, but safe.
            OutputStream os = null;
            InputStream is = null;
            try {
                tempMmFile = File.createTempFile("zcal", "tmp");
                os = new FileOutputStream(tempMmFile);
                csd.mMm.writeTo(os);
                ByteUtil.closeStream(os);
                os = null;
                is = new ZSharedFileInputStream(tempMmFile);
                csd.mMm = new FixedMimeMessage(JMSession.getSmtpSession(acct), is);
            } catch (IOException e) {
                if (tempMmFile != null)
                    tempMmFile.delete();
                throw ServiceException.FAILURE("error creating calendar message content", e);
            } catch (MessagingException e) {
                if (tempMmFile != null)
                    tempMmFile.delete();
                throw ServiceException.FAILURE("error creating calendar message content", e);
            } finally {
                ByteUtil.closeStream(os);
                ByteUtil.closeStream(is);
            }
        }
        // because email send will delete uploaded attachments as a side-effect.
        if (updateOwnAppointment) {
            aid = mbox.addInvite(octxt, csd.mInvite, apptFolderId, pm);
        }
        // Next, notify any attendees.
        if (willNotify) {
            MailSendQueueEntry entry = new MailSendQueueEntry(octxt, mbox, csd, tempMmFile);
            sendQueue.add(entry);
            queued = true;
        }
    } finally {
        // Delete the temp file if it wasn't queued.
        if (tempMmFile != null && !queued) {
            tempMmFile.delete();
        }
    }
    if (updateOwnAppointment && response != null && aid != null) {
        csd.mAddInvData = aid;
        ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
        String id = ifmt.formatItemId(aid.calItemId);
        response.addAttribute(MailConstants.A_CAL_ID, id);
        if (csd.mInvite.isEvent())
            // for backward compat
            response.addAttribute(MailConstants.A_APPT_ID_DEPRECATE_ME, id);
        response.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(aid.calItemId, aid.invId));
        if (Invite.isOrganizerMethod(csd.mInvite.getMethod())) {
            response.addAttribute(MailConstants.A_MODIFIED_SEQUENCE, aid.modSeq);
            response.addAttribute(MailConstants.A_REVISION, aid.rev);
        }
    }
    return response;
}
Also used : InternetAddress(javax.mail.internet.InternetAddress) SendFailedException(javax.mail.SendFailedException) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) MessagingException(javax.mail.MessagingException) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) AddInviteData(com.zimbra.cs.mailbox.Mailbox.AddInviteData) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) IOException(java.io.IOException) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Example 7 with ZSharedFileInputStream

use of com.zimbra.common.zmime.ZSharedFileInputStream in project zm-mailbox by Zimbra.

the class SmtpInject method main.

public static void main(String[] args) {
    CliUtil.toolSetup();
    CommandLine cl = parseArgs(args);
    if (cl.hasOption("h")) {
        usage(null);
    }
    String file = null;
    if (!cl.hasOption("f")) {
        usage("no file specified");
    } else {
        file = cl.getOptionValue("f");
    }
    try {
        ByteUtil.getContent(new File(file));
    } catch (IOException ioe) {
        usage(ioe.getMessage());
    }
    String host = null;
    if (!cl.hasOption("a")) {
        usage("no smtp server specified");
    } else {
        host = cl.getOptionValue("a");
    }
    String sender = null;
    if (!cl.hasOption("s")) {
        usage("no sender specified");
    } else {
        sender = cl.getOptionValue("s");
    }
    String recipient = null;
    if (!cl.hasOption("r")) {
        usage("no recipient specified");
    } else {
        recipient = cl.getOptionValue("r");
    }
    boolean trace = false;
    if (cl.hasOption("T")) {
        trace = true;
    }
    boolean tls = false;
    if (cl.hasOption("t")) {
        tls = true;
    }
    boolean auth = false;
    String user = null;
    String password = null;
    if (cl.hasOption("A")) {
        auth = true;
        if (!cl.hasOption("u")) {
            usage("auth enabled, no user specified");
        } else {
            user = cl.getOptionValue("u");
        }
        if (!cl.hasOption("p")) {
            usage("auth enabled, no password specified");
        } else {
            password = cl.getOptionValue("p");
        }
    }
    if (cl.hasOption("v")) {
        mLog.info("SMTP server: " + host);
        mLog.info("Sender: " + sender);
        mLog.info("Recipient: " + recipient);
        mLog.info("File: " + file);
        mLog.info("TLS: " + tls);
        mLog.info("Auth: " + auth);
        if (auth) {
            mLog.info("User: " + user);
            char[] dummyPassword = new char[password.length()];
            Arrays.fill(dummyPassword, '*');
            mLog.info("Password: " + new String(dummyPassword));
        }
    }
    Properties props = System.getProperties();
    props.put("mail.smtp.host", host);
    if (auth) {
        props.put("mail.smtp.auth", "true");
    } else {
        props.put("mail.smtp.auth", "false");
    }
    if (tls) {
        props.put("mail.smtp.starttls.enable", "true");
    } else {
        props.put("mail.smtp.starttls.enable", "false");
    }
    // Disable certificate checking so we can test against
    // self-signed certificates
    props.put("mail.smtp.ssl.socketFactory", SocketFactories.dummySSLSocketFactory());
    Session session = Session.getInstance(props, null);
    session.setDebug(trace);
    try {
        // create a message
        MimeMessage msg = new ZMimeMessage(session, new ZSharedFileInputStream(file));
        InternetAddress[] address = { new JavaMailInternetAddress(recipient) };
        msg.setFrom(new JavaMailInternetAddress(sender));
        // attach the file to the message
        Transport transport = session.getTransport("smtp");
        transport.connect(null, user, password);
        transport.sendMessage(msg, address);
    } catch (MessagingException mex) {
        mex.printStackTrace();
        Exception ex = null;
        if ((ex = mex.getNextException()) != null) {
            ex.printStackTrace();
        }
        System.exit(1);
    }
}
Also used : JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) InternetAddress(javax.mail.internet.InternetAddress) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MessagingException(javax.mail.MessagingException) IOException(java.io.IOException) Properties(java.util.Properties) MessagingException(javax.mail.MessagingException) IOException(java.io.IOException) ParseException(org.apache.commons.cli.ParseException) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) CommandLine(org.apache.commons.cli.CommandLine) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Transport(javax.mail.Transport) File(java.io.File) Session(javax.mail.Session)

Example 8 with ZSharedFileInputStream

use of com.zimbra.common.zmime.ZSharedFileInputStream in project zm-mailbox by Zimbra.

the class SpamExtract method extractMessages.

private static List<String> extractMessages(HttpClient hc, GetMethod gm, String path, File outdir, boolean raw) throws HttpException, IOException {
    List<String> extractedIds = new ArrayList<String>();
    gm.setPath(path);
    if (LOG.isDebugEnabled()) {
        LOG.debug("Fetching " + path);
    }
    HttpClientUtil.executeMethod(hc, gm);
    if (gm.getStatusCode() != HttpStatus.SC_OK) {
        throw new IOException("HTTP GET failed: " + gm.getPath() + ": " + gm.getStatusCode() + ": " + gm.getStatusText());
    }
    ArchiveInputStream tgzStream = null;
    try {
        tgzStream = new TarArchiveInputStream(new GZIPInputStream(gm.getResponseBodyAsStream()), Charsets.UTF_8.name());
        ArchiveInputEntry entry = null;
        while ((entry = tgzStream.getNextEntry()) != null) {
            LOG.debug("got entry name %s", entry.getName());
            if (entry.getName().endsWith(".meta")) {
                ItemData itemData = new ItemData(readArchiveEntry(tgzStream, entry));
                UnderlyingData ud = itemData.ud;
                //.meta always followed by .eml
                entry = tgzStream.getNextEntry();
                if (raw) {
                    // Write the message as-is.
                    File file = new File(outdir, mOutputPrefix + "-" + mExtractIndex++);
                    OutputStream os = null;
                    try {
                        os = new BufferedOutputStream(new FileOutputStream(file));
                        byte[] data = readArchiveEntry(tgzStream, entry);
                        ByteUtil.copy(new ByteArrayInputStream(data), true, os, false);
                        if (verbose) {
                            LOG.info("Wrote: " + file);
                        }
                        extractedIds.add(ud.id + "");
                    } catch (java.io.IOException e) {
                        String fileName = outdir + "/" + mOutputPrefix + "-" + mExtractIndex;
                        LOG.error("Cannot write to " + fileName, e);
                    } finally {
                        if (os != null) {
                            os.close();
                        }
                    }
                } else {
                    // Write the attached message to the output directory.
                    BufferStream buffer = new BufferStream(entry.getSize(), MAX_BUFFER_SIZE);
                    buffer.setSequenced(false);
                    MimeMessage mm = null;
                    InputStream fis = null;
                    try {
                        byte[] data = readArchiveEntry(tgzStream, entry);
                        ByteUtil.copy(new ByteArrayInputStream(data), true, buffer, false);
                        if (buffer.isSpooled()) {
                            fis = new ZSharedFileInputStream(buffer.getFile());
                            mm = new ZMimeMessage(mJMSession, fis);
                        } else {
                            mm = new ZMimeMessage(mJMSession, buffer.getInputStream());
                        }
                        writeAttachedMessages(mm, outdir, entry.getName());
                        extractedIds.add(ud.id + "");
                    } catch (MessagingException me) {
                        LOG.warn("exception occurred fetching message", me);
                    } finally {
                        ByteUtil.closeStream(fis);
                    }
                }
            }
        }
    } finally {
        Closeables.closeQuietly(tgzStream);
    }
    return extractedIds;
}
Also used : ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MessagingException(javax.mail.MessagingException) ArchiveInputEntry(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputEntry) GZIPInputStream(java.util.zip.GZIPInputStream) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ArchiveInputStream(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) InputStream(java.io.InputStream) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) IOException(java.io.IOException) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) GZIPInputStream(java.util.zip.GZIPInputStream) BufferStream(com.zimbra.common.util.BufferStream) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) ArchiveInputStream(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) FileOutputStream(java.io.FileOutputStream) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream) ItemData(com.zimbra.cs.service.util.ItemData)

Example 9 with ZSharedFileInputStream

use of com.zimbra.common.zmime.ZSharedFileInputStream in project zm-mailbox by Zimbra.

the class TestMain method processMimeFile.

/**
     * @param mimeFile Name of original test file - used for diagnostic reporting
     * @param icalFile the file to write the ICALENDAR data to.
     * @param tnefFile the file to write TNEF data to.
     * @param recurInfoFile the file to write recurrence diagnostics data to.
     * @return true if successfully written data.
     */
private static boolean processMimeFile(File mimeFile, File icalFile, File tnefFile, File recurInfoFile, boolean verbose) {
    if (!mimeFile.exists()) {
        sLog.warn("Can't find MIME file %s", mimeFile.getPath());
        return false;
    }
    sLog.debug("Processing MIME file %s", mimeFile.getPath());
    // Prepare the input and output.
    InputStream fisMime = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream(10240);
    Writer baosOut = null;
    boolean doneConversion = false;
    try {
        fisMime = new ZSharedFileInputStream(mimeFile);
        baosOut = new OutputStreamWriter(baos, UTF8);
        // Do the conversion.
        MimeMessage mm = new ZMimeMessage(JMSession.getSession(), fisMime);
        TnefToICalendar converter = getConverter();
        doneConversion = doConversion(mm, baosOut, converter, tnefFile, verbose);
        if (recurInfoFile != null) {
            if (converter instanceof DefaultTnefToICalendar) {
                DefaultTnefToICalendar tnef2ical = (DefaultTnefToICalendar) converter;
                RecurrenceDefinition recurDef = tnef2ical.getRecurDef();
                if (recurDef != null) {
                    FileWriter rsFileWriter = null;
                    try {
                        rsFileWriter = new FileWriter(recurInfoFile);
                        rsFileWriter.write(recurDef.toString());
                    } finally {
                        try {
                            if (rsFileWriter != null) {
                                rsFileWriter.close();
                            }
                        } catch (IOException e) {
                            sLog.error("Problem writing to recurInfo file %s", recurInfoFile, e);
                        }
                    }
                }
            }
        }
    } catch (UnsupportedTnefCalendaringMsgException ex) {
        sLog.warn("Unable to map %s to ICALENDAR", mimeFile.getPath(), ex);
        return false;
    } catch (TNEFtoIcalendarServiceException ex) {
        sLog.warn("Problem encountered mapping %s to ICALENDAR", mimeFile.getPath(), ex);
        return false;
    } catch (MessagingException ex) {
        sLog.warn("Problem encountered mapping %s to ICALENDAR", mimeFile.getPath(), ex);
        return false;
    } catch (ServiceException ex) {
        sLog.warn("Problem encountered mapping %s to ICALENDAR", mimeFile.getPath(), ex);
        return false;
    } catch (IOException ex) {
        sLog.warn("IO Problem encountered mapping %s to ICALENDAR", mimeFile.getPath(), ex);
        return false;
    } finally {
        try {
            if (fisMime != null)
                fisMime.close();
        } catch (IOException e) {
            sLog.error("Problem closing mime stream", e);
        }
    }
    if (!doneConversion) {
        return false;
    }
    if (!writeIcalendarData(mimeFile, baos, icalFile)) {
        return false;
    }
    if (!validateIcalendarData(mimeFile, baos)) {
        return false;
    }
    return true;
}
Also used : ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MessagingException(javax.mail.MessagingException) ByteArrayInputStream(java.io.ByteArrayInputStream) SharedFileInputStream(javax.mail.util.SharedFileInputStream) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) InputStream(java.io.InputStream) FileWriter(java.io.FileWriter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) ServiceException(com.zimbra.common.service.ServiceException) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) OutputStreamWriter(java.io.OutputStreamWriter) UnsupportedTnefCalendaringMsgException(com.zimbra.cs.util.tnef.TNEFtoIcalendarServiceException.UnsupportedTnefCalendaringMsgException) OutputStreamWriter(java.io.OutputStreamWriter) FileWriter(java.io.FileWriter) Writer(java.io.Writer) RecurrenceDefinition(com.zimbra.cs.util.tnef.mapi.RecurrenceDefinition)

Aggregations

ZSharedFileInputStream (com.zimbra.common.zmime.ZSharedFileInputStream)9 MimeMessage (javax.mail.internet.MimeMessage)8 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)5 IOException (java.io.IOException)5 MessagingException (javax.mail.MessagingException)5 JavaMailMimeMessage (com.zimbra.common.mime.shim.JavaMailMimeMessage)4 InputStream (java.io.InputStream)4 Test (org.junit.Test)4 ServiceException (com.zimbra.common.service.ServiceException)3 Element (com.zimbra.common.soap.Element)3 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)3 DeliveryOptions (com.zimbra.cs.mailbox.DeliveryOptions)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 Message (com.zimbra.cs.mailbox.Message)3 GetMsg (com.zimbra.cs.service.mail.GetMsg)3 File (java.io.File)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 FileOutputStream (java.io.FileOutputStream)2 OutputStream (java.io.OutputStream)2 InternetAddress (javax.mail.internet.InternetAddress)2