On Mon, Nov 04, 2019 at 10:18:07PM +0100, Joerg Jung wrote:
> On Thu, Oct 31, 2019 at 08:28:23AM +0000, gil...@poolp.org wrote:
> > October 24, 2019 8:35 PM, "Joerg Jung" <m...@umaxx.net> wrote:
> > 
> > > I used some regex filters in the past which I'm trying to convert to the
> > > latest builtin filters. In particular, I stumbled over a HELO filter,
> > > which rejects non-FQDN HELO forcing SMTP protocol, aka: 
> > > Sendmail FEATURE(block_bad_helo) or Postfix reject_non_fqdn_helo_hostname
> > > 
> > > I had significant success rate with this kind of blocking, since a good
> > > portions of spammers seem to be too lazy to configure HELO correctly.
> > > 
> > > Here is what I came up with:
> > > 
> > > # reject HELO/EHLO with leading or trailing dot, and without dots 
> > > (non-FQDN)
> > > filter helo phase helo connect match helo regex { "^\.", "\.$", 
> > > "^[^\.]*$" } disconnect "554 5.7.1
> > > HELO rejected" 
> > > filter ehlo phase ehlo connect match helo regex { "^\.", "\.$", 
> > > "^[^\.]*$" } disconnect "554 5.7.1
> > > EHLO rejected
> > > 
> > > Now, I just need a way to skip/allow IPv6 address literals, e.g. there
> > > are no dots in EHLO [::1], but still a valid/allowed value.
> > > With old filter-regex I just did a negotiation: ! regex "^\[" to
> > > not apply filter to v6 literals
> > > 
> > > Any ideas/hints how to add/implement this with the new builtin regex
> > > filter syntax?
> > > 
> > 
> > Sadly there would have been a very easy way if I had that use-case in mind 
> > pre-release,
> > which would be to make the "proceed" action explicit, you could have had a 
> > filter
> > match the inet6 address and proceed to shortcut the matching of non fqdn.
> 
> :)
> 
> > As of today, there will be no option but to craft your regex to contain 
> > both the pattern
> > you want to match AND exclude [ as far as I see it.
> 
> But that AND EXCLUDE (aka AND NOT) is not possible with re_format(7), 
> because no zero-width negative lookahead or similar tricks are 
> available, right?
> 
> I wonder if abusing "match" instead of filtering is an option here, with
> match I have the negotiation operator available, so something like this
> would probably work, right?
> 
> match ! helo regex "^\[" myaction
> match helo regex { "^\.", "\.$", "^[^\.]*$" } reject
> # further standard match rules following...
> 
> The question is, what to put into: myaction, there is no 
> pass/accept/skip/jump to other match rules... and "relay" 
> will probably result in a loop, no?
> 
> Seems like this is just not possible with the built-in syntax for now
> and I need to write a tiny proc-exec filter instead?

I took a quick shot and wrote a tiny and portable ~20 lines sed based 
filter, which can be found below and is released here:
https://www.umaxx.net/dl/filter-fqdn-0.1.tar.gz

I'm not an sed expert and I'm pretty sure the script can be shortened
and further simplified e.g. with some hold buffer exchange, yalla, yalla
Any suggestions or comments are welcome, but for now it does what I want
and works fine for me. 

Thanks,
Regards,
Joerg


#!/usr/bin/sed -Enuf
# $Id: filter-fqdn.sed 53 2019-11-20 19:27:59Z umaxx $
# Copyright (c) 2019 Joerg Jung <m...@umaxx.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# filter-fqdn - opensmtpd filter for HELO/EHLO FQDN filtering
#
# version: 0.1
#
# uncomment for debug
#s/(.*)/\1/w /dev/stderr

/^config|ready$/ { a\
register|filter|smtp-in|helo\
register|filter|smtp-in|ehlo\
register|ready
}

/^filter\|0.4\|.*\|smtp-in\|.*/ {
    # skip address literals
    /^.*smtp-in\|(.*)\|(.*)\|\[.*$/ {
        bproceed
    }
    # reject leading dot
    /^.*smtp-in\|(.*)\|(.*)\|(.*)\|\..*$/ {
        s//filter-result\|\3|\2\|reject\|554 5.7.1 \1 failed/p
    }
    # reject trailing dot
    /^.*smtp-in\|(.*)\|(.*)\|(.*)\|.*\.$/ {
        s//filter-result\|\3|\2\|reject\|554 5.7.1 \1 failed/p
    }
    # reject without dots (non-FQDN)
    /^.*smtp-in\|(.*)\|(.*)\|(.*)\|[^\.]*$/ {
        s//filter-result\|\3|\2\|reject\|554 5.7.1 \1 failed/p
    }
:proceed
    /^.*smtp-in\|.*\|(.*)\|(.*)\|.*$/ {
        s//filter-result\|\2|\1\|proceed/p
    }
}

Reply via email to