~ubuntu-branches/ubuntu/utopic/spamassassin/utopic-updates

« back to all changes in this revision

Viewing changes to .pc/10_change_config_paths/lib/Mail/SpamAssassin/Conf.pm

  • Committer: Package Import Robot
  • Author(s): Noah Meyerhans
  • Date: 2014-02-14 22:45:15 UTC
  • mfrom: (0.8.1) (0.6.2) (5.1.22 sid)
  • Revision ID: package-import@ubuntu.com-20140214224515-z1es2twos8xh7n2y
Tags: 3.4.0-1
* New upstream version! (Closes: 738963, 738872, 738867)
* Scrub the environment when switching to the debian-spamd user in
  postinst and cron.daily. (Closes: 738951)
* Enhancements to postinst to better manage ownership of
  /var/lib/spamassassin, via Iain Lane <iain.lane@canonical.com>
  (Closes: 738974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
84
84
 
85
85
use Mail::SpamAssassin::Util;
86
86
use Mail::SpamAssassin::NetSet;
87
 
use Mail::SpamAssassin::Constants qw(:sa);
 
87
use Mail::SpamAssassin::Constants qw(:sa :ip);
88
88
use Mail::SpamAssassin::Conf::Parser;
89
89
use Mail::SpamAssassin::Logger;
90
90
use Mail::SpamAssassin::Util::TieOneStringHash;
92
92
use File::Spec;
93
93
 
94
94
use vars qw{
95
 
  @ISA $VERSION
 
95
  @ISA 
96
96
  $CONF_TYPE_STRING $CONF_TYPE_BOOL
97
97
  $CONF_TYPE_NUMERIC $CONF_TYPE_HASH_KEY_VALUE
98
98
  $CONF_TYPE_ADDRLIST $CONF_TYPE_TEMPLATE
99
99
  $CONF_TYPE_STRINGLIST $CONF_TYPE_IPADDRLIST
100
 
  $CONF_TYPE_NOARGS
101
 
  $INVALID_VALUE $MISSING_REQUIRED_VALUE
 
100
  $CONF_TYPE_DURATION $CONF_TYPE_NOARGS
 
101
  $MISSING_REQUIRED_VALUE $INVALID_VALUE $INVALID_HEADER_FIELD_NAME
102
102
  @MIGRATED_SETTINGS
103
103
  $COLLECT_REGRESSION_TESTS
104
104
 
131
131
                  "full_evals", "rawbody_tests", "rawbody_evals",
132
132
                  "rbl_evals", "meta_tests");
133
133
 
134
 
$VERSION = 'bogus';     # avoid CPAN.pm picking up version strings later
 
134
#Removed $VERSION per BUG 6422
 
135
#$VERSION = 'bogus';     # avoid CPAN.pm picking up version strings later
135
136
 
136
137
# these are variables instead of constants so that other classes can
137
138
# access them; if they're constants, they'd have to go in Constants.pm
145
146
$CONF_TYPE_NOARGS           =  7;
146
147
$CONF_TYPE_STRINGLIST       =  8;
147
148
$CONF_TYPE_IPADDRLIST       =  9;
148
 
$MISSING_REQUIRED_VALUE     = -99999999999999;
149
 
$INVALID_VALUE              = -99999999999998;
 
149
$CONF_TYPE_DURATION         = 10;
 
150
$MISSING_REQUIRED_VALUE     = '-99999999999999';  # string expected by parser
 
151
$INVALID_VALUE              = '-99999999999998';
 
152
$INVALID_HEADER_FIELD_NAME  = '-99999999999997';
150
153
 
151
154
# set to "1" by the test suite code, to record regression tests
152
155
# $Mail::SpamAssassin::Conf::COLLECT_REGRESSION_TESTS = 1;
183
186
 
184
187
  push (@cmds, {
185
188
    setting => 'required_score',
186
 
    aliases => ['required_hits'],       # backwards compat
 
189
    aliases => ['required_hits'],       # backward compatible
187
190
    default => 5,
188
191
    type => $CONF_TYPE_NUMERIC,
189
192
  });
295
298
 
296
299
Whitelist and blacklist addresses are now file-glob-style patterns, so
297
300
C<friend@somewhere.com>, C<*@isp.com>, or C<*.domain.net> will all work.
298
 
Specifically, C<*> and C<?> are allowed, but all other metacharacters are not.
299
 
Regular expressions are not used for security reasons.
 
301
Specifically, C<*> and C<?> are allowed, but all other metacharacters
 
302
are not. Regular expressions are not used for security reasons.
 
303
Matching is case-insensitive.
300
304
 
301
305
Multiple addresses per line, separated by spaces, is OK.  Multiple
302
 
C<whitelist_from> lines is also OK.
 
306
C<whitelist_from> lines are also OK.
303
307
 
304
308
The headers checked for whitelist addresses are as follows: if C<Resent-From>
305
309
is set, use that; otherwise check all addresses taken from the following
330
334
Used to override a default whitelist_from entry, so for example a distribution
331
335
whitelist_from can be overridden in a local.cf file, or an individual user can
332
336
override a whitelist_from entry in their own C<user_prefs> file.
333
 
The specified email address has to match exactly the address previously
334
 
used in a whitelist_from line.
 
337
The specified email address has to match exactly (although case-insensitively)
 
338
the address previously used in a whitelist_from line, which implies that a
 
339
wildcard only matches literally the same wildcard (not 'any' address).
335
340
 
336
341
e.g.
337
342
 
350
355
=item whitelist_from_rcvd addr@lists.sourceforge.net sourceforge.net
351
356
 
352
357
Works similarly to whitelist_from, except that in addition to matching
353
 
a sender address, a relay's rDNS name must match too for the whitelisting
354
 
rule to fire. The first parameter is an address to whitelist, and the
355
 
second is a string to match the relay's rDNS.
356
 
 
357
 
This string is matched against the reverse DNS lookup used during the handover
358
 
from the internet to your internal network's mail exchangers.  It can
359
 
either be the full hostname, or the domain component of that hostname.  In
360
 
other words, if the host that connected to your MX had an IP address that
361
 
mapped to 'sendinghost.spamassassin.org', you should specify
362
 
C<sendinghost.spamassassin.org> or just C<spamassassin.org> here.
363
 
 
364
 
Note that this requires that C<internal_networks> be correct.  For simple cases,
365
 
it will be, but for a complex network you may get better results by setting that
366
 
parameter.
 
358
a sender address, a relay's rDNS name or its IP address must match too
 
359
for the whitelisting rule to fire. The first parameter is a sender's e-mail
 
360
address to whitelist, and the second is a string to match the relay's rDNS,
 
361
or its IP address. Matching is case-insensitive.
 
362
 
 
363
This second parameter is matched against the TCP-info information field as
 
364
provided in a FROM clause of a trace information (i.e. the Received header
 
365
field, see RFC 5321). Only the Received header fields inserted by trusted
 
366
hosts are considered. This parameter can either be a full hostname, or the
 
367
domain component of that hostname, or an IP address in square brackets.
 
368
The reverse DNS lookup is done by a MTA, not by SpamAssassin.
 
369
 
 
370
In case of an IPv4 address in brackets, it may be truncated on classful
 
371
boundaries to cover whole subnets, e.g. C<[10.1.2.3]>, C<[10.1.2]>,
 
372
C<[10.1]>, C<[10]>.  CIDR notation is currently not supported, nor is
 
373
IPv6. The matching on IP address is mainly provided to cover rare cases
 
374
where whitelisting of a sending MTA is desired which does not have a
 
375
correct reverse DNS configured.
 
376
 
 
377
In other words, if the host that connected to your MX had an IP address
 
378
192.0.2.123 that mapped to 'sendinghost.example.org', you should specify
 
379
C<sendinghost.example.org>, or C<example.org>, or C<[192.0.2.123]> or
 
380
C<[192.0.2]> here.
 
381
 
 
382
Note that this requires that C<internal_networks> be correct.  For simple
 
383
cases, it will be, but for a complex network you may get better results
 
384
by setting that parameter.
367
385
 
368
386
It also requires that your mail exchangers be configured to perform DNS
369
387
reverse lookups on the connecting host's IP address, and to record the
370
 
result in the generated Received: header.
 
388
result in the generated Received header field according to RFC 5321.
371
389
 
372
390
e.g.
373
391
 
374
392
  whitelist_from_rcvd joe@example.com  example.com
375
393
  whitelist_from_rcvd *@axkit.org      sergeant.org
 
394
  whitelist_from_rcvd *@axkit.org      [192.0.2.123]
376
395
 
377
396
=item def_whitelist_from_rcvd addr@lists.sourceforge.net sourceforge.net
378
397
 
424
443
 
425
444
Whitelist and blacklist addresses are now file-glob-style patterns, so
426
445
C<friend@somewhere.com>, C<*@isp.com>, or C<*.domain.net> will all work.
427
 
Specifically, C<*> and C<?> are allowed, but all other metacharacters are not.
428
 
Regular expressions are not used for security reasons.
 
446
Specifically, C<*> and C<?> are allowed, but all other metacharacters
 
447
are not. Regular expressions are not used for security reasons.
 
448
Matching is case-insensitive.
429
449
 
430
450
Multiple addresses per line, separated by spaces, is OK.  Multiple
431
 
C<whitelist_allows_relays> lines is also OK.
 
451
C<whitelist_allows_relays> lines are also OK.
432
452
 
433
453
The specified email address does not have to match exactly the address
434
454
previously used in a whitelist_from_rcvd line as it is compared to the
641
661
    code => \&Mail::SpamAssassin::Conf::Parser::remove_addrlist_value
642
662
  });
643
663
 
 
664
 
 
665
=item enlist_uri_host (listname) host ...
 
666
 
 
667
Adds one or more host names or domain names to a named list of URI domains.
 
668
The named list can then be consulted through a check_uri_host_listed()
 
669
eval rule implemented by the WLBLEval plugin, which takes the list name as
 
670
an argument. Parenthesis around a list name are literal - a required syntax.
 
671
 
 
672
Host names may optionally be prefixed by an exclamantion mark '!', which
 
673
produces false as a result if this entry matches. This makes it easier
 
674
to exclude some subdomains when their superdomain is listed, for example:
 
675
 
 
676
  enlist_uri_host (MYLIST) !sub1.example.com !sub2.example.com example.com
 
677
 
 
678
No wildcards are supported, but subdomains do match implicitly. Lists
 
679
are independent. Search for each named list starts by looking up the
 
680
full hostname first, then leading fields are progressively stripped off
 
681
(e.g.: sub.example.com, example.com, com) until a match is found or we run
 
682
out of fields. The first matching entry (the most specific) determines if a
 
683
lookup yielded a true (no '!' prefix) or a false (with a '!' prefix) result.
 
684
 
 
685
If an URL found in a message contains an IP address in place of a host name,
 
686
the given list must specify the exact same IP address (instead of a host name)
 
687
in order to match.
 
688
 
 
689
Use the delist_uri_host directive to neutralize previous enlist_uri_host
 
690
settings.
 
691
 
 
692
Enlisting to lists named 'BLACK' and 'WHITE' have their shorthand directives
 
693
blacklist_uri_host and whitelist_uri_host and corresponding default rules,
 
694
but the names 'BLACK' and 'WHITE' are otherwise not special or reserved.
 
695
 
 
696
=cut
 
697
 
 
698
  push (@cmds, {
 
699
    command => 'enlist_uri_host',
 
700
    setting => 'uri_host_lists',
 
701
    type => $CONF_TYPE_ADDRLIST,
 
702
    code => sub {
 
703
      my($conf, $key, $value, $line) = @_;
 
704
      local($1,$2);
 
705
      if ($value !~ /^ \( (.*?) \) \s+ (.*) \z/sx) {
 
706
        return $MISSING_REQUIRED_VALUE;
 
707
      }
 
708
      my $listname = $1;  # corresponds to arg in check_uri_host_in_wblist()
 
709
      # note: must not factor out dereferencing, as otherwise
 
710
      # subhashes would spring up in a copy and be lost
 
711
      foreach my $host ( split(' ', lc $2) ) {
 
712
        my $v = $host =~ s/^!// ? 0 : 1;
 
713
        $conf->{uri_host_lists}{$listname}{$host} = $v;
 
714
      }
 
715
    }
 
716
  });
 
717
 
 
718
=item delist_uri_host [ (listname) ] host ...
 
719
 
 
720
Removes one or more specified host names from a named list of URI domains.
 
721
Removing an unlisted name is ignored (is not an error). Listname is optional,
 
722
if specified then just the named list is affected, otherwise hosts are
 
723
removed from all URI host lists created so far. Parenthesis around a list
 
724
name are a required syntax.
 
725
 
 
726
Note that directives in configuration files are processed in sequence,
 
727
the delist_uri_host only applies to previously listed entries and has
 
728
no effect on enlisted entries in yet-to-be-processed directives.
 
729
 
 
730
For convenience (similarity to the enlist_uri_host directive) hostnames
 
731
may be prefixed by a an exclamation mark, which is stripped off from each
 
732
name and has no meaning here.
 
733
 
 
734
=cut
 
735
 
 
736
  push (@cmds, {
 
737
    command => 'delist_uri_host',
 
738
    setting => 'uri_host_lists',
 
739
    type => $CONF_TYPE_ADDRLIST,
 
740
    code => sub {
 
741
      my($conf, $key, $value, $line) = @_;
 
742
      local($1,$2);
 
743
      if ($value !~ /^ (?: \( (.*?) \) \s+ )? (.*) \z/sx) {
 
744
        return $MISSING_REQUIRED_VALUE;
 
745
      }
 
746
      my @listnames = defined $1 ? $1 : keys %{$conf->{uri_host_lists}};
 
747
      my @args = split(' ', lc $2);
 
748
      foreach my $listname (@listnames) {
 
749
        foreach my $host (@args) {
 
750
          my $v = $host =~ s/^!// ? 0 : 1;
 
751
          delete $conf->{uri_host_lists}{$listname}{$host};
 
752
        }
 
753
      }
 
754
    }
 
755
  });
 
756
 
 
757
=item blacklist_uri_host host-or-domain ...
 
758
 
 
759
Is a shorthand for a directive:  enlist_uri_host (BLACK) host ...
 
760
 
 
761
Please see directives enlist_uri_host and delist_uri_host for details.
 
762
 
 
763
=cut
 
764
 
 
765
  push (@cmds, {
 
766
    command => 'blacklist_uri_host',
 
767
    setting => 'uri_host_lists',
 
768
    type => $CONF_TYPE_ADDRLIST,
 
769
    code => sub {
 
770
      my($conf, $key, $value, $line) = @_;
 
771
      foreach my $host ( split(' ', lc $value) ) {
 
772
        my $v = $host =~ s/^!// ? 0 : 1;
 
773
        $conf->{uri_host_lists}{'BLACK'}{$host} = $v;
 
774
      }
 
775
    }
 
776
  });
 
777
 
 
778
=item whitelist_uri_host host-or-domain ...
 
779
 
 
780
Is a shorthand for a directive:  enlist_uri_host (BLACK) host ...
 
781
 
 
782
Please see directives enlist_uri_host and delist_uri_host for details.
 
783
 
 
784
=cut
 
785
 
 
786
  push (@cmds, {
 
787
    command => 'whitelist_uri_host',
 
788
    setting => 'uri_host_lists',
 
789
    type => $CONF_TYPE_ADDRLIST,
 
790
    code => sub {
 
791
      my($conf, $key, $value, $line) = @_;
 
792
      foreach my $host ( split(' ', lc $value) ) {
 
793
        my $v = $host =~ s/^!// ? 0 : 1;
 
794
        $conf->{uri_host_lists}{'WHITE'}{$host} = $v;
 
795
      }
 
796
    }
 
797
  });
 
798
 
644
799
=back
645
800
 
646
801
=head2 BASIC MESSAGE TAGGING OPTIONS
972
1127
        unless (defined $value && $value !~ /^$/) {
973
1128
            return $MISSING_REQUIRED_VALUE;
974
1129
        }
975
 
        return undef if $value == 0;
 
1130
        return  if $value == 0;
976
1131
        return $INVALID_VALUE unless $value == 1;
977
1132
 
978
1133
        unless ($] > 5.008004) {
1004
1159
 
1005
1160
=over 4
1006
1161
 
1007
 
=item trusted_networks ip.add.re.ss[/mask] ...   (default: none)
 
1162
=item trusted_networks IPaddress[/masklen] ...   (default: none)
1008
1163
 
1009
1164
What networks or hosts are 'trusted' in your setup.  B<Trusted> in this case
1010
1165
means that relay hosts on these networks are considered to not be potentially
1019
1174
are not MXes or internal relays for your domain(s) they should B<only> be
1020
1175
specified in C<trusted_networks>.
1021
1176
 
1022
 
If a C</mask> is specified, it's considered a CIDR-style 'netmask', specified
1023
 
in bits.  If it is not specified, but less than 4 octets are specified with a
1024
 
trailing dot, that's considered a mask to allow all addresses in the remaining
1025
 
octets.  If a mask is not specified, and there is not trailing dot, then just
1026
 
the single IP address specified is used, as if the mask was C</32>.
1027
 
 
1028
 
If a network or host address is prefaced by a C<!> the network or host will be
1029
 
excluded (or included) in a first listed match fashion.
1030
 
 
1031
 
Note: 127/8 and ::1 are always included in trusted_networks, regardless of
1032
 
your config.
 
1177
The C<IPaddress> can be an IPv4 address (in a dot-quad form), or an IPv6
 
1178
address optionally enclosed in square brackets. Scoped link-local IPv6
 
1179
addresses are syntactically recognized but the interface scope is currently
 
1180
ignored (e.g. [fe80::1234%eth0] ) and should be avoided.
 
1181
 
 
1182
If a C</masklen> is specified, it is considered a CIDR-style 'netmask' length,
 
1183
specified in bits.  If it is not specified, but less than 4 octets of an IPv4
 
1184
address are specified with a trailing dot, an implied netmask length covers
 
1185
all addresses in remaining octets (i.e. implied masklen is /8 or /16 or /24).
 
1186
If masklen is not specified, and there is not trailing dot, then just a single
 
1187
IP address specified is used, as if the masklen were C</32> with an IPv4
 
1188
address, or C</128> in case of an IPv6 address.
 
1189
 
 
1190
If a network or host address is prefaced by a C<!> the matching network or
 
1191
host will be excluded from the list even if a less specific (shorter netmask
 
1192
length) subnet is later specified in the list. This allows a subset of
 
1193
a wider network to be exempt. In case of specifying overlapping subnets,
 
1194
specify more specific subnets first (tighter matching, i.e. with a longer
 
1195
netmask length), followed by less specific (shorter netmask length) subnets
 
1196
to get predictable results regarless of the search algorithm used - when
 
1197
Net::Patricia module is installed the search finds the tightest matching
 
1198
entry in the list, while a sequential search as used in absence of the
 
1199
module Net::Patricia will find the first matching entry in the list.
 
1200
 
 
1201
Note: 127.0.0.0/8 and ::1 are always included in trusted_networks, regardless
 
1202
of your config.
1033
1203
 
1034
1204
Examples:
1035
1205
 
1036
 
   trusted_networks 192.168/16            # all in 192.168.*.*
 
1206
   trusted_networks 192.168.0.0/16        # all in 192.168.*.*
 
1207
   trusted_networks 192.168.              # all in 192.168.*.*
1037
1208
   trusted_networks 212.17.35.15          # just that host
1038
1209
   trusted_networks !10.0.1.5 10.0.1/24   # all in 10.0.1.* but not 10.0.1.5
1039
 
   trusted_networks DEAD:BEEF::/32        # all in that ipv6 prefix
 
1210
   trusted_networks 2001:db8:1::1 !2001:db8:1::/64 2001:db8::/32
 
1211
     # 2001:db8::/32 and 2001:db8:1::1/128, except the rest of 2001:db8:1::/64
1040
1212
 
1041
1213
This operates additively, so a C<trusted_networks> line after another one
1042
1214
will append new entries to the list of trusted networks.  To clear out the
1087
1259
      unless (!defined $value || $value eq '') {
1088
1260
        return $INVALID_VALUE;
1089
1261
      }
1090
 
      $self->{trusted_networks} = $self->new_netset();
 
1262
      $self->{trusted_networks} = $self->new_netset('trusted_networks',1);
1091
1263
      $self->{trusted_networks_configured} = 0;
1092
1264
    }
1093
1265
  });
1094
1266
 
1095
 
=item internal_networks ip.add.re.ss[/mask] ...   (default: none)
 
1267
=item internal_networks IPaddress[/masklen] ...   (default: none)
1096
1268
 
1097
1269
What networks or hosts are 'internal' in your setup.   B<Internal> means
1098
1270
that relay hosts on these networks are considered to be MXes for your
1099
 
domain(s), or internal relays.  This uses the same format as
1100
 
C<trusted_networks>, above.
 
1271
domain(s), or internal relays.  This uses the same syntax as
 
1272
C<trusted_networks>, above - see there for details.
1101
1273
 
1102
1274
This value is used when checking 'dial-up' or dynamic IP address
1103
1275
blocklists, in order to detect direct-to-MX spamming.
1141
1313
      unless (!defined $value || $value eq '') {
1142
1314
        return $INVALID_VALUE;
1143
1315
      }
1144
 
      $self->{internal_networks} = $self->new_netset();
 
1316
      $self->{internal_networks} = $self->new_netset('internal_networks',1);
1145
1317
      $self->{internal_networks_configured} = 0;
1146
1318
    }
1147
1319
  });
1148
1320
 
1149
 
=item msa_networks ip.add.re.ss[/mask] ...   (default: none)
1150
 
 
1151
 
The networks or hosts which are acting as MSAs in your setup (but not also as
1152
 
MX relays).  B<MSA> means that the relay hosts on these networks accept mail
1153
 
from your own users and authenticates them appropriately.  These relays
1154
 
will never accept mail from hosts that aren't authenticated in some way.
1155
 
Examples of authentication include, IP lists, SMTP AUTH, POP-before-SMTP, etc.
 
1321
=item msa_networks IPaddress[/masklen] ...   (default: none)
 
1322
 
 
1323
The networks or hosts which are acting as MSAs in your setup (but not also
 
1324
as MX relays). This uses the same syntax as C<trusted_networks>, above - see
 
1325
there for details.
 
1326
 
 
1327
B<MSA> means that the relay hosts on these networks accept mail from your
 
1328
own users and authenticates them appropriately.  These relays will never
 
1329
accept mail from hosts that aren't authenticated in some way. Examples of
 
1330
authentication include, IP lists, SMTP AUTH, POP-before-SMTP, etc.
1156
1331
 
1157
1332
All relays found in the message headers after the MSA relay will take
1158
1333
on the same trusted and internal classifications as the MSA relay itself,
1194
1369
      unless (!defined $value || $value eq '') {
1195
1370
        return $INVALID_VALUE;
1196
1371
      }
1197
 
      $self->{msa_networks} = Mail::SpamAssassin::NetSet->new(); # not new_netset
 
1372
      $self->{msa_networks} =
 
1373
        $self->new_netset('msa_networks',0);  # no loopback IP
1198
1374
      $self->{msa_networks_configured} = 0;
1199
1375
    }
1200
1376
  });
1280
1456
    type => $CONF_TYPE_BOOL,
1281
1457
  });
1282
1458
 
1283
 
=item dns_available { yes | test[: name1 name2...] | no }   (default: test)
1284
 
 
1285
 
By default, SpamAssassin will query some default hosts on the internet to
1286
 
attempt to check if DNS is working or not. The problem is that it can
1287
 
introduce some delay if your network connection is down, and in some cases it
1288
 
can wrongly guess that DNS is unavailable because the test connections failed.
1289
 
SpamAssassin includes a default set of 13 servers, among which 3 are picked
1290
 
randomly.
1291
 
 
1292
 
You can however specify your own list by specifying
1293
 
 
1294
 
  dns_available test: domain1.tld domain2.tld domain3.tld
1295
 
 
1296
 
Please note, the DNS test queries for NS records.
 
1459
=item dns_available { yes | no | test[: domain1 domain2...] }   (default: yes)
 
1460
 
 
1461
Tells SpamAssassin whether DNS resolving is available or not. A value I<yes>
 
1462
indicates DNS resolving is available, a value I<no> indicates DNS resolving
 
1463
is not available - both of these values apply unconditionally and skip initial
 
1464
DNS tests, which can be slow or unreliable.
 
1465
 
 
1466
When the option value is a I<test> (with or without arguments), SpamAssassin
 
1467
will query some domain names on the internet during initialization, attempting
 
1468
to determine if DNS resolving is working or not. A space-separated list
 
1469
of domain names may be specified explicitly, or left to a built-in default
 
1470
of a dozen or so domain names. From an explicit or a default list a subset
 
1471
of three domain names is picked randomly for checking. The test queries for
 
1472
NS records of these domain: if at least one query returns a success then
 
1473
SpamAssassin considers DNS resolving as available, otherwise not.
 
1474
 
 
1475
The problem is that the test can introduce some startup delay if a network
 
1476
connection is down, and in some cases it can wrongly guess that DNS is
 
1477
unavailable because a test connection failed, what causes disabling several
 
1478
DNS-dependent tests.
 
1479
 
 
1480
Please note, the DNS test queries for NS records, so specify domain names,
 
1481
not host names.
 
1482
 
 
1483
Since version 3.4.0 of SpamAssassin a default setting for option
 
1484
I<dns_available> is I<yes>. A default in older versions was I<test>.
1297
1485
 
1298
1486
=cut
1299
1487
 
1300
1488
  push (@cmds, {
1301
1489
    setting => 'dns_available',
1302
 
    default => 'test',
 
1490
    default => 'yes',
1303
1491
    type => $CONF_TYPE_STRING,
1304
1492
    code => sub {
1305
1493
      my ($self, $key, $value, $line) = @_;
1306
 
      if ($value =~ /^test(?::\s+.+)?$/) {
 
1494
      if ($value =~ /^test(?::\s*\S.*)?$/) {
1307
1495
        $self->{dns_available} = $value;
1308
1496
      }
1309
1497
      elsif ($value =~ /^(?:yes|1)$/) {
1318
1506
    }
1319
1507
  });
1320
1508
 
 
1509
=item dns_server ip-addr-port  (default: entries provided by Net::DNS)
 
1510
 
 
1511
Specifies an IP address of a DNS server, and optionally its port number.
 
1512
The I<dns_server> directive may be specified multiple times, each entry
 
1513
adding to a list of available resolving name servers. The I<ip-addr-port>
 
1514
argument can either be an IPv4 or IPv6 address, optionally enclosed in
 
1515
brackets, and optionally followed by a colon and a port number. In absence
 
1516
of a port number a standard port number 53 is assumed. When an IPv6 address
 
1517
is specified along with a port number, the address B<must> be enclosed in
 
1518
brackets to avoid parsing ambiguity regarding a colon separator,
 
1519
 
 
1520
Examples :
 
1521
 dns_server 127.0.0.1
 
1522
 dns_server 127.0.0.1:53
 
1523
 dns_server [127.0.0.1]:53
 
1524
 dns_server [::1]:53
 
1525
 
 
1526
In absence of I<dns_server> directives, the list of name servers is provided
 
1527
by Net::DNS module, which typically obtains the list from /etc/resolv.conf,
 
1528
but this may be platform dependent. Please consult the Net::DNS::Resolver
 
1529
documentation for details.
 
1530
 
 
1531
=cut
 
1532
 
 
1533
  push (@cmds, {
 
1534
    setting => 'dns_server',
 
1535
    type => $CONF_TYPE_STRING,
 
1536
    code => sub {
 
1537
      my ($self, $key, $value, $line) = @_;
 
1538
      my($address,$port); local($1,$2,$3);
 
1539
      if ($value =~ /^(?: \[ ([^\]]*) \] | ([^:]*) ) : (\d+) \z/sx) {
 
1540
        $address = defined $1 ? $1 : $2;  $port = $3;
 
1541
      } elsif ($value =~ /^(?: \[ ([^\]]*) \] | ([0-9a-fA-F.:]+) ) \z/sx) {
 
1542
        $address = defined $1 ? $1 : $2;  $port = '53';
 
1543
      } else {
 
1544
        return $INVALID_VALUE;
 
1545
      }
 
1546
      my $IP_ADDRESS = IP_ADDRESS;
 
1547
      if ($address =~ /$IP_ADDRESS/ && $port >= 1 && $port <= 65535) {
 
1548
        $self->{dns_servers} = []  if !$self->{dns_servers};
 
1549
        # checked, untainted, stored in a normalized form
 
1550
        push(@{$self->{dns_servers}}, untaint_var("[$address]:$port"));
 
1551
      } else {
 
1552
        return $INVALID_VALUE;
 
1553
      }
 
1554
    }
 
1555
  });
 
1556
 
 
1557
=item clear_dns_servers
 
1558
 
 
1559
Empty the list of explicitly configured DNS servers through a I<dns_server>
 
1560
directive, falling back to Net::DNS -supplied defaults.
 
1561
 
 
1562
=cut
 
1563
 
 
1564
  push (@cmds, {
 
1565
    setting => 'clear_dns_servers',
 
1566
    type => $CONF_TYPE_NOARGS,
 
1567
    code => sub {
 
1568
      my ($self, $key, $value, $line) = @_;
 
1569
      unless (!defined $value || $value eq '') {
 
1570
        return $INVALID_VALUE;
 
1571
      }
 
1572
      undef $self->{dns_servers};
 
1573
    }
 
1574
  });
 
1575
 
 
1576
=item dns_local_ports_permit ranges...
 
1577
 
 
1578
Add the specified ports or ports ranges to the set of allowed port numbers
 
1579
that can be used as local port numbers when sending DNS queries to a resolver.
 
1580
 
 
1581
The argument is a whitespace-separated or a comma-separated list of
 
1582
single port numbers n, or port number pairs (i.e. m-n) delimited by a '-',
 
1583
representing a range. Allowed port numbers are between 1 and 65535.
 
1584
 
 
1585
Directives I<dns_local_ports_permit> and I<dns_local_ports_avoid> are processed
 
1586
in order in which they appear in configuration files. Each directive adds
 
1587
(or subtracts) its subsets of ports to a current set of available ports.
 
1588
Whatever is left in the set by the end of configuration processing
 
1589
is made available to a DNS resolving client code.
 
1590
 
 
1591
If the resulting set of port numbers is empty (see also the directive
 
1592
I<dns_local_ports_none>), then SpamAssassin does not apply its ports
 
1593
randomization logic, but instead leaves the operating system to choose
 
1594
a suitable free local port number.
 
1595
 
 
1596
The initial set consists of all port numbers in the range 1024-65535.
 
1597
Note that system config files already modify the set and remove all the
 
1598
IANA registered port numbers and some other ranges, so there is rarely
 
1599
a need to adjust the ranges by site-specific directives.
 
1600
 
 
1601
See also directives I<dns_local_ports_permit> and I<dns_local_ports_none>.
 
1602
 
 
1603
=cut
 
1604
 
 
1605
  push (@cmds, {
 
1606
    setting => 'dns_local_ports_permit',
 
1607
    type => $CONF_TYPE_STRING,
 
1608
    is_admin => 1,
 
1609
    code => sub {
 
1610
      my($self, $key, $value, $line) = @_;
 
1611
      my(@port_ranges); local($1,$2);
 
1612
      foreach my $range (split(/[ \t,]+/, $value)) {
 
1613
        if ($range =~ /^(\d{1,5})\z/) {
 
1614
          # don't allow adding a port number 0
 
1615
          if ($1 < 1 || $1 > 65535) { return $INVALID_VALUE }
 
1616
          push(@port_ranges, [$1,$1]);
 
1617
        } elsif ($range =~ /^(\d{1,5})-(\d{1,5})\z/) {
 
1618
          if ($1 < 1 || $1 > 65535) { return $INVALID_VALUE }
 
1619
          if ($2 < 1 || $2 > 65535) { return $INVALID_VALUE }
 
1620
          push(@port_ranges, [$1,$2]);
 
1621
        } else {
 
1622
          return $INVALID_VALUE;
 
1623
        }
 
1624
      }
 
1625
      foreach my $p (@port_ranges) {
 
1626
        undef $self->{dns_available_portscount};  # invalidate derived data
 
1627
        set_ports_range(\$self->{dns_available_ports_bitset},
 
1628
                        $p->[0], $p->[1], 1);
 
1629
      }
 
1630
    }
 
1631
  });
 
1632
 
 
1633
=item dns_local_ports_avoid ranges...
 
1634
 
 
1635
Remove specified ports or ports ranges from the set of allowed port numbers
 
1636
that can be used as local port numbers when sending DNS queries to a resolver.
 
1637
 
 
1638
Please see directive I<dns_local_ports_permit> for details.
 
1639
 
 
1640
=cut
 
1641
 
 
1642
  push (@cmds, {
 
1643
    setting => 'dns_local_ports_avoid',
 
1644
    type => $CONF_TYPE_STRING,
 
1645
    is_admin => 1,
 
1646
    code => sub {
 
1647
      my($self, $key, $value, $line) = @_;
 
1648
      my(@port_ranges); local($1,$2);
 
1649
      foreach my $range (split(/[ \t,]+/, $value)) {
 
1650
        if ($range =~ /^(\d{1,5})\z/) {
 
1651
          if ($1 > 65535) { return $INVALID_VALUE }
 
1652
          # don't mind clearing also the port number 0
 
1653
          push(@port_ranges, [$1,$1]);
 
1654
        } elsif ($range =~ /^(\d{1,5})-(\d{1,5})\z/) {
 
1655
          if ($1 > 65535 || $2 > 65535) { return $INVALID_VALUE }
 
1656
          push(@port_ranges, [$1,$2]);
 
1657
        } else {
 
1658
          return $INVALID_VALUE;
 
1659
        }
 
1660
      }
 
1661
      foreach my $p (@port_ranges) {
 
1662
        undef $self->{dns_available_portscount};  # invalidate derived data
 
1663
        set_ports_range(\$self->{dns_available_ports_bitset},
 
1664
                        $p->[0], $p->[1], 0);
 
1665
      }
 
1666
    }
 
1667
  });
 
1668
 
 
1669
=item dns_local_ports_none
 
1670
 
 
1671
Is a fast shorthand for:
 
1672
 
 
1673
  dns_local_ports_avoid 1-65535
 
1674
 
 
1675
leaving the set of available DNS query local port numbers empty. In all
 
1676
respects (apart from speed) it is equivalent to the shown directive, and can
 
1677
be freely mixed with I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
 
1678
 
 
1679
If the resulting set of port numbers is empty, then SpamAssassin does not
 
1680
apply its ports randomization logic, but instead leaves the operating system
 
1681
to choose a suitable free local port number.
 
1682
 
 
1683
See also directives I<dns_local_ports_permit> and I<dns_local_ports_avoid>.
 
1684
 
 
1685
=cut
 
1686
 
 
1687
  push (@cmds, {
 
1688
    setting => 'dns_local_ports_none',
 
1689
    type => $CONF_TYPE_NOARGS,
 
1690
    is_admin => 1,
 
1691
    code => sub {
 
1692
      my ($self, $key, $value, $line) = @_;
 
1693
      unless (!defined $value || $value eq '') {
 
1694
        return $INVALID_VALUE;
 
1695
      }
 
1696
      undef $self->{dns_available_portscount};  # invalidate derived data
 
1697
      wipe_ports_range(\$self->{dns_available_ports_bitset}, 0);
 
1698
    }
 
1699
  });
 
1700
 
1321
1701
=item dns_test_interval n   (default: 600 seconds)
1322
1702
 
1323
 
If dns_available is set to 'test' (which is the default), the dns_test_interval
1324
 
time in number of seconds will tell SpamAssassin how often to retest for working DNS.
 
1703
If dns_available is set to I<test>, the dns_test_interval time in number
 
1704
of seconds will tell SpamAssassin how often to retest for working DNS.
 
1705
A numeric value is optionally suffixed by a time unit (s, m, h, d, w,
 
1706
indicating seconds (default), minutes, hours, days, weeks).
1325
1707
 
1326
1708
=cut
1327
1709
 
1328
1710
  push (@cmds, {
1329
1711
    setting => 'dns_test_interval',
1330
1712
    default => 600,
1331
 
    type => $CONF_TYPE_NUMERIC,
1332
 
    code => sub {
1333
 
      my ($self, $key, $value, $line) = @_;
1334
 
      if ($value !~ /^\d+$/) { return $INVALID_VALUE; }
1335
 
      $self->{dns_test_interval} = $value;
1336
 
    }
 
1713
    type => $CONF_TYPE_DURATION,
1337
1714
  });
1338
1715
 
1339
 
=item dns_options rotate    (default: empty)
1340
 
 
1341
 
If set to 'rotate', this causes SpamAssassin to choose a DNS server at random
1342
 
from all servers listed in C</etc/resolv.conf> every 'dns_test_interval'
 
1716
=item dns_options opts   (default: norotate, nodns0x20, edns=4096)
 
1717
 
 
1718
Provides a (whitespace or comma -separated) list of options applying
 
1719
to DNS resolving. Available options are: I<rotate>, I<dns0x20> and
 
1720
I<edns> (or I<edns0>). Option name may be negated by prepending a I<no>
 
1721
(e.g. I<norotate>, I<NoEDNS>) to counteract a previously enabled option.
 
1722
Option names are not case-sensitive. The I<dns_options> directive may
 
1723
appear in configuration files multiple times, the last setting prevails.
 
1724
 
 
1725
Option I<edns> (or I<edsn0>) may take a value which specifies a requestor's
 
1726
acceptable UDP payload size according to EDNS0 specifications (RFC 6891,
 
1727
ex RFC 2671) e.g. I<edns=4096>. When EDNS0 is off (I<noedns> or I<edns=512>)
 
1728
a traditional implied UDP payload size is 512 bytes, which is also a minimum
 
1729
allowed value for this option. When the option is specified but a value
 
1730
is not provided, a conservative default of 1220 bytes is implied. It is
 
1731
recommended to keep I<edns> enabled when using a local recursive DNS server
 
1732
which supports EDNS0 (like most modern DNS servers do), a suitable setting
 
1733
in this case is I<edns=4096>, which is also a default. Allowing UDP payload
 
1734
size larger than 512 bytes can avoid truncation of resource records in large
 
1735
DNS responses (like in TXT records of some SPF and DKIM responses, or when
 
1736
an unreasonable number of A records is published by some domain). The option
 
1737
should be disabled when a recursive DNS server is only reachable through
 
1738
non- RFC 6891 compliant middleboxes (such as some old-fashioned firewall)
 
1739
which bans DNS UDP payload sizes larger than 512 bytes. A suitable value
 
1740
when a non-local recursive DNS server is used and a middlebox B<does> allow
 
1741
EDNS0 but blocks fragmented IP packets is perhaps 1220 bytes, allowing a
 
1742
DNS UDP packet to fit within a single IP packet in most cases (a slightly
 
1743
less conservative range would be 1280-1410 bytes).
 
1744
 
 
1745
Option I<rotate> causes SpamAssassin to choose a DNS server at random
 
1746
from all servers listed in C</etc/resolv.conf> every I<dns_test_interval>
1343
1747
seconds, effectively spreading the load over all currently available DNS
1344
1748
servers when there are many spamd workers. 
1345
1749
 
 
1750
Option I<dns0x20> enables randomization of letters in a DNS query label
 
1751
according to draft-vixie-dnsext-dns0x20, decreasing a chance of collisions
 
1752
of responses (by chance or by a malicious intent) by increasing spread
 
1753
as provided by a 16-bit query ID and up to 16 bits of a port number,
 
1754
with additional bits as encoded by flipping case (upper/lower) of letters
 
1755
in a query. The number of additional random bits corresponds to the number
 
1756
of letters in a query label. Should work reliably with all mainstream
 
1757
DNS servers - do not turn on if you see frequent info messages
 
1758
"dns: no callback for id:" in the log, or if RBL or URIDNS lookups
 
1759
do not work for no apparent reason.
 
1760
 
1346
1761
=cut
1347
1762
 
1348
1763
  push (@cmds, {
1350
1765
    type => $CONF_TYPE_HASH_KEY_VALUE,
1351
1766
    code => sub {
1352
1767
      my ($self, $key, $value, $line) = @_;
1353
 
      my $allowed_opts = "rotate";
1354
 
      
1355
 
      foreach my $option (split (/\s+/, $value)) {
1356
 
        if ($allowed_opts !~ /^$option$/) { return $INVALID_VALUE; }
1357
 
        else { $self->{dns_options}->{$option} = 1; }
1358
 
      }
 
1768
      foreach my $option (split (/[\s,]+/, lc $value)) {
 
1769
        local($1,$2);
 
1770
        if ($option =~ /^no(rotate|dns0x20)\z/) {
 
1771
          $self->{dns_options}->{$1} = 0;
 
1772
        } elsif ($option =~ /^no(edns)0?\z/) {
 
1773
          $self->{dns_options}->{$1} = 0;
 
1774
        } elsif ($option =~ /^(rotate|dns0x20)\z/) {
 
1775
          $self->{dns_options}->{$1} = 1;
 
1776
        } elsif ($option =~ /^(edns)0? (?: = (\d+) )? \z/x) {
 
1777
          # RFC 6891 (ex RFC 2671) - EDNS0, value is a requestor's UDP payload
 
1778
          # size, defaults to some UDP packet size likely to fit into a single
 
1779
          # IP packet which is more likely to pass firewalls which choke on IP
 
1780
          # fragments.  RFC 2460: min MTU is 1280 for IPv6, minus 40 bytes for
 
1781
          # basic header, yielding 1240.  RFC 3226 prescribes a min of 1220 for
 
1782
          # RFC 2535 compliant servers.  RFC 6891: choosing between 1280 and
 
1783
          # 1410 bytes for IP (v4 or v6) over Ethernet would be reasonable.
 
1784
          # 
 
1785
          $self->{dns_options}->{$1} = $2 || 1220;
 
1786
          return $INVALID_VALUE  if $self->{dns_options}->{$1} < 512;
 
1787
        } else {
 
1788
          return $INVALID_VALUE;
 
1789
        }
 
1790
      }
 
1791
    }
 
1792
  });
 
1793
 
 
1794
=item dns_query_restriction (allow|deny) domain1 domain2 ...
 
1795
 
 
1796
Option allows disabling of rules which would result in a DNS query to one of
 
1797
the listed domains. The first argument must be a literal C<allow> or C<deny>,
 
1798
remaining arguments are domains names.
 
1799
 
 
1800
Most DNS queries (with some exceptions) are subject to dns_query_restriction.
 
1801
A domain to be queried is successively stripped-off of its leading labels
 
1802
(thus yielding a series of its parent domains), and on each iteration a
 
1803
check is made against an associative array generated by dns_query_restriction
 
1804
options. Search stops at the first match (i.e. the tightest match), and the
 
1805
matching entry with its C<allow> or C<deny> value then controls whether a
 
1806
DNS query is allowed to be launched.
 
1807
 
 
1808
If no match is found an implicit default is to allow a query. The purpose of
 
1809
an explicit C<allow> entry is to be able to override a previously configured
 
1810
C<deny> on the same domain or to override an entry (possibly yet to be
 
1811
configured in subsequent config directives) on one of its parent domains.
 
1812
Thus an 'allow zen.spamhaus.org' with a 'deny spamhaus.org' would permit
 
1813
DNS queries on a specific DNS BL zone but deny queries to other zones under
 
1814
the same parent domain.
 
1815
 
 
1816
Domains are matched case-insensitively, no wildcards are recognized,
 
1817
there should be no leading or trailing dot.
 
1818
 
 
1819
Specifying a block on querying a domain name has a similar effect as setting
 
1820
a score of corresponding DNSBL and URIBL rules to zero, and can be a handy
 
1821
alternative to hunting for such rules when a site policy does not allow
 
1822
certain DNS block lists to be queried.
 
1823
 
 
1824
Example:
 
1825
  dns_query_restriction deny  dnswl.org surbl.org
 
1826
  dns_query_restriction allow zen.spamhaus.org
 
1827
  dns_query_restriction deny  spamhaus.org mailspike.net spamcop.net
 
1828
 
 
1829
=cut
 
1830
 
 
1831
  push (@cmds, {
 
1832
    setting => 'dns_query_restriction',
 
1833
    type => $CONF_TYPE_STRING,
 
1834
    code => sub {
 
1835
      my ($self, $key, $value, $line) = @_;
 
1836
      defined $value && $value =~ s/^(allow|deny)\s+//i
 
1837
        or return $INVALID_VALUE;
 
1838
      my $blocked = lc($1) eq 'deny' ? 1 : 0;
 
1839
      foreach my $domain (split(' ', $value)) {
 
1840
        $domain =~ s/^\.//; $domain =~ s/\.\z//;  # strip dots
 
1841
        $self->{dns_query_blocked}{lc $domain} = $blocked;
 
1842
      }
 
1843
    }
 
1844
  });
 
1845
 
 
1846
=item clear_dns_query_restriction
 
1847
 
 
1848
The option removes any entries entered by previous 'dns_query_restriction'
 
1849
options, leaving the list empty, i.e. allowing DNS queries for any domain
 
1850
(including any DNS BL zone).
 
1851
 
 
1852
=cut
 
1853
 
 
1854
  push (@cmds, {
 
1855
    setting =>  'clear_dns_query_restriction',
 
1856
    aliases => ['clear_dns_query_restrictions'],
 
1857
    type => $CONF_TYPE_NOARGS,
 
1858
    code => sub {
 
1859
      my ($self, $key, $value, $line) = @_;
 
1860
      return $INVALID_VALUE  if defined $value && $value ne '';
 
1861
      delete $self->{dns_query_blocked};
1359
1862
    }
1360
1863
  });
1361
1864
 
1548
2051
=item bayes_use_hapaxes         (default: 1)
1549
2052
 
1550
2053
Should the Bayesian classifier use hapaxes (words/tokens that occur only
1551
 
once) when classifying?  This produces significantly better hit-rates, but
1552
 
increases database size by about a factor of 8 to 10.
 
2054
once) when classifying?  This produces significantly better hit-rates.
1553
2055
 
1554
2056
=cut
1555
2057
 
1593
2095
 
1594
2096
If enabled, the Bayes system will try to automatically expire old tokens
1595
2097
from the database.  Auto-expiry occurs when the number of tokens in the
1596
 
database surpasses the bayes_expiry_max_db_size value.
 
2098
database surpasses the bayes_expiry_max_db_size value. If a bayes datastore
 
2099
backend does not implement individual key/value expirations, the setting
 
2100
is silently ignored.
1597
2101
 
1598
2102
=cut
1599
2103
 
1603
2107
    type => $CONF_TYPE_BOOL,
1604
2108
  });
1605
2109
 
 
2110
=item bayes_token_ttl                   (default: 3w, i.e. 3 weeks)
 
2111
 
 
2112
Time-to-live / expiration time in seconds for tokens kept in a Bayes database.
 
2113
A numeric value is optionally suffixed by a time unit (s, m, h, d, w,
 
2114
indicating seconds (default), minutes, hours, days, weeks).
 
2115
 
 
2116
If bayes_auto_expire is true and a Bayes datastore backend supports it
 
2117
(currently only Redis), this setting controls deletion of expired tokens
 
2118
from a bayes database. The value is observed on a best-effort basis, exact
 
2119
timing promises are not necessarily kept. If a bayes datastore backend
 
2120
does not implement individual key/value expirations, the setting is silently
 
2121
ignored.
 
2122
 
 
2123
=cut
 
2124
 
 
2125
  push (@cmds, {
 
2126
    setting => 'bayes_token_ttl',
 
2127
    default => 3*7*24*60*60,  # seconds (3 weeks)
 
2128
    type => $CONF_TYPE_DURATION,
 
2129
  });
 
2130
 
 
2131
=item bayes_seen_ttl                    (default: 8d, i.e. 8 days)
 
2132
 
 
2133
Time-to-live / expiration time in seconds for 'seen' entries
 
2134
(i.e. mail message digests with their status) kept in a Bayes database.
 
2135
A numeric value is optionally suffixed by a time unit (s, m, h, d, w,
 
2136
indicating seconds (default), minutes, hours, days, weeks).
 
2137
 
 
2138
If bayes_auto_expire is true and a Bayes datastore backend supports it
 
2139
(currently only Redis), this setting controls deletion of expired 'seen'
 
2140
entries from a bayes database. The value is observed on a best-effort basis,
 
2141
exact timing promises are not necessarily kept. If a bayes datastore backend
 
2142
does not implement individual key/value expirations, the setting is silently
 
2143
ignored.
 
2144
 
 
2145
=cut
 
2146
 
 
2147
  push (@cmds, {
 
2148
    setting => 'bayes_seen_ttl',
 
2149
    default => 8*24*60*60,  # seconds (8 days)
 
2150
    type => $CONF_TYPE_DURATION,
 
2151
  });
 
2152
 
1606
2153
=item bayes_learn_to_journal    (default: 0)
1607
2154
 
1608
2155
If this option is set, whenever SpamAssassin does Bayes learning, it
1678
2225
  push (@cmds, {
1679
2226
    setting => 'time_limit',
1680
2227
    default => 300,
1681
 
    type => $CONF_TYPE_NUMERIC,
1682
 
    code => sub {
1683
 
      my ($self, $key, $value, $line) = @_;
1684
 
      if ($value !~ /^\d+(?:\.\d*)?$/) { return $INVALID_VALUE }
1685
 
      $value = 0+$value;
1686
 
      if ($value < 0) { return $INVALID_VALUE }
1687
 
      $self->{time_limit} = $value;
1688
 
    }
 
2228
    type => $CONF_TYPE_DURATION,
1689
2229
  });
1690
2230
 
1691
2231
=item lock_method type
1954
2494
    code => \&Mail::SpamAssassin::Conf::Parser::set_template_clear
1955
2495
  });
1956
2496
 
 
2497
=item mbox_format_from_regex
 
2498
 
 
2499
Set a specific regular expression to be used for mbox file From separators.
 
2500
 
 
2501
For example, this setting will allow sa-learn to process emails stored in
 
2502
a kmail 2 mbox:
 
2503
 
 
2504
mbox_format_from_regex /^From \S+  ?[[:upper:]][[:lower:]]{2}(?:, \d\d [[:upper:]][[:lower:]]{2} \d{4} [0-2]\d:\d\d:\d\d [+-]\d{4}| [[:upper:]][[:lower:]]{2} [ 1-3]\d [ 0-2]\d:\d\d:\d\d \d{4})/
 
2505
 
 
2506
 
 
2507
=cut
 
2508
 
 
2509
  push (@cmds, {
 
2510
    setting => 'mbox_format_from_regex',
 
2511
    type => $CONF_TYPE_STRING
 
2512
  });
 
2513
 
1957
2514
=back
1958
2515
 
1959
2516
=head1 RULE DEFINITIONS AND PRIVILEGED SETTINGS
2061
2618
their 'Resent-*' counterparts, and the 'Return-Path'.
2062
2619
 
2063
2620
Appending a modifier C<:name> to a header field name will cause everything
2064
 
except the first display name to be removed from the header field.  It is
2065
 
mainly applicable to header fields 'From' and 'Resent-From'.
 
2621
except the first display name to be removed from the header field. It is
 
2622
mainly applicable to header fields containing a single mail address: 'From',
 
2623
'Sender', along with their 'Resent-From' and 'Resent-Sender' counterparts.
2066
2624
 
2067
2625
It is syntactically permitted to append more than one modifier to a header
2068
2626
field name, although currently most combinations achieve no additional effect,
2069
2627
for example C<From:addr:raw> or C<From:raw:addr> is currently the same as
2070
2628
C<From:addr> .
2071
2629
 
 
2630
For example, appending C<:addr> to a header name will result in example@foo
 
2631
in all of the following cases:
 
2632
 
2072
2633
=over 4
2073
2634
 
2074
2635
=item example@foo
2087
2648
 
2088
2649
=back
2089
2650
 
2090
 
Appending C<:name> to the header name will cause everything except
2091
 
the first real name to be removed from the header.  For example,
2092
 
all of the following will result in "Foo Blah"
 
2651
For example, appending C<:name> to a header name will result in "Foo Blah"
 
2652
(without quotes) in all of the following cases:
2093
2653
 
2094
2654
=over 4
2095
2655
 
2164
2724
by running C<spamassassin --lint>.  This will avoid confusing error
2165
2725
messages, or other tests being skipped as a side-effect.
2166
2726
 
2167
 
=item header SYMBOLIC_TEST_NAME exists:name_of_header
 
2727
=item header SYMBOLIC_TEST_NAME exists:header_field_name
2168
2728
 
2169
 
Define a header existence test.  C<name_of_header> is the name of a
2170
 
header field to test for existence.  This is just a very simple version
2171
 
of the above header tests.
 
2729
Define a header field existence test.  C<header_field_name> is the name
 
2730
of a header field to test for existence.  Not to be confused with a
 
2731
test for a nonempty header field body, which can be implemented by a
 
2732
C<header SYMBOLIC_TEST_NAME header =~ /\S/> rule as described above.
2172
2733
 
2173
2734
=item header SYMBOLIC_TEST_NAME eval:name_of_eval_method([arguments])
2174
2735
 
2192
2753
<http://www.iana.org/assignments/ipv4-address-space>,
2193
2754
<http://duxcw.com/faq/network/privip.htm>,
2194
2755
<http://duxcw.com/faq/network/autoip.htm>, or
2195
 
<ftp://ftp.rfc-editor.org/in-notes/rfc3330.txt> as private.
 
2756
<http://tools.ietf.org/html/rfc5735> as private.
2196
2757
 
2197
2758
=item the 'set' argument
2198
2759
 
2199
2760
This is used as a 'zone ID'.  If you want to look up a multiple-meaning zone
2200
 
like NJABL or SORBS, you can then query the results from that zone using it;
 
2761
like SORBS, you can then query the results from that zone using it;
2201
2762
but all check_rbl_sub() calls must use that zone ID.
2202
2763
 
2203
2764
Also, if more than one IP address gets a DNSBL hit for a particular rule, it
2205
2766
 
2206
2767
=item the 'zone' argument
2207
2768
 
2208
 
This is the root zone of the DNSBL, ending in a period.
 
2769
This is the root zone of the DNSBL.
 
2770
 
 
2771
The domain name is considered to be a fully qualified domain name
 
2772
(i.e. not subject to DNS resolver's search or default domain options).
 
2773
No trailing period is needed, and will be removed if specified.
2209
2774
 
2210
2775
=item the 'sub-test' argument
2211
2776
 
2282
2847
      my ($self, $key, $value, $line) = @_;
2283
2848
      local ($1,$2);
2284
2849
      if ($value =~ /^(\S+)\s+(?:rbl)?eval:(.*)$/) {
2285
 
        my ($name, $fn) = ($1, $2);
 
2850
        my ($rulename, $fn) = ($1, $2);
2286
2851
 
2287
2852
        if ($fn =~ /^check_(?:rbl|dns)/) {
2288
 
          $self->{parser}->add_test ($name, $fn, $TYPE_RBL_EVALS);
 
2853
          $self->{parser}->add_test ($rulename, $fn, $TYPE_RBL_EVALS);
2289
2854
        }
2290
2855
        else {
2291
 
          $self->{parser}->add_test ($name, $fn, $TYPE_HEAD_EVALS);
 
2856
          $self->{parser}->add_test ($rulename, $fn, $TYPE_HEAD_EVALS);
2292
2857
        }
2293
2858
      }
2294
 
      elsif ($value =~ /^(\S+)\s+exists:([!-9;-\176]+)$/) {
 
2859
      elsif ($value =~ /^(\S+)\s+exists:(.*)$/) {
 
2860
        my ($rulename, $header_name) = ($1, $2);
2295
2861
        # RFC 5322 section 3.6.8, ftext printable US-ASCII ch not including ":"
2296
 
        $self->{parser}->add_test ($1, "defined($2)", $TYPE_HEAD_TESTS);
2297
 
        $self->{descriptions}->{$1} = "Found a $2 header";
 
2862
        if ($header_name !~ /\S/) {
 
2863
          return $MISSING_REQUIRED_VALUE;
 
2864
      # } elsif ($header_name !~ /^([!-9;-\176]+)$/) {
 
2865
        } elsif ($header_name !~ /^([^: \t]+)$/) {  # be generous
 
2866
          return $INVALID_HEADER_FIELD_NAME;
 
2867
        }
 
2868
        $self->{parser}->add_test ($rulename, "defined($header_name)",
 
2869
                                   $TYPE_HEAD_TESTS);
 
2870
        $self->{descriptions}->{$rulename} = "Found a $header_name header";
2298
2871
      }
2299
2872
      else {
2300
2873
        my @values = split(/\s+/, $value, 2);
2531
3104
    }
2532
3105
  });
2533
3106
 
2534
 
=item tflags SYMBOLIC_TEST_NAME [ {net|nice|learn|userconf|noautolearn|multiple} ]
 
3107
=item tflags SYMBOLIC_TEST_NAME flags
2535
3108
 
2536
 
Used to set flags on a test.  These flags are used in the
2537
 
score-determination back end system for details of the test's
2538
 
behaviour.  Please see C<bayes_auto_learn> for more information
2539
 
about tflag interaction with those systems. The following flags
2540
 
can be set:
 
3109
Used to set flags on a test. Parameter is a space-separated list of flag
 
3110
names or flag name = value pairs.
 
3111
These flags are used in the score-determination back end system for details
 
3112
of the test's behaviour.  Please see C<bayes_auto_learn> for more information
 
3113
about tflag interaction with those systems. The following flags can be set:
2541
3114
 
2542
3115
=over 4
2543
3116
 
2553
3126
 
2554
3127
=item  userconf
2555
3128
 
2556
 
The test requires user configuration before it can be used (like language-
2557
 
specific tests).
 
3129
The test requires user configuration before it can be used (like
 
3130
language-specific tests).
2558
3131
 
2559
3132
=item  learn
2560
3133
 
2561
3134
The test requires training before it can be used.
2562
3135
 
2563
 
=item noautolearn
 
3136
=item  noautolearn
2564
3137
 
2565
3138
The test will explicitly be ignored when calculating the score for
2566
3139
learning systems.
2567
3140
 
2568
 
=item multiple
 
3141
=item  autolearn_force
 
3142
 
 
3143
The test will be subject to less stringent autolearn thresholds.
 
3144
 
 
3145
Normally, SpamAssassin will require 3 points from the header and 3
 
3146
points from the body to be auto-learned as spam. This option keeps
 
3147
the threshold at 6 points total but changes it to have no regard to the 
 
3148
source of the points.
 
3149
 
 
3150
=item  multiple
2569
3151
 
2570
3152
The test will be evaluated multiple times, for use with meta rules.
2571
3153
Only affects header, body, rawbody, uri, and full tests.
2572
3154
 
 
3155
=item  maxhits=N
 
3156
 
 
3157
If B<multiple> is specified, limit the number of hits found to N.
 
3158
If the rule is used in a meta that counts the hits (e.g. __RULENAME > 5),
 
3159
this is a way to avoid wasted extra work (use "tflags multiple maxhits=6").
 
3160
 
 
3161
For example:
 
3162
 
 
3163
  uri      __KAM_COUNT_URIS /^./
 
3164
  tflags   __KAM_COUNT_URIS multiple maxhits=16
 
3165
  describe __KAM_COUNT_URIS A multiple match used to count URIs in a message
 
3166
 
 
3167
  meta __KAM_HAS_0_URIS (__KAM_COUNT_URIS == 0)
 
3168
  meta __KAM_HAS_1_URIS (__KAM_COUNT_URIS >= 1)
 
3169
  meta __KAM_HAS_2_URIS (__KAM_COUNT_URIS >= 2)
 
3170
  meta __KAM_HAS_3_URIS (__KAM_COUNT_URIS >= 3)
 
3171
  meta __KAM_HAS_4_URIS (__KAM_COUNT_URIS >= 4)
 
3172
  meta __KAM_HAS_5_URIS (__KAM_COUNT_URIS >= 5)
 
3173
  meta __KAM_HAS_10_URIS (__KAM_COUNT_URIS >= 10)
 
3174
  meta __KAM_HAS_15_URIS (__KAM_COUNT_URIS >= 15)
 
3175
 
 
3176
=item  ips_only
 
3177
 
 
3178
This flag is specific to rules invoking an URIDNSBL plugin,
 
3179
it is documented there.
 
3180
 
 
3181
=item  domains_only
 
3182
 
 
3183
This flag is specific to rules invoking an URIDNSBL plugin,
 
3184
it is documented there.
 
3185
 
 
3186
=item  ns
 
3187
 
 
3188
This flag is specific to rules invoking an URIDNSBL plugin,
 
3189
it is documented there.
 
3190
 
 
3191
=item  a
 
3192
 
 
3193
This flag is specific to rules invoking an URIDNSBL plugin,
 
3194
it is documented there.
 
3195
 
2573
3196
=back
2574
3197
 
2575
3198
=cut
2709
3332
        return $MISSING_REQUIRED_VALUE;
2710
3333
      }
2711
3334
      local ($1,$2,$3);
2712
 
      unless ($value =~ /^        ( [+-]? \d+ (?: \. \d*)? )
2713
 
                          (?: \s+ ( [+-]? \d+ (?: \. \d*)? ) )?
2714
 
                          (?: \s+ (\S* [a-zA-Z]) )? $/xs) {
 
3335
      unless ($value =~ /^        ( \+? \d+ (?: \. \d*)? [smhdw]? )
 
3336
                          (?: \s+ ( \+? \d+ (?: \. \d*)? [smhdw]? ) )?
 
3337
                          (?: \s+ (\S* [a-zA-Z]) )? $/xsi) {
2715
3338
        return $INVALID_VALUE;
2716
3339
      }
2717
 
      my $zone = $3;
 
3340
      my($timeout, $timeout_min, $zone) = ($1, $2, $3);
 
3341
      foreach ($timeout, $timeout_min) {
 
3342
        if (defined $_ && s/\s*([smhdw])\z//i) {
 
3343
          $_ *= { s => 1, m => 60, h => 3600,
 
3344
                  d => 24*3600, w => 7*24*3600 }->{lc $1};
 
3345
        }
 
3346
      }
2718
3347
      if (!defined $zone) {  # a global setting
2719
 
        $self->{rbl_timeout}     = $1+0;
2720
 
        $self->{rbl_timeout_min} = $2+0  if defined $2;
 
3348
        $self->{rbl_timeout}     = 0 + $timeout;
 
3349
        $self->{rbl_timeout_min} = 0 + $timeout_min  if defined $timeout_min;
2721
3350
      }
2722
3351
      else {  # per-zone settings
2723
 
        $zone =~ s/^\.//;  $zone =~ s/\.$//;  # strip leading and trailing dot
 
3352
        $zone =~ s/^\.//;  $zone =~ s/\.\z//;  # strip leading and trailing dot
2724
3353
        $zone = lc $zone;
2725
 
        $self->{by_zone}{$zone}{rbl_timeout}     = $1+0;
2726
 
        $self->{by_zone}{$zone}{rbl_timeout_min} = $2+0  if defined $2;
 
3354
        $self->{by_zone}{$zone}{rbl_timeout} = 0 + $timeout;
 
3355
        $self->{by_zone}{$zone}{rbl_timeout_min} =
 
3356
                                     0 + $timeout_min  if defined $timeout_min;
2727
3357
      }
2728
3358
    },
2729
 
    type => $CONF_TYPE_NUMERIC,
 
3359
    type => $CONF_TYPE_DURATION,
2730
3360
  });
2731
3361
 
2732
3362
=item util_rb_tld tld1 tld2 ...
2858
3488
    type => $CONF_TYPE_NUMERIC,
2859
3489
    code => sub {
2860
3490
      my ($self, $key, $value, $line) = @_;
2861
 
      if ($value !~ /^0?\d{3}$/) { return $INVALID_VALUE }
 
3491
      if ($value !~ /^0?[0-7]{3}$/) { return $INVALID_VALUE }
2862
3492
      $self->{bayes_file_mode} = untaint_var($value);
2863
3493
    }
2864
3494
  });
3099
3729
    type => $CONF_TYPE_STRING,
3100
3730
  });
3101
3731
 
 
3732
=item user_scores_fallback_to_global        (default: 1)
 
3733
 
 
3734
Fall back to global scores and settings if userprefs can't be loaded
 
3735
from SQL or LDAP, instead of passing the message through unprocessed.
 
3736
 
 
3737
=cut
 
3738
 
 
3739
  push (@cmds, {
 
3740
    setting => 'user_scores_fallback_to_global',
 
3741
    is_admin => 1,
 
3742
    default => 1,
 
3743
    type => $CONF_TYPE_BOOL,
 
3744
  });
 
3745
 
3102
3746
=item loadplugin PluginModuleName [/path/module.pm]
3103
3747
 
3104
3748
Load a SpamAssassin plugin module.  The C<PluginModuleName> is the perl module
3223
3867
This is a function call that returns C<1> if the plugin named
3224
3868
C<Name::Of::Plugin> is loaded, or C<undef> otherwise.
3225
3869
 
3226
 
=item can(Name::Of::Package::function_name)
 
3870
=item has(Name::Of::Package::function_name)
3227
3871
 
3228
3872
This is a function call that returns C<1> if the perl package named
3229
3873
C<Name::Of::Package> includes a function called C<function_name>, or C<undef>
3230
3874
otherwise.  Note that packages can be SpamAssassin plugins or built-in classes,
3231
 
there's no difference in this respect.
 
3875
there's no difference in this respect.  Internally this invokes UNIVERSAL::can.
 
3876
 
 
3877
=item can(Name::Of::Package::function_name)
 
3878
 
 
3879
This is a function call that returns C<1> if the perl package named
 
3880
C<Name::Of::Package> includes a function called C<function_name>
 
3881
B<and> that function returns a true value when called with no arguments,
 
3882
otherwise C<undef> is returned.
 
3883
 
 
3884
Is similar to C<has>, except that it also calls the named function,
 
3885
testing its return value (unlike the perl function UNIVERSAL::can).
 
3886
This makes it possible for a 'feature' function to determine its result
 
3887
value at run time.
3232
3888
 
3233
3889
=back
3234
3890
 
3303
3959
 _REQD_            message threshold
3304
3960
 _VERSION_         version (eg. 3.0.0 or 3.1.0-r26142-foo1)
3305
3961
 _SUBVERSION_      sub-version/code revision date (eg. 2004-01-10)
 
3962
 _RULESVERSION_    comma-separated list of rules versions, retrieved from
 
3963
                   an '# UPDATE version' comment in rules files; if there is
 
3964
                   more than one set of rules (update channels) the order
 
3965
                   is unspecified (currently sorted by names of files);
3306
3966
 _HOSTNAME_        hostname of the machine the mail was processed on
3307
3967
 _REMOTEHOSTNAME_  hostname of the machine the mail was sent from, only
3308
3968
                   available with spamd
3517
4177
  $self->{more_spam_to} = { };
3518
4178
  $self->{all_spam_to} = { };
3519
4179
 
3520
 
  $self->{trusted_networks} = $self->new_netset();
3521
 
  $self->{internal_networks} = $self->new_netset();
3522
 
  $self->{msa_networks} = Mail::SpamAssassin::NetSet->new(); # not new_netset
 
4180
  $self->{trusted_networks} = $self->new_netset('trusted_networks',1);
 
4181
  $self->{internal_networks} = $self->new_netset('internal_networks',1);
 
4182
  $self->{msa_networks} = $self->new_netset('msa_networks',0); # no loopback IP
3523
4183
  $self->{trusted_networks_configured} = 0;
3524
4184
  $self->{internal_networks_configured} = 0;
3525
4185
 
3530
4190
    push(@{$self->{headers_ham}},  $r);
3531
4191
  }
3532
4192
 
 
4193
  # RFC 6891: A good compromise may be the use of an EDNS maximum payload size
 
4194
  # of 4096 octets as a starting point.
 
4195
  $self->{dns_options}->{edns} = 4096;
 
4196
 
3533
4197
  # these should potentially be settable by end-users
3534
4198
  # perhaps via plugin?
3535
4199
  $self->{num_check_received} = 9;
3618
4282
        return $self->{$test_type}->{$pri}->{$rulename};
3619
4283
      }
3620
4284
    }
3621
 
    return undef; # if we get here we didn't find the rule
 
4285
    return;  # if we get here we didn't find the rule
3622
4286
  }
3623
4287
}
3624
4288
 
3639
4303
        return delete($self->{$test_type}->{$pri}->{$rulename});
3640
4304
      }
3641
4305
    }
3642
 
    return undef; # if we get here we didn't find the rule
 
4306
    return;  # if we get here we didn't find the rule
3643
4307
  }
3644
4308
}
3645
4309
 
3652
4316
  my ($self, $regexp) = @_;
3653
4317
 
3654
4318
  my @all_rules;
3655
 
  my $rule_type;
3656
4319
 
3657
 
  foreach $rule_type ($self->get_rule_types()) {
 
4320
  foreach my $rule_type ($self->get_rule_types()) {
3658
4321
    push(@all_rules, $self->get_rule_keys($rule_type));
3659
4322
  }
3660
4323
 
3675
4338
    $rules_to_keep_hash{$rule} = 1;
3676
4339
  }
3677
4340
 
3678
 
  foreach $rule_type ($self->get_rule_types()) {
 
4341
  foreach my $rule_type ($self->get_rule_types()) {
3679
4342
    foreach my $rulekey ($self->get_rule_keys($rule_type)) {
3680
4343
      $self->delete_rule($rule_type, $rulekey)
3681
4344
                    if (!$rules_to_keep_hash{$rulekey});
3737
4400
 
3738
4401
###########################################################################
3739
4402
 
 
4403
# treats a bitset argument as a bit vector of all possible port numbers (8 kB)
 
4404
# and sets bit values to $value (0 or 1) in the specified range of port numbers
 
4405
#
 
4406
sub set_ports_range {
 
4407
  my($bitset_ref, $port_range_lo, $port_range_hi, $value) = @_;
 
4408
  $port_range_lo = 0      if $port_range_lo < 0;
 
4409
  $port_range_hi = 65535  if $port_range_hi > 65535;
 
4410
  if (!defined $$bitset_ref) {  # provide a sensible default
 
4411
    wipe_ports_range($bitset_ref, 1);  # turn on all bits 0..65535
 
4412
    vec($$bitset_ref,$_,1) = 0  for 0..1023;  # avoid 0 and privileged ports
 
4413
  } elsif ($$bitset_ref eq '') {  # repopulate the bitset (late configuration)
 
4414
    wipe_ports_range($bitset_ref, 0);  # turn off all bits 0..65535
 
4415
  }
 
4416
  $value = !$value ? 0 : 1;
 
4417
  for (my $j = $port_range_lo; $j <= $port_range_hi; $j++) {
 
4418
    vec($$bitset_ref,$j,1) = $value;
 
4419
  }
 
4420
}
 
4421
 
 
4422
sub wipe_ports_range {
 
4423
  my($bitset_ref, $value) = @_;
 
4424
  $value = !$value ? "\000" : "\377";
 
4425
  $$bitset_ref = $value x 8192;  # quickly turn all bits 0..65535 on or off
 
4426
}
 
4427
 
 
4428
###########################################################################
 
4429
 
3740
4430
sub add_to_addrlist {
3741
4431
  my $self = shift; $self->{parser}->add_to_addrlist(@_);
3742
4432
}
3799
4489
sub maybe_header_only {
3800
4490
  my($self,$rulename) = @_;
3801
4491
  my $type = $self->{test_types}->{$rulename};
 
4492
 
 
4493
  if ($rulename =~ /AUTOLEARNTEST/i) {
 
4494
    dbg("config: auto-learn: $rulename - Test type is $self->{test_types}->{$rulename}.");
 
4495
  }
 
4496
 
3802
4497
  return 0 if (!defined ($type));
3803
4498
 
3804
4499
  if (($type == $TYPE_HEAD_TESTS) || ($type == $TYPE_HEAD_EVALS)) {
3805
4500
    return 1;
3806
4501
 
3807
4502
  } elsif ($type == $TYPE_META_TESTS) {
3808
 
    my $tflags = $self->{tflags}->{$rulename}; $tflags ||= '';
 
4503
    my $tflags = $self->{tflags}->{$rulename}; 
 
4504
    $tflags ||= '';
3809
4505
    if ($tflags =~ m/\bnet\b/i) {
3810
4506
      return 0;
3811
4507
    } else {
3819
4515
sub maybe_body_only {
3820
4516
  my($self,$rulename) = @_;
3821
4517
  my $type = $self->{test_types}->{$rulename};
 
4518
 
 
4519
  if ($rulename =~ /AUTOLEARNTEST/i) {
 
4520
    dbg("config: auto-learn: $rulename - Test type is $self->{test_types}->{$rulename}.");
 
4521
  }
 
4522
 
3822
4523
  return 0 if (!defined ($type));
3823
4524
 
3824
4525
  if (($type == $TYPE_BODY_TESTS) || ($type == $TYPE_BODY_EVALS)
3873
4574
    $dest = $self;
3874
4575
  }
3875
4576
 
 
4577
  my %done;
 
4578
 
3876
4579
  # keys that should not be copied in ->clone().
3877
4580
  # bug 4179: include want_rebuild_for_type, so that if a user rule
3878
4581
  # is defined, its method will be recompiled for future scans in
3882
4585
    scoreset scores want_rebuild_for_type
3883
4586
  );
3884
4587
 
 
4588
  # special cases.  first, skip anything that cannot be changed
 
4589
  # by users, and the stuff we take care of here
 
4590
  foreach my $var (@NON_COPIED_KEYS) {
 
4591
    $done{$var} = undef;
 
4592
  }
 
4593
 
3885
4594
  # keys that should can be copied using a ->clone() method, in ->clone()
3886
4595
  my @CLONABLE_KEYS = qw(
3887
4596
    internal_networks trusted_networks msa_networks 
3888
4597
  );
3889
4598
 
3890
 
  my %done;
3891
 
 
3892
 
  # special cases.  first, skip anything that cannot be changed
3893
 
  # by users, and the stuff we take care of here
3894
4599
  foreach my $key (@CLONABLE_KEYS) {
3895
4600
    $dest->{$key} = $source->{$key}->clone();
3896
4601
    $done{$key} = undef;
3897
4602
  }
3898
4603
 
3899
 
  foreach my $var (@NON_COPIED_KEYS) {
3900
 
    $done{$var} = undef;
 
4604
  # two-level hashes
 
4605
  foreach my $key (qw(uri_host_lists askdns)) {
 
4606
    my $v = $source->{$key};
 
4607
    my $dest_key_ref = $dest->{$key} = {};  # must start from scratch!
 
4608
    while(my($k2,$v2) = each %{$v}) {
 
4609
      %{$dest_key_ref->{$k2}} = %{$v2};
 
4610
    }
 
4611
    $done{$key} = undef;
3901
4612
  }
3902
4613
 
3903
4614
  # bug 4179: be smarter about cloning the rule-type structures;
3984
4695
}
3985
4696
 
3986
4697
sub new_netset {
3987
 
  my ($self) = @_;
3988
 
  my $set = Mail::SpamAssassin::NetSet->new();
3989
 
  $set->add_cidr ('127/8');
3990
 
  $set->add_cidr ('::1');
 
4698
  my ($self, $netset_name, $add_loopback) = @_;
 
4699
  my $set = Mail::SpamAssassin::NetSet->new($netset_name);
 
4700
  if ($add_loopback) {
 
4701
    $set->add_cidr('127.0.0.0/8');
 
4702
    $set->add_cidr('::1');
 
4703
  }
3991
4704
  return $set;
3992
4705
}
3993
4706
 
4009
4722
#   if (can(Mail::SpamAssassin::Conf::feature_originating_ip_headers))
4010
4723
 
4011
4724
sub feature_originating_ip_headers { 1 }
 
4725
sub feature_dns_local_ports_permit_avoid { 1 }
4012
4726
sub feature_bayes_auto_learn_on_error { 1 }
 
4727
sub feature_uri_host_listed { 1 }
 
4728
sub feature_yesno_takes_args { 1 }
4013
4729
sub feature_bug6558_free { 1 }
 
4730
sub feature_edns { 1 }  # supports 'dns_options edns' config option
 
4731
sub feature_dns_query_restriction { 1 }  # supported config option
4014
4732
 
4015
4733
###########################################################################
4016
4734