in lib/Mail/SpamAssassin/Plugin/DCC.pm [127:422]
sub set_config {
my($self, $conf) = @_;
my @cmds;
=head1 USER SETTINGS
=over 4
=item use_dcc (0|1) (default: 1)
Whether to use DCC, if it is available.
=cut
push(@cmds, {
setting => 'use_dcc',
default => 1,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
});
=item use_dcc_rep (0|1) (default: 1)
Whether to use the commercial DCC Reputation feature, if it is available.
Note that reputation data is free for all starting from DCC 2.x version,
where it's automatically used.
=cut
push(@cmds, {
setting => 'use_dcc_rep',
default => 1,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
});
=item dcc_body_max NUMBER
=item dcc_fuz1_max NUMBER
=item dcc_fuz2_max NUMBER
Sets how often a message's body/fuz1/fuz2 checksum must have been reported
to the DCC server before SpamAssassin will consider the DCC check hit.
C<999999> is DCC's MANY count.
The default is C<999999> for all these options.
=item dcc_rep_percent NUMBER
Only the commercial DCC software provides DCC Reputations (but starting from
DCC 2.x version it is available for all). A DCC Reputation is the
percentage of bulk mail received from the last untrusted relay in the path
taken by a mail message as measured by all commercial DCC installations.
See http://www.rhyolite.com/dcc/reputations.html You C<must> whitelist your
trusted relays or MX servers with MX or MXDCC lines in /var/dcc/whiteclnt as
described in the main DCC man page to avoid seeing your own MX servers as
sources of bulk mail. See
https://www.dcc-servers.net/dcc/dcc-tree/dcc.html#White-and-Blacklists The
default is C<90>.
=cut
push (@cmds, {
setting => 'dcc_body_max',
default => 999999,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC
},
{
setting => 'dcc_fuz1_max',
default => 999999,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC
},
{
setting => 'dcc_fuz2_max',
default => 999999,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC
},
{
setting => 'dcc_rep_percent',
default => 90,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC
});
=back
=head1 ADMINISTRATOR SETTINGS
=over 4
=item dcc_timeout n (default: 5)
How many seconds you wait for DCC to complete, before scanning continues
without the DCC results. A numeric value is optionally suffixed by a
time unit (s, m, h, d, w, indicating seconds (default), minutes, hours,
days, weeks).
=cut
push (@cmds, {
setting => 'dcc_timeout',
is_admin => 1,
default => 5,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATION,
});
=item dcc_home STRING
This option tells SpamAssassin where to find the dcc homedir.
If not specified, try to use the locally configured directory
from the C<cdcc homedir> command.
Try /var/dcc if that command fails.
=cut
push (@cmds, {
setting => 'dcc_home',
is_admin => 1,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
code => sub {
my ($self, $key, $value, $line) = @_;
if (!defined $value || $value eq '') {
return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
}
$value = untaint_file_path($value);
my $stat_errn = stat($value) ? 0 : 0+$!;
if ($stat_errn != 0 || !-d _) {
my $msg = $stat_errn == ENOENT ? "does not exist"
: !-d _ ? "is not a directory" : "not accessible: $!";
info("config: dcc_home \"$value\" $msg");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$self->{dcc_home} = $value;
}
});
=item dcc_dccifd_path STRING
This option tells SpamAssassin where to find the dccifd socket instead
of a local Unix socket named C<dccifd> in the C<dcc_home> directory.
If a socket is specified or found, use it instead of C<dccproc>.
If specified, C<dcc_dccifd_path> is the absolute path of local Unix socket
or an INET socket specified as C<[Host]:Port> or C<Host:Port>.
Host can be an IPv4 or IPv6 address or a host name
Port is a TCP port number. The brackets are required for an IPv6 address.
The default is C<undef>.
=cut
push (@cmds, {
setting => 'dcc_dccifd_path',
is_admin => 1,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
code => sub {
my ($self, $key, $value, $line) = @_;
if (!defined $value || $value eq '') {
return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
}
local($1,$2,$3);
if ($value =~ m{^ (?: \[ ([^\]]*) \] | ([^:]*) ) : ([^:]*) \z}sx) {
my $host = untaint_var(defined $1 ? $1 : $2);
my $port = untaint_var($3);
if (!$host) {
info("config: missing or bad host name in dcc_dccifd_path '$value'");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
if (!$port || $port !~ /^\d+\z/ || $port < 1 || $port > 65535) {
info("config: bad TCP port number in dcc_dccifd_path '$value'");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$self->{dcc_dccifd_host} = $host;
$self->{dcc_dccifd_port} = $port;
dbg("config: dcc_dccifd_path set to [%s]:%s", $host, $port);
} else {
# assume a unix socket
if ($value !~ m{^/}) {
info("config: dcc_dccifd_path '$value' is not an absolute path");
# return $Mail::SpamAssassin::Conf::INVALID_VALUE; # abort or accept?
}
$value = untaint_file_path($value);
$self->{dcc_dccifd_socket} = $value;
dbg("config: dcc_dccifd_path set to local socket %s", $value);
dbg("dcc: dcc_dccifd_path set to local socket %s", $value);
}
$self->{dcc_dccifd_path_raw} = $value;
}
});
=item dcc_path STRING
Where to find the C<dccproc> client program instead of relying on SpamAssassin
to find it in the current PATH or C<dcc_home/bin>. This must often be set,
because the current PATH is cleared by I<taint mode> in the Perl interpreter,
If a C<dccifd> socket is found in C<dcc_home> or specified explicitly
with C<dcc_dccifd_path>, use the C<dccifd(8)> interface instead of C<dccproc>.
The default is C<undef>.
=cut
push (@cmds, {
setting => 'dcc_path',
is_admin => 1,
default => undef,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
code => sub {
my ($self, $key, $value, $line) = @_;
if (!defined $value || $value eq '') {
return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
}
$value = untaint_file_path($value);
if (!-x $value) {
info("config: dcc_path '$value' is not executable");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$self->{dcc_path} = $value;
}
});
=item dcc_options options
Specify additional options to the dccproc(8) command. Only
characters in the range [0-9A-Za-z ,._/-] are allowed for security reasons.
The default is C<undef>.
=cut
push (@cmds, {
setting => 'dcc_options',
is_admin => 1,
default => undef,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
code => sub {
my ($self, $key, $value, $line) = @_;
if ($value !~ m{^([0-9A-Za-z ,._/-]+)$}) {
info("config: dcc_options '$value' contains impermissible characters");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$self->{dcc_options} = $1;
}
});
=item dccifd_options options
Specify additional options to send to the dccifd daemon with
the ASCII protocol described on the dccifd(8) man page.
Only characters in the range [0-9A-Za-z ,._/-] are allowed for security reasons.
The default is C<undef>.
=cut
push (@cmds, {
setting => 'dccifd_options',
is_admin => 1,
default => undef,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
code => sub {
my ($self, $key, $value, $line) = @_;
if ($value !~ m{^([0-9A-Za-z ,._/-]+)$}) {
info("config: dccifd_options '$value' contains impermissible characters");
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$self->{dccifd_options} = $1;
}
});
=item dcc_learn_score n (default: undef)
Report messages with total scores this much larger than the
SpamAssassin spam threshold to DCC as spam.
=back
=cut
push (@cmds, {
setting => 'dcc_learn_score',
is_admin => 1,
default => undef,
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC,
});
$conf->{parser}->register_commands(\@cmds);
}