5.7. Whitelisting & blacklisting

Whitelisting is a process which allows mail which would otherwise have been rejected to be accepted for delivery.

As documented each incoming message would have a rejected note stored in its transaction object if it were judged to be SPAM. This made the process of whitelisting very straightfoward, as removing the note would be sufficient to reverse the "SPAM" decision.

The actual whitelisting process only had to cover two cases:

In short the whitelisting process was just another plugin for qpsmtpd, it was only special in the sense that it ran immediately before the reject or queue actions - so that it could override any previous bad decisions.

The code beind the whitelist plugin was very simple, and could be summerized as follows:

Example 5-4. A simple whitelisting plugin

=begin doc

  Remove the "rejected" note if the sender, or sending IP is whitelisted.

=end doc

=cut

sub hook_data_post
{
    my ( $self, $transaction ) = (@_);

    #
    #  If the mail is not to be rejected then we'll terminate
    # without doing any work.
    #
    if ( ( $transaction->notes("rejected") || 0 ) == 0 )
    {
        return DECLINED;
    }


    #
    # Get the domain this mail is for.
    #
    my $domain = $transaction->notes("domain") || undef;
    return DECLINED unless ( defined($domain) );



    #
    # Get the sending IP address, and whitelist if present.
    #
    my $remote_ip = $self->qp->connection->remote_ip;

    if ( -e "/srv/$domain/whitelisted/ips/$remote_ip" )
    {

        #
        #  OK this was from a whitelisted IP, remove the note.
        #
        $transaction->notes( "rejected", 0 );
        $transaction->notes( "reason", 0 );
        return DECLINED;
    }


    #
    # Get the sender address, stripping brackets if present
    #
    my $sender = $transaction->notes("MAIL-FROM");
    $sender =~ s/^<//g;
    $sender =~ s/>$//g;

    #
    #  Is the sender whitelisted?
    #
    if ( -e "/srv/$domain/whitelisted/senders/$sender" )
    {

        #
        #  OK this was from a whitelisted sender, remove the note.
        #
        $transaction->notes( "rejected", 0 );
        $transaction->notes( "reason", 0 );
        return DECLINED;
    }

    # Message still rejected.
    return DECLINED;
}
1;

We also allowed per-domain blacklists. These would operate in an opposite fashion to the whitelist, and the discussion is largely the same: