mirror of
https://git.proxmox.com/git/proxmox-spamassassin
synced 2025-04-28 12:19:37 +00:00
139 lines
3.5 KiB
Perl
139 lines
3.5 KiB
Perl
package Mail::SpamAssassin::Spamd::Apache2::AclRFC1413;
|
|
use strict;
|
|
|
|
use Apache2::Const -compile => qw(OK FORBIDDEN SERVER_ERROR);
|
|
use Apache2::Connection ();
|
|
use Apache2::RequestUtil (); # RequestRec->new
|
|
use Apache2::RequestRec ();
|
|
use Apache2::Access (); # $r->get_remote_logname
|
|
|
|
use Apache::Test;
|
|
use constant APACHE24 => have_min_apache_version('2.4.0');
|
|
|
|
use APR::SockAddr (); # $c->remote_addr->...
|
|
use APR::Table (); # $c->notes
|
|
|
|
=head1 NAME
|
|
|
|
Mail::SpamAssassin::Spamd::Apache2::AclRFC1413 - check spamd's client ident
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
##### in httpd.conf:
|
|
# engine; module has been separated in Apache 2.1
|
|
LoadModule ident_module modules/mod_ident.so
|
|
IdentityCheck on
|
|
IdentityTimeout 4
|
|
|
|
# enable check
|
|
PerlLoadModule Mail::SpamAssassin::Spamd::Apache2::Config
|
|
SAident on
|
|
|
|
##### in PerlProcessConnectionHandler:
|
|
Mail::SpamAssassin::Spamd::Apache2::AclRFC1413::check_ident($c, "user")
|
|
or return Apache2::Const::FORBIDDEN;
|
|
|
|
# or like this:
|
|
my $remote_logname =
|
|
Mail::SpamAssassin::Spamd::Apache2::AclRFC1413::get_ident($c)
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Queries remote ident server using mod_ident.so, saves result in
|
|
C<$c-E<gt>notes()>.
|
|
|
|
Returns C<Apache2::Const::FORBIDDEN> on failure.
|
|
|
|
The C<SAident On> directive actually does this:
|
|
PerlPreConnectionHandler Mail::SpamAssassin::Spamd::Apache2::AclRFC1413
|
|
|
|
=head1 NOTE
|
|
|
|
Doing ident for non-localhost users is rather pointless. Unless you
|
|
know what you're doing, listen only on C<127.0.0.1> and/or C<::1>, if
|
|
you want to prevent users from lying about their identity. Or use SSL
|
|
with client certificates (refer to C<mod_ssl> documentation for details).
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=cut
|
|
|
|
sub handler {
|
|
my ($c) = @_;
|
|
|
|
# is there a point in doing ident for remote users?
|
|
#$c->remote_ip eq $c->local_ip
|
|
# or return Apache2::Const::FORBIDDEN;
|
|
|
|
my $r = Apache2::RequestRec->new($c)
|
|
or die 'Apache2::RequestRec->new($c) failed';
|
|
|
|
my $remote_user = $r->get_remote_logname;
|
|
|
|
unless (defined $remote_user && length $remote_user) {
|
|
warn 'rfc1413 check: failed to obtain info for '
|
|
. APACHE24 ? $c->client_addr->ip_get() : $c->remote_addr->ip_get() . ':'
|
|
. APACHE24 ? $c->client_addr->port() : $c->remote_addr->port() . "\n";
|
|
return Apache2::Const::FORBIDDEN;
|
|
}
|
|
|
|
my $notes = $c->notes # APR::Table
|
|
or die '$c->notes failed';
|
|
$notes->{remote_user} = $remote_user;
|
|
$c->notes($notes);
|
|
|
|
return Apache2::Const::OK;
|
|
}
|
|
|
|
=head2 check_ident($c, $username)
|
|
|
|
Returns remote username (might be "0"), as returned by the ident server, if it
|
|
matches supplied $username; undef otherwise.
|
|
|
|
=cut
|
|
|
|
sub check_ident {
|
|
my ($c, $user) = @_;
|
|
my $remote_user = $c->notes->{remote_user};
|
|
die "rfc1413 check: no query result for user=$user ip="
|
|
. APACHE24 ? $c->client_addr->ip_get() : $c->remote_addr->ip_get()
|
|
. ' port='
|
|
. APACHE24 ? $c->client_addr->port() : $c->remote_addr->port()
|
|
unless defined $remote_user && length $remote_user;
|
|
return $remote_user if $user eq $remote_user;
|
|
warn "ident mismatch for [$user] from "
|
|
. APACHE24 ? $c->client_addr->ip_get() : $c->remote_addr->ip_get() . ':'
|
|
. APACHE24 ? $c->client_addr->port() : $c->remote_addr->port()
|
|
. "; remote identd returned [$remote_user]\n";
|
|
0;
|
|
}
|
|
|
|
=head2 get_ident($c)
|
|
|
|
Returns remote username (might be "0"), as returned by the ident server.
|
|
|
|
=cut
|
|
|
|
sub get_ident {
|
|
my ($c) = @_;
|
|
$c->notes->{remote_user};
|
|
}
|
|
|
|
=head1 EXPORTS
|
|
|
|
Nothing.
|
|
|
|
=head1 BUGS
|
|
|
|
See E<lt>http://bugzilla.spamassassin.org/E<gt>
|
|
|
|
=head1 SEE ALSO
|
|
|
|
C<Mail::SpamAssassin::Spamd::Apache2::Config(3)>
|
|
|
|
=cut
|
|
|
|
1;
|
|
|
|
# vim: ts=8 sw=2 et
|