Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overwrite Return-Path for the outbound emails #2946

Closed
wasifahmad opened this issue May 15, 2021 · 7 comments
Closed

Overwrite Return-Path for the outbound emails #2946

wasifahmad opened this issue May 15, 2021 · 7 comments

Comments

@wasifahmad
Copy link

wasifahmad commented May 15, 2021

There is no way I am able to overwrite the Return-Path! Below is my code for the custom plugin. Any help will be appreciated. So far, I love haraka.

exports.hook_data_post = function (next, connection) {
    var txn = connection.transaction;
    txn.remove_header('Return-Path');
    // Add a new one
    txn.add_header('Return-Path', '<somthing@example.com>');

    next();
}
@wasifahmad
Copy link
Author

I believe what I need here is, to add a header at the top of DATA. Otherwise, Return-Path will be duplicated!

@msimerson
Copy link
Member

msimerson commented May 17, 2021

I believe what I need here is, to add a header at the top of DATA

Have you seen add_leading_header?

@wasifahmad
Copy link
Author

Yes, it didn't work!

@endreszabo
Copy link
Contributor

endreszabo commented May 20, 2021 via email

@wasifahmad
Copy link
Author

wasifahmad commented May 20, 2021

I am configuring/tweaking haraka to act as a middleware between my MTA server and the Application Server. So my app pushes the emails to haraka and goes through several checks, and then finally the packet is pushed to MTA. Now in my case, I have both headers sent to haraka i.e. Return-Path and From. In my case, both are different mostly. So I am setting up haraka to fetch the MailFrom and match across the whitelist file. If found then push as it is, if didn't find then change it to my set value so the SPF doesn't fail.

Also, I've noticed, haraka has rcpt and mail_from hooks that are excellent but it should also have a very important hook -> send_from. As return-path just becomes equal to the send_from email when there is no Return-Path value set by the actual sender. e.g, if I put the SMTP in my outlook, so my return-path will be my own email address by default. But when I use advanced applications, it allows us to set the return-path ourselves which is great. So here, haraka fails to distinguish between Return-Path and From emails. So to make things easy, we should have a hook that returns you send_from email address so we can deny incoming emails and return the correct reason.

For now, I did custom coding for it but it doesn't return the deny message to the user that I've set. It just logs the message

const haddr     = require('address-rfc2822');

exports.register = function () {
    const plugin = this;
    plugin.register_hook('data_post', 'send_from_access');
}

exports.init_config = function () {
    const plugin = this;

    plugin.cfg = {
        deny_msg: {
            send: 'The From email is unauthorized to relay emails',
        },
        white: {
            send: 'send_from.access.whitelist',
        },
     };
}

exports.send_from_access = function (next, connection) {
    const plugin = this;

    const sn_domain = plugin.get_sender_domain(connection);
	
    // address whitelist checks
    let file = plugin.cfg.white.send;
    connection.logdebug(plugin, `checking ${sn_domain} against ${file}`);
    if (!plugin.in_list('white', 'send', sn_domain)) {
        connection.transaction.results.add(plugin, {fail: file, emit: true});
        return next(DENY, `${sn_domain} is not authorized to relay emails`);
    }
    return next();
}

exports.in_list = function (type, phase, address) {
    const plugin = this;
    if (plugin.list[type][phase] === undefined) {
        console.log(`phase not defined: ${phase}`);
        return false;
    }
    if (!address) return false;
    if (plugin.list[type][phase][address.toLowerCase()]) return true;
    return false;
}

exports.get_sender_domain = function (connection) {
    const plugin = this;
    if (!connection.transaction) {
        connection.logerror(plugin, 'no transaction!')
        return;
    }

    const txn = connection.transaction;

    // fallback: use Envelope FROM when header parsing fails
    let domain;
    if (txn.mail_from.host) {
        try { domain = txn.mail_from.host.toLowerCase(); }
        catch (e) {
            connection.logerror(plugin, e);
        }
    }

    // In case of forwarding, only use the Envelope
    if (txn.notes.forward) return domain;
    if (!txn.header) return domain;

    // the DKIM signing key should be aligned with the domain in the From
    // header (see DMARC). Try to parse the domain from there.
    const from_hdr = txn.header.get_decoded('From');
    if (!from_hdr) return domain;

    // The From header can contain multiple addresses and should be
    // parsed as described in RFC 2822 3.6.2.
    let addrs;
    try {
        addrs = haddr.parse(from_hdr);
    }
    catch (e) {
        connection.logerror(plugin, `address-rfc2822 failed to parse From header: ${from_hdr}`)
        return domain;
    }
    if (!addrs || ! addrs.length) return domain;

    // If From has a single address, we're done
    if (addrs.length === 1 && addrs[0].host) {
        let fromHost = addrs[0].host();
        if (fromHost) {
            // don't attempt to lower a null or undefined value #1575
            fromHost = fromHost.toLowerCase();
        }
        return fromHost;
    }

    // If From has multiple-addresses, we must parse and
    // use the domain in the Sender header.
    const sender = txn.header.get_decoded('Sender');
    if (sender) {
        try {
            domain = (haddr.parse(sender))[0].host().toLowerCase();
        }
        catch (e) {
            connection.logerror(plugin, e);
        }
    }
    return domain;
}

@rogereiddir
Copy link

you can use smtp_forward plugin check this :
https://gist.github.com/rogereiddir/c0ae7b029da213261e3f701fba73febb
#2882

@ajay-psd
Copy link

ajay-psd commented Jun 29, 2021

there is verp plugin do rewrite mail_from

exports.register = function() {
  var plugin = this;
  plugin.register_hook('data_post', 'set_verp_mail_from');
};

exports.set_verp_mail_from = function (next, connection) {
  connection.transaction.parse_body = true;
  var transaction = connection.transaction;
  var token = transaction.uuid.split("-")[0];
  var verp = ("bounces+" + token + "-" + transaction.rcpt_to[0].original).replace(/@/,"=").replace(/>/,"").replace(/</,"") + '@' + 'your-email-domain.com';
  transaction.mail_from = verp;
  next();
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants