Hi,
this is a patch against Michael's patch for version 2.43. It adds
the --proxy-user option to spamd. Any user in that list that can set
the user that spamd should use with the -u option to spamc. The idea
is borrowed from the Cyrus imapd.
If you have virtual users and want to let your MTA set the user,
this might be useful for you.
cu,
Jan
Michael Stenner wrote:
I've whipped up a little patch that enables ident-based authentication
for spamd/spamc. That is, spamd uses ident to verify that spamc is
really being run by the user it claims to be running on the behalf of.
I'm interested in comments on this code. Currently, it requires
Net::Ident (available from CPAN) but fails nicely (ie., loudly) when
it's not present AND --auth-ident is used. I used --auth-ident
anticipating that other authentication methods may be add later.
The patch provided here is for the current cvs version of spamd.raw,
but a backport to 2.43 is available here:
http://www.dulug.duke.edu/~mstenner/spamassassin/auth-ident/
-Michael
P.S. I intend to look into a unix-socket-based spamc/spamd connection
that would also allow user authentication. Preliminary poking around
suggests that will be much more difficult, so we'll see.
P.P.S. If the cross-posting is inappropriate here, just tell me which
way I should go :)
------------------------------------------------------------------------
--- spamd.raw.orig Sun Nov 10 17:14:42 2002
+++ spamd.raw Sun Nov 10 17:31:15 2002
@@ -54,7 +54,10 @@
);
# defaults
-my %opt = ('user-config' => 1);
+my %opt = (
+ 'user-config' => 1,
+ 'ident-timeout' => 5.0,
+ );
my @OLD_ARGV = @ARGV; # Getopt::Long tends to clear @ARGV
Getopt::Long::Configure ("bundling");
@@ -82,6 +85,8 @@
'paranoid!' => \$opt{'paranoid'}, 'P' => \$opt{'paranoid'},
'stop-at-threshold!' => \$opt{'stop-at-threshold'}, 'S' => \$opt{'stop-at-threshold'},
'helper-home-dir|H:s' => \$opt{'home_dir_for_helpers'},
+ 'auth-ident' => \$opt{'auth-ident'},
+ 'ident-timeout=f' => \$opt{'ident-timeout'},
# will be stripped in future release
'add-from!' => sub { warn "The --add-from option has been removed\n" },
@@ -102,6 +107,18 @@
set_allowed_ip('127.0.0.1');
}
+# ident-based spamc user authentication
+if ($opt{'auth-ident'}) {
+ eval { require Net::Ident };
+ if ($@) {
+ die "fatal: ident-based authentication requested, " .
+ "but Net::Ident is unavailable.\n";
+ } else {
+ $opt{'ident-timeout'} = undef if $opt{'ident-timeout'} >= 0.0;
+ import Net::Ident qw(ident_lookup);
+ }
+}
+
# This can be changed on the command line with the -s flag
my $log_facility = $opt{'syslog'} || 'mail';
@@ -389,6 +406,7 @@
if (/^User: (.*)\r\n/)
{
$current_user = $1;
+ auth_ident($current_user) if $opt{'auth-ident'};
if (!$opt{'user-config'})
{
if ($opt{'sql-config'}) {
@@ -578,6 +596,19 @@
exit &$coderef();
}
+sub auth_ident
+{
+ my $username = shift;
+ my $ident_username = ident_lookup(\*STDIN, $opt{'ident-timeout'});
+ my $dn = $ident_username || 'NONE'; # display name
+ warn "ident_username = $dn, spamc_username = $username\n" if $opt{'debug'};
+ if ($username ne $ident_username) {
+ logmsg "fatal: ident username ($dn) does not match " .
+ "spamc username ($username)";
+ exit 1;
+ }
+}
+
sub handle_user
{
my $username = shift;
@@ -867,6 +898,8 @@
-u username, --username=username Run as username
-v, --vpopmail Enable vpopmail config
-x, --nouser-config Disable user config files
+ --auth-ident Use ident to authenticate spamc user
+ --ident-timeout=timeout Timeout for ident connections
-A host,..., --allowed-ips=..,.. Limit ip addresses which can connect
-D, --debug Print debugging messages
-L, --local Use local tests only (no DNS)
@@ -1002,6 +1035,24 @@
Turn off(on) per-user config files. All users will just get the default
configuration.
+=item B<--auth-ident>
+
+Verify the username provided by spamc using ident. This is only
+useful if connections are only allowed from trusted hosts (because an
+identd that lies is trivial to create) and if spamc REALLY SHOULD be
+running as the user it represents. Connections are terminated
+immediately if authentication fails. In this case, spamc will pass
+the mail through unchecked. Failure to connect to an ident server,
+and response timeouts are considered authentication failures. This
+requires that Net::Ident be installed.
+
+=item B<--ident-timeout>=I<timeout>
+
+Wait at most I<timeout> seconds for a response to ident queries.
+Authentication that takes long that I<timeout> seconds will fail, and
+mail will not be processed. Setting this to 0.0 or less results in no
+timeout, which is STRONGLY discouraged. The default is 5 seconds.
+
=item B<-A> I<host,...>, B<--allowed-ips>=I<host,...>
Specify a list of authorized hosts or networks which can connect to this spamd
--- spamd.raw.orig Mon Nov 11 09:19:12 2002
+++ spamd.raw Mon Nov 11 09:19:16 2002
@@ -82,6 +82,7 @@
'helper-home-dir|H:s' => \$opt{'home_dir_for_helpers'},
'auth-ident' => \$opt{'auth-ident'},
'ident-timeout=f' => \$opt{'ident-timeout'},
+ 'proxy-user=s' => \$opt{'proxy-user'},
# will be stripped in future release
'add-from!' => sub { warn "The --add-from option has been removed\n" },
@@ -103,6 +104,7 @@
}
# ident-based spamc user authentication
+my %proxy_user = ();
if ($opt{'auth-ident'}) {
eval { require Net::Ident };
if ($@) {
@@ -111,6 +113,11 @@
} else {
$opt{'ident-timeout'} = undef if $opt{'ident-timeout'} >= 0.0;
import Net::Ident qw(ident_lookup);
+
+ if (@{opt{'proxy-user'}}) {
+ my @proxy_user_list = split /,/,join(',',@{opt{'proxy-user'}});
+ @proxy_user{@proxy_user_list} = "";
+ }
}
}
@@ -673,9 +680,14 @@
my $dn = $ident_username || 'NONE'; # display name
warn "ident_username = $dn, spamc_username = $username\n" if $opt{'debug'};
if ($username ne $ident_username) {
- logmsg "fatal: ident username ($dn) does not match " .
- "spamc username ($username)";
- exit 1;
+ if (exists $proxy_user{$ident_username}) {
+ warn "found $ident_username in proxy-user list - proxy for $username\n"
+if $opt{'debug'};
+ }
+ else {
+ logmsg "fatal: ident username ($dn) does not match " .
+ "spamc username ($username)";
+ exit 1;
+ }
}
}
@@ -937,6 +949,7 @@
-x, --nouser-config Disable user config files
--auth-ident Use ident to authenticate spamc user
--ident-timeout=timeout Timeout for ident connections
+ --proxy-user=user,... Users that can proxy for other users (require
+--auth-ident)
-A host,..., --allowed-ips=..,.. Limit ip addresses which can connect
-D, --debug Print debugging messages
-L, --local Use local tests only (no DNS)
@@ -1078,6 +1091,12 @@
Authentication that takes long that I<timeout> seconds will fail, and
mail will not be processed. Setting this to 0.0 or less results in no
timeout, which is STRONGLY discouraged. The default is 5 seconds.
+
+=item B<--proxy-user>=I<user,...>
+
+Users in that list are allowed to set the user with the B<-u> switch
+to spamc. You need to use B<--auth-ident>. This is mostly useful in
+a virtual user environment, where spamc is called from the MTA.
=item B<-A> I<host,...>, B<--allowed-ips>=I<host,...>