qpsmtpd-plugins/qpsmtpd-plugins-bz10126.patch

228 lines
7.3 KiB
Diff
Raw Normal View History

diff -Nur qpsmtpd-plugins-openfusion-20050429.old/plugins/whitelist_soft qpsmtpd-plugins-openfusion-20050429/plugins/whitelist_soft
--- qpsmtpd-plugins-openfusion-20050429.old/plugins/whitelist_soft 2005-03-29 00:02:37.000000000 -0500
+++ qpsmtpd-plugins-openfusion-20050429/plugins/whitelist_soft 1969-12-31 19:00:00.000000000 -0500
@@ -1,223 +0,0 @@
-=head1 NAME
-
-whitelist_soft - whitelist override for other qpsmtpd plugins
-
-
-=head1 DESCRIPTION
-
-The whitelist_soft plugin allows selected hosts or senders or recipients
-to be whitelisted as exceptions to later plugin processing. It is a more
-conservative variant of Devin Carraway's 'whitelist' plugin.
-
-
-=head1 CONFIGURATION
-
-To enable the plugin, add it to the qpsmtpd/config/plugins file as usual.
-It should precede any plugins you might wish to whitelist for.
-
-Several configuration files are supported, corresponding to different
-parts of the SMTP conversation:
-
-=over 4
-
-=item whitelisthosts
-
-Any IP address (or start-anchored fragment thereof) listed in the
-whitelisthosts file is exempted from any further validation during
-'connect', and can be selectively exempted at other stages by
-plugins testing for a 'whitelisthost' connection note.
-
-Similarly, if the environment variable $WHITELISTCLIENT is set
-(which can be done by tcpserver), the connection will be exempt from
-further 'connect' validation, and the host can be selectively
-exempted by other plugins testing for a 'whitelistclient' connection
-note.
-
-=item whitelisthelo
-
-Any host that issues a HELO matching an entry in whitelisthelo will
-be exempted from further validation at the 'helo' stage. Subsequent
-plugins can test for a 'whitelisthelo' connection note. Note that
-this does not actually amount to an authentication in any meaningful
-sense.
-
-=item whitelistsenders
-
-If the envelope sender of a mail (that which is sent as the MAIL FROM)
-matches an entry in whitelistsenders, or if the hostname component
-matches, the mail will be exempted from any further validation within
-the 'mail' stage. Subsequent plugins can test for this exemption as a
-'whitelistsender' transaction note.
-
-=item whitelistrcpt
-
-If any recipient of a mail (that sent as the RCPT TO) matches an
-entry from whitelistrcpt, or if the hostname component matches, no
-further validation will be required for this recipient. Subsequent
-plugins can test for this exemption using a 'whitelistrcpt'
-transaction note, which holds the count of whitelisted recipients.
-
-=back
-
-whitelist_soft also supports per-recipient whitelisting when using
-the per_user_config plugin. To enable the per-recipient behaviour
-(delaying all whitelisting until the rcpt part of the smtp
-conversation, and using per-recipient whitelist configs, if
-available), pass a true 'per_recipient' argument in the
-config/plugins invocation i.e.
-
- whitelist_soft per_recipient 1
-
-By default global and per-recipient whitelists are merged; to turn off
-the merge behaviour pass a false 'merge' argument in the config/plugins
-invocation i.e.
-
- whitelist_soft per_recipient 1 merge 0
-
-
-=head1 BUGS
-
-Whitelist lookups are all O(n) linear scans of configuration files, even
-though they're all associative lookups. Something should be done about
-this when CDB/DB/GDBM configs are supported.
-
-
-=head1 AUTHOR
-
-Based on the 'whitelist' plugin by Devin Carraway <qpsmtpd@devin.com>.
-
-Modified by Gavin Carr <gavin@openfusion.com.au> to not inherit
-whitelisting across hooks, but use per-hook whitelist notes instead.
-This is a more conservative approach e.g. whitelisting an IP will not
-automatically allow relaying from that IP.
-
-=cut
-
-my $VERSION = 0.02;
-
-# Default is to merge whitelists in per_recipient mode
-my %MERGE = ( merge => 1 );
-
-sub register {
- my ($self, $qp, %arg) = @_;
-
- $self->{_per_recipient} = 1 if $arg{per_recipient};
- $MERGE{merge} = $arg{merge} if defined $arg{merge};
-
- # Normal mode - whitelist per hook
- unless ($arg{per_recipient}) {
- $self->register_hook("connect", "check_host");
- $self->register_hook("helo", "check_helo");
- $self->register_hook("ehlo", "check_helo");
- $self->register_hook("mail", "check_sender");
- $self->register_hook("rcpt", "check_rcpt");
- }
- # Per recipient mode - defer all whitelisting to rcpt hook
- else {
- $self->register_hook("rcpt", "check_host");
- $self->register_hook("helo", "helo_helper");
- $self->register_hook("ehlo", "helo_helper");
- $self->register_hook("rcpt", "check_helo");
- $self->register_hook("rcpt", "check_sender");
- $self->register_hook("rcpt", "check_rcpt");
- }
-}
-
-sub check_host {
- my ($self, $transaction, $rcpt) = @_;
- my $ip = $self->qp->connection->remote_ip || return (DECLINED);
-
- # From tcpserver
- if (exists $ENV{WHITELISTCLIENT}) {
- $self->qp->connection->notes('whitelistclient', 1);
- $self->log(2,"host $ip is a whitelisted client");
- return OK;
- }
-
- my $config_arg = $self->{_per_recipient} ? { rcpt => $rcpt, %MERGE } : {};
- for my $h ($self->qp->config('whitelisthosts', $config_arg)) {
- if ($h eq $ip or $ip =~ /^\Q$h\E/) {
- $self->qp->connection->notes('whitelisthost', 1);
- $self->log(2,"host $ip is a whitelisted host");
- return OK;
- }
- }
- return DECLINED;
-}
-
-sub helo_helper {
- my ($self, $transaction, $helo) = @_;
- $self->{_whitelist_soft_helo} = $helo;
- return DECLINED;
-}
-
-sub check_helo {
- my ($self, $transaction, $helo) = @_;
-
- # If per_recipient will be rcpt hook, and helo actually rcpt
- my $config_arg = {};
- if ($self->{_per_recipient}) {
- $config_arg = { rcpt => $helo, %MERGE };
- $helo = $self->{_whitelist_soft_helo};
- }
-
- for my $h ($self->qp->config('whitelisthelo', $config_arg)) {
- if ($helo and lc $h eq lc $helo) {
- $self->qp->connection->notes('whitelisthelo', 1);
- $self->log(2,"helo host $helo in whitelisthelo");
- return OK;
- }
- }
- return DECLINED;
-}
-
-sub check_sender {
- my ($self, $transaction, $sender) = @_;
-
- # If per_recipient will be rcpt hook, and sender actually rcpt
- my $config_arg = {};
- if ($self->{_per_recipient}) {
- $config_arg = { rcpt => $sender, %MERGE };
- $sender = $transaction->sender;
- }
-
- return DECLINED if $sender->format eq '<>';
- my $addr = lc $sender->address or return DECLINED;
- my $host = lc $sender->host or return DECLINED;
-
- for my $h ($self->qp->config('whitelistsenders', $config_arg)) {
- next unless $h;
- $h = lc $h;
-
- if ($addr eq $h or $host eq $h) {
- $transaction->notes('whitelistsender', 1);
- $self->log(2,"envelope sender $addr in whitelistsenders");
- return OK;
- }
- }
- return DECLINED;
-}
-
-sub check_rcpt {
- my ($self, $transaction, $rcpt) = @_;
-
- my $addr = lc $rcpt->address or return DECLINED;
- my $host = lc $rcpt->host or return DECLINED;
-
- my $config_arg = $self->{_per_recipient} ? { rcpt => $rcpt, %MERGE } : {};
- for my $h ($self->qp->config('whitelistrcpt', $config_arg)) {
- next unless $h;
- $h = lc $h;
-
- if ($addr eq $h or $host eq $h) {
- my $note = $transaction->notes('whitelistrcpt');
- $transaction->notes('whitelistrcpt', ++$note);
- $self->log(2,"recipient $addr in whitelistrcpt");
- return OK;
- }
- }
- return DECLINED;
-}
-
-# arch-tag: 15a093f1-2960-4dbe-be72-584d7ff1d92a
-