Author: msergeant
Date: Thu Mar 13 12:59:15 2008
New Revision: 857
Modified:
trunk/plugins/async/require_resolvable_fromhost
Log:
Fix to prevent denying mail from some otherwise valid hosts
Fix to prevent run_continuation being incorrectly called
(both Radu Greab)
Modified: trunk/plugins/async/require_resolvable_fromhost
==============================================================================
--- trunk/plugins/async/require_resolvable_fromhost (original)
+++ trunk/plugins/async/require_resolvable_fromhost Thu Mar 13 12:59:15 2008
@@ -37,8 +37,14 @@
return Qpsmtpd::DSN->addr_bad_from_system( DENYSOFT,
"FQDN required in the envelope sender" );
}
-
- $self->check_dns( $sender->host );
+
+ return DECLINED if $sender->host =~ m/^\[(\d{1,3}\.){3}\d{1,3}\]$/;
+
+ unless ($self->check_dns( $sender->host )) {
+ return Qpsmtpd::DSN->temp_resolver_failed(
+ "Could not resolve " . $sender->host );
+ }
+
return YIELD;
}
@@ -63,62 +69,77 @@
my ( $self, $host ) = @_;
my @host_answers;
- return if $host =~ m/^\[(\d{1,3}\.){3}\d{1,3}\]$/;
-
my $qp = $self->qp;
+ $qp->input_sock->pause_read;
my $a_records = [];
- my $num_queries = $has_ipv6 ? 2 : 1;
+ my $num_queries = $has_ipv6 ? 3 : 2; # queries in progress
+
ParaDNS->new(
callback => sub {
my $mx = shift;
return if $mx =~ /^[A-Z]+$/; # error
+
my $addr = $mx->[0];
+
$num_queries++;
ParaDNS->new(
callback => sub { push @$a_records, $_[0] if $_[0] !~
/^[A-Z]+$/; },
- finished => sub { $num_queries--; $self->finish_up($qp,
$a_records) unless $num_queries; },
+ finished => sub { $num_queries--; $self->finish_up($qp,
$a_records, $num_queries) },
host => $addr,
type => 'A',
);
+
if ($has_ipv6) {
$num_queries++;
ParaDNS->new(
callback => sub { push @$a_records, $_[0] if $_[0] !~
/^[A-Z]+$/; },
- finished => sub { $num_queries--; $self->finish_up($qp,
$a_records) unless $num_queries; },
+ finished => sub { $num_queries--; $self->finish_up($qp,
$a_records, $num_queries) },
host => $addr,
type => 'AAAA',
);
}
},
+ finished => sub { $num_queries--; $self->finish_up($qp, $a_records,
$num_queries) },
host => $host,
type => 'MX',
- );
+ ) or return;
ParaDNS->new(
callback => sub { push @$a_records, $_[0] if $_[0] !~ /^[A-Z]+$/; },
- finished => sub { $num_queries--; $self->finish_up($qp, $a_records)
unless $num_queries },
+ finished => sub { $num_queries--; $self->finish_up($qp, $a_records,
$num_queries) },
host => $host,
type => 'A',
- );
+ ) or return;
ParaDNS->new(
callback => sub { push @$a_records, $_[0] if $_[0] !~ /^[A-Z]+$/; },
- finished => sub { $num_queries--; $self->finish_up($qp, $a_records)
unless $num_queries },
+ finished => sub { $num_queries--; $self->finish_up($qp, $a_records,
$num_queries) },
host => $host,
type => 'AAAA',
- ) if $has_ipv6;
+ ) or return if $has_ipv6;
+
+ return 1;
}
sub finish_up {
- my ($self, $qp, $a_records) = @_;
-
+ my ($self, $qp, $a_records, $num_queries, $source) = @_;
+
+ return if defined $qp->transaction->notes('resolvable_fromhost');
+
foreach my $addr (@$a_records) {
if (is_valid($addr)) {
$qp->transaction->notes('resolvable_fromhost', 1);
- last;
+ $qp->input_sock->continue_read;
+ $qp->run_continuation;
+ return;
}
}
- $qp->run_continuation;
+ unless ($num_queries) {
+ # all queries returned no valid response
+ $qp->transaction->notes('resolvable_fromhost', 0);
+ $qp->input_sock->continue_read;
+ $qp->run_continuation;
+ }
}
sub is_valid {