Re: newer check_spamhelo
On Sun, 24 May 2009, Peter Walter wrote: Charlie Brady wrote: On Mon, 11 May 2009, Hanno Hecker wrote: > What about something like the attached? I'll have a closer look, but looks an excellent suggestion. Thanks Hanno. Charlie, I assume Hanno asked you for code review? Did you get a chance to look at it? No.
Re: newer check_spamhelo
Charlie Brady wrote: On Mon, 11 May 2009, Hanno Hecker wrote: What about something like the attached? I'll have a closer look, but looks an excellent suggestion. Thanks Hanno. --- Charlie Charlie, I assume Hanno asked you for code review? Did you get a chance to look at it? Peter
Re: newer check_spamhelo
On Mon, 11 May 2009, Hanno Hecker wrote: What about something like the attached? I'll have a closer look, but looks an excellent suggestion. Thanks Hanno. --- Charlie
Re: newer check_spamhelo
Robert Spier wrote: Ask Bjørn Hansen wrote: On May 9, 2009, at 19:21, Charlie Brady wrote: If the assertion that the existing old simple version is useless is correct, is there much justification for keeping the old simple version? This is really a namespace issue, I think. Should "check_spamhelo" belong to an old simple ineffective plugin, or a newer, and presumably more useful, one? As much as it sucks to lose the old simple plugins for examples, I think I could go for replacing it with a newer one. The old plugin isn't ineffective at all, it's just very basic. Well, "ineffective" is a judgment call, then. Perhaps a better word would be "useless" because it is trivial to bypass the check. The spammers tend to use varying subdomains in the HELO, such as mx1.domain.com, mx2.domain2, etc., where, once you block a specific subdomain, they simply use another. If the newer one is going to have different behavior, or doesn't support the old config file, it'll potentially break people who upgrade. (And people don't read documentation or check the changes file -- it just doesn't happen.) The easiest way around that is to make the new version have a different name. As I understand it, the new plugin supports the old config file as is backward-compatible in that it will support the existing entries as they are now. So, nothing will break. Peter
Re: newer check_spamhelo
On Sun, 10 May 2009 17:33:28 -0400 "Chris Lewis" wrote: > This might be a good opportunity to introduce standardization into > pattern matching plugins with common config file parser. I can offer up > my set, but once you see one, you don't need the rest. I use this > mechanism for _all_ pattern matching (mailfrom, from, rcptto, To, rdns, > body strings etc). They'll need a little tweaking because my plugins > themselves _never_ DENY, they use subsequent plugins to decide what > action to take (the notes() stuff). > > Here's my helo plugin - note the NTMqplib::configpattern call, and the > if ( $host =~ /$self->{f_badhelo}/o ) { line. Hmm, this wouldn't easily allow adding exceptions if a match was found Yes, you can always tweak the regexp, but without //x in a config file it will be unreadable / unmaintainable. What about something like the attached? The main logic is the same as in the rcpt_regexp plugin, see the docs there until there's documentation for this module. Additional: '%s' in the comment field will be replaced by the argument given to check(). Checks (i.e. new sample config) for check_spamhelo can be (REs taken from http://www.nntp.perl.org/group/perl.qpsmtpd/2004/07/msg1674.html): # these domains never uses their domain when greeting us, so reject # transactions, both get the default arguments of # "DENY", "Sorry, I don't believe that you are %s." aol.com yahoo.com # new (additional): /^\[[a-z\d\-]*[a-z\d]:([^\\\[\]]|\\.)+\]$/i DECLINED IPv6 literal /^\[(((?(? reverse mapping of ## the HELO host The "check_spamhelo" can be rewritten like below without any troubles for upgrading users. use Qpsmtpd::ConfigRE; sub register { my ($self, $qp, @args) = @_; $self->configure("badhelo", # defaults for "old" check_spamhelo: "DENY", # string, not the constant! q{Sorry, I don't believe that you are %s.} # '%s' will be replaced by the arg given to ->check() ); } sub hook_helo { my ($self, $transaction, $host) = @_; ($host = lc $host) or return DECLINED; return $self->check($host); } # also support EHLO *hook_ehlo = \&hook_helo; Hanno ConfigRE.pm Description: Perl program
Re: newer check_spamhelo
Charlie Brady wrote: http://markmail.org/message/sckrkzhtft34rqgg Does anyone have existing literal badhelo matches which might match a valid helo hostname if interpreted as an RE? This might be a good opportunity to introduce standardization into pattern matching plugins with common config file parser. I can offer up my set, but once you see one, you don't need the rest. I use this mechanism for _all_ pattern matching (mailfrom, from, rcptto, To, rdns, body strings etc). They'll need a little tweaking because my plugins themselves _never_ DENY, they use subsequent plugins to decide what action to take (the notes() stuff). Here's my helo plugin - note the NTMqplib::configpattern call, and the if ( $host =~ /$self->{f_badhelo}/o ) { line. use NTMqplib qw(configpattern); sub register { my ( $self, $qp, @args ) = @_; &NTMqplib::configpattern( $self, 'badhelo' ); return; } # Doing this later (after MAILFROM) so the per-recipient # domain configuration has been done by this point, and # we know whether to do this or not. sub hook_data { my ( $self, $transaction ) = @_; return DECLINED if $transaction->notes('filter') !~ /yes/i || !$self->{f_badhelo} || $transaction->notes('reason'); my $host = $self->qp->connection->hello_host(); $host = lc $host; return DECLINED if !$host; if ( $host =~ /$self->{f_badhelo}/o ) { my $content = &NTMqplib::genreason( 'badhelo', $1, "Bad HELO/EHLO name $host" ); $self->log( LOGINFO, $content ); $transaction->notes( 'reason', $content ); } return DECLINED; } This is the configpattern function. It's job is to create a big alternating pattern, where each line in the config file is one of the alternates. If the config line is /.../ it's taken as a bare regexp. If doesn't have /.../, it's taken literally, and \xXX encoded to de-meta any characters there might be. The pattern is unanchored. If you want to anchor (eg: insisting that all rDNS entries have an implicit "$"), you do that in the plugin. sub configpattern { my ( $self, $parname ) = @_; my @entries = $self->qp->config($parname); return if !scalar(@entries); my @cookedpatterns = (); for my $p (@entries) { next if $p =~ /^\s*#/; next if $p =~ /^\s*$/; if ( $p =~ /^\/(.*)\// ) { push( @cookedpatterns, '(' . $1 . ')' ); } else { $p =~ s/([^A-Za-z0-9])/sprintf("\\x%02x", ord($1))/ge; push( @cookedpatterns, $p ); } } $cookedpattern = '(?i)(' . join( '|', @cookedpatterns ) . ')'; $self->{ 'f_' . $parname } = $cookedpattern; $self->log( LOGDEBUG, "CONFIGPATTERN($parname): $cookedpattern" ); }
Re: newer check_spamhelo
On Sun, 10 May 2009, Robert Spier wrote: Ask Bjørn Hansen wrote: On May 9, 2009, at 19:21, Charlie Brady wrote: This is really a namespace issue, I think. Should "check_spamhelo" belong to an old simple ineffective plugin, or a newer, and presumably more useful, one? As much as it sucks to lose the old simple plugins for examples, I think I could go for replacing it with a newer one. ... If the newer one is going to have different behavior, or doesn't support the old config file, it'll potentially break people who upgrade. (And people don't read documentation or check the changes file -- it just doesn't happen.) The easiest way around that is to make the new version have a different name. Yes that's easier. But not better. What would be better IMO is to have an enhanced plugin which is a strict superset of the existing plugin. I think that would be easy to do with a legacy badhelo config, and new badhelo_re config. That would work simply, but at the cost of an extra config load per execution. Or we could fudge a bit and just have badhelo. I doubt there will be many false positive re matches with the existing badhelo configs. e.g "aolycom" will be a false positive match with "aol.com", but it's probably something you'd reject anyway and would have rejected via existing check_spamhelo if a patch proposed by Andrew Pam in 2003 had been accepted: http://markmail.org/message/sckrkzhtft34rqgg Does anyone have existing literal badhelo matches which might match a valid helo hostname if interpreted as an RE? --- Charlie
Re: newer check_spamhelo
Ask Bjørn Hansen wrote: > > > On May 9, 2009, at 19:21, Charlie Brady wrote: > > > If the assertion that the existing old simple version is useless is > > correct, is there much justification for keeping the old simple > > version? > > > > This is really a namespace issue, I think. Should "check_spamhelo" > > belong to an old simple ineffective plugin, or a newer, and > > presumably more useful, one? > > As much as it sucks to lose the old simple plugins for examples, I > think I could go for replacing it with a newer one. The old plugin isn't ineffective at all, it's just very basic. If the newer one is going to have different behavior, or doesn't support the old config file, it'll potentially break people who upgrade. (And people don't read documentation or check the changes file -- it just doesn't happen.) The easiest way around that is to make the new version have a different name. -R
Re: newer check_spamhelo
On May 9, 2009, at 19:21, Charlie Brady wrote: If the assertion that the existing old simple version is useless is correct, is there much justification for keeping the old simple version? This is really a namespace issue, I think. Should "check_spamhelo" belong to an old simple ineffective plugin, or a newer, and presumably more useful, one? As much as it sucks to lose the old simple plugins for examples, I think I could go for replacing it with a newer one. My only nitpicks on Marks code (on scanning the code for the patch) are 1) don't have the 'tld regexp' be configurable 2) the documentation needs updating (and/or a default config should be supplied) 3) The NOIPHC thing is a little dubious -- it won't work with forkserver etc anyway, so if we need a whitelisting mechanism, that isn't it. - ask -- http://develooper.com/ - http://askask.com/
Re: newer check_spamhelo
On Sat, 9 May 2009, Robert Spier wrote: Reading through that thread, it looks like the right code to use is http://www.nntp.perl.org/group/perl.qpsmtpd/2004/07/msg1674.html Because this is a large change, and the old version is so simple, I think I'd rather add this as a new plugin, check_spamhelo_fancy or something. If the assertion that the existing old simple version is useless is correct, is there much justification for keeping the old simple version? This is really a namespace issue, I think. Should "check_spamhelo" belong to an old simple ineffective plugin, or a newer, and presumably more useful, one? [I'm assuming that the new one will be code reviewed and tested, and therefore presumed functional.] --- Charlie
Re: newer check_spamhelo
Reading through that thread, it looks like the right code to use is http://www.nntp.perl.org/group/perl.qpsmtpd/2004/07/msg1674.html Because this is a large change, and the old version is so simple, I think I'd rather add this as a new plugin, check_spamhelo_fancy or something. If someone can put together and test a patch (or just new file) from Mark Powell's updated code and comments in the thread, I'll commit it. -R Peter Walter wrote: > > In http://www.nntp.perl.org/group/perl.qpsmtpd/2004/06/msg1438.html , > Mark Powell proposed a revised version of the check_spamhelo plugin, > but his changes never seemed to make it into the base. I have asked > that the changes be incorporated into a distribution I use (SME Server > 7.4), but the maintainers of the distribution tell me they would > prefer than the change come from upstream. Is there any likelihood > that this newer version of the check_spamhelo plugin will be > incorporated into the base anytime soon? > > Regards, > Peter
newer check_spamhelo
In http://www.nntp.perl.org/group/perl.qpsmtpd/2004/06/msg1438.html , Mark Powell proposed a revised version of the check_spamhelo plugin, but his changes never seemed to make it into the base. I have asked that the changes be incorporated into a distribution I use (SME Server 7.4), but the maintainers of the distribution tell me they would prefer than the change come from upstream. Is there any likelihood that this newer version of the check_spamhelo plugin will be incorporated into the base anytime soon? Regards, Peter
newer check_spamhelo
In http://www.nntp.perl.org/group/perl.qpsmtpd/2004/06/msg1438.html , Mark Powell proposed a revised version of the check_spamhelo plugin, but his changes never seemed to make it into the base. I have asked that the changes be incorporated into a distribution I use (SME Server 7.4), but the maintainers of the distribution tell me they would prefer than the change come from upstream. Is there any likelihood that this newer version of the check_spamhelo plugin will be incorporated into the base anytime soon? Regards, Peter
Re: Newer check_spamhelo patch for PPerl (was Re: newer still check_spamhelo)
Hello, Sunday, August 15, 2004, 4:31:21 PM, Mark Powell wrote: > I posted a newer check_spamhelo.diff on 31/7/04 which uses conn->notes > throughout. Did that not work with PPerl? ups, I owe you a reply. I'm sorry, I must have missed your patch or something. It works with pperl, but it has an issue I think, I'll reply to the original message. -- spaze -- exploited.cz -- tojeono.cz - forget everything and remember! -
Re: Newer check_spamhelo patch for PPerl (was Re: newer still check_spamhelo)
On Thu, 5 Aug 2004, spaze wrote: > Hello, > > Tuesday, June 15, 2004, 5:04:23 PM, you wrote: > > Here is the latest check_spamhelo > [...] > > I found that it doesn't work correctly when qpsmtpd is run under PPerl, it > wasn't resetting the values properly. I posted a newer check_spamhelo.diff on 31/7/04 which uses conn->notes throughout. Did that not work with PPerl? Cheers. > Find attached a "diff -bu check_spamhelo.orig check_spamhelo" > against the Tue, 15 Jun 2004 16:04:23 +0100 (BST) version (the message i'm > replying to) sized 6048 bytes. > > It is heavily inspired by this diff > http://cvs.perl.org/viewcvs/viewcvs.py/cvs-public/qpsmtpd/plugins/count_unrecognized_commands?r1=1.1&r2=1.2 > > -- Mark Powell - UNIX System Administrator - The University of Salford Information Services Division, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 4837 Fax: +44 161 295 5888 www.pgp.com for PGP key
Newer check_spamhelo patch for PPerl (was Re: newer still check_spamhelo)
Hello, Tuesday, June 15, 2004, 5:04:23 PM, you wrote: > Here is the latest check_spamhelo [...] I found that it doesn't work correctly when qpsmtpd is run under PPerl, it wasn't resetting the values properly. Find attached a "diff -bu check_spamhelo.orig check_spamhelo" against the Tue, 15 Jun 2004 16:04:23 +0100 (BST) version (the message i'm replying to) sized 6048 bytes. It is heavily inspired by this diff http://cvs.perl.org/viewcvs/viewcvs.py/cvs-public/qpsmtpd/plugins/count_unrecognized_commands?r1=1.1&r2=1.2 -- spaze -- exploited.cz -- tojeono.cz - forget everything and remember! - check_spamhelo.pperl.diff Description: Binary data
Re: newer check_spamhelo (was Re: RFC: new check_spamhelo)
> From: [EMAIL PROTECTED] (Devin Carraway) ... > I've seen excite.com also, so you might consider adding that. > I had excite in my badhelo list until last week when I fielded a user complaint. They may be legit (as in, I took it out of the list and the complaint went away -- I didn't actually research it). Peter
Re: newer still check_spamhelo (was Re: newer check_spamhelo (was Re: RFC: new check_spamhelo))
On Tue, Jun 15, 2004 at 04:04:23PM +0100, Mark Powell wrote: > Here is the latest check_spamhelo that surrounds each regexp, with > simply '^' & '$'. Slashes are not needed to surround a regexp anymore. See > the attached badhelo for some examples. Excellent, much cleaner. > Passing the argument 'checkip', in addition to 'rfc', will also check > that the IP address given in an IPv4 address literal actually matches that > of the connection. Yummy, though I'd be somewhat concerned about environments placing their outbound mailservers behind NAT firewalls. Still, the proportion of servers both (a) doing that and (b) issuing IP HELOs is probably vanishingly small. > # A lot of spammers use the following which are not used by the real domain owners I've seen excite.com also, so you might consider adding that. Ask, Mark has pretty well superceded my original check_spamhelo with this, so once this is adequately tested I suggest deprecating or replacing mine in favor of this one. -- Devin \ aqua(at)devin.com, 1024D/E9ABFCD2; http://www.devin.com Carraway \ IRC: Requiem GCS/CC/L s-:--- !a !tv C$ ULB+++$ O+@ P L+++ signature.asc Description: Digital signature
newer still check_spamhelo (was Re: newer check_spamhelo (was Re: RFC: new check_spamhelo))
On Mon, 14 Jun 2004, Mark Powell wrote: > On Sun, 13 Jun 2004, Keith C. Ivey wrote: > My finger trouble. I meant '\.?$'. The argument is supposed to be a FQDN, > so it may end with a dot char. Thus any pattern you match, must match the > same with and without a dot at the end. Actually on a proper reading of RFC2821, it's clear that a '.' is not allowed at the end of a HELO argument :( Here is the latest check_spamhelo that surrounds each regexp, with simply '^' & '$'. Slashes are not needed to surround a regexp anymore. See the attached badhelo for some examples. In addition this version now performs a complete check on a FQDN to make sure it completely matches the allowed RFC2821 format e.g. a-.uk, -.com, a.b., a_b.hello are not allowed. Passing the argument 'checkip', in addition to 'rfc', will also check that the IP address given in an IPv4 address literal actually matches that of the connection. It's up to you where you put the line in config/plugins. If you put it before dnsbl, then the error reported during the conversation and in the logs, will be due to any bad HELO, even if an RBL check was positive. Putting it after gets you the opposite result. I put following line in my config/plugins: check_spamhelo delay rfc checkip just after dnsbl as I prefer to know whether any email was prevented due to that rather than badhelo. This allows logging of the message details, only allows proper FQDN or IPv4/IPv6 address literals and checks that an IPv4 address literal corresponds to the connection. This greatly reduces what you have to check for in badhelo, as everything illegal is already rejected. Cheers. -- Mark Powell - UNIX System Administrator - The University of Salford Information Services Division, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 4837 Fax: +44 161 295 5888 www.pgp.com for PGP key# # A lot of spammers use the following which are not used by the real domain owners # aol\.com yahoo\.com bbc\.com addr\.com netscape\.com cpan\.org msn\.com # # Block helos pretending to be in our domain .*example\.com # # Some IPv4 address literal checks. # # NB Passing argument 'rfc' would already prevent all bare IP addresses so # there'd be no need to check for them. Argument 'checkip' would also prevent # private addresses and other IP forgery, obviating the need for any of # the following IP based checks. # # Block helos pretending to be on our net. #\[1\.2\.\d+\.\d+\] # Block private address space IPv4 literals #\[10\.\d+\.\d+\.\d+\] #\[172\.(1[6-9]|2[0-9]|3[01])\.\d+\.\d+\] #\[192\.168\.\d+\.\d+\] # # Some more regexps to catch out other baddies .*\.prod-infinitum\.com\.mx [A-Z\d]{8}\.ipt\.aol\.com netscape\d+\.com =head1 NAME check_spamhelo - Check a HELO argument delivered from a connecting host. =head1 DESCRIPTION Check a HELO argument delivered from a connecting host. Reject any that are matched by a regexp in the badhelo config -- e.g. yahoo\.com and aol\.com, which neither the real Yahoo or the real AOL use, but which spammers use rather a lot. Can also provide some limited RFC2821 enforcement. =head1 CONFIGURATION =head2 Regexp HELO argument matching Add regexp patterns to the F configuration file; one per line. All regexp patterns will have an implied prefix of '^' and a post-fix of '$'. Any pattern that matches a HELO argument will cause the SMTP conversation to be rejected. =head2 RELAYCLIENT support If RELAYCLIENT is set then this plugin will perform no checking at all. This allows pre-approved sites to use any or no argument to HELO. The RELAYCLIENT check can be disabled by passing the plugin the arg 'checkrc', in which case all HELOs will be checked. This provided primarliy for testing. You should be using tcpserver to determine which IP addresses get RELAYCLIENT set. =head2 RFC2821 enforcement If the argument 'rfc' is given to the plugin then some limited enforcement of RFC2821 requirements are performed. In that case the argument to the HELO command must either be a FQDN or a properly formatted address literal. The following are valid: HELO a.b.uk HELO 163.com HELO a-b.be HELO [1.2.3.4] HELO 1.2.3.4.us The following are invalid: HELO localhost HELO [1.2.3.256] HELO a-.com HELO a.uk. HELO 1.2.3.4 This is a limited implementation of RFC2821; paragraphs 4.1.1.1 & 4.1.3. Both IPv4 and IPv6 address literals are supported, but IPv6 are not fully validated. Passing the argument 'checkip' in addition to 'rfc' will check that the IPv4 address given in an address literal matches the IP address of the connection. =head2 Delaying failure If the argument 'delay' is passed to the plugin then any denial will be delayed until the RCPT TO stage. This allows the logging of MAIL FROM and RCPT TO on any connections that you have chosen to fail. =cut use constant SPAMHELO_RFCFAIL => 1; use constant SPAMHELO_MATCHFAIL => 2; sub register { my ($self, $qp, @args) = @_; $self->register_hook("helo", "check_helo");
Re: newer check_spamhelo (was Re: RFC: new check_spamhelo)
On Sun, 13 Jun 2004, Keith C. Ivey wrote: > Mark Powell <[EMAIL PROTECTED]> wrote: > > > Attached is a newer version of the plugin. Each line in badhelo is a > > regexp. If the regexp is enclosed in '/' chars then it is used as is, > > giving total freedom, otherwise an implied prefix of '^' and a post-fix of > > '.?$' are added before processing. It seems that most patterns will > > require that. > > I don't understand when you would want the '.?$' suffix. What > sort of strings are you talking about? It would seem more > straightforward just to require an exact match (except maybe > for case) if the line isn't enclosed in slashes. My finger trouble. I meant '\.?$'. The argument is supposed to be a FQDN, so it may end with a dot char. Thus any pattern you match, must match the same with and without a dot at the end. Cheers. -- Mark Powell - UNIX System Administrator - The University of Salford Information Services Division, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 4837 Fax: +44 161 295 5888 www.pgp.com for PGP key
Re: newer check_spamhelo (was Re: RFC: new check_spamhelo)
Mark Powell <[EMAIL PROTECTED]> wrote: > Attached is a newer version of the plugin. Each line in badhelo is a > regexp. If the regexp is enclosed in '/' chars then it is used as is, > giving total freedom, otherwise an implied prefix of '^' and a post-fix of > '.?$' are added before processing. It seems that most patterns will > require that. I don't understand when you would want the '.?$' suffix. What sort of strings are you talking about? It would seem more straightforward just to require an exact match (except maybe for case) if the line isn't enclosed in slashes. -- Keith C. Ivey <[EMAIL PROTECTED]> Washington, DC
newer check_spamhelo (was Re: RFC: new check_spamhelo)
On Sun, 13 Jun 2004, Matt Sergeant wrote: > I do a lot of regexp matching from my custom HELO plugin here. There's > no escaping to be done - this is all I do: > >foreach my $re ($self->qp->config('bad_helo_re')) { >if ($hello =~ /^$re/i) { >$self->log(LOGDEBUG, "HELO $hello is bad ($re)"); >$conn->notes('bad_helo', 'bad_helo_re'); What is the above line for? >return 1; >} >} Of course, you guys are right. It makes much more sense to just use regexp. I took out the extra code and just made it use regexps all the time. Attached is a newer version of the plugin. Each line in badhelo is a regexp. If the regexp is enclosed in '/' chars then it is used as is, giving total freedom, otherwise an implied prefix of '^' and a post-fix of '.?$' are added before processing. It seems that most patterns will require that. Although I've not used many patterns as just turning the RFC checking on drops lots of connections :) It also now supports IPv6 address literals from a regexp by Mark Cranness, but they are not fully validated. Cheers. -- Mark Powell - UNIX System Administrator - The University of Salford Information Services Division, Clifford Whitworth Building, Salford University, Manchester, M5 4WT, UK. Tel: +44 161 295 4837 Fax: +44 161 295 5888 www.pgp.com for PGP key# NB all regexps will have '^' prepended and '\.?$' appended unless enclosed in '/' chars # these domains never uses their domain when greeting us, so reject transactions aol\.com yahoo\.com # Block helos pretending to be in our domain #.*example\.com # Block helos pretending to be on our net. NB using RFC checking would already drop these #/^1\.2\.\d+\.\d+$/ # Some more regexps to catch out other baddies #.*\.prod-infinitum\.com\.mx #[A-Z0-9]{8}\.ipt\.aol\.com =head1 NAME check_spamhelo - Check a HELO argument delivered from a connecting host. =head1 DESCRIPTION Check a HELO argument delivered from a connecting host. Reject any that are matched by a regexp in the badhelo config -- e.g. yahoo\.com and aol\.com, which neither the real Yahoo or the real AOL use, but which spammers use rather a lot. Can also provide some limited RFC2821 enforcement. =head1 CONFIGURATION =head2 Regexp HELO argument matching Add regexp patterns to the F configuration file; one per line. All patterns will have an implied prefix of '^' and a post-fix of '\.?$' unless it is enclosed in '/' chars. In that case the regexp is used as is. Any pattern that matches a HELO argument will cause the SMTP conversation to be rejected. =head2 RELAYCLIENT support If RELAYCLIENT is set then this plugin will perform no checking at all. This allows pre-approved sites to use any or no argument to HELO. The RELAYCLIENT check can be disabled by passing the plugin the arg 'checkrc', in which case all HELOs will be checked. This provided primarliy for testing. You should be using tcpserver to determine which IP addresses get RELAYCLIENT set. =head2 RFC2821 enforcement If the argument 'rfc' is given to the plugin then some limited enforcement of RFC2821 requirements are performed. In that case the argument to the HELO command must either be a FQDN or a properly formatted address literal. The following are valid: HELO a.b.uk HELO [1.2.3.4] HELO 1.2.3.4.us. The following are invalid: HELO localhost HELO [1.2.3.256] HELO a.b HELO 1.2.3.4 This is a limited implementation of RFC2821; paragraphs 4.1.1.1 & 4.1.3. Both IPv4 and IPv6 address literals are supported, but IPv6 are not fully validated. =head2 Delaying failure If the argument 'delay' is passed to the plugin then any denial will be delayed until the RCPT TO stage. This allows the logging of MAIL FROM and RCPT TO on any connections that you have chosen to fail. =cut use constant SPAMHELO_RFCFAIL => 1; use constant SPAMHELO_MATCHFAIL => 2; sub register { my ($self, $qp, @args) = @_; $self->register_hook("helo", "check_helo"); $self->register_hook("ehlo", "check_helo"); $self->{_spamhelo_rfc} = 0; $self->{_spamhelo_delayfailure} = 0; $self->{_spamhelo_checkrc} = 0; $self->{_spamhelo_badhelo} = 0; while (@args) { my $arg = shift @args; $self->{_spamhelo_rfc} = 1, next if ($arg eq 'rfc'); $self->{_spamhelo_delayfailure} = 1, next if ($arg eq 'delay'); $self->{_spamhelo_checkrc} = 1, next if ($arg eq 'checkrc'); } $self->register_hook("rcpt", "rcpt_handler") if $self->{_spamhelo_delayfailure}; } sub check_helo { my ($self, $transaction, $hello) = @_; return (DECLINED) if !$self->{_spamhelo_checkrc} && exists $ENV{RELAYCLIENT}; #$hello !~ /^(\..*[a-z]{2}\.?|\[(((?(?{_spamhelo_rfc} && $hello !~ /^\[(((?(?{_spamhelo_delayfailure}) { $self->{_spamhelo_badhelo} = SPAMHELO_RFCFAIL; $self->{_spamhelo_hello} = $hello; return DECLINED; } else { $self->log(LOGDEBUG, rfc_fail_log_mes($hello)); return (DENY, rfc_fail_con_mes($hello)); } } # perf