Search in sources :

Example 1 with ErejectException

use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.

the class RuleManager method applyRulesToIncomingMessage.

/**
 * Adds a message to a mailbox.  If filter rules exist, processes
 * the filter rules.  Otherwise, files to <tt>Inbox</tt> or <tt>Spam</tt>.
 *
 * @param allowFilterToMountpoint if <tt>false</tt>, rules
 * @return the list of message id's that were added, or an empty list.
 */
public static List<ItemId> applyRulesToIncomingMessage(OperationContext octxt, Mailbox mailbox, ParsedMessage pm, int size, String recipient, LmtpEnvelope env, DeliveryContext sharedDeliveryCtxt, int incomingFolderId, boolean noICal, boolean allowFilterToMountpoint) throws ServiceException {
    List<ItemId> addedMessageIds = null;
    IncomingMessageHandler handler = new IncomingMessageHandler(octxt, sharedDeliveryCtxt, mailbox, recipient, pm, size, incomingFolderId, noICal);
    ZimbraMailAdapter mailAdapter = new ZimbraMailAdapter(mailbox, handler);
    mailAdapter.setEnvelope(env);
    mailAdapter.setAllowFilterToMountpoint(allowFilterToMountpoint);
    String[] filters = { ADMIN_FILTER_RULES_BEFORE_CACHE_KEY, FILTER_RULES_CACHE_KEY, ADMIN_FILTER_RULES_AFTER_CACHE_KEY };
    try {
        boolean applyRules = true;
        Account account = mailbox.getAccount();
        for (String filter : filters) {
            // Determine whether to apply rules
            Node node = getRulesNode(account, filter);
            if (null == node) {
                applyRules = false;
            }
            if (SpamHandler.isSpam(handler.getMimeMessage()) && !account.getBooleanAttr(Provisioning.A_zimbraSpamApplyUserFilters, false)) {
                // Don't apply user filters to spam by default
                applyRules = false;
                break;
            }
            if (applyRules) {
                if (filter.equals(FILTER_RULES_CACHE_KEY)) {
                    mailAdapter.setUserScriptExecuting(true);
                }
                boolean proceed = evaluateScript(mailAdapter, node);
                if (!proceed) {
                    continue;
                }
                if (mailAdapter.isStop()) {
                    break;
                }
                mailAdapter.resetValues();
                mailAdapter.resetCapabilities();
            }
        }
        if (applyRules) {
            mailAdapter.executeAllActions();
            addedMessageIds = mailAdapter.getAddedMessageIds();
        }
    } catch (ErejectException ex) {
        throw DeliveryServiceException.DELIVERY_REJECTED(ex.getMessage(), ex);
    } catch (Exception e) {
        ZimbraLog.filter.warn("An error occurred while processing filter rules. Filing message to %s.", handler.getDefaultFolderPath(), e);
    } catch (TokenMgrError e) {
        // Workaround for bug 19576.  Certain parse errors can cause JavaCC to throw an Error
        // instead of an Exception.  Woo.
        ZimbraLog.filter.warn("An error occurred while processing filter rules. Filing message to %s.", handler.getDefaultFolderPath(), e);
    }
    if (addedMessageIds == null) {
        // Filter rules were not processed.  File to the default folder.
        Message msg = mailAdapter.keep(KeepType.IMPLICIT_KEEP);
        addedMessageIds = new ArrayList<ItemId>(1);
        addedMessageIds.add(new ItemId(msg));
    }
    return addedMessageIds;
}
Also used : Account(com.zimbra.cs.account.Account) Message(com.zimbra.cs.mailbox.Message) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Node(org.apache.jsieve.parser.generated.Node) TokenMgrError(org.apache.jsieve.parser.generated.TokenMgrError) ItemId(com.zimbra.cs.service.util.ItemId) ServiceException(com.zimbra.common.service.ServiceException) ParseException(org.apache.jsieve.parser.generated.ParseException) SieveException(org.apache.jsieve.exception.SieveException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) DeliveryServiceException(com.zimbra.common.service.DeliveryServiceException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException)

Example 2 with ErejectException

use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.

the class ErejectTest method testThatSenderRcdUnDeliveredEmail.

/*
     * applyRulesToIncomingMessage() should throw an exception to cancel the message delivery.
     * No message is delivered.
     *
     * The following error will be logged:
     * ERROR - Evaluation failed. Reason: 'ereject' action refuses delivery of a message. Sieve rule evaluation is cancelled
     */
@Test
public void testThatSenderRcdUnDeliveredEmail() {
    Account acct1 = null;
    Mailbox mbox1 = null;
    Account acct2 = null;
    Mailbox mbox2 = null;
    try {
        acct1 = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
        mbox1 = MailboxManager.getInstance().getMailboxByAccount(acct1);
        RuleManager.clearCachedRules(acct1);
        acct2 = Provisioning.getInstance().get(Key.AccountBy.name, "test2@zimbra.com");
        mbox2 = MailboxManager.getInstance().getMailboxByAccount(acct2);
        LmtpEnvelope env = new LmtpEnvelope();
        LmtpAddress sender = new LmtpAddress("<test2@zimbra.com>", new String[] { "BODY", "SIZE" }, null);
        LmtpAddress recipient = new LmtpAddress("<test@zimbra.com>", null, null);
        env.setSender(sender);
        env.addLocalRecipient(recipient);
        acct1.setMailSieveScript(filterScript);
        RuleManager.applyRulesToIncomingMessage(new OperationContext(mbox1), mbox1, new ParsedMessage(sampleBaseMsg.getBytes(), false), 0, acct1.getName(), env, new DeliveryContext(), Mailbox.ID_FOLDER_INBOX, true);
    } catch (DeliveryServiceException e) {
        if (e.getCause() instanceof ErejectException) {
            try {
                List<Integer> items = mbox1.getItemIds(null, Mailbox.ID_FOLDER_INBOX).getIds(MailItem.Type.MESSAGE);
                Assert.assertEquals(null, items);
            } catch (Exception ex) {
                ex.printStackTrace();
                fail("No exception should be thrown: " + ex.getMessage());
            }
        } else {
            fail("No exception other than DeliveryServiceException/ErejectException should be thrown: " + e.getMessage());
        }
    } catch (Exception e) {
        fail("No exception should be thrown: " + e.getMessage());
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Account(com.zimbra.cs.account.Account) Mailbox(com.zimbra.cs.mailbox.Mailbox) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) LmtpAddress(com.zimbra.cs.lmtpserver.LmtpAddress) List(java.util.List) LmtpEnvelope(com.zimbra.cs.lmtpserver.LmtpEnvelope) DeliveryContext(com.zimbra.cs.mailbox.DeliveryContext) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) DeliveryServiceException(com.zimbra.common.service.DeliveryServiceException) ServiceException(com.zimbra.common.service.ServiceException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) DeliveryServiceException(com.zimbra.common.service.DeliveryServiceException) Test(org.junit.Test)

Example 3 with ErejectException

use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.

the class ZimbraMailAdapter method executeActions.

@Override
public void executeActions() throws SieveException {
    try {
        handler.beforeFiltering();
        String messageId = Mime.getMessageID(handler.getMimeMessage());
        // the script contains a single discard action, JSieve returns an empty list.
        if (getActions().size() == 0) {
            ZimbraLog.filter.info("Discarding message with Message-ID %s from %s", messageId, Mime.getSender(handler.getMimeMessage()));
            handler.discard();
            return;
        }
        List<Action> deliveryActions = getDeliveryActions();
        if (deliveryActions.isEmpty()) {
            // i.e. no keep/fileinto/redirect actions
            if (getReplyNotifyRejectActions().isEmpty()) {
                // if only flag/tag actions are present, we keep the message even if discard
                // action is present
                keep(KeepType.EXPLICIT_KEEP);
            } else if (!discardActionPresent) {
                // else if reply/notify/reject/ereject actions are present and there's no discard, do sort
                // of implicit keep
                keep(KeepType.EXPLICIT_KEEP);
            }
        } else {
            ListIterator<Action> li = deliveryActions.listIterator(deliveryActions.size());
            while (li.hasPrevious()) {
                Action lastDeliveryAction = li.previous();
                if (lastDeliveryAction instanceof ActionFileInto) {
                    ActionFileInto lastFileIntoAction = (ActionFileInto) lastDeliveryAction;
                    if (lastFileIntoAction.isCopy() && !discardActionPresent) {
                        keep(KeepType.EXPLICIT_KEEP);
                    }
                    break;
                } else if (lastDeliveryAction instanceof ActionRedirect) {
                    ActionRedirect lastRedirectAction = (ActionRedirect) lastDeliveryAction;
                    if (lastRedirectAction.isCopy() && !discardActionPresent) {
                        keep(KeepType.EXPLICIT_KEEP);
                    }
                    break;
                }
            }
        }
        for (Action action : actions) {
            if (action instanceof ActionKeep) {
                if (context == null) {
                    ZimbraLog.filter.warn("SieveContext has unexpectedly not been set");
                    keep(KeepType.IMPLICIT_KEEP);
                } else if (context.getCommandStateManager().isImplicitKeep()) {
                    // implicit keep: this means that none of the user's rules have been matched
                    // we need to check system spam filter to see if the mail is spam
                    keep(KeepType.IMPLICIT_KEEP);
                } else {
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionFileInto) {
                ActionFileInto fileinto = (ActionFileInto) action;
                String folderPath = fileinto.getDestination();
                folderPath = FilterUtil.replaceVariables(this, folderPath);
                try {
                    if (!allowFilterToMountpoint && isMountpoint(mailbox, folderPath)) {
                        ZimbraLog.filter.info("Filing to mountpoint \"%s\" is not allowed.  Filing to the default folder instead.", folderPath);
                        keep(KeepType.EXPLICIT_KEEP);
                    } else {
                        fileInto(folderPath);
                    }
                } catch (ServiceException e) {
                    ZimbraLog.filter.info("Unable to file message to %s.  Filing to %s instead.", folderPath, handler.getDefaultFolderPath(), e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionRedirect) {
                // redirect mail to another address
                ActionRedirect redirect = (ActionRedirect) action;
                String addr = redirect.getAddress();
                addr = FilterUtil.replaceVariables(this, addr);
                ZimbraLog.filter.info("Redirecting message to %s.", addr);
                try {
                    handler.redirect(addr);
                } catch (Exception e) {
                    ZimbraLog.filter.warn("Unable to redirect to %s.  Filing message to %s.", addr, handler.getDefaultFolderPath(), e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionReply) {
                // reply to mail
                ActionReply reply = (ActionReply) action;
                ZimbraLog.filter.debug("Replying to message");
                try {
                    String replyStrg = FilterUtil.replaceVariables(this, reply.getBodyTemplate());
                    handler.reply(replyStrg);
                } catch (Exception e) {
                    ZimbraLog.filter.warn("Unable to reply.", e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionNotify) {
                ActionNotify notify = (ActionNotify) action;
                ZimbraLog.filter.debug("Sending notification message to %s.", notify.getEmailAddr());
                try {
                    handler.notify(FilterUtil.replaceVariables(this, notify.getEmailAddr()), FilterUtil.replaceVariables(this, notify.getSubjectTemplate()), FilterUtil.replaceVariables(this, notify.getBodyTemplate()), notify.getMaxBodyBytes(), notify.getOrigHeaders());
                } catch (Exception e) {
                    ZimbraLog.filter.warn("Unable to notify.", e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionReject) {
                ActionReject reject = (ActionReject) action;
                ZimbraLog.filter.debug("Refusing delivery of a message: %s", reject.getMessage());
                try {
                    String msg = FilterUtil.replaceVariables(this, reject.getMessage());
                    handler.reject(msg, envelope);
                    handler.discard();
                } catch (Exception e) {
                    ZimbraLog.filter.info("Unable to reject.", e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            } else if (action instanceof ActionEreject) {
                ActionEreject ereject = (ActionEreject) action;
                ZimbraLog.filter.debug("Refusing delivery of a message at the protocol level");
                try {
                    handler.ereject(envelope);
                } catch (ErejectException e) {
                    // 'ereject' action executed
                    throw e;
                } catch (Exception e) {
                    ZimbraLog.filter.warn("Unable to ereject.", e);
                }
            } else if (action instanceof ActionNotifyMailto) {
                ActionNotifyMailto notifyMailto = (ActionNotifyMailto) action;
                ZimbraLog.filter.debug("Sending RFC 5435/5436 compliant notification message to %s.", notifyMailto.getMailto());
                try {
                    handler.notifyMailto(envelope, notifyMailto.getFrom(), notifyMailto.getImportance(), notifyMailto.getOptions(), notifyMailto.getMessage(), notifyMailto.getMailto(), notifyMailto.getMailtoParams());
                } catch (Exception e) {
                    ZimbraLog.filter.warn("Unable to notify (mailto).", e);
                    keep(KeepType.EXPLICIT_KEEP);
                }
            }
        }
        handler.afterFiltering();
    } catch (ServiceException e) {
        throw new ZimbraSieveException(e);
    }
}
Also used : Action(org.apache.jsieve.mail.Action) ActionReply(com.zimbra.cs.filter.jsieve.ActionReply) ActionRedirect(com.zimbra.cs.filter.jsieve.ActionRedirect) MessagingException(javax.mail.MessagingException) SieveMailException(org.apache.jsieve.mail.SieveMailException) SieveException(org.apache.jsieve.exception.SieveException) AddressException(javax.mail.internet.AddressException) ServiceException(com.zimbra.common.service.ServiceException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) IOException(java.io.IOException) ActionEreject(com.zimbra.cs.filter.jsieve.ActionEreject) ActionNotifyMailto(com.zimbra.cs.filter.jsieve.ActionNotifyMailto) ServiceException(com.zimbra.common.service.ServiceException) ActionKeep(org.apache.jsieve.mail.ActionKeep) ActionReject(org.apache.jsieve.mail.ActionReject) ActionFileInto(com.zimbra.cs.filter.jsieve.ActionFileInto) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) ActionNotify(com.zimbra.cs.filter.jsieve.ActionNotify)

Example 4 with ErejectException

use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.

the class ErejectTest method test.

/*
     * applyRulesToIncomingMessage() should throw an exception to cancel the message delivery.
     * No message is delivered.
     *
     * The following error will be logged:
     * ERROR - Evaluation failed. Reason: 'ereject' action refuses delivery of a message. Sieve rule evaluation is cancelled
     */
@Test
public void test() {
    Account acct1 = null;
    Mailbox mbox1 = null;
    boolean isPassed = false;
    try {
        acct1 = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
        mbox1 = MailboxManager.getInstance().getMailboxByAccount(acct1);
        RuleManager.clearCachedRules(acct1);
        LmtpEnvelope env = new LmtpEnvelope();
        LmtpAddress sender = new LmtpAddress("<test2@zimbra.com>", new String[] { "BODY", "SIZE" }, null);
        LmtpAddress recipient = new LmtpAddress("<test@zimbra.com>", null, null);
        env.setSender(sender);
        env.addLocalRecipient(recipient);
        acct1.setMailSieveScript(filterScript);
        RuleManager.applyRulesToIncomingMessage(new OperationContext(mbox1), mbox1, new ParsedMessage(sampleBaseMsg.getBytes(), false), 0, acct1.getName(), env, new DeliveryContext(), Mailbox.ID_FOLDER_INBOX, true);
    } catch (DeliveryServiceException e) {
        if (e.getCause() instanceof ErejectException) {
            try {
                List<Integer> items = mbox1.getItemIds(null, Mailbox.ID_FOLDER_INBOX).getIds(MailItem.Type.MESSAGE);
                Assert.assertEquals(null, items);
                isPassed = true;
            } catch (Exception ex) {
                fail("No exception should be thrown: " + ex.getMessage());
            }
        } else {
            fail("No exception other than DeliveryServiceException/ErejectException should be thrown: " + e.getMessage());
        }
    } catch (Exception e) {
        fail("No exception should be thrown: " + e.getMessage());
    }
    if (!isPassed) {
        fail("DeliveryServiceException/ErejectException should have been thrown, but no exception is thrown");
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Account(com.zimbra.cs.account.Account) Mailbox(com.zimbra.cs.mailbox.Mailbox) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) LmtpAddress(com.zimbra.cs.lmtpserver.LmtpAddress) List(java.util.List) LmtpEnvelope(com.zimbra.cs.lmtpserver.LmtpEnvelope) DeliveryContext(com.zimbra.cs.mailbox.DeliveryContext) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) DeliveryServiceException(com.zimbra.common.service.DeliveryServiceException) ServiceException(com.zimbra.common.service.ServiceException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) DeliveryServiceException(com.zimbra.common.service.DeliveryServiceException) Test(org.junit.Test)

Example 5 with ErejectException

use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.

the class ZimbraMailAdapter method executeActionErejectInternal.

private void executeActionErejectInternal(Action action) throws ErejectException {
    ActionEreject ereject = (ActionEreject) action;
    ZimbraLog.filter.debug("Refusing delivery of a message at the protocol level");
    try {
        handler.ereject(envelope);
    } catch (ErejectException e) {
        // 'ereject' action executed
        throw e;
    } catch (Exception e) {
        ZimbraLog.filter.warn("Unable to ereject.", e);
    }
}
Also used : ActionEreject(com.zimbra.cs.filter.jsieve.ActionEreject) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) MessagingException(javax.mail.MessagingException) SieveMailException(org.apache.jsieve.mail.SieveMailException) SieveException(org.apache.jsieve.exception.SieveException) AddressException(javax.mail.internet.AddressException) ServiceException(com.zimbra.common.service.ServiceException) ErejectException(com.zimbra.cs.filter.jsieve.ErejectException) IOException(java.io.IOException)

Aggregations

ServiceException (com.zimbra.common.service.ServiceException)5 ErejectException (com.zimbra.cs.filter.jsieve.ErejectException)5 DeliveryServiceException (com.zimbra.common.service.DeliveryServiceException)3 Account (com.zimbra.cs.account.Account)3 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)3 IOException (java.io.IOException)3 SieveException (org.apache.jsieve.exception.SieveException)3 ActionEreject (com.zimbra.cs.filter.jsieve.ActionEreject)2 LmtpAddress (com.zimbra.cs.lmtpserver.LmtpAddress)2 LmtpEnvelope (com.zimbra.cs.lmtpserver.LmtpEnvelope)2 DeliveryContext (com.zimbra.cs.mailbox.DeliveryContext)2 Mailbox (com.zimbra.cs.mailbox.Mailbox)2 OperationContext (com.zimbra.cs.mailbox.OperationContext)2 List (java.util.List)2 MessagingException (javax.mail.MessagingException)2 AddressException (javax.mail.internet.AddressException)2 SieveMailException (org.apache.jsieve.mail.SieveMailException)2 Test (org.junit.Test)2 ActionFileInto (com.zimbra.cs.filter.jsieve.ActionFileInto)1 ActionNotify (com.zimbra.cs.filter.jsieve.ActionNotify)1