haraka / Haraka

A fast, highly extensible, and event driven SMTP server

Home Page:https://haraka.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feedback needed] Execution control of plugins

gminogiannis opened this issue · comments

I'm using Haraka v2.8.24 as an MTA for incoming SMTP connections to WildDuck v1.23.5 (yes, I know I have old versions).
The default /opt/haraka/config/plugins contains the following:

spf
dkim_verify

rspamd
tls

# WildDuck plugin handles recipient checking and queueing
wildduck

The wildduck plugin is located under the folder /opt/haraka/plugins/wildduck

Now, I would like to implement a plugin that takes control before the wildduck plugin.
Below is the content of my custom plugin (which just aims to skip WildDuck for a specific recipient pattern):

exports.hook_rcpt = function (next, connection, params) {
    const rcpt = params[0];
    const address = rcpt.address();

    const dropPattern = /^foo.*@mailsac\.com$/i;

    if (dropPattern.test(address)) {
       connection.loginfo(this, "Dropping message to: " + address);
       return;
    }

    return next();
};

The file /opt/haraka/config/plugins is adjusted so that the last lines are the following:

pre-wildduck-hook
# WildDuck plugin handles recipient checking and queueing
wildduck

According to the logs, it takes exactly 30 seconds to pass control from the plugin pre-wildduck-hook to the core.
See the logs of Haraka:

Apr 04 21:43:51: [INFO] [98FEDD2A-2362-4924-9C0F-D72CC1469030.1] [pre-wildduck-hook] Dropping message to: foo1@mailsac.com
Apr 04 21:44:21: [INFO] [98FEDD2A-2362-4924-9C0F-D72CC1469030.1] [core]  hook=rcpt plugin=pre-wildduck-hook function=hook_rcpt params=<foo1@mailsac.com> retval=DENYSOFT msg="plugin timeout"

Any ideas why ?
Thank you!

Any ideas why?

Yes, remove the line with the bare return; Hooks must always call next when they're completed. If not, they get timed out after 30 seconds.

Improved:

exports.hook_rcpt = function (next, connection, params) {
    const rcpt = params[0];
    const address = rcpt.address();

    const dropPattern = /^foo.*@mailsac\.com$/i;

    if (dropPattern.test(address)) {
       connection.loginfo(this, `Dropping message to: ${address}`);
    }

    next();
}

Thank you @msimerson for the prompt response.
Nevertheless, the purpose of the custom plugin is to silently drop a message if the recipient conforms to the pattern foo*@mailsac.com

Your suggestion appends a log entry that a message is to be dropped, but it isn't (it's "promoted" to the next chain of commands and reaches the wildduck plugin).
As mentioned in the original comment, the purpose of the plugin is to conditionally skip WildDuck.

Can you help ?

You asked why it paused for 30 seconds. I answered your question.

To change what Haraka does when you call next, look into next return codes

Thank you for pointing me to the proper section of the documentation.

For anyone encountering this thread, the solution was to use next(OK) in case the recipient's address matched the pattern.
Quoting from the documentation:

After a plugin calls next(OK), no further plugins on that hook will run.