[svn:qpsmtpd] r715 - in contrib/hjp/require_resolvable_client: . config.sample plugins t t/plugin_tests
[email protected] Sat, 24 Feb 2007 12:46:39 -0800 (PST)
| Newsgroups | perl.cvs.qpsmtpd |
|---|---|
| Message-ID | <[email protected]> |
Author: hjp Date: Sat Feb 24 12:46:38 2007 New Revision: 715 Added: contrib/hjp/require_resolvable_client/config.sample/ contrib/hjp/require_resolvable_client/config.sample/plugins contrib/hjp/require_resolvable_client/plugins/ contrib/hjp/require_resolvable_client/plugins/require_resolvable_client contrib/hjp/require_resolvable_client/t/ contrib/hjp/require_resolvable_client/t/plugin_tests/ contrib/hjp/require_resolvable_client/t/plugin_tests/require_resolvable_client Removed: contrib/hjp/require_resolvable_client/require_resolvable_client Modified: contrib/hjp/require_resolvable_client/Makefile contrib/hjp/require_resolvable_client/Makerules contrib/hjp/require_resolvable_client/qpsmtpd-plugin-require_resolvable_client.spec Log: r249@hjp: Made forward lookup configurable (thanks to "m. allan noah" <[email protected]> for the suggestion and part of the patch). Also added some tests. Modified: contrib/hjp/require_resolvable_client/Makefile ============================================================================== --- contrib/hjp/require_resolvable_client/Makefile (original) +++ contrib/hjp/require_resolvable_client/Makefile Sat Feb 24 12:46:38 2007 @@ -2,12 +2,18 @@ FILES = $(PKG).spec \ Makefile \ Makerules \ - $(NAME) \ + plugins/$(NAME) \ + t/plugin_tests/$(NAME) \ + config.sample/plugins \ +TEST_LIB=~/wrk/qpsmtpd/trunk/t all: clean: rm -f $(PKG).tar.gz *.tmp +test: + perl -I $(TEST_LIB) t/01_basic.t + include Makerules Modified: contrib/hjp/require_resolvable_client/Makerules ============================================================================== --- contrib/hjp/require_resolvable_client/Makerules (original) +++ contrib/hjp/require_resolvable_client/Makerules Sat Feb 24 12:46:38 2007 @@ -8,7 +8,7 @@ cp -p $^ $@ rpm: $(PKG).tar.gz - rpm -ta --clean --sign --rmsource $^ + rpmbuild -ta --clean --sign --rmsource $^ $(PKG).tar.gz: $(FILES) tar cfz $@ $^ Added: contrib/hjp/require_resolvable_client/config.sample/plugins ============================================================================== --- (empty file) +++ contrib/hjp/require_resolvable_client/config.sample/plugins Sat Feb 24 12:46:38 2007 @@ -0,0 +1 @@ +require_resolvable_client Added: contrib/hjp/require_resolvable_client/plugins/require_resolvable_client ============================================================================== --- (empty file) +++ contrib/hjp/require_resolvable_client/plugins/require_resolvable_client Sat Feb 24 12:46:38 2007 @@ -0,0 +1,140 @@ +=head1 NAME + +require_resolvable_client + +=head1 DESCRIPTION + +Plugin to reject mails if the IP address of the client doesn't resolve +to a hostname. + +=head1 CONFIG + +The following parameters can be passed to require_resolvable_client: + +=over 4 + + +=item per_recipient <bool> + +Per recipient flag - if this is set, the plugin is only run for +recipients which have recipient_option 'require_resolvable_client' set. +This can be set by the aliases plugin. +Default: 0. + +=item at_connect <bool> + +If this flag is set, the temporary failure will be generated immediately +after the connect and the connection will be terminated. Otherwise, it +will be generated in response to RCPT TO commands. +Dropping the connection immediately saves resources and prevents address +harvesting. On the other hand, it cannot be (de)activated per recipient. +Default: 0 + +=item permfail <bool> + +If this flag is set, a permanent failure is reported. Otherwise it is +only a temporary failure, giving the admin of the client a chance to fix +the problem before the user notices it. +Default: 0 + +=item forward_lookup <bool> + +If this flag is set, an additional forward DNS check (hostname to IP) is +performed. Otherwise, only the reverse DNS check is performed. +Default: 1 + +=back + +=head1 NOTES + +This plugin makes use of the following connection notes: + +=over + +=item 'client_options'->{require_resolvable_client}{skip} + +If true, do nothing. This note is usually set by the +client_options plugin. + +=back + +and of the following transaction notes: + +=over + +=item 'recipient_options'->{require_resolvable_client} + +If true, per recipient checking is performed. This is only used if the +per_recipient flag is set. This note is usually set by the aliases +plugin. + +=back + +=head1 COPYRIGHT AND LICENSE + +Copyright (c) 2006 Peter J. Holzer <[email protected]>. + +This plugin is licensed under the same terms as the qpsmtpd package +itself. +Please see the LICENSE file included with qpsmtpd for details. + +=cut + + + +sub register { + my ($self, $qp, %arg) = @_; + $self->{_require_resolvable_client_per_recipient} = $arg{per_recipient}; + $self->{_require_resolvable_client_permfail} = $arg{permfail}; + $self->{_require_resolvable_client_forward_lookup} + = defined $arg{forward_lookup} ? $arg{forward_lookup} : 1; + if ($arg{at_connect}) { + $self->register_hook("connect", "handler"); + } else { + $self->register_hook("rcpt", "handler"); + } +} + +sub handler { + my ($self, $transaction) = @_; + + $self->log(LOGDEBUG, "in handler"); + if (my $co = $self->qp->connection->notes('client_options')) { + if ($co->{require_resolvable_client}{skip}) { + $self->log(LOGINFO, "client is whitelisted, skipping IP checks"); + return DECLINED + } + } + my $forward_lookup = $self->{_require_resolvable_client_forward_lookup}; + if ($self->{_require_resolvable_client_per_recipient}) { + my $ro = $transaction->notes('recipient_options'); + return DECLINED unless ($ro && $ro->{require_resolvable_client}); + $forward_lookup = $ro->{require_resolvable_client}{forward_lookup} + if (ref $ro->{require_resolvable_client} eq 'HASH' + && exists $ro->{require_resolvable_client}{forward_lookup}); + } + my $hostname = $self->connection->remote_host; + $self->log(LOGDEBUG, "hostname $hostname"); + if ($hostname eq "Unknown" || $hostname =~ m /^\[[\d.]+\]$/ || $hostname =~ m /^[\d.]+$/ ) { + $self->log(LOGINFO, "$hostname not a FQDN, returning failure"); + return $self->{_require_resolvable_client_permfail} ? DENY : DENYSOFT, + "Reverse lookup for " . $self->connection->remote_ip . " failed"; + } + + if (!$forward_lookup) { + $self->log(LOGDEBUG, "skipping forward lookup of $hostname against " . $self->connection->remote_ip); + return DECLINED; + } + + $self->log(LOGDEBUG, "checking addresses of $hostname against " . $self->connection->remote_ip); + my $ip = pack("C*", split(/\./, $self->connection->remote_ip)); + my ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($hostname); + for (@addrs) { + $self->log(LOGDEBUG, "checking address " . join(".", unpack("C4", $_))); + return DECLINED if ($ip eq $_); + } + $self->log(LOGINFO, "no address matches " . $self->connection->remote_ip . ", returning failure"); + return $self->{_require_resolvable_client_permfail} ? DENY : DENYSOFT, + "Host name " . $self->connection->remote_host . " doesn't match IP address " . $self->connection->remote_ip; +} + Modified: contrib/hjp/require_resolvable_client/qpsmtpd-plugin-require_resolvable_client.spec ============================================================================== --- contrib/hjp/require_resolvable_client/qpsmtpd-plugin-require_resolvable_client.spec (original) +++ contrib/hjp/require_resolvable_client/qpsmtpd-plugin-require_resolvable_client.spec Sat Feb 24 12:46:38 2007 @@ -1,5 +1,5 @@ Name: qpsmtpd-plugin-require_resolvable_client -Version: 199 +Version: 248 Release: 1 Packager: [email protected] Summary: require_resolvable_client plugin for qpsmtpd @@ -25,7 +25,7 @@ %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/share/qpsmtpd/plugins -cp require_resolvable_client $RPM_BUILD_ROOT/usr/share/qpsmtpd/plugins +cp plugins/require_resolvable_client $RPM_BUILD_ROOT/usr/share/qpsmtpd/plugins [ -x /usr/lib/rpm/brp-compress ] && /usr/lib/rpm/brp-compress @@ -35,6 +35,12 @@ /usr/share/qpsmtpd/plugins/require_resolvable_client %changelog +* Sat Feb 24 2007 <[email protected]> 248-1 +- r248: use rpmbuild instead of rpm. +- r247: Made forward lookup per-recipient configurable. +- r243: Patch by "m. allan noah" <[email protected]> to make forward + lookup optional. + * Fri Aug 11 2006 <[email protected]> 199-1 - First RPM package. Added: contrib/hjp/require_resolvable_client/t/plugin_tests/require_resolvable_client ============================================================================== --- (empty file) +++ contrib/hjp/require_resolvable_client/t/plugin_tests/require_resolvable_client Sat Feb 24 12:46:38 2007 @@ -0,0 +1,31 @@ +sub register_tests { + my ($self) = @_; + + $self->register_test("test", 5); +} + +sub test { + my ($self) = @_; + my $connection = $self->qp->connection; + $connection->remote_host('example.com'); + $connection->remote_ip('192.0.34.166'); + my ($code, @strings) = $self->handler(); + ok ($code == DECLINED, "example.com is 192.0.34.166"); + $connection->remote_ip('127.0.0.2'); + ($code, @strings) = $self->handler(); + ok ($code == DENYSOFT, "example.com isn't 127.0.0.2"); + $self->{_require_resolvable_client_forward_lookup} = 0; + ($code, @strings) = $self->handler(); + ok ($code == DECLINED, "skipping forward check works"); + + $self->{_require_resolvable_client_forward_lookup} = 1; + $self->{_require_resolvable_client_per_recipient} = 1; + my $transaction = $self->transaction(); + $transaction->notes('recipient_options', { require_resolvable_client => 1 }); + ($code, @strings) = $self->handler($transaction); + cmp_ok($code, '==', DENYSOFT, "example.com isn't 127.0.0.2"); + $transaction->notes('recipient_options', + { require_resolvable_client => { forward_lookup => 0 } }); + ($code, @strings) = $self->handler($transaction); + ok ($code == DECLINED, "skipping forward check works"); +}