qpsmtpd/plugins/skip_plugins
Hanno Hecker 39a9271213 New "skip plugin API" + example plugin skip_plugins, see perldoc
Qpsmtpd::Plugins for more info. This can be used to disable (and re-
enable) loaded plugins for the current connection.


git-svn-id: https://svn.perl.org/qpsmtpd/branches/0.3x@700 958fd67b-6ff1-0310-b445-bb7760255be9
2006-12-31 11:07:32 +00:00

98 lines
2.9 KiB
Plaintext

=head1 NAME
skip_plugins - don't run selected plugins for some hosts
=head1 DESCRIPTION
The B<skip_plugins> plugin allows you to skip selected plugins for some
clients. This is similar to some whitelist plugins, without the need to
modify any plugin.
This plugin should be run before any other plugins hooking to the
I<hook_connect>. The config allows to run all plugins for one host in a
subnet and skip some for all other hosts in this network.
=head1 CONFIG
The config file I<skip_plugins> contains lines with two or three items per
line. The first field is a network/mask pair (or just a single IP address).
An action is set in the second field: currently B<continue> or B<skip> are
valid actions.
If a host matches a B<continue> line, the parsing is stopped and all
plugins are run for this host. A B<skip> action tells qpsmtpd to skip
the plugins listed in the third field for this connection.
The plugin list in the third field must be separated by "," without any spaces.
=head1 EXAMPLE
10.7.7.2 continue
10.7.7.0/24 skip spamassassin,check_earlytalker
To disable a plugin for all clients except for one subnet:
10.1.0.0/16 continue
0.0.0.0/0 skip virus/clamdscan
=head1 NOTES
See perldoc Qpsmtpd::Plugin for more about disabling / re-enabling plugins
for the current connection.
=head1 BUGS
This plugin does not have IPv6 support.
=cut
use Socket;
sub hook_connect {
my ($self,$transaction) = @_;
my %skip = ();
#my %l = $self->loaded_plugins;
#foreach my $p (keys %l) {
# $self->log(LOGDEBUG, "LOADED: $p");
#}
my $remote = $self->qp->connection->remote_ip;
foreach ($self->qp->config("skip_plugins")) {
chomp;
s/^\s*//;
s/\s*$//;
my ($ipmask, $action, $plugins) = split /\s+/, $_, 3;
next unless defined $action;
$action = lc $action;
$plugins = "" unless defined $plugins;
my ($net,$mask) = split '/', $ipmask, 2;
if (!defined $mask) {
$mask = 32;
}
$mask = pack "B32", "1"x($mask)."0"x(32-$mask);
if (join(".", unpack("C4", inet_aton($remote) & $mask)) eq $net) {
if ($action eq 'skip') {
foreach my $plugin (split /,/, $plugins) {
$self->plugin_disable($self->escape_plugin($plugin))
or $self->log(LOGWARN, "tried to disable a plugin "
."which was not loaded: $plugin");
}
$self->log(LOGDEBUG, "skipping plugins "
.join(",", $self->disabled_plugins));
}
elsif ($action eq 'continue') {
$self->log(LOGDEBUG, "ok, doing nothing with the plugins");
}
else {
$self->log(LOGWARN, "unknown action '$action' for $ipmask");
}
last;
}
}
return (DECLINED);
}
# vim: sw=4 ts=4 expandtab syn=perl