the pre-connection and post-connection hooks are not working in
qpsmtpd-forkserver. This patch merges Peter's patch (with the possibilty to DENY/DENSOFT the connection) and my first attempt. The --max-from-ip check was moved from core to the hosts_allow plugin. Patch by: Hanno Hecker <hah@uu-x.de> git-svn-id: https://svn.perl.org/qpsmtpd/branches/0.3x@599 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
bfcd620a83
commit
c0920346e5
@ -6,6 +6,12 @@
|
|||||||
# plugins/http_config for details.
|
# plugins/http_config for details.
|
||||||
# http_config http://localhost/~smtpd/config/ http://www.example.com/smtp.pl?config=
|
# http_config http://localhost/~smtpd/config/ http://www.example.com/smtp.pl?config=
|
||||||
|
|
||||||
|
# The hosts_allow module must be loaded if you want the -m / --max-from-ip /
|
||||||
|
# my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
||||||
|
# settings... without this it will NOT refuse more than $MAXCONNIP connections
|
||||||
|
# from one IP!
|
||||||
|
hosts_allow
|
||||||
|
|
||||||
quit_fortune
|
quit_fortune
|
||||||
|
|
||||||
check_earlytalker
|
check_earlytalker
|
||||||
|
@ -84,6 +84,7 @@ sub disconnect {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->log(LOGDEBUG,"click, disconnecting");
|
$self->log(LOGDEBUG,"click, disconnecting");
|
||||||
$self->SUPER::disconnect(@_);
|
$self->SUPER::disconnect(@_);
|
||||||
|
$self->run_hooks("post-connection");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,23 +192,34 @@ while (1) {
|
|||||||
}
|
}
|
||||||
IO::Handle::blocking($client, 1);
|
IO::Handle::blocking($client, 1);
|
||||||
my ($port, $iaddr) = sockaddr_in($hisaddr);
|
my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||||
if ($MAXCONNIP) {
|
my $localsockaddr = getsockname($client);
|
||||||
my $num_conn = 1; # seed with current value
|
my ($lport, $laddr) = sockaddr_in($localsockaddr);
|
||||||
|
|
||||||
foreach my $rip (values %childstatus) {
|
my ($rc, @msg) = $qpsmtpd->run_hooks("pre-connection",
|
||||||
++$num_conn if (defined $rip && $rip eq $iaddr);
|
remote_ip => inet_ntoa($iaddr),
|
||||||
|
remote_port => $port,
|
||||||
|
local_ip => inet_ntoa($laddr),
|
||||||
|
local_port => $lport,
|
||||||
|
max_conn_ip => $MAXCONNIP,
|
||||||
|
child_addrs => [values %childstatus],
|
||||||
|
);
|
||||||
|
if ($rc == DENYSOFT || $rc == DENYSOFT_DISCONNECT) {
|
||||||
|
unless ($msg[0]) {
|
||||||
|
@msg = ("Sorry, try again later");
|
||||||
}
|
}
|
||||||
|
&respond_client($client, 451, @msg);
|
||||||
if ($num_conn > $MAXCONNIP) {
|
|
||||||
my $rem_ip = inet_ntoa($iaddr);
|
|
||||||
::log(LOGINFO,"Too many connections from $rem_ip: "
|
|
||||||
."$num_conn > $MAXCONNIP. Denying connection.");
|
|
||||||
$client->autoflush(1);
|
|
||||||
print $client "451 Sorry, too many connections from $rem_ip, try again later\r\n";
|
|
||||||
close $client;
|
close $client;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
elsif ($rc == DENY || $rc == DENY_DISCONNECT) {
|
||||||
|
unless ($msg[0]) {
|
||||||
|
@msg = ("Sorry, service not available for you");
|
||||||
}
|
}
|
||||||
|
&respond_client($client, 550, @msg);
|
||||||
|
close $client;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
my $pid = safe_fork();
|
my $pid = safe_fork();
|
||||||
if ($pid) {
|
if ($pid) {
|
||||||
# parent
|
# parent
|
||||||
@ -231,8 +242,6 @@ while (1) {
|
|||||||
::log(LOGINFO, "Connection Timed Out");
|
::log(LOGINFO, "Connection Timed Out");
|
||||||
exit; };
|
exit; };
|
||||||
|
|
||||||
my $localsockaddr = getsockname($client);
|
|
||||||
my ($lport, $laddr) = sockaddr_in($localsockaddr);
|
|
||||||
$ENV{TCPLOCALIP} = inet_ntoa($laddr);
|
$ENV{TCPLOCALIP} = inet_ntoa($laddr);
|
||||||
# my ($port, $iaddr) = sockaddr_in($hisaddr);
|
# my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||||
$ENV{TCPREMOTEIP} = inet_ntoa($iaddr);
|
$ENV{TCPREMOTEIP} = inet_ntoa($iaddr);
|
||||||
@ -256,6 +265,7 @@ while (1) {
|
|||||||
);
|
);
|
||||||
$qpsmtpd->run();
|
$qpsmtpd->run();
|
||||||
|
|
||||||
|
$qpsmtpd->run_hooks("post-connection");
|
||||||
exit; # child leaves
|
exit; # child leaves
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +275,18 @@ sub log {
|
|||||||
$qpsmtpd->log($level,$message);
|
$qpsmtpd->log($level,$message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub respond_client {
|
||||||
|
my ($client, $code, @message) = @_;
|
||||||
|
$client->autoflush(1);
|
||||||
|
while (my $msg = shift @message) {
|
||||||
|
my $line = $code . (@message?"-":" ").$msg;
|
||||||
|
::log(LOGDEBUG, $line);
|
||||||
|
print $client "$line\r\n"
|
||||||
|
or (::log(LOGERROR, "Could not print [$line]: $!"), return 0);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
### routine to protect process during fork
|
### routine to protect process during fork
|
||||||
sub safe_fork {
|
sub safe_fork {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user