Re: How to get both sender and recipient address for mail-hook

[email protected] ("Chris Lewis")
Newsgroups perl.qpsmtpd
Organization Nortel
Message-ID <[email protected]>
On 1/11/2011 6:55 AM, Steve Freegard wrote:
> Hi Tapio,
>
> On 11 Jan 2011, at 11:34, Tapio Salonsaari wrote:

>> My web gui stores black / white lists into psql-database and the idea is
>> to do an SQL-search like:
>> SELECT * FROM blacklist WHERE sender="$senderdomain" AND
>> recipient="$recipientdomain";
>>
>> Then if the query returns any rows the plugin would return DENY. If
>> there's no rows on blacklist search the same for whitelist -table and
>> process the data accordingly.
>>
>> I'm using http://devin.com/qpsmtpd/whitelist as an base (don't know if
>> there's something more suitable to start with) and currently I'm stuck
>> with sub mail_handler, since I can't figure out how to pass both sender
>> and recipient addresses to function.
>>
>
> You can't do anything with the recipient addresses in the mail handler because they haven't been received yet!  In an SMTP transaction the recipients are sent after the MAIL command (see rfc5321).

The whitelist plugin he's using for has both mail from and rcpt to hooks 
(and helos), so as to do whitelisting in all three, and, you can access 
both mail from and rcpt to in the rcpt hook.  So, he could do the coding 
he wants in the rcpt hook.

However, I'm not sure why he needs both at the same time.  In order for 
his version of blacklisting or whitelisting to do anything, _both_ mail 
from and rcpt to have to be in the same list.

In other words, you can only say "A can't send mail to B" - you can't 
say "A can't send mail".

This isn't how you normally set up black/whitelists, and the usefulness 
would be minimal.

Normally, you'd do something like this (state would be a qpsmtpd note)

state=neutral
if receiver in whitelist
    state=whitelist
else if sender in whitelist
    state=whitelist
if state == neutral
    if sender in blacklist
        reject
    if receiver in blacklist
        reject

[You wouldn't normally have blacklists on receivers]

Or, more simply, do each in separate plugins and remember state.

All of my filter/don't filter plugins merely set state (neutral, allow, 
reject) in a note.  Filtering plugins return OK if the state is allow or 
reject, and only apply filtering heuristics if the state is neutral.

Then your subsequent plugins would check state before applying _their_ 
filtering.

As a FYI, the whitelist plugin is rather suboptimal.  It linear-searches 
thru the list of hash keys for a match on host or full address so it can 
do regexps against the keys (to catch domain-wide listings) in addition 
to exact matches on full addresses.

The better way is to load _both_ the domain and email address as 
separate items into the hash.  Then you can do direct hash lookups 
without scanning.

I do mine somewhat differently:

I do my analogous from/to whitelist and blacklist lookups in separate 
plugins - whitelist on MAILFROM, blacklist on MAILFROM, whitelist on 
From: and whitelist on RCPTTO (filter bypass).  Each has a separate flat 
file.

The files are maintained in a postgresql database with a web front end. 
  When it's ready to publish the config, the postgresql dumps to the 
file, and rsyncs it to the qpsmtpds (note the plural).

The flat files are turned into an alternating regexp.  Eg: something 
like this as a blacklist:

[email protected]
[email protected]
/.*\@foo\.com/

[The first two are non-regexp exact matches, the latter is full regexp]

gets turned into:

... notes('blacklistfrom', '(foo\@bar\.com|baf\@bar\.com|.*\@foo\.com)')

[I don't use hashes as I described above, because I really do want full 
regexps on it, and not constrain myself to full addresses or domains 
only.  For example, I can do thing like /\d+\@.*/ if I want to block all 
numeric LHSes.]

[I have a library routine to do the conversion - most of my filtering 
plugins use it.]

which I test in the plugin with something like:

$pat = ... notes('blacklistfrom')
if (from =~ /^$pat$/) {
     ...
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.